What happens
scripts/wiki-check.mjs freshness-checks every page identically. It mentions superseded exactly once — at line 52-55, in a comment explaining that decisions/ legitimately use status: for their lifecycle:
// Legacy tooling-owned fields (decisions/ legitimately use `status:` for
// their lifecycle — proposed/accepted/superseded — so only flag the old
// computed freshness values).
if (/^status:\s*(fresh|stale|unmanaged)\s*$/m.test(parts.fm) || /^last_checked:/m.test(parts.fm)) legacyPages.push(rel);
The code never reads that value. So a record marked status: superseded is checked for drift like a living page — and it can never come back, because AGENTS.md forbids the only thing that would fix it:
Decision records are immutable-with-supersession: once status: accepted, never rewrite the decision […] When wiki-check.mjs flags an accepted decision stale (its covered files changed), that is a prompt to consider a superseding record, not to edit the old one.
For an accepted ADR that rule works: stale is an actionable prompt with an exit. For a superseded one there is no exit — the supersession already happened, and there is nothing left to do, ever. It contributes to the stale count and to the non-zero exit code permanently.
Why it matters
It is the erosion AGENTS.md warns about in the refresh-by-rote passage, arriving from the other side: a check that can never read clean stops being read.
This is not hypothetical at scale. In a repo that just deleted a predecessor system, five decision records went permanently stale at once — three superseded, two accepted whose covered files merely moved. The check will now never report all-green again, and the three genuinely-terminal ones are indistinguishable from the two that might still deserve attention.
Suggested shape (owner's call)
Split by lifecycle rather than muting decisions/ wholesale — the accepted-ADR signal is real and worth keeping:
status: superseded → its own reported category (ARCHIVED / historical), excluded from the stale count and from the exit code. Freshness is meaningless for a record whose whole job is to describe a past state.
status: accepted, covered file changed → stale, as today. Actionable: consider a superseding record.
status: accepted, covered file deleted → arguably deserves to be louder than a normal stale, not quieter. A live decision record covering code that no longer exists is the strongest possible "you owe a superseding record" signal, and today it is indistinguishable from a whitespace change.
A wiki-stamp guard that refuses to stamp a superseded record would close the same loop from the other end — stamping one asserts prose reflecting current code, which a superseded record by definition does not.
Version
Reproduced at cfe6ce4; also present in the 0.4.7 scripts vendored into a consuming repo.
What happens
scripts/wiki-check.mjsfreshness-checks every page identically. It mentionssupersededexactly once — at line 52-55, in a comment explaining thatdecisions/legitimately usestatus:for their lifecycle:The code never reads that value. So a record marked
status: supersededis checked for drift like a living page — and it can never come back, becauseAGENTS.mdforbids the only thing that would fix it:For an accepted ADR that rule works: stale is an actionable prompt with an exit. For a superseded one there is no exit — the supersession already happened, and there is nothing left to do, ever. It contributes to the stale count and to the non-zero exit code permanently.
Why it matters
It is the erosion
AGENTS.mdwarns about in the refresh-by-rote passage, arriving from the other side: a check that can never read clean stops being read.This is not hypothetical at scale. In a repo that just deleted a predecessor system, five decision records went permanently stale at once — three
superseded, twoacceptedwhose covered files merely moved. The check will now never report all-green again, and the three genuinely-terminal ones are indistinguishable from the two that might still deserve attention.Suggested shape (owner's call)
Split by lifecycle rather than muting
decisions/wholesale — the accepted-ADR signal is real and worth keeping:status: superseded→ its own reported category (ARCHIVED/historical), excluded from the stale count and from the exit code. Freshness is meaningless for a record whose whole job is to describe a past state.status: accepted, covered file changed → stale, as today. Actionable: consider a superseding record.status: accepted, covered file deleted → arguably deserves to be louder than a normal stale, not quieter. A live decision record covering code that no longer exists is the strongest possible "you owe a superseding record" signal, and today it is indistinguishable from a whitespace change.A
wiki-stampguard that refuses to stamp asupersededrecord would close the same loop from the other end — stamping one asserts prose reflecting current code, which a superseded record by definition does not.Version
Reproduced at
cfe6ce4; also present in the0.4.7scripts vendored into a consuming repo.