Pi Orchestration Architecture
Design of a human-gated multi-agent coding system using Claude Code or OpenCode as orchestrator, pi workers dispatched via pueue, and thepi-diff-review extension as the review gate.
All design decisions derived from a structured grill session.
System Overview
Key Design Decisions
Orchestrator choice
Claude Code or OpenCode — contextual or manual. No automated routing between them. Both dispatch pi workers identically. Orchestrator choice is about what model family runs the planning layer (Claude judgment vs GPT-5.x), not about task type.Dispatch mechanism
pueue — background task queue. Orchestrator fires N workers simultaneously, each as an independent pi -p "..." process. pueue wait <id> blocks until completion; pueue log <id> captures stdout for debugging.
Task prompt format
Structured spec, not free text:File isolation
Task scoping (not git worktrees). Orchestrator assigns non-overlapping file/module scopes per worker. Worktrees add overhead not justified for ≤5 parallel tasks with clean module boundaries. See Shared Task Queue (Cross-Worktree) for when worktree pools are needed instead.Model routing
Workers self-route via~/.pi/agent/AGENTS.md difficulty-tier routing. Orchestrator passes the task; worker picks the model. OpenCode Go subscription ($10/mo) provides the model pool: DeepSeek V4 Pro (high), Flash (medium/low). See Pi Agent (pi-mono) for the full routing table.
Worker subagents
Scouts only (read-only, Haiku-class, depth-limited). Write-capable sub-workers not enabled — creates nested task-scope coordination problem the architecture doesn’t solve. See Pi Agent (pi-mono) for Scout/Researcher/Worker tier definitions.Review modes — two distinct paths
Interactive pi sessions (human runs pi with TUI):pi-diff-reviewfires per write/edit- Human reviews line-by-line: accept/deny/edit per changed row
- Model self-corrects within session when lines are denied
- After session: manual git review + commit
pi -p "..."):
ctx.hasUI = false→ extension auto-accepts, writes audit log only- Human gate happens post-completion at orchestrator level
- Orchestrator reads
git diff+status-<id>.jsonand presents to human - Human commits manually after review
Status artifact
Written onsession_shutdown. Named status-<PUEUE_TASK_ID>.json (falls back to status.json). Fields:
resolved: all files’ last decision was"accepted"unresolvedFiles: files whose lastapplyReviewaction ≠"accepted"retryCount: value ofDIFF_REVIEW_RETRY_COUNTenv var at time of writeneedsHuman:!resolved && retryCount >= 2— orchestrator stops retrying
decisions.jsonl entry per file path. Earlier denials followed by a final acceptance = resolved. See apply-decisions.ts:writeStatusArtifact.
Retry strategy
Orchestrator re-runs failed workers with added context, up to 3 total attempts (retry counts 0, 1, 2). On attempt 2 with unresolved files:needsHuman=true in status artifact → orchestrator halts, human takes over manually.
Re-run prompt pattern:
Commit strategy
No auto-commit. Orchestrator presents fullgit diff after all workers complete. Human reviews and commits manually. Per Pi Building In World Of Slop: “critical code, read every line.”
Extension loading
pi-diff-review installed globally via pi install. Orchestrator verifies extension presence at startup (fail-fast gate) before firing any workers. Silent absence of the review gate is worse than a loud startup failure.
Artifact Layout
Orchestrator Dispatch Snippet
Related Pages
- Pi Agent (pi-mono) — pi-mono architecture, AGENTS.md routing, subagents extension
- OpenCode — OpenCode as orchestrator; headless
run/servemodes - OpenCode Go — OpenCode Go subscription; model pool for pi workers
- Pi Building In World Of Slop — Pi design philosophy; minimal harness, self-modifying extensions
- Agent Harness — harness primitives; filesystem as coordination layer
- Agent Primitive Selection — decision tree for orchestration patterns
- Shared Task Queue (Cross-Worktree) — when to use worktrees instead of task scoping