| name | fleet |
| description | Parallel campaign orchestrator. Runs multiple campaigns in coordinated waves within a single session. Spawns 2-3 agents per wave in isolated worktrees, collects discoveries, shares context between waves. Use when work decomposes into 3+ independent streams that can run simultaneously. |
| user-invocable | true |
| auto-trigger | false |
| last-updated | "2026-03-21T00:00:00.000Z" |
/fleet — Parallel Coordinator
Use for 3+ independent work streams that can run simultaneously in isolated worktrees. Do NOT use for single-file scope, linear work, or when a marshal or skill suffices.
Orientation
Use when: Running 2+ independent work streams in parallel — tasks with non-overlapping file scopes that can execute simultaneously.
Don't use when: Work must execute sequentially or accumulate findings across phases (use /archon), a single orchestrated session is enough (use /marshal), or the task is simple enough for a bare skill.
Commands
| Command | Behavior |
|---|
/fleet [direction] | Decompose direction into parallel streams, execute in waves |
/fleet [path-to-spec] | Read a spec file, decompose into streams |
/fleet continue | Resume from the last fleet session file |
/fleet (no args) | Health diagnostic → work queue → execute |
/fleet --quick [task1]; [task2] | Lightweight parallel mode for solo devs — 2+ tasks, single wave, auto-merge, no session file |
/fleet --speculative N [direction] | Try N different approaches to the same task in parallel — see Speculative Mode below |
Protocol
Step 1: WAKE UP
- Read CLAUDE.md (project conventions)
- Check
.planning/campaigns/ for active campaigns
- Check
.planning/coordination/claims/ for external claims
- Determine input mode: directed, spec-driven, continuing, or undirected
- Load prior session context: If
.planning/momentum.json exists, run
node .citadel/scripts/momentum-read.cjs
and read the output. Use the active scopes and recurring decisions to inform
work queue prioritization. Skip silently if the file is absent or output is empty.
Wave context restoration: Use the Claude Code Compaction API to restore fleet
session context at the start of each session. Do NOT read .claude/compact-state.json
— that pattern is deprecated in favour of server-side compaction (available on Opus 4.6+).
Fleet session files (.planning/fleet/session-{slug}.md) remain the source of truth
for inter-wave discovery relay; compaction handles agent memory, not campaign state.
If the Compaction API is unavailable, fall back to reading the fleet session file's
Continuation State directly.
Step 1b: LOG SESSION START + START WATCHER
node .citadel/scripts/telemetry-log.cjs --event campaign-start --agent fleet --session {session-slug}
node .citadel/scripts/momentum-watch-start.cjs
The watcher runs in the background and re-synthesizes momentum.json within 500ms of any new discovery write. Safe to call if already running — only one watcher runs per project.
Step 2: WORK QUEUE
Produce a ranked list of campaigns with:
| Column | Purpose |
|---|
| Campaign name | What this stream does |
| Scope | Which directories it touches |
| Dependencies | What must complete before this can start |
| Wave | Which wave to assign it to |
| Agent type | What kind of agent to spawn |
Rules for work queue:
- Independent items go in Wave 1
- Items that depend on Wave 1 results go in Wave 2
- Maximum 3 agents per wave (conservative default)
- Scope must NOT overlap between agents in the same wave
Step 3: WAVE EXECUTION
For each wave:
-
Prepare context for each agent:
- CLAUDE.md content
.claude/agent-context/rules-summary.md
- Map slice (if
.planning/map/index.json exists): run
node scripts/map-index.js --query "<agent's scope keywords>" --max-files 15
and inject the results as a === MAP SLICE === block. If the index does
not exist, skip silently.
- Prior session context (all waves): re-read
momentum.json fresh at each
wave boundary via node .citadel/scripts/momentum-read.cjs and inject as a
=== PRIOR SESSION CONTEXT === block. Re-reading (rather than reusing the
Step 1 snapshot) picks up discoveries written by parallel Fleet sessions in
other terminals. If the output is empty, skip silently.
- Campaign-specific direction and scope
- Discovery briefs from previous waves (if any)
-
Log wave start:
node .citadel/scripts/telemetry-log.cjs --event wave-start --agent fleet --session {session-slug} --meta '{"wave":N,"agents":["name1","name2"]}'
-
Spawn agents with isolation: "worktree":
Agent(
prompt: "{full context + direction}",
isolation: "worktree",
mode: "bypassPermissions"
)
-
Collect results from all agents in the wave
4.5. Validate wave results — spawn one Phase Validator per agent in parallel
(validators are Haiku, read-only, effort: low):
Agent(
subagent_type: "citadel:phase-validator",
prompt: "Campaign: {session-slug}. Wave {N} agent: {agent-name}.
Exit conditions: {agent's scope goal and any stated conditions}.
HANDOFF: {agent's full handoff text}",
effort: "low"
)
Collect all validator verdicts. For each agent:
verdict: "pass": mark agent validated in session file. Proceed.
verdict: "fail": check retry counter for this agent (max 2 retries in fleet;
single-session so lower budget than Archon's 3):
- Retries remain: re-spawn the failed agent in a new worktree with the
validator's
conditions_failed and suggestions appended to its prompt.
Collect its result and re-validate. Decrement counter.
- Retries exhausted: mark agent
partial in session file. Log
validator_halt: {agent-name} wave {N} — {conditions_failed}. Continue.
- Validator timeout or unparseable output: treat as pass with warning. Log. Advance.
Run all validators for the wave in a single parallel batch — do not validate
sequentially. The cost is proportional to the wave size, not multiplicative.
-
Log per-agent results:
node .citadel/scripts/telemetry-log.cjs --event agent-complete --agent {agent-name} --session {session-slug} --status {success|partial|failed}
-
Compress discoveries for each agent:
- Extract HANDOFF blocks
- Run
node .citadel/scripts/compress-discovery.cjs on each output
- Write compressed briefs to
.planning/fleet/briefs/
6b. Write persistent discovery records for each agent (cross-session memory):
node .citadel/scripts/discovery-write.cjs \
--session {session-slug} \
--agent {agent-name} \
--wave {wave-number} \
--status {success|partial|failed} \
--scope "{comma-separated-scope-dirs}" \
--handoff "{json-array-of-handoff-items}" \
--decisions "{json-array-of-decisions}" \
--files "{json-array-of-files-touched}" \
--failures "{json-array-of-failures}"
-
Log wave complete:
node .citadel/scripts/telemetry-log.cjs --event wave-complete --agent fleet --session {session-slug} --meta '{"wave":N,"status":"complete"}'
-
Merge branches from worktrees:
- Review changes from each agent
- If clean merge: merge the branch
- If conflicts: record in session file, then decide:
- Resolve if: the conflict is < 20 lines and affects only formatting or naming
- Skip if: the conflict involves competing logic changes; keep the higher-delta worktree result and log the discarded changes in session file
-
Update session file with wave results and accumulated discoveries
Step 5: COMPLETION
After all waves:
- Run typecheck on the full project via
node scripts/run-with-timeout.js 300 <typecheck-cmd>
- Run tests if configured (also use the timeout wrapper). If tests fail after wave completion: apply the same error ladder as the main protocol — 1-2 failures: fix before merging; 3-4 failures: attempt fixes, continue if resolved; 5+ failures: halt the wave merge for that worktree and log
wave_test_fail: true in the session file.
- Update session file status to
completed
- Log session completion:
node .citadel/scripts/telemetry-log.cjs --event campaign-complete --agent fleet --session {session-slug}
- Update momentum (cross-session synthesis):
node .citadel/scripts/momentum-synthesize.cjs
5.5. Propagate knowledge — for each campaign that completed this session, run:
npm run propagate -- --campaign {slug}
Run once per completed campaign slug (not per wave). If multiple campaigns
completed, run for each slug. If npm run propagate is unavailable, note each
slug in the fleet session file under ## Pending Propagation.
6. Output final HANDOFF
Fleet Session File Format
Create at .planning/fleet/session-{slug}.md:
# Fleet Session: {name}
Status: active | needs-continue | completed
Started: {ISO timestamp}
Direction: {original direction}
## Work Queue
| # | Campaign | Scope | Deps | Status | Wave | Agent |
## Wave N Results
### Agent: {name}
**Status:** complete | partial | failed
**Built:** ... **Decisions:** ... **Files:** ...
## Shared Context (Discovery Relay)
- {cross-agent finding → what Wave N+1 should know}
## Continuation State
Next wave: N Blocked items: ... Auto-continue: true
Scope Overlap Prevention
Before assigning agents to a wave:
- List all scope directories for each agent
- Check for parent/child overlaps:
src/api/ and src/api/auth/ OVERLAP (parent/child)
src/api/ and src/ui/ do NOT overlap (siblings)
(read-only) scopes never conflict
- If overlap: move one agent to a later wave
Also check .planning/coordination/claims/ for external claims.
Budget Management
Effort hints for wave agents (use the effort parameter, not budget_tokens):
| Agent Type | Effort | ~Tokens |
|---|
| Fleet scouts (research, mapping, audit) | medium | ~100K each |
| Execution agents (build, refactor, implement) | high | ~250K each |
| Verify agents (typecheck, visual-verify, QA) | low | ~60K each |
The effort parameter is GA as of April 2026 and produces ~20–40% token reduction
compared to manually tuned budget_tokens values. Always prefer effort for new wave definitions.
Quality Gates
- All agents must receive full context injection
- Scope must not overlap between same-wave agents
- Every wave must produce compressed discovery briefs
- Discovery relay must be injected into subsequent waves
- Merge conflicts must be resolved or explicitly recorded
- Final typecheck must pass after all waves
Agent Timeouts
Sub-agents can hang indefinitely on tool calls. Fleet must enforce execution time limits
at the orchestrator level.
Default Timeouts
| Agent Type | Default Timeout | Override Key |
|---|
| Skill-level agents | 10 minutes | agentTimeouts.skill |
| Research scouts | 15 minutes | agentTimeouts.research |
| Build agents | 30 minutes | agentTimeouts.build |
Timeouts are configurable in harness.json:
{
"agentTimeouts": {
"skill": 600000,
"research": 900000,
"build": 1800000
}
}
Timeout Protocol
On timeout: log agent-timeout event, extract partial HANDOFF if present, retry once with simplified prompt (Wave 1 critical scope only), skip otherwise. Never block the wave. Record Status: timed out in session file.
Read timeout values from harness.json → agentTimeouts.{skill|research|build} (defaults: 600000/900000/1800000ms).
Shared State Merge Strategies
Parallel agents writing to the same .planning/ directory can silently overwrite
each other. Each shared resource has a declared merge strategy:
| Resource | Strategy | Rule |
|---|
.planning/discoveries/*.md | append-only | Never overwrite an existing discovery file. Each agent writes its own uniquely-named file: {agent-id}-{timestamp}.md. |
.planning/fleet/briefs/*.md | append-only | Each agent writes its own brief. Fleet coordinator reads all of them. |
.planning/fleet/session-{slug}.md | lock-on-write | Only the Fleet coordinator updates the session file. Agents never write to it directly — they emit HANDOFFs that the coordinator reads and transcribes. |
.planning/campaigns/{slug}.md | lock-on-write | Only the owning Archon instance updates this file. Fleet agents that produce campaign-adjacent work report it in their HANDOFF and let Archon update. |
.planning/telemetry/*.jsonl | append-only | Append-only log. Multiple agents may append simultaneously — JSONL format guarantees each line is an atomic write. |
.planning/wiki/_staging/*.jsonl | append-only | Each agent writes a uniquely-named staging file. Compile step resolves all of them in order. No concurrent write conflicts possible. |
.planning/coordination/claims/*.json | lock-on-write | Each agent owns its own claim file (named by instance ID). No sharing; no conflicts. |
Enforcement: Before Step 3 (spawn agents), remind each agent in its context
injection which paths it may write to and what the strategy is for each. Agents
that attempt to modify lock-on-write resources they don't own must be blocked via
scope claim verification.
Consistency Voting (High-Stakes Decisions)
For decisions that cannot easily be undone — campaign completion approval, campaign
merge to main, fleet abort — spawn 3 judgment agents in parallel and require 2/3
agreement before proceeding.
When to vote:
- Proposing to mark a multi-wave fleet
completed when any wave is partial
- Merging an agent's branch when its phase validator returned a
fail (even after retries)
- Deciding to abort and discard work from a wave with mixed results
How to vote:
Vote prompt: "Fleet session {slug}, Wave {N}. The proposed decision is: {decision}.
Evidence: {handoff summaries, validator results}.
Should we proceed? Respond with JSON: {verdict: 'proceed'|'block', reason: '...'}"
Spawn 3 Phase Validators with the vote prompt. Collect results. Tally:
- 3/3 proceed → proceed
- 2/3 proceed → proceed, log the dissenting reason
- 2/3 block → block, escalate to user with the reasons
- 3/3 block → block
If voting agents time out: count the timeout as a proceed vote (conservative — don't let validator failure park the fleet).
Skip voting when the decision is clearly safe (all waves complete, all validators pass).
Coordination Safety
Instance ID Generation
Every agent spawned by Fleet must have a unique instance ID.
Format: fleet-{session-slug}-{wave}-{agent-index}
Example: fleet-auth-refactor-w1-a3 (wave 1, agent 3)
The instance ID is:
- Written to the agent's worktree as
.fleet-instance-id
- Included in all telemetry log entries for this agent
- Used in coordination claims to identify which agent owns which scope
- Used in dead instance recovery to identify orphaned claims
Scope Overlap Detection
Before spawning: compare all agent scopes pairwise (directory scopes overlap any file inside them). On overlap: merge tasks, narrow scopes, or sequence. NEVER proceed with overlapping scopes.
Dead Instance Recovery
After each wave: read .planning/coordination/claims/, verify each instance is still alive (worktree exists + HANDOFF present). Release orphaned claims, return uncompleted scope to next wave's queue.
Fringe Cases
.planning/fleet/ does not exist: Create the directory before writing the session file.
- All agents in a wave fail: Escalate to the user rather than proceeding to the next wave. Output which agents failed and why before continuing.
- Worktree checkout fails for an agent: Skip that agent, log the failure in the session file, and continue. Record the skipped scope as a gap for the next wave.
.planning/ does not exist: Create .planning/fleet/ before starting. If .planning/coordination/ is absent, skip scope claim registration.
- Discovery compression script missing: Write raw HANDOFF excerpts to the briefs directory instead.
- Phase validator times out or returns malformed output: Treat as pass with warning. Log and advance. Never block a wave on validator failure.
- All agents in a wave fail validation and exhaust retries: Mark the entire wave
partial. Log wave_validator_halt. Escalate to the user before proceeding to the next wave — partial wave results may invalidate downstream wave assumptions.
Speculative Mode
/fleet --speculative N [direction]
Try N different approaches to the same task simultaneously. Each approach gets its own
worktree and branch. When all finish, the user picks the winner; losers are archived (not deleted).
Step 1: Decompose into N strategies
Before spawning, enumerate N distinct approaches. Each approach must:
- Target the exact same files and end goal
- Use a meaningfully different strategy (not just style variations)
- Be feasible to complete in a single agent session
Step 2: Spawn N agents in parallel
Each agent gets:
- The common direction (same for all)
- Its strategy description (different per agent)
- Its own branch name:
speculative/{session-slug}/{strategy-label}
- Instruction to set
branch and worktree_status: active in its campaign frontmatter
Spawn with isolation: "worktree". Scope overlap rules do NOT apply between speculative
agents — they will all touch the same files intentionally.
Step 3: Collect and compare
After all agents complete, for each:
- Read the HANDOFF
- Run typecheck on that worktree's branch via
node scripts/run-with-timeout.js 300 <typecheck-cmd>
- Record in the session file: what was built, typecheck result, key decisions
Present a comparison table to the user:
| Strategy | Branch | Typecheck | Key Decision | Notable Tradeoffs |
|---|
If ALL N approaches fail typecheck: present the comparison table with all entries marked FAIL typecheck. Ask the user to pick the least-broken approach or abort. Do not proceed to Step 4 without a user decision.
Step 4: Archive losers, merge winner
When the user picks a winner:
- Winner: Update campaign frontmatter
worktree_status: merged, proceed with normal merge
- Losers: Update campaign frontmatter
worktree_status: archived. Do NOT delete branches.
git tag archive/{loser-branch} {loser-branch}
Add ## Speculative Comparison to session file: direction, N strategies, comparison table (strategy/branch/status/typecheck/notes), winner, merge timestamp.
Quick Mode
/fleet --quick [task1]; [task2]; [task3]
Differences from standard fleet
| Property | Standard Fleet | Quick Mode |
|---|
| Min streams | 3 | 2 |
| Min complexity | 4 | 3 |
| Waves | Multi-wave with discovery relay | Single wave only |
| Session file | Written to .planning/fleet/ | Skipped — results reported inline |
| Discovery briefs | Compressed to .planning/fleet/briefs/ | Skipped |
| Merge | Per-wave confirmation | Auto-merge if no conflicts |
| Scope claim | Written to coordination/ | Skipped |
Protocol
- Parse tasks from the
--quick argument (semicolon-separated)
- Validate scope overlap — if any two tasks touch the same files, merge them or sequence them
- Spawn all agents simultaneously with
isolation: "worktree"
- Collect results; auto-merge worktrees if no conflicts detected
- If merge conflict: surface to user, offer manual resolution
- Report results inline — no session file written unless the user asks
When /do routes here
/do routes to --quick mode (not standard fleet) when:
- Input contains "at the same time", "simultaneously", "in parallel", "both ... and"
- Two or more clearly independent tasks are detected
- Complexity is 3 (moderate), not 4+ (complex)
- User chose "1" (yes once) or "2" (always) on the Fleet confirmation prompt
Entry from /do confirmation prompt: user chose yes (1) or always (2). Preferences stored under consent.fleetSpawn in harness.json via readConsent/writeConsent.
Contextual Gates
Disclosure
- "Spawning {N} agents across {waves} waves in isolated worktrees. Estimated token budget: ~{tokens}K."
- For speculative mode: "Running {N} parallel approaches to the same task. All will touch the same files."
Reversibility
- Green: Single-wave fleet with < 3 agents
- Amber: Multi-wave fleet (the default) -- each wave's merge is a separate commit
- Red: Speculative mode or fleets that modify shared infrastructure
Red actions require explicit confirmation regardless of trust level.
Proportionality
- Standard fleet: work queue requires 3+ independent streams. Fewer → downgrade to Marshal or Archon.
- Quick mode: 2+ tasks with non-overlapping scopes. No minimum complexity gate.
- If all streams touch the same directory: downgrade to sequential Archon phases
- If estimated agents > 6: confirm with user (even trusted level)
Trust Gating
Read trust level from harness.json:
- Novice (0-4 sessions): Always confirm before spawning. Show agent count, scopes, and estimated cost.
- Familiar (5-19 sessions): Confirm only for > 3 agents or speculative mode.
- Trusted (20+ sessions): Auto-proceed for standard fleet. Confirm only for speculative mode or > 6 agents.
Exit Protocol
Update the session file, then output:
---HANDOFF---
- Fleet session: {name} — {waves completed} waves, {agents} agents total
- Built: {summary of all wave results}
- Discoveries: {key cross-agent findings}
- Merge conflicts: {count and resolution}
- Next: {remaining work if any}
- Reversibility: amber -- multi-wave merges, revert each wave's merge commit
---