The durable agent runs to an approval gate: a $180 refund over the $100 threshold. Instead of firing the tool it journals a pending_approval, raises a serializable PendingApproval (a token), and PAUSES. No money has moved. Then you, the human, decide. Each decision resumes by REPLAYING the same journal, never a fresh run.
The world: one run run-aa10, frozen timestamps 2026-07-06T09:00:NNZ by seq, threshold $100. The gated refund keeps its idempotency key ORD-3300:refund, so an approved resume executes EXACTLY ONCE even if retried. State is the FOLD over the journal, the same spine as Part 9.
Where we are in the story
1 · run2 · pause3 · human decides4 · resume
Waiting for a human decisiontoken appr-1
The run is paused, not dead. The token and the pending action are persisted in the journal. Pick one of three first-class actions. STEER is more than a yes or no: it injects a correction.
$
A steer to $100 or more is still over the threshold and would just pause again. Lower it under $100.
The journal, the ledger, and a live feed read from the same log
journal · append-only events (JSONL)0 events
ledger · where money actually moves
ORD-3300$0.00
No money has moved yet. The gate held the refund.
result
run status
Not started.
Streaming progress (a read over the journal events)
live feed · stream(journal)0 lines
The decision is a first-class action, not a binary gate. APPROVE and DENY are a yes or no. STEER is different: the approver injects a correction (here, lowering the refund under the threshold) that changes what the agent does next, then the run continues. Answering a clarifying question back to the user is the same mechanism. And because the gated refund keeps its key ORD-3300:refund, an approved or steered resume moves money EXACTLY ONCE, even if resume is retried.
How we keep it honest:interrupt() raises a serializable PendingApproval caught at the top level, NOT sys.exit, so a notebook or server stays runnable; it persists the journal and returns the token. resume() then REPLAYS that journal (step 0 memoized) and acts on the recorded decision. A real deployment pauses in one process and resumes in another over the same persisted log; here both phases run over one journal.
run / decision
pending / steer
tool result
approved / done
deny / blocked