AI-written docs drift the moment code moves, and confident inaccuracy is worse than none. Generate from real signatures and test the examples.
AI-generated documentation is fast to produce and confidently wrong the moment the code moves underneath it. Name the failure mode: drift, not clumsy prose. The doc keeps describing a function signature, a config key, or a return shape that changed three commits ago, and it describes the old behavior in clean, authoritative sentences. A reader trusts it because it reads like reference material, follows it, and ships a bug the docs actively invited.
Confidently wrong documentation is more dangerous than no documentation at all. A blank page makes a reader go read the code. A polished, out-of-date page tells the reader they do not need to, and they believe it. The prose quality that makes AI documentation attractive is exactly what makes its inaccuracy costly, because fluency is the signal humans use to decide something is trustworthy, and a language model produces fluency whether or not the underlying claim is still true.
The fix is not to stop generating docs. It is to treat a doc as an artifact that must be verified against the code it describes, the same way a diff must be verified against the spec it claims to satisfy. That thesis points somewhere commercial: we build TLM Forge, a process layer that gates AI-written changes before they ship. So read the vendor-neutral argument as the load-bearing part, and read the one product section knowing where it comes from.
Why AI docs drift faster than the code they describe
Documentation drifts whenever the code changes and the doc does not, and AI generation widens that gap in two directions at once. It lowers the cost of producing docs, so more of them exist, and it raises the volume of code changes, because the same agents write features faster than a human alone would. More documented surface plus more frequent change means more places where a description and its subject silently disagree. Drift is not a new problem invented by language models. Docs have always rotted. What is new is the rate, and the polish that hides it.
There is a second, subtler source. An AI writing a doc reasons from the prompt and the snapshot of code in its context, not from a live read of the current signatures. If the context is stale, or the model infers a plausible parameter that was renamed, or it recalls how a popular library "usually" behaves, the doc encodes a guess. That is the same generative mechanism behind hallucinated APIs: a confident description of a method that does not exist, or no longer works the way described. In prose the guess is harder to catch than in code, because there is no compiler to reject a sentence.
Confident inaccuracy is the actual failure
The danger is not that AI docs are occasionally wrong. It is that they are wrong in a register that signals correct. Human-written docs that lag behind code often show their age: a TODO, an inconsistent tone, a section that trails off. AI-generated reference reads uniformly finished, so a stale claim and a current one look identical on the page. The reader has no surface cue that one paragraph describes today's behavior and the next describes last month's. Every sentence carries the same authority, which means the wrong ones borrow credibility from the right ones.
A missing doc costs a reader a trip to the source. A confidently wrong doc costs them a bug, plus the time to discover the doc lied, plus the erosion of trust in every other doc in the repo. The blank page is honest about what it does not know. The fluent, stale page is not.
This is why "the AI wrote our docs, so coverage is up" is a misleading metric. Coverage measures how much surface has a description attached, not whether the description is true. A repository can go from 40 percent documented to 95 percent documented and become harder to work in, if the added 55 percent is prose that no gate ever checked against the code. Untested documentation is a liability that grows with its own volume.
How drift actually happens
Drift is not one event. It is a set of small, recurring divergences, and naming them makes them catchable.
- A signature changes: a parameter is renamed, reordered, or made optional, and the doc still lists the old shape that a caller copies verbatim.
- A default flips: a config value or flag changes its default, the behavior changes for everyone, and the doc still states the old default as fact.
- A return shape moves: an endpoint adds a field or nests its payload, and the documented example no longer parses the way a reader expects.
- An example goes stale: a code sample that once ran now references a deleted helper or an old import path, and nothing ever re-runs it to notice.
- A behavior is inferred, not observed: the model describes what a function "should" do from its name, and the description was never true.
- A deprecation is missed: a method is marked deprecated in code, but the doc keeps recommending it as the primary path.
Every item on that list shares one property: the doc and the code are two separate artifacts that were allowed to change independently. Nothing in the workflow forced them to agree. The disciplines that fix drift all attack that one property, by tying the doc back to the code so the two cannot diverge silently.
| Doc property | Prose written from a prompt | Generated from the artifact |
|---|---|---|
| Source of truth | The model's snapshot of the code, possibly stale | The live signatures, schema, or types at build time |
| What happens when code changes | Doc keeps describing the old behavior until noticed | Regeneration reflects the change, or the build flags it |
| How a wrong claim is caught | A human happens to re-read and remember the truth | A failing test or a schema mismatch fails the pipeline |
| Examples | Illustrative snippets that no tool executes | Executable samples run as tests on every commit |
| Failure register | Confident, authoritative, indistinguishable from correct | Loud: the build breaks or the diff shows the drift |
Discipline one: generate from the artifact, not the vibe
Where a doc can be derived mechanically from the code, derive it. Reference documentation for a public interface is the strongest case, because the interface is already a structured artifact: signatures, types, and schemas that a tool can read directly. An OpenAPI description turned into docs by a tool like Swagger UI produces an interactive console generated from the API contract itself, not from a description of it, so the reference tracks the definition instead of a paraphrase of the definition. The same idea drives type-aware doc generators that read source signatures at build time.
Sources: Swagger: Documenting APIs with OpenAPI
This does not eliminate AI from the process. It relocates it. Let the model write the parts that genuinely need judgment, the explanation of why an interface exists, the how-to guide that sequences several calls, the tradeoff a reader should weigh. Generate the parts that are pure fact, the parameter list, the return type, the enum values, from the code. The Diátaxis framework is a useful map here: reference is the mode most safely machine-derived, while tutorials, how-to guides, and explanation are where a model's prose adds value and where a human still verifies the claims.
Sources: Diátaxis: a systematic framework for technical documentation
Discipline two: prefer examples that execute
An executable example cannot lie for long, because something runs it. This is the single highest-impact move against drift: replace prose claims about behavior with code samples that a test harness actually executes and asserts against. Python's doctest module searches for pieces of text that look like interactive sessions and executes them to verify they work exactly as shown, so a docstring example that stops matching reality fails the suite. Rust's rustdoc runs the code examples in documentation comments as tests, precisely so that examples within the documentation stay up to date and working.
Sources: Python doctest module documentation, Rust: documentation tests in rustdoc
The mechanism is what matters, not the specific language. When an example is executable, drift converts from a silent inaccuracy into a loud build failure. The doc can no longer describe a return value the function stopped producing, because the assertion on that value would fail and the pipeline would go red. A prose sentence claiming the same thing sails through untouched. Every claim you can express as a runnable, asserted example is a claim that verifies itself on every commit instead of waiting for a reader to catch it.
When an AI drafts a doc with a code sample, do not accept the sample as illustration. Move it into a doctest, a rustdoc example, or a tested snippet in your example suite, and run it in CI. If the sample cannot be made to run, that is the signal: either the example is wrong, or the thing it describes is not real. Both are worth knowing before a reader finds out.
This is the documentation version of a lesson that already applies to code the agent writes. A passing example proves the behavior at least once; an unrun example proves nothing. The reasoning in testing AI-generated code carries over directly: treat the green result as the evidence, and treat unexecuted prose, in docs as in code, as an unverified claim.
Discipline three: review the doc in the same gate as the code
Tie every doc change to the same review and pipeline that governs the code it describes. This is the docs-as-code practice: write documentation with the same tools as code, version control, code review, and automated tests, so a doc edit travels through the same pull request, the same reviewers, and the same checks as a code edit. When the doc lives beside the code and moves through one gate, a reviewer looking at a changed function sees the changed doc in the same diff, and a stale doc becomes a reviewable defect rather than an invisible one.
Sources: Write the Docs: Docs as Code
The failure to fix is a workflow where docs are a separate track: written later, reviewed by different people, or not reviewed at all. That separation is exactly what lets the doc and the code diverge, because nothing in the process forces them to change together. If a change to a function's behavior is allowed to merge without the change to its documentation, drift is not a risk, it is the default outcome. The discipline is structural: make the doc part of the unit of change, so the same gate that judges the code judges its description.
That gate is what TLM Forge is built to enforce for AI-written work. The same spec-and-review discipline that governs code should govern the docs an agent writes: a claim in a doc gets verified, not trusted. A spec audit fixes what a change is supposed to do before an agent writes either the code or the doc, independent review agents that did not draft the diff examine the doc changes alongside the code changes rather than waving them through, and the convergence gate blocks shipping until critical issues reach zero. A confidently wrong doc is a critical issue, and the point of the gate is that fluency does not earn a pass.
Part of what lets docs drift is lost context: the reason an interface exists, the decision a doc encodes, the fact that a default was deliberately chosen. When that context evaporates between sessions, a later agent regenerates a doc from a guess. A private, persistent memory layer such as MemX keeps those decisions durable across sessions, so the description of a system stays anchored to why it was built that way instead of drifting toward whatever the model infers this time.
AI-generated docs are worth having, coverage of an interface is useful, and no one should ship a system with nothing written down. The claim is narrower: a doc is only an asset once it is verified against the code, and verification has to be built into how docs are produced and merged, not left to a reader's luck. Generate the factual parts from the artifact, make examples execute, and review docs in the same gate as code. The alternative is a repository full of authoritative prose that quietly describes a system that no longer exists. This connects to the broader case for spec-driven development: a doc, like a diff, should be checked against the intent it claims to serve.
Frequently asked questions
01Why is AI-generated documentation risky if it reads well?
Because fluency is not accuracy. AI docs read uniformly authoritative whether or not the underlying claim is still true, so a stale sentence looks identical to a current one. Readers trust polished prose and follow it, which makes a confidently wrong doc more costly than a missing one that sends them to read the code.
02What is documentation drift?
Documentation drift is when code changes and the doc describing it does not, so the two silently disagree. A renamed parameter, a flipped default, or a changed return shape leaves the doc describing old behavior. AI widens the gap by producing more docs over faster-changing code, so drift accumulates in more places.
03How do you keep AI docs from going out of date?
Tie the doc to the code so they cannot diverge silently. Generate reference material from live signatures or an OpenAPI schema, turn code samples into executable tests that fail when behavior changes, and review doc edits in the same pull request and pipeline as the code they describe.
04Are executable documentation examples actually tested?
Yes, in tooling built for it. Python's doctest executes the interactive examples in docstrings and checks their output, and Rust's rustdoc compiles and runs the code examples in documentation comments as tests. When an example stops matching the code, the suite fails, so drift becomes a loud build error instead of a silent inaccuracy.
05Is having AI write docs better than having no docs?
Only if the docs are verified. Unchecked AI docs can be worse than none, because a blank page makes a reader consult the source while a fluent, stale page tells them not to. AI documentation becomes an asset once it is generated from the code or gated by tests and review, not before.