computeRunState, never inferring
status from ps, event absence, or partial table reads: it reads the same
RunStateView, computed server-side from persisted state plus liveness
signals.
RunState
unknown.
The legacy run-row status column maps to RunState like this:
recovering is reserved for the supervisor takeover window. As of this writing, it’s defined but not yet emitted.
When a fail-closed composite such as <TryCatchFinally> terminates a run, its
run-level SCHEDULER_ERROR includes the nearest completed output row’s
summary and blockers fields. The leaf diagnostic is therefore visible in
up, inspect, and autopsy output without a separate node/output lookup.
ReasonBlocked / ReasonUnhealthy
ReasonBlocked and ReasonUnhealthy are optional reason payloads for waiting
and unhealthy states; the type unions are wider than the variants currently
derived from the DB rows.
computeRunState / deriveRunState
emits approval, event, timer, approval-decided-resume-required, and
external-trigger blocked reasons, plus engine-heartbeat-stale and
timer-overdue unhealthy reasons; the rest are reserved by the public type for
future run-state surfaces.
RunStateView
blocked is present for a waiting-* state when computeRunState can load
matching pending approval/timer/event context, when a parked waiting-event
run has no event-waiting node, or when that context is supplied to
deriveRunState. A waiting-* state can be returned without blocked when
the supporting row is unavailable. unhealthy is present for stale,
orphaned, and overdue-timer results. recovering stays unemitted for now
(see above), and terminal states (succeeded, succeeded-with-failures,
failed, cancelled) carry neither.
warnings retains durable operator diagnostics independently of lifecycle
state. When automatic concurrency reaches its configured ceiling while demand
remains queued, the latest warning reports the requested demand, effective cap,
and exact --max-concurrency remediation command.
computeRunState
computeRunState is pure over the DB plus the heartbeat / lease signals on
the run row: no ps calls, no socket probes, no heuristics.
deriveRunState is the underlying pure function, useful in tests or
when you already have the rows in memory:
staleThresholdMs is 30_000, the same threshold the
engine uses for isRunHeartbeatFresh.
Where it shows up
RunStateView is the wire format on every read surface:
bunx smthrs inspect RUN_ID: top-levelrunStatefield on the JSON output (and rendered in the human view).- Gateway RPC
getRun:runStatefield on the response. - DevTools snapshot header:
runState?: RunStateViewfield. ps --json: compatiblestatus: "finished"plus the distinctstate: "succeeded-with-failures";status,inspect,tail,why, and monitor views render the degraded outcome without keeping the run active.- Event stream:
RunStatusChangedrecords persisted status transitions.RunStateChangedis a typed/reserved event variant, but the current runtime does not emit it; callgetRunorcomputeRunStatewhen you need the derivedRunStateView.
RunState. It’s an error
(RUN_NOT_FOUND); unknown is for ambiguity, not for “doesn’t exist.”