Version: Current
Historical release snapshot. These docs are frozen. Read current docs.
ADR: the documentation iteration engine
ADR: the documentation iteration engine
Section titled “ADR: the documentation iteration engine”Context
Section titled “Context”The site had 30+ pages and no way to answer “what is missing?”. Three failure modes were observed:
- the API contract is generated from the gateway’s route tables, but the docs site described it by hand, so a new route reached the contract without a page;
- code examples were never executed, so a command that stopped working stayed on the page;
- nothing compared a page’s last edit with the code it describes, so a stale page looked exactly like a current one.
Decision
Section titled “Decision”- Generate every reference from its source of truth. The OpenAPI document,
the protobuf services, the CLI dispatcher, the flags and the error taxonomy
are read by
tools/docs-engine/generate.mjs, and the gate fails when the page and the source disagree. - Measure the rest. A detector diffs the surface inventory against the
published pages, runs the examples a page opts into (
exec), reads the sidebar, the changelog and an optional support-signal file, and ranks the result. - One page per cycle, recorded. Each cycle writes one decision card, one
page, and one entry in
docs/ITERATION.mdplus a row invar/docs-engine/cycles.db. - Prose needs a reviewer; reference regeneration does not. A generated reference page is mechanical, so it may land on a green gate. A tutorial or a runbook is a judgement about what a reader needs, so it lands only with an approval recorded on its card.
- Absence is reported, not invented. A missing source repository is a note.
The scheduled cycle passes
--require-sourcesso an absence cannot be mistaken for a clean run on the docs host.
Consequences
Section titled “Consequences”- A contributor adding a route to the gateway must run
npm run docs:generatebefore the docs gate passes. That is the cost of the reference never drifting. - The engine adds ~2,000 lines of Node with no dependencies. It cannot use a build tool, because it must run before the build.
- The cycle store is SQLite, not PostgreSQL, because the engine runs on a laptop and on the docs host with no shared database, and a cycle record is not worth a network dependency.
- Coverage is a floor, not a proof: a mention counts. The “mentioned, no section” detector exists to keep that honest, and the panel reports both.
Alternatives considered
Section titled “Alternatives considered”- A docs-as-code linter only. Focuses on formatting and links; cannot see a route that reached the server and no page.
- A generated site with no hand-written pages. Would remove the drift but also remove the tutorials and runbooks, which are the pages that answer a question the contract cannot.
- An LLM writing pages from the diff on every merge. Rejected as the default: an unreviewed prose change is indistinguishable from a correct one, and the card/review step is what makes the cycle auditable. The model is allowed to draft; it is not allowed to merge prose.