5 agents. Two modes. In Pipeline Mode, agents pass work back and forth autonomously until it's perfect. In Manual Mode, you are the orchestrator — 5 Claude sessions with expertise labels, no automation, you direct everything.
- S — Supervisor: Assists the user in overseeing the pipeline. Reads everything. Diagnoses issues. Not part of the autonomous flow — available on demand.
- A — Planner: Chats with the user, researches, writes the build plan, deploys at the end
- B — Plan Reviewer: Pokes holes in the plan until there are none left
- C — Coder: Follows the approved plan and writes the code
- D — Code Reviewer + Tester: Reviews the code against the plan, then tests it
- The user chats with A in the viewer. This is the only required human interaction.
- A asks clarifying questions — what do you want, how should it work, any constraints?
- Chat happens in a staging area (
~/Builds/.staging/). No project directory created yet. - When the user hits START, staging moves to a real project dir and the pipeline runs autonomously.
- A reads
build-plan-template.md— A's playbook. - A completes the entire checklist — research, write, verify, context, review.
- A writes the plan to
plan.mdwith complete, copy-pasteable code for every file. - A self-reviews multiple times before sending to B.
- B reads the plan and sends structured questions back to A.
- A answers with verified information and updates the plan.
- This loops until B is fully satisfied. No round limit.
- B approves. The plan is locked — no agent can modify it from this point.
- C reads the locked plan and builds exactly what it says.
- No improvising, no interpreting, no "improving."
- D reads the plan and the code. Checks: does the code match the plan?
- If D has issues, sends them to C. C fixes, sends back.
- Loops until D is satisfied with the code.
- D runs the code. Tests it.
- If tests fail, D sends failures to C. C fixes, D tests again.
- Loops until all tests pass.
- Build complete. Project is in
~/Builds/<project-name>/.
LLMs ignore prompt instructions. An agent told "only write plan.md" will write code files. An agent told "don't modify anything" will edit the plan.
Restrictions are enforced by a PreToolUse hook (pipeline/.claude/hooks/approval-gate.sh) that prevents agents from accidentally exceeding their role. The hook is a guardrail, not a sandbox — see SECURITY.md for the threat model and known limitations. The hook reads the PIPELINE_AGENT environment variable and gates every tool call:
| Agent | Write | Bash | Agent Tool |
|---|---|---|---|
| A (Planner) | plan.md only |
Blocked | Blocked |
| B (Reviewer) | Blocked | Blocked | Blocked |
| C (Coder) | Inside ~/Builds/ (except plan.md) |
Safe=auto, dangerous=approval | Blocked |
| D (Tester) | Blocked | Safe=auto, dangerous=approval | Blocked |
| S (Supervisor) | ~/Builds/ only (no .claude/) |
Yes (restricted) | Blocked |
Additional protections:
- All writes outside
~/Builds/are blocked for every agent - Plan is locked after B approves
- Agent tool blocked for all agents (prevents recursive spawning)
--permission-mode autoadds Claude's AI safety classifier on top
Agents don't parse free text. They communicate via structured JSON schemas:
// B reviewing A's plan
{ "status": "approved" }
{ "status": "questions", "questions": ["What about error handling?"] }
// D reviewing C's code
{ "status": "approved" }
{ "status": "issues", "issues": ["Missing input validation on POST /users"] }
// D testing C's code
{ "status": "passed" }
{ "status": "failed", "failures": ["PUT /users returns 500 on empty body"] }The orchestrator routes these signals and uses isPositiveSignal() to normalize approval variants.
Each agent runs as a separate Claude Code session:
claude -p "<prompt>" \
--system-prompt-file <role-file> \
--permission-mode auto \
--model claude-opus-4-6 \
--output-format stream-json \
--verbose--permission-mode auto— Claude's AI classifier handles general safety--output-format stream-json— real-time streaming for the viewerPIPELINE_AGENTenv var — tells the hook which agent is running- Role files provide context (what the agent's job is), hooks provide law (what the agent can do)
pipeline/orchestrator.ts is deterministic code, not an LLM. It:
- Spawns agent sessions in order
- Parses their streaming JSON output
- Routes structured signals between agents
- Advances the pipeline phase on approval signals
- Tracks token usage, costs, and events
- Writes everything to
pipeline-events.jsonfor the viewer
The orchestrator cannot be confused, distracted, or convinced to skip steps.
A Next.js app that polls pipeline-events.json every 400ms and renders:
- Pixel art office scene with 5 agents at desks
- Live feed of all events
- 5-panel grid (S + A/B/C/D) with per-agent event streams
- Dashboard with phase progress, token usage, cost
- Per-panel chat inputs for direct agent communication
- START/STOP/Reset controls
API routes handle:
POST /api/chat— spawns a claude session for direct chat (Phase 0 or post-build)POST /api/start-pipeline— creates project dir from staging, spawns orchestratorPOST /api/stop-pipeline— kills orchestrator + claude sessionsPOST /api/reset— clears staging, resets stuck projectsGET /api/state— returns current pipeline statePOST /api/approve— approves/denies dangerous bash commands
User types in viewer
-> POST /api/chat -> spawns claude session -> writes to .staging/pipeline-events.json
-> GET /api/state polls .staging/ -> viewer renders events
User hits START
-> POST /api/start-pipeline
-> staging moves to ~/Builds/<project>/
-> orchestrator spawns as detached process
-> orchestrator writes to ~/Builds/<project>/pipeline-events.json
-> GET /api/state polls project dir -> viewer renders events
User hits STOP
-> POST /api/stop-pipeline -> pkill orchestrator + claude sessions
User hits RESET
-> POST /api/reset -> clears staging, resets active projects
┌─────┐
│ YOU │ gives concept, answers A's questions (Phase 0 only)
└──┬──┘
│
┌─────┐
│ B │ plan reviewer — only talks to A
└──┬──┘
│
┌─────┴─────┐
│ A │ planner / deployer — talks to everyone
└─────┬─────┘
│
┌─────┴─────┐
│ C │ coder — talks to A (questions) and D (code)
└─────┬─────┘
│
┌─────┴─────┐
│ D │ reviewer + tester — talks to C (fixes) and A (final)
└───────────┘
S sits above — available when things go sideways
After Phase 0, pipeline runs fully autonomous
All sessions: claude --permission-mode auto --model claude-opus-4-6
In manual mode, the orchestrator does not exist. The user is the orchestrator.
- No pipeline, no phases, no automation. 5 Claude sessions with one-line expertise labels.
- State lives in
~/Builds/.manual/manual-state.json— separate from pipeline state. - No role files. Agents get a one-line system prompt on first message:
- A: "You specialize in software planning and architecture."
- B: "You specialize in code review and finding gaps."
- C: "You specialize in writing code."
- D: "You specialize in testing and debugging."
- S: "You help oversee and diagnose issues."
- No
PIPELINE_AGENTenv var — hooks don't apply pipeline restrictions. - Model picker — user chooses Opus or Sonnet per session.
- Handoff button — grabs an agent's last text response and stages it as context for the next agent messaged. Max 2000 chars.
- Per-agent sending — multiple agents can be active simultaneously.
- Session resume — sessions persist in
manual-state.jsonand resume via--resume.
Manual Mode Data Flow
User types in any panel
-> POST /api/chat { mode: 'manual', model, agent, message }
-> spawns claude with --system-prompt (first msg) or --resume (subsequent)
-> cwd: ~/Builds/.manual/
-> streams events into manual-state.json
-> GET /api/state?mode=manual polls manual-state.json -> viewer renders
User hits RESET
-> POST /api/reset { mode: 'manual' } -> deletes ~/Builds/.manual/