claude-dev-env 1.36.1 → 1.37.0

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 (101) hide show
  1. package/_shared/pr-loop/audit-contract.md +159 -0
  2. package/_shared/pr-loop/code-rules-gate.md +64 -0
  3. package/_shared/pr-loop/fix-protocol.md +37 -0
  4. package/_shared/pr-loop/gh-payloads.md +85 -0
  5. package/_shared/pr-loop/scripts/README.md +20 -0
  6. package/_shared/pr-loop/scripts/_claude_permissions_common.py +234 -0
  7. package/_shared/pr-loop/scripts/code_rules_gate.py +975 -0
  8. package/_shared/pr-loop/scripts/config/__init__.py +0 -0
  9. package/_shared/pr-loop/scripts/config/claude_permissions_constants.py +36 -0
  10. package/_shared/pr-loop/scripts/config/claude_settings_keys_constants.py +11 -0
  11. package/_shared/pr-loop/scripts/config/code_rules_gate_constants.py +56 -0
  12. package/_shared/pr-loop/scripts/config/fix_hookspath_constants.py +25 -0
  13. package/_shared/pr-loop/scripts/config/gh_util_constants.py +31 -0
  14. package/_shared/pr-loop/scripts/config/preflight_constants.py +68 -0
  15. package/_shared/pr-loop/scripts/fix_hookspath.py +260 -0
  16. package/_shared/pr-loop/scripts/gh_util.py +193 -0
  17. package/_shared/pr-loop/scripts/grant_project_claude_permissions.py +130 -0
  18. package/_shared/pr-loop/scripts/preflight.py +449 -0
  19. package/_shared/pr-loop/scripts/revoke_project_claude_permissions.py +156 -0
  20. package/_shared/pr-loop/scripts/tests/conftest.py +51 -0
  21. package/_shared/pr-loop/scripts/tests/test__claude_permissions_common.py +135 -0
  22. package/_shared/pr-loop/scripts/tests/test_claude_permissions_common.py +169 -0
  23. package/_shared/pr-loop/scripts/tests/test_claude_permissions_constants.py +58 -0
  24. package/_shared/pr-loop/scripts/tests/test_claude_settings_keys_constants.py +50 -0
  25. package/_shared/pr-loop/scripts/tests/test_code_rules_gate.py +917 -0
  26. package/_shared/pr-loop/scripts/tests/test_code_rules_gate_constants.py +102 -0
  27. package/_shared/pr-loop/scripts/tests/test_fix_hookspath.py +374 -0
  28. package/_shared/pr-loop/scripts/tests/test_fix_hookspath_constants.py +47 -0
  29. package/_shared/pr-loop/scripts/tests/test_gh_util.py +257 -0
  30. package/_shared/pr-loop/scripts/tests/test_gh_util_constants.py +61 -0
  31. package/_shared/pr-loop/scripts/tests/test_grant_project_claude_permissions.py +49 -0
  32. package/_shared/pr-loop/scripts/tests/test_preflight.py +670 -0
  33. package/_shared/pr-loop/scripts/tests/test_preflight_constants.py +77 -0
  34. package/_shared/pr-loop/scripts/tests/test_revoke_project_claude_permissions.py +49 -0
  35. package/_shared/pr-loop/state-schema.md +81 -0
  36. package/hooks/blocking/code_rules_enforcer.py +269 -23
  37. package/hooks/blocking/test_code_rules_enforcer_unused_imports.py +157 -1
  38. package/hooks/config/test_unused_module_import_constants.py +48 -0
  39. package/hooks/config/unused_module_import_constants.py +41 -0
  40. package/package.json +2 -1
  41. package/skills/bg-agent/SKILL.md +69 -0
  42. package/skills/bugteam/CONSTRAINTS.md +10 -19
  43. package/skills/bugteam/PROMPTS.md +3 -3
  44. package/skills/bugteam/SKILL.md +103 -202
  45. package/skills/bugteam/SKILL_EVALS.md +75 -114
  46. package/skills/bugteam/reference/README.md +2 -4
  47. package/skills/bugteam/reference/design-rationale.md +3 -8
  48. package/skills/bugteam/reference/team-setup.md +11 -19
  49. package/skills/bugteam/reference/teardown-publish-permissions.md +2 -14
  50. package/skills/bugteam/scripts/config/__init__.py +0 -0
  51. package/skills/bugteam/scripts/config/reflow_skill_md_constants.py +12 -0
  52. package/skills/bugteam/scripts/reflow_skill_md.py +51 -47
  53. package/skills/bugteam/sources.md +1 -25
  54. package/skills/bugteam/test_skill_additions.py +4 -13
  55. package/skills/fresh-branch/SKILL.md +71 -0
  56. package/skills/gotcha/SKILL.md +73 -0
  57. package/skills/monitor-open-prs/SKILL.md +4 -37
  58. package/skills/monitor-open-prs/test_skill_contract.py +0 -5
  59. package/skills/pr-converge/SKILL.md +60 -1298
  60. package/skills/pr-converge/reference/convergence-gates.md +118 -0
  61. package/skills/pr-converge/reference/examples.md +76 -0
  62. package/skills/pr-converge/reference/fix-protocol.md +54 -0
  63. package/skills/pr-converge/reference/ground-rules.md +13 -0
  64. package/skills/pr-converge/reference/multi-pr-orchestration.md +204 -0
  65. package/skills/pr-converge/reference/per-tick.md +201 -0
  66. package/skills/pr-converge/reference/state-schema.md +19 -0
  67. package/skills/pr-converge/reference/stop-conditions.md +26 -0
  68. package/skills/pr-converge/scripts/README.md +36 -9
  69. package/skills/pr-converge/scripts/check_pr_mergeability.py +1 -2
  70. package/skills/pr-converge/scripts/config/pr_converge_constants.py +58 -5
  71. package/skills/pr-converge/scripts/config/reflow_skill_md_constants.py +13 -0
  72. package/skills/pr-converge/scripts/config/test_pr_converge_constants.py +0 -24
  73. package/skills/pr-converge/scripts/cursor-agents-continue.ahk +22 -2
  74. package/skills/pr-converge/scripts/fetch_bugbot_inline_comments.py +19 -59
  75. package/skills/pr-converge/scripts/fetch_bugbot_reviews.py +15 -61
  76. package/skills/pr-converge/scripts/fetch_claude_inline_comments.py +70 -0
  77. package/skills/pr-converge/scripts/fetch_claude_reviews.py +61 -0
  78. package/skills/pr-converge/scripts/fetch_copilot_inline_comments.py +19 -61
  79. package/skills/pr-converge/scripts/fetch_copilot_reviews.py +14 -74
  80. package/skills/pr-converge/scripts/reflow_skill_md.py +71 -50
  81. package/skills/pr-converge/scripts/reviewer_fetch_core.py +153 -0
  82. package/skills/pr-converge/scripts/reviewer_specs.py +98 -0
  83. package/skills/pr-converge/scripts/test_cursor_agents_continue.py +65 -0
  84. package/skills/pr-converge/scripts/test_fetch_bugbot_inline_comments.py +107 -6
  85. package/skills/pr-converge/scripts/test_fetch_bugbot_reviews.py +85 -6
  86. package/skills/pr-converge/scripts/test_fetch_claude_inline_comments.py +485 -0
  87. package/skills/pr-converge/scripts/test_fetch_claude_reviews.py +368 -0
  88. package/skills/pr-converge/scripts/test_fetch_copilot_inline_comments.py +74 -6
  89. package/skills/pr-converge/scripts/test_fetch_copilot_reviews.py +94 -8
  90. package/skills/pr-converge/scripts/test_reflow_skill_md.py +162 -0
  91. package/skills/pr-converge/scripts/test_reviewer_fetch_core.py +448 -0
  92. package/skills/pr-converge/scripts/test_reviewer_specs.py +107 -0
  93. package/skills/pr-converge/workflows/schedule-wakeup-loop.md +24 -22
  94. package/skills/bugteam/reference/workflow-path-a-orchestrated-teams.md +0 -113
  95. package/skills/bugteam/reference/workflow-path-b-task-harness.md +0 -48
  96. package/skills/bugteam/test_team_lifecycle.py +0 -103
  97. package/skills/monitor-open-prs/test_team_lifecycle.py +0 -46
  98. package/skills/pr-converge/scripts/open_followup_copilot_pr.py +0 -136
  99. package/skills/pr-converge/scripts/test_open_followup_copilot_pr.py +0 -236
  100. package/skills/pr-converge/test_team_lifecycle.py +0 -56
  101. package/skills/pr-converge/workflows/ahk-auto-continue-loop.md +0 -108
