Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .ai-team/decisions.md
Original file line number Diff line number Diff line change
Expand Up @@ -4380,7 +4380,7 @@ The merge base is `d405871`. Since then:
- **main** got 21 non-merge commits (mostly release work, docs updates, guard cleanups)
- **dev** got extensive squad-sdk planning work (session logs, decisions, orchestration logs)

The branches effectively represent two different workstreams that happened in parallel:
The branches effectively represent two different SubSquads that happened in parallel:
- **main**: Release management (v0.5.x), guard cleanup, archive notices
- **dev**: Squad-SDK planning, CLI migration logs, PRD work

Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ coverage/
.test-cli-*
# Docs site generated files
docs/dist/
# Squad: workstream activation file (local to this machine)
# Squad: SubSquad activation file (local to this machine)
.squad-workstream
.squad/.first-run
2 changes: 1 addition & 1 deletion CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ These community members shaped Squad through issues, discussions, and feedback.
| [@tomasherceg](https://github.com/tomasherceg) | #184 (Multi-PR commit isolation), #237 (CLI wiring bug) — worktree improvements and bug reports |
| [@csharpfritz](https://github.com/csharpfritz) | #205 (Per-member model configuration) — model selection feature (shipped!) |
| [@johnwc](https://github.com/johnwc) | #176 (Different repo support) — multi-repo workflows |
| [@tamirdresher](https://github.com/tamirdresher) | #200 (Squad Workstreams PRD), #237 (CLI wiring bug) — horizontal scaling concept and bug reports |
| [@tamirdresher](https://github.com/tamirdresher) | #200 (Squad SubSquads PRD), #237 (CLI wiring bug) — horizontal scaling concept and bug reports |
| [@marchermans](https://github.com/marchermans) | #247 (Installation failure) — install bug report |
| [@dkirby-ms](https://github.com/dkirby-ms) | #239 (Terminal flickering bug) — UX bug report |
| [@EirikHaughom](https://github.com/EirikHaughom) | #223 (Model & reasoning configuration) — model config improvements |
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
---
title: "Workstreams — Scaling Squad Across Multiple Codespaces"
title: "SubSquads — Scaling Squad Across Multiple Codespaces"
date: 2026-03-05
author: "Tamir Dresher (Community Contributor)"
wave: null
tags: [squad, workstreams, scaling, codespaces, horizontal-scaling, multi-instance, community]
tags: [squad, subsquads, scaling, codespaces, horizontal-scaling, multi-instance, community]
status: draft
hero: "Squad Workstreams lets you partition a repo's work across multiple Codespaces — each running its own scoped Squad instance. One repo, multiple AI teams, zero conflicts."
hero: "Squad SubSquads lets you partition a repo's work across multiple Codespaces — each running its own scoped Squad instance. One repo, multiple AI teams, zero conflicts."
---

# Workstreams — Scaling Squad Across Multiple Codespaces
# SubSquads — Scaling Squad Across Multiple Codespaces

> Blog post #23 — A community contribution: horizontal scaling for Squad.

## The Problem We Hit

We were building a multiplayer Tetris game with Squad. One team, 30 issues — UI, backend, cloud infra. Squad handled it fine at first, but as the issue count grew, a single Squad instance became a bottleneck. Agents stepped on each other in shared packages, there was no workflow enforcement, and we had no way to scope each Codespace to its slice of work.

So we built Workstreams.
So we built SubSquads.

## What Are Workstreams?
## What Are SubSquads?

Workstreams partition your repo's issues into labeled subsets. Each Codespace (or machine) runs one workstream, scoped to matching issues only.
SubSquads partition your repo's issues into labeled subsets. Each Codespace (or machine) runs one SubSquad, scoped to matching issues only.

```
┌─────────────────────────────────────────────────┐
Expand All @@ -33,13 +33,13 @@ Workstreams partition your repo's issues into labeled subsets. Each Codespace (o
│ └─────────────┘ └─────────────┘ └───────────┘ │
│ │
│ Ralph only picks up issues matching │
│ the active workstream's label. │
│ the active SubSquad's label. │
└─────────────────────────────────────────────────┘
```

## How It Works

**1. Define workstreams** in `.squad/workstreams.json`:
**1. Define SubSquads** in `.squad/streams.json`:

```json
{
Expand All @@ -61,14 +61,14 @@ Workstreams partition your repo's issues into labeled subsets. Each Codespace (o
}
```

**2. Activate a workstream:**
**2. Activate a SubSquad:**

```bash
# Via environment variable (ideal for Codespaces)
export SQUAD_TEAM=bridge

# Or via CLI (local machines)
squad workstreams activate bridge
squad subsquads activate bridge
```

**3. Run Squad normally.** Ralph will only pick up issues labeled `team:bridge`. Agents enforce branch+PR workflow. `folderScope` guides where agents focus (advisory, not enforced — shared code is still accessible).
Expand All @@ -77,7 +77,7 @@ squad workstreams activate bridge

We validated this with [tamirdresher/squad-tetris](https://github.com/tamirdresher/squad-tetris) — 3 Codespaces, 30 issues, Star Trek TNG crew names:

| Codespace | Workstream | Squad Members | Focus |
| Codespace | SubSquad | Squad Members | Focus |
|-----------|-----------|---------------|-------|
| CS-1 | `ui` | Riker, Troi | React game board, animations |
| CS-2 | `backend` | Geordi, Worf | WebSocket server, game state |
Expand All @@ -88,32 +88,32 @@ We validated this with [tamirdresher/squad-tetris](https://github.com/tamirdresh
## CLI Commands

```bash
squad workstreams list # Show all configured workstreams
squad workstreams status # Activity per workstream (branches, PRs)
squad workstreams activate X # Activate a workstream for this machine
squad subsquads list # Show all configured SubSquads
squad subsquads status # Activity per SubSquad (branches, PRs)
squad subsquads activate X # Activate a SubSquad for this machine
```

## Resolution Chain

Squad resolves the active workstream in priority order:
Squad resolves the active SubSquad in priority order:

1. `SQUAD_TEAM` environment variable
2. `.squad-workstream` file (written by `activate`, gitignored)
3. Auto-select if exactly one workstream is defined
4. No workstream → single-squad mode (backward compatible)
3. Auto-select if exactly one SubSquad is defined
4. No SubSquad → single-squad mode (backward compatible)

## Key Design Decisions

- **folderScope is advisory** — agents prefer these directories but can modify shared code when needed
- **Workflow enforcement** — `branch-per-issue` means every issue gets a branch and PR, never direct commits to main
- **Backward compatible** — repos without `workstreams.json` work exactly as before
- **Single-machine testing** — use `squad workstreams activate` to switch workstreams sequentially without needing multiple Codespaces
- **Backward compatible** — repos without `streams.json` work exactly as before
- **Single-machine testing** — use `squad subsquads activate` to switch SubSquads sequentially without needing multiple Codespaces

## What's Next

We're looking at cross-workstream coordination — a central dashboard showing all workstreams' activity, conflict detection for shared files, and auto-merge coordination. See the [PRD](https://github.com/bradygaster/squad/issues/200) for the full roadmap.
We're looking at cross-SubSquad coordination — a central dashboard showing all SubSquads' activity, conflict detection for shared files, and auto-merge coordination. See the [PRD](https://github.com/bradygaster/squad/issues/200) for the full roadmap.

Also: we haven't settled on the name yet! "Workstreams" is the working title, but we're considering alternatives like "Lanes", "Teams", or "Streams". If you have an opinion, let us know in the [discussion](https://github.com/bradygaster/squad/issues/200).
The community decided on the name "SubSquads" — each partition is a SubSquad of the main Squad.

## Try It

Expand All @@ -124,10 +124,10 @@ npm install -g @bradygaster/squad-cli
# Init in your repo
squad init

# Create workstreams.json and label your issues
# Create streams.json and label your issues
# Then activate and go
squad workstreams activate frontend
squad subsquads activate frontend
squad start
```

Full docs: [Scaling with Workstreams](../scenarios/scaling-workstreams.md) | [Multi-Codespace Setup](../scenarios/multi-codespace.md) | [Workstreams PRD](../specs/streams-prd.md)
Full docs: [Scaling with SubSquads](../scenarios/scaling-workstreams.md) | [Multi-Codespace Setup](../scenarios/multi-codespace.md) | [SubSquads PRD](../specs/streams-prd.md)
66 changes: 34 additions & 32 deletions docs/features/streams.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
# Squad Workstreams
# Squad SubSquads

> Scale Squad across multiple Codespaces by partitioning work into labeled workstreams.
> Scale Squad across multiple Codespaces by partitioning work into labeled SubSquads.

## What Are Workstreams?
## What Are SubSquads?

A **workstream** is a named partition of work within a Squad project. Each workstream targets a specific GitHub label (e.g., `team:ui`, `team:backend`) and optionally restricts agents to certain directories. Multiple Squad instances — each running in its own Codespace — can each activate a different workstream, enabling parallel work across teams.
A **SubSquad** is a named partition of work within a Squad project. Each SubSquad targets a specific GitHub label (e.g., `team:ui`, `team:backend`) and optionally restricts agents to certain directories. Multiple Squad instances — each running in its own Codespace — can each activate a different SubSquad, enabling parallel work across teams.

## Why Workstreams?
## Why SubSquads?

Squad was originally designed for a single team per repository. As projects grow, a single Codespace becomes a bottleneck:

- **Model rate limits** — One Codespace hitting API limits slows the whole team
- **Context overload** — Ralph picks up all issues, not just the relevant ones
- **Folder conflicts** — Multiple agents editing the same files causes merge pain

Workstreams solve this by giving each Codespace a scoped view of the project.
SubSquads solve this by giving each Codespace a scoped view of the project.

## Configuration

### 1. Create `.squad/workstreams.json`
### 1. Create `.squad/streams.json`

```json
{
Expand Down Expand Up @@ -49,9 +49,9 @@ Workstreams solve this by giving each Codespace a scoped view of the project.
}
```

### 2. Activate a Workstream
### 2. Activate a SubSquad

There are three ways to tell Squad which workstream to use:
There are three ways to tell Squad which SubSquad to use:

#### Environment Variable (recommended for Codespaces)

Expand All @@ -72,71 +72,73 @@ Set this in your Codespace's environment or devcontainer.json:
#### .squad-workstream File (local activation)

```bash
squad workstreams activate ui-team
squad subsquads activate ui-team
```

This writes a `.squad-workstream` file (gitignored) so the setting is local to your machine.

#### Auto-select (single workstream)
#### Auto-select (single SubSquad)

If `workstreams.json` contains only one workstream, it's automatically selected.
If `streams.json` contains only one SubSquad, it's automatically selected.

### 3. Resolution Priority

1. `SQUAD_TEAM` env var (highest)
2. `.squad-workstream` file
3. Single-workstream auto-select
4. No workstream (classic single-squad mode)
3. Single-SubSquad auto-select
4. No SubSquad (classic single-squad mode)

## Workstream Definition Fields
## SubSquad Definition Fields

| Field | Required | Description |
|-------|----------|-------------|
| `name` | Yes | Unique workstream identifier (kebab-case) |
| `name` | Yes | Unique SubSquad identifier (kebab-case) |
| `labelFilter` | Yes | GitHub label to filter issues |
| `folderScope` | No | Directories this workstream may modify |
| `folderScope` | No | Directories this SubSquad may modify |
| `workflow` | No | `branch-per-issue` (default) or `direct` |
| `description` | No | Human-readable purpose |

## CLI Reference

```bash
# List configured workstreams
squad workstreams list
# List configured SubSquads
squad subsquads list

# Show workstream activity (branches, PRs)
squad workstreams status
# Show SubSquad activity (branches, PRs)
squad subsquads status

# Activate a workstream locally
squad workstreams activate <name>
# Activate a SubSquad locally
squad subsquads activate <name>
```

> **Note:** `squad workstreams` and `squad streams` are deprecated aliases for `squad subsquads`.

## How It Works

### Triage (Ralph)

When a workstream is active, Ralph's triage only picks up issues labeled with the workstream's `labelFilter`. Unmatched issues are left for other workstreams or the main squad.
When a SubSquad is active, Ralph's triage only picks up issues labeled with the SubSquad's `labelFilter`. Unmatched issues are left for other SubSquads or the main squad.

### Workflow Enforcement

- **branch-per-issue** (default): Every issue gets its own branch and PR. Agents never commit directly to main.
- **direct**: Agents may commit directly (useful for infra/ops workstreams).
- **direct**: Agents may commit directly (useful for infra/ops SubSquads).

### Folder Scope

When `folderScope` is set, agents should primarily modify files within those directories. However, `folderScope` is **advisory, not a hard lock** — agents may still touch shared files (types, configs, package exports) when their issue requires it. The real protection comes from `branch-per-issue` workflow: each issue gets its own branch, so two workstreams editing the same file won't conflict until merge time.
When `folderScope` is set, agents should primarily modify files within those directories. However, `folderScope` is **advisory, not a hard lock** — agents may still touch shared files (types, configs, package exports) when their issue requires it. The real protection comes from `branch-per-issue` workflow: each issue gets its own branch, so two SubSquads editing the same file won't conflict until merge time.

> **Tip:** If two workstreams' PRs touch the same file, Git resolves non-overlapping changes automatically. For semantic conflicts (incompatible API changes), use PR review to catch them.
> **Tip:** If two SubSquads' PRs touch the same file, Git resolves non-overlapping changes automatically. For semantic conflicts (incompatible API changes), use PR review to catch them.

### Cost Optimization: Single-Machine Multi-Workstream
### Cost Optimization: Single-Machine Multi-SubSquad

You don't need a separate Codespace per workstream. One machine can serve multiple workstreams:
You don't need a separate Codespace per SubSquad. One machine can serve multiple SubSquads:

```bash
# Switch between workstreams manually
squad workstreams activate ui-team # Ralph works team:ui issues
# Switch between SubSquads manually
squad subsquads activate ui-team # Ralph works team:ui issues
# ... later ...
squad workstreams activate backend-team # now works team:backend issues
squad subsquads activate backend-team # now works team:backend issues
```

This gives you 1× Codespace cost instead of N×, at the expense of serial (not parallel) execution. Each issue still gets its own branch — no conflicts.
Expand Down
38 changes: 19 additions & 19 deletions docs/scenarios/multi-codespace.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
# Multi-Codespace Setup with Squad Workstreams
# Multi-Codespace Setup with Squad SubSquads

> End-to-end walkthrough of running multiple Squad instances across Codespaces.

## Background: The Tetris Experiment

We validated Squad Workstreams by building a multiplayer Tetris game using 3 Codespaces, each running a separate workstream:
We validated Squad SubSquads by building a multiplayer Tetris game using 3 Codespaces, each running a separate SubSquad:

| Codespace | Workstream | Label | Focus |
| Codespace | SubSquad | Label | Focus |
|-----------|--------|-------|-------|
| CS-1 | `ui-team` | `team:ui` | React game board, piece rendering, animations |
| CS-2 | `backend-team` | `team:backend` | WebSocket server, game state, matchmaking |
| CS-3 | `infra-team` | `team:infra` | CI/CD, Docker, deployment |

All three Codespaces shared the same repository. Each Squad instance only picked up issues matching its workstream's label.
All three Codespaces shared the same repository. Each Squad instance only picked up issues matching its SubSquad's label.

## Setup Steps

### 1. Create the workstreams config
### 1. Create the SubSquads config

In your repository, create `.squad/workstreams.json`:
In your repository, create `.squad/streams.json`:

```json
{
Expand Down Expand Up @@ -67,7 +67,7 @@ In `.devcontainer/devcontainer.json`, set the `SQUAD_TEAM` env var. For multiple

```bash
export SQUAD_TEAM=ui-team
squad # launches with workstream context
squad # launches with SubSquad context
```

### 3. Label your issues
Expand All @@ -82,7 +82,7 @@ gh issue create --title "Add Docker compose for dev" --label "team:infra"

### 4. Launch Squad in each Codespace

Each Codespace runs `squad` normally. The workstream context is detected automatically:
Each Codespace runs `squad` normally. The SubSquad context is detected automatically:

```bash
# In Codespace 1 (SQUAD_TEAM=ui-team)
Expand All @@ -96,32 +96,32 @@ squad
# → Agents only modify files in src/server, src/shared
```

### 5. Monitor across workstreams
### 5. Monitor across SubSquads

Use the CLI from any Codespace to see all workstreams:
Use the CLI from any Codespace to see all SubSquads:

```bash
squad workstreams status
squad subsquads status
```

<!-- Screenshot: workstreams status output showing PRs per workstream -->
<!-- Screenshot: SubSquads status output showing PRs per SubSquad -->
<!-- TODO: Add screenshot placeholder -->

## What Worked

- **Clear separation**: Each workstream had well-defined boundaries, minimizing merge conflicts
- **Clear separation**: Each SubSquad had well-defined boundaries, minimizing merge conflicts
- **Parallel velocity**: 3x throughput vs. single-squad mode for independent work
- **Label-based routing**: Simple, uses existing GitHub infrastructure

## What Didn't Work (Yet)

- **Cross-workstream dependencies**: When the UI team needed a backend API change, manual coordination was required
- **Cross-SubSquad dependencies**: When the UI team needed a backend API change, manual coordination was required
- **Shared files**: `package.json`, `tsconfig.json`, and other root files caused occasional conflicts
- **No meta-coordinator**: No automated way to coordinate across workstreams (future work)
- **No meta-coordinator**: No automated way to coordinate across SubSquads (future work)

## Lessons Learned

1. **Keep workstreams independent** — design folder boundaries to minimize shared files
2. **Use branch-per-issue** — direct commits across workstreams cause merge hell
3. **Label everything** — unlabeled issues get lost between workstreams
4. **Start with 2 workstreams** — add more once the team finds its rhythm
1. **Keep SubSquads independent** — design folder boundaries to minimize shared files
2. **Use branch-per-issue** — direct commits across SubSquads cause merge hell
3. **Label everything** — unlabeled issues get lost between SubSquads
4. **Start with 2 SubSquads** — add more once the team finds its rhythm
Loading
Loading