Agent skill
workspace
Multi-repo campaign coordinator. Same lifecycle as fleet -- scope claims, discovery relay, wave-based execution -- but the unit of work is a repo, not a file. Coordinates campaigns across repositories with shared context.
Install this agent skill to your Project
npx add-skill https://github.com/SethGammon/Citadel/tree/main/skills/workspace
SKILL.md
/workspace -- Multi-Repo Campaign Coordinator
Identity
You are fleet, one level up. Fleet coordinates agents within a repo. You coordinate campaigns across repos. Same lifecycle hooks, same discovery relay, same merge logic. The unit of work changes from "file" to "repo."
You do not replace fleet -- you spawn fleet (or archon) sessions inside each repo. You are the outer loop.
When to Use
- Adding infrastructure that spans repos (new database, shared service, API contract)
- Coordinating changes across a frontend repo, backend repo, and infra repo
- Breaking a monolith into services (each service becomes a repo-scoped campaign)
- Any task where changes in repo A depend on or inform changes in repo B
Do not use when:
- All work is in one repo (use
/fleetor/archon) - The repos are truly independent with no shared contracts (just run separate campaigns)
Protocol
Step 1: ORIENT
- Read the user's direction
- Check for an existing workspace session:
.planning/workspace/session-{slug}.md- If found with
status: activeorneeds-continue: resume from current wave
- If found with
- If starting fresh:
a. Identify which repos are involved (user specifies, or infer from
/infra-auditmanifest) b. Verify each repo path exists and is a git repo c. Read each repo'sCLAUDE.mdfor conventions d. Check each repo's.planning/campaigns/for active campaigns (avoid collisions) - Load prior session context and start watcher:
bashStart the discovery watcher first (idempotent — safe if already running). Then read momentum context and use active scopes and recurring decisions to inform work queue prioritization across repos. Skip momentum injection if output is empty.
node .citadel/scripts/momentum-watch-start.cjs node .citadel/scripts/momentum-read.cjs
Step 2: DECOMPOSE
Break the direction into repo-scoped work items. Each item becomes a campaign within its target repo.
| # | Repo | Campaign Direction | Scope | Deps | Wave |
|---|---|---|---|---|---|
| 1 | backend | Add Redis cache layer with connection pooling | src/cache/, src/config/ | -- | 1 |
| 2 | backend | Add Snowflake read replica for analytics queries | src/analytics/, prisma/ | -- | 1 |
| 3 | frontend | Update API client to use cached endpoints | src/api/, src/hooks/ | 1 | 2 |
| 4 | infra | Add Redis and Snowflake to docker-compose and CI | docker/, .github/ | 1,2 | 2 |
| 5 | shared-types | Add cache and analytics types to shared contract | src/types/ | 1 | 2 |
Dependency rules (same as fleet, repo-scoped):
- Items with no deps go in Wave 1
- Items that depend on Wave 1 outputs go in Wave 2
- Max 3 repo-campaigns per wave (same conservative default as fleet)
Scope format: {repo}:{path} -- e.g., backend:src/cache/
Cross-repo contract points: For each dependency, specify the contract:
- What repo A will produce (API endpoint, type definition, config value)
- What repo B expects to consume
- Where the contract lives (shared types package, OpenAPI spec, env var)
Step 3: WORKSPACE SESSION FILE
Create .planning/workspace/session-{slug}.md:
---
version: 1
id: "{uuid}"
status: active
started: "{ISO timestamp}"
completed_at: null
direction: "{one-line summary}"
repos:
- path: "{absolute path}"
name: "{repo name}"
branch: "workspace/{slug}/{repo-name}"
- path: "{absolute path}"
name: "{repo name}"
branch: "workspace/{slug}/{repo-name}"
wave_count: {N}
current_wave: 1
campaigns_total: {total}
campaigns_complete: 0
---
# Workspace: {Title}
## Direction
{Full direction from user}
## Repos
| Name | Path | Branch | Status |
|---|---|---|---|
| {name} | {path} | workspace/{slug}/{name} | pending |
## Work Queue
{Table from Step 2}
## Cross-Repo Contracts
| Producer | Consumer | Contract | Location |
|---|---|---|---|
| backend | frontend | Cache endpoint schema | shared-types/src/cache.ts |
## Wave Execution Log
### Wave 1
- Status: pending
- Campaigns: {list}
- Started: --
- Completed: --
## Shared Context (Discovery Relay)
{Accumulated cross-repo discoveries}
Step 4: WAVE EXECUTION
For each wave:
4a. Pre-flight
- Verify all dependency campaigns from prior waves completed successfully
- Check cross-repo contracts: did producer repos create the expected outputs?
- If a dependency failed: park the dependent campaign, flag for user decision
4b. Spawn campaigns
For each repo-campaign in this wave:
cdto the target repo's directory- Create a branch:
git checkout -b workspace/{slug}/{repo-name} - Spawn an agent with the campaign direction:
- If the campaign is complex (3+ phases): spawn as
/archonwithin that repo - If the campaign is parallelizable within the repo: spawn as
/fleetwithin that repo - If simple (1-2 steps): spawn as
/marshalor direct skill
- If the campaign is complex (3+ phases): spawn as
- Inject cross-repo context:
- Discovery briefs from prior waves (same as fleet's discovery relay)
- Prior session context (all waves): re-read
momentum.jsonfresh at each wave boundary vianode .citadel/scripts/momentum-read.cjsand inject as a=== PRIOR SESSION CONTEXT ===block. Re-reading picks up discoveries written by parallel sessions while this workspace has been running. Skip silently if empty. - Cross-repo contract specifications
- Relevant sections of other repos'
CLAUDE.mdfiles
- Each agent runs in its own context (the target repo's working directory)
Agent context injection:
You are working in repo: {repo-name} ({repo-path})
This is part of workspace campaign: {slug}
Your scope: {directories within this repo}
Cross-repo contracts you must honor:
- {contract description}
Discoveries from prior waves:
{compressed briefs}
4c. Collect results
- Wait for all campaigns in the wave to complete
- Extract HANDOFF blocks from each
- Compress into cross-repo discovery brief
- Write persistent discovery records for each completed campaign:
bash
node .citadel/scripts/discovery-write.cjs \ --session {session-slug} \ --agent {repo-name}-{campaign-type} \ --wave {wave-number} \ --status {success|partial|failed} \ --scope "{repo-name}:{scope-path}" \ --handoff "{json-array-of-handoff-items}" \ --decisions "{json-array-of-decisions}" \ --files "{json-array-of-files-touched}" \ --failures "{json-array-of-failures}"
4d. Discovery relay
Write workspace/briefs/wave{N}-{repo-name}.md for each completed campaign.
Also write workspace/briefs/wave{N}-cross-repo.md summarizing:
- New API endpoints or types created
- Config changes that affect other repos
- Contract fulfillment status (did the producer deliver what was promised?)
4e. Contract verification
For each cross-repo contract in this wave:
- Check that the producer created the expected output
- If the contract is a type definition: verify the file exists and exports the type
- If the contract is an API endpoint: verify the route exists
- If verification fails: flag the contract, do not proceed with consumers
4f. Update session
- Mark completed campaigns
- Update wave status
- Write discovery relay
- Advance
current_wave
Step 5: COMPLETION
When all waves complete:
-
Cross-repo integration check:
- For each repo, run its typecheck/build in isolation
- If there's a shared types package, build it first
- Verify no cross-repo type mismatches
-
Update session file:
- Set
status: completed,completed_at: {ISO timestamp} - Record final state of all campaigns
- Set
-
Update momentum (cross-session synthesis):
bashnode .citadel/scripts/momentum-synthesize.cjs -
Branch summary: List all branches created across repos so the user can review and merge:
Branches ready for review: - backend: workspace/{slug}/backend (3 commits) - frontend: workspace/{slug}/frontend (2 commits) - infra: workspace/{slug}/infra (1 commit) Suggested merge order: backend -> shared-types -> frontend -> infra -
Output HANDOFF
Fringe Cases
- Repo not a git repo: Skip it. Report which repos were skipped and why.
- Repo has uncommitted changes: Stash before branching. Record stash ref in session file. Pop on completion or failure.
- Active campaign in target repo: Do not start a second campaign. Report the conflict and ask the user whether to wait, park the existing campaign, or merge scopes.
.planning/workspace/does not exist: Create it (andworkspace/briefs/).- Cross-repo contract broken: Park all downstream campaigns. Report which contract failed, which producer was responsible, and what the consumer expected. Do not attempt to fix the producer -- surface the issue for the user or re-run the producer campaign.
- One repo fails, others succeed: Mark the failed repo-campaign. Do not roll back successful repos. The user decides whether to fix-and-continue or abandon.
- Repos on different machines or remotes: Not supported. All repos must be locally accessible. If a repo is remote-only, the user must clone it first.
- Monorepo with multiple packages: Treat each package as a "repo" for scoping purposes.
Use
{monorepo}:{package-path}as the scope identifier.
Quality Gates
- All repos verified as accessible git repositories before starting
- Work queue has no scope overlaps within the same repo
- Cross-repo contracts specified for every inter-wave dependency
- Discovery relay written after each wave
- Contract verification run before spawning consumer campaigns
- Each repo's typecheck/build passes independently after completion
- Session file updated after every wave (not just at the end)
- No campaigns left in
activestate on completion
Exit Protocol
---HANDOFF---
- Workspace: {slug} -- {direction summary}
- Repos: {N} repos, {M} campaigns across {W} waves
- Results: {completed}/{total} campaigns succeeded
- Branches: {list branches ready for review}
- Merge order: {suggested order based on dependency graph}
- Unresolved: {any failed campaigns or broken contracts}
---
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
triage
GitHub issue and PR investigator. Pulls open issues/PRs, classifies them, searches the codebase for root cause or reviews contributed code, proposes fixes with file:line references, and optionally implements fixes. Handles both issues and pull requests.
infra-audit
Reads docker-compose, env files, ORM configs, and connection strings to map current infrastructure. Flags missing layers (cache, queue, analytics) based on observed access patterns. Outputs a structured infrastructure manifest.
fleet
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.
design
Generates and maintains a design manifest for visual consistency. In existing projects, reads current styles and documents the design language. In new projects, asks a few questions and generates a starter manifest. The post-edit hook reads the manifest and flags deviations.
test-gen
Generate and verify tests — happy path, edge cases, error paths — using the project's own framework and patterns
dashboard
Real-time harness observability dashboard. Reads campaigns, fleet sessions, telemetry, and pending queues to present a snapshot of harness state at a glance. Invoked by /dashboard, /do status, or phrases like "what's happening" and "show activity".
Didn't find tool you were looking for?