Documentation my agents can trust (and why it made me faster too)
Two earlier posts - a retrieval bug with twenty measured queries and a presence layer with its design alternatives - describe work finished weeks earlier. I wrote each in an afternoon, and I reconstructed nothing. Every number, every rejected option, every reason was already written down, in a predictable place, in a form I could trust had not drifted since.
That is not diligence. Left to my own habits I document like everyone else: enthusiastically at the start, then never again. The reason the records exist is that my projects follow a documentation standard designed for a reader with less context than any human: a coding agent landing cold. It turns out that optimizing docs for that reader makes them dramatically better for the human too - future-me is also a reader landing cold, just with more overconfidence.
The failure mode: nobody can tell what is true
Before standardizing, I surveyed my own repos. The evidence was embarrassing in a specific, countable way:
- Architecture decision records that only ever grew. One ADR had accumulated nine dated amendment sections and roughly 390 lines. Another was over 500. Reading one meant reading a journal and mentally replaying which parts still applied.
- A monolithic build-plan file, plus a 960-line "shipped" ledger, with no in-progress state and two sources of truth for "done" that disagreed.
- A "current task" note that was stale more often than not, because nothing ever forced it to be true.
For a human this is friction. For an agent it is poison: an agent reads the stale note and acts on it. The core question a repo has to answer - what is decided, what is to-do, what is done, what is in-flight - had no reliable answer anywhere.
Decisions are immutable; change means supersede
The cornerstone rule: an accepted decision record is never edited again. One decision per ADR, short. If the decision changes, you write a new ADR that supersedes the old one, and the old one's status flips to "superseded by NNNN" - a one-line metadata change, with the body untouched.
Before adopting it I ran a research pass across the published field, with each claim adversarially verified, and this was the single strongest convergence: four independent primary sources (AWS's prescriptive guidance, adr-tools, log4brains, MADR) all name immutability-plus-supersession as the cure for exactly the append-only journal sprawl my repos exhibited.
The deeper reason it works is trust, and trust is an agent requirement before it is a style preference. An agent quoting a mutable document has to wonder whether the text changed since the decision was made. An immutable record with an explicit supersession chain cannot lie about its history: if its status says accepted, the body means today what it meant the day it was accepted. That property is what let me lift design rationale into a blog post weeks later without re-verifying any of it against the code.
One companion rule keeps the immutability honest: as-built reality does not live on the ADR. The ADR records the decision and carries one pointer line to the plan that implemented it. How the implementation actually went - the surprises, the deviations - lives in the plan. Without this split, the pressure to "just add a note" reintroduces the journal.
Plans: stable task ids and a decision log
Work items live as plan files in an active/ directory, moving to
archive/ when done. The skeleton is boring on purpose: intent, approach,
a task checklist, and a decision log. Two rules carry the weight:
Task ids are stable forever. Tasks are T1, T2, ... assigned at
creation and never renumbered. A split or reordered task gets a fresh id; an
existing id never silently changes meaning. This sounds pedantic until you
have commits, session notes, and a current-task pointer all referencing
"T4" - renumbering would quietly repoint every one of them at different
work. Stable ids are what let a task be checked off with a one-line
"done, as built" note and trusted years later.
Small decisions go in the plan's decision log, not new ADRs. The threshold: an ADR is for a decision that outlives one work item. Everything local - "we fold the panel by section, not per-fact, because..." - lands as a dated entry in the plan that needed it. This keeps ADRs rare and heavy while still capturing the reasoning that debugging (or blogging) later depends on. My measurement-traps post was essentially written from these entries; the traps were recorded as decision-log entries the day they bit.
There is also a gate for honesty about ignorance: an unresolved question in
a plan is written as an explicit [NEEDS CLARIFICATION: ...] marker, and no
task it gates may start while one remains. An agent that hits the marker
asks instead of guessing. The alternative - the agent inventing an answer
with full confidence - is how plausible-but-wrong work happens.
One authoritative home per question
The piece that killed the most staleness is a small table: every question a reader might ask has exactly one place whose answer counts.
| Question | Authoritative home |
|---|---|
| Why is it built this way? | ADRs |
| What does it actually do? | The code |
| What is to-do / done? | The plan's task checklist |
| Who is working on what right now? | The ephemeral presence layer |
| What is this branch about? | A one-line pointer file into the active plan |
Two entries deserve comment. First, the code stays authoritative for what. The research pass surfaced the fashionable inverse - make the spec canonical and subordinate the code to it - and it failed adversarial verification outright. Docs own intent and rationale; behavior is what ships.
Second, in-flight status is deliberately ephemeral. "Session A is working on T3" lives in the live presence registry, never as a durable marker in the plan. A durable in-progress flag is precisely the thing that rots when a session dies mid-task - which is how my old current-task note became a professional liar. Durable files record what is true durably; live state lives somewhere that dies with the process.
Discipline that is not enforced is decoration
Everything above would decay in a month if it relied on my consistency, so it does not:
- New repos are scaffolded with the structure, templates, and glossary in their first commit, so the standard is the path of least resistance.
- A lint runs over the machine-readable invariants: frontmatter status values, task-id uniqueness, archive moves, pointer files that reference plans that exist, an ADR's implemented-by path that still resolves.
- The migration rule for old repos is forward-only: nothing is retroactively rewritten, but touching an old open item means first lifting it into a real plan. Old mess is contained, not laundered.
The lint matters more than it looks. It converts "we agreed to do this" into "the build tells you when you did not," which is the only form of agreement that survives contact with a busy week.
What transfers
- Write for the reader with the least context. An agent landing cold is the honest proxy for future-you. If an agent can reconstruct what is decided, done, and open from your repo, so can any human.
- Make records immutable and change explicit. A document that cannot have been quietly edited is the only kind either of you can quote without re-verifying.
- Give every question exactly one authoritative home, and be honest about which axis is durable and which is ephemeral. Most staleness is a durable file claiming to know live state.
- Stable ids beat tidy renumbering. Anything referenced from outside a document must never change meaning.
- Enforce mechanically or watch it drift. Templates make compliance cheap; a lint makes drift loud.
The compounding effect surprised me. Each layer - the memory system, the presence layer, this standard - was built to solve its own local problem, and the posts about them exist because the layers also happen to document each other. The infrastructure that keeps my agents honest turned out to be the same infrastructure that lets me tell you about it.