# How the forge.bb Module Manages Multiple Project Instantiation in SwarmForge

> Learn how the forge.bb module manages multiple project instantiation in SwarmForge. Discover its stateless registry and deterministic functions for unlimited concurrent projects.

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

---

**The `forge.bb` module provides a stateless, file-based registry that supports unlimited concurrent projects through deterministic functions like `instantiate!`, `open-project!`, and `close-project!`, storing active project states in a simple text file while isolating each workspace in its own filesystem directory.**

The `forge.bb` script serves as the core library for the SwarmForge ecosystem, enabling hosts to create, open, refresh, and close project workspaces without external database dependencies. Located at `swarmforge/scripts/forge.bb`, this module implements a lightweight, filesystem-driven approach to multi-project management that scales to any number of concurrent instances.

## Detecting SwarmForge Roots and Resolving Paths

Before managing projects, the module validates the host environment. The `forge?` predicate (lines 14-16) checks for the existence of a `projects` directory under the given root to confirm a valid SwarmForge installation.

Once validated, helper functions map logical names to concrete filesystem paths. The `project-dir`, `pack-dir`, `packs-dir`, and `projects-dir` functions (lines 20-25) generate absolute paths for project workspaces and their associated packs, ensuring consistent directory navigation across the codebase.

## Normalizing Project Names

The `inferred-name` function (lines 30-38) handles input sanitization by stripping URLs, `.git` suffixes, and whitespace from project identifiers. This utility optionally processes GitHub URLs to extract repository names, ensuring that project directories are created with clean, filesystem-safe names regardless of input format.

## Instantiating New Projects

The `instantiate!` function (lines 82-108) serves as the primary entry point for project creation. This multi-step process ensures that every new project starts from a validated, reproducible state:

1. **Resolves the directory name** via `dir-name` transformation
2. **Validates required fields** including `:name` and `:pack`
3. **Verifies pack existence** in the `packs/` directory
4. **Prevents overwrites** by failing if the target directory already exists
5. **Optionally clones GitHub repos** through `clone-github!` when the `:github` flag is true
6. **Applies pack overlays** via `overlay-pack!` to copy shared scripts and pack-specific files
7. **Writes custom configuration** when a `:conf` parameter is supplied
8. **Persists pack metadata** using `write-pack-name!` for future refresh operations
9. **Initializes Git repositories** for non-cloned projects

### Configuration Validation and Directory Creation

During instantiation, the module enforces strict validation rules. The function checks that both `:name` and `:pack` keys exist in the configuration map and that the specified pack exists in the filesystem. If a project directory already occupies the target path, the operation fails immediately to prevent data corruption.

### Pack Overlays and Git Initialization

For successful instantiations, the module overlays pack-specific assets from the `packs/<name>/` directory onto the new project workspace. When the project is not a GitHub clone, `instantiate!` initializes a fresh local Git repository to track changes independently from the pack source.

## Tracking and Managing Active Projects

Once instantiated, projects enter a managed lifecycle through open/close operations that control runtime processes and registry state.

### The Open Projects Registry

The module maintains a simple newline-separated text file at `.swarmforge/open-projects` to track active projects. This stateless registry supports unlimited concurrent projects through CRUD-style helper functions:

- **`read-open-projects`** (lines 81-88) parses the registry file
- **`mark-open!`** (lines 98-100) appends project names to the active list
- **`mark-closed!`** removes entries when projects stop
- **`project-open?`** checks membership in the active set

The `open-project!` function (lines 39-49) validates the project directory, refreshes its pack overlay, optionally starts the runtime via `start-project-runtime!`, and records the project as active. Conversely, `close-project!` (lines 51-55) stops background processes through `stop-project-runtime!` and removes the project from the registry. For system shutdown scenarios, `close-all-projects!` (lines 57-60) iterates the registry and invokes `close-project!` for each entry.

## Refreshing Existing Projects

When pack templates update, projects require synchronization without losing local work. The `refresh!` function (lines 110-118) retrieves the stored pack name via `stored-pack` and reapplies the pack overlay through `overlay-pack!`, preserving existing project files while updating shared assets and scripts.

## Practical Code Examples

```clojure
;; Create a fresh project from the "four-pack" pack
(require '[forge :as f])

(let [forge-root "/path/to/swarmforge"]
  (f/instantiate! forge-root
    {:name "my-awesome-app"
     :github false
     :pack "four-pack"
     :conf "(some swarmforge.conf)"
     :mission "Add first feature"}))
;; => {:name "my-awesome-app"
;;     :path "/path/to/swarmforge/projects/my-awesome-app"}

```

```clojure
;; Open an existing project so its agents start running
(let [forge-root "/path/to/swarmforge"]
  (f/open-project! forge-root "my-awesome-app"))
;; Starts the SwarmForge runtime and records it in 
;; .swarmforge/open-projects

```

```clojure
;; Close a project and clean up its runtime
(let [forge-root "/path/to/swarmforge"]
  (f/close-project! forge-root "my-awesome-app"))
;; Stops background processes and removes the entry from
;; the open-projects list

```

```clojure
;; Refresh a project after its pack was updated
(let [forge-root "/path/to/swarmforge"]
  (f/refresh! forge-root "my-awesome-app"))
;; Re-applies the pack overlay while preserving the worktree

```

## Summary

- **`forge.bb`** implements a stateless, file-based project registry located at `.swarmforge/open-projects` that requires no external database.
- **`instantiate!`** creates isolated project workspaces with validated configurations, Git initialization, and pack overlays.
- **`open-project!`** and **`close-project!`** manage runtime lifecycles and maintain the active projects list through simple text file operations.
- **`refresh!`** synchronizes projects with updated pack templates without destroying local work.
- The module supports unlimited concurrent projects through filesystem isolation and deterministic path resolution.

## Frequently Asked Questions

### How does forge.bb track multiple open projects without a database?

The module uses a plain text file at `.swarmforge/open-projects` that stores one project name per line. Helper functions like `read-open-projects` and `mark-open!` provide atomic read/write operations to this file, enabling the host to track unlimited concurrent projects through simple filesystem I/O rather than complex database connections.

### What happens when you call refresh! on an existing project?

The `refresh!` function retrieves the originally assigned pack name from the project's metadata and invokes `overlay-pack!` to reapply the pack's files. This operation updates shared scripts and configurations while preserving the project's existing worktree, local Git history, and any files not managed by the pack template.

### How does the module prevent duplicate project instantiation?

During the `instantiate!` workflow, the module checks for existing directories at the target path before performing any write operations. If a directory already exists for the requested project name, the function fails immediately with an error, preventing accidental overwrites of active projects.

### Can forge.bb create projects directly from GitHub repositories?

Yes. When the `:github` parameter is set to `true` in the configuration map, `instantiate!` invokes `clone-github!` to clone the repository before applying pack overlays. The `inferred-name` function automatically handles GitHub URL formats to extract clean project names from repository addresses.