# How SwarmForge Manages Project-Specific tmux Sockets: Isolation and Discovery

> SwarmForge isolates project tmux sockets in temp directories and saves paths to .swarmforge/tmux-socket. Discover how this ensures independent project operation.

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

---

**SwarmForge creates isolated tmux sockets in user-specific temporary directories and persists their paths to `.swarmforge/tmux-socket` to ensure each project operates independently of the host's default tmux server.**

SwarmForge, the open-source project orchestration tool by Uncle Bob Martin, implements strict process isolation by managing **project-specific tmux sockets** for every workspace. Unlike standard tmux usage that relies on a global server socket, SwarmForge generates unique socket files stored in temporary directories and records their locations within the project’s `.swarmforge` metadata folder. This architecture prevents session collisions and enables multiple SwarmForge projects to run concurrently without interfering with each other or the user's existing tmux sessions.

## Socket Directory and Naming Convention

SwarmForge constructs a dedicated namespace for tmux sockets under `/tmp` to avoid permission conflicts and ensure multi-user safety.

### User-Specific Temporary Directories

The socket directory path incorporates the current user’s identity to prevent cross-user collisions. In `swarmforge/scripts/swarmforge.bb` (lines 464-465), the system checks for the `UID` environment variable first, falling back to the `user.name` property:

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

```

This generates a path like `/tmp/swarmforge-1000` or `/tmp/swarmforge-alice`, ensuring that different users on the same host cannot overwrite each other’s socket files.

### Unique Socket File Generation

Within this directory, SwarmForge appends a random identifier to create the actual socket file. The construction at lines 483-485 joins the directory with a socket ID and `.sock` suffix:

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

```

The resulting absolute path (e.g., `/tmp/swarmforge-1000/a1b2c3.sock`) becomes the dedicated communication endpoint for that specific project instance.

## Persisting Socket Paths for Discovery

To enable external tools and user interaction, SwarmForge writes the socket path to a persistent location within the project root. At line 246 of `swarmforge/scripts/swarmforge.bb`, the application spits the socket location to `.swarmforge/tmux-socket`:

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

```

This file serves as the canonical reference for any process needing to communicate with the project's tmux server, eliminating the need to parse environment variables or guess socket locations.

## Sharing Sockets Across Role State

When SwarmForge initializes individual roles, it propagates the socket configuration into each role’s state directory. Lines 285-286 copy both the socket reference and associated environment files:

```clojure
(fs/copy (:tmux-socket-file ctx) (fs/path role-state-dir "tmux-socket")
         {:replace-existing true})
(fs/copy (:tmux-env-file ctx) (fs/path role-state-dir "tmux-env")
         {:replace-existing true})

```

This replication ensures that role-specific processes can attach to the correct tmux server without maintaining a global state reference, supporting SwarmForge’s distributed role architecture.

## Invoking tmux with Custom Sockets

Every tmux command executed by SwarmForge explicitly targets the project-specific socket using the `-S` flag. Line 297 demonstrates session creation with the socket parameter:

```clojure
(sh "tmux" "-S" (:tmux-socket ctx) "new-session" "-d" "-s" session "-n" agent-window)

```

By consistently passing the socket path via `-S`, SwarmForge guarantees that all session management operations—whether creating windows, splitting panes, or attaching clients—occur within the isolated project environment rather than the user’s default tmux instance.

## Manual Socket Interaction

Developers can interact directly with SwarmForge’s isolated tmux sessions using the persisted socket path.

### Attaching from the Command Line

To manually attach to a running SwarmForge session, read the socket path from the project metadata:

```bash

# Read the socket path that SwarmForge stored

SOCKET=$(cat .swarmforge/tmux-socket | tr -d '\n')

# Attach to the first SwarmForge session (e.g., "swarmforge-coder")

tmux -S "$SOCKET" attach-session -t swarmforge-coder

```

### Programmatic Access in Clojure

For Babashka scripts or Clojure tooling, retrieve the socket programmatically:

```clojure
(require '[babashka.fs :as fs]
         '[clojure.string :as str])

(def socket-path (str/trim (slurp (fs/path ".swarmforge" "tmux-socket"))))
;; Execute tmux commands against the project-specific server
(process/sh {:continue true}
            "tmux" "-S" socket-path "list-sessions")

```

## Summary

- **SwarmForge** generates unique **project-specific tmux sockets** under `/tmp/swarmforge-<user>` to isolate project sessions from the host’s default tmux server.
- Socket paths are constructed using the user’s UID or username to prevent multi-user conflicts on shared systems.
- The active socket location is persisted to `.swarmforge/tmux-socket` in the project root, enabling discovery by external tools and manual attachment.
- Role state directories receive copies of the socket file, ensuring distributed role processes can connect to the correct tmux instance.
- All tmux invocations use the `-S <socket>` flag to enforce communication through the project-specific endpoint.

## Frequently Asked Questions

### Where does SwarmForge store tmux sockets?

SwarmForge stores tmux sockets in a user-specific subdirectory under `/tmp`, formatted as `/tmp/swarmforge-<uid-or-username>/<random-id>.sock`. The specific path for the current project is saved to `.swarmforge/tmux-socket` in the project root directory, allowing tools and users to locate the exact socket file without searching the filesystem.

### How can I attach to a SwarmForge tmux session manually?

To attach manually, first read the socket path from `.swarmforge/tmux-socket`, then pass it to tmux using the `-S` flag: `tmux -S $(cat .swarmforge/tmux-socket) attach-session -t <session-name>`. This connects your terminal to the isolated SwarmForge server rather than your default tmux instance.

### Why does SwarmForge use project-specific sockets instead of the default tmux server?

Project-specific sockets prevent session name collisions and allow multiple SwarmForge projects to run simultaneously without interfering with each other or the user’s personal tmux sessions. According to the `swarmforge/scripts/swarmforge.bb` source, this isolation is critical for the tool’s multi-project orchestration capabilities, ensuring that killing or attaching to one project’s session never affects another.

### How does SwarmForge ensure socket uniqueness across different users?

The socket directory path includes either the `UID` environment variable or the `user.name` system property, creating separate namespaces like `/tmp/swarmforge-1000/` and `/tmp/swarmforge-alice/`. This design prevents permission errors and socket conflicts when multiple users run SwarmForge on the same host machine.