@bradygaster/squad-sdk 0.8.25 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (228) hide show
  1. package/README.md +296 -296
  2. package/dist/adapter/client.d.ts +17 -0
  3. package/dist/adapter/client.d.ts.map +1 -1
  4. package/dist/adapter/client.js +101 -1
  5. package/dist/adapter/client.js.map +1 -1
  6. package/dist/agents/history-shadow.d.ts.map +1 -1
  7. package/dist/agents/history-shadow.js +129 -62
  8. package/dist/agents/history-shadow.js.map +1 -1
  9. package/dist/agents/index.d.ts +1 -0
  10. package/dist/agents/index.d.ts.map +1 -1
  11. package/dist/agents/index.js +2 -0
  12. package/dist/agents/index.js.map +1 -1
  13. package/dist/agents/model-selector.d.ts +2 -0
  14. package/dist/agents/model-selector.d.ts.map +1 -1
  15. package/dist/agents/model-selector.js +41 -35
  16. package/dist/agents/model-selector.js.map +1 -1
  17. package/dist/agents/personal.d.ts +35 -0
  18. package/dist/agents/personal.d.ts.map +1 -0
  19. package/dist/agents/personal.js +67 -0
  20. package/dist/agents/personal.js.map +1 -0
  21. package/dist/build/github-dist.js +42 -42
  22. package/dist/builders/index.d.ts +3 -2
  23. package/dist/builders/index.d.ts.map +1 -1
  24. package/dist/builders/index.js +28 -0
  25. package/dist/builders/index.js.map +1 -1
  26. package/dist/builders/types.d.ts +13 -0
  27. package/dist/builders/types.d.ts.map +1 -1
  28. package/dist/config/init.d.ts +8 -0
  29. package/dist/config/init.d.ts.map +1 -1
  30. package/dist/config/init.js +304 -193
  31. package/dist/config/init.js.map +1 -1
  32. package/dist/config/models.d.ts +112 -0
  33. package/dist/config/models.d.ts.map +1 -1
  34. package/dist/config/models.js +329 -18
  35. package/dist/config/models.js.map +1 -1
  36. package/dist/coordinator/index.js +2 -2
  37. package/dist/coordinator/index.js.map +1 -1
  38. package/dist/index.d.ts +8 -3
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +7 -2
  41. package/dist/index.js.map +1 -1
  42. package/dist/platform/azure-devops.d.ts +42 -0
  43. package/dist/platform/azure-devops.d.ts.map +1 -1
  44. package/dist/platform/azure-devops.js +75 -0
  45. package/dist/platform/azure-devops.js.map +1 -1
  46. package/dist/platform/comms-file-log.d.ts.map +1 -1
  47. package/dist/platform/comms-file-log.js +2 -1
  48. package/dist/platform/comms-file-log.js.map +1 -1
  49. package/dist/platform/index.d.ts +2 -1
  50. package/dist/platform/index.d.ts.map +1 -1
  51. package/dist/platform/index.js +1 -0
  52. package/dist/platform/index.js.map +1 -1
  53. package/dist/ralph/capabilities.d.ts +67 -0
  54. package/dist/ralph/capabilities.d.ts.map +1 -0
  55. package/dist/ralph/capabilities.js +111 -0
  56. package/dist/ralph/capabilities.js.map +1 -0
  57. package/dist/ralph/index.d.ts +2 -0
  58. package/dist/ralph/index.d.ts.map +1 -1
  59. package/dist/ralph/index.js +6 -5
  60. package/dist/ralph/index.js.map +1 -1
  61. package/dist/ralph/rate-limiting.d.ts +99 -0
  62. package/dist/ralph/rate-limiting.d.ts.map +1 -0
  63. package/dist/ralph/rate-limiting.js +170 -0
  64. package/dist/ralph/rate-limiting.js.map +1 -0
  65. package/dist/resolution.d.ts +24 -2
  66. package/dist/resolution.d.ts.map +1 -1
  67. package/dist/resolution.js +106 -6
  68. package/dist/resolution.js.map +1 -1
  69. package/dist/roles/catalog-categories.d.ts +146 -0
  70. package/dist/roles/catalog-categories.d.ts.map +1 -0
  71. package/dist/roles/catalog-categories.js +374 -0
  72. package/dist/roles/catalog-categories.js.map +1 -0
  73. package/dist/roles/catalog-engineering.d.ts +212 -0
  74. package/dist/roles/catalog-engineering.d.ts.map +1 -0
  75. package/dist/roles/catalog-engineering.js +549 -0
  76. package/dist/roles/catalog-engineering.js.map +1 -0
  77. package/dist/roles/catalog.d.ts +24 -0
  78. package/dist/roles/catalog.d.ts.map +1 -0
  79. package/dist/roles/catalog.js +28 -0
  80. package/dist/roles/catalog.js.map +1 -0
  81. package/dist/roles/index.d.ts +69 -0
  82. package/dist/roles/index.d.ts.map +1 -0
  83. package/dist/roles/index.js +197 -0
  84. package/dist/roles/index.js.map +1 -0
  85. package/dist/roles/types.d.ts +87 -0
  86. package/dist/roles/types.d.ts.map +1 -0
  87. package/dist/roles/types.js +14 -0
  88. package/dist/roles/types.js.map +1 -0
  89. package/dist/runtime/benchmarks.js +5 -5
  90. package/dist/runtime/benchmarks.js.map +1 -1
  91. package/dist/runtime/constants.d.ts +2 -2
  92. package/dist/runtime/constants.d.ts.map +1 -1
  93. package/dist/runtime/constants.js +5 -3
  94. package/dist/runtime/constants.js.map +1 -1
  95. package/dist/runtime/cross-squad.d.ts +118 -0
  96. package/dist/runtime/cross-squad.d.ts.map +1 -0
  97. package/dist/runtime/cross-squad.js +234 -0
  98. package/dist/runtime/cross-squad.js.map +1 -0
  99. package/dist/runtime/otel-init.d.ts +24 -17
  100. package/dist/runtime/otel-init.d.ts.map +1 -1
  101. package/dist/runtime/otel-init.js +29 -20
  102. package/dist/runtime/otel-init.js.map +1 -1
  103. package/dist/runtime/otel-metrics.d.ts +5 -0
  104. package/dist/runtime/otel-metrics.d.ts.map +1 -1
  105. package/dist/runtime/otel-metrics.js +54 -0
  106. package/dist/runtime/otel-metrics.js.map +1 -1
  107. package/dist/runtime/rework.d.ts +71 -0
  108. package/dist/runtime/rework.d.ts.map +1 -0
  109. package/dist/runtime/rework.js +107 -0
  110. package/dist/runtime/rework.js.map +1 -0
  111. package/dist/runtime/scheduler.d.ts +128 -0
  112. package/dist/runtime/scheduler.d.ts.map +1 -0
  113. package/dist/runtime/scheduler.js +427 -0
  114. package/dist/runtime/scheduler.js.map +1 -0
  115. package/dist/runtime/squad-observer.d.ts.map +1 -1
  116. package/dist/runtime/squad-observer.js +4 -0
  117. package/dist/runtime/squad-observer.js.map +1 -1
  118. package/dist/runtime/streaming.d.ts +2 -0
  119. package/dist/runtime/streaming.d.ts.map +1 -1
  120. package/dist/runtime/streaming.js +6 -0
  121. package/dist/runtime/streaming.js.map +1 -1
  122. package/dist/runtime/telemetry.d.ts +2 -0
  123. package/dist/runtime/telemetry.d.ts.map +1 -1
  124. package/dist/runtime/telemetry.js +6 -0
  125. package/dist/runtime/telemetry.js.map +1 -1
  126. package/dist/sharing/consult.d.ts +2 -2
  127. package/dist/sharing/consult.js +83 -83
  128. package/dist/sharing/consult.js.map +1 -1
  129. package/dist/sharing/export.d.ts.map +1 -1
  130. package/dist/sharing/export.js +17 -4
  131. package/dist/sharing/export.js.map +1 -1
  132. package/dist/skills/handler-types.d.ts +271 -0
  133. package/dist/skills/handler-types.d.ts.map +1 -0
  134. package/dist/skills/handler-types.js +31 -0
  135. package/dist/skills/handler-types.js.map +1 -0
  136. package/dist/skills/index.d.ts +3 -0
  137. package/dist/skills/index.d.ts.map +1 -1
  138. package/dist/skills/index.js +3 -0
  139. package/dist/skills/index.js.map +1 -1
  140. package/dist/skills/skill-script-loader.d.ts +65 -0
  141. package/dist/skills/skill-script-loader.d.ts.map +1 -0
  142. package/dist/skills/skill-script-loader.js +227 -0
  143. package/dist/skills/skill-script-loader.js.map +1 -0
  144. package/dist/skills/skill-source.d.ts.map +1 -1
  145. package/dist/skills/skill-source.js +5 -1
  146. package/dist/skills/skill-source.js.map +1 -1
  147. package/dist/tools/index.d.ts +10 -1
  148. package/dist/tools/index.d.ts.map +1 -1
  149. package/dist/tools/index.js +49 -8
  150. package/dist/tools/index.js.map +1 -1
  151. package/dist/upstream/resolver.d.ts.map +1 -1
  152. package/dist/upstream/resolver.js +14 -5
  153. package/dist/upstream/resolver.js.map +1 -1
  154. package/package.json +34 -3
  155. package/templates/casting/Futurama.json +10 -0
  156. package/templates/casting-history.json +4 -4
  157. package/templates/casting-policy.json +37 -35
  158. package/templates/casting-reference.md +104 -0
  159. package/templates/casting-registry.json +3 -3
  160. package/templates/ceremonies.md +41 -41
  161. package/templates/charter.md +53 -53
  162. package/templates/constraint-tracking.md +38 -38
  163. package/templates/cooperative-rate-limiting.md +229 -0
  164. package/templates/copilot-instructions.md +46 -46
  165. package/templates/history.md +10 -10
  166. package/templates/identity/now.md +9 -9
  167. package/templates/identity/wisdom.md +15 -15
  168. package/templates/issue-lifecycle.md +412 -0
  169. package/templates/keda-scaler.md +164 -0
  170. package/templates/machine-capabilities.md +75 -0
  171. package/templates/mcp-config.md +90 -98
  172. package/templates/multi-agent-format.md +28 -28
  173. package/templates/orchestration-log.md +27 -27
  174. package/templates/package.json +3 -0
  175. package/templates/plugin-marketplace.md +49 -49
  176. package/templates/ralph-circuit-breaker.md +313 -0
  177. package/templates/ralph-triage.js +543 -0
  178. package/templates/raw-agent-output.md +37 -37
  179. package/templates/roster.md +60 -60
  180. package/templates/routing.md +39 -54
  181. package/templates/run-output.md +50 -50
  182. package/templates/schedule.json +19 -0
  183. package/templates/scribe-charter.md +119 -119
  184. package/templates/skill.md +24 -24
  185. package/templates/skills/agent-collaboration/SKILL.md +42 -0
  186. package/templates/skills/agent-conduct/SKILL.md +24 -0
  187. package/templates/skills/architectural-proposals/SKILL.md +151 -0
  188. package/templates/skills/ci-validation-gates/SKILL.md +84 -0
  189. package/templates/skills/cli-wiring/SKILL.md +47 -0
  190. package/templates/skills/client-compatibility/SKILL.md +89 -0
  191. package/templates/skills/cross-squad/SKILL.md +114 -0
  192. package/templates/skills/distributed-mesh/SKILL.md +287 -0
  193. package/templates/skills/distributed-mesh/mesh.json.example +30 -0
  194. package/templates/skills/distributed-mesh/sync-mesh.ps1 +111 -0
  195. package/templates/skills/distributed-mesh/sync-mesh.sh +104 -0
  196. package/templates/skills/docs-standards/SKILL.md +71 -0
  197. package/templates/skills/economy-mode/SKILL.md +114 -0
  198. package/templates/skills/external-comms/SKILL.md +329 -0
  199. package/templates/skills/gh-auth-isolation/SKILL.md +183 -0
  200. package/templates/skills/git-workflow/SKILL.md +204 -0
  201. package/templates/skills/github-multi-account/SKILL.md +95 -0
  202. package/templates/skills/history-hygiene/SKILL.md +36 -0
  203. package/templates/skills/humanizer/SKILL.md +105 -0
  204. package/templates/skills/init-mode/SKILL.md +102 -0
  205. package/templates/skills/model-selection/SKILL.md +117 -0
  206. package/templates/skills/nap/SKILL.md +24 -0
  207. package/templates/skills/personal-squad/SKILL.md +57 -0
  208. package/templates/skills/project-conventions/SKILL.md +56 -56
  209. package/templates/skills/release-process/SKILL.md +423 -0
  210. package/templates/skills/reskill/SKILL.md +92 -0
  211. package/templates/skills/reviewer-protocol/SKILL.md +79 -0
  212. package/templates/skills/secret-handling/SKILL.md +200 -0
  213. package/templates/skills/session-recovery/SKILL.md +155 -0
  214. package/templates/skills/squad-conventions/SKILL.md +69 -0
  215. package/templates/skills/test-discipline/SKILL.md +37 -0
  216. package/templates/skills/windows-compatibility/SKILL.md +74 -0
  217. package/templates/squad.agent.md +1287 -1146
  218. package/templates/workflows/squad-ci.yml +24 -24
  219. package/templates/workflows/squad-docs.yml +54 -50
  220. package/templates/workflows/squad-heartbeat.yml +171 -316
  221. package/templates/workflows/squad-insider-release.yml +61 -61
  222. package/templates/workflows/squad-issue-assign.yml +161 -161
  223. package/templates/workflows/squad-label-enforce.yml +181 -181
  224. package/templates/workflows/squad-preview.yml +55 -55
  225. package/templates/workflows/squad-promote.yml +120 -120
  226. package/templates/workflows/squad-release.yml +77 -77
  227. package/templates/workflows/squad-triage.yml +260 -260
  228. package/templates/workflows/sync-squad-labels.yml +169 -169
@@ -0,0 +1,412 @@
1
+ # Issue Lifecycle — Repo Connection & PR Flow
2
+
3
+ Reference for connecting Squad to a repository and managing the issue→branch→PR→merge lifecycle.
4
+
5
+ ## Repo Connection Format
6
+
7
+ When connecting Squad to an issue tracker, store the connection in `.squad/team.md`:
8
+
9
+ ```markdown
10
+ ## Issue Source
11
+
12
+ **Repository:** {owner}/{repo}
13
+ **Connected:** {date}
14
+ **Platform:** {GitHub | Azure DevOps | Planner}
15
+ **Filters:**
16
+ - Labels: `{label-filter}`
17
+ - Project: `{project-name}` (ADO/Planner only)
18
+ - Plan: `{plan-id}` (Planner only)
19
+ ```
20
+
21
+ **Detection triggers:**
22
+ - User says "connect to {repo}"
23
+ - User says "monitor {repo} for issues"
24
+ - Ralph is activated without an issue source
25
+
26
+ ## Platform-Specific Issue States
27
+
28
+ Each platform tracks issue lifecycle differently. Squad normalizes these into a common board state.
29
+
30
+ ### GitHub
31
+
32
+ | GitHub State | GitHub API Fields | Squad Board State |
33
+ |--------------|-------------------|-------------------|
34
+ | Open, no assignee | `state: open`, `assignee: null` | `untriaged` |
35
+ | Open, assigned, no branch | `state: open`, `assignee: @user`, no linked PR | `assigned` |
36
+ | Open, branch exists | `state: open`, linked branch exists | `inProgress` |
37
+ | Open, PR opened | `state: open`, PR exists, `reviewDecision: null` | `needsReview` |
38
+ | Open, PR approved | `state: open`, PR `reviewDecision: APPROVED` | `readyToMerge` |
39
+ | Open, changes requested | `state: open`, PR `reviewDecision: CHANGES_REQUESTED` | `changesRequested` |
40
+ | Open, CI failure | `state: open`, PR `statusCheckRollup: FAILURE` | `ciFailure` |
41
+ | Closed | `state: closed` | `done` |
42
+
43
+ **Issue labels used by Squad:**
44
+ - `squad` — Issue is in Squad backlog
45
+ - `squad:{member}` — Assigned to specific agent
46
+ - `squad:untriaged` — Needs triage
47
+ - `go:needs-research` — Needs investigation before implementation
48
+ - `priority:p{N}` — Priority level (0=critical, 1=high, 2=medium, 3=low)
49
+ - `next-up` — Queued for next agent pickup
50
+
51
+ **Branch naming convention:**
52
+ ```
53
+ squad/{issue-number}-{kebab-case-slug}
54
+ ```
55
+ Example: `squad/42-fix-login-validation`
56
+
57
+ ### Azure DevOps
58
+
59
+ | ADO State | Squad Board State |
60
+ |-----------|-------------------|
61
+ | New | `untriaged` |
62
+ | Active, no branch | `assigned` |
63
+ | Active, branch exists | `inProgress` |
64
+ | Active, PR opened | `needsReview` |
65
+ | Active, PR approved | `readyToMerge` |
66
+ | Resolved | `done` |
67
+ | Closed | `done` |
68
+
69
+ **Work item tags used by Squad:**
70
+ - `squad` — Work item is in Squad backlog
71
+ - `squad:{member}` — Assigned to specific agent
72
+
73
+ **Branch naming convention:**
74
+ ```
75
+ squad/{work-item-id}-{kebab-case-slug}
76
+ ```
77
+ Example: `squad/1234-add-auth-module`
78
+
79
+ ### Microsoft Planner
80
+
81
+ Planner does not have native Git integration. Squad uses Planner for task tracking and GitHub/ADO for code management.
82
+
83
+ | Planner Status | Squad Board State |
84
+ |----------------|-------------------|
85
+ | Not Started | `untriaged` |
86
+ | In Progress, no PR | `inProgress` |
87
+ | In Progress, PR opened | `needsReview` |
88
+ | Completed | `done` |
89
+
90
+ **Planner→Git workflow:**
91
+ 1. Task created in Planner bucket
92
+ 2. Agent reads task from Planner
93
+ 3. Agent creates branch in GitHub/ADO repo
94
+ 4. Agent opens PR referencing Planner task ID in description
95
+ 5. Agent marks task as "Completed" when PR merges
96
+
97
+ ## Issue → Branch → PR → Merge Lifecycle
98
+
99
+ ### 1. Issue Assignment (Triage)
100
+
101
+ **Trigger:** Ralph detects an untriaged issue or user manually assigns work.
102
+
103
+ **Actions:**
104
+ 1. Read `.squad/routing.md` to determine which agent should handle the issue
105
+ 2. Apply `squad:{member}` label (GitHub) or tag (ADO)
106
+ 3. Transition issue to `assigned` state
107
+ 4. Optionally spawn agent immediately if issue is high-priority
108
+
109
+ **Issue read command:**
110
+ ```bash
111
+ # GitHub
112
+ gh issue view {number} --json number,title,body,labels,assignees
113
+
114
+ # Azure DevOps
115
+ az boards work-item show --id {id} --output json
116
+ ```
117
+
118
+ ### 2. Branch Creation (Start Work)
119
+
120
+ **Trigger:** Agent accepts issue assignment and begins work.
121
+
122
+ **Actions:**
123
+ 1. Ensure working on latest base branch (usually `main` or `dev`)
124
+ 2. Create feature branch using Squad naming convention
125
+ 3. Transition issue to `inProgress` state
126
+
127
+ **Branch creation commands:**
128
+
129
+ **Standard (single-agent, no parallelism):**
130
+ ```bash
131
+ git checkout main && git pull && git checkout -b squad/{issue-number}-{slug}
132
+ ```
133
+
134
+ **Worktree (parallel multi-agent):**
135
+ ```bash
136
+ git worktree add ../worktrees/{issue-number} -b squad/{issue-number}-{slug}
137
+ cd ../worktrees/{issue-number}
138
+ ```
139
+
140
+ > **Note:** Worktree support is in progress (#525). Current implementation uses standard checkout.
141
+
142
+ ### 3. Implementation & Commit
143
+
144
+ **Actions:**
145
+ 1. Agent makes code changes
146
+ 2. Commits reference the issue number
147
+ 3. Pushes branch to remote
148
+
149
+ **Commit message format:**
150
+ ```
151
+ {type}({scope}): {description} (#{issue-number})
152
+
153
+ {detailed explanation if needed}
154
+
155
+ {breaking change notice if applicable}
156
+
157
+ Closes #{issue-number}
158
+
159
+ Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
160
+ ```
161
+
162
+ **Commit types:** `feat`, `fix`, `docs`, `refactor`, `test`, `chore`, `perf`, `style`, `build`, `ci`
163
+
164
+ **Push command:**
165
+ ```bash
166
+ git push -u origin squad/{issue-number}-{slug}
167
+ ```
168
+
169
+ ### 4. PR Creation
170
+
171
+ **Trigger:** Agent completes implementation and is ready for review.
172
+
173
+ **Actions:**
174
+ 1. Open PR from feature branch to base branch
175
+ 2. Reference issue in PR description
176
+ 3. Apply labels if needed
177
+ 4. Transition issue to `needsReview` state
178
+
179
+ **PR creation commands:**
180
+
181
+ **GitHub:**
182
+ ```bash
183
+ gh pr create --title "{title}" \
184
+ --body "Closes #{issue-number}\n\n{description}" \
185
+ --head squad/{issue-number}-{slug} \
186
+ --base main
187
+ ```
188
+
189
+ **Azure DevOps:**
190
+ ```bash
191
+ az repos pr create --title "{title}" \
192
+ --description "Closes #{work-item-id}\n\n{description}" \
193
+ --source-branch squad/{work-item-id}-{slug} \
194
+ --target-branch main
195
+ ```
196
+
197
+ **PR description template:**
198
+ ```markdown
199
+ Closes #{issue-number}
200
+
201
+ ## Summary
202
+ {what changed}
203
+
204
+ ## Changes
205
+ - {change 1}
206
+ - {change 2}
207
+
208
+ ## Testing
209
+ {how this was tested}
210
+
211
+ {If working as a squad member:}
212
+ Working as {member} ({role})
213
+
214
+ {If needs human review:}
215
+ ⚠️ This task was flagged as "needs review" — please have a squad member review before merging.
216
+ ```
217
+
218
+ ### 5. PR Review & Updates
219
+
220
+ **Review states:**
221
+ - **Approved** → `readyToMerge`
222
+ - **Changes requested** → `changesRequested`
223
+ - **CI failure** → `ciFailure`
224
+
225
+ **When changes are requested:**
226
+ 1. Agent addresses feedback
227
+ 2. Commits fixes to the same branch
228
+ 3. Pushes updates
229
+ 4. Requests re-review
230
+
231
+ **Update workflow:**
232
+ ```bash
233
+ # Make changes
234
+ git add .
235
+ git commit -m "fix: address review feedback"
236
+ git push
237
+ ```
238
+
239
+ **Re-request review (GitHub):**
240
+ ```bash
241
+ gh pr ready {pr-number}
242
+ ```
243
+
244
+ ### 6. PR Merge
245
+
246
+ **Trigger:** PR is approved and CI passes.
247
+
248
+ **Merge strategies:**
249
+
250
+ **GitHub (merge commit):**
251
+ ```bash
252
+ gh pr merge {pr-number} --merge --delete-branch
253
+ ```
254
+
255
+ **GitHub (squash):**
256
+ ```bash
257
+ gh pr merge {pr-number} --squash --delete-branch
258
+ ```
259
+
260
+ **Azure DevOps:**
261
+ ```bash
262
+ az repos pr update --id {pr-id} --status completed --delete-source-branch true
263
+ ```
264
+
265
+ **Post-merge actions:**
266
+ 1. Issue automatically closes (if "Closes #{number}" is in PR description)
267
+ 2. Feature branch is deleted
268
+ 3. Squad board state transitions to `done`
269
+ 4. Worktree cleanup (if worktree was used — #525)
270
+
271
+ ### 7. Cleanup
272
+
273
+ **Standard workflow cleanup:**
274
+ ```bash
275
+ git checkout main
276
+ git pull
277
+ git branch -d squad/{issue-number}-{slug}
278
+ ```
279
+
280
+ **Worktree cleanup (future, #525):**
281
+ ```bash
282
+ cd {original-cwd}
283
+ git worktree remove ../worktrees/{issue-number}
284
+ ```
285
+
286
+ ## Spawn Prompt Additions for Issue Work
287
+
288
+ When spawning an agent to work on an issue, include this context block:
289
+
290
+ ```markdown
291
+ ## ISSUE CONTEXT
292
+
293
+ **Issue:** #{number} — {title}
294
+ **Platform:** {GitHub | Azure DevOps | Planner}
295
+ **Repository:** {owner}/{repo}
296
+ **Assigned to:** {member}
297
+
298
+ **Description:**
299
+ {issue body}
300
+
301
+ **Labels/Tags:**
302
+ {labels}
303
+
304
+ **Acceptance Criteria:**
305
+ {criteria if present in issue}
306
+
307
+ **Branch:** `squad/{issue-number}-{slug}`
308
+
309
+ **Your task:**
310
+ {specific directive to the agent}
311
+
312
+ **After completing work:**
313
+ 1. Commit with message referencing issue number
314
+ 2. Push branch
315
+ 3. Open PR using:
316
+ ```
317
+ gh pr create --title "{title}" --body "Closes #{number}\n\n{description}" --head squad/{issue-number}-{slug} --base {base-branch}
318
+ ```
319
+ 4. Report PR URL to coordinator
320
+ ```
321
+
322
+ ## Ralph's Role in Issue Lifecycle
323
+
324
+ Ralph (the work monitor) continuously checks issue and PR state:
325
+
326
+ 1. **Triage:** Detects untriaged issues, assigns `squad:{member}` labels
327
+ 2. **Spawn:** Launches agents for assigned issues
328
+ 3. **Monitor:** Tracks PR state transitions (needsReview → changesRequested → readyToMerge)
329
+ 4. **Merge:** Automatically merges approved PRs
330
+ 5. **Cleanup:** Marks issues as done when PRs merge
331
+
332
+ **Ralph's work-check cycle:**
333
+ ```
334
+ Scan → Categorize → Dispatch → Watch → Report → Loop
335
+ ```
336
+
337
+ See `.squad/templates/ralph-reference.md` for Ralph's full lifecycle.
338
+
339
+ ## PR Review Handling
340
+
341
+ ### Automated Approval (CI-only projects)
342
+
343
+ If the project has no human reviewers configured:
344
+ 1. PR opens
345
+ 2. CI runs
346
+ 3. If CI passes, Ralph auto-merges
347
+ 4. Issue closes
348
+
349
+ ### Human Review Required
350
+
351
+ If the project requires human approval:
352
+ 1. PR opens
353
+ 2. Human reviewer is notified (GitHub/ADO notifications)
354
+ 3. Reviewer approves or requests changes
355
+ 4. If approved + CI passes, Ralph merges
356
+ 5. If changes requested, agent addresses feedback
357
+
358
+ ### Squad Member Review
359
+
360
+ If the issue was assigned to a squad member and they authored the PR:
361
+ 1. Another squad member reviews (conflict of interest avoidance)
362
+ 2. Original author is locked out from re-working rejected code (rejection lockout)
363
+ 3. Reviewer can approve edits or reject outright
364
+
365
+ ## Common Issue Lifecycle Patterns
366
+
367
+ ### Pattern 1: Quick Fix (Single Agent, No Review)
368
+ ```
369
+ Issue created → Assigned to agent → Branch created → Code fixed →
370
+ PR opened → CI passes → Auto-merged → Issue closed
371
+ ```
372
+
373
+ ### Pattern 2: Feature Development (Human Review)
374
+ ```
375
+ Issue created → Assigned to agent → Branch created → Feature implemented →
376
+ PR opened → Human reviews → Changes requested → Agent fixes →
377
+ Re-reviewed → Approved → Merged → Issue closed
378
+ ```
379
+
380
+ ### Pattern 3: Research-Then-Implement
381
+ ```
382
+ Issue created → Labeled `go:needs-research` → Research agent spawned →
383
+ Research documented → Research PR merged → Implementation issue created →
384
+ Implementation agent spawned → Feature built → PR merged
385
+ ```
386
+
387
+ ### Pattern 4: Parallel Multi-Agent (Future, #525)
388
+ ```
389
+ Epic issue created → Decomposed into sub-issues → Each sub-issue assigned →
390
+ Multiple agents work in parallel worktrees → PRs opened concurrently →
391
+ All PRs reviewed → All PRs merged → Epic closed
392
+ ```
393
+
394
+ ## Anti-Patterns
395
+
396
+ - ❌ Creating branches without linking to an issue
397
+ - ❌ Committing without issue reference in message
398
+ - ❌ Opening PRs without "Closes #{number}" in description
399
+ - ❌ Merging PRs before CI passes
400
+ - ❌ Leaving feature branches undeleted after merge
401
+ - ❌ Using `checkout -b` when parallel agents are active (causes working directory conflicts)
402
+ - ❌ Manually transitioning issue states — let the platform and Squad automation handle it
403
+ - ❌ Skipping the branch naming convention — breaks Ralph's tracking logic
404
+
405
+ ## Migration Notes
406
+
407
+ **v0.8.x → v0.9.x (Worktree Support):**
408
+ - `checkout -b` → `git worktree add` for parallel agents
409
+ - Worktree cleanup added to post-merge flow
410
+ - `TEAM_ROOT` passing to agents to support worktree-aware state resolution
411
+
412
+ This template will be updated as worktree lifecycle support lands in #525.
@@ -0,0 +1,164 @@
1
+ # KEDA External Scaler for GitHub Issue-Driven Agent Autoscaling
2
+
3
+ > Scale agent pods to zero when idle, up when work arrives — driven by GitHub Issues.
4
+
5
+ ## Overview
6
+
7
+ When running Squad on Kubernetes, agent pods sit idle when no work exists. [KEDA](https://keda.sh) (Kubernetes Event-Driven Autoscaler) solves this for queue-based workloads, but GitHub Issues isn't a native KEDA trigger.
8
+
9
+ The `keda-copilot-scaler` is a KEDA External Scaler (gRPC) that bridges this gap:
10
+ 1. Polls GitHub API for issues matching specific labels (e.g., `squad:copilot`)
11
+ 2. Reports queue depth as a KEDA metric
12
+ 3. Handles rate limits gracefully (Retry-After, exponential backoff)
13
+ 4. Supports composite scaling decisions
14
+
15
+ ## Quick Start
16
+
17
+ ### Prerequisites
18
+ - Kubernetes cluster with KEDA v2.x installed
19
+ - GitHub personal access token (PAT) with `repo` scope
20
+ - Helm 3.x
21
+
22
+ ### 1. Install the Scaler
23
+
24
+ ```bash
25
+ helm install keda-copilot-scaler oci://ghcr.io/tamirdresher/keda-copilot-scaler \
26
+ --namespace squad-scaler --create-namespace \
27
+ --set github.owner=YOUR_ORG \
28
+ --set github.repo=YOUR_REPO \
29
+ --set github.token=YOUR_TOKEN
30
+ ```
31
+
32
+ Or with Kustomize:
33
+ ```bash
34
+ kubectl apply -k https://github.com/tamirdresher/keda-copilot-scaler/deploy/kustomize
35
+ ```
36
+
37
+ ### 2. Create a ScaledObject
38
+
39
+ ```yaml
40
+ apiVersion: keda.sh/v1alpha1
41
+ kind: ScaledObject
42
+ metadata:
43
+ name: picard-scaler
44
+ namespace: squad
45
+ spec:
46
+ scaleTargetRef:
47
+ name: picard-deployment
48
+ minReplicaCount: 0 # Scale to zero when idle
49
+ maxReplicaCount: 3
50
+ pollingInterval: 30 # Check every 30 seconds
51
+ cooldownPeriod: 300 # Wait 5 minutes before scaling down
52
+ triggers:
53
+ - type: external
54
+ metadata:
55
+ scalerAddress: keda-copilot-scaler.squad-scaler.svc.cluster.local:6000
56
+ owner: your-org
57
+ repo: your-repo
58
+ labels: squad:copilot # Only count issues with this label
59
+ threshold: "1" # Scale up when >= 1 issue exists
60
+ ```
61
+
62
+ ### 3. Verify
63
+
64
+ ```bash
65
+ # Check the scaler is running
66
+ kubectl get pods -n squad-scaler
67
+
68
+ # Check ScaledObject status
69
+ kubectl get scaledobject picard-scaler -n squad
70
+
71
+ # Watch scaling events
72
+ kubectl get events -n squad --watch
73
+ ```
74
+
75
+ ## Scaling Behavior
76
+
77
+ | Open Issues | Target Replicas | Behavior |
78
+ |------------|----------------|----------|
79
+ | 0 | 0 | Scale to zero — save resources |
80
+ | 1–3 | 1 | Single agent handles work |
81
+ | 4–10 | 2 | Scale up for parallel processing |
82
+ | 10+ | 3 (max) | Maximum parallelism |
83
+
84
+ The threshold and max replicas are configurable per ScaledObject.
85
+
86
+ ## Rate Limit Awareness
87
+
88
+ The scaler tracks GitHub API rate limits:
89
+ - Reads `X-RateLimit-Remaining` from API responses
90
+ - Backs off when quota is low (< 100 remaining)
91
+ - Reports rate limit metrics as secondary KEDA triggers
92
+ - Never exhausts API quota from polling
93
+
94
+ ## Integration with Squad
95
+
96
+ ### Machine Capabilities (#514)
97
+
98
+ Combine with machine capability labels for intelligent scheduling:
99
+
100
+ ```yaml
101
+ # Only scale pods on GPU-capable nodes
102
+ spec:
103
+ template:
104
+ spec:
105
+ nodeSelector:
106
+ node.squad.dev/gpu: "true"
107
+ triggers:
108
+ - type: external
109
+ metadata:
110
+ labels: squad:copilot,needs:gpu
111
+ ```
112
+
113
+ ### Cooperative Rate Limiting (#515)
114
+
115
+ The scaler exposes rate limit metrics that feed into the cooperative rate limiting system:
116
+ - Current `X-RateLimit-Remaining` value
117
+ - Predicted time to exhaustion (from predictive circuit breaker)
118
+ - Can return 0 target replicas when rate limited → pods scale to zero
119
+
120
+ ## Architecture
121
+
122
+ ```
123
+ GitHub API KEDA Kubernetes
124
+ ┌──────────┐ ┌──────────┐ ┌──────────────┐
125
+ │ Issues │◄── poll ──►│ Scaler │──metrics─►│ HPA / KEDA │
126
+ │ (REST) │ │ (gRPC) │ │ Controller │
127
+ └──────────┘ └──────────┘ └──────┬───────┘
128
+
129
+ scale up/down
130
+
131
+ ┌──────▼───────┐
132
+ │ Agent Pods │
133
+ │ (0–N replicas)│
134
+ └──────────────┘
135
+ ```
136
+
137
+ ## Configuration Reference
138
+
139
+ | Parameter | Default | Description |
140
+ |-----------|---------|-------------|
141
+ | `github.owner` | — | Repository owner |
142
+ | `github.repo` | — | Repository name |
143
+ | `github.token` | — | GitHub PAT with `repo` scope |
144
+ | `github.labels` | `squad:copilot` | Comma-separated label filter |
145
+ | `scaler.port` | `6000` | gRPC server port |
146
+ | `scaler.pollInterval` | `30s` | GitHub API polling interval |
147
+ | `scaler.rateLimitThreshold` | `100` | Stop polling below this remaining |
148
+
149
+ ## Source & Contributing
150
+
151
+ - **Repository:** [tamirdresher/keda-copilot-scaler](https://github.com/tamirdresher/keda-copilot-scaler)
152
+ - **License:** MIT
153
+ - **Language:** Go
154
+ - **Tests:** 51 passing (unit + integration)
155
+ - **CI:** GitHub Actions
156
+
157
+ The scaler is maintained as a standalone project. PRs and issues welcome.
158
+
159
+ ## References
160
+
161
+ - [KEDA External Scalers](https://keda.sh/docs/latest/concepts/external-scalers/) — KEDA documentation
162
+ - [Squad on AKS](https://github.com/tamirdresher/squad-on-aks) — Full Kubernetes deployment example
163
+ - [Machine Capabilities](machine-capabilities.md) — Capability-based routing (#514)
164
+ - [Cooperative Rate Limiting](cooperative-rate-limiting.md) — Multi-agent rate management (#515)
@@ -0,0 +1,75 @@
1
+ # Machine Capability Discovery & Label-Based Routing
2
+
3
+ > Enable Ralph to skip issues requiring capabilities the current machine lacks.
4
+
5
+ ## Overview
6
+
7
+ When running Squad across multiple machines (laptops, DevBoxes, GPU servers, Kubernetes nodes), each machine has different tooling. The capability system lets you declare what each machine can do, and Ralph automatically routes work accordingly.
8
+
9
+ ## Setup
10
+
11
+ ### 1. Create a Capabilities Manifest
12
+
13
+ Create `~/.squad/machine-capabilities.json` (user-wide) or `.squad/machine-capabilities.json` (project-local):
14
+
15
+ ```json
16
+ {
17
+ "machine": "MY-LAPTOP",
18
+ "capabilities": ["browser", "personal-gh", "onedrive"],
19
+ "missing": ["gpu", "docker", "azure-speech"],
20
+ "lastUpdated": "2026-03-22T00:00:00Z"
21
+ }
22
+ ```
23
+
24
+ ### 2. Label Issues with Requirements
25
+
26
+ Add `needs:*` labels to issues that require specific capabilities:
27
+
28
+ | Label | Meaning |
29
+ |-------|---------|
30
+ | `needs:browser` | Requires Playwright / browser automation |
31
+ | `needs:gpu` | Requires NVIDIA GPU |
32
+ | `needs:personal-gh` | Requires personal GitHub account |
33
+ | `needs:emu-gh` | Requires Enterprise Managed User account |
34
+ | `needs:azure-cli` | Requires authenticated Azure CLI |
35
+ | `needs:docker` | Requires Docker daemon |
36
+ | `needs:onedrive` | Requires OneDrive sync |
37
+ | `needs:teams-mcp` | Requires Teams MCP tools |
38
+
39
+ Custom capabilities are supported — any `needs:X` label works if `X` is in the machine's `capabilities` array.
40
+
41
+ ### 3. Run Ralph
42
+
43
+ ```bash
44
+ squad watch --interval 5
45
+ ```
46
+
47
+ Ralph will log skipped issues:
48
+ ```
49
+ ⏭️ Skipping #42 "Train ML model" — missing: gpu
50
+ ✓ Triaged #43 "Fix CSS layout" → Picard (routing-rule)
51
+ ```
52
+
53
+ ## How It Works
54
+
55
+ 1. Ralph loads `machine-capabilities.json` at startup
56
+ 2. For each open issue, Ralph extracts `needs:*` labels
57
+ 3. If any required capability is missing, the issue is skipped
58
+ 4. Issues without `needs:*` labels are always processed (opt-in system)
59
+
60
+ ## Kubernetes Integration
61
+
62
+ On Kubernetes, machine capabilities map to node labels:
63
+
64
+ ```yaml
65
+ # Node labels (set by capability DaemonSet or manually)
66
+ node.squad.dev/gpu: "true"
67
+ node.squad.dev/browser: "true"
68
+
69
+ # Pod spec uses nodeSelector
70
+ spec:
71
+ nodeSelector:
72
+ node.squad.dev/gpu: "true"
73
+ ```
74
+
75
+ A DaemonSet can run capability discovery on each node and maintain labels automatically. See the [squad-on-aks](https://github.com/tamirdresher/squad-on-aks) project for a complete Kubernetes deployment example.