# How to Define Task or Batch Processing Modes for SwarmForge Agents

> Learn how to define task or batch processing modes for SwarmForge agents by configuring the roles.tsv file and utilizing the role-receive-mode function for efficient workflow management.

- Repository: [Robert C. Martin/swarm-forge](https://github.com/unclebob/swarm-forge)
- Tags: how-to-guide
- Published: 2026-09-02

---

**SwarmForge agents process work as either a single task or a batch based on the *mode* column in your project's `roles.tsv` file, with the `role-receive-mode` function in `hand-off-lib.bb` parsing this configuration at runtime.**

SwarmForge is a multi-agent orchestration framework where each role's behavior is configured through declarative tab-separated files. Understanding how to set **task** versus **batch processing modes** lets you control whether an agent handles isolated work units or groups multiple handoffs into coordinated batches. This article shows exactly how these modes are defined, parsed, and applied according to the unclebob/swarm-forge source code.

---

## How Role Modes Are Stored and Parsed

The processing mode for any agent is stored in `roles.tsv`, located in your project's `.swarmforge/` directory. Each role occupies one tab-separated line with eight columns (zero-indexed):

| Column | Purpose |
|--------|---------|
| 0 | Role name (e.g., `cleaner`, `architect`) |
| 1 | Worktree name |
| 2 | Worktree path (optional) |
| 3 | Session name |
| 4 | Actor description |
| 5 | Model/engine (e.g., `codex`, `grok`) |
| **6** | **Mode**: `"task"` or `"batch"` |
| 7 | Propagation: `"forward-only"`, `"back-all"`, or `"back-one"` |

The `hand-off-lib.bb` script parses this file. The `role-rows` function (lines 44-46) loads and splits the TSV, making each role's configuration available to downstream functions.

---

## The Core Functions: `role-receive-mode` and `role-propagation`

Two helper functions in `swarmforge/scripts/handoff_lib.bb` extract the critical columns.

### `role-receive-mode` (Lines 72-75)

This function reads column 6 and defaults to `"task"` when empty:

```clojure
(defn role-receive-mode [role-name]
  (let [mode (nth (role-row role-name) 6 "")]
    (if (str/blank? mode) "task" mode)))

```

The logic is straightforward: if you leave the 7th column blank, the agent runs in **task mode**; explicitly write `"batch"` to enable **batch processing**.

### `role-propagation` (Lines 76-79)

The 8th column controls how handoffs flow back through the pipeline:

```clojure
(defn role-propagation [role-name]
  (let [mode (nth (role-row role-name) 7 "")]
    (if (str/blank? mode) "forward-only" mode)))

```

Options include `"forward-only"` (default), `"back-all"` (notify all previous lanes), and `"back-one"` (notify immediate predecessor).

---

## Configuring Batch Mode in `roles.tsv`

To enable batch processing for a specific role, edit `.swarmforge/roles.tsv` and add `"batch"` as the 7th field.

### Example: Batch-Enabled Cleaner Role

```

cleaner	cleaner	/path/to/cleaner	session	Cleaner	codex	batch	back-all

```

**Key points:**
- Fields are **tab-separated** — spaces or commas will break parsing.
- The `back-all` propagation setting ensures completed batches notify all upstream roles.
- Changes take effect on the next agent cycle; restart the tmux session to force immediate reload.

### Example: Task-Mode Architect Role (Default Behavior)

```

architect	architect	/path/to/architect	session	Architect	grok		

```

Here columns 6 and 7 are empty, so `role-receive-mode` returns `"task"` and `role-propagation` returns `"forward-only"`.

---

## How Agents Consume the Mode at Runtime

Agent scripts query their mode dynamically through `hand-off-lib.bb`.

### `ready_for_next.bb` (Lines 24-25)

The entry point for picking up work checks the mode before deciding how to group incoming handoffs:

```clojure
(let [mode (handoff-lib/role-receive-mode role-name)]
  ;; mode is now "task" or "batch"
  )

```

### `done_with_current.bb`

Similarly, this script uses the mode to determine whether to:
- Archive a single handoff (task mode), or
- Close and aggregate an entire batch directory (batch mode).

### Batch Directory Structure

When mode is `"batch"`, SwarmForge creates timestamped directories under `.swarmforge/handoffs/inbox/in_process/`:

```

batch_20260824T150500Z_000001/
├── handoff_001.json
├── handoff_002.json
└── ...

```

The dashboard aggregates these groups for monitoring and debugging.

---

## Practical Code Examples

### Query a Role's Mode from CLI

```bash
./swarmforge/scripts/handoff_lib.bb role-receive-mode cleaner

```

**Output:** `batch`

### Clojure Agent Script Snippet

```clojure
(require '[handoff-lib :as handoff-lib])

(let [mode (handoff-lib/role-receive-mode (handoff-lib/role))]
  (if (= mode "batch")
    (println "Batch mode: collecting handoffs into grouped directory")
    (println "Task mode: processing individual handoffs")))

```

### Dynamic Handoff Invocation with Mode Detection

```bash
#!/bin/bash
ROLE="cleaner"
MODE=$(./swarmforge/scripts/handoff_lib.bb role-receive-mode "$ROLE")

./swarmforge/scripts/swarm_handoff.sh \
  --role "$ROLE" \
  --to architect \
  --type "code-review" \
  --mode "$MODE"

```

---

## Key Source Files Reference

| File | Purpose |
|------|---------|
| `swarmforge/scripts/handoff_lib.bb` | Contains `role-receive-mode` and `role-propagation` parsers |
| `swarmforge/scripts/ready_for_next.bb` | Entry point that reads mode before work selection |
| `swarmforge/scripts/done_with_current.bb` | Finalizes tasks or batches based on mode |
| `.swarmforge/roles.tsv` | Project-specific role definitions (per-project) |

---

## Summary

- **Task vs. batch processing modes** are defined in column 6 of `roles.tsv` — leave empty for `"task"`, write `"batch"` for grouped processing.
- The `role-receive-mode` function in `hand-off-lib.bb` (lines 72-75) parses this column with a fallback to `"task"`.
- **Propagation behavior** (column 7) is controlled by `role-propagation` (lines 76-79), defaulting to `"forward-only"`.
- Agents call these functions at runtime to adapt their CLI flags, directory handling, and handoff aggregation logic.

---

## Frequently Asked Questions

### What happens if I leave the mode column empty in `roles.tsv`?

SwarmForge defaults to `"task"` mode. The `role-receive-mode` function treats blank values as task processing, ensuring backward compatibility and predictable behavior when no mode is specified.

### Can I change a role's mode without restarting the entire SwarmForge session?

Yes, but the change only takes effect when the role's agent script next calls `role-receive-mode`. To force immediate recognition, restart the tmux session for that role or trigger a role reload through your orchestration tooling.

### How does batch mode affect the handoff file structure?

Batch mode creates timestamped batch directories under `.swarmforge/handoffs/inbox/in_process/` rather than placing individual handoff files directly in the inbox. All handoffs sharing the same batch directory are processed and archived as a logical unit, with propagation rules applied to the entire batch.

### What's the difference between `"back-all"` and `"back-one"` propagation?

`"back-all"` notifies **all** upstream roles that contributed to the current pipeline, while `"back-one"` only notifies the **immediate predecessor**. Use `"back-all"` for fan-in architectures where multiple lanes converge, and `"back-one"` for strict sequential pipelines.