Oroboro Labs
field notes

The pending state nobody lists

2026-09-05 · field note #109 · E-125

The gate from the previous note works: when the effect classifier says a scheduled task is destructive — or says nothing intelligible — the acceptance runner refuses to fire it and writes a receipt that ends in acceptance pending. That refusal is correct, and it creates something new: a population of tasks sitting in a state between registered and accepted. The scheduler shows them as Ready, exactly like every healthy task in the house. Blocked and forgotten are indistinguishable from the outside.

So the gate shipped with a debt. Today's instrument collects it: a small script that sweeps the acceptance receipts for the blocked line, asks the scheduler for each named task's last run and last result, and writes one CSV row per blocked task. The verdict for each row is one of three: pending (blocked, and no successful run since the block), accepted later (it already ran clean after the block), or orphan — a block receipt whose task no longer exists.

First sweep: one real, one orphan

The real population was two. One was the genuine case: the cleanup task classified destructive earlier today, sitting at 0x41303 — the scheduler's code for has never run — correctly pending, waiting for its own scheduled window. The other was the throwaway dummy from the gate's kill test, unregistered afterwards. The instrument didn't shrug at it; it exited non-zero, because a block receipt that points at nothing is a tracking failure, not an empty list. That distinction was chosen on purpose: an empty list means all clear, an orphan means the paper trail and reality diverged, and only one of them deserves silence.

The kill criteria were proven in both directions before trusting any output: a fake directory holding one block receipt for a nonexistent task exits with the orphan code, and an empty directory exits zero with an empty CSV. The instrument also proved honest in development — the first run missed the real pending entirely, because the receipt pattern didn't match the classifier's actual filename and the task name carried a state suffix. Both were found against the disk, not guessed.

Every gate mints a currency

The general lesson: a gate that refuses work doesn't make the work disappear — it mints a new state, and someone has to be able to enumerate that state or the gate is quietly manufacturing unreviewed inventory. The same is true of quarantined mail, blocked transactions, failed-verification artifacts, deferred migrations. Each one is a promise that a human or a process will come back. The promise is only as good as the list that can name every item waiting on it.

The sweep now runs beside the weekly census of waiting-class jobs, and the pending list has its own kill criterion: four consecutive weeks of empty lists and it degrades to on-demand. An instrument that never finds anything is a cost, not a guard — but that decision belongs to the numbers, not to fatigue.

Proof: radares\aceites-pendentes.csv · receipts: radares\e125-pendentes-20260905-*.txt + radares\e125-kill-criteria-20260905.txt · instrument: nave\e125-pendentes.py

Read before or after: The gate that fired anyway ; and The classifier that hadn't read the script.

Oroboro Labs is a one-person automation workshop publishing its own field notes. Numbers here come from receipts on disk, named above.

← The gate that fired anyway Work with the workshop