Skip to content

Halt Reasons

Documentation source v0.5.0-rc.1. Published releases

5. Halt reasons -> exit codes (canonical map)

The halt_reason string is the stable integration contract; the exit code is a coarse class CI can branch on without parsing JSON. Existing codes 0/10/11/12/20/30/40/50 predate this spec; 13-19 are new classes introduced here. The table below is the full normative taxonomy; which halt_reason strings the binary emits today versus holds reserved is tracked in section 11 - as of v0.2.0, every class 13-19 emits (their core reasons; 18 via inspect-cost, 15 via doctor --mutate-cmd), while only class 11’s task-list reasons (the task_list topology) stay reserved until their detectors ship. Every reason MUST be computed from observed state - --halt-reason is a hidden test fixture only.

exitclasshalt_reason stringsowner
0nominal(loop ran, no halt)LoopExec
10convergedsuccess_condition_metLoopExec
11terminal-blockedno_actionable_tasks, human_requiredhuman
12iteration-capmax_iterations_reachedLoopExec
13integrityblocked_path_modified, reward_hacking_detected, metric_integrity_violation, credential_scope_invalid, objective_unverifiedLoopExec (det.)
14oracle-untrustedcheck_flaky, check_has_side_effects, check_not_hermetic, hermeticity_violationLoopExec (det.)
15check-inadequatecheck_inadequateLoopExec (det.)
16resumable-judgmentescalation_pending, reviewer_rejectedMusketeer / human
17no-convergenceno_progress_detected, same_failure_repeated, oscillation_detected, same_test_regressed, unsatisfiable_constraints, infeasible_suspectedLoopExec (det.)
18budgetbudget_exceeded, cost_anomalyLoopExec (det.)
19liveness/driftheartbeat_stale, model_drift_detected, comprehension_debt_exceeded, context_budget_unsatisfiableLoopExec (det.)
20invariantinvariant_failedLoopExec
30workspaceworkspace_invalid, isolation_unsatisfiableLoopExec
40executionexecution_failureLoopExec
50internalinternal_errorLoopExec

Ownership stance. LoopExec owns everything a number can decide (exit codes, the F_i trajectory, a fingerprint hash, a coverage/mutation delta, a manifest hash, a spend ledger, a model-identity tuple, a sequential flake bound). Musketeer owns only what a number cannot express - reward_hacking_detected, reviewer_rejected - layered on top of the deterministic metric_integrity_violation, never replacing it. Humans own the irreducible decision and the ack. Judgment is never the stop oracle: it can veto a green loop or escalate, but it cannot promote a red one to green.

Migration. The legacy bare "blocked" string (one word, three meanings) is split: no_actionable_tasks (11), blocked_path_modified (13), human_required (11).