Expand description
Exit-code mapping for EXEC-021.
Maps a finished crate::run_graph::RunGraphOutcome (and an
optional CancellationSignal recorded by the binary’s OS
signal handler) to the numeric exit status the haz run
process MUST report.
Per locked decision D5 of the parent haz-exec plan
(“Pure library. No process::exit, stdio writes, or signal
handlers inside haz-exec.”), this module computes the number
and nothing else. The actual process::exit(code) call lives
in the binary that consumes haz-exec (haz-cli).
§Spec contract (EXEC-021)
The spec requires four distinguishable classes:
- Success: every requested task reached the succeeded state
and no runtime invariant (
EXEC-019cycle,EXEC-020overlap) was violated. Maps to0. - Task failure: at least one task reached the failed state
under
EXEC-009, or the lookup-then-spawn pipeline surfaced an error, or a runtime invariant was violated. Maps to1in this implementation. The spec leaves the specific number to implementation v1; the class-from-class distinguishability is the load-bearing requirement. - Signal interruption: the run was cancelled because an OS
signal flipped the cancellation token (
EXEC-012). Maps to128 + signal_numberper POSIX convention (130forSIGINT,143forSIGTERM). - Workspace-load / internal error: handled by the consuming binary (haz-cli), which by definition never invokes the scheduler if workspace load fails. This module does NOT produce a number for class 4; the binary picks a value distinct from those this module returns.
§Precedence
Signal interruption wins over task failure. A run where the user pressed Ctrl+C while a task was failing exits with the signal code, mirroring POSIX semantics for a process killed by signal.
§Cancellation without a recorded signal
A crate::run_task::RunOutcome::Cancelled entry without
an accompanying CancellationSignal argument indicates an
internal cancellation (e.g. the scheduler tripped its own
child token after detecting a runtime cycle per EXEC-019).
In that case the runtime-cycle diagnostic lives in
crate::run_graph::RunGraphOutcome::invariant_violations,
which by itself maps to the task-failure class. Treating
bare-Cancelled-without-signal as a third failure source
would double-count the cycle, so the helper does not.
§Skipped tasks
crate::run_task::RunOutcome::Skipped entries are effects,
not causes: a skip records that the cascade prevented a task
from running, never that the task itself failed. The original
failure or cancellation that caused the cascade appears in
the same outcomes map (as a Completed with state Failed
or a Cancelled entry), or in task_errors, or in
invariant_violations. The helper consults those sources
directly; it does not re-count skips.
Enums§
- Cancellation
Signal - The OS signal that initiated a run-cancellation request, per
EXEC-012.
Constants§
- EXIT_
TASK_ FAILURE - Exit code reported when at least one task failed, surfaced a pipeline error, or a runtime invariant was violated, AND the run was not cancelled by an OS signal.
Functions§
- exit_
code_ for - Compute the process exit code for a finished
RunGraphOutcomeperEXEC-021.