Every team has the doc that lies. The README that describes a setup step removed a year ago. The architecture page showing three services when there are now five. The onboarding guide that sends new people to a repo that got split. Nobody wrote it wrong. It was true the day it was written, and then the code moved and the doc didn’t.
The usual explanation is discipline. If people just updated the docs when they changed the code, the docs would be fine. This is comforting and wrong. Documentation rots for a structural reason, and no amount of discipline fixes a structural problem for long.
Why docs rot, precisely
A traditional doc is a second copy of the truth. The truth lives in the code, the config, the running system. The doc is a separate artifact, in a separate place, that describes that truth in prose. The two are connected by exactly one thing: a human remembering to update the second copy when the first one changes.
That link is the defect. It is manual, it is nobody’s explicit job, and it fails silently. When someone ships a change and forgets the doc, nothing breaks, no test goes red, no alert fires. The doc just becomes a little less true, quietly, and it keeps looking authoritative the whole time. Rot is not an event you can catch. It is the default state of any artifact whose only tie to reality is human memory.
This is why the standard fixes do not work. A better template is still a second copy. A stricter review process is still leaning on humans to remember. A nicer wiki is a prettier place for the same rot. You are optimizing the copy when the problem is that a copy exists at all.
The AI era makes this sharper in two directions at once. Agents now read your docs as context and answer with total confidence from whatever the doc says, so a rotted doc doesn’t just mislead a new hire, it poisons every agent that trusts it. And agents write code faster than any human can hand-update the prose describing it, so the gap between code and doc widens faster than the old discipline can close it.
The fix is to remove the copy, not to update it faster
Living documentation is not “documentation you are better at maintaining.” It is documentation with the human-in-the-loop taken out of the update path. The doc stops being a second copy and becomes a projection of the first.
The move is to derive the docs from the system instead of writing them beside it. If the description of your API is generated from the actual routes and types, then when a route changes the description changes, because they are the same fact rendered once. If your architecture view is read off the real code knowledge graph, the map of what actually calls what, then a new service shows up in the view the moment it shows up in the code, without anyone drawing a box. There is no second copy to fall out of sync, because there is no second copy. There is the system, and a view of it.
“True” stops being a chore you keep failing to do and becomes a property of how the doc is produced. You cannot forget to update a projection. It updates because the thing it projects updated.
Not everything can be derived, and it is worth being clear about the line. The what and the how of a system, the routes, the call structure, the dependencies, the shape, can be read off the code. The why usually cannot, because the reason a decision was made is not visible in the code that resulted from it. That part has to be captured deliberately, as the decision is made, and then attached to the code it governs. Which is a different discipline from writing prose after the fact, and a durable one, because it is recorded once at the moment the knowledge exists rather than reconstructed later from memory. This is the same reasoning behind a product brain that maintains itself: capture the why at the moment of the decision, derive everything else from the system.
Docs-as-code is a half-measure, and worth understanding why
The most common step teams take toward living docs is docs-as-code: put the documentation in the repo, in markdown, next to the code, reviewed in the same pull requests. This is a real improvement. The docs travel with the code, they go through review, and a diff at least gives someone the chance to notice the prose is now wrong.
But look at what it actually fixes. It moves the second copy closer to the first and improves the odds that a human notices the drift. It does not remove the second copy, and it does not remove the human. The markdown file describing the architecture is still a hand-written parallel artifact that has to be updated by someone who remembered to, in the same commit, correctly. Docs-as-code makes the rot more catchable. It does not make it structurally impossible. You still have two things that can disagree, and you are still relying on discipline to keep them agreeing, just with a better chance of catching a lapse in review.
Living documentation is the step past docs-as-code. Keep the reviewed-in-repo discipline for the prose that genuinely has to be written, the why, the intent, the things no system can derive. But for everything that can be read off the code, stop writing a parallel copy at all and render a view of the system instead. Docs-as-code is where you put the copy in a good place. Living documentation is where you delete the copy for everything that shouldn’t have been a copy.
What living documentation is not
It is not auto-generated prose that no one reads. A wall of machine-written text describing every function is not living documentation, it is noise with a fresh timestamp. The value is not that a machine wrote it. The value is that it is a faithful projection of the real system, so what it says is what is true.
It is also not a replacement for judgment about what is worth documenting at all. Deriving a view of everything is easy and mostly useless. The skill is choosing which projections matter, the API surface, the architecture, the provenance from code back to decisions, and letting those stay true automatically while you spend your actual attention on the why that no system can derive for you. Getting the right structure in front of readers and agents is the documentation half of context engineering: not more text, the right projection.
Where PaellaDoc fits
PaellaDoc treats documentation as a projection, not a parallel artifact. It reads your repo into a graph on your machine and derives the views from it, so the map of the system stays current as the system moves. The parts that cannot be derived, the decisions and their reasons, get captured as they happen and linked to the code they govern, so the why is recorded once and never reconstructed. The result is documentation that is true because of how it is made, read the same way by the people on your team and the agents doing the work.
Which doc on your team is lying right now, and how long has it been lying? Tell me on the forum.
Frequently asked questions
Why does documentation always rot?
For a structural reason, not laziness. A traditional doc is a second copy of the truth, kept in a different place from the code and tied to it by exactly one thing: a human remembering to update it. That link is manual, nobody’s explicit job, and fails silently, so the doc quietly becomes less true while still looking authoritative.
What is living documentation?
Documentation with the human taken out of the update path. Instead of writing docs beside the system, you derive them from it, so an API description generated from the real routes changes when a route changes, and an architecture view read off the code graph shows a new service the moment it exists. There’s no second copy to fall out of sync.
Is docs-as-code the same as living documentation?
No, docs-as-code is a half-measure. Putting markdown in the repo, reviewed in pull requests, moves the second copy closer to the code and improves the odds a human notices drift. But the copy and the human are still there. Living documentation is the step past it: for anything that can be read off the code, delete the copy and render a view.
What can’t be derived from code?
The why. The what and the how, routes, call structure, dependencies, shape, can be read off the code. The reason a decision was made isn’t visible in the code that resulted from it, so it has to be captured deliberately as the decision is made and attached to the code it governs. Derive everything else; spend your attention on the why.