Summary
flows check already computes the facts that would have prevented five dead runs, and spends none of them. It is a static analyzer with the answers in hand that stays silent about the specific properties it can see.
This issue asks for one thing: when check can already tell that a spec will fail or degrade at run time, say so.
The evidence
Authoring a 58-step campaign flow for AgentWorkforce/relay on CLI 2.0.22, five runs died. Every one was knowable before the run started, and check printed CHECK PASSED for all of them.
1. Agent steps with no worker. check already prints exactly the right fact:
REQUIRES codex (step "implement-rust"), claude (step "shadow-rust")
It knows which steps need an agent worker. It then says nothing about --local-agent, and the run parks:
PARKED [run_parked] parked at step "implement-rust" (agent): no worker is attached for step type "agent".
Cost: one run. (See also #503, #504 — the flag is missing on schedule and ignored on resume.)
2. A subprocess_gate whose output cannot be seen. check knows the gate's type at compile time. It knows the lowering runs the command under stdio: 'inherit', and that the daemon's stdio is captured nowhere, so a red verdict arrives as exit=1 with empty stdout_tail and stderr_tail (#511). Nothing is said. Cost: one run, plus a long detour through the journal to work out why.
3. An artifact_exists path that can never match. check has the literal path string. The worker's journaled artifacts list omits dot-directories, so path: '.workflow-artifacts/.../review.md' cannot ever pass (#513). This is decidable by prefix comparison, before anything runs. Cost: one run, with the gated file sitting on disk at 25 KB.
What to change
Add diagnostics for properties check can already decide. Suggested, in leverage order:
Two of the three are temporary — they describe current bugs and should be deleted with their fixes. The first is permanent.
Why this rather than the individual bugs
#503, #504, #506, #509, #511 and #513 are each worth fixing. But an author meets them one dead run at a time, and the reason is structural: the product's one validation tool is not asked whether the run will work, only whether the spec is well-formed. Closing that gap is worth more than the six fixes, because it also catches the seventh.
Relatedly, check cannot see the daemon at all (#502), so its blind spots compound: it neither validates against the runtime's schema nor reports the run-time properties it can compute locally.
Acceptance
- A spec containing
agent steps produces a diagnostic naming --local-agent, next to the existing REQUIRES line.
- An
artifact_exists gate whose path cannot match is refused, naming the excluded prefix.
- A
subprocess_gate produces a warning that its output will not be captured, for as long as that is true.
- Each diagnostic is a distinct kind, so it can be suppressed and later deleted independently.
Out of scope
Summary
flows checkalready computes the facts that would have prevented five dead runs, and spends none of them. It is a static analyzer with the answers in hand that stays silent about the specific properties it can see.This issue asks for one thing: when
checkcan already tell that a spec will fail or degrade at run time, say so.The evidence
Authoring a 58-step campaign flow for
AgentWorkforce/relayon CLI 2.0.22, five runs died. Every one was knowable before the run started, andcheckprintedCHECK PASSEDfor all of them.1. Agent steps with no worker.
checkalready prints exactly the right fact:It knows which steps need an agent worker. It then says nothing about
--local-agent, and the run parks:Cost: one run. (See also #503, #504 — the flag is missing on
scheduleand ignored onresume.)2. A
subprocess_gatewhose output cannot be seen.checkknows the gate's type at compile time. It knows the lowering runs the command understdio: 'inherit', and that the daemon's stdio is captured nowhere, so a red verdict arrives asexit=1with emptystdout_tailandstderr_tail(#511). Nothing is said. Cost: one run, plus a long detour through the journal to work out why.3. An
artifact_existspath that can never match.checkhas the literalpathstring. The worker's journaledartifactslist omits dot-directories, sopath: '.workflow-artifacts/.../review.md'cannot ever pass (#513). This is decidable by prefix comparison, before anything runs. Cost: one run, with the gated file sitting on disk at 25 KB.What to change
Add diagnostics for properties
checkcan already decide. Suggested, in leverage order:agent_worker_unresolved— the spec hasagentsteps and the invocation has no worker surface. Emit alongside the existingREQUIRESline: "3 agent steps require an attached worker; a local run needs--local-agent." This is the one that matters most, becauseREQUIRESproves the analysis already exists.gate_output_not_captured— asubprocess_gateis present; warn that its stdout and stderr will not be journaled, and name the alternatives. Retire this when A failing subprocess_gate journals empty stdout/stderr: the lowering uses stdio:'inherit' and the daemon's stdio is captured nowhere #511 lands.gate_path_unreachable— anartifact_existspathfalls inside a prefix the worker's artifact scan excludes. This one should arguably be a refusal, not a warning: the gate is statically unsatisfiable. Retire when artifact_exists can never pass for a dot-directory path: the worker's journaled artifacts list omits them #513 lands.Two of the three are temporary — they describe current bugs and should be deleted with their fixes. The first is permanent.
Why this rather than the individual bugs
#503, #504, #506, #509, #511 and #513 are each worth fixing. But an author meets them one dead run at a time, and the reason is structural: the product's one validation tool is not asked whether the run will work, only whether the spec is well-formed. Closing that gap is worth more than the six fixes, because it also catches the seventh.
Relatedly,
checkcannot see the daemon at all (#502), so its blind spots compound: it neither validates against the runtime's schema nor reports the run-time properties it can compute locally.Acceptance
agentsteps produces a diagnostic naming--local-agent, next to the existingREQUIRESline.artifact_existsgate whose path cannot match is refused, naming the excluded prefix.subprocess_gateproduces a warning that its output will not be captured, for as long as that is true.Out of scope