SwarmForge Handoff File Format: Complete Guide to Headers, Structure, and Naming
A SwarmForge handoff file is a plain-text file with a key-value header block, a blank line separator, and an opaque body, stored in .swarmforge/handoffs/ with a lexicographically sortable filename encoding priority, timestamp, and routing metadata.
SwarmForge implements durable inter-agent communication through a file-based handoff protocol. Each handoff is a self-contained document that agents create, queue, and process according to strict conventions defined in [swarmforge/handoff-protocol.md](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/handoff-protocol.md). Understanding the SwarmForge handoff file format is essential for building compliant agents and debugging message flows.
Header Block Structure
The header block contains required metadata as key: value pairs, one per line. According to the protocol specification 88-92, the following headers are mandatory:
id– unique identifier for this handofffrom– role creating the handoffto– primary recipient rolerecipient– redundant copy for routing (matchestoin simple cases)priority– numeric priority for queue orderingtype– message type (git_handoffornote)role– role context of the sendertask– associated task identifiercommit– Git commit hash (forgit_handofftype)created_at– ISO 8601 timestampenqueued_at– timestamp when queued for delivery
Reserved headers including completed_at, dequeued_at, and dequeued_at must never be written by agents—these are managed exclusively by the handoff daemon or helper scripts 57-68.
Header Parsing Priority
Scripts parse authoritative metadata from headers, not from the filename 84-86. This design ensures that renaming or filesystem operations cannot corrupt message routing logic.
Body Section
After a single blank line, the body contains free-form text generated by the handoff daemon 90-92. The body is opaque to the daemon after creation—agents may embed:
- Short instructions
- Git commands
- Multi-line notes
- Structured data (YAML, JSON, etc.)
The daemon treats everything after the first blank line as payload without interpretation.
Filename Convention
The SwarmForge handoff filename encodes routing metadata for priority-ordered directory listing:
<priority>_<timestamp>_<sequence>_from_<sender>_to_<recipient-list>.handoff
| Component | Description |
|---|---|
priority |
Two-digit number 00-99 (lower = higher priority) |
timestamp |
UTC datetime in YYYYMMDDTHHMMSSZ format |
sequence |
Per-worktie counter for sub-second tie-breaking |
sender |
Role creating the handoff |
recipient-list |
Comma-separated targets (for audit trail) |
Example filename from the specification 63-73:
00_20260615T140531Z_000042_from_architect_to_coder_cleaner_QA.handoff
This lexicographic sort order ensures that ls and glob patterns naturally yield priority-queued processing order.
Complete Handoff File Example
id: 20260615T140531Z_000042_from_coder
from: coder
to: cleaner
recipient: cleaner
priority: 50
type: git_handoff
role: coder
task: task-1-cave-setup
commit: a1b2c3d9
created_at: 2026-06-15T14:05:31Z
enqueued_at: 2026-06-15T14:05:32Z
Re-read your role and constitution.
merge_and_process coder a1b2c3d9
The blank line after enqueued_at terminates the header; everything following is the opaque body 94-119.
Directory Layout
Handoff files traverse a defined lifecycle through subdirectories of .swarmforge/handoffs/ 26-38:
outbox/– pending outbound handoffs waiting for daemon pickupinbox/new/– freshly delivered handoffs awaiting processinginbox/in_process/– handoffs currently being handled by an agentinbox/completed/– successfully processed handoffssent/– audit copies of handoffs originated by this agentfailed/– handoffs that encountered delivery or processing errors
Working with Handoff Files
Creating and Queuing a Handoff
Write a draft containing only user-supplied headers, then use swarm_handoff.sh to validate and generate the complete file:
# Create a draft handoff (header section only)
cat > /tmp/draft.handoff <<'EOF'
type: git_handoff
to: cleaner
priority: 50
task: task-1-cave-setup
commit: a1b2c3d9e8
EOF
# Validate and queue – script generates id, timestamps, and filename
swarm_handoff.sh /tmp/draft.handoff
# Result: .swarmforge/handoffs/outbox/50_20231102T123045Z_000001_from_coder_to_cleaner.handoff
Inspecting Received Handoffs
Extract just the header portion for quick inspection:
head -n 12 .swarmforge/handoffs/inbox/new/50_20231102T123045Z_000001_from_coder_to_cleaner.handoff
Parsing Headers Programmatically
The test suite in test/swarmforge/handoff_test.clj demonstrates robust header parsing:
(require '[clojure.java.io :as io])
(defn parse-headers [path]
(with-open [r (io/reader path)]
(->> (line-seq r)
(take-while (complement clojure.string/blank?))
(map #(clojure.string/split % #":\s+" 2))
(into {}))))
(parse-headers ".swarmforge/handoffs/inbox/new/50_20231102T123045Z_000001_from_coder_to_cleaner.handoff")
;; => {"id" "20231102T123045Z_000001_from_coder", "from" "coder", ...}
Key Implementation Files
| File | Purpose |
|---|---|
[swarmforge/handoff-protocol.md](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/handoff-protocol.md) |
Canonical specification of format, naming, and lifecycle |
[swarmforge/scripts/swarm_handoff.sh](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/scripts/swarm_handoff.sh) |
Validates drafts and writes complete handoff files |
swarmforge/scripts/handoffd.bb |
Daemon for delivery and audit header management |
test/swarmforge/handoff_test.clj |
Conformance tests for parsing and handling |
Message Types
The SwarmForge handoff file format supports two primary message types 27-33:
git_handoff– Transfers a Git commit hash between roles, typically accompanied by processing instructions in the bodynote– Short free-form messages without commit references
Both types share identical header structure and filename conventions.
Summary
- SwarmForge handoff files are plain-text documents with
key: valueheaders, a blank separator, and an opaque body - Filenames encode priority and routing using a sortable format:
priority_timestamp_sequence_from_sender_to_recipients.handoff - Headers are authoritative—scripts ignore filename metadata for critical routing decisions
- The handoff daemon manages reserved headers like
completed_at; agents must never write these - Two message types (
git_handoff,note) support commit handoffs and unstructured communication - Files lifecycle through
.swarmforge/handoffs/subdirectories:outbox→inbox/new→inbox/in_process→inbox/completed
Frequently Asked Questions
What happens if an agent writes a reserved header?
Reserved headers such as completed_at, dequeued_at, and enqueued_at are managed exclusively by the handoff daemon and helper scripts. According to the protocol specification 57-68, agents that write these headers violate the contract and may cause routing or audit failures. The swarm_handoff.sh script prevents this by only allowing agent-supplied headers in draft files.
How does SwarmForge ensure handoffs process in priority order?
The filename convention guarantees lexicographic sort order matches priority order. Filenames begin with a two-digit priority (00-99), followed by timestamp and sequence. Lower numeric priority values indicate higher urgency. When agents or the daemon list directory contents, the natural sort order yields correct processing sequence without additional indexing.
Can the handoff body contain structured data?
Yes. The body is opaque to the daemon after creation 90-92. Agents may embed JSON, YAML, shell commands, or plain text instructions. The daemon copies the body unchanged during delivery. Recipients are responsible for parsing body content according to their agreed protocols—typically git_handoff bodies contain Git commands and note bodies contain human-readable instructions.
What creates the sequence number in filenames?
The per-worktree counter in swarm_handoff.sh generates sequence numbers 63-73. This six-digit zero-padded number ensures unique filenames when multiple handoffs share the same timestamp second. The counter persists in the worktree state and increments atomically to prevent collisions during high-throughput scenarios.
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 →