@@ -3,13 +3,9 @@ name: bugteam
3
3
  description: >-
4
4
  Open pull request audit–fix until convergence: CODE_RULES gate, clean-room
5
5
  audit (`code-quality-agent`, opus) and fix (`clean-coder`, opus), per-loop
6
- GitHub reviews, 10-audit cap; grant then revoke `.claude/**`. **Path A** when
7
- `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1` (orchestrated teams, `TeamCreate`).
8
- **Path B** otherwise (Task harness workflow in
9
- `reference/workflow-path-b-task-harness.md`). **This `SKILL.md` holds only
10
- shared steps**; per-path harness lives in `reference/workflow-path-*.md`.
11
- Triggers: '/bugteam', 'run the bug team', 'auto-fix the PR until clean', 'loop
12
- audit and fix'.
6
+ GitHub reviews, 10-audit cap; grant then revoke `.claude/**`. Spawns
7
+ background subagents (`Agent(..., run_in_background=true)`). Triggers: '/bugteam', 'run
8
+ the bug team', 'auto-fix the PR until clean', 'loop audit and fix'.
13
9
  ---
14
10
 
15
11
  # Bugteam
@@ -18,103 +14,22 @@ description: >-
18
14
  `code-quality-agent`, fresh context each loop. **Bugfix:** `clean-coder`. Hard
