How the Swarm-Forge `ready_for_next.sh` Script Dispatches Between Task and Batch Modes
The ready_for_next.sh script dispatches between task and batch modes by delegating to a Babashka script that reads the SWARMFORGE_ROLE environment variable, looks up its receive mode in .swarmforge/roles.tsv, and executes either ready_for_next_task.sh or ready_for_next_batch.sh accordingly.
Swarm-Forge, an open-source multi-agent workflow framework created by Robert C. Martin ("Uncle Bob"), uses a role-based configuration system to determine how agents consume work. The ready_for_next.sh script serves as the primary entry point for agents requesting their next unit of work, with behavior dynamically determined by role configuration rather than hard-coded logic.
The Shell Wrapper: ready_for_next.sh
The ready_for_next.sh script is intentionally minimal. It acts as a thin launcher that hands off execution to the Babashka runtime.
This design keeps the dispatch logic in a more expressive language (Clojure/Babashka) while maintaining a simple shell interface for users and agent scripts.
The Dispatch Logic in ready_for_next.bb
The actual mode detection and dispatching occurs in swarmforge/scripts/ready_for_next.bb. This script performs three sequential operations:
Step 1: Locate the Project Root
The script walks up the directory tree to find the Git repository root, then validates that a .swarmforge/roles.tsv file exists. This establishes the configuration context for the entire dispatch operation.
Step 2: Read the Role's Receive Mode
The receive-mode function (lines 44-56 in ready_for_next.bb) implements the core lookup logic:
- Extracts the
SWARMFORGE_ROLEenvironment variable - Parses
.swarmforge/roles.tsvto find the matching role entry - Returns the receive mode column value: either task or batch
According to the Swarm-Forge source code, this function handles TSV parsing and returns the mode as a string keyword used in the subsequent dispatch decision.
Step 3: Dispatch to the Appropriate Helper
The run-helper! function (lines 60-64 in ready_for_next.bb) branches based on the receive mode:
- task mode → executes
ready_for_next_task.sh - batch mode → executes
ready_for_next_batch.sh
This branching is the sole dispatch point; no other logic in the script path makes mode-dependent decisions.
Visual Flow of the Dispatch Process
ready_for_next.sh
└─ exec bb ready_for_next.bb
├─ locate project root → verify .swarmforge/roles.tsv
├─ read SWARMFORGE_ROLE environment variable
├─ lookup receive mode (task|batch) in roles.tsv
└─ invoke run-helper!:
• ready_for_next_task.sh (if mode == "task")
• ready_for_next_batch.sh (if mode == "batch")
The two helper paths diverge significantly after this point:
| Mode | Helper Script | Behavior |
|---|---|---|
| task | ready_for_next_task.sh |
Returns the next single handoff file immediately |
| batch | ready_for_next_batch.sh |
Groups handoffs into a batch directory, returns batch metadata |
Practical Usage Examples
Configuring and Running a Task-Mode Role
# Define a role that processes individual tasks
export SWARMFORGE_ROLE=worker
# Verify role configuration in .swarmforge/roles.tsv:
# worker some-model task /path/to/prompt
# Execute the dispatcher
./swarmforge/scripts/ready_for_next.sh
# → ready_for_next_task.sh launches ready_for_next_task.bb
# → prints path to next available handoff file
Configuring and Running a Batch-Mode Role
# Define a role that collects batches of work
export SWARMFORGE_ROLE=collector
# Verify role configuration in .swarmforge/roles.tsv:
# collector some-model batch /path/to/prompt
# Execute the dispatcher
./swarmforge/scripts/ready_for_next.sh
# → ready_for_next_batch.sh launches ready_for_next_batch.bb
# → creates batch directory, moves matching handoffs, prints batch info
The batch implementation in ready_for_next_batch.bb (lines 12-47) handles directory creation, file selection, and metadata generation, making it substantially more complex than the task path.
Key Implementation Details
- No hard-coded roles: The
ready_for_next.bbscript contains no preset knowledge of which roles use which mode; all decisions flow fromroles.tsv - Environment-driven: The
SWARMFORGE_ROLEvariable is the only runtime input affecting dispatch behavior - Consistent interface: Both helpers present the same stdout contract to callers, despite vastly different internal implementations
Summary
ready_for_next.shis a shell wrapper that launchesready_for_next.bbvia Babashka- Dispatch between task and batch modes is determined by the
receive-modefunction reading.swarmforge/roles.tsv - The
run-helper!function executes eitherready_for_next_task.shorready_for_next_batch.shbased on the configured mode - Task mode returns single handoffs; batch mode aggregates multiple handoffs with metadata
- All behavior is configuration-driven through the
SWARMFORGE_ROLEenvironment variable androles.tsv
Frequently Asked Questions
What happens if SWARMFORGE_ROLE is not set?
The receive-mode function will fail to find a matching entry in roles.tsv, causing the dispatch to error before any helper script executes. The script expects this environment variable to be explicitly defined.
Can a role switch between task and batch modes dynamically?
No. The receive mode is static configuration stored in .swarmforge/roles.tsv. Changing a role's mode requires editing this file and restarting any running agents. The ready_for_next.bb script reads this configuration fresh on every invocation.
Where is the actual task-selection logic implemented?
The task-specific selection logic resides in ready_for_next_task.bb (called via ready_for_next_task.sh), not in the dispatcher. The dispatcher's only responsibility is choosing which helper to execute based on the role's configured receive mode.
Is there performance overhead to this two-layer dispatch?
Minimal. The shell wrapper adds negligible overhead, and the Babashka startup is the dominant cost. The configuration lookup in roles.tsv is a simple file parse; no network or database operations are involved.
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 →