Why a ticket is not being dispatched right now: the reporting decision,
built only by the daemon’s show/list handlers. The dispatcher does not
call this module — scheduler::reconcile checks its own gates inline — so
the global gates here mirror the dispatcher’s by construction and must be
kept in step with them by hand.
Flow definitions and the pure walk over them. Parsing turns a committed
YAML file into a validated Flow; next_step then replays the run’s
ordered evidence log over that flow to derive the next stage to run or a
terminal reading. Neither half touches a clock, a process, or the store,
so policy can be tested without a daemon.
Outcome derivation. Evidence in, verdict out: this module is the only
place a run’s terminal outcome is decided, and it is pure so policy can
be tested without a daemon, a process, or a repository.
Human rendering of response envelopes. JSON envelopes remain the internal
and --json representation; this module is a one-way translation applied
at the final write, so the socket API and agent-facing output are
unaffected by presentation changes here.
Per-run NDJSON output capture. Agent and stage stdout/stderr are
untrusted evidence: they are stored as ordered chunks, never parsed as
lines and never routed through the dispatcher.