Documentation as Code
Documentation kept apart from the code goes out of date, because nothing forces it to keep up. Treat docs like code: in the repo, reviewed in the same PR, and versioned with what they describe. Then they stay correct. Write the docs that are worth keeping: the why behind decisions, the things that would surprise the next person, and how to run the system.
Documentation-as-code means docs are first-class artifacts. They are stored in version control next to the code, changed in the same pull request as the behaviour they describe, and reviewed for accuracy like any other change. Keeping them next to the code keeps them correct. A doc you must update to merge the change stays current, while a wiki page nobody has to touch slowly becomes wrong.
Be deliberate about what to document. Code shows what and how. Comments and docs should capture why: the reason, the trade-off, the non-obvious constraint, and the regulatory reason something works the way it does. Clear code (good names, small functions) removes the need for much explanation, so your writing can focus on what the code cannot express.
Keep docs close and current
- DoStore documentation in the repo with the code, and update it in the same PR as the change it describes.
- DoReview docs for accuracy alongside the code. Out-of-date documentation is worse than none, because people trust it and it misleads them.
- DoKeep a useful README and run notes for each service: how to build, run, test, and configure it, and what its dependencies are.
- DoRecord significant decisions and their reasons (lightweight ADRs), so the why survives after the people who decided it have moved on.
- ConsiderGenerating reference docs from the source of truth (for example, OpenAPI from the API) so they cannot drift from the implementation.
- AlwaysUpdate the documentation in the same change as the behaviour it describes. Never merge a change that leaves the docs wrong.
Write what earns its keep
- DoDocument the why and the surprising: reasons, trade-offs, non-obvious constraints, and the regulatory reasons behind a design.
- DoPrefer clear code (good names, small focused functions) over comments that repeat what the code already says.
- DoComment the tricky and the dangerous: workarounds, traps, and any deliberate exception (for example, why an error is safely ignored here).
- ConsiderA short architecture overview and diagrams for the whole system, so newcomers see the shape before the detail.
- AvoidWriting comments that state the obvious (
i++ // increment i). They add noise and go out of date. - NeverPut secrets, credentials, tokens, or real customer/PII data into documentation, comments, READMEs, or examples.
// set the timeout to 30000
client.Timeout = 30000;
// example config: ConnectionString = "Server=...;Password=Prod123!"
The comment repeats the obvious and explains nothing, and the README example leaks a real production password. Worse than no docs on both counts.
// Sumsub p95 is ~12s under load; 30s gives headroom before we
// fail closed and escalate, rather than timing out on a slow-but-valid check.
client.Timeout = TimeSpan.FromSeconds(30);
// example config uses a Key Vault reference, never a real secret
The comment captures the reasoning a future maintainer needs, and the example shows the secure pattern instead of leaking a credential.
Self-review checklist
- AskDid this change leave any doc, README, or comment saying something no longer true?
- AskHave I captured the why for anything non-obvious or surprising here?
- AskCould the next person run, configure, and operate this from what's written?
- AskIs there any secret or real PII in my docs, comments, or examples?