Skip to content

ADR-0086: A Spill Response branch is a container, and its stated condition is corrected by an act of its own

Status: Accepted Date: 2026-09-20

Decisions

D-179 A Spill Response branch is a container rather than an attachment row, and D-176 never governed it

ADR-0084 treats five models as the rows a correction replaces, and D-176 rules that superseding one of them is a field on the selection command rather than a command of its own. That ruling is about selections. A SpillResponseBranch is not one, and the two facts that say so were both already in the record before this ADR:

  • It may hold no Source Span at all. conditionSourceSpanId is nullable by D-97, because half the curation spike's sample states no branch condition and both shapes are legitimate GHS. Every other row ADR-0084 covers always displays at least one passage. A selection that displays nothing is the thing the selection command's required-passage rule exists to forbid.
  • It owns other rows. D-177 says so in its own words — "not only an attachment row; it is the parent its steps hang from" — and no other row ADR-0084 covers has children.

So the five were grouped because they all carry an ordinal, which is true and is about D-172's mechanism rather than about what the rows are. D-176 stands unamended and in full force for the four rows it actually governs. This ADR narrows what D-169's "attachment row" was ever reaching.

D-180 A branch's stated condition is corrected by superseding the branch, through a command of its own, named for the row

POST /v1/curation/branch-supersessions replaces one live branch with its successor in one statement, marks the two sides as D-169 requires, releases the replaced branch's position as D-172 requires, and re-parents its live steps as D-177 requires.

The body is scoped to the condition, because the condition is the only content a branch holds that this act can change. Its ordinal is where it sits, and a correction replaces a row where it sits. Its steps are rows of their own, which move rather than change. So the request carries the branch, the Section the condition is drawn from, the stated condition or the instruction to keep the one already there, a Curator, a reason, and the document's resolutions.

Three states for the condition, and they are the selection command's three exactly (D-169, D-178): a stated passage becomes a new Source Span judged like any other; keep carries forward the span the replaced branch was displaying; and a stated absence records that the document states none (D-97). Naming the condition as kept and stating it is refused.

Named for the row and not for the field, and that is the ruling rather than a label. Every correction in this product is named for the act, because D-150 refused an update that wears a create's name. A route called branch-conditions reads like a field a caller sets, and the next agent to meet one reaches for PATCH and an in-place write — the overwrite this whole line of rulings exists to refuse.

D-181 Its refusal table declares every code it can throw, borrowed ones included

A branch supersession that states a condition runs the whole-document verification gate, the verified-text check and the resolution builder, so it can refuse for reasons those already name. All of them are declared in this command's own table, which is what D-136 requires and what reconcile-restriction already does for the three resolution codes it shares with the selection command.

Fourteen codes: one from the verification gate, one from the verified-text check, one from the Section lookup, six from the resolution builder, and five of its own — SUPERSEDED_BRANCH_NOT_FOUND, BRANCH_ALREADY_SUPERSEDED, KEPT_CONDITION_RESTATED, CONDITION_NOT_ON_SUPERSEDED_BRANCH and BRANCH_CONDITION_UNCHANGED.

Nine of the fourteen already have Thai wording, because the curator surface's table is keyed by code and deduplicated across commands. So declaring the borrowed ones costs nothing on the far side and keeps the property D-136 exists for: a code the API can emit is a code the contract and the committed fixture carry.

Context

ADR-0084 ruled that a curated selection is superseded or retracted, and D-177 ruled that superseding a parent re-parents its live children, naming the Spill Response branch as the case. Building it found that the branch half of D-177 cannot be reached: a branch is created implicitly by its first step, so nothing in the selection command addresses one, and there is no request a Curator can send that names a branch as the row being replaced.

Retraction reached it, because a retraction addresses rows by id and kind and needs no passage. Supersession did not, because the selection command's request is one required passage plus attachment-specific extras — and a branch may carry no passage at all.

That is the gap this ADR closes. It is the second thing implementing ADR-0084 found that its own text did not reach; ADR-0085 was the first.

Decision

A Spill Response branch is a container rather than a selection, so D-176's rule about where a supersession lives never governed it. Correcting a branch's stated condition is its own command, addressing the branch by id, named for the row it replaces and scoped to the one value a branch holds that such an act can change. It declares every refusal it can make, borrowed or its own.

Rejected options

  • A fifth attachment kind on the selection command — rejected. It would require the required-passage rule to grow an exception for one kind, and that rule is what makes "a selection displays something" structural rather than conventional. It also cannot express the case that motivated this: correcting a branch from states a threshold to states none means arriving with no passage and nothing kept, which is exactly the shape the rule refuses. An exception carved for one kind is how the next agent learns the rule is negotiable.
  • A command of its own, ruled as an override of D-176 — rejected, and this is the option this ADR was first drafted as. It builds the identical command. It loses on what the ADR then says: an override invites the next reader to weigh D-176 against this and wonder which governs their case, where a clarification leaves D-176 untouched and unambiguous for the four rows it does govern. The code is the same; the record is not.
  • Correcting the condition through a step supersession — rejected, and it is the cheapest option by some way: the condition already travels on a SPILL_RESPONSE attachment, so a supersession carrying a different one could supersede the branch alongside the step and no new ADR would be needed at all. It loses because it records one act where two happened. A Curator who wants only a threshold corrected must supersede a step they did not intend to touch, and the single reason and curatorName then stand behind a step change nobody meant to make — which is the judgement D-173 requires be recorded honestly.
  • Declaring only the codes this command defines, letting the borrowed ones surface from the shared builders — rejected. It saves nothing, because the borrowed codes are already worded on the curator surface, and it breaks D-136's derivation, which is the property that makes a code the API can emit necessarily a code the contract and the fixture carry.

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 give the selection command a branch attachment kind, and do not relax its required-passage rule to admit one.
  • Do not rename this command after the condition, and do not add a PATCH or any in-place write to it. The row is replaced; that is what the name has to say.
  • Do not remove SPILL_BRANCH_CONDITION_CONFLICT on the grounds that a sanctioned correction path now exists. It is what keeps that path sanctioned: without it a Curator changes a stored threshold by restating a different one on a step, with no supersession recorded and nobody named.
  • Do not collapse BRANCH_CONDITION_UNCHANGED into the selection command's SUPERSEDES_NOTHING_CHANGED. They are different sentences to a Curator, because here the only thing that can have changed is the condition.

Consequences

What becomes easy. D-177 becomes reachable in full: a branch can be superseded, its steps move with it keeping every judgement recorded about them, and a stated threshold can be corrected without charging a procedure's worth of Reconciliations for a typo.

What becomes hard. Nothing that was not already hard. A branch supersession that states a new condition faces the same gates and the same unjudged pair any new span faces (D-171).

What this costs. A ninth curation command; five new refusal codes, so thirty-three in the curator surface's table rather than twenty-eight, each needing Thai wording and at least one golden fixture case.

What is closed off. A branch attachment kind on the selection command. An in-place condition edit. Correcting a threshold as a side effect of superseding a step.

Stated so it is not discovered later: dropping a branch's condition does not reach D-175. A branch that states no condition still displays its steps, so the Spill Response field is not emptied and no assertion about the document's silence is involved. "Removing content" and "emptying a field" look adjacent and are different acts.

Coverage

No upstream finding lands here. This came from implementing ADR-0084 and finding that D-177's branch half had no reachable request — the same way ADR-0085 arose, and the same way ADR-0021 and ADR-0038 recorded gaps found while working rather than while deciding (D-104).

UpstreamLanded inEvidenceNote