How Swarm-Forge Implements Project-Isolated TMUX Socket Naming Conventions

Swarm-Forge generates a unique TMUX socket for each project by combining a per-user temporary directory with a CRC32 checksum of the absolute working directory path, ensuring complete isolation between concurrent projects.

The TMUX socket naming convention in Swarm-Forge is designed to prevent session collisions when multiple projects run simultaneously. According to the unclebob/swarm-forge source code, this isolation is achieved through deterministic path generation and explicit socket targeting in all TMUX commands.

Understanding the Socket Path Structure

Swarm-Forge constructs the full socket path using two components:

Component Derivation Result
Socket directory /tmp/swarmforge- + current user UID (or user.name fallback) Per-user temp folder
Socket filename CRC32 checksum of absolute working directory + .sock Unique per project

The complete path follows this pattern:

/tmp/swarmforge-<uid>/<crc32-of-working-dir>.sock

This structure guarantees that two different projects—even for the same user—receive distinct socket files because the absolute project directory feeds into the checksum calculation.

How the Socket Is Generated

In swarmforge/scripts/swarmforge.bb, the context function implements the TMUX socket naming convention at lines 64-66:

(defn context [working-dir]
  (let [working-dir (fs/absolutize (fs/path working-dir))
        crc (java.util.zip.CRC32.)
        _ (.update crc (.getBytes (str working-dir) java.nio.charset.StandardCharsets/UTF_8))
        socket-id (str (.getValue crc))                         ;; ← unique per project
        tmux-socket-dir (fs/path "/tmp"
                                 (str "swarmforge-"
                                      (or (System/getenv "UID")
                                          (System/getProperty "user.name"))))
        tmux-socket (str (fs/path tmux-socket-dir (str socket-id ".sock")))]
    {:tmux-socket-dir tmux-socket-dir
     :tmux-socket     tmux-socket}))

The socket-id variable captures the CRC32 value, which serves as the project fingerprint. Because it derives from the full absolute path, renaming or moving a project changes its socket identity.

Project Isolation Mechanism

Swarm-Forge enforces project isolation through three concrete steps:

  1. Directory creation — fs/create-dirs ensures the per-user socket directory exists before any TMUX interaction
  2. State persistence — The socket path is written to .swarmforge/tmux-socket for subprocess discovery
  3. Explicit socket targeting — Every TMUX command uses the -S flag with the generated path

This last step is critical. Here's how Swarm-Forge creates a detached session using the isolated socket:


# Example TMUX command using the generated socket

tmux -S /tmp/swarmforge-1000/12345678.sock new-session -d -s my-session sleep 120

And here's session cleanup with the same isolation guarantee:

;; Checking/cleaning a session belonging to this project
(when (sh-ok? "tmux" "-S" (:tmux-socket ctx) "has-session" "-t" (:session row))
  (sh "tmux" "-S" (:tmux-socket ctx) "kill-session" "-t" (:session row)))

The -S flag appears in every TMUX invocation, ensuring commands only affect the current project's session space.

Socket Persistence and Discovery

Swarm-Forge persists the socket path so that external processes and terminal adapters can reconnect to the correct session:

;; Persist the socket path so other scripts can read it
(spit (str (:tmux-socket-file ctx))
      (str (:tmux-socket ctx) "\n"))

Shell wrappers in swarmforge/scripts/terminal-adapters/*.sh read this value and execute:

exec tmux -S "$TMUX_SOCKET" attach-session -t "$SESSION_NAME"

This allows seamless handoff between Swarm-Forge's Clojure core and external terminal processes while maintaining project-scoped isolation.

CRC32 Collision Resistance

A 32-bit CRC32 provides 4,294,967,296 possible values. For the TMUX socket naming convention, this is practically collision-free given that:

  • Socket directories are already segmented by user UID
  • Projects typically number in the dozens per user, not millions
  • The absolute path includes high-entropy components like usernames and deep directory structures

The deterministic nature also means the same project always receives the same socket path on restart, enabling idempotent session management.

Summary

  • Swarm-Forge uses /tmp/swarmforge-<uid>/<crc32>.sock as its TMUX socket naming convention
  • The CRC32 checksum of the absolute working directory ensures project-isolated sockets
  • All TMUX commands explicitly target the socket via -S, preventing cross-project interference
  • Socket paths are persisted to .swarmforge/tmux-socket for subprocess discovery
  • The implementation lives primarily in swarmforge/scripts/swarmforge.bb lines 64-66

Frequently Asked Questions

What happens if two users run Swarm-Forge on the same project directory?

Each user receives a distinct socket directory due to the UID/username component (/tmp/swarmforge-1000/ vs /tmp/swarmforge-1001/). The CRC32 portion may match, but the full paths remain unique, ensuring no socket collision occurs.

Can I change where Swarm-Forge stores its TMUX sockets?

The source code hardcodes /tmp as the base directory in the context function. To relocate sockets, you would need to modify swarmforge.bb and rebuild. There is no configuration flag for this path.

Why does Swarm-Forge use CRC32 instead of a cryptographic hash?

CRC32 is sufficient for unique identification without the computational overhead of SHA or MD5. TMUX socket names don't require cryptographic security—only collision avoidance and deterministic generation.

How does Swarm-Forge clean up old socket files?

The codebase does not implement automatic socket cleanup. Socket files persist in /tmp until system reboot or manual deletion. However, since sockets are recreated on each project start, stale files have no functional impact.

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 →