Files
boocode/openspec/changes/archived/orchestrator/proposal.md
indifferentketchup a734615480 docs: archive shipped openspec changes, refresh roadmap + DEFERRED-WORK
Move openspec/changes/{contracts-ssot,orchestrator} → archived/ (both shipped,
v2.7.13 and v2.7.17). Mark the roadmap's "Write/edit robustness" and "Claude
provider SDK" milestones as shipped (fuzzy-match.ts + checkpoints.ts; the
claude-sdk backend is live via CLAUDE_SDK_BACKEND in .env.host) and add a
v2.7.12–v2.7.17 shipped summary. Flag DEFERRED-WORK.md as superseded.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 16:30:01 +00:00

4.5 KiB

Orchestrator (Phase 2) — in-app multi-agent conductor

Source

Settled via a conversational grill-me design session. The captured behavioral spec (12 decisions, the what) is artifacts/design-context.md; the HOW is design.md, decomposed in tasks.md and committed in artifacts/implementation-decision-log.md (D-1…D-10). Note: design-context decision 5 ("no worktree") is REVISED by D-3/D-4 (worktree kept as a harmless read snapshot; read-only enforced by qwen plan mode).

Why

Phase 1 shipped a deterministic multi-agent conductor as a standalone host CLI (/opt/boocode/conductor/): Han flows that fan out read-only specialist agents, apply the evidence/yagni contracts, and emit an evidence-disciplined report. It is not reachable from the app — a user in BooChat or BooCoder cannot launch a flow, cannot watch agents progress live, and the run leaves no persisted, reopenable artifact.

This change brings the conductor in-app: launch any Han flow from the shared composer, watch each agent stream live (Paseo-style parent-with-subagents), and get the report — all on the already-loaded local Qwen 35B, free, with the run persisted and resumable across a coder restart. It reuses the existing task dispatcher, streaming pipeline, and broker rather than standing up a parallel execution path (see design-context decision 4 and D-2/D-3).

What Changes

  • Two doors, full parity. A Workflow button and a slash command on the shared ChatInput composer → both appear in BooChat (ChatPane) and BooCoder (CoderPane), desktop and mobile (icon-only). Slash launches instantly with defaults; the button opens a flow launcher first. (decisions 2, 8, 9 · D-8)
  • A new orchestrator pane kind. A run view alongside chat | coder | terminal: flow + band header, the report at the top on completion, a collapsed agent roster, expand-one-at-a-time to watch a single agent's live stream. (decision 3 · D-7)
  • Read-only flows, enforced HARD. Every step runs as a qwen agent under --approval-mode plan (mode_id='plan'): reads allowed, writes blocked at the tool level. Flows never write the repo; the report is the only output. (decision 5 revised · D-4)
  • Execution reuses the dispatcher. Each flow step is inserted as a normal tasks row; the existing dispatcher runs it through the external-agent path and streams AgentEvents → WS frames unchanged. One new onTaskTerminal hook advances the flow. (decisions 1, 4 · D-2, D-3)
  • Persisted + resumable runs. New flow_runs / flow_steps tables in the coder schema; a run survives a coder restart (initResume reconciles mid-flight steps). Runs are reopenable from a history; the report is exportable on demand (copy / save-file / send-to-chat). (decisions 4, 10 · D-5, D-9)
  • Qwen-only, one model per run. Default qwen3.6-35b-a3b-mxfp4, held as a single config value so more local models slot in later. Multiple runs allowed, each its own pane. (decisions 6, 11 · D-10)
  • Conductor definitions re-homed. The pure flow/spine/contracts/types/render files + 23 personas are copied into apps/coder/src/conductor/; the Phase-1 CLI stays alive. The evidence/yagni contracts and adversarial-validator gate are preserved (the flow-runner builds each prompt in-process before dispatch). (decision 1 · D-1)

Impact

  • apps/coder (deploy: sudo systemctl restart boocoder): new conductor/ defs, flow-runner.ts, the onTaskTerminal dispatcher hook, flow_runs/flow_steps in schema.sql, initResume, POST /api/runs + list/reopen routes.
  • packages/contracts + apps/web (deploy: docker compose up --build -d boocode): two new WS frames (in all three registries), the orchestrator pane kind + OrchestratorPane.tsx, the Workflow toolbar button + slash wiring, FlowLauncherDialog.tsx, runs history + export.
  • No apps/server chat-pipeline change beyond the contracts frame registry (the web type is the wire gate).
  • Safety: read-only is the whole feature's invariant; D-4 makes it a tool-level gate, not a prompt. Reviewed by adversarial-security-analyst in R2.

Out of scope (carried from design-context)

  • A Claude execution path (Claude Code covers it).
  • Folding Arena into the Orchestrator (stays separate).
  • Per-agent model tiering (single model per run for now).
  • Pixel-faithful per-skill Han report templates (spine-level only).