2026-07-18 · Updated 2026-08-27 · 5 min read
Choose Workflow Runner or Parallel Runner
Pick Workflow Runner or Parallel Runner in one keyed pass over step coupling, evidence needs, and failure semantics, with concrete commands for each choice.
By Juno AI INC · workflow-runner · parallel-runner
Both runners install into every initialized YYLO project, so the choice is not about what you have — it is about which failure and evidence model the work actually has. The decision is about data dependency, not the number of commands: ask whether any item needs another item's response, artifact, or session before it can start. Everything below is that one question applied three times.
The decision in one pass
Key the choice on three dimensions. Each row names the owner for one answer:
- Step coupling. A step consumes an earlier step's
{{ steps.<id>.response }}, a file it produced, or the session it captured — Workflow Runner. Every item starts from the same inputs and no ordering exists between them — Parallel Runner. - Evidence needs. You must replay one ordered run later: rendered commands, per-step responses, summary, and the final session for continuation — Workflow Runner. You must review many equivalent items side by side: per-item exit codes, responses, and one aggregate — Parallel Runner.
- Failure semantics. One step's failure must stop the sequence at that boundary — Workflow Runner with
fail_workflow: true. A failed item should strand only itself while the rest of the batch finishes — Parallel Runner.
One real coupling edge decides the whole question: model it as an ordered workflow, because fan-out can only represent a dependency as timing luck. When you are genuinely torn, ask which retry you would want after a failure — rerunning a single item, or resuming an ordered run at a specific step — and pick the runner that makes that retry cheap.
Choose Parallel Runner for independent fan-out
Use Parallel Runner when tasks are independent and a bounded worker pool can process them safely. It owns queueing, a maximum worker count, per-item execution, and aggregation.
--kanban-filter "ready" is the dependency-aware input: it admits only tasks whose declared blockers are satisfied. Keep the filter quoted so it forwards as one argument. Items can also come from record files with an explicit prompt (--items-file data.csv --prompt-file instructions.md --strict) or from complete commands (--commands-file). Generate and lint a command file before any unattended batch so schema mistakes fail before expensive agents launch:
Its evidence is item-oriented: each item writes JSON with its exit code, elapsed time, and final response and session ID, next to parallel_runner_status.json, logs, and one aggregation_*.json for the batch. Continue a captured item session with yy continue SESSION_ID instead of reconstructing work from terminal scrollback. Tmux modes make the pool visible while it runs. For worker quotas, per-worker isolation, and readiness rules, see Run kanban tasks safely in parallel — that guide owns the safety depth; this one only owns the choice.
Choose Workflow Runner for ordered flow
Use Workflow Runner when ordered steps exchange responses, files, or captured sessions — reviewed operator playbooks, validation pipelines, agent chains, and deliberate final handoff.
Lint catches noisy stdout and stderr template anti-patterns before launch, and the dry run writes the rendered commands without executing steps. Resume at a specific boundary with --from-step — a step id, a zero-based index, or -1 for the final step.
Its evidence is run-oriented: a run directory under .juno_task/specs/workflows/<workflow_id>/<run_id> persists the manifest, the rendered workflow, every step's stdout, stderr, and response, the summary, and captured session IDs. For agent steps, the response is the answer — successful stderr stays in artifacts — and an agent command that exits zero with an empty response is failed rather than recorded as done. The final successful agent session is persisted for yy cc, and top-level continue_from_step selects a different step's session when the handoff must point there. Its --tmux flag adds a detached observer that never detaches the producer, so the invoking command stays the source of truth. For manifests, failure artifacts, and recovery practice, see Build auditable agent workflows with handoff.
Match the failure semantics you can afford
The runners fail in opposite shapes, and the decision fixes which failure you will be cleaning up.
- Parallel Runner strands one item. The failed item's JSON records its exit code while the pool moves on. Retry that task ID alone once the failure is understood; do not relaunch the successful majority.
parallel_runner_wait.sh --timeout SECONDSgives deterministic waits for nonblocking launches, and--stop-allis only for intentional broad shutdown. - Workflow Runner records a failed step and still exits zero by default, so later steps keep running. Add
fail_workflow: trueto the validation and destructive boundaries where automation must stop instead of continuing past bad evidence.
If you cannot name the boundary where the run should stop, you do not have a workflow yet — you have a batch, and Parallel Runner plus per-item review is the honest shape for it.
Compose them deliberately
The runners compose at one seam: an ordered step can own a fan-out.
- A workflow can launch a capped parallel investigation and let a later review step consume the aggregation artifact. The shipped
parallel-kanban-reviewexample follows exactly this shape: a planning agent creates kanban tasks, parallel workers writeaggregation_*.jsonartifacts, and a master review step reads the latest aggregation. - Raw command mode fans out complete workflows:
parallel_runner.sh --commands-fileowns concurrency, queueing, and aggregate status while eachworkflow_runner.shinvocation keeps its ordered steps and per-run artifacts.
Keep one owner for each ordering boundary and never represent a real dependency as timing luck. Revisit the choice per batch rather than by habit: as work gains or loses dependency edges, the runner follows the coupling.