Orchestration
Coordinate agents with Runs, tasks, supervised workers, messages, and decision gates.
Orchestration is DevAgent's structured multi-agent layer: a Run (namespace + coordinator inbox), Tasks, Dispatches, supervised workers, messages, and decision gates.
Use it when you need ownership, completion tracking, or a DAG. For one-off prompts, use devcore terminal send. For full ownership handoffs without supervision, use worktree/terminal commands from the orca-cli skill.
Experimental
Enable orchestration under Settings → Experimental before using these commands. The CLI talks to the running DevAgent runtime, so devcore status --json should succeed first.
Legacy commands retired
devcore orchestration run and run-stop (and coordinator-start / coordinator-stop) perform no effects. They return recovery text pointing at devcore skills get orchestration --full. Use the Run + worker-start flow below.
Core model
- Run — durable namespace and home inbox. Never schedules or places workers.
- Task — a work item with a spec, dependencies, and status:
pending,ready,dispatched,completed,failed, orblocked. - Dispatch — one attempt of a task on a terminal; lifecycle authority for
worker_done/ heartbeat. - Message — inbox mail (
status,dispatch,worker_done,escalation,question,heartbeat, …). - Decision gate — a coordinator-owned question that blocks a task until it is resolved.
Completion authority comes from the active dispatch context. Worker completion and heartbeat messages should include both taskId and dispatchId.
Task IDs printed in terminals, such as task_..., are clickable links. Clicking one asks the DevAgent runtime for the task's current dispatch and focuses the assigned terminal, including when the task lives in a remote or SSH runtime.
Preferred supervised loop
devcore orchestration run-create --objective "Split checkout QA and summarize blockers" --json
devcore orchestration task-create --spec "Audit billing settings for mobile layout" --task-title "Billing audit" --json
devcore orchestration worker-start --task <taskId> --worktree current --agent codex --json
# or new worktree:
devcore orchestration worker-start --task <taskId> --worktree new-child --name billing-audit --agent codex --setup run --json
# optional per-worker model / effort (Claude, Codex, Cursor only; not with --terminal):
devcore orchestration worker-start --task <taskId> --worktree current --agent claude --model <opaque-model-id> --effort high --json--model accepts opaque provider model IDs for Claude, Codex, and Cursor. --effort requires --model and only applies when that agent/model supports the level. Neither flag can combine with --terminal (reuse an existing pane). Overrides apply to that launch only and show under launch.requested / launch.effective in the start receipt. Federated starts need a worker host that advertises launch-preference support.
Wait for completions (process every message in a Delivery, then ack):
devcore orchestration check --wait --types worker_done,escalation,question --timeout-ms 900000 --json
devcore orchestration check --ack <deliveryId> --wait --types worker_done,escalation,question --timeout-ms 900000 --jsonWorker completion (from the worker pane; include injected IDs):
devcore orchestration send \
--type worker_done \
--subject "Completed mobile audit" \
--body "Fixed footer overlap; no follow-ups." \
--task-id <taskId> \
--dispatch-id <dispatchId> \
--outcome succeeded \
--files-modified "src/app/settings/Billing.tsx" \
--jsonworker_done requires --outcome succeeded|failed.
Inspect / recover:
devcore orchestration worker-show --dispatch <dispatchId> --json
devcore orchestration worker-read --dispatch <dispatchId> --limit 50 --json
devcore orchestration worker-stop --dispatch <dispatchId> --json
# After an accepted worker_done: reuse the same terminal for a follow-up Dispatch, or release it
# (archives inspectable output, then closes only that coordinator-owned agent terminal):
devcore orchestration worker-release --dispatch <dispatchId> --json
# Keep a settled worker live for debugging when the user asked to retain it:
devcore orchestration worker-retain --dispatch <dispatchId> --json
# retry placement is explicit — --retry-of does not inherit --on/worktree:
devcore orchestration worker-start --task <taskId> --retry-of <dispatchId> --worktree current --agent codex --jsonDo not leave completed worker terminals open just to re-read output — use worker-read after worker-release. Do not substitute a broad terminal close when release returns release_pending or release_unknown; follow the receipt's recovery action.
Federated workers (optional)
devcore orchestration worker-start \
--task <taskId> \
--on windows \
--worktree new-top-level \
--repo <exact_remote_repo_selector> \
--name remote-worker \
--agent codex \
--setup run \
--json
devcore orchestration send --to dispatch:<dispatchId> --subject "Follow-up" --body "…" --jsonLater commands route by Dispatch ID; do not repeat --on.
Low-level dispatch (custom topology)
devcore worktree create --name billing-audit --agent codex --json
devcore terminal wait --terminal <workerHandle> --for tui-idle --timeout-ms 60000 --json
devcore orchestration dispatch --task <taskId> --to <workerHandle> --inject --jsonMessaging notes
- Default
checkis the bound Run's oldest unacked Delivery (FIFO). Replay until--ack. --peek/--alldo not consume mail.- Group addresses:
@all,@idle,@claude,@codex,@opencode,@gemini,@droid,@grok,@cursor,@worktree:<id>— never forworker_done/ heartbeat. - Quote PowerShell group addresses:
--to "@all".
devcore orchestration send --to @all --subject "Heads up" --body "Pausing dispatches for a review." --json
devcore orchestration send --to @idle --subject "Anyone free?" --json
devcore orchestration send --to @codex --subject "Codex agents only" --jsonWhile a wait is active, the CLI emits small JSON heartbeat lines to stderr every 15 seconds. Stdout remains the final command result.
Worker contract
Dispatched workers receive a preamble that tells them how to communicate with the coordinator:
- Send
worker_doneexactly once, even on failure, with--outcome. - Include a short
--bodysummary: what was done, what was found, and what remains. - Include both task and dispatch IDs so stale retries cannot complete the wrong dispatch.
- Send
heartbeatmessages during long active work. - Use
devcore orchestration askfor blocking questions instead of local TUI prompts.
devcore orchestration ask \
--to <coordinatorHandle> \
--question "Should I update the shared component or only this page?" \
--options "shared,page-only" \
--timeout-ms 600000 \
--jsonWith --json, ask prints a single JSON object so workers can pipe it to jq -r .answer.
Decision gates
Use ask for worker-to-coordinator questions. Use explicit gates when the coordinator has created a task DAG and wants to block a task until a decision is recorded:
devcore orchestration gate-create \
--task <taskId> \
--question "Merge the shared button change into the task branch?" \
--options '["yes","no"]' \
--json
devcore orchestration gate-resolve --id <gateId> --resolution "yes" --jsonRecovery
devcore orchestration dispatch-show --task <taskId> --json
devcore orchestration dispatch-show --task <taskId> --preamble --json
devcore orchestration task-list --json
devcore orchestration task-update --id <taskId> --status blocked --result '{"reason":"waiting on credentials"}' --jsonReset only when you are intentionally abandoning orchestration state:
devcore orchestration reset --tasks --json
devcore orchestration reset --messages --json
devcore orchestration reset --all --jsonreset affects runtime-global orchestration state. Do not run it while another coordinator is active unless that is the intended cleanup.
Choosing the right command
Use devcore terminal send for a lightweight prompt to an agent you are watching.
Use devcore orchestration worker-start (or dispatch --inject) when a worker must report worker_done, ask questions through the coordinator, and be tracked by task ID.
Use devcore orchestration run-create + tasks + workers when you want a durable Run namespace and supervised multi-agent loop — not the retired orchestration run command.
Full guide
Command flags evolve with the app. After install, agents should run:
devcore skills get orchestration --full