Orchestrating parallel sprints

Multiple agents. Multiple terminals. One sprint. Atomic file operations.

The problem

After the build phase, review, QA, and security are all read-only analyses. They read the same code, produce independent artifacts, and never modify source files. Running them one after another wastes time. A full sequential sprint takes 15-20 minutes. Running the three analysis phases in parallel cuts that to 6-8 minutes.

Batch assignment

Run sprint.sh batch to see how the conductor distributes work:

$ bin/sprint.sh batch --preview

Batch 1 (sequential):  think
Batch 2 (sequential):  plan
Batch 3 (sequential):  build
Batch 4 (parallel):    review, qa, security
Batch 5 (sequential):  ship

Total phases: 7
Parallelizable: 3 of 7 (batch 4)
Estimated speedup: 2.1x over sequential

The /nano command saves artifacts as phase "plan".

Batches 1-3 run in a single agent session. Batch 4 fans out to multiple agents. Batch 5 waits for all of batch 4 to complete before running.

Concurrency classification

Each skill declares its concurrency mode in the SKILL.md frontmatter. The conductor uses this to decide what can run in parallel:

Phase        Concurrency
──────────────────────────
think        read
plan (nano)  read
build        write
review       read
qa           read
security     read
ship         exclusive
guard        exclusive
compound     write
conductor    exclusive
  • read phases can run in parallel with other read phases. They share the codebase without conflict.
  • write phases can run in parallel with read phases but not with other write phases. One writer at a time.
  • exclusive phases run alone. Nothing else executes until an exclusive phase finishes.

Note: build is not a skill. It is the phase where code gets written. It has concurrency: write because it modifies files.

Multi-terminal setup

The simplest way to parallelize: open multiple terminal windows in the same project directory.

# Terminal 1: run the sprint up to the parallel phase
$ claude
> /conductor start

# Conductor runs think → plan → build sequentially,
# then prints:

Ready for parallel execution.
Run 'sprint.sh batch' in 2 more terminals.

# Terminal 2:
$ bin/sprint.sh batch
Claimed: review
Running /review...

# Terminal 3:
$ bin/sprint.sh batch
Claimed: qa
Running /qa...

# Terminal 1 (conductor picks up the remaining phase):
$ bin/sprint.sh batch
Claimed: security
Running /security...

# When all three complete:
$ bin/sprint.sh status
review:   complete (artifact saved)
qa:       complete (artifact saved)
security: complete (artifact saved)

All parallel phases complete. Run /ship to finalize.

Multi-agent setup

Different agents can handle different phases. Each agent reads the same codebase and writes artifacts to the same store. The coordination layer does not care which agent runs which phase.

# Terminal 1: Claude Code handles review
$ claude
> /review
# Reads code, produces review artifact

# Terminal 2: Codex handles QA
$ codex
> Run the nanostack QA phase. Follow .claude/commands/qa.md
# Reads code, produces QA artifact

# Terminal 3: OpenCode handles security
$ opencode
> Run the nanostack security phase. Follow .claude/commands/security.md
# Reads code, produces security artifact

The artifacts are agent-agnostic. They follow the same JSON schema regardless of which agent produced them. /ship reads all three artifacts and aggregates the findings.

Stale lock recovery

If an agent crashes or a terminal closes mid-phase, the lock directory stays on disk. The conductor detects stale locks by checking whether the PID in the lock file is still running:

$ bin/sprint.sh status
review:   complete
qa:       stale (pid 42399 not running)
security: complete

# Reclaim the stale lock
$ bin/sprint.sh claim qa
Reclaimed stale lock: qa (previous owner: pid 42399)

# Or force-reclaim without checking
$ bin/sprint.sh claim --force qa
Force-claimed: qa

Stale detection happens automatically when you run sprint.sh status or sprint.sh batch. A phase marked stale is eligible for reclaim by any agent. The original agent's partial work is discarded — the phase starts fresh.

PreviousStack defaultsNextConflict rules