Revisits the lifecycle decision on the evidence of ADR-011 (a real draft with open questions). Adds a fourth state, Proposed (YYYY-MM-DD), to ADR-023, the template, the adr-structure check (+test), spec and plan. Sets ADR-011's Status to Proposed and removes its now-redundant inline 'Proposed' line. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5.2 KiB
ADR-023 — ADR structure & lifecycle
Status
Accepted (2026-06-10). Meta/doctrine ADR — pins how ADRs are written; the
adr-structure check (scripts/repo-scan.py) and docs/decisions/adr-template.md
ship with it, and ADRs 001–018 were retroactively restructured to conform. Resolves
the FRICTION signal (2026-05-31) about ADR-writing policy being unsettled.
Context
boma records architectural decisions as numbered ADRs in docs/decisions/, and
CLAUDE.md treats them as load-bearing. Yet no ADR said how an ADR is written. The
newest ADRs (019–022) converged on a clean shape — Status → Context → Decision →
Consequences → Related — but only by imitation. ADRs 001–018 predate it and drifted
widely: most lacked a ## Status section entirely (016–018 carried only a trailing
build-state note), and many lacked an explicit ## Decision or ## Consequences
heading, their decisions spread across ad-hoc topical sections. The result was
structural drift and no uniform way to tell an active decision from a superseded or
deprecated one.
Decision
1. Title & filename
Title line: # ADR-NNN — <Title>: <optional clarifying subtitle> (em-dash). Filename:
NNN-kebab-title.md, zero-padded 3-digit, monotonic, never reused — a superseded ADR
keeps its number and file. A new ADR is registered as a row in the CLAUDE.md
"Further reading" table.
2. Mandatory sections, in this order
## Status— a lifecycle line, usuallyAccepted (YYYY-MM-DD)(see §4), plus an optional one-line note.## Context— the forces, the problem, what exists today, why now.## Decision— what we are doing; numbered sub-decisions for multi-part ADRs.## Consequences— results, trade-offs explicitly accepted, follow-on work.
3. Optional sections (use only where they genuinely apply)
## Related, ## Scope, ## Guardrails / ## Enforcement, ## What was ruled out,
## Verified facts (ADR-014).
4. Status lifecycle
Four states. Because boma is single-contributor and trunk-based with no review gate,
most ADRs are born Accepted (YYYY-MM-DD) — committed-to on writing. A
Proposed state exists for a genuine draft whose core direction is recorded but
whose specifics are still open for discussion (e.g. ADR-011); it is promoted to
Accepted once settled.
Proposed (YYYY-MM-DD)— drafted, under discussion, not yet committed-to. May carry open questions. Promoted toAccepted (YYYY-MM-DD)when decided.Accepted (YYYY-MM-DD)— committed-to. The common starting state.- Replaced → old ADR's Status becomes
Superseded by ADR-NNN (YYYY-MM-DD); the new ADR recordsSupersedes ADR-MMMin its Status and## Related. The link is bidirectional. - Retired with no replacement →
Deprecated (YYYY-MM-DD)+ a one-line reason.
No silent rewrites. An Accepted ADR is not edited to reverse its decision. Typo and
clarity fixes are fine; a material reversal requires a new ADR and a Superseded by
marker on the old one.
5. Template & enforcement
docs/decisions/adr-template.md is the scaffold for new ADRs. The /review-repo
command's pre-scan (scripts/repo-scan.py) emits an adr-structure finding for any
numbered ADR missing a mandatory section or with an unparseable Status line. It checks
presence and Status, not section order — order is a convention the template carries,
deliberately not gated, to keep enforcement lightweight (consistent with boma's other
doctrine ADRs adding no CI gate).
6. Retroactive conformance of the back-catalogue
ADRs 001–018 are restructured to satisfy this standard rather than grandfathered. The
restructure is presentational — existing headings are relabelled, regrouped, or
demoted under a ## Decision umbrella; a dated ## Status is added; a ## Consequences
section is assembled from implications the ADR already states. The substance of no
decision is changed. This keeps the check uniform (no number threshold) and the corpus
a consistent, legible decision history.
Consequences
- New ADRs have one obvious shape and a scaffold; structural drift stops.
- Every ADR declares its lifecycle state uniformly, and reversals are traceable.
- The whole corpus conforms; the check needs no grandfathering and stays simple.
- One-time restructure churn across ADRs 001–018 (heading reorganization + a Status and a Consequences section per file; no decision substance changed).
/review-repogrows one deterministic check; no new CI machinery.- This ADR is the first conformant example and is held to its own check.
What was ruled out
- A
make lint/ CI gate for ADR structure — heavier than the risk warrants; the/review-repocheck and the template suffice. - Machine-enforcing section order — brittle for marginal value; left as a template-demonstrated convention.
- Grandfathering 001–018 from the check — rejected in favour of restructuring the whole corpus to conform, so the standard applies uniformly with no exceptions.
Related
- ADR-014 — knowledge sourcing (the
Verified factsoptional section). - ADR-019/020/021/022 — the emergent structure this ADR codifies.
docs/decisions/adr-template.md— the scaffold.scripts/repo-scan.py— theadr-structureenforcement check.