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 SOW (`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. An archive inside `.coder/`, 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.

AMENDED 2026-10-01 — that paragraph took the evasion as the only reason an archive could exist, and the polarization settled while it was drafted. A level's SOWs also leave force for reasons that are not evasion at all: several versions of one SOW, and SOWs whose terms simply stopped being in force. Measured in DD-eca the same day: no SOW declared validity, so «live» was inferred from a receipt nobody signed, 23 SOWs stayed live forever, a new version did not retire the older ones (one SOW's v1–v5 still judged beside its signed v6), and a per-turn hook ran 133 contracts, 71 of them with cargo, blocking every turn on stale checks. Archiving its 58 SOWs by hand, signatures untouched, took the turn from 133 contracts to 0 and from minutes to 0.13 s. What separates that from evasion is not the path but whether the move is a CLASSIFICATION BY STATE that the gate can still check.

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.

AS AMENDED 2026-10-01 — supersession is one reading of the level's SOW registry (`form registry-sow`, reflection/modules/sows.nu), and three things widen it:

RELATION. A version relates to earlier ones in one of two ways, declared in `relation` (schemas/sow.ncl): 'Supersedes leaves the targets obsolete; 'Amends extends one or several targets, which stay part of the contract and are owed under the amending SOW's validity. `predecessor_sow` / `predecessor_wo` read as 'Supersedes of one target. Only 'Supersedes stops evaluation. Whether an amendment needs a fresh signature is decided by its flow, not by the schema.

VALIDITY. Whether a SOW is in force, and when each contract is paid, is adr-127. What this ADR reads from it: a SOW whose validity does not read true is not live, and one without validity belongs in archive/.

ARCHIVE BY STATE. `<level>/.governance/archive/` holds SOWs out of force. A SOW is archived (`form archive-sow`, one event in ledger/archive.jsonl) only when its validity is absent or false, with its bytes, name and signatures untouched; its stage is derived from the place, never stored; and the commit gate fires on archive/ too, blocking a SOW there whose signatures no longer verify or whose validity reads true or unknown. The archive is inside the gate, not around 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.
  • Hard The commit gate that runs biop on a staged SOW also fires on `.governance/archive/`, and there blocks a SOW whose signatures no longer verify or whose validity reads true or unknown.
  • Hard `form archive-sow` refuses a SOW whose validity reads true or unknown: a SOW is archived because it is out of force, never because a contract is red.

Alternatives considered

  • Teach `absence-reverified` to read `predecessor_wo` itself — rejected: 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 alone — rejected: 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:` pattern — rejected: 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. (Amended 2026-10-01: still rejected as stated — OUTSIDE the pattern. What the amendment adopts is different in the one property that matters: archive/ stays inside the gate's pattern and the gate checks the move is by state.)
  • Let the pre-commit hook skip files it judges historical, leaving `biop run` untouched — rejected: 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 · ADR-127

Perspectives
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