Source: guides/library_first.md

Generated automatically from the published contract sources.

Source path: guides/library_first.md.

Contract text

Library First — the served guide

Served-bundle content (CTX-06 in "The Served Context — One Source, Three Forms"): the discipline a coding agent applies before it builds a capability by hand. This file declares no requirements; every rule it teaches is owned by the statement it cites.

The discipline

Check the published library before writing a capability yourself. Use list_library to find available entries and read_library_entry to inspect a candidate's contract and selection summary (API-L0-14). Availability comes from the current inventory; a capability named elsewhere in the documentation may be planned or unpublished. Use a suitable entry when one covers the need. If an entry does not fit, record the deficiency in the project's own record instead of editing the vendored copy (SPM-L0-49).

Use secret custody for stored upstream keys. An application calls an external API that needs a stored key through a declared upstream (EGW-L0-01). Store the value with store_secret, then call declare_upstream with its name. Declaration refuses credential_not_in_custody if the named credential is not stored, and the credential must belong to the declaring account (SCRT-L0-08; EGW-L0-01). The gateway applies the key; the application does not keep its own copy (SCRT-L0-01). A project may document the name and usage in a credential register, but the Kit Project Contract requires no such file or format (SPM-L0-50; Q-229).

An upstream record is a suggestion, never a requirement. Where the application declares upstreams, a project-owned document can record the declarations beside the code that calls them. One form that works keeps two documents in the project: an upstream record with one entry per declared upstream, and a credential register with one entry per stored credential. An upstream declaration names the product, the gateway path the backend calls, the credential name applied at the edge, the models as configuration, and the failover posture as the application's own declared behavior. The backend calls each upstream at the gateway path its entry names. A credential declaration names the credential — its name, the service that consumes it, what it authorizes, and how a value is obtained, a suggested form and no rule (Q-229) — and never its value. No row of the Kit Project Contract asks for either file (Q-252).

Tools and skills

  • list_library tool — returns entries to any signed-in connection, and anonymously on the wire (API-L0-15). Each row includes name, kind, version, closure_hash, summary, and supersedes (LC-01); an entry's previously published versions, with their dates, come from read_library_entry (LC-06). To compare an existing installation, pass installed with one item per manifest row: its name, version, and closure_hash renamed to hash. A matching hash produces standing: "current"; a different hash produces "newer"; an installed name absent from the served catalog produces "withdrawn"; a served entry missing from installed produces "not_held", compared with nothing (LC-06). newer is a catalog comparison result, not a semantic-version comparison, and not_held is not an instruction to install the entry. Add held_only: true beside installed to answer only the entries installed names, each row whole, which is all a proof or an update's compare reads; held_only without installed is refused invalid_request (LC-06).
  • read_library_entry tool — takes the entry's name. With no file, it returns entry, including the file list with SHA-256 hashes and sizes. Add file to read one listed path; the response's file object contains path, encoding (utf8 or base64), content, and sha256. Decode base64 before hashing or writing binary bytes. On the MCP surface the entry answer also carries download: the line that takes the entry with the turnzero-cloud command, as command and, for Windows, command_windows, and next, what remains after it. Run at the project's root, the line checks every file before it writes the entry and its manifest row (LC-05; LC-07; PLD-L0-94). An unknown entry or file returns no_such_entry. A package that carries runtime code lists its compiled modules under lib/ with their declarations and a package.json beside them, and lists no source and no tests (LC-01; Q-235).
  • add-library-entry skill — guides choosing an entry and running its line, which writes the entry's files and its manifest row into the project's library folder (LC-07). For a package that carries runtime code, the line also copies its package.json and lib/ into app/lib/<name>/, declares the dependency file:lib/<name>, and runs npm install; the skill then commits the copy and imports the package by its npm name (SPM-L0-49).
  • update-library skill — asks once per entry and runs each accepted entry's line, which replaces the entry folder with the published files and updates the manifest row, and, where the entry carries a package, replaces the copy in app/lib/<name>/ and runs npm install. It follows the package's migration instructions and changes the instance file's package pin through the registrar (SPM-L0-49).

A large file reads in chunks. With file, pass limit, 1 to 16000 code points and 8000 by default, then each answer's next_offset as offset with the stamp it returned, until next_offset is null. Each chunk's stamp is the file's SHA-256, and a nonzero offset needs it. Join the chunks' content in order, decode it where encoding is base64, and check the result against the file's sha256 (LC-05; CTX-07). A publication that changes the file between two chunks refuses the stale stamp context_changed; restart at offset 0 without a stamp. An offset, limit, or stamp without file is refused invalid_request.

