# How SwarmForge Swarm Topology Is Configured: A Complete Guide to swarmforge.conf

> Configure SwarmForge swarm topology using swarmforge.conf. Define roles, LLM backends, tmux visibility, and git mappings for process materialization. Get the complete guide.

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

---

**SwarmForge configures its swarm topology through a declarative configuration file located at [`swarmforge/swarmforge.conf`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/swarmforge.conf), which defines roles, LLM backends, tmux window visibility, and git worktree mappings that the launcher script materializes into concrete processes.**

SwarmForge is an open-source multi-agent orchestration framework developed by Robert C. Martin (Uncle Bob). Unlike hard-coded shell scripts, SwarmForge adopts a **configuration-driven approach** where the entire swarm shape—how many agents run, which models they use, and how they connect—is determined at runtime by parsing [`swarmforge.conf`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge.conf). This article explains the configuration format, the files involved, and how to customize your swarm topology.

---

## The Core Configuration File: swarmforge/swarmforge.conf

The topology originates from [`swarmforge/swarmforge.conf`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/swarmforge.conf) according to the repository architecture. This file is not hardcoded into the launcher; instead, it is copied into each project when created and read dynamically by `swarmforge/scripts/swarmforge.bb`.

The configuration uses **EDN (Extensible Data Notation)** format, common in Clojure/Babashka ecosystems, and supports the following top-level keys:

- **`:session-prefix`** — String prefix for tmux session names (e.g., `"swarmforge-coder"`).
- **`:window-invisible`** — Boolean flag; when `true`, creates headless tmux windows without visible terminals.
- **`:roles`** — Map of role identifiers to their specifications.

### Role Specification Structure

Each entry under `:roles` defines a swarm member:

| Key | Purpose | Example Values |
|-----|---------|--------------|
| `:backend` | LLM provider/backend | `"claude"`, `"codex"`, `"copilot"`, `"grok"` |
| `:worktree` | Git worktree directory name under `.worktrees/` | `"coder"`, `"specifier"`, `"cleaner"` |

---

## How the Launcher Reads the Configuration

In `swarmforge/scripts/swarmforge.bb`, the launcher performs the following steps at startup:

1. Locates [`swarmforge.conf`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge.conf) in the project directory.
2. Parses the EDN configuration into a data structure.
3. Iterates over `:roles` to spawn one tmux window per role.
4. Applies `:window-invisible` to control terminal visibility.
5. Assigns the specified `:backend` to each role's message routing.
6. Sets up git worktrees at `.worktrees/<worktree-name>` for isolated file contexts.

This separation of **topology declaration** from **orchestration logic** allows the same `swarmforge.bb` script to power wildly different workflows—from minimal two-agent setups to full six-pack specification pipelines.

---

## Example swarmforge.conf Configurations

### Minimal Two-Agent Backend-Only Setup

```clojure
{
  :session-prefix "backend-swarm"
  :window-invisible false
  :roles {
    :architect {:backend "claude" :worktree "main"}
    :implementer {:backend "codex" :worktree "main"}
  }
}

```

### Full Six-Pack Specification-Driven Pipeline

```clojure
{
  :session-prefix "enterprise-swarm"
  :window-invisible true
  :roles {
    :specifier  {:backend "grok"  :worktree "specs"}
    :architect  {:backend "claude" :worktree "design"}
    :writer     {:backend "copilot" :worktree "src"}
    :critic     {:backend "claude" :worktree "review"}
    :cleaner    {:backend "codex" :worktree "src"}
    :deployer   {:backend "claude" :worktree "ops"}
  }
}

```

---

## Where Configuration Files Originate

SwarmForge uses a **pack template system** to distribute default configurations. The sequence works as follows:

1. **Pack Selection** — When creating a project via the dashboard or `get-swarm-forge`, you select a pack (template).
2. **File Copying** — The pack copies its bundled [`swarmforge.conf`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge.conf) into `projects/<project-name>/swarmforge/`.
3. **Customization** — Edit the project-local [`swarmforge.conf`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge.conf) to reshape the swarm without touching the launcher code.

This design follows the **configuration-over-convention** principle: the orchestration engine (`swarmforge.bb`) remains stable while topology varies per project.

---

## Key Source Files and Their Roles

| File | Path | Function |
|------|------|----------|
| [`swarmforge.conf`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge.conf) | [`swarmforge/swarmforge.conf`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/swarmforge.conf) | Topology declaration (roles, backends, visibility, worktrees) |
| `swarmforge.bb` | `swarmforge/scripts/swarmforge.bb` | Launcher that parses config and materializes tmux sessions |
| [`README.md`](https://github.com/unclebob/swarm-forge/blob/main/README.md) | Repository root | Documents config-driven architecture and pack system |
| Role prompts | `swarmforge/roles/*.prompt` | Behavior definitions referenced by role names in config |

---

## Practical Workflow: Running a Custom Topology

```bash

# Start the forge dashboard and lieutenant

./swarm

# In the web UI:

# 1. Click "New Project"

# 2. Name it "my-custom-swarm"

# 3. Select a base pack (e.g., "three-pack")

# Modify the copied configuration

cat > projects/my-custom-swarm/swarmforge/swarmforge.conf << 'EOF'
{
  :session-prefix "custom"
  :window-invisible false
  :roles {
    :lead {:backend "claude" :worktree "lead-wt"}
    :support {:backend "codex" :worktree "support-wt"}
  }
}
EOF

# Restart the project swarm—the launcher will read the new config

```

---

## Summary

- **SwarmForge swarm topology** is declared in [`swarmforge/swarmforge.conf`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/swarmforge.conf) using EDN format, not hardcoded in shell scripts.
- The **`:roles`** map defines each agent's LLM backend, git worktree, and visibility.
- **`swarmforge/scripts/swarmforge.bb`** parses this file at launch to create tmux sessions and establish message routing.
- **Packs provide default configurations** that are copied per-project, enabling topology customization without engine modification.
- The **`:window-invisible`** flag supports headless operation while maintaining dashboard control via handoff messages.

---

## Frequently Asked Questions

### What file format does swarmforge.conf use?

SwarmForge uses **EDN (Extensible Data Notation)**, a Clojure-native data format that supports maps, keywords, vectors, and primitive types. This allows rich, readable configuration without the complexity of YAML or JSON. The `swarmforge.bb` launcher parses EDN directly using Babashka's built-in reader.

### Can I run multiple swarms with different topologies simultaneously?

Yes. Each project has its own [`swarmforge.conf`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge.conf), and the **`:session-prefix`** ensures tmux session names remain isolated. Run `swarm` from different project directories, and each will spawn independent tmux sessions prefixed accordingly. The dashboard routes messages to the correct swarm based on active project context.

### How do I hide agent windows but keep them operational?

Set **`:window-invisible true`** in [`swarmforge.conf`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge.conf). This creates tmux sessions without attached terminal windows. The agents remain fully functional—the dashboard can still address them through handoff messages, and logs are accessible via tmux attach commands. This is useful for long-running background agents like cleaners or deployment monitors.

### What happens if I edit swarmforge.conf while a swarm is running?

Changes take effect on **next launch**. The `swarmforge.bb` launcher reads the configuration once at startup. To apply topology changes, stop the current swarm and restart. There is no hot-reload mechanism; this design prevents runtime topology corruption and ensures clean session state.