Architecture decision record
Purpose
Two failures recur. A decision gets made in a meeting, nobody writes down what
was rejected, and six months later the team relitigates it with worse
information. Or an ADR is written as an advertisement for the chosen option:
alternatives listed only to be dismissed, no cost admitted. This skill produces
records that survive both — a record whose value is that it tells you what
would have to change for the decision to be reversed.
Prerequisites
- Inputs: the decision being forced and what triggers it now; the
constraints that are genuinely fixed (deadline, existing systems, team
skills, regulatory obligation); at least two options that a competent
engineer would defend.
- Access: whoever holds the authority to accept the decision. An ADR nobody
can accept is a proposal, and should be labelled Proposed, not Accepted.
If only one option exists, this is not a decision — it is a constraint. Record
it as context somewhere else and stop.
Procedure
Write the forcing function first. One paragraph: what is true now that
makes this decision necessary this quarter? "We should think about our
database" is not a forcing function. "Write throughput on the primary is at
70% of capacity and growth projects it to 100% within two quarters" is. An
ADR without a forcing function is usually premature and will be overtaken.
State the constraints separately from the preferences. A constraint is
something an option must satisfy to be viable; a preference is something that
makes an option nicer. Mixing them lets a preference silently eliminate a
viable option. Write them as a list where each entry is testable: "must run
in our existing region set" is a constraint; "the team likes it" is not.
Describe each option on its own terms, in the same shape. For each: how it
works in two or three sentences, what it costs to build, what it costs to
operate, what it makes easy later, what it makes hard later, and who has done
it before. If you cannot write the "makes easy later" line for an option you
intend to reject, you have not understood it well enough to reject it.
Compare against the constraints, in a table, before stating a choice.
|
Option A |
Option B |
Option C |
| Meets constraint 1 |
yes |
yes |
no |
| Meets constraint 2 |
yes |
partial — needs X |
— |
| Build cost |
weeks |
days |
— |
| Operational cost |
new component to run |
none |
— |
| Reversibility |
high |
low, data migration required |
— |
Write "partial" honestly. Tables where the chosen option scores best on every
row are a signal the criteria were chosen after the decision.
State the decision in one sentence, in active voice, with the accepting
authority named by role. "We will use B, accepted by the platform lead on
."
Write consequences as things that are now true, not as risks that might
materialise. Split into: what this enables, what this now costs us
permanently, and what we have given up. The "given up" section is the part
readers come back for — an ADR with no costs listed is not trusted.
Record the reversal condition. What observation would make this decision
wrong? ("If write volume exceeds N, B's single-writer model stops working and
we revisit.") This is what turns an ADR from history into an operating
instrument, and it is the section most often missing.
Assign status and never edit an accepted record in place.
| Status |
Meaning |
Editable |
| Proposed |
Circulated, not yet accepted |
Yes |
| Accepted |
Decision in force |
No — only status changes |
| Superseded by NNN |
A later ADR replaced it |
No |
| Deprecated |
No longer relevant, no replacement |
No |
Superseding records link both ways. Rewriting an accepted ADR destroys the
only record of what the team believed at the time, which is the thing that
makes the archive worth reading.
Number sequentially and keep it short. One decision per record, one to two
pages. If the draft exceeds that, it is either two decisions or it contains
design detail that belongs in the design doc the ADR points to.
Failure modes this skill exists to prevent
- The straw-man alternative. Options listed with only their weaknesses. Test:
could an advocate of the rejected option read your description and agree it is
fair? If not, rewrite it.
- Retrofitting. An ADR written after the code shipped, to justify it. Still
worth writing, but label the date honestly and record the constraints as they
actually were, including "we had already built it".
- Decision without an owner. No accepting authority named, so the decision is
never truly binding and the argument reopens.
- Consequence amnesia. The permanent operating cost never gets recorded, so
the next team inherits a component nobody budgeted for.
Data handling
Classification: Internal, and ADRs are frequently read by new joiners and
sometimes shared with auditors or partners. Keep vendor pricing under NDA,
security control details, and any credentials out of the record — reference them
by pointer. Do not include personal data or customer identifiers in examples;
use synthetic values.
Boundaries
- The choice is cheap to reverse (a library swap contained in one module) —
record it in the pull request; an ADR is overhead.
- The decision is about a product feature or scope rather than technical
structure — that belongs in a product brief, not here.
- The change is already decided and you are assessing its implementation —
engineering-code-review.
- The decision emerged from an outage and remediation actions are being tracked —
engineering-incident-postmortem owns the actions; the ADR covers only the
structural choice one of them implies.
Hand-offs
- Receives from:
engineering-incident-postmortem (a remediation implying an
architectural change); data-analytics-metric-definition (when a metric
contract forces a storage or pipeline decision).
- Routes to:
engineering-code-review (the accepted option becomes the
reviewer's intent baseline); it-change-management when implementing the
decision requires a controlled change.
1---2name: engineering-decision-record3description: Writes and reviews architecture decision records (ADRs): frames the decision as a forced choice, states the options actually considered with their real trade-offs, and records the consequences the team accepts. Use when a technical choice will be expensive to reverse, when a decision keeps being relitigated, when onboarding reveals nobody knows why a component exists, or when reviewing a draft ADR. Trigger on 'write an ADR', 'architecture decision record', 'document this decision', 'why did we choose X', 'we keep re-arguing this'. Not for decisions that are cheap to reverse — record those in the ticket; not for reviewing code that implements an already-accepted decision, which is engineering-code-review.4---56# Architecture decision record78## Purpose910Two failures recur. A decision gets made in a meeting, nobody writes down what11was rejected, and six months later the team relitigates it with worse12information. Or an ADR is written as an advertisement for the chosen option:13alternatives listed only to be dismissed, no cost admitted. This skill produces14records that survive both — a record whose value is that it tells you what15would have to change for the decision to be reversed.1617## Prerequisites1819- **Inputs:** the decision being forced and what triggers it now; the20 constraints that are genuinely fixed (deadline, existing systems, team21 skills, regulatory obligation); at least two options that a competent22 engineer would defend.23- **Access:** whoever holds the authority to accept the decision. An ADR nobody24 can accept is a proposal, and should be labelled Proposed, not Accepted.2526If only one option exists, this is not a decision — it is a constraint. Record27it as context somewhere else and stop.2829## Procedure30311. **Write the forcing function first.** One paragraph: what is true now that32 makes this decision necessary this quarter? "We should think about our33 database" is not a forcing function. "Write throughput on the primary is at34 70% of capacity and growth projects it to 100% within two quarters" is. An35 ADR without a forcing function is usually premature and will be overtaken.36372. **State the constraints separately from the preferences.** A constraint is38 something an option must satisfy to be viable; a preference is something that39 makes an option nicer. Mixing them lets a preference silently eliminate a40 viable option. Write them as a list where each entry is testable: "must run41 in our existing region set" is a constraint; "the team likes it" is not.42433. **Describe each option on its own terms, in the same shape.** For each: how it44 works in two or three sentences, what it costs to build, what it costs to45 operate, what it makes easy later, what it makes hard later, and who has done46 it before. If you cannot write the "makes easy later" line for an option you47 intend to reject, you have not understood it well enough to reject it.48494. **Compare against the constraints, in a table, before stating a choice.**5051 | | Option A | Option B | Option C |52 | --- | --- | --- | --- |53 | Meets constraint 1 | yes | yes | no |54 | Meets constraint 2 | yes | partial — needs X | — |55 | Build cost | weeks | days | — |56 | Operational cost | new component to run | none | — |57 | Reversibility | high | low, data migration required | — |5859 Write "partial" honestly. Tables where the chosen option scores best on every60 row are a signal the criteria were chosen after the decision.61625. **State the decision in one sentence, in active voice, with the accepting63 authority named by role.** "We will use B, accepted by the platform lead on64 <date>."65666. **Write consequences as things that are now true**, not as risks that might67 materialise. Split into: what this enables, what this now costs us68 permanently, and what we have given up. The "given up" section is the part69 readers come back for — an ADR with no costs listed is not trusted.70717. **Record the reversal condition.** What observation would make this decision72 wrong? ("If write volume exceeds N, B's single-writer model stops working and73 we revisit.") This is what turns an ADR from history into an operating74 instrument, and it is the section most often missing.75768. **Assign status and never edit an accepted record in place.**7778 | Status | Meaning | Editable |79 | --- | --- | --- |80 | Proposed | Circulated, not yet accepted | Yes |81 | Accepted | Decision in force | No — only status changes |82 | Superseded by NNN | A later ADR replaced it | No |83 | Deprecated | No longer relevant, no replacement | No |8485 Superseding records link both ways. Rewriting an accepted ADR destroys the86 only record of what the team believed at the time, which is the thing that87 makes the archive worth reading.88899. **Number sequentially and keep it short.** One decision per record, one to two90 pages. If the draft exceeds that, it is either two decisions or it contains91 design detail that belongs in the design doc the ADR points to.9293## Failure modes this skill exists to prevent9495- **The straw-man alternative.** Options listed with only their weaknesses. Test:96 could an advocate of the rejected option read your description and agree it is97 fair? If not, rewrite it.98- **Retrofitting.** An ADR written after the code shipped, to justify it. Still99 worth writing, but label the date honestly and record the constraints as they100 actually were, including "we had already built it".101- **Decision without an owner.** No accepting authority named, so the decision is102 never truly binding and the argument reopens.103- **Consequence amnesia.** The permanent operating cost never gets recorded, so104 the next team inherits a component nobody budgeted for.105106## Data handling107108Classification: **Internal**, and ADRs are frequently read by new joiners and109sometimes shared with auditors or partners. Keep vendor pricing under NDA,110security control details, and any credentials out of the record — reference them111by pointer. Do not include personal data or customer identifiers in examples;112use synthetic values.113114## Boundaries115116- The choice is cheap to reverse (a library swap contained in one module) —117 record it in the pull request; an ADR is overhead.118- The decision is about a product feature or scope rather than technical119 structure — that belongs in a product brief, not here.120- The change is already decided and you are assessing its implementation —121 `engineering-code-review`.122- The decision emerged from an outage and remediation actions are being tracked —123 `engineering-incident-postmortem` owns the actions; the ADR covers only the124 structural choice one of them implies.125126## Hand-offs127128- **Receives from:** `engineering-incident-postmortem` (a remediation implying an129 architectural change); `data-analytics-metric-definition` (when a metric130 contract forces a storage or pipeline decision).131- **Routes to:** `engineering-code-review` (the accepted option becomes the132 reviewer's intent baseline); `it-change-management` when implementing the133 decision requires a controlled change.