AI-REPO-STANDARD.md — structure a repo so AI sessions compound


A portable standard for the repo side of AI-assisted development. Its companion, AI-DEVELOPMENT.md, covers the working relationship — how the human and the AI interact, the standards a change is held to, the pitfalls. This file covers the machinery you commit to the repo so that every AI session inherits everything the previous sessions learned, instead of starting from zero and re-making old mistakes.

Distilled from a repo where this is working well (the bread monorepo). Drop this file into any repo and build the kit below.

One floor up, LOOP.md owns the workflow that runs across every repo — the work-triggered heartbeat, the thin-CLAUDE.md kit shape, the accountability contract. This file owns what one repo commits; LOOP owns how the estate is operated the same way. The thin-kit shape LOOP defines is the front-door minimum for the CLAUDE.md described in §2.

The one-line version: treat every AI mistake as a bug in the repo's docs or architecture, and fix it where it compounds — in a committed contract, not in the chat.


0. The core principle everything else serves

An operator tripping on the system measures the system's clarity, not just the operator's. If the AI got something wrong building here, suspect the docs or the design first. The bar: the repo must be easy for a human and even more legible and operable for an AI.

A chat session is disposable; the repo is durable. Anything learned in a session — a decision, a trap, a convention — is lost unless it lands in a committed file the next session will actually read. Every pattern below is a different answer to "where does this learning go so it can't be lost?"


1. The file kit

FileJobOne-line test that it's working
CLAUDE.md (root)Onboarding + operating rules. The front door for any AI or human.A fresh session can start real work without asking orientation questions.
CLAUDE.md (per subsystem)That area's non-negotiables + its hard-won lessons.The same mistake never ships twice in that subsystem.
AUDIT.mdA repeatable alignment runbook: does the repo still obey its own rules?Any session (human or AI) can run it and produce the same findings.
DOCS.mdThe map: where every doc lives and what altitude it covers.No one greps for "where is the doc about X."
ROADMAP.md (or PLAN.md)The canonical execution plan; read before substantive work.Parallel sessions don't drift or duplicate effort.
AI-DEVELOPMENT.mdThe interaction playbook (portable, copied between repos).New collaborators (human or AI) work the same way.

Small repo? Collapse the kit: one CLAUDE.md with an audit section and a plan section. The jobs are the invariant, not the file count.


2. The root CLAUDE.md — onboarding, not a config dump

The strongest CLAUDE.md files read like onboarding for a new senior hire, and they follow a consistent shape:

  1. A self-maintenance contract in the first lines. *"Read this first, then the docs it

points to. Keep it accurate: if you change how the project works, update this file too."* This single sentence is what keeps the file alive instead of rotting.

  1. What this is — one paragraph plus (if layered) a small dependency diagram. The AI's

mental model of the architecture forms here; get the direction of dependency into it early.

  1. A reading order, why-first. Numbered: philosophy/intent doc first, then the rulebook,

then the reference docs. An AI that knows why the rules exist applies them to cases the rules never anticipated. Name the single source of truth explicitly ("the SSOT for X is path/to/file.ts") and name the reference example ("the reference screen is /, the hero desk").

  1. Commands — the exact dev/check/test invocations, nothing the AI has to guess.
  2. Non-negotiables — a short list of the rules that must never break, each one line,

pointing at the full rule elsewhere. Not the whole rulebook: the five things that, if violated, poison everything downstream.

  1. The sync table (§3) and the definition of done (§8).
  2. Working notes — commit etiquette, environment quirks, "run from repo root."

What it is not: a style guide, a changelog, or a dump of everything. Length is a cost the AI pays every session — every line must earn its place, and detail belongs in the docs the reading order points to.


3. The sync table — "when you change X, also update Y"

The single highest-leverage pattern. Drift — code that outgrew its docs, a copied constant that diverged, a test that no longer covers the behavior — is the default failure mode of AI-speed development, because the AI happily changes X without knowing Y exists.

The fix is an explicit table in CLAUDE.md mapping every kind of change to everything that must move with it:

You change……also update
A public verb / API actionthe type/registry → its handler → unit + integration test → the contract doc
A componentits colocated doc → a test for any behavior → the catalog/index
A design token / config valuethe one source file only (never per-consumer)
User-visible behaviorthe doc that describes it, in the same change
A plan/roadmap steptick it in the plan → sync the affected layer's plan
A notable decisiona memory / decision record, so the next session inherits it

