How `merge_and_process.sh` and `swarm_handoff.sh` Interact During a Swarm Handoff
merge_and_process.sh sources swarm_handoff.sh to consume handoff artifacts, merges incoming swarm configuration, and signals completion via a shared .handoff status file that the handoff daemon monitors.
The unclebob/swarm-forge repository implements a deterministic handoff protocol through two core shell scripts that coordinate the transfer of swarm state between nodes. Understanding how merge_and_process.sh and swarm_handoff.sh interact during handoff is essential for debugging handoff failures and extending the protocol. This article examines their four-step coordination pipeline, shared environment contract, and file-based signaling mechanism.
The Four-Step Handoff Pipeline
The interaction between these scripts follows a strict producer-consumer pattern with feedback signaling.
Step 1: swarm_handoff.sh Initiates the Handoff
swarmforge/scripts/swarm_handoff.sh begins the handoff by packaging the current swarm state—tasks, logs, and environment—into a temporary payload directory. It spawns the handoffd daemon and writes a .handoff metadata file containing:
- The daemon's PID
- The temporary directory path for the payload
- A status flag (
IN_PROGRESS)
At this stage, swarm_handoff.sh operates independently. No direct call to merge_and_process.sh occurs; the script simply creates the artifacts that the merge process will later consume.
Step 2: merge_and_process.sh Sources and Validates
When execution reaches swarmforge/scripts/merge_and_process.sh, it sources swarm_handoff.sh directly:
source "$SWARM_FORGE_PATH/scripts/swarm_handoff.sh"
This sourcing provides access to helper functions defined in swarm_handoff.sh, including:
handoff_cleanup()— removes temporary directorieshandoff_success?()— validates handoff completion status
merge_and_process.sh reads the .handoff file, verifies the IN_PROGRESS status, and confirms the payload was correctly produced before proceeding.
Step 3: Merge, Process, and Signal Completion
After validation, merge_and_process.sh performs three operations:
- Merges the incoming swarm configuration (new lieutenant definitions, updated task queues) into the local repository
- Normalizes the merged data—re-indexing tasks, updating the constitution, rebuilding
forge.bbartifacts - Writes
DONE=1into the.handofffile to signal completion
This step relies on environment variables exported by swarm_handoff.sh: SWARM_FORGE_PATH and HANDOFF_DIR. Both scripts share identical views of the swarm state through these variables.
Step 4: The Handoff Daemon Completes Cleanup
The handoffd daemon—spawned in Step 1—runs a watchdog loop monitoring the .handoff file. When it detects DONE=1 written by merge_and_process.sh, it:
- Removes the temporary directory
- Signals the original swarm that handoff is complete
- Exits cleanly
This tight coupling ensures the handoff only finalizes after the merge has been fully applied.
Environment Contract and Shared State
The scripts coordinate through a minimal, well-defined contract:
| Element | Purpose | Set By |
|---|---|---|
SWARM_FORGE_PATH |
Base installation directory | swarm_handoff.sh |
HANDOFF_DIR |
Temporary payload directory | swarm_handoff.sh |
.handoff file |
Status file with PID, paths, flags | swarm_handoff.sh (write), merge_and_process.sh (update) |
This design avoids complex IPC—both scripts read from and write to the same filesystem location, making the protocol resilient to network interruptions and easy to inspect manually.
Practical Code Examples
Initiate a handoff from a swarm node:
./swarmforge/scripts/swarm_handoff.sh start
This creates .handoff with STATUS=IN_PROGRESS and launches handoffd. After the daemon finishes payload preparation, run the merge:
./swarmforge/scripts/merge_and_process.sh
The second command sources swarm_handoff.sh, performs the merge, and writes DONE=1. The daemon detects this automatically and cleans up—no additional command required.
Key Source Files
| File | Role in Handoff Interaction |
|---|---|
swarmforge/scripts/swarm_handoff.sh |
Producer: sets up payload, spawns daemon, exports environment |
swarmforge/scripts/merge_and_process.sh |
Consumer: sources helper functions, merges state, signals completion |
swarmforge/scripts/handoffd |
Runtime-generated daemon; watches .handoff for DONE flag |
swarmforge/scripts/ready_for_next.sh |
Post-handoff: resumes normal swarm operation |
The protocol specification in swarmforge/handoff-protocol.md documents this contract formally for implementers extending the system.
Summary
swarm_handoff.shprepares handoff artifacts and spawns a monitoring daemon without directly invoking the merge processmerge_and_process.shsourcesswarm_handoff.shto reuse validation functions and environment variables, then consumes the prepared payload- The
.handofffile serves as the contract:swarm_handoff.shwrites initial state,merge_and_process.shupdates withDONE=1, andhandoffdobserves the change - Environment variables (
SWARM_FORGE_PATH,HANDOFF_DIR) ensure both scripts operate on identical paths without hardcoded dependencies
Frequently Asked Questions
Does swarm_handoff.sh directly execute merge_and_process.sh?
No. swarm_handoff.sh creates artifacts and exits after spawning handoffd. merge_and_process.sh runs separately—either manually or via automation—and sources swarm_handoff.sh only for helper functions, not to trigger execution. This decoupling allows flexible deployment topologies.
What happens if merge_and_process.sh fails before writing DONE=1?
The handoffd daemon continues monitoring indefinitely. The swarm remains in handoff state until the daemon is killed manually or the .handoff file is repaired. This blocking behavior prevents partial merges from corrupting swarm state.
Why does merge_and_process.sh source rather than execute swarm_handoff.sh?
Sourcing preserves the environment variable exports and function definitions in the current shell context. Executing as a subprocess would isolate these definitions, forcing duplication of path logic and increasing maintenance burden across the repository.
Can the handoff protocol operate across network-mounted filesystems?
Yes. The file-based contract relies only on atomic write visibility, not local filesystem specifics. As long as $HANDOFF_DIR and .handoff reside on a filesystem visible to both nodes (NFS, distributed storage, etc.), the signaling mechanism functions identically.
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 →