Skip to content

Documentation policy

Last updated: 2026-08-22 (created in the doc reset, D:doc-reset). This file is normative: it defines which docs are maintained, how they get updated, and how docs die. The failure mode it exists to prevent is the one the reset fixed — a STATUS.md whose top banner stayed fresh while the body froze six weeks behind the code.

  1. Living trackers — describe NOW; updating them is part of shipping. STATUS.md, DECISIONS.md, plans/OWNER-OPS.md, plans/BONDLAYER-FOLLOWUPS-WORKSTREAM.md, plans/LOOSE-ENDS-EXECUTION-SPECS.md, db/MIGRATIONS.md, CLAUDE.md, this file.
  2. Durable reference — architecture and contracts that change rarely: ARCHITECTURE.md, docs/architecture/**, docs/reference/**, docs/specs/**, docs/design/**, active plans/* specs. Must carry a dated status header.
  3. Dated researchdocs/Research/**: captures with a Captured: date and a “re-verify before relying on it” banner. Never “updated” — superseded by a new capture.
  4. Frozen archive — everything under archive/ and plans/archive/. Never edited, for any reason.
  • STATUS.md describes the present. Edit the section that changed, bump the single Last updated: date at the top. No banner stacking — do not prepend dated announcements; history belongs to DECISIONS.md and git. If a section no longer matches the code, fixing it is in scope for whatever PR broke it.
  • DECISIONS.md is append-only. Number claiming follows the anti-collision rules in CLAUDE.md (claim late, cite by slug until merged).
  • Plans open with a status header (Status: active|proposal|spec — YYYY-MM-DD). When the work ships, either annotate as-built (and say so in the header) or move the plan to the current archive set. A plan that self-declares “EXECUTED/CLOSED” should be archived in the same PR that closes it, not left to rot.
  • Migrations: every new file in db/migrations/ or workers/drizzle/ gets its row in db/MIGRATIONS.md in the same PR — the prod-apply ledger only works if it’s complete.
  • Docs describing future work must say so explicitly (proposal/spec/deferred). When the future arrives, the doc gets repaired or archived — a doc claiming something is “not yet executed” after it shipped is a bug.
  1. Create (or reuse) a dated set: archive/YYYY-MM-DD-<reason>/.
  2. git mv files preserving their repo-relative paths under it.
  3. Repoint inbound links in kept files (grep for the filename). Historical citations inside DECISIONS.md and plans/archive/** are left as-is.
  4. Add/extend the set’s README.md: what moved, why, what replaced it.
  5. Never edit anything already under archive/.
  • docs.matriz.designapps/docs-product (Astro Starlight). User-facing product docs, authored by hand in src/content/docs/. Written for customers: no internal codenames, no repo paths. Update when user-visible behavior changes.
  • dev.matriz.designapps/docs-dev (Astro Starlight). Engineering docs generated from repo markdown at build time by scripts/sync-content.mjs (manifest inside the script). Never edit src/content/docs/repo/** — edit the repo source file; add new pages by extending the manifest.
  • Both deploy from master via .github/workflows/deploy-docs-*.yml to Cloudflare Pages (projects matriz-docs / matriz-docs-dev). The docs apps are deliberately outside the pnpm workspace (own lockfiles) so Astro stays out of the main install; build them with pnpm --dir apps/docs-<x> build.

Before each launch milestone (and roughly monthly), run a docs audit: every class-2 doc’s status header is checked against code; anything failing moves through the archiving procedure. The 2026-08-22 reset is the template (archive/2026-08-22-doc-reset/README.md).