# How get-swarm-forge Composes a Forge from Multiple Git Branches

> Discover how get-swarm-forge composes a SwarmForge from multiple Git branches by merging core components and pack branches into a unified environment. Learn the process now.

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

---

**The `get-swarm-forge` script assembles a complete SwarmForge environment by downloading the `main` branch for shared core components and merging files from three pack branches (`two-pack`, `four-pack`, `six-pack`) into a unified directory structure.**

The `get-swarm-forge` utility in the `unclebob/swarm-forge` repository automates the complex task of building a functional SwarmForge environment from distributed git branches. By orchestrating downloads from the base branch and multiple pack-specific branches, the script ensures both shared constitutional articles and pack-specific configurations are correctly integrated without conflicts.

## Architecture Overview

The composition process follows a **base-plus-packs** architecture. The script first establishes the shared foundation from the `main` branch, then layers pack-specific configurations from `two-pack`, `four-pack`, and `six-pack` branches. This approach ensures that critical shared files—particularly the three constitutional articles (`engineering.prompt`, `workflow.prompt`, `handoffs.prompt`)—remain consistent across all pack configurations while allowing each pack to define unique roles and governance extensions.

## Step-by-Step Composition Process

### 1. Branch Discovery and Configuration

The script begins by defining the three pack branches it will process: `two-pack`, `four-pack`, and `six-pack` (lines 4-6 in `get-swarm-forge`). It also reads optional environment variables to customize behavior:

- **`SWARMFORGE_REPO_URL`**: Overrides the default repository URL
- **`SWARMFORGE_BASE_BRANCH`**: Specifies the base branch (defaults to `main`)
- **`SWARMFORGE_PACKS_DIR`**: Points to pre-downloaded pack trees to avoid redundant fetching

These configurations allow forks and custom deployments to use alternative source locations without modifying the script.

### 2. Downloading Source Trees

The `download_branch` function (lines 27-32) handles retrieval of branch contents via tarball downloads. The script invokes this helper twice:

- First, to fetch the **main** branch into `$base_dir` (lines 68-71)
- Subsequently, to fetch each pack branch into temporary directories at `$tmp_dir/packs/<pack>` (lines 103-109)

This separation ensures that pack files remain isolated during initial download, preventing premature overwrites of base branch content.

### 3. Core Validation

Before proceeding with assembly, the script validates that the downloaded base branch contains required directories. Using the `fail_missing` helper, it verifies the presence of `swarmforge/scripts` and `swarmforge/constitution/articles` (lines 72-74). If either directory is absent, the script aborts immediately with a descriptive error message, preventing incomplete forge construction.

### 4. Assembling Shared Components

The script constructs the target hierarchy and populates it with core files from the base branch (lines 75-88):

1. Creates directory structure: `swarmforge/`, `packs/`, and `projects/`
2. Copies all host scripts from `main` into `swarmforge/scripts/`
3. Copies the three **shared constitution articles** into `swarmforge/constitution/articles/`:
   - `engineering.prompt`
   - `workflow.prompt`
   - `handoffs.prompt`
4. Copies core role files including `constitution.prompt` and `lieutenant.prompt`

These files form the invariant core of every forge installation.

### 5. Creating the Launcher

