Files
ersatztv/docs/decisions/archive
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
..

Archive — superseded / retired decision records

This directory holds decision records whose status is superseded or retired. They are kept verbatim (rationale prose untouched — see docs/decisions.md header and scripts/decisions_lib.py) for history: why we changed our mind is the point, never silently rewritten.

They are out of the active startup path: scripts/decisions_lib.py active_files() / all_active_records() do not glob this directory, docs/decisions/README.md (the active catalog) never lists a record from here, and an agent doing task-router discovery should not need to read this directory to find the current rule — follow a record's superseded-by key to the active successor instead.

The lifecycle validator (scripts/decisions_validate.py) still enforces invariants here:

  • a superseded/retired record MUST live under this directory, never in an active file;
  • an active record MUST NOT live under this directory;
  • supersedes/superseded-by keys must resolve reciprocally to a record in the active set OR here;
  • a record moved here must not have its rationale prose changed in the same commit (unless the commit message carries the [decisions-edit] token, reserved for genuine rationale edits).

One file per topic cluster (e.g. ci.md, release-ci-governance.md), mirroring the active docs/decisions/*.md topic-file split. See docs/decisions/migration-map.md for the legacy heading → key → status → location mapping produced during the #521 lifecycle migration.