How Propagation Tokens Work in SwarmForge: `forward-only`, `back-one`, and `back-all` Explained
Propagation tokens in SwarmForge control how handoffs are distributed after a role finishes processing, with three modes: forward-only (default, next role only), back-one (next role plus immediate predecessor), and back-all (next role plus all preceding roles).
In SwarmForge, a pack is a sequence of roles (or "windows") that process work in stages. When one role hands off a task to the next, the propagation token determines exactly which roles receive copies of that handoff. This mechanism—implemented in the unclebob/swarm-forge open-source project—enables flexible workflow patterns beyond simple linear pipelines.
What Propagation Tokens Control
Each role in a pack can declare a propagation token that governs handoff distribution. The token answers one question: after this role finishes, who else should see the result?
| Token | Behavior | Typical Use Case |
|---|---|---|
forward-only |
Handoff sent only to the next role; earlier roles receive nothing | Standard linear flow (e.g., coder → cleaner → architect) |
back-one |
Handoff sent to next role and immediate predecessor | Verification loops or quick back-and-forth between adjacent roles |
back-all |
Handoff sent to next role and broadcast to all earlier roles | Final QA or reporting steps that must notify everyone upstream |
If omitted, forward-only is the default.
Where Propagation Tokens Are Parsed
The parser resides in swarmforge/scripts/swarmforge.bb, where the receive-fields function extracts the token from window configuration lines.
First, the valid tokens are defined as a Clojure set:
(def propagation-modes #{"forward-only" "back-one" "back-all"})
Then receive-fields parses the trailing arguments after the required window parameters:
(defn receive-fields [trailing]
(let [[receive-mode after-receive]
(if (receive-modes (first trailing))
[(first trailing) (rest trailing)]
["task" trailing])
[propagation extra]
(if (propagation-modes (first after-receive))
[(first after-receive) (rest after-receive)]
["forward-only" after-receive])]
[receive-mode propagation extra]))
The parser checks if the next token matches propagation-modes. If not, it substitutes "forward-only" as the default. This ensures every role has a valid propagation setting at runtime.
How Tokens Are Stored at Runtime
After parsing, the propagation value is persisted to .swarmforge/roles.tsv—the authoritative runtime configuration for launched packs.
The function role-propagation in swarmforge/scripts/handoff_lib.bb retrieves this value:
(defn role-propagation [role-name]
(let [mode (nth (role-row role-name) 7 "")]
(if (str/blank? mode) "forward-only" mode)))
This makes .swarmforge/roles.tsv the single source of truth that handoff scripts consult when determining recipient lists.
How Tokens Influence Handoff Creation
When a role emits a handoff, swarmforge/scripts/swarm_handoff.bb uses the sender's propagation mode to compute destinations:
(case (handoff-lib/role-propagation sender)
"forward-only" … ; only the next role receives the handoff
"back-one" … ; next role + immediate predecessor
"back-all" …) ; next role + all earlier roles
The resulting recipient list is encoded in the handoff's to: header. The handoff daemon then places copies in each target role's inbox directory, guaranteeing that every designated role receives an identical copy of the handoff file.
End-to-End Example: Coder → Cleaner → Architect
Consider a three-role pack with different propagation settings per role:
| Configuration Line | Parsed Propagation |
|---|---|
window coder claude master forward-only |
"forward-only" — only cleaner receives |
window cleaner claude master back-one |
"back-one" — architect and coder receive |
window architect claude master back-all |
"back-all" — architect receives, plus broadcast to cleaner and coder |
When cleaner (with back-one) finishes:
;; Parsed configuration for cleaner
{:role "cleaner"
:agent "claude"
:receive-mode "task"
:propagation "back-one"
:extra-args nil}
swarm_handoff.bb creates two handoff copies:
- One addressed
to: architect— the normal forward direction - One addressed
to: coder— the backward copy to the immediate predecessor
The daemon delivers both to their respective inboxes. Each role then processes its copy according to its own receive mode (task or batch).
Key Implementation Files
| File | Responsibility |
|---|---|
swarmforge/scripts/swarmforge.bb |
Defines propagation-modes set and parses tokens via receive-fields |
swarmforge/scripts/handoff_lib.bb |
Reads stored tokens via role-propagation from .swarmforge/roles.tsv |
swarmforge/scripts/swarm_handoff.bb |
Switches on token value to build recipient lists at handoff time |
swarmforge/handoff-protocol.md |
Documents token semantics and default behavior |
Summary
- Propagation tokens are per-role settings that control handoff distribution in SwarmForge packs
forward-only(default) creates linear pipelines;back-oneenables adjacent-role loops;back-allbroadcasts to all upstream roles- Tokens are parsed in
swarmforge.bb, stored in.swarmforge/roles.tsv, and applied byswarm_handoff.bbusing acaseexpression - The mechanism supports complex workflows—verification loops, multi-party notifications, and hybrid patterns—without requiring pack reconfiguration
Frequently Asked Questions
What happens if I don't specify a propagation token for a role?
The parser automatically assigns "forward-only" as the default. This is hardcoded in receive-fields within swarmforge.bb and confirmed by the fallback logic in role-propagation within handoff_lib.bb.
Can I use back-one or back-all on the first role in a pack?
Technically yes, but practically limited. back-one on the first role has no predecessor, so it behaves like forward-only. back-all similarly has no earlier roles to broadcast to. Both tokens still send to the next role normally.
How does back-all differ from just listing multiple roles manually?
back-all dynamically targets all roles defined before the current one in the pack order, regardless of pack size or composition. This makes packs reusable: you can insert or remove roles without reconfiguring propagation settings. Manual recipient lists would require editing every role's configuration when the pack structure changes.
Is the propagation token related to the receive mode (task vs batch)?
No—these are orthogonal settings. Receive mode controls how a role consumes incoming handoffs (individual tasks or batched queues). Propagation token controls where outgoing handoffs are sent. A role can combine any receive mode with any propagation token (e.g., batch receiving with back-all distribution).
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 →