main
md 126 lines 7.18 KB
Rendered Raw
1 # Worktree Reference
2
3 ### Worktree Awareness
4
5 Squad and all spawned agents may be running inside a **git worktree** rather than the main checkout. All `.squad/` paths (charters, history, decisions, logs) MUST be resolved relative to a known **team root**, never assumed from CWD.
6
7 **Two strategies for resolving the team root:**
8
9 | Strategy | Team root | State scope | When to use |
10 |----------|-----------|-------------|-------------|
11 | **worktree-local** | Current worktree root | Branch-local — each worktree has its own `.squad/` state | Feature branches that need isolated decisions and history |
12 | **main-checkout** | Main working tree root | Shared — all worktrees read/write the main checkout's `.squad/` | Single source of truth for memories, decisions, and logs across all branches |
13
14 **How the Coordinator resolves the team root (on every session start):**
15
16 0. **Check config.json overrides first** — read `.squad/config.json` in the current directory (or at the git root):
17 - If `teamRoot` is set → Team root = that path. **STOP — do not walk further.**
18 - If `stateLocation` is `"external"` → Resolve external AppData path. Team root = external path. **STOP.**
19 - Otherwise → continue to step 1.
20 1. **Check CWD first** — does `.squad/` exist in the current working directory?
21 - **Yes** → Team root = CWD. This handles monorepos where `.squad/` lives in a subfolder.
22 2. If not, run `git rev-parse --show-toplevel` to get the current worktree root.
23 3. Check if `.squad/` exists at that root (fall back to `.ai-team/` for repos that haven't migrated yet).
24 - **Yes** → use **worktree-local** strategy. Team root = current worktree root.
25 - **No** → use **main-checkout** strategy. Discover the main working tree:
26 ```
27 git worktree list --porcelain
28 ```
29 The first `worktree` line is the main working tree. Team root = that path.
30 4. The user may override the strategy at any time (e.g., *"use main checkout for team state"* or *"keep team state in this worktree"*).
31
32 **Passing the team root to agents:**
33 - The Coordinator includes `TEAM_ROOT: {resolved_path}` in every spawn prompt.
34 - Agents resolve ALL `.squad/` paths from the provided team root — charter, history, decisions inbox, logs.
35 - Agents never discover the team root themselves. They trust the value from the Coordinator.
36
37 **Cross-worktree considerations (worktree-local strategy — recommended for concurrent work):**
38 - `.squad/` files are **branch-local**. Each worktree works independently — no locking, no shared-state races.
39 - When branches merge into main, `.squad/` state merges with them. The **append-only** pattern ensures both sides only added content, making merges clean.
40 - A `merge=union` driver in `.gitattributes` (see Init Mode) auto-resolves append-only files by keeping all lines from both sides — no manual conflict resolution needed.
41 - The Scribe commits `.squad/` changes to the worktree's branch. State flows to other branches through normal git merge / PR workflow.
42
43 **Cross-worktree considerations (main-checkout strategy):**
44 - All worktrees share the same `.squad/` state on disk via the main checkout — changes are immediately visible without merging.
45 - **Not safe for concurrent sessions.** If two worktrees run sessions simultaneously, Scribe merge-and-commit steps will race on `decisions.md` and git index. Use only when a single session is active at a time.
46 - Best suited for solo use when you want a single source of truth without waiting for branch merges.
47
48 ### Worktree Lifecycle Management
49
50 When worktree mode is enabled, the coordinator creates dedicated worktrees for issue-based work. This gives each issue its own isolated branch checkout without disrupting the main repo.
51
52 **Worktree mode activation:**
53 - Explicit: `worktrees: true` in project config (squad.config.ts or package.json `squad` section)
54 - Environment: `SQUAD_WORKTREES=1` set in environment variables
55 - Default: `false` (backward compatibility — agents work in the main repo)
56
57 **Creating worktrees:**
58 - One worktree per issue number
59 - Multiple agents on the same issue share a worktree
60 - Path convention: `{repo-parent}/{repo-name}-{issue-number}`
61 - Example: Working on issue #42 in `C:\src\squad` → worktree at `C:\src\squad-42`
62 - Branch: `squad/{issue-number}-{kebab-case-slug}` (created from base branch, typically `main`)
63
64 **Dependency management:**
65 - After creating a worktree, link `node_modules` from the main repo to avoid reinstalling
66 - Windows: `cmd /c "mklink /J {worktree}\node_modules {main-repo}\node_modules"`
67 - Unix: `ln -s {main-repo}/node_modules {worktree}/node_modules`
68 - If linking fails (permissions, cross-device), fall back to `npm install` in the worktree
69
70 **Reusing worktrees:**
71 - Before creating a new worktree, check if one exists for the same issue
72 - `git worktree list` shows all active worktrees
73 - If found, reuse it (cd to the path, verify branch is correct, `git pull` to sync)
74 - Multiple agents can work in the same worktree concurrently if they modify different files
75
76 **Cleanup:**
77 - After a PR is merged, the worktree should be removed
78 - `git worktree remove {path}` + `git branch -d {branch}`
79 - Ralph heartbeat can trigger cleanup checks for merged branches
80
81 ### Pre-Spawn: Worktree Setup
82
83 When spawning an agent for issue-based work (user request references an issue number, or agent is working on a GitHub issue):
84
85 **1. Check worktree mode:**
86 - Is `SQUAD_WORKTREES=1` set in the environment?
87 - Or does the project config have `worktrees: true`?
88 - If neither: skip worktree setup → agent works in the main repo (existing behavior)
89
90 **2. If worktrees enabled:**
91
92 a. **Determine the worktree path:**
93 - Parse issue number from context (e.g., `#42`, `issue 42`, GitHub issue assignment)
94 - Calculate path: `{repo-parent}/{repo-name}-{issue-number}`
95 - Example: Main repo at `C:\src\squad`, issue #42 → `C:\src\squad-42`
96
97 b. **Check if worktree already exists:**
98 - Run `git worktree list` to see all active worktrees
99 - If the worktree path already exists → **reuse it**:
100 - Verify the branch is correct (should be `squad/{issue-number}-*`)
101 - `cd` to the worktree path
102 - `git pull` to sync latest changes
103 - Skip to step (e)
104
105 c. **Create the worktree:**
106 - Determine branch name: `squad/{issue-number}-{kebab-case-slug}` (derive slug from issue title if available)
107 - Determine base branch (typically `main`, check default branch if needed)
108 - Run: `git worktree add {path} -b {branch} {baseBranch}`
109 - Example: `git worktree add C:\src\squad-42 -b squad/42-fix-login main`
110
111 d. **Set up dependencies:**
112 - Link `node_modules` from main repo to avoid reinstalling:
113 - Windows: `cmd /c "mklink /J {worktree}\node_modules {main-repo}\node_modules"`
114 - Unix: `ln -s {main-repo}/node_modules {worktree}/node_modules`
115 - If linking fails (error), fall back: `cd {worktree} && npm install`
116 - Verify the worktree is ready: check build tools are accessible
117
118 e. **Include worktree context in spawn:**
119 - Set `WORKTREE_PATH` to the resolved worktree path
120 - Set `WORKTREE_MODE` to `true`
121 - Add worktree instructions to the spawn prompt (see template below)
122
123 **3. If worktrees disabled:**
124 - Set `WORKTREE_PATH` to `"n/a"`
125 - Set `WORKTREE_MODE` to `false`
126 - Use existing `git checkout -b` flow (no changes to current behavior)