A script can download an entry and check its hashes. Beside the chunked read, the same action answers anonymously over HTTP at /api/v1/actions/read_library_entry on the origin the MCP server's instructions name: a POST with name and file as its JSON body, or a GET with them as query parameters (MAPI-10; API-L0-15). Such a script reads each listed file whole, writes its bytes, and checks each written file against the listed sha256 (LC-05). The line the entry answer carries reads this route itself, so a project takes an entry with that line rather than with a script of its own. This route's answer carries no download: write the line as read_documentation's page /cloud/concepts/turnzero-cloud-command/ gives it. Where download.next says no line takes an entry, the entry cannot be taken.

A package's import name is the name in its served package.json, @turnzero/<name>, which resolves to lib/index.js, the re-export of the package's runtime modules. The package's test double is its testing subpath, @turnzero/<name>/testing, which only the application's tests import (FTR-L0-26; Q-235).

When a publication exists, both read tools include its source_commit and published_at. The service serves the latest published catalog; a later publication can change what subsequent calls return (API-L0-14). A withdrawn entry remains usable from the project's committed copy; withdrawal deletes nothing a project holds (LC-04).

The proof

If the project has the Turn Zero Blueprint registrar, run its validate tool with kind: "library" against the library folder. This rehashes the files and compares them with the manifest (REG-25; LC-07). A package's compiled lib/ folder and its package.json are files of the entry and are rehashed with the rest; the copy the application made under app/lib/ is outside the library folder and is not (SPM-L0-49). Where validate names the entry library/prd unaddressable, the installed registrar predates that entry, the library's own requirements documents: prove that row with list_library and installed, as the next paragraph describes.

Without a registrar, the line has checked each file's hash before it wrote anything; then call list_library with installed entries shaped as {name, version, hash: closure_hash} from the manifest rows. Every entry just fetched should report current. newer means its recorded hash differs from the published hash; run that entry's line again, which takes it whole and rewrites the row. Other available entries absent from installed report not_held, compared with nothing; this does not instruct you to install them. A withdrawn result means the served catalog no longer carries it. The catalog comparison checks recorded hashes and reads no local files, so it cannot detect later edits to the vendored files. Keep the vendored folder unchanged under SPM-L0-49.

Exact source Markdown

# Library First — the served guide

Served-bundle content (CTX-06 in "The Served Context — One Source, Three Forms"): the discipline a coding agent applies before it builds a capability by hand. This file declares no requirements; every rule it teaches is owned by the statement it cites.

## The discipline

**Check the published library before writing a capability yourself.** Use `list_library` to find available entries and `read_library_entry` to inspect a candidate's contract and selection summary (API-L0-14). Availability comes from the current inventory; a capability named elsewhere in the documentation may be planned or unpublished. Use a suitable entry when one covers the need. If an entry does not fit, record the deficiency in the project's own record instead of editing the vendored copy (SPM-L0-49).

**Use secret custody for stored upstream keys.** An application calls an external API that needs a stored key through a declared upstream (EGW-L0-01). Store the value with `store_secret`, then call `declare_upstream` with its name. Declaration refuses `credential_not_in_custody` if the named credential is not stored, and the credential must belong to the declaring account (SCRT-L0-08; EGW-L0-01). The gateway applies the key; the application does not keep its own copy (SCRT-L0-01). A project may document the name and usage in a credential register, but the Kit Project Contract requires no such file or format (SPM-L0-50; Q-229).

**An upstream record is a suggestion, never a requirement.** Where the application declares upstreams, a project-owned document can record the declarations beside the code that calls them. One form that works keeps two documents in the project: an upstream record with one entry per declared upstream, and a credential register with one entry per stored credential. An upstream declaration names the product, the gateway path the backend calls, the credential name applied at the edge, the models as configuration, and the failover posture as the application's own declared behavior. The backend calls each upstream at the gateway path its entry names. A credential declaration names the credential — its name, the service that consumes it, what it authorizes, and how a value is obtained, a suggested form and no rule (Q-229) — and never its value. No row of the Kit Project Contract asks for either file (Q-252).

## Tools and skills

