---
id: 0
title: "Blueprints"
version: "1.0.0"
status: stable
date: 2026-07-27
authors:
  - "Theo Zourzouvillys"
tags: [meta, process, llm, standards]
summary: "What Blueprints are: versioned, normative implementation specifications for cross-cutting concerns, written to be pulled into a build by URL and implemented directly — by a person or by a language model — with numbered requirements you can grep for."
use_when: "You are writing a Blueprint, or you want to understand the contract a Blueprint offers before pulling one into a build."
not_for:
  - "Deciding whether a practice is a good idea — that argument lives in a Field Note, not here."
  - "Learning a technology from scratch; a blueprint assumes you know the domain and want the specification."
requires: []
provides:
  - "blueprint-format"
implements_notes: [0, 14, 30, 45, 47]
supersedes: null
superseded_by: null
aliases: []
crossrefs:
  ZFN-0: "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."
  ZFN-14: "The same instinct one level up: a Blueprint is the contract for a subsystem, written before and apart from any implementation of it."
  ZFN-30: "Why a Blueprint's job is to specify how to deploy an existing standard correctly rather than to invent a house protocol."
  ZFN-45: "The reason each Blueprint cites its source RFCs and is expected to be read alongside them rather than instead of them."
  ZFN-47: "A Blueprint is that governed artefact made explicit and versioned."
  ZBP-1: "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."
  ZBP-2: "Referenced as an example of a blueprint that declares its requirements, showing how the composition model resolves in practice."
  ZBP-4: "Referenced as the largest example of composition: it requires two other blueprints, which is what the bundle mechanism was built to serve."
---

## 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](/zfn/), 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-0](/zfn/0-engineering-field-notes/) 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-2's requirements may
  assume ZBP-1 is in force.
- `provides: ["capability-slug", …]` — what implementing it gives you, so a dependent blueprint's
  `requires` resolves to something meaningful rather than a bare number.

The manifest exposes both, so "pull in 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.

1. **TL;DR** — what this specifies, in a paragraph.
2. **Applicability** — use this when / do not use this when. First, always.
3. **Scope and non-goals** — the boundary of the document.
4. **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.
5. **Architecture** — the components and their boundaries.
6. **Normative requirements** — the numbered core.
7. **Wire formats and interfaces** — concrete. Real headers, real payloads, schemas.
8. **Algorithms** — ordered steps with named failure outcomes.
9. **Threat model and failure modes** — what breaks, how it's detected, what it costs.
10. **Anti-patterns** — "if you find yourself doing this, you've misread the document."
11. **Test vectors** — concrete inputs and expected outputs.
12. **Conformance checklist** — the deliverable an implementer grades themselves against.
13. **Rationale** — links to the Field Notes carrying the argument. Brief.
14. **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>.md`** and **`/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_when` and SHOULD declare `not_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_notes`
  rather than restating the argument at length.
- **ZBP-0-R14** A blueprint MUST declare `requires` for every other blueprint its requirements assume,
  and SHOULD declare `provides` for the capabilities it delivers.

## Conformance checklist

An authored blueprint conforms when:

- [ ] Front matter validates, including `version`, `use_when`, and `status`.
- [ ] 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`, and `provides` are populated (ZBP-0-R13, ZBP-0-R14).
- [ ] `pnpm build` passes, which validates the requirement graph across the whole library.

## Rationale

The positions underneath this format are argued elsewhere and not repeated here:
[ZFN-14](/zfn/14-schema-first-apis-generate-clients/) on specifying the contract first and generating
from it; [ZFN-30](/zfn/30-use-standards-dont-reinvent/) and
[ZFN-45](/zfn/45-read-the-standards/) on building from standards rather than around them;
[ZFN-47](/zfn/47-govern-the-contract-between-teams/) on the contract as the governed artefact; and
[ZFN-0](/zfn/0-engineering-field-notes/) 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-N` numbering,
  `ZBP-N-Rk` requirement ids with build-time validation, semantic versioning with pinned major URLs,
  the `requires`/`provides` composition model, and the `blueprints.json` + raw-markdown + `llms.txt`
  machine interface.
