claude-dev-env 1.34.1 → 1.36.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 (148) hide show
  1. package/agents/clean-coder.md +109 -1
  2. package/agents/docs-agent.md +1 -1
  3. package/agents/project-docs-analyzer.md +0 -1
  4. package/agents/skill-to-agent-converter.md +0 -1
  5. package/bin/install.mjs +28 -8
  6. package/bin/install.test.mjs +9 -1
  7. package/commands/initialize.md +0 -1
  8. package/commands/readability-review.md +4 -4
  9. package/commands/review-plan.md +2 -4
  10. package/commands/stubcheck.md +1 -2
  11. package/docs/CODE_RULES.md +3 -0
  12. package/docs/agents-md-alignment-plan.md +123 -0
  13. package/hooks/blocking/code_rules_enforcer.py +686 -60
  14. package/hooks/blocking/es_exe_path_rewriter.py +10 -4
  15. package/hooks/blocking/test_code_rules_enforcer.py +273 -39
  16. package/hooks/blocking/test_code_rules_enforcer_annotations.py +97 -0
  17. package/hooks/blocking/test_code_rules_enforcer_banned_identifier.py +106 -0
  18. package/hooks/blocking/test_code_rules_enforcer_cap_meta.py +173 -0
  19. package/hooks/blocking/test_code_rules_enforcer_collection_prefix.py +328 -0
  20. package/hooks/blocking/test_code_rules_enforcer_config_path.py +0 -20
  21. package/hooks/blocking/test_code_rules_enforcer_constant_equality.py +33 -11
  22. package/hooks/blocking/test_code_rules_enforcer_existence_checks.py +0 -18
  23. package/hooks/blocking/test_code_rules_enforcer_hardcoded_user_path.py +291 -0
  24. package/hooks/blocking/test_code_rules_enforcer_inline_literal_collections.py +155 -0
  25. package/hooks/blocking/test_code_rules_enforcer_loop_variable_naming.py +194 -0
  26. package/hooks/blocking/test_code_rules_enforcer_naming_pattern.py +49 -13
  27. package/hooks/blocking/test_code_rules_enforcer_skip_decorators.py +0 -26
  28. package/hooks/blocking/test_code_rules_enforcer_string_magic.py +234 -0
  29. package/hooks/blocking/test_code_rules_enforcer_sys_path_insert.py +157 -0
  30. package/hooks/blocking/test_code_rules_enforcer_unused_imports.py +244 -0
  31. package/hooks/blocking/test_es_exe_path_rewriter.py +81 -3
  32. package/hooks/blocking/test_windows_rmtree_blocker.py +120 -8
  33. package/hooks/blocking/windows_rmtree_blocker.py +23 -6
  34. package/hooks/config/banned_identifiers_constants.py +24 -0
  35. package/hooks/config/hardcoded_user_path_constants.py +12 -0
  36. package/hooks/config/hook_log_extractor_constants.py +1 -1
  37. package/hooks/config/pre_tool_use_stdin.py +48 -0
  38. package/hooks/config/setup_project_paths_constants.py +4 -0
  39. package/hooks/config/stuttering_check_config.py +14 -0
  40. package/hooks/config/stuttering_import_binding_constants.py +11 -0
  41. package/hooks/config/sys_path_insert_constants.py +4 -0
  42. package/hooks/config/test_banned_identifiers_constants.py +48 -0
  43. package/hooks/config/test_hardcoded_user_path_constants.py +78 -0
  44. package/hooks/config/test_hook_log_extractor_constants.py +3 -3
  45. package/hooks/config/test_pre_tool_use_stdin.py +80 -0
  46. package/hooks/config/unused_module_import_constants.py +7 -0
  47. package/hooks/config/windows_rmtree_blocker_constants.py +3 -0
  48. package/hooks/diagnostic/hook_log_stop_wrapper.py +7 -4
  49. package/hooks/git-hooks/config.py +3 -3
  50. package/hooks/git-hooks/test_gate_utils.py +10 -10
  51. package/hooks/mypy.ini +2 -0
  52. package/package.json +1 -1
  53. package/rules/gh-paginate.md +125 -0
  54. package/skills/bugteam/CONSTRAINTS.md +12 -6
  55. package/skills/bugteam/PROMPTS.md +0 -39
  56. package/skills/bugteam/SKILL.md +93 -125
  57. package/skills/bugteam/SKILL_EVALS.md +25 -23
  58. package/skills/bugteam/reference/README.md +2 -0
  59. package/skills/bugteam/reference/audit-and-teammates.md +2 -2
  60. package/skills/bugteam/reference/copilot-gap-analysis.md +12 -0
  61. package/skills/bugteam/reference/teardown-publish-permissions.md +1 -1
  62. package/skills/bugteam/reference/workflow-path-a-orchestrated-teams.md +113 -0
  63. package/skills/bugteam/reference/workflow-path-b-task-harness.md +48 -0
  64. package/skills/bugteam/test_skill_additions.py +13 -4
  65. package/skills/bugteam/test_team_lifecycle.py +94 -0
  66. package/skills/findbugs/SKILL.md +3 -3
  67. package/skills/fixbugs/SKILL.md +4 -4
  68. package/skills/monitor-open-prs/SKILL.md +32 -2
  69. package/skills/monitor-open-prs/test_team_lifecycle.py +46 -0
  70. package/skills/pr-converge/SKILL.md +576 -95
  71. package/skills/pr-converge/scripts/README.md +145 -0
  72. package/skills/pr-converge/scripts/caller-window-pid.ps1 +86 -0
  73. package/skills/pr-converge/scripts/check_pr_mergeability.py +79 -0
  74. package/skills/pr-converge/scripts/config/pr_converge_constants.py +65 -0
  75. package/skills/pr-converge/scripts/config/test_pr_converge_constants.py +176 -0
  76. package/skills/pr-converge/scripts/cursor-agents-continue-caller.cmd +9 -0
  77. package/skills/pr-converge/scripts/cursor-agents-continue-stop-others.ps1 +16 -0
  78. package/skills/pr-converge/scripts/cursor-agents-continue.ahk +172 -0
  79. package/skills/pr-converge/scripts/cursor-agents-continue.cmd +2 -0
  80. package/skills/pr-converge/scripts/evict_cached_config_modules.py +20 -0
  81. package/skills/pr-converge/scripts/fetch_bugbot_inline_comments.py +110 -0
  82. package/skills/pr-converge/scripts/fetch_bugbot_reviews.py +103 -0
  83. package/skills/pr-converge/scripts/fetch_copilot_inline_comments.py +112 -0
  84. package/skills/pr-converge/scripts/fetch_copilot_reviews.py +121 -0
  85. package/skills/pr-converge/scripts/mark_pr_ready.py +54 -0
  86. package/skills/pr-converge/scripts/open_followup_copilot_pr.py +136 -0
  87. package/skills/pr-converge/scripts/post-bugbot-run.helpers.ps1 +49 -0
  88. package/skills/pr-converge/scripts/post-bugbot-run.ps1 +33 -0
  89. package/skills/pr-converge/scripts/reply_to_inline_comment.py +84 -0
  90. package/skills/pr-converge/scripts/request_copilot_review.py +71 -0
  91. package/skills/pr-converge/scripts/resolve_pr_head.py +58 -0
  92. package/skills/pr-converge/scripts/review_field_helpers.py +43 -0
  93. package/skills/pr-converge/scripts/test_check_pr_mergeability.py +126 -0
  94. package/skills/pr-converge/scripts/test_evict_cached_config_modules.py +22 -0
  95. package/skills/pr-converge/scripts/test_fetch_bugbot_inline_comments.py +342 -0
  96. package/skills/pr-converge/scripts/test_fetch_bugbot_reviews.py +220 -0
  97. package/skills/pr-converge/scripts/test_fetch_copilot_inline_comments.py +372 -0
  98. package/skills/pr-converge/scripts/test_fetch_copilot_reviews.py +280 -0
  99. package/skills/pr-converge/scripts/test_mark_pr_ready.py +69 -0
  100. package/skills/pr-converge/scripts/test_open_followup_copilot_pr.py +236 -0
  101. package/skills/pr-converge/scripts/test_post_bugbot_run.py +195 -0
  102. package/skills/pr-converge/scripts/test_reply_to_inline_comment.py +159 -0
  103. package/skills/pr-converge/scripts/test_request_copilot_review.py +101 -0
  104. package/skills/pr-converge/scripts/test_resolve_pr_head.py +79 -0
  105. package/skills/pr-converge/scripts/test_review_field_helpers.py +80 -0
  106. package/skills/pr-converge/scripts/test_trigger_bugbot.py +139 -0
  107. package/skills/pr-converge/scripts/test_view_pr_context.py +111 -0
  108. package/skills/pr-converge/scripts/trigger_bugbot.py +77 -0
  109. package/skills/pr-converge/scripts/view_pr_context.py +47 -0
  110. package/skills/pr-converge/test_team_lifecycle.py +47 -0
  111. package/skills/pr-converge/workflows/ahk-auto-continue-loop.md +108 -0
  112. package/skills/pr-converge/workflows/schedule-wakeup-loop.md +37 -0
  113. package/skills/qbug/SKILL.md +4 -4
  114. package/skills/qbug/test_qbug_skill_post_fix_audit.py +2 -2
  115. package/skills/resume-review/SKILL.md +261 -0
  116. package/agents/agent-writer.md +0 -157
  117. package/agents/config-centralizer.md +0 -686
  118. package/agents/config-extraction-agent.md +0 -225
  119. package/agents/doc-orchestrator.md +0 -47
  120. package/agents/docx-agent.md +0 -211
  121. package/agents/magic-value-eliminator-agent.md +0 -72
  122. package/agents/mandatory-agent-workflow-agent.md +0 -88
  123. package/agents/parallel-workflow-coordinator.md +0 -779
  124. package/agents/pdf-agent.md +0 -302
  125. package/agents/project-context-loader.md +0 -238
  126. package/agents/readability-review-agent.md +0 -76
  127. package/agents/refactoring-specialist.md +0 -69
  128. package/agents/right-sized-engineer.md +0 -129
  129. package/agents/session-continuity-manager.md +0 -53
  130. package/agents/stub-detector-agent.md +0 -140
  131. package/agents/tdd-test-writer.md +0 -62
  132. package/agents/test-data-builder.md +0 -68
  133. package/agents/tooling-builder.md +0 -78
  134. package/agents/validation-expert.md +0 -71
  135. package/agents/xlsx-agent.md +0 -169
  136. package/skills/bugteam/scripts/README.md +0 -58
  137. package/skills/bugteam/scripts/_claude_permissions_common.py +0 -219
  138. package/skills/bugteam/scripts/bugteam_code_rules_gate.py +0 -633
  139. package/skills/bugteam/scripts/bugteam_fix_hookspath.py +0 -260
  140. package/skills/bugteam/scripts/bugteam_preflight.py +0 -201
  141. package/skills/bugteam/scripts/config/bugteam_fix_hookspath_constants.py +0 -17
  142. package/skills/bugteam/scripts/grant_project_claude_permissions.py +0 -109
  143. package/skills/bugteam/scripts/revoke_project_claude_permissions.py +0 -135
  144. package/skills/bugteam/scripts/test_bugteam_code_rules_gate.py +0 -271
  145. package/skills/bugteam/scripts/test_bugteam_fix_hookspath.py +0 -267
  146. package/skills/bugteam/scripts/test_bugteam_preflight.py +0 -189
  147. package/skills/bugteam/scripts/test_claude_permissions_common.py +0 -44
  148. /package/skills/{bugteam → pr-converge}/scripts/config/__init__.py +0 -0
