| name | dispatching-parallel-agents |
| description | Use when facing 2 or more independent tasks that can be worked on without shared state or sequential dependencies |
Dispatching Parallel Agents
Overview
Run a pipeline of N workers against a prioritized task queue. Each worker executes one task end-to-end via oro work. As workers complete, merge results and immediately launch the next task.
Core principle: Keep N worker slots saturated. Merge as you go. Never wait for all workers to finish before starting more.
When to Use
- Queue of 2+ independent tasks to execute
- Multiple subsystems to build/fix in parallel
- Each task can be understood without context from others
Don't use when:
- Failures are related (fix one might fix others)
- Need to understand full system state first
- Exploratory debugging (don't know what's broken yet)
Preflight
Before dispatching, clean house:
git worktree list
oro task ready
oro task list --status=in_progress
Remove stale worktrees from previous sessions. Reset stale in_progress tasks if the worker is gone.
Priority Order
Process the queue in this order:
- Individual tasks (not epic children), bugs first
- Decomposed epic children, bugs first then tasks
- New epics needing decomposition
Within each tier: higher priority (P0 > P1 > P2) first.
Scheduling Rules
- Different files → parallel: Launch simultaneously
- Same file → sequential: Wire deps with
oro task dep add
- Default concurrency: 5 oro workers
The Pipeline
1. Launch Workers
Fill empty slots up to N concurrency:
Primary — oro work (handles worktree, TDD, QG, ops review, merge):
oro work <task-id> &
Fallback — Task agent (when work is not a task, or oro unavailable):
You are working in an isolated git worktree at: /absolute/path/.worktrees/<id>
Branch: agent/<id>
FIRST: oro task update <id> --status=in_progress
## Task
[task description]
## Rules
- ONLY modify files within /absolute/path/.worktrees/<id>
- Run tests: go test -C /absolute/path/.worktrees/<id> ./pkg/... -race -count=1
- Commit your work with a descriptive message before completing
- Do NOT push, merge, or rebase
- Close task: oro task close <id> --reason="summary"
IMPORTANT: Tell agents to use go -C <worktree> or absolute paths, never cd <worktree>. The cd persists in the Bash tool cwd — if the worktree is later removed, ALL subsequent bash commands fail silently.
2. Monitor
- Run background agents with
run_in_background: true
- Never poll — trust task completion notifications
- Never use TaskOutput to read full transcripts (70k+ tokens eats context)
- Do NOT create TaskCreate/TodoWrite entries to track agents — they go stale after compaction. Use
tasks for persistent tracking.
- Agent closes task with
oro task close <id> — the task IS the output
3. Merge (as each worker completes)
Rebase + fast-forward merge. Always. This gives clean linear history without duplicate commits.
git stash
git worktree remove --force .worktrees/<id>
git rebase main <branch>
git checkout main
git merge --ff-only <branch>
git branch -D <branch>
git stash pop
Why not cherry-pick? Cherry-pick duplicates commit hashes, polluting git log and breaking git bisect. Rebase preserves authorship and produces identical diffs with clean history.
Worktree removal unblocks rebase. The rebase guard hook only fires when worktrees are active. Remove the worktree first (step 2), then rebase freely — even while other worktrees exist for different agents.
CRITICAL: Do not backfill or use any tools between removing a worktree and completing the merge. Removing a worktree can corrupt the hook resolver's CWD — all tools break until the merge sequence finishes. Complete the full 7-step sequence atomically.
4. Backfill
Launch the next task from the queue into the freed slot. Repeat until queue is empty.
Check dependency chains: if task X was blocking task Y (same file), Y is now unblocked.
5. Finalize
When all workers are done and merged:
go test ./...
git push
Merge Strategy Details
Fixing Agent Mistakes at Merge Time
Agents frequently make these errors — check before merging:
| Problem | Detection | Fix |
|---|
| Didn't commit | git -C .worktrees/X log shows same commit as main | Stage + commit from manager |
| Syntax errors | go -C .worktrees/X build ./... fails | Read the file, fix, recommit |
| Wrong package name | Linter rejects | Fix the package declaration, recommit |
Always verify agent commits compile before merging: go -C .worktrees/X build ./...
Conflict Resolution
When git rebase main agent/X produces conflicts:
- Read the conflict markers — understand what both sides changed
- Keep both changes when they're additive (new fields, new methods, new tests)
- Prefer HEAD for structural changes (type renames, package moves)
- Fix cross-references after resolution
- Always build + test after conflict resolution before merging the next branch
Error Recovery
| Situation | Action |
|---|
| Worker completes, merge succeeds | Pull. Launch next. |
| Worker completes, merge conflicts | Resolve during rebase, build + test, continue. |
| Worker fails (test failure) | Inspect worktree. Fix + recommit, or re-dispatch. |
| Worker killed (signal:killed) | Resource contention. Reduce concurrency. Re-dispatch. |
| Worker stuck (no progress) | Check output file tail. Kill and re-dispatch if needed. |
| Task too large (worker decomposes) | Worker promotes to epic. Pick up children in next cycle. |
Do NOT blindly retry failed workers. Inspect first.
Resource Limits
- Default concurrency: 5 oro workers
- Monitor for signal:killed — reduce to 3 if it occurs
- Task agents are lighter weight — can run more concurrently
Task Agent Fallback
Use raw Task agents instead of oro work when:
- Work is not tracked as a task (ad-hoc exploration, research)
oro binary is unavailable or broken
- Need custom agent behavior beyond
oro work's lifecycle
Task agent prompt template must include:
- Absolute worktree path
oro task update <id> --status=in_progress at start
oro task close <id> at end
- Commit instructions (do NOT push/merge/rebase)
Common Mistakes
| Mistake | Fix |
|---|
| Batch dispatch (wait for all, then merge all) | Pipeline: merge each as it finishes, backfill |
Not claiming tasks (in_progress) | Worker prompt must include oro task update at start |
| Dispatching overlapping file scopes | Same file = sequential deps via oro task dep add |
| Using TaskOutput to read transcripts | Trust notifications. Read task, not transcript. |
| Using tools between worktree remove and merge complete | Complete the 7-step merge atomically |
| Polling agents with sleep loops | Trust task notifications |
| Forgetting stale worktree cleanup | Preflight: git worktree list |
Using cd into worktrees | Shell cwd persists — use absolute paths |
Red Flags
- All slots empty while queue has work (pipeline stall)
- Two workers editing the same file (merge conflict guaranteed)
- Worker running >10min on a 7min task (check progress)
- signal:killed appearing (reduce concurrency)
- Saying "ready to push" (just push)