SwarmForge Handoff Directory Structure: A Complete Guide to the Inbox/Outbox Protocol
SwarmForge uses a dedicated .swarmforge/handoffs/ directory with fixed subdirectories (outbox/, inbox/, sent/, failed/) to enable reliable, audit-trailed work exchanges between AI agents without direct socket communication.
The SwarmForge handoff directory structure implements a durable, filesystem-based message queue that replaces traditional inter-agent networking. Each agent's worktree contains a single hidden directory where all task exchanges are staged, delivered, and archived. This design ensures restart-safe processing and deterministic order guarantees, as specified in swarmforge/handoff-protocol.md【/cache/repos/github.com/unclebob/swarm-forge/main/swarmforge/handoff-protocol.md#L24-L38】.
Root Handoff Directory Location
Every agent operates within a worktree root containing:
.swarmforge/
└── handoffs/
├── outbox/
├── sent/
├── failed/
└── inbox/
The .swarmforge/handoffs/ path is hardcoded and enforced by the handoff daemon (handoffd.bb) and all helper scripts. No configuration overrides this location.
Outbox Subdirectories
The outbox/ branch handles outbound handoffs created by the local agent.
outbox/
Holds validated .handoff files ready for delivery. Files here follow strict naming conventions:
00_20260615T140531Z_000042_from_architect_to_coder.handoff
└┬┘ └─────────┬────────┘ └─┬─┘ └──┬──┘ └──┬───┘
│ │ │ │ └─ recipient agent
│ │ │ └─ sender agent
│ │ └─ sequence number
│ └─ UTC timestamp
└─ priority (00-99, lower = higher priority)
outbox/tmp/
A private scratch area for atomic file creation. The handoff daemon ignores this directory entirely. Scripts like swarm_handoff.sh write handoff contents here first, then perform an atomic move to outbox/ once fully formed. This prevents the daemon from processing incomplete files.
Delivery Archive Directories
After processing, outbound handoffs land in one of two terminal states.
sent/
Contains successfully delivered handoffs. The daemon (handoffd.bb) moves the original file here after:
- Validating the handoff structure
- Copying it to every recipient's
inbox/new/ - Adding audit headers (
recipient,enqueued_at)
failed/
Stores undeliverable handoffs with diagnostic context. Common failure modes include:
- Validation errors (malformed headers)
- Missing or invalid recipient agents
- Permission or disk space issues
Each failed handoff retains its original content plus error annotations.
Inbox Subdirectories
The inbox/ branch manages incoming work from other agents.
inbox/new/
The task queue for unclaimed handoffs. Agent helper scripts scan this directory to find the next available work item. The ready_for_next.sh entry point dispatches to ready_for_next_task.sh or ready_for_next_batch.sh based on configuration.
Selection uses priority-then-FIFO ordering: lower numeric prefixes process first; ties resolve by arrival time.
inbox/in_process/
Holds the currently active handoff (or batch directory in batch mode). When an agent claims work:
ready_for_next.sh
# Output:
# TASK: .swarmforge/handoffs/inbox/in_process/00_20260615T140531Z_000042_from_architect_to_coder.handoff
# FROM: architect
# TYPE: git_handoff
# PRIORITY: 00
# TASK_NAME: task-1-cave-setup
The atomic move from inbox/new/ to inbox/in_process/ prevents double-claiming.
inbox/completed/
Archive of finished handoffs. The done_with_current.sh script (dispatching to done_with_current_task.sh) finalizes the active work:
- Adds
completed_attimestamp - Records processing outcome
- Moves file to
inbox/completed/
Complete Directory Tree Example
.swarmforge/
└── handoffs/
├── outbox/
│ ├── tmp/
│ ├── 00_20260615T140531Z_000042_from_architect_to_coder.handoff
│ └── 01_20260615T140545Z_000043_from_architect_to_tester.handoff
├── sent/
│ └── 00_20260615T140500Z_000041_from_pm_to_architect.handoff
├── failed/
│ └── 02_20260615T140600Z_000044_from_architect_to_invalid_agent.handoff.err
└── inbox/
├── new/
│ ├── 00_20260615T140548Z_000045_from_tester_to_architect.handoff
│ └── 01_20260615T140555Z_000046_from_pm_to_architect.handoff
├── in_process/
│ └── 00_20260615T140531Z_000042_from_architect_to_coder.handoff
└── completed/
├── 00_20260615T140400Z_000040_from_coder_to_tester.handoff
└── 01_20260615T140420Z_000039_from_tester_to_pm.handoff
Handoff File Format
Files stored throughout this structure follow a YAML frontmatter + body format:
id: 20260615T140531Z_000042_from_architect
from: architect
to: coder
recipient: coder
priority: 00
type: git_handoff
role: architect
task: task-1-cave-setup
commit: a1b2c3d9e8
created_at: 2026-06-15T14:05:31Z
enqueued_at: 2026-06-15T14:05:32Z
Re-read your role and constitution.
merge_and_process.sh architect a1b2c3d9e8
Headers are space-separated key-value pairs. The blank line separates metadata from payload. The enqueued_at field is added by the daemon during delivery—not present on creation.
Key Scripts Enforcing Structure
| Script | Path | Function |
|---|---|---|
swarm_handoff.sh |
swarmforge/scripts/swarm_handoff.sh |
Creates handoffs in outbox/tmp/, validates, atomically moves to outbox/ |
handoffd.bb |
swarmforge/scripts/handoffd.bb |
Daemon watching outbox/, delivering to inbox/new/, archiving to sent/ or failed/ |
ready_for_next.sh |
swarmforge/scripts/ready_for_next.sh |
Entry point for claiming next task; dispatches to task/batch variants |
ready_for_next_task.sh |
swarmforge/scripts/ready_for_next_task.sh |
Selects from inbox/new/, atomically moves to inbox/in_process/ |
done_with_current.sh |
swarmforge/scripts/done_with_current.sh |
Finalizes active work, moves to inbox/completed/ |
These scripts embed the directory structure as constants—no runtime configuration exists to alter paths.
Summary
- Root location:
.swarmforge/handoffs/per worktree, enforced by all scripts - Outbound flow:
outbox/tmp/→outbox/→sent/orfailed/(daemon-managed) - Inbound flow:
inbox/new/→inbox/in_process/→inbox/completed/(agent-managed) - Atomicity:
outbox/tmp/and atomic moves prevent partial file processing - Audit trail: Headers added at each stage (
enqueued_at,completed_at) enable full traceability
Frequently Asked Questions
Where does SwarmForge store handoff files between agents?
Handoff files reside in .swarmforge/handoffs/ within each agent's worktree. This hidden directory contains subdirectories for outbound drafts (outbox/), delivery archives (sent/, failed/), and inbound task queues (inbox/). The structure is fixed across all agent types and enforced by the handoff daemon and helper scripts.
What prevents the daemon from processing incomplete handoff files?
The outbox/tmp/ subdirectory serves as a private staging area. Scripts write handoff content here first and only move the completed file to outbox/ once fully formed. The daemon watches only outbox/, never outbox/tmp/, ensuring atomic handoff creation without partial file hazards.
How does an agent claim the next available task?
Agents invoke ready_for_next.sh, which dispatches to ready_for_next_task.sh or ready_for_next_batch.sh. These scripts scan inbox/new/, select by priority-then-FIFO ordering, and perform an atomic move to inbox/in_process/. This prevents race conditions when multiple agent instances attempt to claim the same work item.
What happens to handoffs that fail delivery?
Failed handoffs move to failed/ with diagnostic extensions (.err files). Common causes include validation errors, missing recipients, or system resource issues. Unlike sent/, the failed/ directory preserves error context to enable debugging and potential reprocessing without original data loss.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →