Skip to content

Docs as Memory

Every agent session ends in total amnesia. Every new session — yours tomorrow, your teammate's agent this afternoon, the CI agent tonight — reconstructs its understanding of the project from what's in the repo. Markdown docs are therefore not documentation in the traditional sense; they are the only persistent memory the system has. A fact that lives in a chat transcript is gone. A fact in docs/ARCHITECTURE.md is loaded into every future session that needs it.

This changes the economics of doc maintenance. Traditional docs rot because nothing reads them; agent-facing docs are executed — read at session start, trusted, and acted on. A stale doc is not a cosmetic problem, it is misinformation injected into every future run. The maintenance question shifts from "is this worth writing?" to "who updates it, when, and what breaks when they don't?"

The five surfaces

Each doc earns its place by answering questions a fresh session would otherwise answer wrongly. For each: what it must answer, what triggers an update, how you notice it's decayed, and who updates it. "Who" is usually the agent, in the same PR — humans forget; a prompt clause doesn't.

README.md — the human entry point

  • Must answer: What is this, how do I run it locally, where does everything else live. It is for humans (new teammates, future you); agents get their version in CLAUDE.md. Keep the two consistent by making both point into docs/ rather than duplicating content.
  • Update trigger: Setup steps change, a new top-level doc appears, the elevator pitch changes.
  • Decay symptom: A new hire's first day is spent in Slack asking how to get the dev server up.
  • Who updates: Human-owned; agents rarely need to touch it.

ARCHITECTURE.md — system shape, invariants, boundaries

  • Must answer: What are the major components and how does data flow between them; which boundaries must not be crossed ("billing never imports admin"); which invariants hold everywhere ("all writes go through the outbox — no direct queue publishes"). This is the doc that stops architecture erosion: agents violate boundaries they were never told exist.
  • Update trigger: Any PR that adds a component, moves a boundary, or creates/retires an invariant.
  • Decay symptom: The agent proposes designs that contradict the actual system; humans say "ignore the architecture doc, it's old" — at which point it is actively harmful and should be fixed or deleted that day.
  • Who updates: The agent, in the architecture-changing PR. Prompt clause:
text
If this change adds/removes a component, crosses a documented boundary, or
changes an invariant, update docs/ARCHITECTURE.md in the same PR. If it
violates a documented invariant, stop and flag it instead of proceeding.

DECISIONS.md / ADRs — why, so agents stop relitigating

  • Must answer: What was decided, what was rejected, and why — one record per settled question (docs/decisions/0002-no-orm-in-payment-path.md, or a single DECISIONS.md log for small repos). Without this, every session re-derives the "obvious" solution you already rejected: the agent helpfully suggests an ORM in the payment path, you re-explain the 2023 incident, forever. With it, one CLAUDE.md line — "read docs/decisions/ before proposing redesigns" — ends the loop.
  • Update trigger: Any decision you'd otherwise re-explain in chat. Especially decisions against the idiomatic default, because agents gravitate to idiomatic defaults.
  • Decay symptom: The same design debate recurs across sessions; or worse, an ADR documents a decision the code has since abandoned, and the agent enforces a dead rule.
  • Who updates: The agent drafts, you review — the reasoning must be your reasoning. Prompt clause:
text
We just decided <decision> over <rejected alternatives> because <reasons>.
Write it as docs/decisions/NNNN-<slug>.md using the ADR format in
docs/decisions/0001-*.md, status Accepted. Include what would make us revisit.

Full format in Decision Records.

TASKS.md — work state across sessions and handoffs

  • Must answer: What is in progress, what is blocked and on what, what's next, and — critically for agents — where the last session stopped ("migration script written and tested; cutover of invoice_lines reads NOT done, see spec §4"). This is the handoff document between session N and session N+1, whether the next operator is you, a teammate, or an agent resuming a large task.
  • Update trigger: End of every working session that touched task state; part of every task-completing PR.
  • Decay symptom: Sessions start with 20 minutes of re-discovering state; two sessions independently "finish" the same half-done task, divergently.
  • Who updates: The agent, always — this is the doc humans most reliably forget. Prompt clause:
text
Before finishing: update TASKS.md — mark what you completed, add anything
you started but did not finish (with the exact stopping point and next step),
and list new blockers you discovered.

CHANGELOG.md — what shipped and why it mattered

  • Must answer: What changed, when, at what version, and what a consumer/operator must do about it. For agents it doubles as recent-history context: "why did the auth flow change last week" is answerable without archaeology.
  • Update trigger: Every user-visible or operationally relevant change, in the shipping PR.
  • Decay symptom: Release notes get reconstructed from git log under time pressure; nobody can say what version introduced the regression.
  • Who updates: The agent, in the same PR. Prompt clause: Add a CHANGELOG.md entry under Unreleased: one line, imperative, noting any migration/config action required.

Summary table

DocMust answerUpdate triggerDecay symptomUpdater
README.mdWhat is this, how do I run itSetup or scope changesOnboarding happens in SlackHuman
ARCHITECTURE.mdShape, boundaries, invariantsBoundary/invariant-touching PR"Ignore that doc, it's old"Agent, same PR
DECISIONS.md / ADRsWhat we decided and whyAny decision you'd re-explainSame debate every sessionAgent drafts, human reviews
TASKS.mdState, blockers, stopping pointsEvery session / task PR20-minute state archaeologyAgent, every session
CHANGELOG.mdWhat shipped, action requiredEvery shipping PRRelease notes from git logAgent, same PR

The lifecycle

Memory only works if writes happen in the same transaction as the change. "We'll update the docs later" means the next session reads pre-change state as truth.

The enforcement point is the PR template and the prompt, not discipline: a standing CLAUDE.md line — "update ARCHITECTURE.md / TASKS.md / CHANGELOG.md in the same PR when the change affects them" — plus a reviewer habit of treating missing doc updates like missing tests.

The stale-docs failure

Staleness is worse than absence. With no ARCHITECTURE.md, the agent explores the code and builds a mostly-correct model. With a stale one, it trusts the doc over its own exploration — docs read as authoritative intent — and produces work that's consistent with your system as of eight months ago.

Concrete shape of the cost: ARCHITECTURE.md still says "invoices are generated synchronously in the request handler." Three months ago that moved to a queue-based worker. An agent asked to "add PDF attachments to invoices" reads the doc, wires PDF generation into the request path, and the tests it writes pass — against the synchronous path that still exists as dead code. Review catches it (or production does). Cost: one rewritten PR, one confused reviewer hour, and — the compounding part — every future session inherits the same landmine until someone fixes the line.

Triage rule: a doc you won't maintain should be deleted, not kept. An absent doc makes the agent look at the code; a wrong doc makes it confidently not look. And the fix is cheap when you catch it — the moment anyone says "that doc is out of date," the response is a two-minute prompt: docs/ARCHITECTURE.md says invoice generation is synchronous; the code in src/workers/invoice.ts says otherwise. Update the doc to match the code, and flag anything else in the doc that contradicts what you can verify.

A field manual for AI-native software engineering.