19
15
  cap: 10 audit loops. Grant `.claude/**` at start, revoke always at end.
20
16
 
21
- **Path routing** picks **Path A** (orchestrated teams) vs **Path B** (Task
22
- harness). Harness execution `TeamCreate`, `Agent`/`Task` spawns,
23
- `SendMessage`, `TeamDelete`, who runs Step 2.5 `gh api` — lives only in
24
- [`reference/workflow-path-a-orchestrated-teams.md`][path-a] and
25
- [`reference/workflow-path-b-task-harness.md`][path-b]. Verbatim doc quotes and
26
- URLs: [`sources.md`](sources.md).
27
-
28
- ## Path routing (mandatory first branch)
29
-
30
- At `/bugteam` entry, evaluate **once** (same rule as pr-converge §Team
31
- infrastructure detection):
32
-
33
- - **Path A** — `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS` set and equals **`1`**
34
- after trim → load and follow
35
- [`reference/workflow-path-a-orchestrated-teams.md`][path-a] for every harness
36
- step (with this `SKILL.md` for shared material).
37
- - **Path B** — otherwise → load and follow
38
- [`reference/workflow-path-b-task-harness.md`][path-b] for every harness step
39
- (with this `SKILL.md` for shared material).
40
-
41
- Shared material is **everything else in this file** plus
42
- [`PROMPTS.md`](PROMPTS.md), [`EXAMPLES.md`](EXAMPLES.md),
43
- [`CONSTRAINTS.md`](CONSTRAINTS.md) — agent types, models, XML, gates, cycle
44
- state machine, Step 2.5 payload shapes, shared teardown `rmtree`, revoke, final
45
- report.
46
-
47
- ## Team lifecycle (Path A only)
48
-
49
- The `TeamCreate` / `TeamDelete` pair has historically been bound to a single
50
- `/bugteam` invocation. That coupling fails when an orchestrator (`pr-converge`
51
- multi-PR mode, `monitor-open-prs`) needs to call `/bugteam` repeatedly inside
52
- one parent session: only one team can be led at a time, and a missed Step 4
53
- leaks the team. To decouple, every Path A invocation reads
54
- `BUGTEAM_TEAM_LIFECYCLE` (defaults to `auto`) and may also read
55
- `BUGTEAM_TEAM_NAME`.
56
-
57
- **`owned`**
58
-
59
- - **Step 2:** `TeamCreate(<computed_team_name>)`. If the runtime returns
60
- `Already leading team "<existing>". A leader can only manage one team at a
61
- time.` → **error**: `Already leading team <existing>; rerun with
62
- BUGTEAM_TEAM_LIFECYCLE=attach BUGTEAM_TEAM_NAME=<existing>`.
63
- - **Step 4:** `TeamDelete()` (lead-owned).
64
- - **Use case:** Pre-decoupling behavior. Use only when you know the session
65
- leads no other team.
66
-
67
- **`attach`**
68
-
69
- - **Step 2:** Require `BUGTEAM_TEAM_NAME`. Treat that team as already-led; do
70
- **not** call `TeamCreate`.
71
- - **Step 4:** **Skip** `TeamDelete` — the orchestrator owns teardown.
72
- - **Use case:** Orchestrators (pr-converge multi-PR, monitor-open-prs) that
73
- explicitly created a team and will tear it down themselves.
74
-
75
- ### `auto` (**default: `auto`**)
76
-
77
- - **Step 2:** Try `TeamCreate(<computed_team_name>)`. On `Already leading team
78
- "<existing>"` → parse `<existing>`, attach (do **not** call `TeamCreate`
79
- again), set `team_owned=false`. On success → set `team_owned=true`.
80
- - **Step 4:** If `team_owned=true` → `TeamDelete()`. Else → **skip**
81
- `TeamDelete`.
82
- - **Use case:** All callers when in doubt. Solo invocations behave like `owned`;
83
- nested or repeated invocations attach safely.
84
-
85
- **`team_owned` flag** — set in Step 2 by all three modes
86
- (`owned` always `true`; `attach` always `false`; `auto` reflects the
87
- `TeamCreate` outcome). Read in Step
88
- 4 to decide whether to call `TeamDelete`. The same flag also gates
89
- `<team_temp_dir>` `rmtree`: when `team_owned=false`, only the per-PR subfolders
90
- this invocation created (`<team_temp_dir>/pr-<N>/`) are removed; the
91
- orchestrator's parent directory survives.
92
-
93
- **Path B note:** Path B does not use `TeamCreate` / `TeamDelete`, so
94
- `BUGTEAM_TEAM_LIFECYCLE` is read but only its `team_temp_dir` cleanup behavior
95
- applies. `team_owned` is treated as `true` by default in Path B; orchestrators
96
- driving Path B that share a temp directory should set
97
- `BUGTEAM_TEAM_LIFECYCLE=attach` so the per-PR subfolder cleanup rule applies.
17
+ Both audit and fix roles run as background subagents
18
+ (`Agent(..., run_in_background=true)`). Verbatim doc quotes and URLs:
19
+ [`sources.md`](sources.md).
98
20
 
