Blueprint 0stablev1.0.0
Blueprints
Pull this in
https://zrz.io/zbp/0-blueprints/v1.mdVersion-pinned. Latest tracks revisions; the pinned URL does not. Requirements are cited individually as ZBP-0-Rk, so an implementation can annotate and a review can check them one at a time.
TL;DR
A Blueprint is a complete, versioned, normative specification for one cross-cutting concern — workload identity, request signing, tenant isolation, and their kin. It is written to be handed to whoever is building the thing, as a URL, with the instruction “implement this.” Increasingly that “whoever” is a language model, and the format is shaped accordingly: self-contained, unambiguous, numbered, and testable.
Each blueprint is referenced as ZBP-N. Each individual requirement inside it is referenced as
ZBP-N-Rk — so you can cite ZBP-1-R1 in a code comment, grep a codebase for coverage, and have
a review answer “which requirements does this implementation actually satisfy?” mechanically rather
than impressionistically.
Blueprints are a sibling of Field Notes, not a kind of them. A Field Note argues; a Blueprint specifies. The two are linked but never merged.
Why these are separate from Field Notes
ZFN-0Field Note · currentZFN-0 — Engineering Field NotesWhat Field Notes are, why I write them, and how they work — numbered, status-tracked notes on building software well, published openly and importable as JSON and raw markdown.Why it's cited here: Cited to draw the line between the two formats: it defines a note as a short, arguable position and says explicitly that a note is not a tutorial — which is precisely the gap Blueprints exist to fill.Open ZFN-0 → says plainly that a Field Note is not a tutorial. It is a short, falsifiable position whose payload is the reasoning — the why, in about a thousand words, written to be argued with. That is exactly the right shape for a position and exactly the wrong shape for something you hand to a builder.
What a builder needs is the opposite document: long, complete, boring, and specific. It should not re-litigate whether the approach is correct — that debate belongs upstairs. It should tell you the wire format, the validation order, the failure modes, the error codes, and how you know when you’re done.
So the split is:
| Field Note (ZFN-N) | Blueprint (ZBP-N) | |
|---|---|---|
| Payload | the reasoning | the specification |
| Answers | should we? | how, exactly? |
| Length | ~1,000 words | 4,000–15,000 words |
| Voice | opinionated, arguable | normative, testable |
| Correctness test | do I still believe it? | did something build the right thing from it? |
| Lifecycle | status; superseded by a new note | semantic version; consumers pin a major |
A blueprint names the notes it rests on in implements_notes and links to them. It does not restate
their arguments. If you want to know why tokens should be bound to a key, read the note. If you
want to build it, read the blueprint.
The pull-in contract
The core use case is blunt: someone gives a coding agent a URL and says pull this in. Everything in the format follows from taking that seriously.
Implement DPoP for our API. Follow https://zrz.io/zbp/1-dpop-bound-requests.md exactly.
Report which ZBP-1-Rk requirements you satisfied and which you skipped.
That works only if a blueprint holds up alone. The agent fetches one document. It may not follow your links; it certainly won’t chase a chain of them. Which gives the format’s hardest rule:
No normative requirement may live only behind a link.
Inline the requirement; cite the source for depth. A blueprint that says “handle nonces per the RFC” has failed — it has outsourced the part the reader needed. Say what to do, then cite the RFC for the reader who wants the full picture. Links are depth, never load-bearing.
The second thing that follows is applicability. The dominant failure of pull-in-by-URL isn’t a bad
specification; it’s a good specification confidently applied to the wrong problem. Every blueprint
therefore opens with what it’s for and, more importantly, what it is not for — and carries both in
front matter (use_when, not_for) so a tool can check fit before spending the context window.
Normative language and requirement ids
Blueprints use RFC 2119 / RFC 8174 keywords — MUST, MUST NOT, SHOULD, SHOULD NOT, MAY — capitalised, and only where they carry that meaning. This is not ceremony. Capitalised normative keywords survive summarisation, translation, and chunked retrieval far better than prose hedging, and they force the author to decide whether something is actually required or merely nice.
Every normative requirement gets a stable identifier, written as a bolded id at the start of its line:
- **ZBP-N-Rk** The server MUST reject a proof whose `htu` does not match the request URI.
Definition syntax (bolded, line-initial) is deliberately distinct from citation syntax (bare
ZBP-N-Rk in prose), which makes the requirement set mechanically knowable. The site validates this
at build time: ids run 1..n with no gaps or duplicates, no blueprint defines a requirement belonging
to another, and every cited requirement resolves to one that exists. A dangling requirement citation
is worse than none — it reads as authoritative.
The payoff is that a document becomes a conformance surface:
- An implementation can annotate itself —
// ZBP-1-R9: reject non-asymmetric alg. git grep -n 'ZBP-[0-9]*-R[0-9]*'gives you a coverage map of your own codebase.- A review — human or agent — can go requirement by requirement instead of forming an impression.
- A gap becomes a citable fact: “we do not satisfy ZBP-1-R14” is a decision, not an oversight.
Renumbering is prohibited. If a requirement is withdrawn, its number is retired in place and marked withdrawn; downstream code and audits reference these numbers, and silently reusing one turns an accurate annotation into a lie.
Versioning and pinning
A blueprint gets pinned into someone’s codebase. That makes silent drift a correctness bug for the consumer, not just an editorial matter — so blueprints carry a semantic version, and the versions are addressable:
/zbp/<slug>— the rendered page, latest version./zbp/<slug>.md— raw markdown, latest version. Convenient; moves under you./zbp/<slug>/vN.md— raw markdown, pinned to major N. This is what you reference in a repository, a prompt, or an architecture document.
The version rules:
- MAJOR — a normative requirement changed meaning, was removed, or a new MUST was added. An implementation that conformed may no longer conform. The prior major is frozen into the archive and keeps serving at its pinned URL forever.
- MINOR — new non-breaking material: a new SHOULD or MAY, a new annex, more test vectors, clarification that doesn’t change what conforms.
- PATCH — typos, formatting, prose that changes no meaning.
Every entry in /zbp/blueprints.json carries a content_sha256 of the exact bytes served, so a
consumer can detect that a document moved without diffing it.
Composition
Real architectures are several of these at once, which is the whole point of writing them as components. Two front-matter fields carry it:
requires: [N, …]— blueprints this one builds on. It is not a suggestion: ZBP-2Blueprint · v1.0.0ZBP-2 — A Security Token Service for workload identityServices in your platform need to authenticate to each other and you want every call attributable to a named workload holding no long-lived secret.Why it's cited here: Referenced as an example of a blueprint that declares its requirements, showing how the composition model resolves in practice.Open ZBP-2 →’s requirements may assume ZBP-1Blueprint · v1.0.0ZBP-1 — DPoP-bound requests across an API surfaceYou are issuing or accepting access tokens over HTTP and want a stolen token to be useless without the holder's private key.Why it's cited here: Used here as the worked example of a requirement identifier — ZBP-1-R1 — because it is the smallest blueprint and its requirements are self-contained.Open ZBP-1 → is in force.provides: ["capability-slug", …]— what implementing it gives you, so a dependent blueprint’srequiresresolves to something meaningful rather than a bare number.
The manifest exposes both, so “pull in ZBP-4Blueprint · v1.0.0ZBP-4 — Authentication for a multi-tenant SaaS productYou are building sign-in for a product where people belong to customer organisations, and one person may belong to several.Why it's cited here: Referenced as the largest example of composition: it requires two other blueprints, which is what the bundle mechanism was built to serve.Open ZBP-4 →” transitively names everything else worth fetching.
Anatomy
The section order below is the house shape. Not every blueprint needs every section, but the order is fixed, because consistent ordering is what lets a reader — or a retrieval system pulling a single chunk — know where they are.
- TL;DR — what this specifies, in a paragraph.
- Applicability — use this when / do not use this when. First, always.
- Scope and non-goals — the boundary of the document.
- Vocabulary — defined terms, then used consistently. Synonym drift is the single most common way a long specification becomes ambiguous, and models drift more than people do.
- Architecture — the components and their boundaries.
- Normative requirements — the numbered core.
- Wire formats and interfaces — concrete. Real headers, real payloads, schemas.
- Algorithms — ordered steps with named failure outcomes.
- Threat model and failure modes — what breaks, how it’s detected, what it costs.
- Anti-patterns — “if you find yourself doing this, you’ve misread the document.”
- Test vectors — concrete inputs and expected outputs.
- Conformance checklist — the deliverable an implementer grades themselves against.
- Rationale — links to the Field Notes carrying the argument. Brief.
- References and Changelog.
Test vectors and the conformance checklist are the load-bearing sections. Prose describing an algorithm produces plausible implementations; a vector with an expected output produces correct ones, because it can be run. Where a vector can be made real — an actual signature that actually verifies — make it real. A fabricated example that doesn’t validate is worse than none, since the first thing a careful implementer does is try it.
Length, annexes, and context budget
These documents are long, and context is finite. Pulling three 12,000-word blueprints into a session
costs more than the work usually deserves. So a blueprint is written as a core — the part that is
always needed — with optional annexes at /zbp/<slug>/annex-<topic>.md, each self-contained and
separately addressable. Key rotation, migration from a predecessor, platform-specific notes: these are
annexes. An agent pulls the core plus the one annex it needs.
Structure serves retrieval too. Headings are the chunk boundaries a semantic index will use, so each
## section should stand on its own and repeat enough context to be intelligible in isolation. A
section that only makes sense after reading the previous one will be retrieved and misread.
Machine interface
Blueprints exist as data, not only as pages:
/zbp/blueprints.json— every blueprint: id, ref, title, version, status,use_when,not_for,requires,provides, the Field Notes behind it, requirement count,content_sha256, and both rendered and raw URLs (latest and pinned)./zbp/<slug>.mdand/zbp/<slug>/vN.md— the authored markdown, front matter included, byte-exact./llms.txt— the discovery file, listing every blueprint with its one-line applicability test, so an agent can pick the right document without fetching all of them.
Authoring requirements
These apply to writing a blueprint, and this document dogfoods them.
- ZBP-0-R1 A blueprint MUST be self-contained: every normative requirement MUST be stated in the document itself. External specifications MAY be cited for depth but MUST NOT be the only place a requirement appears.
- ZBP-0-R2 A blueprint MUST declare
use_whenand SHOULD declarenot_for, and MUST open with an Applicability section stating both in prose. - ZBP-0-R3 Normative keywords MUST follow RFC 2119 / RFC 8174 and MUST be capitalised. Prose that is not normative MUST NOT use them.
- ZBP-0-R4 Every normative requirement MUST have an identifier of the form
ZBP-N-Rk, defined by a bolded, line-initial id, where N is the blueprint’s own id. - ZBP-0-R5 Requirement numbers MUST run from 1 with no gaps and no duplicates, and MUST NOT be reused or renumbered once published. A withdrawn requirement MUST be retained in place and marked withdrawn.
- ZBP-0-R6 A blueprint MUST carry a semantic
version. A change that alters, removes, or adds a MUST-level requirement MUST be a MAJOR bump. - ZBP-0-R7 On a MAJOR bump the prior major MUST be frozen, unmodified, at its pinned URL
(
/zbp/<slug>/vN.md), so an implementation built against it can still read what it was built against. - ZBP-0-R8 A blueprint MUST define its terms before using them, and MUST use one term per concept throughout.
- ZBP-0-R9 A blueprint MUST include a conformance checklist covering every MUST-level requirement.
- ZBP-0-R10 A blueprint SHOULD include executable test vectors. Any vector presented as real MUST actually validate; a vector that cannot be made real MUST be labelled as illustrative.
- ZBP-0-R11 A blueprint MUST NOT contain security-relevant secrets, and any key material included for test purposes MUST be labelled as a test key and MUST NOT be reused in production.
- ZBP-0-R12 A blueprint MUST NOT identify any employer, client, or internal system, and MUST NOT describe a specific organisation’s deployment. Blueprints specify the general pattern; anything that would only make sense inside one company does not belong in one.
- ZBP-0-R13 A blueprint MUST cite the Field Notes carrying its rationale in
implements_notesrather than restating the argument at length. - ZBP-0-R14 A blueprint MUST declare
requiresfor every other blueprint its requirements assume, and SHOULD declareprovidesfor the capabilities it delivers.
Conformance checklist
An authored blueprint conforms when:
- Front matter validates, including
version,use_when, andstatus. - Applicability is the first section after the TL;DR, and states both sides (ZBP-0-R2).
- Normative keywords are capitalised, and ordinary prose uses none (ZBP-0-R3).
- Every normative statement is numbered, and the numbers run 1..n (ZBP-0-R4, ZBP-0-R5).
- No requirement is stated only by reference to an external document (ZBP-0-R1).
- Terms are defined before use and used consistently (ZBP-0-R8).
- The version reflects the change: a MUST that moved is a MAJOR bump (ZBP-0-R6).
- On a MAJOR bump, the outgoing major was frozen to the archive before the live file was edited (ZBP-0-R7).
- A conformance checklist covers every MUST (ZBP-0-R9).
- Test vectors are present, and any presented as real have been verified to validate (ZBP-0-R10).
- No secrets are present, and any test key is labelled as one (ZBP-0-R11).
- No employer, client, or internal system is identifiable anywhere in the text (ZBP-0-R12).
-
implements_notes,requires, andprovidesare populated (ZBP-0-R13, ZBP-0-R14). -
pnpm buildpasses, which validates the requirement graph across the whole library.
Rationale
The positions underneath this format are argued elsewhere and not repeated here: ZFN-14Field Note · currentZFN-14 — Define every API with a schema, and generate the clientsDefine every API with a machine-readable schema (OpenAPI, Protobuf, GraphQL) as the source of truth, and generate clients and server stubs from it — never hand-roll request-building and JSON parsing. Hand-written clients drift and break silently; check schema compatibility in CI.Why it's cited here: The same instinct one level up: a Blueprint is the contract for a subsystem, written before and apart from any implementation of it.Open ZFN-14 → on specifying the contract first and generating from it; ZFN-30Field Note · currentZFN-30 — Use the standard; don't reinvent the protocolWhen a standard exists for a common or complex problem, use it — don't reinvent the protocol. Standards encode huge adversarial expertise, especially in auth and crypto; a partial implementation beats rolling your own. You're not that special, and your problem isn't either.Why it's cited here: Why a Blueprint's job is to specify how to deploy an existing standard correctly rather than to invent a house protocol.Open ZFN-30 → and ZFN-45Field Note · currentZFN-45 — Read the standards; better yet, help write themLearn to read standards docs — RFCs, W3C recs — fluently; they're the primary source, not a last resort. Even better, get involved: reading them well makes you a sharper builder, and helping write them is the best protocol education there is.Why it's cited here: The reason each Blueprint cites its source RFCs and is expected to be read alongside them rather than instead of them.Open ZFN-45 → on building from standards rather than around them; ZFN-47Field Note · currentZFN-47 — Govern the contract between teams, not the code inside themTeams own services end to end; one team owns the gateway that dispatches to them. Govern exactly one thing centrally — the contract at the boundary (schema, identity, errors, idempotency) — and enforce it at runtime. Don't mandate libraries; ship them as an opt-in blueprint.Why it's cited here: A Blueprint is that governed artefact made explicit and versioned.Open ZFN-47 → on the contract as the governed artefact; and ZFN-0Field Note · currentZFN-0 — Engineering Field NotesWhat Field Notes are, why I write them, and how they work — numbered, status-tracked notes on building software well, published openly and importable as JSON and raw markdown.Why it's cited here: Cited to draw the line between the two formats: it defines a note as a short, arguable position and says explicitly that a note is not a tutorial — which is precisely the gap Blueprints exist to fill.Open ZFN-0 → for why the short-form notes stay short.
One position is specific to this format and worth stating plainly: writing specifications this way is worth the effort because the reader is increasingly a model. A model will implement whatever you give it, confidently, including the parts you left vague. Precision, numbering, and test vectors are no longer editorial polish — they’re the difference between generated code that’s right and generated code that merely looks right. The discipline that makes a document good for a machine turns out to make it good for a person on their first week, too.
Reuse
Take what’s useful. Blueprints are written to be implemented, adapted, and argued with. If you adopt one, pin a major so what you built against stays readable. If one is wrong, tell me which requirement and why — that’s a much better conversation than “this doesn’t work.”
Changelog
- 2026-07-27 (1.0.0): First published. Established the Blueprint format,
ZBP-Nnumbering,ZBP-N-Rkrequirement ids with build-time validation, semantic versioning with pinned major URLs, therequires/providescomposition model, and theblueprints.json+ raw-markdown +llms.txtmachine interface.