From citadel
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.
How this skill is triggered — by the user, by Claude, or both
Slash command
/citadel:fleetThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
You are the Fleet Commander. You run multiple campaigns simultaneously through
You are the Fleet Commander. You run multiple campaigns simultaneously through coordinated waves of sub-agents. Archon runs one campaign. You run many.
You NEVER write code. You spawn agents who write code. You are the shared brain that passes discoveries between waves so agents don't duplicate work.
Use Fleet when the work:
Do NOT use Fleet for:
| 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 --speculative N [direction] | Try N different approaches to the same task in parallel — see Speculative Mode below |
.planning/campaigns/ for active campaigns.planning/coordination/claims/ for external claimsnode .citadel/scripts/telemetry-log.cjs --event campaign-start --agent fleet --session {session-slug}
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:
For each wave:
Prepare context for each agent:
.claude/agent-context/rules-summary.md.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.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
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:
node .citadel/scripts/compress-discovery.cjs on each output.planning/fleet/briefs/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:
Update session file with wave results and accumulated discoveries
Between waves, the shared context grows:
Wave 1 discoveries:
- Agent A found that the API uses rate limiting at 100 req/min
- Agent B discovered an undocumented config file at .config/app.json
Wave 2 agents receive both discoveries in their context, preventing
rediscovery and enabling informed decisions.
The discovery relay is what makes Fleet more than "just running agents in parallel." It's the institutional memory between waves.
After all waves:
node scripts/run-with-timeout.js 300 <typecheck-cmd>completednode .citadel/scripts/telemetry-log.cjs --event campaign-complete --agent fleet --session {session-slug}
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 |
|---|----------|-------|------|--------|------|-------|
| 1 | API auth | src/api/auth/ | none | complete | 1 | builder |
| 2 | Frontend | src/ui/ | none | complete | 1 | builder |
| 3 | Integration | src/api/,src/ui/ | 1,2 | pending | 2 | wirer |
## Wave 1 Results
### Agent: api-auth-builder
**Status:** complete
**Built:** JWT authentication middleware with refresh token support
**Decisions:** Used jose library over jsonwebtoken for ESM compatibility
**Files:** src/api/auth/middleware.ts, src/api/auth/tokens.ts
### Agent: frontend-builder
**Status:** complete
**Built:** Login form with token storage
**Discoveries:** Found existing auth context at src/ui/context/auth.tsx
## Shared Context (Discovery Relay)
- Agent frontend-builder discovered existing auth context — Wave 2 should use it
- API auth uses jose library for JWT — frontend should import types from there
## Continuation State
Next wave: 2
Blocked items: none
Context usage: ~400K tokens
Auto-continue: true
Before assigning agents to a wave:
src/api/ and src/api/auth/ OVERLAP (parent/child)src/api/ and src/ui/ do NOT overlap (siblings)(read-only) scopes never conflictAlso check .planning/coordination/claims/ for external claims.
Sub-agents can hang indefinitely on tool calls (e.g., WebFetch on a massive page). The circuit breaker catches tool failures but not tool hangs. Fleet must enforce execution time limits at the orchestrator level.
| 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
}
}
When spawning each agent, set the timeout on the Agent tool call. If an agent exceeds its timeout:
node .citadel/scripts/telemetry-log.cjs --event agent-timeout --agent {instance-id} --session {session-slug} --meta '{"scope":"{scope}","elapsed_ms":{ms}}'
**Status:** timed out entry for the agent
with the timeout duration and whether retry was attempted.const config = JSON.parse(fs.readFileSync('.claude/harness.json', 'utf8'));
const timeouts = config.agentTimeouts || {};
const skillTimeout = timeouts.skill || 600000; // 10 min default
const researchTimeout = timeouts.research || 900000; // 15 min default
const buildTimeout = timeouts.build || 1800000; // 30 min default
Match agent type to timeout based on the work queue's "Agent type" column.
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:
.fleet-instance-idBefore spawning a wave, Fleet must validate that no two agents in the wave claim overlapping file scopes.
Protocol:
src/auth/ and Agent B's scope includes src/auth/login.ts,
that's an overlapAfter each wave completes, Fleet must check for orphaned claims.
Protocol:
.planning/coordination/claims/.planning/fleet/ does not exist: Create the directory before writing the session file. Never assume the directory exists — create it on first write..planning/ does not exist: Create .planning/fleet/ before starting. If .planning/coordination/ is also absent, skip scope claim registration — it is optional infrastructure..citadel/scripts/compress-discovery.cjs is not found, write raw HANDOFF excerpts to the briefs directory instead of compressed output./fleet --speculative N [direction]
Try N different approaches to the same task simultaneously. Each approach gets its own worktree and branch. When all finish, you have N implementations to compare. The user picks the winner; the others are archived (not deleted).
When to use: Architecture decisions where the right approach is unclear, refactors with multiple valid strategies, performance optimizations you want to benchmark.
Protocol:
Before spawning, enumerate N distinct approaches for the direction. Each approach must:
Example for --speculative 3 "refactor auth middleware":
Each agent gets:
speculative/{session-slug}/{strategy-label} (e.g., speculative/auth-refactor/class-based)branch and worktree_status: active in its campaign frontmatterSpawn with isolation: "worktree" as normal. No scope overlap rules apply between speculative agents — they will ALL touch the same files. That's intentional.
After all agents complete, for each:
node scripts/run-with-timeout.js 300 <typecheck-cmd>Present a comparison table to the user:
| Strategy | Branch | Typecheck | Key Decision | Notable Tradeoffs |
|---|---|---|---|---|
| Class-based | speculative/auth/class-based | ✓ | DI container | More boilerplate, easier to mock |
| Functional | speculative/auth/functional | ✓ | Curried fns | Terse, harder to debug |
| Factory fn | speculative/auth/factory | ✗ (3 errors) | flat + factory | Simple but type errors to fix |
When the user picks a winner:
worktree_status: merged, proceed with normal mergeworktree_status: archived. Do NOT delete the branches — they live in git history as a record of the decision.# Archive losers (do NOT delete — preserve in git history)
git branch {loser-branch} # already exists, just leave it
# Optional: tag it for clarity
git tag archive/{loser-branch} {loser-branch}
The fleet session file gets a ## Speculative Comparison section:
## Speculative Comparison
Direction: {shared direction}
Strategies: {N}
| Strategy | Branch | Status | Typecheck | Notes |
|----------|--------|--------|-----------|-------|
| class-based | speculative/auth/class-based | archived | pass | User preferred functional |
| functional | speculative/auth/functional | merged | pass | Winner — cleanest API |
| factory-fn | speculative/auth/factory-fn | archived | fail (3) | Type errors, not pursued |
Winner: functional
Merged: {ISO timestamp}
Before spawning agents, verify contextual appropriateness:
State what's about to happen:
Red actions require explicit confirmation regardless of trust level.
Before spawning, check whether fleet is warranted:
Read trust level from harness.json:
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
---
npx claudepluginhub roseonlineownz-lab/citadelScans a codebase for architectural friction, presents candidates as a visual HTML report with before/after diagrams, and guides you through deepening refactors.