research
docs://contents>
docs/retry-and-recoverydoc 14

Retry and Recovery

Recovery machinery exists to answer one question: when something fails, what is allowed to happen next — and for how long. The answer is a nested budget hierarchy, an escalation ladder, bounded regeneration with a circuit breaker, and checkpoint-based resume. Every mechanism is bounded; none can loop indefinitely.

The budget hierarchy

Level Bound Exhaustion behavior
Iterations per attempt Planner-verifier cycles Attempt fails, critique loop ends
Retries per step Execution attempts Escalation ladder begins
Escalations Human signals before park Workflow parks with diagnosis
Regeneration cap Child generations per SUB_SOP Parent-side escalation, then park
Global timeout Wall clock, max_global_workflow_timeout_ms Run terminates; unconsumed HITL responses stripped

Budgets bind the workflow, not the incarnation. A resume-from restart, a new generation, a re-entered attempt — none of them reset what the run has already consumed. This is the property that makes budgets real: consumption is recorded in the ledger, and the ledger is the run's memory.

The escalation ladder

Each tier signals a human with the step's diagnosis and the inputs already consumed. A response is consumed exactly once, by the first escalation that reads it; an unconsumed response is stripped at hard-cap termination and cannot leak into a later, unrelated gate. The ladder's terminal state is the park.

The circuit breaker

Regeneration exists for transient failure. A deterministic failure — identical signature, identical inputs, no state change between attempts — is not transient, and regenerating against it produces a storm. The breaker enforces the distinction: consecutive generations with the same signature halt regeneration immediately, and the workflow parks with the signature and diagnosis attached. Full mechanics in sub-SOP orchestration.

Resume-from

Mechanism Semantics
Checkpoint Completed prefix, artifact references, budget consumption
Re-entry The failed step re-enters the pipeline at hydration — the completed prefix does not re-execute
Seeding Terminal artifacts from the prefix hydrate into downstream context as before

Park resolution classes

Class Semantics Effect
Data provision A human supplies the missing input Fresh planning iteration with the data in scope
Instruction A human corrects the step's directive Fresh planning iteration under the correction
Gap acceptance The input gap is confirmed real Zero-case exemption honored; step completes on the acknowledged gap
Reject The step's goal is wrong Terminal — compensation path

A generic retry response against a data-level gap re-enters planning with unchanged context and fails identically — the input still contains nothing to select. The engine surfaces this: the escalation payload's diagnosis states which condition holds, and the park distinguishes data-level gaps from transient conditions. The distinction is not advisory; the correct resolution class follows from the diagnosis.

One-shot consumption

A HITL response is consumed exactly once. On consumption, the step's execution state is cleared and planning rerun with the response in context — a fresh iteration, never a blind re-run of the failed attempt. The semantics are specified in HITL gates.

NOTE — The response classes and the budget-persistence rules above are specified from incident post-mortems on the running system: a park whose only offered resolution was retry against a zero-selection input, and escalation counters that reset per generation. Both behaviors are defects of the same class — budgets and resolutions that do not survive a context boundary — and both are closed in the current baseline.