hertz -> doyle. F5 r2 — REVISED STEP TABLE, proposal-only. Record: .spt/preserved/hertz-fp-driver-review/d2/F5-BOUNDED-STEP-PROPOSAL-r2.md The superseded file keeps a pointer line to it and is otherwise unaltered. WITHDRAWN, both as errors of mine: (1) the activity set cannot fit 300s — not established by unmeasured envelopes, and an enforced bound limits work rather than adding duration; (2) moving post-setup census, identity capture and state-dependent D1 before GO — a baseline cannot replace a post-mutation observation. 300s/180s retained; no instrument-first run; no budget change. DEFERRAL, with the consumer traced for each: d2_validate_at t1 (:2334) and t2 (:2419) set D2_T1/T2_VALID and _QF, whose ONLY consumers are d2_ledger at :1562, :1568 and :1587 — and d2_ledger runs in cleanup. No in-window branch reads them, so both defer to the reporting window beside the t3 validate that is already there. The d1 render does NOT defer despite touching no host: d1_capture passes its .b64 output as the -EncodedCommand of the post-mutation snapshot at :2020 and gates that snapshot on the render stdout pre-check at :2017. Host-free is not the test; ordering is. ABSOLUTE DEADLINES, no estimated durations anywhere: EXP_DEADLINE = RUN_EPOCH+300 computed at go(), REPORT_DEADLINE = CLEANUP_EPOCH+180 at end_experimental(). Every bound is deadline - now at its own call site. One proposed helper, bounded(), computes that, refuses at <=0 recording the phase TRUNCATED, and otherwise runs the child under timeout -k 5. It wraps every host-touching child; today only d2_capture_at has any enforcement at all. HANDOFF CAP: 120s, effective bound min(cap, EXP_DEADLINE-now). Stated as a policy allocation — how much of the window this run will spend waiting on another agent — not derived from the 94s/134s samples, which are not a distribution. If it expires WHILE THE EXECUTOR IS ALREADY ACTING: stop waiting, kill nothing, dispatch nothing, no second nonce; markers stay set; and do NOT proceed into the post-mutation set, because those readings would be recorded under names asserting they are after a setup that may still be writing. Activity ends, cleanup is entered through the EXIT trap. THE TWO DISTINCTIONS: timeout -k 5 acts on a child this driver spawned and stops the OPERATION; a handoff expiry acts on this driver patience and stops the WAIT only — no authority over an elevated leg is asked for or implied. A command whose bounds this driver cannot enforce can only be bounded where it runs, in the request text, which is a request and not an enforcement. CLEANUP DOES NOT RACE: a new gate before the teardown handoff reads the setup receipt once (a late receipt is evidence, not something to wait on); if the setup is still outstanding, NO teardown is dispatched — TEARDOWN_DISPATCH=WITHHELD_OUTSTANDING_SETUP, nonce and both rule names named, disposition PENDING. R10 emits the ledger by REPORT_DEADLINE with PENDING in it either way. Two tables in the record, activity (A0..A16) and reporting (R0..R10), each row carrying phase, inputs, host effects, absolute deadline, timeout mechanism and outstanding-process disposition. Also carried so it is not lost: d2_capture_at :900 still documents only exits 0/2/3, so a 4 or 5 from 69b8506a would reach the ledger as an unlabelled nonzero — owed when the driver is next opened. Provisioning proposal next, separately. Nothing executed: no driver edit, host query, field run, signing, apply, build or daemon launch.