Skip to content

ADR-0035: A superseded finding says so on its own page, and a gate enforces it

Status: Accepted Date: 2026-09-08

Decisions

D-81 A superseded or amended finding carries its own status marker, naming what replaced it

**Superseded by:** R-22, R-23 or **Amended by:** R-33, on a line of its own directly under the finding's heading. The record is two-sided: the replacing note still says what it supersedes, and the replaced finding now says it was replaced. Neither side alone is sufficient.

D-82 A Coverage row whose upstream is superseded must name the replacement, and IDSTATUS fails it otherwise

Citing a dead finding is not forbidden — this repository does it deliberately, with rows such as D-26's "superseded by D-44; retained because §7 keeps the failure visible". What is forbidden is citing one silently. The row's Note must name a superseding id.

D-83 Coverage Note cells in an Accepted ADR may be edited for traceability bookkeeping; nothing else in an Accepted ADR may be

This is a narrow, explicit exception to the never-edit rule, and it is drawn here so that the four Note edits this ADR accompanies are not read as licence. A Note records where a decision landed and whether its upstream is still live — bookkeeping about the decision, never the decision. Status lines, Decisions, Context, Rejected options and Consequences remain untouchable; changing any of those still requires a new ADR.

D-84 Partial replacement is an amendment, and an amended finding stays live and citable

Amended by means part of a finding was replaced and the rest survives. R-19 is the case: R-33 replaced its benefit list, while its observation that the claims carry no thresholds is still correctly cited by ADR-0001 and ADR-0017. Amended ids do not trigger D-82.

Context

The 2026-09-08 cross-model grill found three Coverage rows in ADR-0031, ADR-0032 and ADR-0033 landing on findings superseded on 2026-09-02. Verification found a fourth in ADR-0001, untouched since it was written.

coverage_check.py passed all four, and correctly so — its rule 3 checks that an id referenced in a Coverage table was declared somewhere. Nothing checked whether the declaration was still current. The handoff already said "presence is not truthfulness". It was not currency either.

The repository had already diagnosed this exact defect one level up. adr_status_check.py exists because an adversarial review found ADR-0011 declaring "supersedes ADR-0003" while ADR-0003 still read Status: Accepted"two Accepted ADRs giving contradictory rulings, with nothing to warn a reader who opened the dead one directly." Findings had the identical shape and no gate: poster-v2.md said "Supersedes R-03" and R-03's own entry in source-poster.md said nothing at all.

And the correction already existed in prose. ADR-0018's D-34, written 2026-09-02, records that ADR-0005's Context "cites R-03's four settings (superseded by R-22/R-23)". Six days later two new ADRs cited R-03 as a live upstream anyway — and ADR-0018 had itself corrected ADR-0005's prose while leaving ADR-0005's Coverage row standing. The same session also cited R-04.2, an objective ADR-0018 D-33 records as deleted and which ADR-0017 had already corrected another ADR for citing.

That is the argument for a gate rather than another correction document. A prose correction is read once by the person who writes it. A gate is read every time anyone runs ./init.sh. Two separate corrections were on disk, in accepted ADRs, and neither was re-read at the moment it mattered.

Decision

Findings record their own supersession, in the same two-sided shape ADRs already use. A new gate, IDSTATUS, asserts that every supersession claim is matched by a marker on the target, that every marker names ids that exist, and that no Coverage row cites a superseded upstream without naming what replaced it. It runs unconditionally in init.sh alongside the others and is counted in GATES.

Rejected options

  • Fold the check into coverage_check.py — rejected, and this is the decision that matters most. That gate currently reports 67 problems from stage 1's stack-conventions notes, a red everyone has learned to read past. A new defect would print as problem number 68. init.sh's own header records what that costs: "an abort-on-first-error chain meant four lint errors kept the typecheck gate from ever executing. Nobody noticed for two weeks, because the run was red for a reason everyone had learned to ignore." Building a new gate inside a known-red one is committing that failure deliberately.
  • A registry file of dead ids — rejected. It puts the truth somewhere nobody opens on the way to the finding. The reader who needs warning is the one who opened source-poster.md and is reading R-03 right now.
  • Infer supersession at gate time from the "Supersedes" claims, writing no marker — rejected for the same reason. The gate would go green while every human and every agent opening R-03 still saw a live finding. The gate is not the point; the reader is. An agent grepping for R-03 to cite it is precisely how the four bad rows were written.
  • Fail any row citing a superseded id — rejected. It would break three legitimate rows that cite dead ids deliberately and annotate them, and it would push authors to delete history rather than record it — the opposite of D-36's "Row retained, not dropped."
  • Treat every replacement as wholesale, with no amended state — rejected on evidence. Marking R-19 dead would have failed ADR-0001 and ADR-0017 on the gate's first run, both correct and both previously grilled. A gate whose first act is to fail good work teaches everyone that its failures are noise.
  • Warn instead of failing — rejected. A warning inside a run that already prints 67 problems is invisible.

This ruling may not be re-decided

If a change contradicts this ADR: stop and raise it. Do not implement over it.

Specifically: do not read D-83 as permission to edit anything else in an Accepted ADR — it covers Coverage Note cells and nothing else; do not silence IDSTATUS by removing it from GATES, which would leave it running and uncounted, exiting 0 on failure; and do not resolve a D-82 failure by deleting the row. Deleting a row destroys the traceability the row exists to provide, and the gate's message names the replacement precisely so the row can be fixed instead.

Consequences

What becomes easy. Citing an upstream is now safe: if it is dead, the gate says so and names the replacement in the error message. The failure that produced four bad rows cannot recur silently.

What becomes hard. Superseding a finding is now two edits rather than one — the replacing note and the replaced finding. That is the intended cost, and it is the same cost ADRs already pay.

What this does not fix. IDSTATUS checks currency, not correctness. Two rows the grill found — ADR-0031's R-32 row and ADR-0033's R-19 row — cite findings that are live but claim things those findings do not say. No currency gate can catch that, and both remain open. The gate has made one class of defect impossible and left the other exactly where it was.

What was found on the way. The four annotated rows are ADR-0001's R-04, ADR-0005's R-03 (the row ADR-0018's own correction missed), and ADR-0032's and ADR-0033's R-03. The last two carry a second defect: the grill found their claims unsupported on their own terms, independent of currency. Their Notes say so, and they stay open.

Coverage

UpstreamLanded inEvidenceNote
R-24D-81, D-84the finding whose supersession of R-04 deleted an objective five ADRs cited, unnoticed for six dayssupersedes R-04; cited here as the worked case
R-33D-84the partial replacement that proves an amended finding must stay citablesupersedes R-19's list only