# AUTOPILOT-53 — the 30-minute figure is a DEFAULT, not a universal ceiling

## Verification (against this checkout, main @ 50f09ed / 0.6.0)

AUTOPILOT-47/AUTOPILOT-52 built the framework's entire budget model on one
claim: the runtime truncates **every** spawned child to a fixed 30-minute
per-step ceiling, regardless of the `timeoutMs` requested at dispatch —
`src/framework/run-budget.ts`'s `RUNTIME_STEP_BUDGET_CEILING_MS`, the
`assessRequestedBudget`/`budgetCeilingWarning` truncation pair, `recoveryPlan`'s
clamp of its ×1.5 escalation, and the "This run WILL be cut off" warning text
all rest on that claim.

AUTOPILOT-53's investigation (queue item notes) reached the opposite,
decisive conclusion: **the item's `timeoutMs` IS honoured end to end when it
is set at dispatch time.** The 30-minute figure (`DEFAULT_ASYNC_TIMEOUT_MS`)
is the runtime's *default* — the value it falls back to only when NO budget
is supplied — not a ceiling that clamps an explicit, larger request.

This checkout is consistent with that conclusion still being current: nothing
in the codebase re-verifies the old trace against the installed runtime (the
AUTOPILOT-47 doc pins its trace to `pi-subagents@0.66.0`'s source at fixed
line numbers, which this repo does not vendor and cannot re-check), and the
code still asserts and enforces the disproven universal-ceiling model
unchanged since AUTOPILOT-52. No commit between 50f09ed and this branch
touches `run-budget.ts` or `auto-recovery.ts`'s clamp. The fix below removes
the false ceiling assertion and closes the actual remaining gap AUTOPILOT-53
identifies: an item with no `timeoutMs` at all silently inherits the
runtime's 30-minute default, invisibly, which is too short for most work.

## The two-part fix

1. **Correct the model** (`run-budget.ts`, `auto-recovery.ts`, `queue-ops.ts`,
   `docs/AUTOPILOT-47-budget-and-liveness.md`): stop asserting a universal
   ceiling, stop clamping `recoveryPlan`'s escalation to it, stop warning that
   a budget above 30m "WILL be cut off". An explicit `timeoutMs` is honoured;
   only an ABSENT budget falls back to the runtime default.
2. **Stop dispatching with a null budget**: every spawn site now applies an
   explicit, visible default (`DEFAULT_DISPATCH_BUDGET_MS`) when the item
   carries no `timeoutMs`, records it on the item (visible in `queue_list`),
   and names it in the dispatch receipt so the operator can override it
   (`queue_update({timeoutMs})`) instead of it silently defaulting inside the
   runtime where nobody can see or change it.
