- Task: 2.4
- Evaluated: 2026-09-05
- Decision: typed-triage-enforced
- ADR gate:
typed-triage(docs/adr/ADR-0076-eve-governed-delivery-lifecycle.md) - Record digest:
3cf2b21b96ea38743b813408a50d7256b2b9a31dd943e7370b7208003b9812c4
The rule#
A requeue out of a held status and a close both refuse without a triage record, and the refusal writes nothing. Every record names one of a closed set of classes, carries at least one piece of evidence that points at something, and takes the retry disposition its class earns rather than the one its writer preferred. Triage explains; it never moves an item.
The classes, their meanings and their dispositions are read out of the contract module; each guarded exit must name a guard the store calls and a spec that watched it refuse.
The classes#
| Class | Named by | Means | Retry disposition |
|---|---|---|---|
ship-verify-gap |
task 2.4 | The artifact-diff verifier observed the knowledge plane and the shipped claim did not hold. | needs-human-decision |
test-failure |
task 2.4 | The agent's own checks failed; the work did not reach a reviewable state. | retry-when-ready |
conflict |
task 2.4 | A repository, lease, or state conflict blocked the attempt; the work itself was not judged. | retry-when-ready |
ambiguous-requirement |
task 2.4 | The brief could not be executed as written, so no amount of retrying it will help. | needs-human-decision |
budget-exhausted |
task 2.4 | A spend, time, or attempt budget ended the attempt before the work was finished. | needs-human-decision |
agent-refusal |
task 2.4 | The agent declined the work on policy, safety, or capability grounds and said so. | needs-human-decision |
lease-lapsed |
the runtime | The acquisition ended without a report — an expired lease, a vanished holder, or a superseded hold. | retry-when-ready |
not-observed |
the runtime | The item could not be read back after the attempt, so nothing is claimed about what happened to it. | needs-human-decision |
6 of the 8 classes are the ones task 2.4 names; the other 2 are shapes the runtime genuinely produces and cannot express with the six. All 8 meanings are distinct, and the classes resolve to 2 different dispositions — a taxonomy that answered the same way every time would decide nothing.
The two exits that may never be silent#
| Exit | Requirement | Guard | Proved by |
|---|---|---|---|
silent-requeue |
An attempt that leaves a held status for ready or parked must record why it ended; the refusal writes nothing to the append-only ledger. | triageRequiredFor |
refuses a silent requeue and writes NOTHING |
quiet-close |
A rejected item must record why it was refused, and a human is no more exempt than a machine. | triageRequiredFor |
refuses a quiet close and writes NOTHING |
Where the contract is reachable#
- Store refuses on transition: true
- Store appends a standalone record: true
- Queue exposes the canonical operation: true
- BFF route: true
- MCP tool: true
- Fleet drain records it: true
- Drain declares it as an allowed operation: true
- End-to-end probe asserts it: true
- The lease sweep triages automatically: true
Honest limits#
- This record closes task 2.4 only. It does not add the operator read model (2.5), execution isolation (2.6), the orchestrator model and parity proof (2.7), or any live drain or soak result (2.8).
- The retry disposition is recorded and enforced as a value; ACTING on it — re-leasing a retry-when-ready item, holding a needs-human-decision one — is the queue retry budget and quarantine from task 2.2, and no scheduler consumes the disposition field yet.
- The six named classes are proved reaching the ledger from a spec that writes them deliberately. Only lease-lapsed is produced automatically today, by the sweep; the other five arrive when an agent or a drain reports the signal that selects them.
- Classification from agent signals is provider-free and tested, but no real coding agent has yet emitted those signals: an agent that never says "my checks failed" is triaged lease-lapsed, which is honest rather than precise.
- Triage does not itself move an item. An operator still decides what happens next, and nothing in this task automates that decision.
- The two runtime classes beyond the task list are marked runtime-observed rather than folded into the six, so a lapsed lease is never counted as a spent budget.