@@ -1,34 +1,59 @@
1
1
  ---
2
2
  name: bugteam
3
3
  description: >-
4
- Claude Code agent team on the open pull request: run the CODE_RULES gate,
5
- spawn a fresh clean-room audit (code-quality-agent, opus) and a fix pass
6
- (clean-coder, opus), post per-loop GitHub review threads from teammates,
7
- stop at zero findings or a 10-audit safety cap. Grants then revokes
8
- `.claude/**` edit permission around the run. SKILL.md is the orchestration
9
- checklist; `reference/` holds expanded prose by domain; CONSTRAINTS,
10
- PROMPTS, EXAMPLES, and sources are companion files. Requires
11
- CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1. Triggers: '/bugteam',
12
- 'run the bug team', 'auto-fix the PR until clean', 'loop audit and fix'.
4
+ Open pull request audit–fix until convergence: CODE_RULES gate, clean-room
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**
7
+ when `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1` (orchestrated teams, `TeamCreate`).
8
+ **Path B** otherwise (Task harness workflow in `reference/workflow-path-b-task-harness.md`).
9
+ **This `SKILL.md` holds only shared steps**; per-path harness lives in `reference/workflow-path-*.md`.
10
+ Triggers: '/bugteam', 'run the bug team', 'auto-fix the PR until clean', 'loop audit and fix'.
13
11
  ---
14
12
 
15
13
  # Bugteam
16
14
 
17
- **Core principle:** Agent team runs audit–fix until convergence. Bugfind: clean-room audit (fresh context each loop). Bugfix: addresses findings. Hard cap: 10 audit loops. Grant `.claude/**` permissions at start, revoke always at end.
15
+ **Core principle:** Audit–fix until convergence. **Bugfind:** `code-quality-agent`, fresh context each loop. **Bugfix:** `clean-coder`. Hard cap: 10 audit loops. Grant `.claude/**` at start, revoke always at end.
18
16
 
19
- Subagents fold back into the lead context; agent-team teammates do notthat separation is the clean-room guarantee. Verbatim doc quotes and URLs: [`sources.md`](sources.md).
17
+ **Path routing** picks **Path A** (orchestrated teams) vs **Path B** (Task harness). Harness execution `TeamCreate`, `Agent`/`Task` spawns, `SendMessage`, `TeamDelete`, who runs Step 2.5 `gh api` — lives only in [`reference/workflow-path-a-orchestrated-teams.md`](reference/workflow-path-a-orchestrated-teams.md) and [`reference/workflow-path-b-task-harness.md`](reference/workflow-path-b-task-harness.md). Verbatim doc quotes and URLs: [`sources.md`](sources.md).
18
+
19
+ ## Path routing (mandatory first branch)
20
+
21
+ At `/bugteam` entry, evaluate **once** (same rule as pr-converge §Team infrastructure detection):
22
+
23
+ - **Path A** — `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS` set and equals **`1`** after trim → load and follow [`reference/workflow-path-a-orchestrated-teams.md`](reference/workflow-path-a-orchestrated-teams.md) for every harness step (with this `SKILL.md` for shared material).
24
+ - **Path B** — otherwise → load and follow [`reference/workflow-path-b-task-harness.md`](reference/workflow-path-b-task-harness.md) for every harness step (with this `SKILL.md` for shared material).
25
+
26
+ Shared material is **everything else in this file** plus [`PROMPTS.md`](PROMPTS.md), [`EXAMPLES.md`](EXAMPLES.md), [`CONSTRAINTS.md`](CONSTRAINTS.md) — agent types, models, XML, gates, cycle state machine, Step 2.5 payload shapes, shared teardown `rmtree`, revoke, final report.
27
+
28
+ ## Team lifecycle (Path A only)
29
+
30
+ The `TeamCreate` / `TeamDelete` pair has historically been bound to a single `/bugteam` invocation. That coupling fails when an orchestrator (`pr-converge` multi-PR mode, `monitor-open-prs`) needs to call `/bugteam` repeatedly inside one parent session: only one team can be led at a time, and a missed Step 4 leaks the team. To decouple, every Path A invocation reads `BUGTEAM_TEAM_LIFECYCLE` (defaults to `auto`) and may also read `BUGTEAM_TEAM_NAME`.
31
+
32
+ | Mode | Step 2 behavior | Step 4 behavior | Use case |
33
+ | --- | --- | --- | --- |
34
+ | `owned` | `TeamCreate(<computed_team_name>)`. If the runtime returns `Already leading team "<existing>". A leader can only manage one team at a time.` → **error**: `Already leading team <existing>; rerun with BUGTEAM_TEAM_LIFECYCLE=attach BUGTEAM_TEAM_NAME=<existing>`. | `TeamDelete()` (lead-owned). | Pre-decoupling behavior. Use only when you know the session leads no other team. |
35
+ | `attach` | Require `BUGTEAM_TEAM_NAME`. Treat that team as already-led; do **not** call `TeamCreate`. | **Skip** `TeamDelete` — the orchestrator owns teardown. | Orchestrators (pr-converge multi-PR, monitor-open-prs) that explicitly created a team and will tear it down themselves. |
36
+ | `auto` (**default: `auto`**) | Try `TeamCreate(<computed_team_name>)`. On `Already leading team "<existing>"` → parse `<existing>`, attach (do **not** call `TeamCreate` again), set `team_owned=false`. On success → set `team_owned=true`. | If `team_owned=true` → `TeamDelete()`. Else → **skip** `TeamDelete`. | All callers when in doubt. Solo invocations behave like `owned`; nested or repeated invocations attach safely. |
37
+
38
+ **`team_owned` flag** — set in Step 2 by all three modes (`owned` always `true`; `attach` always `false`; `auto` reflects the `TeamCreate` outcome). Read in Step 4 to decide whether to call `TeamDelete`. The same flag also gates `<team_temp_dir>` `rmtree`: when `team_owned=false`, only the per-PR subfolders this invocation created (`<team_temp_dir>/pr-<N>/`) are removed; the orchestrator's parent directory survives.
39
+
40
+ **Path B note:** Path B does not use `TeamCreate` / `TeamDelete`, so `BUGTEAM_TEAM_LIFECYCLE` is read but only its `team_temp_dir` cleanup behavior applies. `team_owned` is treated as `true` by default in Path B; orchestrators driving Path B that share a temp directory should set `BUGTEAM_TEAM_LIFECYCLE=attach` so the per-PR subfolder cleanup rule applies.
20
41
 
