# SwarmForge Handoff Protocol: Full Specification Location and Implementation Guide

> Find the complete SwarmForge handoff protocol specification in a single markdown file. Learn directory layouts, message types, and agent coordination for the unclebob/swarm-forge repository.

- Repository: [Robert C. Martin/swarm-forge](https://github.com/unclebob/swarm-forge)
- Tags: api-reference
- Published: 2026-09-02

---

**The complete SwarmForge handoff protocol specification is located in [`swarmforge/handoff-protocol.md`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/handoff-protocol.md)**, a single markdown file that defines directory layouts, filename formats, message types, and daemon responsibilities for agent-to-agent task coordination.

The SwarmForge repository by Uncle Bob (Martin Fowler) implements a sophisticated multi-agent orchestration system where specialized AI agents pass work to each other through a structured handoff mechanism. This article shows you exactly where to find the authoritative protocol definition and how its components work together.

## Where the Full Specification Lives

The canonical source for the **SwarmForge handoff protocol** is:

- **File**: [[`swarmforge/handoff-protocol.md`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/handoff-protocol.md)](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/handoff-protocol.md)

This file contains the entire protocol definition in one location—no scattering across multiple documents. According to the unclebob/swarm-forge source code, it specifies:

1. **Directory layout** for inbox/outbox queue structures
2. **Filename format** and priority-based ordering rules
3. **Header block specification** for all handoff files
4. **Supported message types**: `git_handoff` and `note`
5. **Validation logic** performed by [`swarm_handoff.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarm_handoff.sh)
6. **Daemon responsibilities** for the `handoffd` process
7. **Helper scripts** agents use: [`ready_for_next.sh`](https://github.com/unclebob/swarm-forge/blob/main/ready_for_next.sh), [`done_with_current.sh`](https://github.com/unclebob/swarm-forge/blob/main/done_with_current.sh), and variants
8. **Audit-trail headers** and complete lifecycle handling

## Protocol Architecture Overview

### Queue Directory Structure

The handoff protocol operates on a filesystem-based message queue. Each agent role maintains:

- `.swarmforge/handoffs/inbox/new/` — incoming handoffs awaiting pickup
- `.swarmforge/handoffs/inbox/in_process/` — handoffs currently being worked
- `.swarmforge/handoffs/inbox/completed/` — finished handoffs preserved for audit
- `.swarmforge/handoffs/outbox/` — outgoing handoffs awaiting daemon delivery

### Filename Convention

Handoff files follow strict naming for priority ordering:

```

<priority>-<timestamp>-<uuid>.handoff

```

Lower priority numbers indicate higher urgency. The daemon processes outbox files in sorted order.

## Creating and Validating Handoffs

### Outbound Handoff Creation

Agents create draft handoffs, then submit them through the validation gate. In [`swarmforge/scripts/swarm_handoff.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/scripts/swarm_handoff.sh), the script enforces header completeness and proper formatting:

```bash

# Write a draft handoff in ./tmp/

cat > ./tmp/handoff.txt <<'EOF'
type: git_handoff
to: cleaner
priority: 50
task: task-1-cave-setup
commit: a1b2c3d9e8
EOF

# Validate and queue the handoff

swarm_handoff.sh ./tmp/handoff.txt

```

The [`swarm_handoff.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarm_handoff.sh) script performs three critical functions:

- **Validates** required headers (`type`, `to`, `priority`, `task`)
- **Auto-generates** metadata headers (`id`, `created_at`, `from`)
- **Atomically moves** the finalized file to `.swarmforge/handoffs/outbox/`

### Header Block Specification

Per [`handoff-protocol.md`](https://github.com/unclebob/swarm-forge/blob/main/handoff-protocol.md), all handoff files must contain a YAML-style header block:

```yaml
---
id: <uuid>
type: <git_handoff|note>
from: <role_name>
to: <role_name>
priority: <integer>
task: <task_identifier>
created_at: <iso_timestamp>
---
<body content>

```

The `---` delimiters are mandatory. Headers are parsed by the daemon and helper scripts using consistent regex patterns.

## Receiving and Processing Handoffs

### Agent Entry Point: ready_for_next.sh

Agents fetch work through [`swarmforge/scripts/ready_for_next.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/scripts/ready_for_next.sh), which dispatches based on the role's receive mode:

```bash

# Inside the worktree of the role ready for work

ready_for_next.sh

```

This script inspects the role configuration and delegates to:

- **[`ready_for_next_task.sh`](https://github.com/unclebob/swarm-forge/blob/main/ready_for_next_task.sh)** — selects single highest-priority handoff from `inbox/new/`
- **[`ready_for_next_batch.sh`](https://github.com/unclebob/swarm-forge/blob/main/ready_for_next_batch.sh)** — selects all handoffs sharing the highest priority value

Both scripts move selected handoffs to `inbox/in_process/` and print a structured summary to stdout for agent consumption.

### Task Completion: done_with_current.sh

After finishing work, agents finalize the handoff:

```bash

# After completing the described work

done_with_current.sh

```

The implementation in [`swarmforge/scripts/done_with_current.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/scripts/done_with_current.sh) handles:

1. Adding `completed_at` timestamp header
2. Moving handoff to `inbox/completed/`
3. Signaling daemon if follow-up handoffs were generated

Variant scripts [`done_with_current_task.sh`](https://github.com/unclebob/swarm-forge/blob/main/done_with_current_task.sh) and [`done_with_current_batch.sh`](https://github.com/unclebob/swarm-forge/blob/main/done_with_current_batch.sh) handle the specific cleanup semantics for single vs. batch modes.

## The Handoff Daemon

### Core Delivery Loop

The `handoffd` daemon—implemented in `swarmforge/scripts/handoffd.bb` as a Babashka script—runs continuously to route handoffs between agent inboxes. Its simplified core logic:

```clojure
(while true
  (doseq [outbox (discover-outbox-files)]
    (if (valid-handoff? outbox)
      (deliver-to-recipients outbox)
      (move-to-failed outbox))))

```

The daemon performs these operations per the SwarmForge handoff protocol specification:

- **Scans** all agent outbox directories
- **Validates** file format and recipient existence
- **Delivers** by hard-linking to recipient inbox/new/ (atomic operation)
- **Archives** processed outbox files
- **Quarantines** invalid files to a failed/ directory with error annotations

### Daemon Startup

`handoffd` is launched automatically by the swarm launcher script and receives its configuration through environment variables defining the swarm root directory and poll interval.

## Message Types Deep Dive

### git_handoff

The primary work-transition message. Fields include:

- `commit` — git SHA being handed off
- `branch` — optional target branch
- `context` — serialized conversation state

Used when one agent's code changes must be reviewed or extended by another role.

### note

Lightweight informational message without code attachment. Used for:

- Status updates
- Blocking notifications
- Coordination signals

Notes skip certain validation checks but follow identical header and lifecycle conventions.

## Validation Logic Reference

The [`swarm_handoff.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarm_handoff.sh) validation gate enforces rules defined in [`handoff-protocol.md`](https://github.com/unclebob/swarm-forge/blob/main/handoff-protocol.md):

| Check | Failure Action |
|-------|---------------|
| Header block present | Reject with parse error |
| Required fields populated | Reject with missing field list |
| `to` role exists in swarm | Reject with unknown recipient |
| `priority` is valid integer | Reject with type error |
| Body content non-empty (for notes) | Reject with empty content |

Validation failures emit structured error messages suitable for agent parsing.

## Summary

- **Primary location**: [`swarmforge/handoff-protocol.md`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/handoff-protocol.md) contains the complete, authoritative SwarmForge handoff protocol specification
- **Validation entry point**: [`swarmforge/scripts/swarm_handoff.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/scripts/swarm_handoff.sh) enforces protocol compliance for outbound handoffs
- **Delivery mechanism**: `swarmforge/scripts/handoffd.bb` implements the routing daemon
- **Agent helpers**: [`ready_for_next.sh`](https://github.com/unclebob/swarm-forge/blob/main/ready_for_next.sh) and [`done_with_current.sh`](https://github.com/unclebob/swarm-forge/blob/main/done_with_current.sh) families provide standardized receive/complete workflows
- **Message types**: `git_handoff` (code + context) and `note` (informational) share common header and lifecycle semantics
- **Queue design**: Filesystem-based with atomic moves, priority ordering, and complete audit trail preservation

## Frequently Asked Questions

### What format does a SwarmForge handoff file use?

SwarmForge handoff files use plain text with a YAML-style header block delimited by `---` markers. The header contains metadata fields; everything after the closing `---` is message body. This format was chosen for human readability and trivial parsing from both shell scripts and Babashka.

### How does priority ordering work in the handoff queue?

Priority is an integer where lower values indicate higher urgency. Files are named with zero-padded priority prefixes so lexical sorting yields correct processing order. The daemon and `ready_for_next*.sh` scripts both rely on this naming convention for correct selection.

### Can I inspect handoffs without processing them?

Yes. Handoffs remain readable text files in `inbox/new/` until [`ready_for_next.sh`](https://github.com/unclebob/swarm-forge/blob/main/ready_for_next.sh) moves them to `in_process/`. However, agents should use the helper scripts to maintain proper state management and audit trail integrity. Direct filesystem manipulation risks protocol violations.

### What happens if a handoff fails validation?

[`swarm_handoff.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarm_handoff.sh) rejects the submission with a detailed error message. For daemon-detected failures (rare), the handoff moves to `outbox/failed/` with an `error:` annotation header explaining the failure reason.