RunStateView,
computed server-side from persisted state plus liveness signals.
Surfaces never infer status from ps, event absence, or partial table
reads. They call computeRunState.
RunState
unknown. Never invent a more specific state.
The legacy run-row status column maps to RunState like this:
_smithers_runs.status | RunState |
|---|---|
running (fresh) | running |
running (stale) | stale or orphaned |
waiting-approval | waiting-approval |
waiting-event | waiting-event |
waiting-timer | waiting-timer |
finished | succeeded |
continued | succeeded |
failed | failed |
cancelled | cancelled |
| missing / unknown text | unknown |
recovering is reserved for the supervisor takeover window. As of this writing, it is defined but not yet emitted by the runtime.
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 unhealthy
reasons. The other variants are reserved by the public type and may appear on
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 current stale
and orphaned results. recovering is reserved by the type but is not
currently emitted by the DB derivation. Terminal states (succeeded, failed,
cancelled) carry neither.
computeRunState
computeRunState is pure over the DB plus the heartbeat / lease signals
on the run row. It does not call ps, does not probe sockets, and does
not run 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 smithers-orchestrator 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. - 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.”