# .swarmforge/handoffs/ Directory Structure Explained: A Complete Guide

> Explore the .swarmforge/handoffs/ directory structure. Understand the dual-queue filesystem, outbox, inbox, and lifecycle management for agent messages and task processing in Swarm Forge.

- Repository: [Robert C. Martin/swarm-forge](https://github.com/unclebob/swarm-forge)
- Tags: how-to-guide
- Published: 2026-08-08

---

**The `.swarmforge/handoffs/` directory implements a dual-queue filesystem layout with an `outbox/` for outbound agent messages and an `inbox/` for local task processing, using subdirectories to enforce a strict, auditable lifecycle for every handoff file.**

The `.swarmforge/handoffs/` directory structure serves as the durable runtime store for the Swarm-Forge agent communication protocol. Located within each worktree, this hierarchy provides a file-based message queue that enables reliable exchanges between AI agents without requiring manual git or tmux manipulation, as defined in the [`swarmforge/handoff-protocol.md`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/handoff-protocol.md) specification.

## Overview of the Directory Layout

The canonical structure follows a strict hierarchy designed to separate message delivery concerns from task execution state:

```

.swarmforge/
└─ handoffs/
   ├─ outbox/
   │  ├─ tmp/
   │  └─ (final .handoff files)
   ├─ sent/
   ├─ failed/
   └─ inbox/
      ├─ new/
      ├─ in_process/
      └─ completed/

```

Each subdirectory represents a specific state in the handoff lifecycle, enabling the `handoffd.bb` daemon to manage transitions atomically.

## The Outbox Lifecycle

The `outbox/` directory handles all outbound communication from an agent to recipient worktrees.

### Temporary Staging (outbox/tmp/)

Newly created handoffs first land in `outbox/tmp/`. This temporary staging area allows agents to atomically write handoff files before promoting them to the outbox root for delivery, preventing partial writes from triggering premature processing.

### Delivery Tracking (sent/ and failed/)

Once the daemon processes an outbox file, the outcome determines its final location:

- **sent/**: Contains copies of successfully delivered handoffs, providing a local archive of outbound correspondence.
- **failed/**: Stores undeliverable handoffs along with diagnostic metadata for debugging routing or validation errors.

The `swarmforge/scripts/handoffd.bb` script manages these transitions, watching the outbox root for `.handoff` files ready for distribution to recipient inboxes.

## The Inbox Task Queue

The `inbox/` directory functions as a local task queue for the receiving worktree, implementing a three-state processing pipeline.

### Pending Tasks (inbox/new/)

Inbound handoffs awaiting processing reside in `inbox/new/`. The daemon populates this directory when delivering messages from other agents' outboxes, creating a FIFO queue of available work.

### Active Work (inbox/in_process/)

When an agent begins working on a task, the `swarmforge/scripts/ready_for_next_task.bb` script moves the handoff from `new/` to `inbox/in_process/`. This state lock prevents duplicate processing across concurrent operations, ensuring single-assignment semantics.

### Archive (inbox/completed/)

Upon task completion, `swarmforge/scripts/done_with_current_task.bb` relocates the handoff to `inbox/completed/`, creating a permanent audit trail of finished work that remains accessible for historical reference.

## Initialization and Management

The directory structure is created automatically by startup scripts, eliminating manual setup. The `swarmforge/scripts/swarmforge.bb` script initializes the full tree when setting up a new worktree, while `swarmforge/scripts/handoffd.bb` manages the runtime flow between directories according to the protocol defined in [`swarmforge/handoff-protocol.md`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/handoff-protocol.md).

## Programmatic Handoff Operations

The test suite in `test/swarmforge/handoff_test.clj` demonstrates how agents interact with this structure programmatically using Clojure's filesystem API.

Creating a new handoff in the outbox temporary staging area:

```clojure
(let [root (fs/path "/tmp/example-worktree")
      outbox (fs/path root ".swarmforge" "handoffs" "outbox")
      new-file (fs/path outbox "new" "item.handoff")]
  (fs/create-dirs outbox)
  (spit new-file "id: 20260615T140531Z_000042_from_coder\n..."))

```

Moving a handoff into active processing mirrors the behavior of [`ready_for_next_task.sh`](https://github.com/unclebob/swarm-forge/blob/main/ready_for_next_task.sh):

```clojure
(let [inbox (fs/path root ".swarmforge" "handoffs" "inbox")
      new (fs/path inbox "new" "00_20260615T140531Z_000042_from_architect_to_coder.handoff")
      proc (fs/path inbox "in_process" "00_20260615T140531Z_000042_from_architect_to_coder.handoff")]
  (fs/move new proc))

```

These operations provide direct filesystem access for testing and custom tooling while maintaining the integrity of the `.swarmforge/handoffs/` directory structure.

## Summary

- The `.swarmforge/handoffs/` directory structure implements a durable, file-based message queue for agent communication in Swarm-Forge.
- **outbox/** manages outbound messages through `tmp/`, `sent/`, and `failed/` subdirectories to handle staging, confirmation, and error states.
- **inbox/** processes incoming tasks via `new/`, `in_process/`, and `completed/` directories that enforce a strict workflow pipeline.
- Lifecycle transitions are handled by `handoffd.bb`, `ready_for_next_task.bb`, and `done_with_current_task.bb` according to the handoff protocol.
- The layout is formally specified in [`swarmforge/handoff-protocol.md`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/handoff-protocol.md) and validated by the test suite in `test/swarmforge/handoff_test.clj`.

## Frequently Asked Questions

### What happens if a handoff fails to deliver?

Failed deliveries are moved to `outbox/failed/` with diagnostic metadata attached, allowing administrators to inspect error conditions without losing the original message payload. The daemon logs the failure reason alongside the handoff file for debugging.

### Can multiple agents process inbox items simultaneously?

No. The `inbox/in_process/` directory acts as a state lock. When `ready_for_next_task.bb` moves a file from `new/` to `in_process/`, it prevents other agents from picking up the same task. This filesystem-based locking ensures single-assignment semantics without requiring external coordination services.

### How is the directory structure created initially?

The `swarmforge/scripts/swarmforge.bb` initialization script automatically creates the entire `.swarmforge/handoffs/` hierarchy when setting up a new worktree. This ensures all required subdirectories exist before the daemon starts watching for file changes.

### Where is the directory layout formally documented?

The complete specification resides in [`swarmforge/handoff-protocol.md`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/handoff-protocol.md) in the "Directory Layout" section. This document serves as the authoritative reference for the handoff protocol implementation and is referenced by the test suite in `test/swarmforge/handoff_test.clj`.