0026 — Execution is per question, because action is

The failure

ADR-0022 put Application in execution.stateone slot per row. A block can hold up to 25 questions, and blocked has required --qid on resolve and on amend since multi-question blocks shipped, for a stated reason: an answer that cannot say which question it means is not an answer. Execution never got the same treatment, so a row with four questions had four actions and one slot.

b89144129 is the record that proves it. Four questions. Three carried out — the worker was restarted, the stale CPU job was gone, the vendor question was overtaken by a later ruling — and the fourth, stamping the existing Conversation records, genuinely unapplied. The row could be called neither:

So it was left unrecorded, which is the third lie: not started, about three things that were finished. The 600s sweep re-armed a fresh driver roughly every third tick, each driver's nag count reset to zero, and the row was typed into a live pane sixteen times. Every one of those wakes asked its recipient to go and re-do three things that were already done, in order to chase one that was not.

This is ADR-0022's own diagnosis one level down. That ADR exists because one status could not hold three facts; this exists because one slot cannot hold N actions. The tell is identical — a state the model cannot express gets rounded to the nearest one it can, and the rounding is invisible.

The decision

1. Application binds to the QUESTION; the row's state is folded from them

executions is a map of question id → the record execution always held (state, evidence, at, by). blocked executed <id> --qid <q> writes one. A single-question row is unchanged and keeps writing the row-level slot.

The ROW's application state is folded, and the fold must not round:

when the row reads
any question carries a word nobody defined unknown
nothing live, every question superseded superseded
nothing live, otherwise applied
every LIVE question blocked blocked
nothing terminal, nothing started queued
otherwise — partly applied executing

executing is a LIVE word, so a partly-applied row keeps being armed. That is the point: keep nagging for what is left, stop nagging for what is done.

⚠️ blocked deliberately loses to a drivable question. A row with one blocked question and one queued one has work a wake can still move; folding it to blocked would stand the driver off from a live question — ADR-0022's decision 2 inverted, turning a stand-off that protects a lane into one that abandons it.

2. A multi-question row refuses a record that does not name a question

blocked executed <id> on a multi row now refuses, naming the questions and the ones still unrecorded. --all fans one evidence out into a record per question — the honest way to say "this covers the whole row", and it leaves a later partial read working.

This is resolve's and amend's existing rule, finally applied to the third verb. Writing an unqualified record to the row-level slot instead is not a neutral fallback: it silences the nag for every OTHER question too, which is exactly the defect.

3. A legacy row-level execution covers EVERY question — nothing migrates

This is the load-bearing half. 226 records predate this and every one carries a single row-level slot. Two readings were available:

The second is chosen, and the reason is stronger than intent: it is the only reading under which no record on disk changes meaning. The fold is gated on executions being present, so a legacy row does not enter it at all and keeps its RAW word — done, not applied — which is why the sweep's manifest bucket keys cannot shift under any record currently on disk. done stays a terminal spelling forever, exactly as ADR-0022 said.

A per-question record overrides the row-level slot for the question it names, and only for that one. That is also the migration path: an old row-level done plus one question corrected afterwards reads as three applied and one outstanding, with nothing rewritten.

4. The wake names what is outstanding, and only that

ADR-0020 ends at delivered; what gets delivered is this ADR's business. The wake is a pointer (2026-09-11) and stays one — it names up to three outstanding question ids, counts the rest, and spells the --qid the writer now requires. An empty outstanding list — a single-question row, an unreadable row, or an activity result recorded before the field existed — types the line it typed before, byte for byte. () is never a claim that nothing is left.

What this does not do

Consequences

The two repos ship separately and are safe in either merge order: the reader handles both shapes, and the writer landing first merely leaves a partly-executed row nagging for all its questions rather than one — more nagging, not less, which is the direction a gap should fail in.

The cost is a second shape in the ledger, forever. That is accepted for the same reason done is kept forever: the alternative is rewriting history to make the present tidy, and a ledger that edits its own past is worth less than one with two shapes in it.