How Back‑One and Back‑All Propagation Tokens Work Without Moving Task Cards in Swarm Forge

The back-one and back-all propagation tokens queue merge‑only handoff copies to earlier roles, but because these copies are marked non‑forwarding, they never update the board card's to: list—so the UI leaves the task card in place until the terminal handoff completes.

Swarm Forge, an open‑source multi‑agent orchestration framework by Uncle Bob, uses propagation tokens in swarmforge.conf to control how handoffs flow through a pack of roles. This article explains the mechanics of back-one and back-all, tracing the implementation from configuration to the Clojure functions that make cards stay put.

Understanding Propagation Tokens in swarmforge.conf

A window line in swarmforge.conf declares how a role handles incoming and outgoing handoffs. The syntax includes an optional propagation token after the receive mode:

window <role> <agent> <worktree> [task|batch] [forward-only|back-one|back-all] …
  • forward-only: Default behavior. The handoff advances to the next role, and the board card moves forward.
  • back-one: Delivers to the next role, plus a merge‑only copy to the immediate predecessor.
  • back-all: Delivers to the next role, plus merge‑only copies to all earlier roles in the pack.

These merge‑only copies let prior roles incorporate changes without re‑triggering the workflow.

Why Task Cards Don't Move on Back Propagation

The key insight lies in how Swarm Forge distinguishes forwarding from merge‑only handoffs. According to the hand‑off protocol in the source repository:

Merge‑only copies are non‑forwarding: the receiving role merges the commit but does not issue a further handoff.

Because the handoff lacks a forward entry for the earlier roles, the UI ignores them for card movement. Only the terminal handoff—the one with a complete recipient list reaching the final role—triggers the transition to Done.

The reverse-roles Function in swarm_handoff.bb

The core selection logic lives in swarmforge/scripts/swarm_handoff.bb. The reverse-roles function determines which earlier roles receive merge‑only copies:

(defn reverse-roles [sender]
  (let [roles (pack-role-names)
        idx   (.indexOf roles sender)]
    (if (neg? idx)
      []
      (case (handoff-lib/role-propagation sender)
        "back-one" (if (pos? idx) [(nth roles (dec idx))] [])
        "back-all" (vec (take idx roles))
        []))))

How It Works

  1. pack-role-names returns the ordered list of roles in the current pack.
  2. handoff-lib/role-propagation reads the sender's propagation token from configuration.
  3. For back-one: Returns the single role at index (dec idx)—the immediate predecessor, if one exists.
  4. For back-all: Returns vec (take idx roles)—every role appearing before the sender.

The returned roles then receive inbox copies marked with with-non-forwarding, preventing any downstream handoff generation.

Code Example: A Three‑Role Pack

Consider a pack with roles [coder, cleaner, architect]:

;; Architect sends with `back-one` token
(reverse-roles "architect")
;;=> ["cleaner"]  ; only immediate predecessor

;; Architect sends with `back-all` token  
(reverse-roles "architect")
;;=> ["coder" "cleaner"]  ; all earlier roles

In both cases, the architect's primary handoff still routes to the next role (or completes if terminal). The merge‑only copies are side deliveries that update earlier worktrees without advancing the board state.

The Non‑Forwarding Marker

Within swarm_handoff.bb, the with-non-forwarding wrapper ensures these copies cannot spawn further handoffs. This containment guarantees that:

  • Earlier roles see the code changes.
  • No infinite loops or redundant forward chains occur.
  • The board card's position reflects only the terminal handoff's completion status.

Summary

  • Propagation tokens in swarmforge.conf (back-one, back-all) configure retroactive visibility without workflow re‑entry.
  • reverse-roles in swarm_handoff.bb implements the selection logic using pack ordering and the sender's token.
  • Merge‑only, non‑forwarding copies update earlier roles' worktrees but omit forward entries, so the UI never moves the task card on these arrivals.
  • Card movement happens exclusively when the terminal handoff updates the final role's to: list.

Frequently Asked Questions

What is the default propagation behavior in Swarm Forge?

forward-only is the default. When omitted, a role's handoffs advance only to the next role in the pack, and the board card moves forward normally. No copies are sent to earlier roles.

Can a role use both back-one and back-all simultaneously?

No. The case statement in reverse-roles evaluates the propagation token as a single value. A role must declare one token—or none—in its swarmforge.conf window line. The implementation does not support combining these modes.

Why distinguish merge‑only copies from regular handoffs at all?

The separation prevents re‑forwarding loops and spurious card movement. If earlier roles received standard handoffs, they would issue their own forward handoffs, potentially cycling indefinitely. The non‑forwarding constraint preserves determinism in the pack's state machine.

Where does the UI check whether to move a card?

Per the README.md board UI description, the interface examines the to: list of the last role's handoff. Merge‑only copies lack this entry for their recipients, so the UI ignores them for transition purposes.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →