| 1 | --- |
| 2 | name: "git-workflow" |
| 3 | description: "Squad branching model: dev-first workflow with insiders preview channel" |
| 4 | domain: "version-control" |
| 5 | confidence: "high" |
| 6 | source: "team-decision" |
| 7 | --- |
| 8 | |
| 9 | ## Context |
| 10 | |
| 11 | Squad uses a three-branch model. **All feature work starts from `dev`, not `main`.** |
| 12 | |
| 13 | | Branch | Purpose | Publishes | |
| 14 | |--------|---------|-----------| |
| 15 | | `main` | Released, tagged, in-npm code only | `npm publish` on tag | |
| 16 | | `dev` | Integration branch — all feature work lands here | `npm publish --tag preview` on merge | |
| 17 | | `insiders` | Early-access channel — synced from dev | `npm publish --tag insiders` on sync | |
| 18 | |
| 19 | ## Branch Naming Convention |
| 20 | |
| 21 | Issue branches MUST use: `squad/{issue-number}-{kebab-case-slug}` |
| 22 | |
| 23 | Examples: |
| 24 | - `squad/195-fix-version-stamp-bug` |
| 25 | - `squad/42-add-profile-api` |
| 26 | |
| 27 | ## Workflow for Issue Work |
| 28 | |
| 29 | 1. **Branch from dev:** |
| 30 | ```bash |
| 31 | git checkout dev |
| 32 | git pull origin dev |
| 33 | git checkout -b squad/{issue-number}-{slug} |
| 34 | ``` |
| 35 | |
| 36 | 2. **Mark issue in-progress:** |
| 37 | ```bash |
| 38 | gh issue edit {number} --add-label "status:in-progress" |
| 39 | ``` |
| 40 | |
| 41 | 3. **Create draft PR targeting dev:** |
| 42 | ```bash |
| 43 | gh pr create --base dev --title "{description}" --body "Closes #{issue-number}" --draft |
| 44 | ``` |
| 45 | |
| 46 | 4. **Do the work.** Make changes, write tests, commit with issue reference. |
| 47 | |
| 48 | 5. **Push and mark ready:** |
| 49 | ```bash |
| 50 | git push -u origin squad/{issue-number}-{slug} |
| 51 | gh pr ready |
| 52 | ``` |
| 53 | |
| 54 | 6. **After merge to dev:** |
| 55 | ```bash |
| 56 | git checkout dev |
| 57 | git pull origin dev |
| 58 | git branch -d squad/{issue-number}-{slug} |
| 59 | git push origin --delete squad/{issue-number}-{slug} |
| 60 | ``` |
| 61 | |
| 62 | ## Parallel Multi-Issue Work (Worktrees) |
| 63 | |
| 64 | When the coordinator routes multiple issues simultaneously (e.g., "fix bugs X, Y, and Z"), use `git worktree` to give each agent an isolated working directory. No filesystem collisions, no branch-switching overhead. |
| 65 | |
| 66 | ### When to Use Worktrees vs Sequential |
| 67 | |
| 68 | | Scenario | Strategy | |
| 69 | |----------|----------| |
| 70 | | Single issue | Standard workflow above — no worktree needed | |
| 71 | | 2+ simultaneous issues in same repo | Worktrees — one per issue | |
| 72 | | Work spanning multiple repos | Separate clones as siblings (see Multi-Repo below) | |
| 73 | |
| 74 | ### Setup |
| 75 | |
| 76 | From the main clone (must be on dev or any branch): |
| 77 | |
| 78 | ```bash |
| 79 | # Ensure dev is current |
| 80 | git fetch origin dev |
| 81 | |
| 82 | # Create a worktree per issue — siblings to the main clone |
| 83 | git worktree add ../squad-195 -b squad/195-fix-stamp-bug origin/dev |
| 84 | git worktree add ../squad-193 -b squad/193-refactor-loader origin/dev |
| 85 | ``` |
| 86 | |
| 87 | **Naming convention:** `../{repo-name}-{issue-number}` (e.g., `../squad-195`, `../squad-pr-42`). |
| 88 | |
| 89 | Each worktree: |
| 90 | - Has its own working directory and index |
| 91 | - Is on its own `squad/{issue-number}-{slug}` branch from dev |
| 92 | - Shares the same `.git` object store (disk-efficient) |
| 93 | |
| 94 | ### Per-Worktree Agent Workflow |
| 95 | |
| 96 | Each agent operates inside its worktree exactly like the single-issue workflow: |
| 97 | |
| 98 | ```bash |
| 99 | cd ../squad-195 |
| 100 | |
| 101 | # Work normally — commits, tests, pushes |
| 102 | git add -A && git commit -m "fix: stamp bug (#195)" |
| 103 | git push -u origin squad/195-fix-stamp-bug |
| 104 | |
| 105 | # Create PR targeting dev |
| 106 | gh pr create --base dev --title "fix: stamp bug" --body "Closes #195" --draft |
| 107 | ``` |
| 108 | |
| 109 | All PRs target `dev` independently. Agents never interfere with each other's filesystem. |
| 110 | |
| 111 | ### .squad/ State in Worktrees |
| 112 | |
| 113 | The `.squad/` directory exists in each worktree as a copy. This is safe because: |
| 114 | - `.gitattributes` declares `merge=union` on append-only files (history.md, decisions.md, logs) |
| 115 | - Each agent appends to its own section; union merge reconciles on PR merge to dev |
| 116 | - **Rule:** Never rewrite or reorder `.squad/` files in a worktree — append only |
| 117 | |
| 118 | ### Cleanup After Merge |
| 119 | |
| 120 | After a worktree's PR is merged to dev: |
| 121 | |
| 122 | ```bash |
| 123 | # From the main clone |
| 124 | git worktree remove ../squad-195 |
| 125 | git worktree prune # clean stale metadata |
| 126 | git branch -d squad/195-fix-stamp-bug |
| 127 | git push origin --delete squad/195-fix-stamp-bug |
| 128 | ``` |
| 129 | |
| 130 | If a worktree was deleted manually (rm -rf), `git worktree prune` recovers the state. |
| 131 | |
| 132 | --- |
| 133 | |
| 134 | ## Multi-Repo Downstream Scenarios |
| 135 | |
| 136 | When work spans multiple repositories (e.g., squad-cli changes need squad-sdk changes, or a user's app depends on squad): |
| 137 | |
| 138 | ### Setup |
| 139 | |
| 140 | Clone downstream repos as siblings to the main repo: |
| 141 | |
| 142 | ``` |
| 143 | ~/work/ |
| 144 | squad-pr/ # main repo |
| 145 | squad-sdk/ # downstream dependency |
| 146 | user-app/ # consumer project |
| 147 | ``` |
| 148 | |
| 149 | Each repo gets its own issue branch following its own naming convention. If the downstream repo also uses Squad conventions, use `squad/{issue-number}-{slug}`. |
| 150 | |
| 151 | ### Coordinated PRs |
| 152 | |
| 153 | - Create PRs in each repo independently |
| 154 | - Link them in PR descriptions: |
| 155 | ``` |
| 156 | Closes #42 |
| 157 | |
| 158 | **Depends on:** squad-sdk PR #17 (squad-sdk changes required for this feature) |
| 159 | ``` |
| 160 | - Merge order: dependencies first (e.g., squad-sdk), then dependents (e.g., squad-cli) |
| 161 | |
| 162 | ### Local Linking for Testing |
| 163 | |
| 164 | Before pushing, verify cross-repo changes work together: |
| 165 | |
| 166 | ```bash |
| 167 | # Node.js / npm |
| 168 | cd ../squad-sdk && npm link |
| 169 | cd ../squad-pr && npm link squad-sdk |
| 170 | |
| 171 | # Go |
| 172 | # Use replace directive in go.mod: |
| 173 | # replace github.com/org/squad-sdk => ../squad-sdk |
| 174 | |
| 175 | # Python |
| 176 | cd ../squad-sdk && pip install -e . |
| 177 | ``` |
| 178 | |
| 179 | **Important:** Remove local links before committing. `npm link` and `go replace` are dev-only — CI must use published packages or PR-specific refs. |
| 180 | |
| 181 | ### Worktrees + Multi-Repo |
| 182 | |
| 183 | These compose naturally. You can have: |
| 184 | - Multiple worktrees in the main repo (parallel issues) |
| 185 | - Separate clones for downstream repos |
| 186 | - Each combination operates independently |
| 187 | |
| 188 | --- |
| 189 | |
| 190 | ## Anti-Patterns |
| 191 | |
| 192 | - ❌ Branching from main (branch from dev) |
| 193 | - ❌ PR targeting main directly (target dev) |
| 194 | - ❌ Non-conforming branch names (must be squad/{number}-{slug}) |
| 195 | - ❌ Committing directly to main or dev (use PRs) |
| 196 | - ❌ Switching branches in the main clone while worktrees are active (use worktrees instead) |
| 197 | - ❌ Using worktrees for cross-repo work (use separate clones) |
| 198 | - ❌ Leaving stale worktrees after PR merge (clean up immediately) |
| 199 | |
| 200 | ## Promotion Pipeline |
| 201 | |
| 202 | - dev → insiders: Automated sync on green build |
| 203 | - dev → main: Manual merge when ready for stable release, then tag |
| 204 | - Hotfixes: Branch from main as `hotfix/{slug}`, PR to dev, cherry-pick to main if urgent |