Worktrees
Swarm uses git worktrees to provide each agent with an isolated working directory and branch. This prevents file conflicts between agents working in parallel and enables clean merging of results back to the main branch.
Prerequisites
- Git 2.20+ — Required for
git worktree lock/unlocksupport. Checked automatically at startup. - Not detached HEAD — Swarm requires a branch checkout for merge-back to work.
- Clean working tree — Either commit/stash changes first, or use
--stashto auto-stash.
Path and Branch Conventions
| Item | Pattern | Example |
|---|---|---|
| Swarm directory | <repo>/.swarm/ | /home/user/project/.swarm/ |
| Worktree path | <repo>/.swarm/worktrees/<name> | .swarm/worktrees/backend |
| Agent branch | swarm/<session_id>/<name> | swarm/20250115-a3f2/backend |
| Supervisor branch | swarm/<session_id>/supervisor | swarm/20250115-a3f2/supervisor |
| Beads branch | swarm/<session_id>/beads | swarm/20250115-a3f2/beads |
The .swarm/ directory is automatically added to .git/info/exclude so it doesn't appear in git status.
Worktree Creation
During session start (Step 7), the orchestrator creates worktrees for each agent and the supervisor:
# For each agent:
git worktree add .swarm/worktrees/<name> -b swarm/<session_id>/<name> <base_commit>
git worktree lock .swarm/worktrees/<name>
# For the supervisor:
git worktree add .swarm/worktrees/supervisor -b swarm/<session_id>/supervisor <base_commit>
git worktree lock .swarm/worktrees/supervisor
# Shared beads branch:
git branch swarm/<session_id>/beads <base_commit>
Each worktree starts from the same base commit (HEAD at session start), ensuring all agents begin with identical codebases.
Worktree Locking
Worktrees are locked immediately after creation using git worktree lock. This prevents git worktree prune from accidentally removing them during the session. Worktrees are unlocked during cleanup.
Worktree Cleanup
When a session stops, worktrees are cleaned up in order:
-
Auto-commit dirty — If the worktree has uncommitted changes, stage and commit them:
git -C .swarm/worktrees/<name> add -A git -C .swarm/worktrees/<name> commit -m "swarm: auto-commit on stop" -
Unlock —
git worktree unlock .swarm/worktrees/<name> -
Remove —
git worktree remove .swarm/worktrees/<name> -
Prune —
git worktree pruneto clean stale references -
Delete branches — Remove all
swarm/<session_id>/*branches
Merge Operations
After cleanup, agent branches are merged based on the stop mode:
Merge (--merge, default)
Non-fast-forward merge in config order (agents first, then supervisor):
git merge --no-ff swarm/<session_id>/backend -m "Merge agent: backend"
git merge --no-ff swarm/<session_id>/frontend -m "Merge agent: frontend"
git merge --no-ff swarm/<session_id>/supervisor -m "Merge supervisor"
Squash (--squash)
Squash-merge each agent branch into a single commit:
git merge --squash swarm/<session_id>/backend
git commit -m "Squash agent: backend"
Discard (--discard)
Delete branches without merging — all agent work is discarded.
Recovery
Swarm handles crash recovery for stale sessions:
Stale Session Detection
A session is stale when its pid (from session.json) no longer corresponds to a running process. This is detected via libc::kill(pid, 0).
Recovery Flow
When a stale session is detected (during swarm start or swarm stop):
- Auto-commit any dirty worktrees
- Remove all session worktrees (unlock + remove)
- Prune stale worktree references
- Delete all
swarm/<session_id>/*branches - Remove
session.jsonandlockfile
Clean Command
swarm clean provides manual cleanup:
swarm clean # Interactive — asks for confirmation
swarm clean --force # Removes artifacts without confirmation
This handles cases where automatic recovery isn't sufficient (e.g., corrupted worktree state).
Related
- ADR-006: Git Worktree Isolation — Design rationale
- Orchestration — How worktrees fit in the start/stop flow
- Architecture — System overview