A SOW declares whether it is in force and when each contract is paid — liveness is read, never inferred, and no default runs every turn

Accepted

ontoref
Until this decision a SOW stated its terms and its signature, and nothing about whether those terms

Context

Until this decision a SOW stated its terms and its signature, and nothing about whether those terms were still in force. `ratification.deadline` is the deadline to sign, not a validity. Every reader that needed «is this SOW live?» therefore had to infer it, and inferred it differently.

MEASURED IN DD-eca ON 2026-10-01. Its gate (`scripts/wo-gate.nu`) read a SOW as live while its delivery receipt was not signed. No receipt was ever signed, so 23 SOWs stayed live for good. A per-turn Claude Code `Stop` hook selected the contracts whose scope the turn touched: with 136 untracked paths across the constellation it ran 133 contracts of those 23 SOWs on every turn, 71 of them with cargo, in series — a trivial act took up to 8 minutes and drafting three SOWs 35 — and the checks that had gone stale (labels renamed, scripts gone, tests renamed) were always red, so the hook blocked the end of every turn and pushed the agent to «repair» SOWs foreign to its task. The loop fed itself. Archiving the 58 SOWs of its three levels by hand, no byte edited, took the turn from 133 contracts to 0 and from minutes to 0.13 s.

Two things were missing, and each is a term of the SOW, not of its signature (an attestation certifies a fact and does not expire — signatio ADR-003): whether the SOW is in force, and how much certainty each of its contracts buys, at what moment. The second is where the cost was: whether an 8-minute cargo run is justified depends on what is at stake and on the certainty wanted before the work is accepted, and a global per-turn hook had answered that for every SOW at once.

The reference the principal named is not new: public works tendering — the specification, its addenda and modifications, the period of validity, and the archive of closed files. Validity and amendment are its vocabulary, and the registry of a level is its file of record.

Decision

THREE OPTIONAL TERMS OF A SOW (schemas/sow.ncl), and how they are read.

VALIDITY — whether the SOW is in force NOW. NOT UNIFIED: a declared value (`'Value`) or an executable reading of state (`'NuCmd`, run at the governed root, its last stdout line the reading). Either way the reading is `true`, `false` or `unknown`; a command that fails or prints anything else reads `unknown` — a broken reading is uncertainty, not refusal. A SOW WITHOUT validity is not valid: it is inert, its place is `<level>/.governance/archive/` (adr-097 as amended), and it never blocks current work.

ON_UNKNOWN — required inside every validity. The uncertain reading is part of what is possible, and the SOW that can read true and false says what unknown does: `'Stop` (halt) or `'Skip` (pass). Sometimes halting is the safe move and sometimes passing is; the SOW decides, never a gate.

PAY_AT — per contract, the moments it is paid: `'Refute` (before ratification), `'Commit`, `'Receipt`, `'Turn`. The default is `['Receipt]`, what governed delivery always did. NO DEFAULT MAY MEAN EVERY TURN: a contract runs per turn only when its SOW declares `'Turn`.

LIVENESS IS A READING ONTOREF GIVES, never a gate's own inference. A SOW is live when it sits in its level, is ratified by what can be proven now (adr-122), is superseded by no ratified successor (adr-097), and its validity reads true. `form registry-sow` gives every SOW of a level with its place, stage, validity, liveness and relations; `form due-sow <paths> [--at <moment>]` gives the contracts of live SOWs that cover those paths, each with `pay_at` and an `action` — `pay`, or the SOW's own `on_unknown` as `stop` / `skip`. Their JSON is the published surface; consumers read it, they do not import it (adr-124).

Constraints

  • Hard A SOW whose validity is absent, false or unproven is never live: liveness requires a validity reading of true.
  • Hard Every validity declares `on_unknown` ('Stop | 'Skip), and the contract does not make it optional.
  • Hard No default of `pay_at` in the Sow contract includes 'Turn: a contract runs per turn only when its SOW declares it.
  • Soft A gate that needs to know which SOWs are live, or which contracts a change owes, asks `form due-sow` (or `form registry-sow`) instead of deciding it from receipts, globs or predecessor fields of its own.

Alternatives considered

  • Infer liveness from the delivery receipt (live until a signed receipt closes it) — rejected: What DD-eca's gate did, measured: receipts were not signed, so 23 SOWs stayed live indefinitely and their stale checks blocked every turn. A bookkeeping step nobody performs cannot be what keeps a mandate alive.
  • One typed validity shape (a date range, or an enum of lifecycle states) — rejected: Rejected by the principal (2026-10-01): validity may be a simple value or a function over state, and only its result is demanded. A date range cannot state «until the receipt is signed» or «while the service is up»; an enum of lifecycle states would be a second ratification model.
  • Treat unknown as false (or as true) in the gate — rejected: Either collapses a real possibility into a pole chosen by the reader instead of the SOW. Sometimes halting is right and sometimes passing is; the SOW that ratified the terms is the party that knows which.
  • Keep contract cost a property of the hook (a global per-turn or per-commit runner) — rejected: That is the configuration that ran 133 contracts per turn. Whether a contract's certainty is worth its cost at a given moment depends on the case, and the case is the SOW.

Anti-patterns

  • A SOW is live because nothing closed it — A gate reads «no signed receipt» or «not superseded» as «in force». Every unsigned receipt then becomes a perpetual mandate, and stale checks from SOWs nobody works on block the work in progress.
  • The hook decides the price of certainty — A per-turn hook runs every covering contract regardless of what its SOW declared, or a schema default is changed to 'Turn «to be safe». The cost of the most expensive contract is paid on every turn by every SOW.
  • Unknown is folded into pass or fail where it is read — A gate treats an unknown validity as false (retiring contracts on a flaky reading) or as true (keeping them on a broken one), ignoring the SOW's `on_unknown`.

Related ADRs

ADR-066 · ADR-097 · ADR-105 · ADR-122 · ADR-123 · ADR-124

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

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