On this page
Code that’s wrong fails a test, throws an exception, pages someone. Documentation that’s wrong does nothing at all. It just sits there, confidently describing a system that no longer exists, waiting for someone — or something — to believe it.
Two of my own projects taught me how expensive that belief has become, now that the primary reader of documentation is increasingly an AI agent that takes every word literally.
Case one: the CLAUDE.md that described a ghost
A trading bot of mine has a CLAUDE.md — the standing instruction file that AI coding agents read before touching a repo. It’s supposed to be the codebase’s self-description: what the modules do, how to run things, what the constraints are.
An audit of the repo against its own doc found the doc was lying in three separate ways:
- Dead modules described as live. Components the doc presented as part of the architecture that nothing imported anymore.
- Zeroed costs presented as real. Cost figures the doc treated as meaningful that the code had since hardcoded to zero — so any reasoning built on those numbers was reasoning about nothing.
- A documented docker mode that was broken. The doc confidently explained how to run the system in a mode that did not currently work at all.
Here’s why this class of rot is newly dangerous: a human reader skims docs with healthy suspicion, but an agent-facing doc is load-bearing. The agent reads that docker mode exists and plans around it. It reads the dead module as live and extends it. Every future AI-assisted session on that repo was being briefed by a fiction — which means the doc wasn’t just stale, it was actively manufacturing wrong work.
Case two: the mock payment RPC that was still in production
A separate product of mine — a job-application automation app with a mobile client and a backend — had drifted far past its own documentation during a fast pivot. So I ran an audit with parallel read-only agents, each assigned a slice of the codebase, with one job: re-derive what the system actually does from the code alone, ignoring what anything claims.
Among the findings: a dev-only mock-payment RPC still live in production. A stub that existed so development could simulate payment success had survived every deploy since, sitting in the production backend, callable.
No document would have surfaced that, because no document knew about it — that’s the point. The stub existed precisely in the gap between what the docs described and what the code contained. Everything dangerous lives in that gap.
The thesis: docs are code that never runs
The reason documentation rots is structural, not moral. Code has a feedback loop — compilers, tests, runtime errors, users. Docs have none. A doc is a program executed only in readers’ heads, and readers don’t file crash reports; they just quietly absorb wrong beliefs. Teams don’t “forget” to update docs — there is simply no mechanism that forces the update, so under deadline pressure the doc always loses.
For years the industry’s honest answer was “read the code, trust nothing,” which worked because reading code was every engineer’s baseline skill and docs were understood to be decorative.
Two things have changed. First, agents made docs load-bearing again — CLAUDE.md and its cousins are executed, every session, as premises. A lie in an agent-facing doc has the blast radius of a lie in a config file. Second, agents made the audit cheap. Re-deriving a system’s true behavior used to cost days of careful human reading, which is why it never happened. A fleet of read-only agents does the reading in an afternoon; the human judges the findings. The same technology that raised the cost of doc rot also collapsed the cost of detecting it. It would be careless to accept the first and not use the second.
The rules I now run
1. Audit the doc against the code on a cadence, not on suspicion. Suspicion arrives too late — you get suspicious after the agent builds on the dead module. For active repos I periodically run the exercise from case two: agents re-derive reality from code, then diff that against what CLAUDE.md claims. The diff is the work list.
2. Docs describe; they must also date. A claim in an agent-facing doc that hasn’t been re-verified in months is a rumor. Cheap discipline: when an audit confirms a section, note it. When a section can’t be confirmed, delete it — a missing doc sends the reader to the code, which is honest; a wrong doc sends them somewhere worse.
3. Every change with a blast radius updates the doc in the same change. Not a follow-up ticket — the same commit. The doc update is part of the diff or the drift starts immediately. This is the one place where AI review helps enforce it: “does this change invalidate anything in CLAUDE.md?” is a checkable question.
4. Deleting beats describing. The mock-payment RPC needed removal, not documentation. Half of “doc drift” findings are really code that should not exist — dev scaffolding, dead modules, broken modes. The audit’s best outcome isn’t a better doc; it’s a smaller system that needs less doc.
The uncomfortable summary
Both of these were my own projects. Nobody else rotted these docs at me — drift is just what documentation does when nothing pushes back. The fix isn’t discipline theater or a wiki nobody reads. It’s accepting that a doc is a claim, claims need verification, and verification finally costs almost nothing. The tools that made stale docs dangerous are the same tools that make honest docs cheap. Use them in that order.