Build the table from your repo's real change-kinds, and grow it: every time drift is discovered, that's a missing or incomplete row — add it. The table turns "keep docs in sync" from a virtue into a checklist an AI can walk mechanically.


4. Subsystem CLAUDE.md + the hard-won lessons section

Each major subsystem (layer, package, app) carries its own CLAUDE.md, seeded from a shared starter template, with two payloads:

  • That area's non-negotiables — the local rules (import boundaries, file conventions,

idioms) that a session working only here must know.

  • Hard-won lessons — do NOT repeat these. The most valuable section in the whole kit.

The lessons format that works:

  • Numbered, and framed as root causes, not incidents. Not "we had a bug in the

spotlight" but "if a treatment needs a new rule per surface kind, the treatment is at the wrong altitude — attach it to the geometry, not the element."

  • Symptom → cause lines for the traps that look like something else: "a demo that

does nothing for a beat, or can't be stopped = dropped early ops, not logic." This is what lets a future session diagnose in one read instead of one afternoon.

  • A shared root named up front when the lessons rhyme: "these all share one root —

reaching for a bespoke mechanism instead of the vocabulary that already exists, and contracts that fail silently."

  • The meta-lesson stated explicitly: if you (human or AI) keep getting something wrong,

the contract is unclear — fix the contract or add a test that catches misuse; don't just patch the instance.

Write a lesson the moment its bug is fixed, while the causal chain is fresh. A lesson that only exists in a chat transcript is a lesson the repo never learned.


5. AUDIT.md — the alignment runbook

A committed, repeatable procedure that checks the repo still obeys its own rules. The design rules that make it work:

  • The canon defines "aligned"; the audit only references it. AUDIT.md points at

CLAUDE.md and the concept docs — it never restates them. If a check and a canon doc disagree, the canon wins and the audit gets fixed. (Single source of truth applies to the audit itself.)

  • Every check is a command plus a pass bar. Not "check layering" but the actual grep

with the expected output ("expect none"). Mechanical checks are checks an AI can run identically every time:

  # layering purity: lower layer imports nothing from upper → expect zero hits
  grep -rn "import" lower/ --include=*.ts | grep -iE "upper|app"
  # hardcoded values that should be tokens/config → expect zero hits
  grep -rnE "#[0-9a-fA-F]{3,6}|rgb\(" components/ --include=*.css
  • A findings template: ✅ passing / ⚠️ findings as file:line — what — fix-or-flag /

deferred-and-accepted. "Done" = all green + every finding fixed or explicitly flagged.

  • When to run: before a commit, after a big change — and periodically as a **full pass

with your strongest model**, including an adversarial review of recent landings. Fix the findings in the same session and commit the report; the report doubles as a dated snapshot of the repo's health.


6. Single source of truth + projections

Every fact gets exactly one home; everything else points at it or summarizes it — a projection, never a fork. Concretely:

  • Concept docs are the source; landing pages, READMEs, and teasers are projections that

must "summarize the source truly and add nothing the source doesn't have."

  • A capabilities list per subsystem ("what X gives you": heroes + also-rans) as the

single source for what it does — with an audit check that walks code against the list both ways: a shipped capability missing from the list is a finding (buried), a listed capability that no longer exists is a finding (stale).

  • DOCS.md maps it all, one table: doc → where it lives → what it is → what altitude.

Why this is an AI concern and not just hygiene: an AI reads everything and trusts what it reads. Two divergent copies of a truth don't just confuse it — they make it confidently wrong. SSOT is what makes "read the docs first" safe advice.


7. The hardening ladder — make rules machine-checkable

When a rule matters, promote it up this ladder as far as it will go:

  1. A comment in one module — worthless as a contract; it gets reinvented, wrong.
  2. A committed doc — the floor. Now every session sees it.
  3. A grep with a pass bar in AUDIT.md — now it's verifiable, identically, by anyone.
  4. A runtime/boot guard or conformance test — a startup check that warns on vocabulary

drift; a test that asserts the usage contract, not just that the page renders.

  1. Designed out — the top rung. Restructure so the mistake is impossible: the invalid

state can't be expressed, the copied constant has nothing to copy.

Two corollaries worth stealing verbatim:

  • Contracts must not fail silently. A no-op on invalid input looks identical to success

from the outside — to an AI especially, which can't squint at the screen. No-op and report, always.

  • A knob that changes nothing is a disconnected knob, not a wrong value. Before tuning

