A SOW with a ratified successor stops being evaluated as a live contract — supersession is decided by the evaluator, never learned by the cell

Accepted

ontoref
`sow-delegation-contract` (pre-commit) runs every biop against a staged

Context

`sow-delegation-contract` (pre-commit) runs every biop against a staged `.governance/<slug>.ncl`. It matches BY PATH and therefore cannot tell a superseded contract from a live one.

MEASURED 2026-08-20, and the cost is an asymmetric audit trail rather than a theoretical one. The domain-page delivery produced four ratified revisions. Three of them — each documenting a defect in its OWN checks — were refused entry by `absence-reverified`, whose claim is that a governed check must not call `rg` or `fd` with the narrowed default:

wo-domain-page-from-its-provider 5 pass, 1 blocking F-2 (phases) …-v2 5 pass, 1 blocking F-3, F-4 (oracles) …-v3 5 pass, 1 blocking F-5 (narrowed rg) …-v4 6 pass, 0 blocking the live contract

Their RECEIPTS committed without objection — receipts are not gated — so the verdicts entered git while the contracts that produced them could not. A reader of the corpus could see that a defective contract had been executed, and never read the contract.

The same asymmetry already existed for the previous Work Order (`wo-verify-state-harness`, superseded by `-v2` on 2026-07-21) and nobody had reason to notice, because nobody had tried to commit a superseded SOW before.

THE FIRST FIX ATTEMPTED WAS AN ARCHIVE OUTSIDE THE REPOSITORY, and it is recorded because it is the tempting one. `.coder/archive/governance/` with the signatures intact and a README. `.coder/` is gitignored: the contracts lived on one machine and were pushed nowhere. That is not preservation, it is the loss made tidy.

WHAT MUST NOT BE DONE INSTEAD is equally worth naming. Renaming a refused SOW into a tracked path outside the gate's pattern would put it in the repository by dodging the check — the `--no-verify` reflex with extra steps.

Decision

`biop run` resolves, before loading any cell, whether the SOW it was handed has a RATIFIED SUCCESSOR. If it has, the SOW is reported as historical, named together with its successor, and not evaluated as a live contract.

A successor counts only when all three hold, and every one of them is declared:

1. another `.governance/*.ncl` exports, and 2. its `predecessor_wo` NAMES this slug, and 3. its detached signature verifies against `.governance/witness.pub` — the same key `sow-ratified` already checks at run start.

The distinction lives in the EVALUATOR. No biop nucleus learns it.

Constraints

  • Hard A successor exempts its predecessor ONLY when its detached signature verifies against .governance/witness.pub. Existence and a `predecessor_wo` link are necessary and never sufficient.
  • Hard No biop nucleus may read `predecessor_wo`, or otherwise carry knowledge of the corpus it is evaluated in.
  • Hard When `biop run` declines to evaluate a superseded SOW it MUST print the fact and NAME the successor.
  • Soft Successor candidates are resolved with `glob`, never with `ls` over a string path, and never inside a try/catch.

Alternatives considered

  • Teach `absence-reverified` to read `predecessor_wo` itselfrejected: The shape this ADR was originally proposed in, and it is wrong at the schema level: a nucleus carrying corpus history stops being exportable, which `schemas/cell.ncl` states as the reason nuclei are stateless. It would also have to be repeated in every other cell that might one day block a superseded SOW — the second implementation of one rule that adr-081 refuses.
  • Archive superseded SOWs under `.coder/` and leave the gate alonerejected: Attempted and reverted the same day. `.coder/` is gitignored, so the contracts existed on one machine and were pushed nowhere. It converts a structural limitation into silent data loss, and leaves the audit trail asymmetric while looking tidy.
  • Move superseded SOWs to a tracked path outside the gate's `files:` patternrejected: Evasion with extra steps. It puts a refused artifact in the repository by renaming it out of the check's reach, which is the `--no-verify` reflex the sow-delegation-contract note already measures on markdownlint.
  • Let the pre-commit hook skip files it judges historical, leaving `biop run` untouchedrejected: Puts the distinction in one circuit, so any other caller of `biop run` — CI, a manual invocation, a consumer's own hook — keeps the old behaviour. Supersession is a fact about the SUBJECT, not a disposition of one circuit, so it belongs where the subject is loaded.

Anti-patterns

  • The version suffix is read as the successor link — A later author notices that `-v4` always follows `-v3` and resolves supersession by sorting names, dropping the `predecessor_wo` read or the signature check as redundant. The mechanism then exempts any file whose name sorts later, and the property that made this legitimate rather than a weakening — that every step is DECLARED — is gone.
  • The cell is made self-contained and stops being exportable — A reviewer objects that the rule is split between a cell and the evaluator, and moves the supersession read into `absence-reverified` so the cell «carries its own logic». The cell now depends on facts about the directory it sits in, cannot be adopted unchanged by a consumer project, and the same read must be repeated in every other cell that could block a superseded SOW.
  • The report is trimmed as noise — Someone running the gate over a large corpus finds the historical lines verbose and silences them, or folds them into the pass count. A SOW that was never evaluated then reads as one that passed, and the corpus reports a coverage it does not have.

Related ADRs

ADR-063 · ADR-066 · ADR-081 · ADR-095 · ADR-096

Was this useful? Rate it
Got something to add? Tell me what you think, what you'd suggest, or whether we should keep exploring this topic.
· reads

We use cookies to help this site function, understand service usage, and support marketing efforts. Cookie Policy for more info.