# Swarm-Forge Agent Wake-Up Notification Behavior When Already Working

> Discover what happens when a Swarm-Forge agent gets a wake-up notification while already working. Learn how the agent prioritizes tasks and completes its current job.

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

---

**When a Swarm-Forge agent receives a wake-up notification while already executing a task, the notification is ignored and the agent continues its current work until completion.**

The **Swarm-Forge** orchestration system uses a simple, lossy wake-up mechanism to nudge idle agents into checking for new work. Understanding how `handoffd` and individual agents coordinate—especially during busy periods—is critical for debugging task distribution delays or designing custom agent behaviors. This article explains the exact semantics of wake-up handling, backed by the official protocol definition and runtime scripts in the `unclebob/swarm-forge` repository.

## How Wake-Up Notifications Work in Swarm-Forge

The `handoffd` daemon monitors each agent's *outbox* directory. When a new handoff file appears, the daemon:

1. Delivers the file to the target agent's *inbox*
2. Sends a **generic tmux wake-up message** to that agent's session

According to the handoff protocol documented in [`swarmforge/handoff-protocol.md`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/handoff-protocol.md) (line 480), this wake-up serves a single purpose: prompting the agent to run [`ready_for_next.sh`](https://github.com/unclebob/swarm-forge/blob/main/ready_for_next.sh) and poll for new work.

## Agent State Determines Wake-Up Response

An agent's reaction to a wake-up depends entirely on its current execution state:

| Agent State | Wake-Up Response |
|-------------|------------------|
| **Idle** (no active task) | Executes [`ready_for_next.sh`](https://github.com/unclebob/swarm-forge/blob/main/ready_for_next.sh), checks inbox for `TASK:` or `BATCH:` entries, and begins work if found |
| **Busy** (task in progress) | **Ignores the wake-up silently**; continues current execution without interruption |

This behavior is intentional and documented across multiple authoritative sources in the repository. The constitution article in `swarmforge/constitution/articles/handoffs.prompt` (line 60) explicitly codifies the rule: *"If a tmux wake-up arrives while already working on a task, ignore it."*

## Why Wake-Ups Are Lossy by Design

The Swarm-Forge architecture treats wake-up messages as **advisory, not guaranteed**. Several design decisions reinforce this:

- **No re-queueing**: If `handoffd` sends a wake-up to a busy agent, the daemon does not track delivery failures or retry later
- **No state synchronization**: The daemon does not query agent state before sending; it broadcasts blindly
- **Polling fallback**: Agents always call [`done_with_current.sh`](https://github.com/unclebob/swarm-forge/blob/main/done_with_current.sh) after task completion, which invokes [`ready_for_next.sh`](https://github.com/unclebob/swarm-forge/blob/main/ready_for_next.sh) to discover any queued work missed during busy periods

This trade-off prioritizes simplicity and avoids complex distributed state management. As noted in [`README.md`](https://github.com/unclebob/swarm-forge/blob/main/README.md) (line 203), agents "can safely ignore" wake-ups when busy because the completion-time poll ensures no work is lost.

## Runtime Flow: From Wake-Up to Task Execution

The complete agent lifecycle follows this sequence:

1. **`handoffd` detects handoff** → delivers files + sends tmux wake-up
2. **Agent receives wake-up** → checks `$CURRENT_TASK` or equivalent state marker
3. **If idle**: [`ready_for_next.sh`](https://github.com/unclebob/swarm-forge/blob/main/ready_for_next.sh) parses inbox, outputs `TASK: <path>` or `BATCH: <path>`, launches helper
4. **If busy**: Wake-up discarded; agent proceeds with current task
5. **Task completes**: [`done_with_current.sh`](https://github.com/unclebob/swarm-forge/blob/main/done_with_current.sh) triggers another [`ready_for_next.sh`](https://github.com/unclebob/swarm-forge/blob/main/ready_for_next.sh) invocation to fetch next item
6. **No work found**: `NO_TASK` printed; agent returns to idle state awaiting next wake-up

## Practical Implementation Example

While the production logic resides in [`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), the following pseudocode illustrates the core state-checking pattern:

```bash
#!/bin/bash

# Simplified agent wake-up handler

# Full implementation: swarmforge/scripts/ready_for_next.sh

INBOX="${AGENT_DIR}/inbox"
WAKEUP_MARKER="${INBOX}/wakeup"
CURRENT_TASK="${AGENT_DIR}/.current_task"

if [ -f "$WAKEUP_MARKER" ]; then
    if [ -z "$CURRENT_TASK" ]; then
        # Agent is idle: process new work

        ./ready_for_next.sh
        # ready_for_next.sh handles TASK/BATCH detection and launch

    else
        # Agent is busy: discard wake-up, preserve focus

        rm -f "$WAKEUP_MARKER"
        # Work will be found via done_with_current.sh after completion

    fi
fi

```

The actual [`ready_for_next.sh`](https://github.com/unclebob/swarm-forge/blob/main/ready_for_next.sh) script performs additional validation: parsing inbox entries, verifying file existence, and emitting structured output for logging and monitoring.

## Key Source Files and Their Roles

| File | Purpose | Line Reference |
|------|---------|---------------|
| [`swarmforge/handoff-protocol.md`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/handoff-protocol.md) | Defines wake-up semantics and "ignore while busy" rule | Line 480 |
| `swarmforge/constitution/articles/handoffs.prompt` | Constitutional reinforcement of wake-up handling policy | Line 60 |
| [`README.md`](https://github.com/unclebob/swarm-forge/blob/main/README.md) | Runtime documentation for agents and handoff flow | Line 203 |
| [`swarmforge/scripts/ready_for_next.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/scripts/ready_for_next.sh) | Entry point for idle agent work discovery | Full implementation |
| [`swarmforge/scripts/done_with_current.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/scripts/done_with_current.sh) | Post-completion polling to find subsequent tasks | Full implementation |

## Summary

- **Busy agents ignore wake-ups** to prevent task interruption and duplicate dispatches
- **Wake-ups are lossy**—no retry mechanism exists in `handoffd`
- **Completion polling** via [`done_with_current.sh`](https://github.com/unclebob/swarm-forge/blob/main/done_with_current.sh) guarantees agents eventually discover all queued work
- **State check location**: Scripts test for active task markers before invoking [`ready_for_next.sh`](https://github.com/unclebob/swarm-forge/blob/main/ready_for_next.sh)
- **Design philosophy**: Simplicity over reliability; the protocol accepts missed wake-ups in exchange for stateless coordination

## Frequently Asked Questions

### What happens to a wake-up if the agent is busy for a long time?

The wake-up is permanently discarded. No queue or retry mechanism exists in `handoffd`. However, when the agent finishes its current task, [`done_with_current.sh`](https://github.com/unclebob/swarm-forge/blob/main/done_with_current.sh) invokes [`ready_for_next.sh`](https://github.com/unclebob/swarm-forge/blob/main/ready_for_next.sh) to check for any work that arrived during the busy period, ensuring nothing is lost.

### Can an agent process multiple wake-ups in sequence?

An idle agent processes one wake-up at a time through [`ready_for_next.sh`](https://github.com/unclebob/swarm-forge/blob/main/ready_for_next.sh). If multiple handoffs arrive while the agent is already executing [`ready_for_next.sh`](https://github.com/unclebob/swarm-forge/blob/main/ready_for_next.sh), the subsequent wake-ups will be handled after the current invocation completes—or ignored if the agent becomes busy with a task.

### How does `handoffd` know whether an agent is idle?

It doesn't. `handoffd` sends wake-ups blindly without querying agent state. The responsibility for ignoring inappropriate wake-ups falls entirely on the agent side, as implemented in the runtime scripts and specified in the handoff protocol.

### Is the wake-up behavior configurable per agent?

No. The "ignore while busy" rule is hardcoded in the protocol definition and constitution articles. All agents in a Swarm-Forge deployment follow the same semantics. Custom agent implementations must replicate this behavior to maintain compatibility with `handoffd`.