Architecture decision records
An ADR is a short, dated record of one decision, kept beside the code; a changed decision gets a new record, not an edit.
Predict first
Before you read: predict
A payments ledger's repository holds six decision records about how amounts are rounded. Their status lines:
0003-round-each-line.md Status: Superseded by ADR-0011
0011-round-each-invoice.md Status: Superseded by ADR-0017
0013-round-fx-down.md Status: Superseded by ADR-0019
0017-round-half-to-even.md Status: Accepted
0019-round-fx-half-up.md Status: Accepted
0021-round-at-settlement.md Status: Proposed
ledger/round.ts carries the comment // rounding rule: see ADR-0003. A developer about to change the rule in that file must follow the decision in force for it.
Which record holds it?
The 30-second version
Write each significant decision as a short numbered file in the repository: its context, the options weighed, the decision and its consequences. It is proposed until agreed, then accepted. To reverse it, write a new record and mark the old one superseded, pointing to its replacement. The decision in force is at the chain's end, if accepted.
An ADR is a short, dated record of one decision, kept beside the code; a changed decision gets a new record, not an edit.
How it works
Step 1 of 12
Analogy: A small brewery's brew book
A brewery keeps a brew book on the shelf beside the fermenters. Each numbered page records one dated decision about one beer: what was pressing (the usual maltster's price doubled; the cellar runs warm in August), what the brewers chose, and what it will cost them (a darker colour, a week longer in the tank). When they change their mind they never scratch a page out: they write the next numbered page and add “replaced by page 31” in the old page's margin. A new brewer who wants today's recipe opens any page about that beer and follows the margin notes to the last page. A page headed “trial, not agreed” changes nothing until the head brewer signs it.
| In the brewhouse | In the repository |
|---|---|
| One page, one dated recipe decision | One ADR, one decision |
| What was pressing, what was chosen, what it costs | Context, decision, consequences |
| The book on the shelf beside the fermenters | ADRs in the repository beside the code |
| A new page, never a scratched-out one | A new record, never an edit |
| “Replaced by page 31” in the margin | “Superseded by ADR-0031” on the status line |
| Following margin notes to the last page | Following the chain to the record in force |
| “Trial, not agreed” | Proposed |
Breaks down when: a brewer can taste the beer to check a page, while nothing in the code shows why it is built as it is. Wrong inference: “the code will tell a newcomer why.” A brew book is also read by one small crew, while a decision log is read by people who join years later.
In real terms: before you merge a decision, add its numbered file under docs/adr/, and when it replaces an older record, change that record's status line to point at the new one.
Try it
Answer first, then check. Nothing is saved.
Question 1 of 5
The ledger team has decided that every posting request must carry an idempotency key, after weighing a unique index on the posting's fields. The code is in pull request #882. Finance staff, who never use git, sometimes ask why the ledger works as it does.
Where should the decision record go?
Question 2 of 5
The ledger team is drafting ADR-0015, “Refunds as reversal entries”, to replace ADR-0009 of 2025.
Which sentence belongs in ADR-0015's Context section?
Question 3 of 5
The ledger team has written ADR-0021, “Round at settlement”, and its pull request adds the file to docs/adr/. Finance signs off every rounding change at its monthly review, next held on 14 October. The pull request merges this week.
Which status line should ADR-0021 carry when it merges?
Question 4 of 5
In 2025 the ledger team recorded 0007-settle-payouts-daily.md, accepted, with the Decision “We will settle card payouts once a day, at 02:00.” Today the team agrees to settle payouts every hour. Its merge request adds 0015-settle-payouts-hourly.md, accepted, whose first line is Supersedes ADR-0007, and deletes ADR-0007's file.
Which change should the reviewer ask for before the merge?
Question 5 of 5
A ledger's decision log after this week's merge:
0004-amounts-in-minor-units.md Status: Accepted · Decides: amount type
0006-postgres-and-nightly-batch.md Status: Superseded by ADR-0013 · Decides: posting store; settlement
0013-stream-settlement.md Status: Accepted · Supersedes ADR-0006 · Decides: settlement
Amounts are still kept in minor units, as ADR-0004 chose; postings are still stored in Postgres, as ADR-0006 chose in 2025; settlement now runs on a stream. A new engineer asks the log which record holds for each question a record decides.
What does the log get wrong?
Go deeper
Pro tip
Write the record when the decision is made, in about ten minutes, with the options you turned down; a short, dated record beats a perfect one written later. (Practice advice from the curriculum row, not a sourced rule.)
Related lessons
Checked against the tools and docs as of 2026-10-02.