The script handles the `swarm` executable by either copying it from the repository or generating a thin wrapper script (lines 91-100). When generating the wrapper, it creates a forwarding script that delegates to [`swarmforge/scripts/swarmforge.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/scripts/swarmforge.sh), ensuring the dashboard entry point is always available at the forge root regardless of how the source repository structures its files.

### 6. Processing Pack Branches

For each pack defined in the branch list, the script determines the source location—either from `SWARMFORGE_PACKS_DIR` or the temporary download—and invokes `copy_pack_template` (lines 103-122). This helper function (lines 40-62) performs selective merging:

- Copies the pack's `swarm` file and [`swarmforge/swarmforge.conf`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/swarmforge.conf)
- Copies the pack-specific `roles/` directory containing `.prompt` files
- Copies pack-specific constitution articles **only if they do not match** the three shared article names, preventing pack branches from overwriting the core governance documents

### 7. Integrity Verification

After copying pack files, the script validates each pack's configuration (lines 123-130). It verifies that [`swarmforge.conf`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge.conf) exists and that every role referenced in that configuration has a corresponding `.prompt` file in the pack's roles directory. This check ensures that the forge will not attempt to invoke undefined roles during operation.

### 8. Final Validation

Before declaring success, the script runs a comprehensive sanity check using a static list of required files defined in lines 20-34. The `fail_missing` function iterates through this checklist, verifying the presence of critical components including the launcher script, constitution articles, and pack configurations. Any missing file triggers an immediate abort with actionable error messaging.

### 9. Completion

When all validation checks pass, the script outputs a completion message (lines 136-138) indicating that the forge is ready to start via the `./swarm` launcher.

## Multi-Branch Merge Strategy

The composition logic specifically protects **shared constitutional articles** from pack-specific overrides. When processing pack content via `copy_pack_template`, the script explicitly skips `engineering.prompt`, `workflow.prompt`, and `handoffs.prompt` if they exist in the pack branch. This ensures that governance standards defined in the `main` branch remain authoritative, while allowing packs to contribute supplementary articles for specialized workflows.

Pack-specific components—including [`swarmforge.conf`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge.conf), custom role prompts, and extended constitution articles—are isolated under `packs/<pack-name>/` to prevent filename collisions and maintain clear organizational boundaries.

## Resulting Directory Structure

The final forge layout reflects the multi-branch composition:

```text
/<forge-root>
├── swarm                    # Launcher (copied or generated)

├── swarmforge/
│   ├── scripts/             # Host scripts from main

│   ├── constitution/
│   │   └── articles/        # Shared articles (main branch)

│   └── roles/
│       └── lieutenant.prompt
├── packs/
│   ├── two-pack/
│   │   └── swarmforge/      # Pack-specific config, roles, articles

│   ├── four-pack/
│   └── six-pack/
└── projects/                # Empty workspace directory

```

## Practical Usage

Install and run the composition script:

```bash

# Make executable and install to PATH

chmod +x get-swarm-forge
cp get-swarm-forge ~/bin/

# Build the forge (downloads branches and assembles structure)

~/bin/get-swarm-forge

# Start the dashboard

./swarm

```

Customize source locations using environment variables:

```bash
export SWARMFORGE_REPO_URL=https://github.com/your-org/swarm-forge
export SWARMFORGE_BASE_BRANCH=develop
export SWARMFORGE_PACKS_DIR=/opt/local/packs
get-swarm-forge

```

## Summary

- **`get-swarm-forge`** composes a SwarmForge by merging the `main` branch with `two-pack`, `four-pack`, and `six-pack` branches.
- The **`download_branch`** function retrieves branch contents via tarball extraction to temporary locations.
- **Shared constitution articles** (`engineering.prompt`, `workflow.prompt`, `handoffs.prompt`) are protected from pack overrides and sourced exclusively from `main`.
- The **`copy_pack_template`** function selectively merges pack files while excluding protected article names.
- **Integrity checks** verify that [`swarmforge.conf`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge.conf) exists and that all referenced role prompts are present before completion.
- **Environment variables** (`SWARMFORGE_REPO_URL`, `SWARMFORGE_BASE_BRANCH`, `SWARMFORGE_PACKS_DIR`) allow customization of source repositories and branches.

## Frequently Asked Questions

### How does get-swarm-forge handle conflicts between main and pack branches?

The script resolves conflicts through explicit exclusion rules in `copy_pack_template`. When processing pack branches, it skips the three shared constitutional articles (`engineering.prompt`, `workflow.prompt`, `handoffs.prompt`), ensuring the `main` branch versions remain authoritative. All other files from pack branches are copied into isolated subdirectories under `packs/`, preventing direct filename collisions with core components.

### Can I use get-swarm-forge with a forked repository or custom branches?

Yes. The script reads three environment variables for customization: `SWARMFORGE_REPO_URL` to specify an alternative git repository, `SWARMFORGE_BASE_BRANCH` to use a branch other than `main` as the foundation, and `SWARMFORGE_PACKS_DIR` to supply pre-downloaded pack trees instead of fetching them remotely. These options enable forked deployments without requiring script modifications.

### What validation does get-swarm-forge perform on the composed forge?

The script performs validation at multiple stages. Initially, it uses `fail_missing` to verify that downloaded branches contain required directories (`swarmforge/scripts`, `swarmforge/constitution/articles`). After assembling packs, it checks that each [`swarmforge.conf`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge.conf) exists and that every role defined in the configuration has a corresponding `.prompt` file. Finally, it runs a comprehensive check against a static list of required files defined in lines 20-34 before marking completion.

### What is the difference between shared articles and pack-specific articles?

Shared articles are the three constitutional documents (`engineering.prompt`, `workflow.prompt`, `handoffs.prompt`) sourced exclusively from the `main` branch and protected from pack overrides. Pack-specific articles are additional governance documents unique to each pack (`two-pack`, `four-pack`, `six-pack`) that supplement—but do not replace—the shared core. These are copied only if their filenames do not collide with the protected shared set.