You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs(governance): allow in-place refinement of accepted ADRs
Replace the strict-immutability rule in docs/decisions/README.md ("do not
edit the original") with the mainstream refine-in-place vs. supersede-on-
reversal model, and add the bookkeeping that makes in-place refinement
auditable.
- Distinguish lifecycle state (proposed/accepted/superseded/deprecated)
from the orthogonal mutability operation (refine vs. supersede).
- Add a boundary test: if the action a reader takes is unchanged it is a
refinement (edit in place); if a past reader would now act differently it
is a reversal (new superseding ADR).
- Add a parallel "Changing an accepted ADR" table (Refinement / Reversal /
Obsolescence).
- Add optional **Last-updated:** field (distinct from immutable **Date:** =
decision date) and a ## Changelog convention to the template.
- Cite precedent (Joel Parker Henderson; MADR last-updated date).
- Regenerate the Starlight mirror.
Removes the contradiction with ADR-012 ("existing ADRs are updated
incrementally") and unblocks the ADR-003 decomposition (#186).
Refs #380
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
**Last-updated:** YYYY-MM-DD (optional; add when the ADR is refined in place after acceptance)
23
24
**Supersedes:** ADR-NNN (if applicable)
24
25
**Superseded by:** ADR-NNN (if applicable)
25
26
@@ -41,8 +42,16 @@ What follows from this decision:
41
42
## References
42
43
43
44
- Links to RFCs, issues, PRs, or external resources that informed the decision
45
+
46
+
## Changelog
47
+
48
+
(Optional; present once the ADR has been refined in place. One dated bullet per refinement. The decision date in `**Date:**` is never overwritten.)
49
+
50
+
- YYYY-MM-DD — What was refined and why (decision unchanged).
44
51
```
45
52
53
+
`**Date:**` records when the decision was **made/accepted** and is never overwritten — it is the historical anchor (which other ADRs existed, what the constraints were). `**Last-updated:**` records when the record was last **refined in place**; the `## Changelog` records *what* changed. See [Changing an accepted ADR](#changing-an-accepted-adr-refine-in-place-vs-supersede).
54
+
46
55
## Numbering
47
56
48
57
ADRs are numbered sequentially with zero-padded three-digit prefixes: `ADR-001-slug.md`, `ADR-002-slug.md`, etc. Numbers are never reused.
@@ -56,7 +65,24 @@ ADRs are numbered sequentially with zero-padded three-digit prefixes: `ADR-001-s
56
65
|`superseded`| Replaced by a newer ADR (link to successor) |
57
66
|`deprecated`| No longer applicable (context changed) |
58
67
59
-
A decision starts as `proposed` during RFC discussion and moves to `accepted` when the implementing PR merges. To change an accepted decision, write a new ADR that supersedes it — do not edit the original.
68
+
A decision starts as `proposed` during RFC discussion and moves to `accepted` when the implementing PR merges.
69
+
70
+
### Changing an accepted ADR: refine in place vs. supersede
71
+
72
+
Lifecycle state (above) is **orthogonal** to ordinary upkeep. Two different operations apply to an accepted ADR, and the status table does not decide between them:
73
+
74
+
-**Refinement** — the decision is unchanged; you are clarifying wording, adding a consequence or risk, extracting operational prose to a guide/skill (see ADR-012), or fixing a reference. **Edit the file in place.** Status stays `accepted`.
75
+
-**Reversal** — the decision itself changes: a different approach is chosen, or what a reader must do changes. **Write a new ADR that supersedes the old one.** The old ADR becomes `superseded`.
76
+
77
+
**The boundary test:***If the action a reader would take is unchanged, it's a refinement — edit in place. If a past reader following the old ADR would now do something different, it's a reversal — write a superseding ADR.*
78
+
79
+
| Change | What it is | What to do | Status effect | Date fields |
| Clarify wording; add a consequence/risk; extract prose to a guide/skill (per ADR-012); fix a broken reference |**Refinement**| Edit in place; append a dated `## Changelog` entry | none (`accepted`) |`Date:` unchanged; bump `Last-updated:`|
82
+
| Reverse the decision; choose a different approach; change what a reader must do |**Reversal**| New ADR with `**Supersedes:** ADR-NNN`; mark the old `**Superseded by:** ADR-MMM`| both change | new ADR gets its own `Date:`|
83
+
| The decision no longer applies (context evaporated) |**Obsolescence**| Mark `deprecated`; note why |`deprecated`| bump `Last-updated:`|
84
+
85
+
This replaces strict immutability with the mainstream ADR practice. Joel Parker Henderson's widely-cited guidance notes that *"in theory, immutability is ideal; in practice, mutability has worked better for our teams"* — insert new information into the existing ADR with a date stamp and a note. MADR likewise tracks a last-updated date distinct from the decision date. The **decision date is never overwritten**; refinements are recorded in the `## Changelog` and the `Last-updated` field, keeping the record self-contained (an agent should not need to excavate git history to learn what was refined and when).
**Last-updated:** YYYY-MM-DD (optional; add when the ADR is refined in place after acceptance)
27
28
**Supersedes:** ADR-NNN (if applicable)
28
29
**Superseded by:** ADR-NNN (if applicable)
29
30
@@ -45,8 +46,16 @@ What follows from this decision:
45
46
## References
46
47
47
48
- Links to RFCs, issues, PRs, or external resources that informed the decision
49
+
50
+
## Changelog
51
+
52
+
(Optional; present once the ADR has been refined in place. One dated bullet per refinement. The decision date in `**Date:**` is never overwritten.)
53
+
54
+
- YYYY-MM-DD — What was refined and why (decision unchanged).
48
55
```
49
56
57
+
`**Date:**` records when the decision was **made/accepted** and is never overwritten — it is the historical anchor (which other ADRs existed, what the constraints were). `**Last-updated:**` records when the record was last **refined in place**; the `## Changelog` records *what* changed. See [Changing an accepted ADR](#changing-an-accepted-adr-refine-in-place-vs-supersede).
58
+
50
59
## Numbering
51
60
52
61
ADRs are numbered sequentially with zero-padded three-digit prefixes: `ADR-001-slug.md`, `ADR-002-slug.md`, etc. Numbers are never reused.
@@ -60,7 +69,24 @@ ADRs are numbered sequentially with zero-padded three-digit prefixes: `ADR-001-s
60
69
|`superseded`| Replaced by a newer ADR (link to successor) |
61
70
|`deprecated`| No longer applicable (context changed) |
62
71
63
-
A decision starts as `proposed` during RFC discussion and moves to `accepted` when the implementing PR merges. To change an accepted decision, write a new ADR that supersedes it — do not edit the original.
72
+
A decision starts as `proposed` during RFC discussion and moves to `accepted` when the implementing PR merges.
73
+
74
+
### Changing an accepted ADR: refine in place vs. supersede
75
+
76
+
Lifecycle state (above) is **orthogonal** to ordinary upkeep. Two different operations apply to an accepted ADR, and the status table does not decide between them:
77
+
78
+
-**Refinement** — the decision is unchanged; you are clarifying wording, adding a consequence or risk, extracting operational prose to a guide/skill (see ADR-012), or fixing a reference. **Edit the file in place.** Status stays `accepted`.
79
+
-**Reversal** — the decision itself changes: a different approach is chosen, or what a reader must do changes. **Write a new ADR that supersedes the old one.** The old ADR becomes `superseded`.
80
+
81
+
**The boundary test:***If the action a reader would take is unchanged, it's a refinement — edit in place. If a past reader following the old ADR would now do something different, it's a reversal — write a superseding ADR.*
82
+
83
+
| Change | What it is | What to do | Status effect | Date fields |
| Clarify wording; add a consequence/risk; extract prose to a guide/skill (per ADR-012); fix a broken reference |**Refinement**| Edit in place; append a dated `## Changelog` entry | none (`accepted`) |`Date:` unchanged; bump `Last-updated:`|
86
+
| Reverse the decision; choose a different approach; change what a reader must do |**Reversal**| New ADR with `**Supersedes:** ADR-NNN`; mark the old `**Superseded by:** ADR-MMM`| both change | new ADR gets its own `Date:`|
87
+
| The decision no longer applies (context evaporated) |**Obsolescence**| Mark `deprecated`; note why |`deprecated`| bump `Last-updated:`|
88
+
89
+
This replaces strict immutability with the mainstream ADR practice. Joel Parker Henderson's widely-cited guidance notes that *"in theory, immutability is ideal; in practice, mutability has worked better for our teams"* — insert new information into the existing ADR with a date stamp and a note. MADR likewise tracks a last-updated date distinct from the decision date. The **decision date is never overwritten**; refinements are recorded in the `## Changelog` and the `Last-updated` field, keeping the record self-contained (an agent should not need to excavate git history to learn what was refined and when).
0 commit comments