Skip to main content

Module exit

Module exit 

Source
Expand description

The public exit-code contract: a stable, machine-actionable API (e.g. for a Kubernetes podFailurePolicy). Schedulers branch on these numbers, so treat any change to a code’s meaning as breaking.

CodeMeaningScheduler hint
0success (one-shot completed / clean SIGTERM drain)Complete
1generic/unspecified failureretriable
2config / usage error (validation)non-retriable
3partial resultpolicy
4intelligence unreachable / auth after retriesretriable
5semantic — task cannot be done / refusednon-retriable
6required MCP server failed to connect/handshake/dieretriable
7budget exceeded (steps/tokens/deadline/tree)policy
124hard wall-clock deadline (mnemonic to timeout(1))
137killed by SIGKILL (128+9, OS-set) — often OOMraise memory
143killed by SIGTERM (128+15, OS-set) — ungraceful

A clean SIGTERM drain returns 0, not 143: draining on request is a success, not a kill. 137/143 only ever appear because the OS sets them when the kernel kills the process; agentd never calls exit(137) itself.

Around the table this module freezes two things a control plane depends on: a contract version (EXIT_CODES, surfaced at surfaces.exit_codes) and a per-code podFailurePolicy intent (pod_failure_intent) that agentctl compiles into onExitCodes rules. agentd emits codes and intents only; the policy decision itself belongs to agentctl.

Constants§

BUDGET
DEADLINE
EXIT_CODES
The exit-code contract version (major.minor), surfaced in the manifest at surfaces.exit_codes. It freezes the code->meaning table plus the pod_failure_intent mapping as a versioned public API that a control plane authors podFailurePolicy rules against. New codes may be added within a major; any change to an existing code’s meaning or intent is breaking and bumps the major, because a reader compiled against the old major would otherwise silently author the wrong policy. agentctl refuses to compile rules for an exit_codes major it does not understand.
GENERIC
INTEL_UNAVAILABLE
MCP_REQUIRED_DOWN
PARTIAL
REFUSED
SIGKILL_EXIT
The OS-set codes (128 + signo). agentd never returns these itself (once_exit tops out at DEADLINE = 124); the kernel sets them when it kills the process. They are named here so pod_failure_intent can classify the kernel-set code a reader actually observes.
SIGTERM_EXIT
SUCCESS
USAGE

Functions§

apply_budget_remap
Apply the operator’s --budget-exit-code remap. ONLY the two operator-tunable policy-intent budget codes are remappable — EXIT_PARTIAL (3) and EXIT_BUDGET (7); every other code (a clean 0, a terminal refusal 5, the policy deadline 124, a kernel 137) is returned UNCHANGED. With no remap configured (None) the canonical table applies verbatim.
once_exit
Map a one-shot root subagent’s outcome to an exit code. partial is the result-body property, not a status: a Completed run that only partially satisfied the objective exits 3. A budget-bounded run that nonetheless produced usable output is still reported under its budget code (7) with the partial flag carried in the result JSON.
pod_failure_intent
The podFailurePolicy intent a control plane compiles each exit code into. agentd emits the code; agentctl owns the actual FailJob/Ignore/Count choice and any operator override — this is the frozen hint it branches on, not a policy.