21
42
  ## Contents
22
43
 
23
44
  Orchestration lives here; companion files hold prompts, invariants, examples, citations, and domain reference notes. Scan this list before a partial read.
24
45
 
25
- - When this skill applies refusal cases (4) and trigger conditions
46
+ - [Path routing](#path-routing-mandatory-first-branch)Path A vs Path B
47
+ - [Team lifecycle](#team-lifecycle-path-a-only) — `owned` / `attach` / `auto` modes; orchestrator-owned teams
48
+ - [`reference/workflow-path-a-orchestrated-teams.md`](reference/workflow-path-a-orchestrated-teams.md) — Path A harness (orchestrated teams)
49
+ - [`reference/workflow-path-b-task-harness.md`](reference/workflow-path-b-task-harness.md) — Path B harness (Task harness)
50
+ - When this skill applies — refusal cases and trigger conditions
26
51
  - Utility scripts — pre-flight (`scripts/`, executed not inlined)
27
52
  - Pre-audit gate — `validate_content` before each AUDIT
28
53
  - The Process — checklist + Steps 0–6
29
54
  - Step 0 — Grant project permissions
30
55
  - Step 1 — Resolve PR scope
31
- - Step 2 — Create the agent team
56
+ - Step 2 — Path harness + loop state
32
57
  - Step 2.5 — PR comment lifecycle (per-loop review + fix replies)
33
58
  - Step 3 — Cycle (AUDIT ↔ FIX, exits)
34
59
  - Step 4 — Teardown + clean tree
@@ -47,20 +72,19 @@ Orchestration lives here; companion files hold prompts, invariants, examples, ci
47
72
 
48
73
  Refusals — first match wins; respond with the quoted line exactly and stop:
49
74
 
50
- - **Agent teams not enabled.** Check `claude config get env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS` and `~/.claude/settings.json`. If neither is `"1"`: `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 not set. /bugteam requires the agent teams feature. See https://code.claude.com/docs/en/agent-teams#enable-agent-teams.`
51
75
  - **No PR or upstream diff.** `No PR or upstream diff. /bugteam needs a target.`
52
76
  - **Dirty tree.** `Uncommitted changes detected. Stash, commit, or revert before /bugteam.`
53
77
  - **Missing subagents.** Before Step 0, confirm `code-quality-agent` and `clean-coder` exist. Else: `Required subagent type <name> not installed. /bugteam needs both code-quality-agent and clean-coder available.`
54
- - **Lead role must be held by the orchestrator.** Run /bugteam in the session that received the user's command. The orchestrator session calls TeamCreate directly. Runtime confirms a single lead per team: `Already leading team "<name>". A leader can only manage one team at a time.`
78
+ - **Lead role must be held by the orchestrator.** Run /bugteam in the session that received the user's command. **Path A:** lead calls `TeamCreate` per [`reference/workflow-path-a-orchestrated-teams.md`](reference/workflow-path-a-orchestrated-teams.md); runtime may return `Already leading team "<name>". A leader can only manage one team at a time.` **Path B:** lead runs the Task harness per [`reference/workflow-path-b-task-harness.md`](reference/workflow-path-b-task-harness.md); no `TeamCreate`.
55
79
 
56
80
  ## Utility scripts
57
81
 
58
- Shell-heavy steps live under `scripts/` (run, do not paste into context). Utility scripts are **executed**, not loaded as primary context ([`sources.md`](sources.md) § Progressive disclosure and utility scripts). [`scripts/README.md`](scripts/README.md).
82
+ Shell-heavy steps live under [`_shared/pr-loop/scripts/`](../../_shared/pr-loop/scripts/) (run, do not paste into context). Utility scripts are **executed**, not loaded as primary context ([`sources.md`](sources.md) § Progressive disclosure and utility scripts).
59
83
 
60
84
  ### Pre-flight (before Step 0)
61
85
 
62
86
  ```bash
63
- python "${CLAUDE_SKILL_DIR}/scripts/bugteam_preflight.py"
87
+ python "${CLAUDE_SKILL_DIR}/../../_shared/pr-loop/scripts/preflight.py"
64
88
  ```
65
89
 
66
90
  Non-zero → fix before grant. `BUGTEAM_PREFLIGHT_SKIP=1` emergency only. `--pre-commit` if `.pre-commit-config.yaml` exists.
@@ -68,10 +92,10 @@ Non-zero → fix before grant. `BUGTEAM_PREFLIGHT_SKIP=1` emergency only. `--pre
68
92
  **Auto-remediation for `core.hooksPath`:** when preflight fails with stderr containing `core.hooksPath` (the message starts with `bugteam_preflight: core.hooksPath is`, or `Git-side CODE_RULES enforcement is not active`), Claude must auto-invoke the fix script — do not fall through to `AskUserQuestion`, do not punt to the user, do not ask for confirmation:
69
93
 
70
94
  ```bash
71
- python "${CLAUDE_SKILL_DIR}/scripts/bugteam_fix_hookspath.py"
95
+ python "${CLAUDE_SKILL_DIR}/../../_shared/pr-loop/scripts/fix_hookspath.py"
72
96
  ```
73
97
 
74
- The fix script removes any non-canonical local-scope override on the active repository, sets the global `core.hooksPath` to `~/.claude/hooks/git-hooks` if missing or wrong, and re-runs `bugteam_preflight.py`. Its exit code becomes the preflight outcome. Exit 0 → continue to Step 0. Non-zero only when the canonical hooks directory is missing (run `npx claude-dev-env .` first) or `git config --global` writes are blocked. Other preflight failures (pytest, pre-commit) still require manual fixes — the auto-remediation only applies to the `core.hooksPath` failure mode.
98
+ The fix script removes any non-canonical local-scope override on the active repository, sets the global `core.hooksPath` to `~/.claude/hooks/git-hooks` if missing or wrong, and re-runs `preflight.py`. Its exit code becomes the preflight outcome. Exit 0 → continue to Step 0. Non-zero only when the canonical hooks directory is missing (run `npx claude-dev-env .` first) or `git config --global` writes are blocked. Other preflight failures (pytest, pre-commit) still require manual fixes — the auto-remediation only applies to the `core.hooksPath` failure mode.
75
99
 
76
100
  ## The Process
77
101
 
@@ -80,10 +104,8 @@ The fix script removes any non-canonical local-scope override on the active repo
80
104
  ```
81
105
  [ ] Step 0: project permissions granted
82
106
  [ ] Step 1: PR scope resolved
83
- [ ] Step 2: agent team created + loop state set
84
- [ ] Step 2.6: INITIAL standards review against cumulative PR diff
107
+ [ ] Step 2: loop state set + path harness applied
85
108
  [ ] Step 3: cycle complete (converged | cap reached | stuck | error)
86
- [ ] Step 3.5: FINAL standards review against cumulative PR diff
87
109
  [ ] Step 4: team torn down + working tree clean
88
110
  [ ] Step 4.5: PR description rewritten (or skip warning logged)
89
111
  [ ] Step 5: project permissions revoked
@@ -93,7 +115,7 @@ The fix script removes any non-canonical local-scope override on the active repo
93
115
  ### Step 0: Grant project permissions (once, first)
94
116
 
95
117
  ```bash
96
- python "${CLAUDE_SKILL_DIR}/scripts/grant_project_claude_permissions.py"
118
+ python "${CLAUDE_SKILL_DIR}/../../_shared/pr-loop/scripts/grant_project_claude_permissions.py"
97
119
  ```
98
120
 
99
121
  `${CLAUDE_SKILL_DIR}` is host-substituted before the shell runs (unlike normal env expansion). Idempotent writes to `~/.claude/settings.json` from repo root. Non-zero → stop. Revoke in Step 5 on every exit path.
@@ -112,42 +134,25 @@ For each PR in all_prs:
112
134
  2. Run `git worktree add "<team_temp_dir>/pr-<N>/worktree" origin/<headRef>`.
113
135
  3. Record the absolute worktree path alongside the PR's other fields.
114
136
 
115
- Teammates spawned for a PR operate inside that PR's worktree. Step 4 teardown runs `git worktree remove "<team_temp_dir>/pr-<N>/worktree"` for each PR before `TeamDelete`.
116
-
117
- ### Step 2: Create the agent team
137
+ Teammates or Task workers for a PR operate inside that PR's worktree. Step 4 teardown runs `git worktree remove "<team_temp_dir>/pr-<N>/worktree"` for each PR, then path-specific harness teardown per [`reference/workflow-path-a-orchestrated-teams.md`](reference/workflow-path-a-orchestrated-teams.md) or [`reference/workflow-path-b-task-harness.md`](reference/workflow-path-b-task-harness.md) § Step 4.
118
138
 
119
- **This session is the lead.** The orchestrator calls `TeamCreate` directly:
139
+ ### Step 2: Path harness + loop state
120
140
 
121
- ```
122
- TeamCreate(
123
- team_name="<team_name>",
124
- description="Bugteam audit/fix loop for PR <number> (<owner>/<repo>)",
125
- agent_type="team-lead"
126
- )
127
- ```
128
-
129
- **Team name:** For a single-PR invocation use `bugteam-pr-<number>-<YYYYMMDDHHMMSS>`. For a multi-PR invocation use `bugteam-<YYYYMMDDHHMMSS>`. The timestamp is captured once at team-creation time. Apply the no-PR fallback (`bugteam-<sanitized-head>-<YYYYMMDDHHMMSS>`) only when no PR resolves at all. `TeamCreate` implements natural-language team creation ([`sources.md`](sources.md) § Team creation in natural language).
130
-
131
- **Sanitize head branch (no-PR only):** replace characters outside `[A-Za-z0-9._-]` with `-` (e.g. `feat/foo*bar` → `feat-foo-bar`). Apply once; reuse everywhere below.
132
-
133
- **`<team_temp_dir>`:** `Path(tempfile.gettempdir()) / team_name` (lead resolves once to an absolute path; every shell gets that literal string).
141
+ Apply the path you chose in [Path routing](#path-routing-mandatory-first-branch): **Path A** — [`reference/workflow-path-a-orchestrated-teams.md`](reference/workflow-path-a-orchestrated-teams.md) § Step 2 (`TeamCreate`, team name, `team_temp_dir`, roles, optional Groq FIX, `--bugbot-retrigger`). **Path B** — [`reference/workflow-path-b-task-harness.md`](reference/workflow-path-b-task-harness.md) § Step 2 (no `TeamCreate` / `TeamDelete`; same worktrees and variables).
134
142
 
135
- **Roles (spawned per loop, not here):** bugfind `code-quality-agent` opus (4.7) at xhigh effort; bugfix `clean-coder` opus (4.7) at xhigh effort. `model="opus"` resolves to Opus 4.7 on the Anthropic API and runs at the model's default `xhigh` effort level — see [`CONSTRAINTS.md`](CONSTRAINTS.md) § **Opus 4.7 at xhigh effort for both teammates** for rationale. **Display:** inherit `teammateMode` from `~/.claude.json`. Reference subagent types by name when spawning teammates ([`sources.md`](sources.md) § Referencing subagent types when spawning teammates).
136
-
137
- **Optional Groq-backed FIX path (explicit opt-in only):** the default flow above always uses Opus teammates. A separate optional path exists only when the user explicitly sets `BUGTEAM_FIX_IMPLEMENTER=groq-coder` before invocation: spawn the FIX teammate with `subagent_type="groq-coder"`. Before Step 3, `groq_bugteam.py` loads `packages/claude-dev-env/.env` when that file exists (gitignored; start from `packages/claude-dev-env/.env.example`). If `GROQ_API_KEY` is still unset after that load, stop and prompt the user to create `packages/claude-dev-env/.env` from the example path above—do not continue the Groq path without a key. Any other `BUGTEAM_FIX_IMPLEMENTER` value (or unset) keeps `clean-coder` on Opus. The FIX spawn XML in [`PROMPTS.md`](PROMPTS.md) is identical for both implementers.
138
-
139
- **`--bugbot-retrigger` flag:** when present on the `/bugteam` invocation, after every successful FIX push in Step 3, post an additional `bugbot run` issue comment via the Step 2.5 issue-comments fallback endpoint (`POST .../issues/{issue}/comments`) to re-trigger Cursor's bugbot on the new commit. Omit when the flag is absent.
143
+ Path A also resolves the team lifecycle here per [Team lifecycle](#team-lifecycle-path-a-only): pick the mode (`owned` / `attach` / `auto`) from `BUGTEAM_TEAM_LIFECYCLE`, set `team_name` (computed for `owned`/`auto` create paths; required `BUGTEAM_TEAM_NAME` for `attach` and `auto`'s attach branch), and set `team_owned` (`true` when `TeamCreate` succeeded in this invocation; `false` when attaching to an existing team). Step 4 reads `team_owned` to decide whether to call `TeamDelete`.
140
144
 
141
145
  **Loop state (lead; not a single script):**
142
146
 
143
147
  ```bash
144
148
  loop_count=0
145
149
  last_action="fresh"
146
- last_findings=""
150
+ last_findings='{"total": 0}'
147
151
  audit_log=""
148
152
  starting_sha="$(git rev-parse HEAD)"
149
153
  team_name="bugteam-pr-<number>-<YYYYMMDDHHMMSS>"
150
154
  team_temp_dir="<absolute-path>/<team_name>"
155
+ team_owned="true" # set by Step 2 lifecycle resolution; see Team lifecycle table
151
156
  loop_comment_index=""
152
157
  ```
153
158
 
@@ -155,7 +160,7 @@ loop_comment_index=""
155
160
 
156
161
  ### Step 2.5: PR comments (one review per loop)
157
162
 
158
- Bugfind posts one `POST .../pulls/<n>/reviews` per loop after audit (body + `comments[]` for anchored P0/P1/P2). Bugfix posts `.../comments/<id>/replies` after push. Lead’s only PR write: Step 4.5 body edit.
163
+ **Who posts:** Path A vs Path B [`reference/workflow-path-a-orchestrated-teams.md`](reference/workflow-path-a-orchestrated-teams.md) § Step 2.5 and [`reference/workflow-path-b-task-harness.md`](reference/workflow-path-b-task-harness.md) § Step 2.5. Payloads and endpoints below are identical for both paths.
159
164
 
160
165
  Order: audit → buffer → validate anchors vs diff → single review POST. Review body states counts; zero findings → still one review, `comments: []`, body `## /bugteam loop <N> audit: 0P0 / 0P1 / 0P2 → clean`.
161
166
 
@@ -205,28 +210,27 @@ jq -n \
205
210
 
206
211
  **Endpoints:** `POST .../pulls/{pull}/reviews`; `POST .../pulls/{pull}/comments/{id}/replies`; fallback `POST .../issues/{issue}/comments` (`issue` = PR number).
207
212
 
208
- ### Step 2.6: INITIAL standards review (once, before Loop 1 audit)
209
-
210
- Run BEFORE the first pre-audit gate fires. Spawn a fresh `code-quality-agent`
211
- teammate inside the same team and drive it through the K–N addendum (see
212
- PROMPTS.md `<copilot_derived_addendum_source>`). The teammate audits the
213
- cumulative PR diff (`gh pr diff <N>`) instead of a single loop's incremental
214
- patch; clean-room context is preserved by the same agent-team isolation as
215
- the per-loop bugfind teammate. Findings are posted using the same Step 2.5
216
- review-shape with body `## /bugteam INITIAL standards review against PR #<N>
217
- cumulative diff: <P0>P0 / <P1>P1 / <P2>P2`. Findings advance the audit/fix
218
- cycle exactly as if they had been raised in Loop 1: the lead increments
219
- `loop_count` to 1, sets `last_action = "audited"` with the merged
220
- `last_findings`, and Step 3 begins on the FIX branch. When the INITIAL
221
- review returns zero findings, `loop_count` stays at 0 and Step 3 begins on
222
- the AUDIT branch as before. Failure on this phase logs the error and
223
- proceeds to Step 3 unchanged so the legacy A–J cycle still runs.
224
-
225
213
  ### Step 3: The cycle
226
214
 
227
215
  Run the AUDIT-FIX cycle for each PR in all_prs, reusing the same team across PRs. The 10-loop cap applies per PR. Exit reasons (converged, cap reached, stuck, error) are tracked per PR; the final report lists one outcome line per PR.
228
216
 
229
- **Gate:** `validate_content` / `hooks/blocking/code_rules_enforcer.py` on PR-scoped files before every AUDIT (`bugteam_code_rules_gate.py`). Lead runs gate; clean-coder clears failures; then bugfind audits.
217
+ **Gate:** `validate_content` / `hooks/blocking/code_rules_enforcer.py` on PR-scoped files before every AUDIT (`_shared/pr-loop/scripts/code_rules_gate.py`). Lead runs gate; clean-coder clears failures; then bugfind audits.
218
+
219
+ **Pre-cycle: walk prior bugteam reviews end-first** (once per PR, after Step 2 and before iteration begins, when `last_action == "fresh"`). A re-invocation of `/bugteam` on a PR with prior loops detects whether the most recent loop already cleaned this HEAD (short-circuit) and otherwise records that prior loops were dirty so the AUDIT runs against the latest diff with that signal in mind:
220
+
221
+ ```bash
222
+ dirty_review_count=0
223
+ gh api "repos/<owner>/<repo>/pulls/<number>/reviews" \
224
+ --jq '[.[] | select(.body | startswith("## /bugteam loop "))] | sort_by(.submitted_at) | reverse'
225
+ ```
226
+
227
+ Iterate from index 0 (most recent) toward older entries:
228
+
229
+ - A bugteam review body that ends with `→ clean` is **clean**; any other `## /bugteam loop ...` body is **dirty**.
230
+ - For a dirty review, increment `dirty_review_count` by one. The review's specific finding bodies are not carried forward — bugteam's AUDIT regenerates findings against the current HEAD's diff each loop, so prior bodies are stale by definition. The count alone is the carried signal.
231
+ - Stop at the first clean review. Older reviews are presumed addressed at that clean checkpoint and are not re-read.
232
+ - When index 0 is itself clean AND its `commit_id` matches `git rev-parse HEAD`, the PR is already converged on this HEAD — set `last_action="audited"`, `last_findings='{"total": 0}'`, fall through to step 1's `converged` exit, skip Step 3 iteration entirely.
233
+ - When `dirty_review_count > 0`, log the count and proceed into the normal iteration; the next AUDIT regenerates anchored findings against the current HEAD so `loop_comment_index` stays correct. Unlike `pr-converge` — where Cursor Bugbot's prior dirty-review *bodies* are read back by the Fix protocol because each dirty body lists specific findings the loop must still address — bugteam's per-loop bodies are anchored to the diff at *that loop's* HEAD, so re-applying them against a newer diff would be incorrect. The count is sufficient signal that "prior loops did not converge here."
230
234
 
231
235
  1. From `last_action` / `last_findings`:
232
236
  - `last_action == "audited"` and `last_findings.total == 0` → exit `converged`
@@ -237,10 +241,10 @@ Run the AUDIT-FIX cycle for each PR in all_prs, reusing the same team across PRs
237
241
  2. **Pre-audit** (only when the next step is AUDIT):
238
242
 
239
243
  ```bash
240
- python "${CLAUDE_SKILL_DIR}/scripts/bugteam_code_rules_gate.py" --base origin/<baseRefName>
244
+ python "${CLAUDE_SKILL_DIR}/../../_shared/pr-loop/scripts/code_rules_gate.py" --base origin/<baseRefName>
241
245
  ```
242
246
 
243
- Lead only; merge-base / diff details in [`scripts/README.md`](scripts/README.md). Non-zero → spawn **clean-coder** standards-fix (read stderr, edit, re-run **this same** command, one commit, `git push`, shutdown) until exit **0** or **5** failed gate rounds → `error: code rules gate failed pre-audit`. After **0**: `loop_count += 1`; if `loop_count > 10` → `cap reached`. Then **AUDIT** (bugfind); print `Loop <N> audit: ...`.
247
+ Lead only; merge-base / diff semantics: [`../../_shared/pr-loop/code-rules-gate.md`](../../_shared/pr-loop/code-rules-gate.md); shared script inventory: [`../../_shared/pr-loop/scripts/README.md`](../../_shared/pr-loop/scripts/README.md). Non-zero → spawn **clean-coder** standards-fix (read stderr, edit, re-run **this same** command, one commit, `git push`, shutdown) until exit **0** or **5** failed gate rounds → `error: code rules gate failed pre-audit`. After **0**: `loop_count += 1`; if `loop_count > 10` → `cap reached`. Then **AUDIT** (bugfind); print `Loop <N> audit: ...`.
244
248
 
245
249
  3. **FIX** (`last_action == "audited"` and `last_findings.total > 0`): `loop_count += 1`; if `loop_count > 10` → `cap reached`; **FIX** (bugfix); print `Loop <N> fix: ...`; `last_action = "fixed"`, update `audit_log`; loop to step 1.
246
250
 
@@ -257,79 +261,45 @@ mkdir -p "<team_temp_dir>/pr-<N>"
257
261
  gh pr diff <N> -R <owner>/<repo> > "<team_temp_dir>/pr-<N>/loop-<L>.patch"
258
262
  ```
259
263
 
260
- ```
261
- Agent(
262
- subagent_type="code-quality-agent",
263
- name="bugfind-pr<N>-loop<L>",
264
- team_name="<team_name>",
265
- model="opus",
266
- description="Bugfind audit PR <N> loop <L>",
267
- prompt="<audit XML; see PROMPTS.md>"
268
- )
269
- ```
270
-
271
- Fresh `Agent` each loop; teammate context excludes lead history ([`sources.md`](sources.md) § Teammate context isolation). [`PROMPTS.md`](PROMPTS.md): XML + outcome schema. Lead reads `.bugteam-pr<N>-loop<L>.outcomes.xml`, fills `loop_comment_index`.
272
-
273
- **Shutdown:** If `Agent` returned and the teammate already ended, skip. Otherwise:
264
+ **Spawn and shutdown:** Path A — [`reference/workflow-path-a-orchestrated-teams.md`](reference/workflow-path-a-orchestrated-teams.md) § AUDIT. Path B — [`reference/workflow-path-b-task-harness.md`](reference/workflow-path-b-task-harness.md) § AUDIT. Same `prompt="<audit XML; see PROMPTS.md>"` and outcome files.
274
265
 
275
- ```
276
- SendMessage(
277
- to="bugfind-pr<N>-loop<L>",
278
- message={"type": "shutdown_request", "reason": "audit PR <N> loop <L> complete; outcome XML captured"}
279
- )
280
- ```
281
-
282
- `approve: false` → `error: bugfind teammate refused shutdown` → Step 4 then 5.
266
+ Fresh spawn each loop; Path A teammate context excludes lead history ([`sources.md`](sources.md) § Teammate context isolation). Path B: fresh Task per loop for the same clean-room intent. [`PROMPTS.md`](PROMPTS.md): XML + outcome schema. Lead reads `.bugteam-pr<N>-loop<L>.outcomes.xml`, fills `loop_comment_index`.
283
267
 
284
268
  `last_action = "audited"`; append audit line to `audit_log`.
285
269
 
286
- **Parallel auditors (`loop_count >= 4`):** gate passes immediately before; after three full audit/fix rounds without convergence, issue three `Agent` calls in one assistant message (parallel). `-a` posts the review and merges outcomes from `-b`/`-c` (read `.bugteam-pr<N>-loop<L>.outcomes.xml` plus `<team_temp_dir>/pr-<N>/loop-<L>-b.outcomes.xml` and `...-c...`); merge key `(file, line, category_letter)`; re-id `loopN-K`. `-b`/`-c` write sibling XML only; prompts must pass literal absolute sibling paths. Shutdown: parallel `SendMessage` to `b` and `c`, then `a`.
270
+ **Parallel auditors (`loop_count >= 4`):** gate passes immediately before; after three full audit/fix rounds without convergence, issue three spawns in one assistant message (parallel): Path A — three `Agent` calls; Path B — three `Task` calls — full rules in the workflow files § parallel auditors. `-a` posts the review and merges outcomes from `-b`/`-c` (read `.bugteam-pr<N>-loop<L>.outcomes.xml` plus `<team_temp_dir>/pr-<N>/loop-<L>-b.outcomes.xml` and `...-c...`); merge key `(file, line, category_letter)`; re-id `loopN-K`. `-b`/`-c` write sibling XML only; prompts must pass literal absolute sibling paths. Shutdown order: Path A workflow § parallel auditors; Path B: await all three Tasks.
287
271
 
288
272
  ### FIX action
289
273
 
290
- ```
291
- Agent(
292
- subagent_type="clean-coder",
293
- name="bugfix-pr<N>-loop<L>",
294
- team_name="<team_name>",
295
- model="opus",
296
- description="Bugfix PR <N> loop <L>",
297
- prompt="<fix XML; see PROMPTS.md>"
298
- )
299
- ```
274
+ **Spawn and shutdown:** Path A — [`reference/workflow-path-a-orchestrated-teams.md`](reference/workflow-path-a-orchestrated-teams.md) § FIX. Path B — [`reference/workflow-path-b-task-harness.md`](reference/workflow-path-b-task-harness.md) § FIX.
300
275
 
301
276
  Pass finding comment URLs/ids from `loop_comment_index` in XML. Replies: `Fixed in <sha>` or `Could not address this loop: <reason>`.
302
277
 
303
- **Shutdown:** same as bugfind; else `SendMessage(to="bugfix-pr<N>-loop<L>", message={"type": "shutdown_request", "reason": "fix PR <N> loop <L> complete; commit <sha7> pushed"})`. `approve: false` → `error: bugfix teammate refused shutdown` → Step 4 then 5.
304
-
305
278
  [`PROMPTS.md`](PROMPTS.md): fix XML + schema. Verify: `git rev-parse HEAD` advanced; `git fetch origin <branch> && git rev-parse origin/<branch>` matches `HEAD`. Unchanged HEAD → `stuck — bugfix teammate could not address findings`.
306
279
 
307
- ### Step 3.5: FINAL standards review (once, after convergence)
280
+ ### Step 4: Teardown
308
281
 
309
- Run AFTER Step 3 exits with `converged`, `cap reached`, or `stuck`, and
310
- BEFORE Step 4 teardown. Spawn one more fresh `code-quality-agent` teammate;
311
- audit the cumulative PR diff against the K–N addendum a second time. Post
312
- the review with body `## /bugteam FINAL standards review against PR #<N>
313
- cumulative diff: <P0>P0 / <P1>P1 / <P2>P2`. When findings remain, the
314
- exit reason is upgraded to `error: final standards review found <P0>+<P1>+<P2>
315
- unresolved finding(s)` and the loop log gains an extra `final-review` line.
316
- A clean FINAL review preserves the existing exit reason. Failure on this
317
- phase logs the error and continues to Step 4 unchanged so teardown,
318
- permission revoke, and the final report still run.
282
+ 1. For each PR in `all_prs`: `git worktree remove "<team_temp_dir>/pr-<N>/worktree"` (from Step 1) before tearing down the team harness — tolerate already-removed worktrees.
319
283
 
320
- ### Step 4: Teardown
284
+ 2. Path-specific harness — [`reference/workflow-path-a-orchestrated-teams.md`](reference/workflow-path-a-orchestrated-teams.md) § Step 4 (teammate `SendMessage`, `TeamDelete` **only when `team_owned=true`**) or [`reference/workflow-path-b-task-harness.md`](reference/workflow-path-b-task-harness.md) § Step 4 (omit those).
321
285
 
322
- 1. For each live teammate: `SendMessage(to="<name>", message={"type": "shutdown_request", "reason": "bugteam cycle ending"})`. `approve: false` on cleanup log and continue.
286
+ 3. **Windows-safe `rmtree` gated by `team_owned` from [Team lifecycle](#team-lifecycle-path-a-only).** The Windows-safe handler strips the Windows ReadOnly attribute and retries the failing syscall (see `~/.claude/rules/windows-filesystem-safe.md`).
323
287
 
324
- 2. `TeamDelete()`
288
+ - `team_owned=true` → remove the full `<team_temp_dir>`:
325
289
 
326
- 3. Windows-safe teardown — `ignore_errors=True` silently swallows ReadOnly-attribute failures on Windows (see `~/.claude/rules/windows-filesystem-safe.md`). Use the inline `force_rmtree` helper:
290
+ ```bash
291
+ python -c "import os, shutil, stat, sys; \
292
+ h = lambda f, p, *_: (os.chmod(p, stat.S_IWRITE), f(p)); \
293
+ shutil.rmtree(r'<team_temp_dir>', **({'onexc': h} if sys.version_info >= (3, 12) else {'onerror': h}))"
294
+ ```
327
295
 
328
- ```bash
329
- python -c "import os, shutil, stat, sys; \
330
- h = lambda f, p, *_: (os.chmod(p, stat.S_IWRITE), f(p)); \
331
- shutil.rmtree(r'<team_temp_dir>', **({'onexc': h} if sys.version_info >= (3, 12) else {'onerror': h}))"
332
- ```
296
+ - `team_owned=false` (attach mode) → for each PR in `all_prs`, remove only that PR's `<team_temp_dir>/pr-<N>/` subfolder. The orchestrator-owned parent `<team_temp_dir>` survives so the next attached invocation can write its own per-PR subfolders without colliding.
297
+
298
+ ```bash
299
+ python -c "import os, shutil, stat, sys; \
300
+ h = lambda f, p, *_: (os.chmod(p, stat.S_IWRITE), f(p)); \
301
+ shutil.rmtree(r'<team_temp_dir>/pr-<N>', **({'onexc': h} if sys.version_info >= (3, 12) else {'onerror': h}))"
302
+ ```
333
303
 
334
304
  ### Step 4.5: PR description
335
305
 
@@ -346,7 +316,7 @@ On failure: log in final report; continue to Step 5.
346
316
  ### Step 5: Revoke permissions (always)
347
317
 
348
318
  ```bash
349
- python "${CLAUDE_SKILL_DIR}/scripts/revoke_project_claude_permissions.py"
319
+ python "${CLAUDE_SKILL_DIR}/../../_shared/pr-loop/scripts/revoke_project_claude_permissions.py"
350
320
  ```
351
321
 
352
322
  Removes Step 0 grant — run even if Step 4 partially failed (log separately).
@@ -361,10 +331,8 @@ Final commit: <current_HEAD_sha7>
361
331
  Net change: <total_files> files, +<total_add>/-<total_del>
362
332
 
363
333
  Loop log:
364
- initial standards review: 1P0 0P1 2P2
365
334
  1 audit: 3P0 2P1 0P2
366
335
  ...
367
- final standards review: 0P0 0P1 0P2
368
336
  ```
369
337
 
370
338
  `cap reached` → suggest `/findbugs`. `stuck` → which findings. `error` → detail + loop.
@@ -14,23 +14,23 @@ Evals are split into two layers. Both layers run against the same trace but carr
14
14
 
15
15
  ## Ironclad invariants (Layer A, apply to every eval)
16
16
 
17
- Each invariant cites the normative section or companion file it derives from.
17
+ Each invariant cites the normative section or companion file it derives from. **Path A vs Path B:** `SKILL.md` **Path routing** splits harnesses. Invariants **I-1, I-3, I-4, I-7, I-9, I-11 (teammate shutdown → `TeamDelete` prefix), I-13** apply to **Path A only**. **Path B** substitutes per [`reference/workflow-path-b-task-harness.md`](reference/workflow-path-b-task-harness.md): no `TeamCreate` / `TeamDelete`; parallel auditors use parallel **`Task`** calls; **I-12 Path B** — the **lead** runs Step 2.5 `gh api` posts. **I-2, I-5, I-6, I-8, I-10** apply to **both** paths (revoke once; fresh spawn per loop; `model="opus"` on audit/fix workers; cap; read outcome XML).
18
18
 
19
19
  | # | Invariant | Citation |
20
20
  |---|---|---|
21
- | I-1 | `Bash` invoking `scripts/grant_project_claude_permissions.py` precedes every `TeamCreate`. | `SKILL.md` § Step 0 |
22
- | I-2 | `Bash` invoking `scripts/revoke_project_claude_permissions.py` runs exactly once per invocation, after the last `TeamDelete`, on every exit path (converged, stuck, cap reached, error). | `SKILL.md` § Step 5 |
23
- | I-3 | Exactly one `TeamCreate` and exactly one `TeamDelete` per invocation. | `SKILL.md` § Step 2; § Step 4 |
24
- | I-4 | Before `TeamDelete`, no teammate remains active without cleanup: either the teammate self-terminated after `Agent` returned, or the lead sent a matching `SendMessage(..., shutdown_request)` (including parallel-auditor shutdowns). No orphaned teammates when `TeamDelete` runs. | `SKILL.md` § AUDIT action (**Shutdown**); § FIX action (**Shutdown**); § Step 4 |
25
- | I-5 | `Agent` calls are fresh per loop the same `name` is never reused across loops without an intervening shutdown. | `CONSTRAINTS.md` — **Fresh teammate per loop** |
26
- | I-6 | Both audit and fix `Agent` calls pass `model="opus"` (resolves to Opus 4.7 via the Anthropic API alias; effort remains the Claude Code/model-config default `xhigh`). | `SKILL.md` § Step 2 (**Roles**); `CONSTRAINTS.md` — **Opus 4.7 at xhigh effort for both teammates** |
27
- | I-7 | `TeamDelete()` is called with no arguments. | TeamDelete schema: no required params, no properties |
21
+ | I-1 | **Path A:** `Bash` invoking `scripts/grant_project_claude_permissions.py` precedes every `TeamCreate`. **Path B:** grant precedes first audit **`Task`**. | `SKILL.md` § Step 0; § Path routing |
22
+ | I-2 | `Bash` invoking `scripts/revoke_project_claude_permissions.py` runs exactly once per invocation on every exit path, **after** teardown that applies to that path (`TeamDelete` only on Path A). | `SKILL.md` § Step 5 |
23
+ | I-3 | **Path A:** Exactly one `TeamCreate` and exactly one `TeamDelete` per invocation. **Path B:** zero `TeamCreate` / `TeamDelete`. | `SKILL.md` § Step 2; § Step 4 |
24
+ | I-4 | **Path A:** Before `TeamDelete`, no teammate remains active without cleanup (self-terminated `Agent` or `SendMessage` shutdown). | `SKILL.md` § AUDIT/FIX shutdown; § Step 4 |
25
+ | I-5 | **Path A:** `Agent` calls are fresh per loop. **Path B:** `Task` calls for audit/fix are fresh per loop (same `name` discipline where the host exposes naming). | `CONSTRAINTS.md` — **Fresh teammate per loop**; deltas **Clean-room note** |
26
+ | I-6 | Both paths: audit and fix worker spawns pass `model="opus"` on `Agent` **or** `Task` as documented in `SKILL.md` § AUDIT/FIX. | `SKILL.md` § Step 2 (**Roles**); `CONSTRAINTS.md` — **Opus 4.7 at xhigh effort for both teammates** |
27
+ | I-7 | **Path A:** `TeamDelete()` is called with no arguments. **Path B:** omit. | `SKILL.md` § Step 4 |
28
28
  | I-8 | Loop count ≤ 10 audits. 11th audit never fires. | `SKILL.md` YAML `description` (10-loop cap); § Step 3 (**Pre-audit** / **FIX** increment rules) |
29
- | I-9 | From loop 4 onward without convergence, the audit phase emits three parallel `Agent` calls in a single assistant message with names `bugfind-loop-<N>-a/b/c`. | `SKILL.md` § AUDIT action (**Parallel auditors**); `reference/audit-and-teammates.md` § **Parallel auditors** |
29
+ | I-9 | **Path A:** From loop 4 onward without convergence, three parallel `Agent` calls in one message. **Path B:** three parallel **`Task`** calls. | `SKILL.md` § AUDIT action (**Parallel auditors**); `reference/workflow-path-b-task-harness.md` |
30
30
  | I-10 | Lead reads `.bugteam-loop-<N>.outcomes.xml` with the `Read` tool after each audit, before the next action. | `SKILL.md` § AUDIT action |
31
- | I-11 | On exit of any kind, ordering is: teammate shutdowns → `TeamDelete` → temp-dir cleanup → Step 4.5 PR rewrite → revoke. | `SKILL.md` § Step 4; § Step 4.5; § Step 5; `reference/teardown-publish-permissions.md` § **Step 4** / **Step 4.5** / **Step 5** |
32
- | I-12 | Lead never posts PR review comments, finding comments, or fix replies. The only lead-side PR mutation is the final `gh pr edit --body-file` in Step 4.5. | `CONSTRAINTS.md` — **Teammates own audit/fix comment posting**; **Lead owns the final PR description rewrite only** |
33
- | I-13 | Only the orchestrator (lead session) invokes `TeamCreate`. Every teammate `Agent(...)` call passes `team_name=<lead_team_name>`. No teammate ever calls `TeamCreate`. When supplementary work arises mid-cycle (parallel auditors, adjacent-file audits, infrastructure fixes), the lead spawns additional teammates into the existing team rather than creating a second team. | `CONSTRAINTS.md` — **Orchestrator-only `TeamCreate`** (runtime error quoted there) |
31
+ | I-11 | **Path A:** `git worktree remove` each PR teammate shutdowns → `TeamDelete` → `rmtree` `<team_temp_dir>` → Step 4.5 → revoke. **Path B:** `git worktree remove` each PR (omit shutdown / `TeamDelete`) `rmtree` → Step 4.5 → revoke. | `SKILL.md` § Step 4; § Step 4.5; § Step 5; `reference/workflow-path-a-orchestrated-teams.md` § Step 4; `reference/workflow-path-b-task-harness.md` § Step 4 |
32
+ | I-12 | **Path A:** Lead never posts PR review / finding / fix replies except Step 4.5 body. **Path B:** Lead performs Step 2.5 posts per deltas; Step 4.5 unchanged. | `CONSTRAINTS.md` — **Audit/fix comment posting** |
33
+ | I-13 | **Path A:** Only the lead invokes `TeamCreate`; every teammate `Agent(..., team_name=...)`. **Path B:** no `TeamCreate`; `Task` spawns omit `team_name`. | `CONSTRAINTS.md` — **Path A — orchestrator-only `TeamCreate`**; `reference/workflow-path-b-task-harness.md` |
34
34
 
35
35
  Any eval failing one or more Layer A invariants fails the run.
36
36
 
@@ -46,23 +46,25 @@ The harness does not yet exist; this document defines its contract.
46
46
 
47
47
  ---
48
48
 
49
- ## Eval 1 — Refusal: agent teams not enabled
49
+ ## Eval 1 — Path B: agent teams env unset (Task harness, not a refusal)
50
50
 
51
51
  **Scenario.** `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS` is unset in both `claude config` and `~/.claude/settings.json`.
52
52
 
53
53
  **Trigger.** `/bugteam`
54
54
 
55
- **Layer A invariants.** None fire downstream this is a pre-cycle refusal.
55
+ **Layer A invariants.** Path B subset (I-2, I-5, I-6, I-8, I-10; I-1/I-3/I-4/I-7/I-9/I-11/I-13 N/A or Path-B-shaped).
56
56
 
57
- **Layer B predicted trace.**
57
+ **Layer B predicted trace (Path B smoke).**
58
58
  1. `Bash("claude config get env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS")` → empty.
59
- 2. `Read("~/.claude/settings.json")` settings without the env var.
60
- 3. No grant script, no `TeamCreate`, no `Agent`.
59
+ 2. `Bash("python .../grant_project_claude_permissions.py")` runs (Step 0).
60
+ 3. **No** `TeamCreate`.
61
+ 4. At least one `Task(subagent_type="code-quality-agent", ...)` or host-equivalent for AUDIT; FIX rounds use the host-appropriate FIX `Task` from `workflow-path-b-task-harness.md` § **FIX spawn** (`clean-coder` subtype on Claude Code when accepted; `generalPurpose` + clean-coder **Read** preamble on Cursor when the enum rejects `clean-coder`).
62
+ 5. `Bash("python .../revoke_project_claude_permissions.py")` on exit.
61
63
 
62
64
  **Pass criteria.**
63
- - Final assistant message contains the exact string `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 not set. /bugteam requires the agent teams feature.`.
64
- - Zero `TeamCreate`, `Agent`, `SendMessage`, `TeamDelete` calls.
65
- - Zero invocations of the grant or revoke scripts.
65
+ - **No** refusal string about missing agent teams.
66
+ - Zero `TeamCreate`, zero `TeamDelete`, zero teammate `SendMessage` shutdowns.
67
+ - Non-zero `Task` (or `Agent` without `team_name` only if the host maps Path B that way) carrying **`code-quality-agent`** / **fix worker under the clean-coder contract** (subtype `clean-coder` where accepted, else `generalPurpose` + `clean-coder.md` Read per `workflow-path-b-task-harness.md`).
66
68
 
67
69
  ---
68
70
 
@@ -95,11 +97,11 @@ The harness does not yet exist; this document defines its contract.
95
97
 
96
98
  ---
97
99
 
98
- ## Eval 5 — Happy path: converges in 2 loops
100
+ ## Eval 5 — Happy path: converges in 2 loops (Path A fixture)
99
101
 
100
- **Scenario.** PR #42 contains three P1 bugs all addressable by the mock fix teammate. Loop 1 audit returns 3 findings; loop 1 fix commits cleanly; loop 2 audit returns zero findings.
102
+ **Scenario.** PR #42 contains three P1 bugs all addressable by the mock fix teammate. Loop 1 audit returns 3 findings; loop 1 fix commits cleanly; loop 2 audit returns zero findings. **`CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1`** (Path A — `TeamCreate` + teammate `Agent`).
101
103
 
102
- **Layer A invariants.** I-1, I-2, I-3, I-4, I-5, I-6, I-7, I-10, I-11, I-12.
104
+ **Layer A invariants.** Path A: I-1, I-2, I-3, I-4, I-5, I-6, I-7, I-10, I-11, I-12, I-13.
103
105
 
104
106
  **Layer B predicted trace.**
105
107
 
@@ -4,6 +4,8 @@ Expanded material that used to live inline in `SKILL.md`. Load a file when the o
4
4
 
5
5
  | File | Domain |
6
6
  |------|--------|
7
+ | [`workflow-path-a-orchestrated-teams.md`](workflow-path-a-orchestrated-teams.md) | **Path A only** — `TeamCreate`, `Agent` + `team_name`, `SendMessage`, `TeamDelete`, who posts Step 2.5 |
8
+ | [`workflow-path-b-task-harness.md`](workflow-path-b-task-harness.md) | **Path B only** — `Task` harness (no `TeamCreate` / `TeamDelete`, lead Step 2.5 `gh api`, Step 4 omissions) |
7
9
  | [`design-rationale.md`](design-rationale.md) | Why agent teams (clean-room), table-of-contents habit, when `/bugteam` applies, refusal reasons |
8
10
  | [`team-setup.md`](team-setup.md) | Permissions grant (`CLAUDE_SKILL_DIR`), PR scope, `TeamCreate`, team name / sanitization / temp dir / roles / loop state |
9
11
  | [`github-pr-reviews.md`](github-pr-reviews.md) | Per-loop reviews, `jq` + `gh api` payloads, anchors, fallbacks, REST endpoints |
@@ -16,10 +16,10 @@ Repeat until an exit condition fires.
16
16
  1. From the repository root, run the gate script (align `--base` with the PR base branch from Step 1, e.g. `origin/main` or `origin/develop`):
17
17
 
18
18
  ```bash
19
- python "${CLAUDE_SKILL_DIR}/scripts/bugteam_code_rules_gate.py" --base origin/<baseRefName>
19
+ python "${CLAUDE_SKILL_DIR}/../../_shared/pr-loop/scripts/code_rules_gate.py" --base origin/<baseRefName>
20
20
  ```
21
21
 
22
- `git merge-base` + `git diff --name-only` live inside the script; see [`../scripts/README.md`](../scripts/README.md). The lead runs this (not a teammate).
22
+ `git merge-base` + `git diff --name-only` live inside the script; see [`../../../_shared/pr-loop/scripts/README.md`](../../../_shared/pr-loop/scripts/README.md) for what lives under this directory, and [`../../../_shared/pr-loop/code-rules-gate.md`](../../../_shared/pr-loop/code-rules-gate.md) for gate-only merge-base / invocation semantics. The lead runs this (not a teammate).
23
23
 
24
24
  2. If exit code **0** → continue to step 2.5 (AUDIT spawn) below.
25
25
  3. If exit code **non-zero** → spawn a new **clean-coder** teammate — **standards-fix pass** — with instructions: read the script’s stderr, edit the repo until a **re-run** of the **same** gate command exits **0**, then one commit, `git push`, shutdown. Repeat standards-fix spawns until the gate exits **0** or **5** failed gate rounds (each round = one teammate session after a non-zero gate). If still non-zero after 5 rounds → exit reason = `error: code rules gate failed pre-audit`.
@@ -1,5 +1,15 @@
1
1
  # Copilot gap analysis
2
2
 
3
+ > **Status: HISTORICAL — patch plan partially superseded.**
4
+ >
5
+ > This file documents the read-only investigation that motivated the K–N rubric addendum and the Step 2.6 / Step 3.5 standards-review phases. **The audit-rubric portion of the patch plan was reverted in [PR #292](https://github.com/jl-cmd/claude-code-config/pull/292):** PROMPTS.md no longer carries the K–N addendum or the `<copilot_derived_addendum_source>` block, and SKILL.md no longer runs the Step 2.6 / Step 3.5 standards-review phases.
6
+ >
7
+ > **What replaced K–N (partial coverage):** several judgment-heavy categories now have deterministic validators in `code_rules_enforcer.py` — `check_collection_prefix` (category K), `check_library_print` (category L), `check_inline_literal_collections`, `check_loop_variable_naming`, `check_parameter_annotations`, `check_return_annotations`. These validators are exercised by `bugteam_code_rules_gate.py` during the bugteam pre-audit / loop, and by the shipped repo `pre-commit` / `pre-push` git hooks that invoke that gate. They are **not** wired into the repo's default `PreToolUse` Write|Edit hook list in `packages/claude-dev-env/hooks/hooks.json`, so they do not block at Write/Edit time by default — enforcement comes from the gate (audit-time) and the git hooks (commit/push-time).
8
+ >
9
+ > **What is NOT a full deterministic replacement (remaining limitations):** the string-literal magic case in this doc is largely about snake_case column / key / table-name literals (`"theme_name"`, `"content_id"`, etc.). `check_string_literal_magic` in `code_rules_enforcer.py` still only flags ALL-CAPS-WITH-UNDERSCORE identifiers and dotted segments, so it does **not** cover those snake_case database-column literals by itself. However, the gap called out in this document is no longer accurately described as “unimplemented”: `check_database_column_string_magic` and `check_wrapper_plumb_through` now exist in `bugteam_code_rules_gate.py` and run in the `/bugteam` gate, including via the shipped repo `pre-commit` / `pre-push` hooks that invoke that gate. The remaining limitation is coverage/wiring scope: these checks are gate-time / git-hook-time validators, not part of the repo's default `PreToolUse` Write|Edit hook path, and any residual misses should be described in terms of validator scope rather than absence.
10
+ >
11
+ > Read this file as **investigation history**: the inventory, rubric/validator coverage diffs, and root-cause statement remain useful context for future bugteam improvements. The "Patch plan" section below describes what was originally proposed, not the current state — references to category K, L, M, N or to Step 2.6 / Step 3.5 in the patch plan are historical and should not be reintroduced.
12
+
3
13
  This file is the reference record produced by the read-only investigation of why the `/bugteam` audit/fix loop and `bugteam_code_rules_gate.py` repeatedly miss the classes of code-quality violations that the GitHub Copilot reviewer raises on follow-up review rounds. It is written so future bugteam runs can skim the inventory, the rubric/validator coverage diffs, and the patch plan without re-deriving them.
4
14
 
5
15
  Sources of truth cited below: `~/.claude/docs/CODE_RULES.md`, `~/.claude/CLAUDE.md`, `~/.claude/rules/file-global-constants.md`, `~/.claude/skills/bugteam/SKILL.md`, `~/.claude/skills/bugteam/PROMPTS.md`, `~/.claude/skills/bugteam/CONSTRAINTS.md`, `~/.claude/skills/bugteam/scripts/bugteam_code_rules_gate.py`, `~/.claude/skills/bugteam/scripts/bugteam_preflight.py`, `~/.claude/hooks/blocking/code_rules_enforcer.py`, plus `gh api repos/JonEcho/python-automation/pulls/{70,73}/comments` filtered to author `Copilot`.
@@ -85,6 +95,8 @@ The bugteam audit rubric (PROMPTS.md §bug_categories A–J) and the determinist
85
95
 
86
96
  ## Patch plan
87
97
 
98
+ > **Historical — the rubric/phases portion below was reverted in PR #292.** Sections (a) PROMPTS.md K–N addendum, (b) Step 2.6 INITIAL standards review, and the FINAL standards review (Step 3.5) were reverted and replaced by deterministic validators (see status banner at the top of this file). Sections that landed deterministic validators in `code_rules_enforcer.py` (collection prefix, library print, string-literal magic, inline literal collections, loop-variable naming, parameter/return annotations) remain in force. Treat the rubric/phase sections below as record-of-what-was-tried, not a current to-do list.
99
+
88
100
  Each section names exactly one target file, the literal text or regex to add, and a verification step that re-runs the new detection against the PR #70 / PR #73 diffs.
89
101
 
90
102
  ### a. `~/.claude/skills/bugteam/PROMPTS.md`
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## Utility scripts (progressive disclosure)
4
4
 
5
- Fragile or repeatable shell sequences belong in `scripts/`. Anthropic: [Progressive disclosure patterns](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices#progressive-disclosure-patterns) — utility scripts are **executed**, not loaded into context as primary reading. Details: [`../scripts/README.md`](../scripts/README.md).
5
+ Fragile or repeatable shell sequences belong in `_shared/pr-loop/scripts/`. Anthropic: [Progressive disclosure patterns](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices#progressive-disclosure-patterns) — utility scripts are **executed**, not loaded into context as primary reading. Script inventory and entry points: [`../../../_shared/pr-loop/scripts/README.md`](../../../_shared/pr-loop/scripts/README.md). Gate-only merge-base / diff semantics: [`../../../_shared/pr-loop/code-rules-gate.md`](../../../_shared/pr-loop/code-rules-gate.md).
6
6
 
7
7
  ### Pre-flight (recommended before Step 0)
8
8