- **`list_library` tool** — returns `entries` to any signed-in connection, and anonymously on the wire (API-L0-15). Each row includes `name`, `kind`, `version`, `closure_hash`, `summary`, and `supersedes` (LC-01); an entry's previously published versions, with their dates, come from `read_library_entry` (LC-06). To compare an existing installation, pass `installed` with one item per manifest row: its `name`, `version`, and `closure_hash` renamed to `hash`. A matching hash produces `standing: "current"`; a different hash produces `"newer"`; an installed name absent from the served catalog produces `"withdrawn"`; a served entry missing from `installed` produces `"not_held"`, compared with nothing (LC-06). `newer` is a catalog comparison result, not a semantic-version comparison, and `not_held` is not an instruction to install the entry. Add `held_only: true` beside `installed` to answer only the entries `installed` names, each row whole, which is all a proof or an update's compare reads; `held_only` without `installed` is refused `invalid_request` (LC-06).
- **`read_library_entry` tool** — takes the entry's `name`. With no `file`, it returns `entry`, including the file list with SHA-256 hashes and sizes. Add `file` to read one listed path; the response's `file` object contains `path`, `encoding` (`utf8` or `base64`), `content`, and `sha256`. Decode base64 before hashing or writing binary bytes. On the MCP surface the entry answer also carries `download`: the line that takes the entry with the turnzero-cloud command, as `command` and, for Windows, `command_windows`, and `next`, what remains after it. Run at the project's root, the line checks every file before it writes the entry and its manifest row (LC-05; LC-07; PLD-L0-94). An unknown entry or file returns `no_such_entry`. A package that carries runtime code lists its compiled modules under `lib/` with their declarations and a `package.json` beside them, and lists no source and no tests (LC-01; Q-235).
- **`add-library-entry` skill** — guides choosing an entry and running its line, which writes the entry's files and its manifest row into the project's library folder (LC-07). For a package that carries runtime code, the line also copies its `package.json` and `lib/` into `app/lib/<name>/`, declares the dependency `file:lib/<name>`, and runs `npm install`; the skill then commits the copy and imports the package by its npm name (SPM-L0-49).
- **`update-library` skill** — asks once per entry and runs each accepted entry's line, which replaces the entry folder with the published files and updates the manifest row, and, where the entry carries a package, replaces the copy in `app/lib/<name>/` and runs `npm install`. It follows the package's migration instructions and changes the instance file's package pin through the registrar (SPM-L0-49).

**A large file reads in chunks.** With `file`, pass `limit`, 1 to 16000 code points and 8000 by default, then each answer's `next_offset` as `offset` with the `stamp` it returned, until `next_offset` is null. Each chunk's `stamp` is the file's SHA-256, and a nonzero `offset` needs it. Join the chunks' `content` in order, decode it where `encoding` is `base64`, and check the result against the file's `sha256` (LC-05; CTX-07). A publication that changes the file between two chunks refuses the stale stamp `context_changed`; restart at `offset` 0 without a stamp. An `offset`, `limit`, or `stamp` without `file` is refused `invalid_request`.

**A script can download an entry and check its hashes.** Beside the chunked read, the same action answers anonymously over HTTP at `/api/v1/actions/read_library_entry` on the origin the MCP server's instructions name: a `POST` with `name` and `file` as its JSON body, or a `GET` with them as query parameters (MAPI-10; API-L0-15). Such a script reads each listed file whole, writes its bytes, and checks each written file against the listed `sha256` (LC-05). The line the entry answer carries reads this route itself, so a project takes an entry with that line rather than with a script of its own. This route's answer carries no `download`: write the line as read_documentation's page /cloud/concepts/turnzero-cloud-command/ gives it. Where `download.next` says no line takes an entry, the entry cannot be taken.

**A package's import name is the `name` in its served `package.json`**, `@turnzero/<name>`, which resolves to `lib/index.js`, the re-export of the package's runtime modules. The package's test double is its `testing` subpath, `@turnzero/<name>/testing`, which only the application's tests import (FTR-L0-26; Q-235).

When a publication exists, both read tools include its `source_commit` and `published_at`. The service serves the latest published catalog; a later publication can change what subsequent calls return (API-L0-14). A withdrawn entry remains usable from the project's committed copy; withdrawal deletes nothing a project holds (LC-04).

## The proof

If the project has the Turn Zero Blueprint registrar, run its `validate` tool with `kind: "library"` against the library folder. This rehashes the files and compares them with the manifest (REG-25; LC-07). A package's compiled `lib/` folder and its `package.json` are files of the entry and are rehashed with the rest; the copy the application made under `app/lib/` is outside the library folder and is not (SPM-L0-49). Where `validate` names the entry `library/prd` unaddressable, the installed registrar predates that entry, the library's own requirements documents: prove that row with `list_library` and `installed`, as the next paragraph describes.

Without a registrar, the line has checked each file's hash before it wrote anything; then call `list_library` with `installed` entries shaped as `{name, version, hash: closure_hash}` from the manifest rows. Every entry just fetched should report `current`. `newer` means its recorded hash differs from the published hash; run that entry's line again, which takes it whole and rewrites the row. Other available entries absent from `installed` report `not_held`, compared with nothing; this does not instruct you to install them. A `withdrawn` result means the served catalog no longer carries it. The catalog comparison checks recorded hashes and reads no local files, so it cannot detect later edits to the vendored files. Keep the vendored folder unchanged under SPM-L0-49.