Documentation for the you who forgot
The only reader who matters, and what changed when the documentation got a second reader who never skims.
14 months away from a project, and back on it in May for two weeks of changes.
There’s a NOTES.md in the root that I wrote. Two entries in it did their job perfectly. One told me the deploy needs a flag I’d never have guessed and would have had to reverse-engineer from a CI config. Another told me that a bit of ordering in the checkout looks wrong and is deliberate, with a sentence about why, which stopped me tidying it up and breaking something.
A third told me confidently how the staging environment works. It had been true in 2023. Nobody had touched the file since, including me, and I spent about 90 minutes finding out it was wrong, most of which I spent assuming I’d misunderstood it rather than that it was lying.
Net, that file is well ahead. But the 90 minutes is the interesting part, because it’s the cost that nobody accounts for when they talk about writing things down.
Who you’re actually writing for
The useful move, and the one that decides everything else, is being specific about the reader.
Future you, at some distance, is not a beginner and not a stranger. They have every bit of general skill you have now. They know the language, they know the framework, they can read the code faster than they can read your prose about the code.
What they have lost is entirely context. Not “how does a Jekyll collection work,” which they can look up in 30 seconds. Rather: why is it done this way here, what was tried before, and what is going to look like a mistake when they open it.
Once that’s the reader, most of what people put in documentation turns out to be for somebody else, and mostly for a person who doesn’t exist.
Three categories, and only one of them pays
Things recoverable from the code. What the function does. What the components are. Where the routes live. Don’t write these down. They’re the cheapest thing in the world to obtain, and the moment you write them somewhere else you’ve created a second copy that drifts, and the drift is invisible. That’s the argument I made about commit messages in 2018 from the other direction: a commit message is welded to its diff and cannot lie, and a paragraph in a wiki has nothing holding it to anything.
Things recoverable, but expensively. The deploy sequence. The flag. The one-off command with seven arguments. Which of the four env vars actually has to be set. These are worth writing down and they’re what most people mean by documentation, and the return is real but bounded, because the alternative is 20 minutes of archaeology rather than a day.
Things not recoverable at all. Why the ordering matters. What we tried that didn’t work. What the client insisted on over your objection. Which bit looks wrong and is deliberate. Why the obvious better approach isn’t better here.
That third category is the whole game and it’s the one almost nobody writes, because at the moment you have the information it feels too obvious to be worth recording. It never survives. Six months is enough to lose it, and after two years it isn’t anywhere in the world except one person’s head, and eventually not there either.
Everything that looks wrong and is deliberate will be tidied up by somebody eventually, and the somebody is usually you.
The two formats I actually keep
Nothing elaborate, and I’ve tried elaborate.
A comment next to the strange line, saying it’s strange on purpose. This is the highest return per second of any writing I do. It’s in the one place guaranteed to be read by whoever is about to break it, more than can be said for a wiki, and it moves with the code when the code moves.
// Deliberate: clear the session BEFORE the redirect, not after.
// Their payment provider re-enters this handler on the way back and
// the later version double-fired the confirmation email. Sept 2023.
clearCart(session);
redirect(returnUrl);
And a decision log: a dated list, appended to, never reorganized. Three lines an entry: what we decided, what we rejected, why. It takes about 90 seconds at the moment of deciding, the only moment you have the information.
The one that has earned its place most unexpectedly is the rejected half. Knowing that somebody already tried the obvious thing in 2024 and it didn’t work has saved me from re-running the same failed experiment at least three times, and on one of those I’d have lost the better part of a week.
The rot problem, which is the real discipline
Back to the 90 minutes.
A document that’s wrong is worse than no document, because it’s confidently wrong and it comes with your own name on it, so the reader trusts it and troubleshoots themselves instead of it. No document at all makes them go and look, slower and correct.
Which means the discipline is not writing more. It’s writing less and deleting aggressively.
The test I use, and it’s the only maintenance ritual that has stuck: whenever I come back to a project after a gap, I do one small task and pay attention to what I have to work out. Whatever I spend more than a minute rediscovering goes in the file. Whatever I find in the file that’s no longer true comes out, right then, while I have the evidence in front of me.
It’s about 15 minutes and it happens at the exact moment I’m most motivated, namely while I’m annoyed.
And now something else reads it
The bit I didn’t expect, and the reason I’m writing this now rather than in 2017 when I wrote about READMEs.
These files have a second reader now. Whatever your agent reads at the start of a session (mine’s a CLAUDE.md) is documentation, written by you, for a reader with perfect attendance and no memory whatsoever, which is a rather precise description of the future-you I’ve been talking about the whole way through.
And it turned out the two are the same document. What makes a file useful to an agent is exactly what makes it useful to somebody returning after a year: specific, current, stated as a rule with a consequence, no aspiration, no “we value clean code.”
The part I found genuinely surprising is which direction the improvement ran. I started writing these files for the machine, and my documentation for people got better, because the machine is unforgiving about vagueness in a way a colleague is far too polite to be. If a line is ambiguous, it does the wrong thing, immediately and visibly, and you go and fix the line. Nobody has ever given me that feedback loop on prose before.
Which is a whole post of its own and I’ll write it properly. For now: the file you’d write for the version of yourself who forgot is the same file, and you were probably going to have to write it anyway.
Even odds
The staging note is fixed. It’s four lines now instead of 11, it has a date on it, and two of the 11 were describing something that no longer exists and are simply gone.
14 months from now I’ll be back on this and I’ll find out whether I did that well. I’d put it at about even odds, honestly, which is the correct amount of confidence to have in a person who has demonstrably done this wrong before.