99
21
  ## Contents
100
22
 
101
23
  Orchestration lives here; companion files hold prompts, invariants, examples,
102
24
  citations, and domain reference notes. Scan this list before a partial read.
103
25
 
104
- - [Path routing](#path-routing-mandatory-first-branch) — Path A vs Path B
105
- - [Team lifecycle](#team-lifecycle-path-a-only) — `owned` / `attach` / `auto`
106
- modes; orchestrator-owned teams
107
- - [`reference/workflow-path-a-orchestrated-teams.md`][path-a] — Path A harness
108
- (orchestrated teams)
109
- - [`reference/workflow-path-b-task-harness.md`][path-b] — Path B harness (Task
110
- harness)
111
26
  - When this skill applies — refusal cases and trigger conditions
112
27
  - Utility scripts — pre-flight (`scripts/`, executed not inlined)
113
28
  - Pre-audit gate — `validate_content` before each AUDIT
114
29
  - The Process — checklist + Steps 0–6
115
30
  - Step 0 — Grant project permissions
116
31
  - Step 1 — Resolve PR scope
117
- - Step 2 — Path harness + loop state
32
+ - Step 2 — Loop state
118
33
  - Step 2.5 — PR comment lifecycle (per-loop review + fix replies)
119
34
  - Step 3 — Cycle (AUDIT ↔ FIX, exits)
120
35
  - Step 4 — Teardown + clean tree
@@ -140,12 +55,6 @@ Refusals — first match wins; respond with the quoted line exactly and stop:
140
55
  - **Missing subagents.** Before Step 0, confirm `code-quality-agent` and
141
56
  `clean-coder` exist. Else: `Required subagent type <name> not installed.
142
57
  /bugteam needs both code-quality-agent and clean-coder available.`
143
- - **Lead role must be held by the orchestrator.** Run /bugteam in the session
144
- that received the user's command. **Path A:** lead calls `TeamCreate` per
145
- [`reference/workflow-path-a-orchestrated-teams.md`][path-a]; runtime may
146
- return `Already leading team "<name>". A leader can only manage one team at a
147
- time.` **Path B:** lead runs the Task harness per
148
- [`reference/workflow-path-b-task-harness.md`][path-b]; no `TeamCreate`.
149
58
 
150
59
  ## Utility scripts
151
60
 
@@ -189,9 +98,9 @@ the auto-remediation only applies to the `core.hooksPath` failure mode.
189
98
  ```
190
99
  [ ] Step 0: project permissions granted
191
100
  [ ] Step 1: PR scope resolved
192
- [ ] Step 2: loop state set + path harness applied
101
+ [ ] Step 2: loop state set
193
102
  [ ] Step 3: cycle complete (converged | cap reached | stuck | error)
194
- [ ] Step 4: team torn down + working tree clean
103
+ [ ] Step 4: working tree clean
195
104
  [ ] Step 4.5: PR description rewritten (or skip warning logged)
196
105
  [ ] Step 5: project permissions revoked
197
106
  [ ] Step 6: final report printed
@@ -200,9 +109,9 @@ the auto-remediation only applies to the `core.hooksPath` failure mode.
200
109
  ### Step 0: Grant project permissions (once, first)
201
110
 
202
111
  ```bash
203
- python
204
- "${CLAUDE_SKILL_DIR}/../../_shared/pr-loop/scripts/grant_project_claude_permis \
205
- sions.py"
112
+ python \
113
+ "${CLAUDE_SKILL_DIR}/../../_shared/pr-loop/scripts/"\
114
+ "grant_project_claude_permissions.py"
206
115
  ```
207
116
 
208
117
  `${CLAUDE_SKILL_DIR}` is host-substituted before the shell runs (unlike normal
@@ -219,62 +128,59 @@ follows the same downstream rules.
219
128
 
220
129
  Keep: owner/repo, branches, PR number, URL — for all loops.
221
130
 
131
+ **`<run_temp_dir>`:** `Path(tempfile.gettempdir()) / run_name` where
132
+ `run_name = "bugteam-pr-<number>-<YYYYMMDDHHMMSS>"` for a single-PR invocation
133
+ or `"bugteam-<YYYYMMDDHHMMSS>"` for multi-PR. Lead resolves once to an absolute
134
+ path; every shell gets that literal string.
135
+
222
136
  #### Per-PR workspace
223
137
 
224
138
  For each PR in all_prs:
225
139
 
226
- 1. Create `<team_temp_dir>/pr-<N>/`.
227
- 2. Run `git worktree add "<team_temp_dir>/pr-<N>/worktree" origin/<headRef>`.
140
+ 1. Create `<run_temp_dir>/pr-<N>/`.
141
+ 2. Run `git worktree add "<run_temp_dir>/pr-<N>/worktree" origin/<headRef>`.
228
142
  3. Record the absolute worktree path alongside the PR's other fields.
229
143
 
230
- Teammates or Task workers for a PR operate inside that PR's worktree. Step 4
231
- teardown runs `git worktree remove "<team_temp_dir>/pr-<N>/worktree"` for each
232
- PR, then path-specific harness teardown per
233
- [`reference/workflow-path-a-orchestrated-teams.md`][path-a] or
234
- [`reference/workflow-path-b-task-harness.md`][path-b] § Step 4.
235
-
236
- ### Step 2: Path harness + loop state
237
-
238
- Apply the path you chose in [Path
239
- routing](#path-routing-mandatory-first-branch): **Path A** —
240
- [`reference/workflow-path-a-orchestrated-teams.md`][path-a] § Step 2
241
- (`TeamCreate`, team name, `team_temp_dir`, roles, optional Groq FIX,
242
- `--bugbot-retrigger`). **Path B** —
243
- [`reference/workflow-path-b-task-harness.md`][path-b] § Step 2 (no `TeamCreate`
244
- / `TeamDelete`; same worktrees and variables).
144
+ Background subagents for a PR operate inside that PR's worktree. Step 4
145
+ teardown runs `git worktree remove "<run_temp_dir>/pr-<N>/worktree"` for each
146
+ PR before the shared `rmtree`.
245
147
 
246
- Path A also resolves the team lifecycle here per [Team
247
- lifecycle](#team-lifecycle-path-a-only): pick the mode (`owned` / `attach` /
248
- `auto`) from `BUGTEAM_TEAM_LIFECYCLE`, set `team_name` (computed for
249
- `owned`/`auto` create paths; required `BUGTEAM_TEAM_NAME` for `attach` and
250
- `auto`'s attach branch), and set `team_owned` (`true` when `TeamCreate`
251
- succeeded in this invocation; `false` when attaching to an existing team). Step
252
- 4 reads `team_owned` to decide whether to call `TeamDelete`.
148
+ ### Step 2: Loop state
253
149
 
254
- **Loop state (lead; not a single script):**
150
+ **Loop state (lead; not a single script; per-PR):** The variables
151
+ below are tracked independently for each PR in `all_prs`. Each PR has its
152
+ own cycle, state, and exit reason.
255
153
 
256
154
  ```bash
257
155
  loop_count=0
258
156
  last_action="fresh"
259
157
  last_findings='{"total": 0}'
260
158
  audit_log=""
261
- starting_sha="$(git rev-parse HEAD)"
262
- team_name="bugteam-pr-<number>-<YYYYMMDDHHMMSS>"
263
- team_temp_dir="<absolute-path>/<team_name>"
264
- team_owned="true" # set by Step 2 lifecycle resolution; see Team lifecycle table
159
+ run_temp_dir="<absolute-path>/<run_name>"
160
+ starting_sha="$(git -C "<run_temp_dir>/pr-<N>/worktree" rev-parse HEAD)"
265
161
  loop_comment_index=""
266
162
  ```
267
163
 
164
+ **Optional Groq-backed FIX (explicit opt-in only):** when the user explicitly
165
+ sets `BUGTEAM_FIX_IMPLEMENTER=groq-coder` before invocation, spawn the FIX
166
+ subagent with `subagent_type="groq-coder"`. Requires `GROQ_API_KEY` in the
167
+ environment (load from `packages/claude-dev-env/.env` when that file exists;
168
+ prompt the user to create it from `.env.example` if still unset). Any other
169
+ `BUGTEAM_FIX_IMPLEMENTER` value (or unset) uses `clean-coder`.
170
+
171
+ **`--bugbot-retrigger` flag:** when present, the FIX subagent posts a `bugbot
172
+ run` issue comment via the Step 2.5 issue-comments fallback endpoint after
173
+ every successful FIX push, to re-trigger Cursor's bugbot on the new commit.
174
+
268
175
  **`loop_comment_index`:** reset each AUDIT start; filled during AUDIT; FIX
269
176
  consumes for replies; cleared after FIX. Entries: `{loop, finding_id,
270
177
  finding_comment_id, finding_comment_url, used_fallback, fix_status}`.
271
178
 
272
179
  ### Step 2.5: PR comments (one review per loop)
273
180
 
274
- **Who posts:** Path A vs Path B
275
- [`reference/workflow-path-a-orchestrated-teams.md`][path-a] § Step 2.5 and
276
- [`reference/workflow-path-b-task-harness.md`][path-b] § Step 2.5. Payloads and
277
- endpoints below are identical for both paths.
181
+ **Who posts:** the AUDIT subagent posts one `POST .../pulls/<n>/reviews` per
182
+ loop. The FIX subagent posts `.../comments/<id>/replies` after push. The lead's
183
+ only PR write before Step 4.5 is the final description rewrite.
278
184
 
279
185
  Order: audit → buffer → validate anchors vs diff → single review POST.
280
186
  Review body states counts; zero findings → still one review, `comments: []`,
@@ -316,7 +222,7 @@ POST --input -`
316
222
  <tmp_fallback.md | gh api repos/<owner>/<repo>/issues/<number>/comments -X POST
317
223
  --input -`
318
224
 
319
- `<head_sha_at_post_time>`: `git rev-parse HEAD` in teammate cwd immediately
225
+ `<head_sha_at_post_time>`: `git rev-parse HEAD` in subagent cwd immediately
320
226
  before POST.
321
227
 
322
228
  **Review body template (`<tmp_review_body.md>`):**
@@ -342,8 +248,7 @@ before POST.
342
248
 
343
249
  ### Step 3: The cycle
344
250
 
345
- Run the AUDIT-FIX cycle for each PR in all_prs, reusing the same team across
346
- PRs. The 10-loop cap applies per PR. Exit reasons (converged, cap reached,
251
+ Run the AUDIT-FIX cycle for each PR in all_prs. The 10-loop cap applies per PR. Exit reasons (converged, cap reached,
347
252
  stuck, error) are tracked per PR; the final report lists one outcome line per
348
253
  PR.
349
254
 
@@ -360,9 +265,8 @@ dirty so the AUDIT runs against the latest diff with that signal in mind:
360
265
 
361
266
  ```bash
362
267
  dirty_review_count=0
363
- gh api "repos/<owner>/<repo>/pulls/<number>/reviews" \
364
- --jq '[.[] | select(.body | startswith("## /bugteam loop "))] |
365
- sort_by(.submitted_at) | reverse'
268
+ gh api "repos/<owner>/<repo>/pulls/<number>/reviews?per_page=100" --paginate --slurp \
269
+ | jq '[.[][] | select((.body // "") | startswith("## /bugteam loop "))] | sort_by(.submitted_at) | reverse'
366
270
  ```
367
271
 
368
272
  Iterate from index 0 (most recent) toward older entries:
@@ -432,85 +336,84 @@ before the next AUDIT.
432
336
  ### AUDIT action
433
337
 
434
338
  ```bash
435
- mkdir -p "<team_temp_dir>/pr-<N>"
436
- gh pr diff <N> -R <owner>/<repo> > "<team_temp_dir>/pr-<N>/loop-<L>.patch"
339
+ mkdir -p "<run_temp_dir>/pr-<N>"
340
+ gh pr diff <N> -R <owner>/<repo> > "<run_temp_dir>/pr-<N>/loop-<L>.patch"
437
341
  ```
438
342
 
439
- **Spawn and shutdown:** Path A —
440
- [`reference/workflow-path-a-orchestrated-teams.md`][path-a] § AUDIT. Path B —
441
- [`reference/workflow-path-b-task-harness.md`][path-b] § AUDIT. Same
442
- `prompt="<audit XML; see PROMPTS.md>"` and outcome files.
343
+ **Spawn:**
443
344
 
444
- Fresh spawn each loop; Path A teammate context excludes lead history
445
- ([`sources.md`](sources.md) § Teammate context isolation). Path B: fresh Task
446
- per loop for the same clean-room intent. [`PROMPTS.md`](PROMPTS.md): XML +
447
- outcome schema. Lead reads `.bugteam-pr<N>-loop<L>.outcomes.xml`, fills
448
- `loop_comment_index`.
345
+ ```
346
+ Agent(
347
+ subagent_type="code-quality-agent",
348
+ name="bugfind-pr<N>-loop<L>",
349
+ model="opus",
350
+ run_in_background=true,
351
+ description="Bugfind audit PR <N> loop <L>",
352
+ prompt="<audit XML; see PROMPTS.md>"
353
+ )
354
+ ```
355
+
356
+ Fresh spawn each loop for clean-room isolation. Lead awaits the
357
+ background-completion notification, then reads
358
+ `.bugteam-pr<N>-loop<L>.outcomes.xml` from the worktree directory, fills
359
+ `loop_comment_index`. [`PROMPTS.md`](PROMPTS.md): XML + outcome schema.
449
360
 
450
361
  `last_action = "audited"`; append audit line to `audit_log`.
451
362
 
452
363
  **Parallel auditors (`loop_count >= 4`):** gate passes immediately before;
453
- after three full audit/fix rounds without convergence, issue three spawns in
454
- one assistant message (parallel): Path A — three `Agent` calls; Path B —
455
- three `Task` calls full rules in the workflow files § parallel auditors.
456
- `-a` posts
457
- the review and merges outcomes from `-b`/`-c` (read
364
+ after three full audit/fix rounds without convergence, issue three `Agent`
365
+ calls in one assistant message (`run_in_background=true`): `-a` posts the
366
+ review and merges outcomes from `-b`/`-c` (read
458
367
  `.bugteam-pr<N>-loop<L>.outcomes.xml` plus
459
- `<team_temp_dir>/pr-<N>/loop-<L>-b.outcomes.xml` and `...-c...`); merge key
368
+ `<run_temp_dir>/pr-<N>/loop-<L>-b.outcomes.xml` and `...-c...`); merge key
460
369
  `(file, line, category_letter)`; re-id `loopN-K`. `-b`/`-c` write sibling XML
461
- only; prompts must pass literal absolute sibling paths. Shutdown order: Path A
462
- workflow § parallel auditors; Path B: await all three Tasks.
370
+ only; prompts must pass literal absolute sibling paths. Output path
371
+ contract: `-b`/`-c` write to `<run_temp_dir>/pr-<N>/loop-<L>-b.outcomes.xml`
372
+ and `<run_temp_dir>/pr-<N>/loop-<L>-c.outcomes.xml`; `-a` writes to
373
+ `<worktree_path>/.bugteam-pr<N>-loop<L>.outcomes.xml`.
374
+ Lead awaits all three background-completion notifications before merging
375
+ outcomes.
463
376
 
464
377
  ### FIX action
465
378
 
466
- **Spawn and shutdown:** Path A —
467
- [`reference/workflow-path-a-orchestrated-teams.md`][path-a] § FIX. Path B —
468
- [`reference/workflow-path-b-task-harness.md`][path-b] § FIX.
379
+ **Spawn:**
469
380
 
470
- Pass finding comment URLs/ids from `loop_comment_index` in XML. Replies: `Fixed
471
- in <sha>` or `Could not address this loop: <reason>`.
381
+ ```
382
+ Agent(
383
+ subagent_type="clean-coder",
384
+ name="bugfix-pr<N>-loop<L>",
385
+ model="opus",
386
+ run_in_background=true,
387
+ description="Bugfix PR <N> loop <L>",
388
+ prompt="<fix XML; see PROMPTS.md>"
389
+ )
390
+ ```
472
391
 
473
- [`PROMPTS.md`](PROMPTS.md): fix XML + schema. Verify: `git rev-parse HEAD`
474
- advanced; `git fetch origin <branch> && git rev-parse origin/<branch>` matches
392
+ Pass finding comment URLs/ids from `loop_comment_index` in XML. Lead awaits the
393
+ background-completion notification. Replies: `Fixed in <sha>` or `Could not
394
+ address this loop: <reason>`.
395
+
396
+ [`PROMPTS.md`](PROMPTS.md): fix XML + schema. Verify from worktree: `git -C "<run_temp_dir>/pr-<N>/worktree" rev-parse HEAD`
397
+ advanced; `git -C "<run_temp_dir>/pr-<N>/worktree" fetch origin <branch> && git -C "<run_temp_dir>/pr-<N>/worktree" rev-parse origin/<branch>` matches
475
398
  `HEAD`. Unchanged HEAD →
476
- `stuck — bugfix teammate could not address findings`.
399
+ `stuck — bugfix subagent could not address findings`.
477
400
 
478
401
  ### Step 4: Teardown
479
402
 
480
403
  1. For each PR in `all_prs`: `git worktree remove
481
- "<team_temp_dir>/pr-<N>/worktree"` (from Step 1) before tearing down the team
482
- harness — tolerate already-removed worktrees.
483
-
484
- 2. Path-specific harness —
485
- [`reference/workflow-path-a-orchestrated-teams.md`][path-a] § Step 4
486
- (teammate `SendMessage`, `TeamDelete` **only when `team_owned=true`**) or
487
- [`reference/workflow-path-b-task-harness.md`][path-b] § Step 4 (omit those).
488
-
489
- 3. **Windows-safe `rmtree` — gated by `team_owned` from [Team
490
- lifecycle](#team-lifecycle-path-a-only).** The Windows-safe handler strips
491
- the Windows ReadOnly attribute and retries the failing syscall (see
492
- `~/.claude/rules/windows-filesystem-safe.md`).
404
+ "<run_temp_dir>/pr-<N>/worktree"` (from Step 1) tolerate already-removed
405
+ worktrees.
493
406
 
494
- - `team_owned=true` remove the full `<team_temp_dir>`:
407
+ 2. **Windows-safe `rmtree`** strips the Windows ReadOnly attribute and retries
408
+ the failing syscall (see `~/.claude/rules/windows-filesystem-safe.md`).
409
+ Remove the full `<run_temp_dir>`:
495
410
 
496
- ```bash
411
+ ```bash
497
412
  python -c "import os, shutil, stat, sys; \
498
413
  h = lambda f, p, *_: (os.chmod(p, stat.S_IWRITE), f(p)); \
499
- shutil.rmtree(r'<team_temp_dir>', **({'onexc': h} if sys.version_info >= (3, 12)
414
+ shutil.rmtree(r'<run_temp_dir>', **({'onexc': h} if sys.version_info >= (3, 12)
500
415
  else {'onerror': h}))"
501
- ```
502
-
503
- - `team_owned=false` (attach mode) → for each PR in `all_prs`, remove only
504
- that PR's `<team_temp_dir>/pr-<N>/` subfolder. The orchestrator-owned
505
- parent `<team_temp_dir>` survives so the next attached invocation can write
506
- its own per-PR subfolders without colliding.
507
-
508
- ```bash
509
- python -c "import os, shutil, stat, sys; \
510
- h = lambda f, p, *_: (os.chmod(p, stat.S_IWRITE), f(p)); \
511
- shutil.rmtree(r'<team_temp_dir>/pr-<N>', **({'onexc': h} if sys.version_info >=
512
- (3, 12) else {'onerror': h}))"
513
- ```
416
+ ```
514
417
 
515
418
  ### Step 4.5: PR description
516
419
 
@@ -532,9 +435,9 @@ On failure: log in final report; continue to Step 5.
532
435
  ### Step 5: Revoke permissions (always)
533
436
 
534
437
  ```bash
535
- python
536
- "${CLAUDE_SKILL_DIR}/../../_shared/pr-loop/scripts/revoke_project_claude_permi \
537
- ssions.py"
438
+ python \
439
+ "${CLAUDE_SKILL_DIR}/../../_shared/pr-loop/scripts/"\
440
+ "revoke_project_claude_permissions.py"
538
441
  ```
539
442
 
540
443
  Removes Step 0 grant — run even if Step 4 partially failed (log separately).
@@ -572,7 +475,5 @@ See [`reference/README.md`](reference/README.md).
572
475
 
573
476
  See [`sources.md`](sources.md).
574
477
 
575
- [path-a]: reference/workflow-path-a-orchestrated-teams.md
576
- [path-b]: reference/workflow-path-b-task-harness.md
577
478
  [path-code-rules]: ../../_shared/pr-loop/code-rules-gate.md
578
479
  [path-scripts-readme]: ../../_shared/pr-loop/scripts/README.md