any config/token, verify the mechanism actually consumes it — measure the behavior; if turning the knob produces no measurable change, the mechanism is broken and the tuning session is over. Never ship a named behavior ("glide", "retry", "cache") the mechanism can't render — documented behavior with no implementation is the worst drift, invisible to typecheck and tests.


8. Definition of done — one sentence, enforced everywhere

Done = code + the right test tier(s) + docs synced (walk the sync table) + checks green + a memory/decision record if a decision was made.

State it in the root CLAUDE.md and repeat it in every subsystem CLAUDE.md. It's the counterweight to the AI's natural failure mode of declaring victory at "it compiles."


9. Memory discipline (agent memory vs. committed docs)

Two tiers, with a promotion rule:

  • Agent memory (Claude's per-project memory) — decisions, preferences, context.

Write one whenever a real decision is made or something non-obvious is learned; the next session inherits it automatically. If a recalled memory contradicts the code, trust the code and fix the memory.

  • Committed docs — anything durable and repo-worthy (a rule, a lesson, a convention)

gets promoted out of memory into CLAUDE.md / the lessons section / the rulebook. Memory is a scratchpad for the pair of you; the repo is the institution.

And make "read the plan first" a rule: substantive work starts by reading ROADMAP/PLAN so concurrent sessions don't drift — and landing a step means ticking it there in the same change.


10. Let the AI show its work

If the project has a UI, an AI in a headless session can't point at a screen — so build the channel once: a scripted command (npm run shots / Playwright) that boots the app, captures the key screens and states (not just pages — the mid-interaction moments), and writes a self-contained gallery the AI can publish or link. Then make it a rule in CLAUDE.md: use it whenever the user asks to "see" something or anything visual changed.

The general form, UI or not: the repo should give the AI a way to produce evidence — screenshots, audit reports, test output — because "show, don't tell" only works if showing is cheap.


11. Index the codebase for the AI

Grepping and re-reading raw files is the AI's default way to orient — and its single biggest token sink, plus a source of partial-picture mistakes (it acts on the three files it read, not the ten that mattered). Commit an index that answers structural questions directly: a whole-repo knowledge graph (I use graphify — local tree-sitter AST, zero API cost) the AI queries — "what connects X to Y", "where does this abstraction live", "what's impacted if I change this" — and gets back a scoped subgraph instead of a pile of files. Measured ~20x fewer tokens per codebase question on the reference repo.

The committed machinery, mapped to this standard's own patterns:

  • A CLAUDE.md rule that teaches query-first — "for codebase questions, run

graphify query before grepping; read raw files to change lines, not to find them." Without the rule the index sits unused; this is the §7 hardening ladder, rung 2.

  • Freshness on the git post-commit hook, never the build or test step. Commits are the

right granularity; build and test fire constantly on unchanged code, so the graph would rebuild for nothing. Incremental AST updates are free (no LLM), so the hook is cheap. A stale index is worse than none — it lies with confidence, the §6 SSOT failure mode.

  • Git-ignore the generated output. It's per-machine and derived, not canon. That also

keeps a foreign toolchain (graphify is Python) out of the app — it's a dev aid, never a runtime dep. Regenerated on clone via the hook install.

The reusable copy-paste setup prompt lives in AI-DEVELOPMENT.md §4 ("Index the codebase for the AI"). The index is an orientation layer, not a substitute for reading the actual lines you're about to change — same as a map is not the territory.


12. Adoption checklist

Day one (an hour):

  • [ ] Copy in AI-DEVELOPMENT.md (the interaction playbook) and this file.
  • [ ] Write the root CLAUDE.md: what-this-is, reading order, commands, five

non-negotiables, definition of done, the self-maintenance line.

  • [ ] Start the sync table with the 3–4 change-kinds you already know about.

First month (as the work happens, not as a project):

  • [ ] First recurring AI mistake → start the hard-won lessons section with it.
  • [ ] First drift discovered → add its row to the sync table; add a grep for it to a new

AUDIT.md.

  • [ ] Subsystems grow distinct rules → give each its own CLAUDE.md from a shared starter.
  • [ ] More than a couple of docs → add DOCS.md.
  • [ ] Codebase big enough that grep/re-read dominates a session → stand up the AI index

(§11): build the graph, add the query-first CLAUDE.md rule, wire the post-commit hook.

  • [ ] Run the first full audit with your strongest model; fix findings in-session; commit

the report.

Steady state: the kit maintains itself, because the operating rules include maintaining it — that's what the sync table, the self-maintenance contract, and "fix the cause, not the instance" are for.


Living document, same rule as everything it describes: when how this works changes, update this file in the same change.