# How SwarmForge Achieves tmux Session Isolation Per Project

> Learn how SwarmForge isolates tmux sessions per project using unique Unix sockets and the -S flag. Enhance your workflow with secure, project-specific terminal environments.

- Repository: [Robert C. Martin/swarm-forge](https://github.com/unclebob/swarm-forge)
- Tags: internals
- Published: 2026-08-10

---

**SwarmForge isolates tmux sessions per project by generating a unique Unix socket file for each project instance and binding every tmux command to that specific socket via the `-S` flag.**

The `unclebob/swarm-forge` repository orchestrates development environments using tmux for terminal management. To prevent conflicts between concurrent projects, the tool implements strict **tmux session isolation per project** through socket-based server separation. This architecture ensures that windows, panes, and sessions from one project never interfere with another, even when multiple SwarmForge instances run simultaneously on the same host.

## Socket-Based Architecture for Complete Isolation

SwarmForge does not rely on session naming conventions alone; it spawns an entirely separate tmux server process for each project by controlling the socket path.

### Per-Project Socket Directory

When SwarmForge initializes, it constructs a temporary directory path that incorporates the user's UID or username to avoid permission conflicts.

```clojure
(def tmux-socket-dir (fs/path "/tmp"
                      (str "swarmforge-" (or (System/getenv "UID")
                                             (System/getProperty "user.name")))))

```

This directory definition in `swarmforge.bb` (lines 464–465) ensures that socket files reside in `/tmp/swarmforge-<user>/`, separating resources by operating system user.

### Unique Socket File Generation

Inside this directory, SwarmForge creates a uniquely named socket file using a random identifier (`socket-id`) generated for each project run.

```clojure
(def tmux-socket (str (fs/path tmux-socket-dir (str socket-id ".sock"))))

```

As implemented in `swarmforge.bb` (lines 465–466), this guarantees that concurrent project instances receive distinct socket files, preventing cross-contamination between tmux servers.

### Persisting the Socket Path

To ensure child processes and terminal adapters can locate the correct server, SwarmForge writes the absolute socket path to a state file within the project directory.

```clojure
(spit (str (:tmux-socket-file ctx)) (str (:tmux-socket ctx) "\n"))

```

This operation, found at lines 246–247 in `swarmforge.bb`, creates `.swarmforge/tmux-socket`, allowing external scripts to reference the isolated tmux instance without hardcoding paths.

## Binding All Operations to the Project Socket

Isolation is enforced at the command level by appending the `-S <socket>` flag to every tmux invocation.

### Command Invocation Pattern

Every tmux operation—from session creation to option queries—targets the specific socket path stored in the context. The `tmux-agent-target` helper (lines 297–304 in `swarmforge.bb`) constructs proper target strings for panes and windows, ensuring all references resolve against the private socket.

For example, creating a new session uses:

```clojure
(defn start-agent-session [ctx session-name]
  (sh "tmux" "-S" (:tmux-socket ctx)
      "new-session" "-d" "-s" session-name "sleep" "120"))

```

### Detecting Base Indexes Independently

SwarmForge probes the isolated socket at startup to discover `base-index` and `pane-base-index` values (lines 88–97 in `swarmforge.bb`). By reading these options from the project-specific server rather than assuming defaults, the tool maintains consistent window and pane numbering that remains independent of any other tmux server running on the host.

## Cleanup and Session Termination

When a project closes, SwarmForge terminates only the sessions associated with its specific socket, leaving other tmux servers untouched.

The `kill-session!` function explicitly references the socket path:

```clojure
(defn kill-session! [tmux-socket session]
  (process/sh {:continue true}
               "tmux" "-S" tmux-socket "kill-session" "-t" session))

```

As shown in lines 520–525 of `swarmforge.bb`, this selective termination prevents accidental disruption of unrelated development sessions.

## Summary

- SwarmForge generates a **unique Unix socket** for each project under `/tmp/swarmforge-<user>/<socket-id>.sock`.
- The socket path is persisted to `.swarmforge/tmux-socket` so child processes can locate the isolated server.
- Every tmux command uses the **`-S` flag** to bind exclusively to the project-specific socket, creating a separate tmux server instance.
- **Base indexes** are detected from the isolated socket to ensure consistent numbering across projects.
- Cleanup operations target only the project's socket, preventing interference with other tmux sessions.

## Frequently Asked Questions

### Why does SwarmForge use socket files instead of session names for isolation?

Session names alone do not prevent conflicts between tmux servers; different projects could accidentally use identical session names. By generating a unique Unix socket file for each project run, SwarmForge creates an entirely separate tmux server process. This guarantees that commands like `tmux new-session` or `tmux kill-session` affect only the intended project, regardless of session naming conventions.

### Where does SwarmForge store the tmux socket path for a project?

SwarmForge writes the absolute path to the socket file into `.swarmforge/tmux-socket` within the project root directory. This occurs at lines 246–247 in `swarmforge.bb` via the `spit` function. Terminal adapter scripts read this file to attach to the correct tmux server when opening new terminal windows.

### Can multiple SwarmForge projects run simultaneously without conflicts?

Yes. Each project instance generates a unique `socket-id` and creates its own `.sock` file in the user's temporary directory. Because every tmux command specifies the socket via the `-S` flag, multiple isolated tmux servers can coexist on the same host. The cleanup logic at lines 520–525 ensures that terminating one project only kills sessions belonging to its specific socket.

### How does SwarmForge handle tmux base-index configurations per project?

At startup, SwarmForge queries the isolated socket to read the `base-index` and `pane-base-index` options (lines 88–97 in `swarmforge.bb`). By inspecting these values directly from the project-specific server, the tool correctly calculates window and pane references without assuming global defaults or conflicting with other running tmux instances.