CRUMB a card from devarno-cloud

Decision Docs Append-Only with Supersession

petrova intermediate 5 min read

ELI5

Decision docs are a courtroom transcript, not a wiki. You don’t go back and pencil corrections into yesterday’s verdict — you file a new verdict that explicitly overturns it, and the old verdict gets a “see new ruling” note pasted on top. Both stay readable.

Technical Deep Dive

Status lifecycle

stateDiagram-v2
[*] --> draft
draft --> open : ratified by author
open --> closed : human sign-off + outcome recorded
closed --> superseded : new doc written that overturns this one
superseded --> [*]
closed --> [*] : remains canonical until/unless superseded
note right of superseded
Status flips by editing
only the status line and
adding the > Superseded
blockquote — the body
stays intact (MR-7).
end note

The full enum (docs/decisions/_template.md): draft, open, closed, superseded. Once closed, a doc’s body is frozen.

The supersession protocol (MR-7)

Two text changes happen together, in the same commit:

On the new doc (YYYY-MM-DD-<slug>.md):

## Supersedes
- `docs/decisions/2026-04-26-soak-result.md` — superseded by this doc on
<reason>. The original verdict is preserved for traceability.

On the old doc, prepended above the existing body:

> **Superseded** by `docs/decisions/YYYY-MM-DD-<new>.md` on YYYY-MM-DD.
> Original content preserved below for traceability.

The old doc’s **Status:** line flips from closed to superseded. The old body remains untouched.

Why “fixing a typo” in a closed doc is the failure mode

Editing closed decision docs silently destroys lineage. From META-RULES.md MR-7:

“You do not edit a closed decision doc to ‘fix’ what it said. You write a new decision doc that supersedes it. … The lineage is part of the system’s memory. Editing closed docs silently destroys it.”

The pragmatic exception is truly mechanical (broken link, typo in heading). Even then, prefer a new note doc; the cost of a one-paragraph follow-up is much lower than the cost of a future reader being unable to reproduce why the closed verdict said what it said.

Filename + dating discipline (MR-4)

docs/decisions/YYYY-MM-DD-<slug>.md. The docs-invariants.yml CI workflow validates:

Terminal window
for f in $(find docs/decisions -maxdepth 1 -name '*.md' \
! -name 'README.md' ! -name '_*' ! -name '_changelog.md'); do
base=$(basename "$f")
if ! [[ "$base" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}-[a-z0-9-]+\.md$ ]]; then
echo "MR-4 violation: $f does not match YYYY-MM-DD-<slug>.md"
fail=1
fi
done

Findings live under docs/findings/ with YYYYMMDD[-HHMM]-<slug>.md (no hyphens between date components — different filename grammar; both are validated).

CI catches the half-supersession

A common shape of failure: someone marks the old doc **Status:** superseded but forgets the > **Superseded-by:** blockquote (or vice versa). The CI workflow has a dedicated check:

if re.search(r'\*\*Status:\*\*\s*superseded', content, re.IGNORECASE):
if not re.search(r'\*\*Superseded-by:\*\*\s*\S', content, re.IGNORECASE):
print(f"MR-7 violation: {path} status=superseded but no Superseded-by link")
fail = True

So the discipline does not rely on goodwill — half-supersessions fail the docs-invariants job before the PR can merge.

Templates and conventions

core/templates/docs/decisions/_template.md mandates: front-matter with rank: decisions + outranks:, a ## Context, a ## Decision, at least two ## Alternatives considered entries (the petrova-decide skill refuses fewer than two), ## Consequences, ## References, and a ## Sign-off block carrying agent + human signatures.

Real-life example: sub-project G chain

The recent G-series (decision-doc lineage in petrova-hq’s own ledger):

stateDiagram-v2
[*] --> g_open : 2026-05-06-sub-project-g-rocky-eva-surface-ratification.md (status: open)
g_open --> g_close : 2026-05-06-sub-project-g-closure.md (closes G with ratified shapes)
g_close --> [*]

G.3 (commit 8d75cbe — feat(schema): G.3 simplify integration_eva.evidence per G.2 ratification) edited the schema; the closing decision doc cited G.2’s eva-hq ratification as grounding. Neither G-open nor G-close edits the other’s body — they reference each other.

Key Terms

  • Supersession protocol — paired text changes (## Supersedes on the new doc; > **Superseded** by ... blockquote on the old) that together flip an old doc’s status without editing its body.
  • outranks: front-matter — every decision doc declares its rank tier and what it outranks; consumed by both the drift-watcher and the docs-invariants CI.
  • MR-7 — the “decision docs are append-only” meta-rule; the foundational invariant of the decision ledger.

Q&A

Q: What two text changes are required when one decision doc supersedes another? A: (1) The new doc gets a ## Supersedes section listing the predecessor and the reason. (2) The old doc gets a > **Superseded** by <new path> on <date>. Original content preserved below for traceability. blockquote prepended, and its **Status:** line flips to superseded. Both edits land in the same commit.

Q: Why is editing a closed decision doc to fix a typo discouraged? A: Because the lineage is part of the system’s memory. Even tiny edits invite “while I’m in here” corrections, which silently rewrite history and break MR-7’s load-bearing property: that any reader can reproduce why a closed verdict said what it said. A short follow-up note doc costs almost nothing and preserves the property.

Q: How does the docs-invariants CI catch a half-supersession? A: It greps every closed-or-later doc for **Status:** superseded and, when it finds one, requires a matching **Superseded-by:** <link> line. Either present without the other fails the job. So a half-supersession cannot merge.

Examples

A 2026-04-26 phase-close decision was overturned on 2026-05-01 because a new probe surfaced a regression. The 2026-05-01 doc carries ## Supersedes - docs/decisions/2026-04-26-phase-7-close.md — soak run regressed; re-classifying advisory as block. The 2026-04-26 doc gets the > **Superseded** by docs/decisions/2026-05-01-phase-7-close-amended.md on 2026-05-01. blockquote and its status flips to superseded. Both commits land together; CI passes.

neighbors on the map