Files
ersatztv/docs/decisions/migration-map.md
T
timothyandClaude Opus 4.8 b1e7e08884 feat(521): rework decisions guard — lifecycle validator + narrow [decisions-edit]; header + CI rewrite [decisions-edit]
Retire the line-level append-only mechanic (ersatztv#303 H9) in favor of the lifecycle validator
built in Tasks 1-5. .claude/hooks/decisions-guard.sh is now a thin fail-open shim around
scripts/decisions_validate.py; .husky/pre-commit calls it for the structural (working-tree) checks,
.husky/commit-msg drops the old staged/[decisions-edit]-deletion block and keeps only the
Co-Authored-By check. The Gitea decisions-guard job is renamed "decisions lifecycle" and now runs
decisions_validate.py --base/--head (structural + body-diff + no-vanish) and
build_decisions_catalog.py --check (active catalog drift), with actions/setup-python@v5 added since
the bare `small` lane doesn't guarantee python3; the old 1800-line consolidation-floor step is
removed (replaced by the validator's aggregate active-corpus budget). docs/decisions.md's header is
rewritten from append-only to lifecycle framing (metadata schema, statuses, generated catalog,
archive, same-PR supersession); [decisions-edit] is re-scoped (not removed) to rationale-prose
edits/factual corrections only. docs/ci-cd.md's release ritual and hook/job descriptions are
rewritten to match.

Also fixes a pre-existing validator false-positive surfaced while sanity-checking against
origin/main: Task 6's #303 H9/H3 split (commit d09be57e) renamed the archived record's heading
away from the pre-split original, which the validator's heading-based relocation check reads as
"removed without an archive copy." Restored the archived heading to match the original text
(functionally unchanged — still status: superseded, same key) and updated the two prose
cross-references (migration-map.md, release-ci-governance.md) that pointed at the old anchor.

PR1 scope only (per brief): does NOT wire the kickoff-guard CI step or touch the
kickoff/README/select-queue docs — that's Task 8/PR2.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 03:00:15 +02:00

5.1 KiB

Decision migration map (legacy heading → active record / archive)

Auditable mapping produced during the #521 lifecycle migration. Every legacy H2 heading maps to either an active record (key) or an archive location. Most headings in docs/decisions.md and the docs/decisions/*.md topic files are still status: legacy-unmigrated (no metadata block yet) — this table only covers records touched so far. PYTHONPATH=. python3 scripts/decisions_validate.py prints the running legacy-unmigrated count; it must trend to 0 over the arc, not drop to 0 in one PR.

Legacy heading Key Status Location
2026-07-17 — No persistent compiler servers in CI; every services: container gets an explicit cap; #390's small-lane move reversed (#406) ci.runner-placement active docs/decisions.md
2026-07-19 — CI test job reports a sampled true peak-anon, not cache-inflated memory.peak (#412) ci.peak-anon-measurement active docs/decisions.md
2026-07-12 — decisions.md is append-only, enforced; root-screenshot guard (#303 H9/H3) — heading kept identical to the pre-split original (only the body/metadata were split) so the lifecycle validator's relocation check matches it docs.append-only-guard superseded (superseded-by: docs.decision-lifecycle@2026-07-21) docs/decisions/archive/release-ci-governance.md
2026-07-12 — Root-screenshot guard: pre-commit refuses root-level *.png (#303 H3) — split from the original H9/H3 bundle ci.root-screenshot-guard active docs/decisions/release-ci-governance.md
2026-07-21 — Decision records carry a lifecycle schema, validated by a script; append-only-by-diff is retired (#521) docs.decision-lifecycle active (supersedes: docs.append-only-guard@2026-07-12) docs/decisions.md

Migration conventions

A legacy ## entry that bundles an active sub-decision with a superseded/retired one is SPLIT during migration — the superseded half moves to archive/, the active half becomes its own status: active record in the active files. Never relocate an active decision to archive/. First applied to the #303 H9/H3 bundle (below): H9 (docs.decisions.md append-only) is genuinely superseded and archived as docs.append-only-guard; H3 (the root-screenshot pre-commit guard) is independent and still active, so it was split out into its own active record, ci.root-screenshot-guard, in docs/decisions/release-ci-governance.md rather than being carried into archive with its superseded sibling.

Notes on records considered but NOT given a standalone entry

  • #390 (small-lane move for api-docs/format). Investigated whether #390's reversal (described in #406's prose, point 3: "#390's small-lane move ... reversed") ever existed as its own ## record. It did not — grep for #390 across docs/decisions.md and docs/decisions/*.md finds it only inside #406's own body text (and one other unrelated mention of #390's apt-ffmpeg estimate, also inside #406). #390 was prose-only: no separate heading, so nothing to mark superseded or move to archive. ci.runner-placement (#406) therefore carries supersedes: none; the reversal is recorded only in its **Signals:** line (#390 (prose-reversed, no standalone record)) and in this note.
  • #411 (the earlier memory.peak-headline measurement). Investigated the "#411 obsolescence" the brief references. #411 is mentioned twice in docs/decisions.md, both inside #412's own body ("the test job's memory instrument (added in #411) now reports ..." and "the older #411 probe ... is superseded"). Like #390, #411 never had its own ## heading — its "decision" was narrated retroactively inside #406 (the "Measurement is now continuous" paragraph, which describes the instrument #411 actually shipped) and explicitly marked obsolete inside #412's own prose. Since there is no standalone #411 record, there is nothing to move to archive/; ci.peak-anon-measurement (#412) — the record that supersedes #411's approach — carries supersedes: none and documents the prose reversal in its **Signals:** line. The governed surface (CI memory measurement) still exists and is very much active, so this is a straightforward supersession of an unnamed predecessor, not a retirement — there's no case to make for retired here since the surface it measures is live.

Still open (tracked for later migration passes, not this PR)

  • ## 2026-07-11 — Queue state lives in the pinned Gitea tracker (#237), not in the handoff file is reversed by #520, not #521 — per the task-5 brief its supersession lands in PR2/Task 8, not here.
  • The remaining ~90 headings in docs/decisions.md and the other three docs/decisions/*.md topic files (optimistic-concurrency.md, api-auth-security.md, spa-modularization.md, and the rest of release-ci-governance.md) are unmigrated (status: legacy-unmigrated, no metadata block). They are valid under the schema as-is (the validator treats an unmigrated H2 as a migration target, not an error) and migrate incrementally as each is next touched, per the arc's design.