Skip to content
Knowledge Hub

Keeping docs alive: docs-as-code, owners and review checklists Intermediate

Estimated reading time: 5 min read

This page answers: why docs die, which mechanisms keep them alive, and what to check when reviewing a PR that touches an ADR or README.

Nygard: “Large documents are never kept up to date.” Docs die because they live far from the code and nobody owns them. Fix it with process, not willpower.

Loading diagram…

Mechanism How Why it works
Docs-as-code Markdown in the repo, link lint in CI Same version as the code; diffable and reviewable
Review in the same PR PR template with a “Docs/ADR/runbook need updating?” item The person who best understands the change writes the docs while it’s fresh
Owner CODEOWNERS for docs/adr/ and docs/runbooks/ GitHub auto-requests the owner’s review when a PR touches their files (except draft PRs)
Expiry Runbooks carry a “last updated”; review runbooks after every incident A wrong runbook during an incident is worse than none
Delete aggressively Delete docs describing things that no longer exist (git keeps the history) Wrong docs erode trust in every other doc
Exception: ADRs ADRs are never deleted, only superseded/deprecated Their value is the history of decisions

Example CODEOWNERS (GitHub: the last matching pattern takes precedence):

# .github/CODEOWNERS
* @acme/checkout
/docs/adr/ @acme/checkout-leads
/docs/runbooks/ @acme/checkout @acme/sre

Pros

  • Docs in the repo: reviewable, versioned with code, available offline, greppable.
  • Small, immutable ADRs: cheap to write, never “stale” in the sense of being untrue.
  • Runbooks linked from alerts: less diagnosis time for people who didn’t write the code.

Cons

  • People outside engineering (PMs, CS) find it hard to read/comment in the repo; design docs that need wide discussion may have to live in another tool.
  • Requires review discipline: PR templates and CODEOWNERS only remind, they can’t enforce quality.
  • A long decision log is hard to search: it needs an index and titles that are decision sentences.
Situation What to do
Hard-to-reverse or convention-breaking decision, team of any size Adopt ADRs. Start with ADR-0001 and the next decision; no need to backfill the whole history
An old decision keeps being questioned Backfill selectively. State “written retroactively on date X, context based on Y’s memory”
Throwaway prototype/spike; a decision inside one module, reversible in one PR Exception: a good commit message is enough
Company-level decisions (cloud choice, main language) Exception: live in a shared repo/space; the service’s ADRs just link to them

ADR checklist (when reviewing a PR that adds an ADR)

Section titled “ADR checklist (when reviewing a PR that adds an ADR)”
  1. Is the title a decision sentence (“Publish events via an outbox instead of publishing directly”), not a noun (“Outbox”)?
  2. Does Context state a concrete problem and constraints, neutrally, without selling the solution?
  3. Are at least two options considered, each with a reason for rejection?
  4. Is the Decision in active voice, specific enough to check whether code follows it?
  5. Do the Consequences include at least one bad consequence and the work that comes with it (runbook, alert, idempotency requirement)?
  6. Is there a condition for revisiting (“when throughput exceeds…, when Kafka Connect is available”)?
  7. Are status, date, decision makers, supersede/related links complete? Is the number unique?
  8. Is it 1–2 pages long? If longer, the exploration belongs in a design doc.

GitHub suggests a README answer: what the project does, why it’s useful, how to get started, where to get help, who maintains it. For an internal service, make that concrete:

  1. One paragraph: what the service does, what it does not do, which bounded context it belongs to.
  2. A quickstart that runs from a clean machine in a few commands (run it in CI or periodically so it doesn’t rot).
  3. Test, lint and migrate commands.
  4. A config/env var table, or a link to auto-generated reference.
  5. Links: docs/architecture.md (C4), docs/adr/, docs/runbooks/, OpenAPI, dashboards.
  6. Owner (team, chat channel), on-call rotation.
  7. Events published/consumed and APIs depended on, with schema links.
  1. The team decides not to cache account balances. Should it write an ADR, and what should Context state?
  2. ADR-0012 chose outbox polling. A year later the team moves to CDC. Which files change, and how?
  3. Why must the outbox ADR’s Consequences mention idempotent consumers?
  4. The README explains why Kafka was chosen over RabbitMQ. Per Diátaxis, where should that part move?
  5. How do design docs and ADRs differ in when they are written and whether they are updated afterwards?

Next: Common mistakes when writing ADRs, runbooks, READMEs.