Architecture Decision Records
Workflows for authoring, reviewing, planning, updating, and backfilling Architecture Decision Records (ADRs).
When to Use
- Creating a new ADR for a technology or architecture decision
- Reviewing an existing ADR for quality and completeness
- Deciding whether something warrants an ADR
- Updating ADR status (accepting, deprecating, superseding)
- Backfilling undocumented decisions from git history
- Adding ADR references to code for traceability
Workflows
Author
When creating a new ADR.
Process:
- Determine next ADR number:
ls docs/src/adr/ | grep -oP '\d+' | sort -n | tail -1
- Create file:
docs/src/adr/adr-NNN-title-in-kebab-case.md
- Add frontmatter (per
frontmatter.md rule):---
id: <uuidv4>
project:
id: <project-uuid>
title: "ADR-NNN: <Title in Imperative Mood>"
status: proposed
tags: [adr, <domain>]
related:
supersedes: []
depends-on: []
---
- Fill required sections (see template in
references/adr-template.md)
- Include at least one Mermaid diagram
- Mark incomplete sections with INVESTIGATE markers
Required Sections:
| Section |
Guidance |
| Status |
Start with proposed |
| Context |
Problem statement, constraints, why now |
| Decision Drivers |
Prioritized factors influencing the choice |
| Considered Options |
2+ alternatives with honest trade-offs |
| Decision Outcome |
Specific choice with rationale |
| Diagram |
Mermaid diagram showing architectural impact |
| Consequences |
Positive, negative, and neutral outcomes |
INVESTIGATE Markers:
For sections that cannot be filled from available information:
- [INVESTIGATE: Confirm scaling requirements with infrastructure team]
- [INVESTIGATE: Benchmark Option 2 vs Option 3 performance]
These signal incomplete sections for later follow-up without blocking the ADR.
Title Convention:
Use imperative mood — describe the action, not the outcome:
| Good |
Bad |
| Use PostgreSQL for user data |
PostgreSQL was chosen |
| Adopt event sourcing pattern |
Event sourcing decision |
| Migrate from REST to gRPC |
REST vs gRPC comparison |
Review
Use the E.C.A.D.R. checklist when reviewing ADRs.
## ADR Review (E.C.A.D.R.)
### Core Quality
- [ ] **E**xplicit problem statement — context clearly states the problem
- [ ] **C**omprehensive options — 2+ alternatives with trade-offs
- [ ] **A**ctionable decision — specific, implementable choice stated
- [ ] **D**ocumented consequences — positive, negative, and neutral listed
- [ ] **R**eviewable — readable by someone without current context
### Structure
- [ ] Frontmatter with id, status, project.id
- [ ] Status is valid (Proposed/Accepted/Deprecated/Superseded/Withdrawn)
- [ ] One decision per ADR
- [ ] Title in imperative mood
- [ ] At least one Mermaid diagram
- [ ] No placeholders or hand-waving
- [ ] Alternatives include honest trade-offs
- [ ] INVESTIGATE markers for known gaps (not silent omissions)
### Strategic Lenses (for significant decisions)
- [ ] Chesterton's Fence: if changing existing, original purpose documented?
- [ ] Path Dependence: irreversibility assessed, exit strategy defined?
- [ ] Second-System Effect: scope bounded, not over-engineering?
Common Issues:
| Issue |
Fix |
| Vague context ("we need a database") |
Add constraints, requirements, and "why now" |
| Single option presented |
Add 2+ alternatives with honest pros/cons |
| Missing trade-offs |
Every choice has downsides — document them |
| No diagram |
Add Mermaid diagram showing architectural impact |
| Placeholder sections ("TBD") |
Use INVESTIGATE markers with specific questions |
| Multiple decisions in one ADR |
Split into separate, focused ADRs |
| Passive title ("Database was selected") |
Use imperative mood ("Use PostgreSQL for X") |
| Missing frontmatter |
Add per frontmatter.md rule |
Plan
Use when deciding what needs an ADR.
Decision Triggers:
| Trigger |
ADR? |
Why |
| Technology choice (DB, framework, language) |
Yes |
Shapes system for years |
| Architectural pattern (microservices, event-driven) |
Yes |
Affects all future development |
| Infrastructure decision (cloud, deployment) |
Yes |
Lock-in implications |
| Security approach (auth, encryption) |
Yes |
Compliance and risk |
| API design (versioning, format) |
Yes |
External contract commitment |
| Build/CI pipeline architecture |
Yes |
Affects all contributors |
| Data model or schema design |
Yes |
Migration cost grows over time |
| Implementation detail (function names) |
No |
Too granular, easily changed |
| Temporary workaround |
No |
Not architectural |
| Minor tooling (linter config, editor settings) |
No |
Low impact, easily reversible |
| Standard library usage |
No |
No real alternatives |
Scope Check:
Before writing, verify the ADR is scoped to one decision:
- Can you state the decision in one sentence? If not, split.
- Does the ADR cover multiple independent choices? Split each into its own ADR.
- Is the decision reversible with minimal effort? Probably doesn't need an ADR.
Timing:
| When |
Approach |
| Before implementation |
Ideal — decision drives the work |
| During implementation |
Acceptable — capture as you learn |
| After implementation |
Backfill — better late than never |
Update
When changing ADR status or superseding decisions.
Status Transitions:
Proposed → Accepted (team/lead approval)
Proposed → Withdrawn (rejected before implementation)
Accepted → Deprecated (no longer relevant, not replaced)
Accepted → Superseded (replaced by newer ADR)
Supersession Workflow:
- Create new ADR with the replacement decision
- In new ADR frontmatter:
related: { supersedes: [<old-adr-uuid>] }
- In new ADR context: reference the old ADR and explain why it's being replaced
- Update old ADR:
- Change
status: superseded
- Add note:
Superseded by [ADR-NNN](./adr-NNN-title.md)
- Never delete the old ADR — it preserves decision history
Deprecation:
- Update
status: deprecated
- Add context explaining why the decision is no longer relevant
- No replacement ADR needed (unlike supersession)
Backfill
When reconstructing undocumented decisions from git history.
Process:
Classify files by architectural significance:
| Tier |
Files |
Signal Strength |
| 0 |
Dependency manifests (Cargo.toml, package.json) |
Highest — every change is a choice |
| 1 |
Infrastructure (Dockerfile, CI configs, terraform) |
High — how the system runs |
| 2 |
Domain structure (core modules, entry points) |
Medium — system shape |
| 3 |
Interface contracts (API schemas, protobuf) |
Medium — external commitments |
Identify decision commits — look for structural changes, not edits:
- New directory created
- Dependency added/removed/major-bumped
- New entry point or service
- CI pipeline added or significantly changed
Cluster related commits into single decisions:
- Related by intent, not just proximity
- Typically spans days to weeks, not months
- Should have a name you could say in a sentence ("the Redis migration")
Ask for context before generating — don't invent rationale:
- What problem prompted this decision?
- What alternatives were considered?
- What trade-offs were accepted?
Generate ADR with reconstructed footer:
---
*Reconstructed from commits abc123..def456 (2024-01-10 to 2024-01-12)*
Quality Bar:
A good backfilled ADR could have been written at the time of the decision. It captures "why", stands alone, and is honest about what's reconstructed vs confirmed.
Quick Reference
ADR Naming
docs/src/adr/adr-NNN-title-in-kebab-case.md
Required Frontmatter
---
id: <uuidv4>
project:
id: <project-uuid>
title: "ADR-NNN: <Title>"
status: proposed # proposed | accepted | deprecated | superseded | withdrawn
tags: [adr]
related:
supersedes: []
depends-on: []
---
Section Quick Reference
| Section |
Required |
Content |
| Status |
Yes |
Current lifecycle state |
| Context |
Yes |
Problem, constraints, "why now" |
| Decision Drivers |
Yes |
Prioritized factors |
| Considered Options |
Yes |
2+ alternatives with trade-offs |
| Decision Outcome |
Yes |
Chosen option with rationale |
| Diagram |
Yes |
Mermaid showing architectural impact |
| Consequences |
Yes |
Positive, negative, neutral |
| References |
No |
Related ADRs, docs, links |
aRustyDev Conventions
- ADRs live in
docs/src/adr/ (mdBook documentation)
- ADR format documented in CLAUDE.md under "ADR Format"
- Frontmatter follows
frontmatter.md rule (UUIDs, project.id, status)
- Related ADRs referenced by UUID in
related: frontmatter, not file path
- ADRs linked from issues and plans when they drive implementation decisions
See Also
references/adr-template.md — complete MADR template with frontmatter
references/quality-checklist.md — full E.C.A.D.R. criteria and strategic lenses
references/code-traceability.md — language-specific ADR references in code
references/decision-triggers.md — detailed guidance on what warrants an ADR
examples/technology-selection.md — example: choosing a CLI parsing library
examples/architectural-change.md — example: adopting a new pattern
tables/status-lifecycle.md — status transitions and governance
1---2name: architecture-decision-records-dev3description: Architecture Decision Record authoring, reviewing, and lifecycle management. Use when creating new ADRs, reviewing ADR quality, deciding what warrants an ADR, updating ADR status, superseding decisions, or backfilling ADRs from git history. Covers MADR template, E.C.A.D.R. quality criteria, status lifecycle, and code traceability patterns.4---56# Architecture Decision Records78Workflows for authoring, reviewing, planning, updating, and backfilling Architecture Decision Records (ADRs).910## When to Use1112- Creating a new ADR for a technology or architecture decision13- Reviewing an existing ADR for quality and completeness14- Deciding whether something warrants an ADR15- Updating ADR status (accepting, deprecating, superseding)16- Backfilling undocumented decisions from git history17- Adding ADR references to code for traceability1819## Workflows2021### Author2223When creating a new ADR.2425**Process:**26271. Determine next ADR number:28 ```bash29 ls docs/src/adr/ | grep -oP '\d+' | sort -n | tail -130 ```312. Create file: `docs/src/adr/adr-NNN-title-in-kebab-case.md`323. Add frontmatter (per `frontmatter.md` rule):33 ```yaml34 ---35 id: <uuidv4>36 project:37 id: <project-uuid>38 title: "ADR-NNN: <Title in Imperative Mood>"39 status: proposed40 tags: [adr, <domain>]41 related:42 supersedes: []43 depends-on: []44 ---45 ```464. Fill required sections (see template in `references/adr-template.md`)475. Include at least one Mermaid diagram486. Mark incomplete sections with INVESTIGATE markers4950**Required Sections:**5152| Section | Guidance |53|---------|----------|54| Status | Start with `proposed` |55| Context | Problem statement, constraints, why now |56| Decision Drivers | Prioritized factors influencing the choice |57| Considered Options | 2+ alternatives with honest trade-offs |58| Decision Outcome | Specific choice with rationale |59| Diagram | Mermaid diagram showing architectural impact |60| Consequences | Positive, negative, and neutral outcomes |6162**INVESTIGATE Markers:**6364For sections that cannot be filled from available information:6566```markdown67- [INVESTIGATE: Confirm scaling requirements with infrastructure team]68- [INVESTIGATE: Benchmark Option 2 vs Option 3 performance]69```7071These signal incomplete sections for later follow-up without blocking the ADR.7273**Title Convention:**7475Use imperative mood — describe the action, not the outcome:7677| Good | Bad |78|------|-----|79| Use PostgreSQL for user data | PostgreSQL was chosen |80| Adopt event sourcing pattern | Event sourcing decision |81| Migrate from REST to gRPC | REST vs gRPC comparison |8283### Review8485Use the E.C.A.D.R. checklist when reviewing ADRs.8687```markdown88## ADR Review (E.C.A.D.R.)8990### Core Quality91- [ ] **E**xplicit problem statement — context clearly states the problem92- [ ] **C**omprehensive options — 2+ alternatives with trade-offs93- [ ] **A**ctionable decision — specific, implementable choice stated94- [ ] **D**ocumented consequences — positive, negative, and neutral listed95- [ ] **R**eviewable — readable by someone without current context9697### Structure98- [ ] Frontmatter with id, status, project.id99- [ ] Status is valid (Proposed/Accepted/Deprecated/Superseded/Withdrawn)100- [ ] One decision per ADR101- [ ] Title in imperative mood102- [ ] At least one Mermaid diagram103- [ ] No placeholders or hand-waving104- [ ] Alternatives include honest trade-offs105- [ ] INVESTIGATE markers for known gaps (not silent omissions)106107### Strategic Lenses (for significant decisions)108- [ ] Chesterton's Fence: if changing existing, original purpose documented?109- [ ] Path Dependence: irreversibility assessed, exit strategy defined?110- [ ] Second-System Effect: scope bounded, not over-engineering?111```112113**Common Issues:**114115| Issue | Fix |116|-------|-----|117| Vague context ("we need a database") | Add constraints, requirements, and "why now" |118| Single option presented | Add 2+ alternatives with honest pros/cons |119| Missing trade-offs | Every choice has downsides — document them |120| No diagram | Add Mermaid diagram showing architectural impact |121| Placeholder sections ("TBD") | Use INVESTIGATE markers with specific questions |122| Multiple decisions in one ADR | Split into separate, focused ADRs |123| Passive title ("Database was selected") | Use imperative mood ("Use PostgreSQL for X") |124| Missing frontmatter | Add per `frontmatter.md` rule |125126### Plan127128Use when deciding what needs an ADR.129130**Decision Triggers:**131132| Trigger | ADR? | Why |133|---------|------|-----|134| Technology choice (DB, framework, language) | Yes | Shapes system for years |135| Architectural pattern (microservices, event-driven) | Yes | Affects all future development |136| Infrastructure decision (cloud, deployment) | Yes | Lock-in implications |137| Security approach (auth, encryption) | Yes | Compliance and risk |138| API design (versioning, format) | Yes | External contract commitment |139| Build/CI pipeline architecture | Yes | Affects all contributors |140| Data model or schema design | Yes | Migration cost grows over time |141| Implementation detail (function names) | No | Too granular, easily changed |142| Temporary workaround | No | Not architectural |143| Minor tooling (linter config, editor settings) | No | Low impact, easily reversible |144| Standard library usage | No | No real alternatives |145146**Scope Check:**147148Before writing, verify the ADR is scoped to one decision:149150- Can you state the decision in one sentence? If not, split.151- Does the ADR cover multiple independent choices? Split each into its own ADR.152- Is the decision reversible with minimal effort? Probably doesn't need an ADR.153154**Timing:**155156| When | Approach |157|------|----------|158| Before implementation | Ideal — decision drives the work |159| During implementation | Acceptable — capture as you learn |160| After implementation | Backfill — better late than never |161162### Update163164When changing ADR status or superseding decisions.165166**Status Transitions:**167168```169Proposed → Accepted (team/lead approval)170Proposed → Withdrawn (rejected before implementation)171Accepted → Deprecated (no longer relevant, not replaced)172Accepted → Superseded (replaced by newer ADR)173```174175**Supersession Workflow:**1761771. Create new ADR with the replacement decision1782. In new ADR frontmatter: `related: { supersedes: [<old-adr-uuid>] }`1793. In new ADR context: reference the old ADR and explain why it's being replaced1804. Update old ADR:181 - Change `status: superseded`182 - Add note: `Superseded by [ADR-NNN](./adr-NNN-title.md)`1835. Never delete the old ADR — it preserves decision history184185**Deprecation:**1861871. Update `status: deprecated`1882. Add context explaining why the decision is no longer relevant1893. No replacement ADR needed (unlike supersession)190191### Backfill192193When reconstructing undocumented decisions from git history.194195**Process:**1961971. **Classify files** by architectural significance:198199 | Tier | Files | Signal Strength |200 |------|-------|-----------------|201 | 0 | Dependency manifests (Cargo.toml, package.json) | Highest — every change is a choice |202 | 1 | Infrastructure (Dockerfile, CI configs, terraform) | High — how the system runs |203 | 2 | Domain structure (core modules, entry points) | Medium — system shape |204 | 3 | Interface contracts (API schemas, protobuf) | Medium — external commitments |2052062. **Identify decision commits** — look for structural changes, not edits:207 - New directory created208 - Dependency added/removed/major-bumped209 - New entry point or service210 - CI pipeline added or significantly changed2112123. **Cluster related commits** into single decisions:213 - Related by intent, not just proximity214 - Typically spans days to weeks, not months215 - Should have a name you could say in a sentence ("the Redis migration")2162174. **Ask for context** before generating — don't invent rationale:218 - What problem prompted this decision?219 - What alternatives were considered?220 - What trade-offs were accepted?2212225. **Generate ADR** with reconstructed footer:223 ```224 ---225 *Reconstructed from commits abc123..def456 (2024-01-10 to 2024-01-12)*226 ```227228**Quality Bar:**229230A good backfilled ADR could have been written at the time of the decision. It captures "why", stands alone, and is honest about what's reconstructed vs confirmed.231232## Quick Reference233234### ADR Naming235236```237docs/src/adr/adr-NNN-title-in-kebab-case.md238```239240### Required Frontmatter241242```yaml243---244id: <uuidv4>245project:246 id: <project-uuid>247title: "ADR-NNN: <Title>"248status: proposed # proposed | accepted | deprecated | superseded | withdrawn249tags: [adr]250related:251 supersedes: []252 depends-on: []253---254```255256### Section Quick Reference257258| Section | Required | Content |259|---------|----------|---------|260| Status | Yes | Current lifecycle state |261| Context | Yes | Problem, constraints, "why now" |262| Decision Drivers | Yes | Prioritized factors |263| Considered Options | Yes | 2+ alternatives with trade-offs |264| Decision Outcome | Yes | Chosen option with rationale |265| Diagram | Yes | Mermaid showing architectural impact |266| Consequences | Yes | Positive, negative, neutral |267| References | No | Related ADRs, docs, links |268269## aRustyDev Conventions270271- ADRs live in `docs/src/adr/` (mdBook documentation)272- ADR format documented in CLAUDE.md under "ADR Format"273- Frontmatter follows `frontmatter.md` rule (UUIDs, project.id, status)274- Related ADRs referenced by UUID in `related:` frontmatter, not file path275- ADRs linked from issues and plans when they drive implementation decisions276277## See Also278279- `references/adr-template.md` — complete MADR template with frontmatter280- `references/quality-checklist.md` — full E.C.A.D.R. criteria and strategic lenses281- `references/code-traceability.md` — language-specific ADR references in code282- `references/decision-triggers.md` — detailed guidance on what warrants an ADR283- `examples/technology-selection.md` — example: choosing a CLI parsing library284- `examples/architectural-change.md` — example: adopting a new pattern285- `tables/status-lifecycle.md` — status transitions and governance