claude-dev-env 2.0.2 → 2.1.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 (88) hide show
  1. package/CLAUDE.md +1 -1
  2. package/hooks/blocking/CLAUDE.md +1 -0
  3. package/hooks/blocking/code_rules_shared.py +126 -47
  4. package/hooks/blocking/config/CLAUDE.md +2 -0
  5. package/hooks/blocking/config/verified_commit_context_constants.py +21 -0
  6. package/hooks/blocking/config/verified_commit_gate_output_constants.py +14 -0
  7. package/hooks/blocking/conftest.py +36 -30
  8. package/hooks/blocking/convergence_gate_blocker.py +76 -8
  9. package/hooks/blocking/plain_language_blocker.py +8 -0
  10. package/hooks/blocking/state_description_blocker.py +4 -1
  11. package/hooks/blocking/test_code_rules_shared.py +120 -20
  12. package/hooks/blocking/test_convergence_gate_blocker.py +146 -0
  13. package/hooks/blocking/test_plain_language_blocker.py +15 -0
  14. package/hooks/blocking/test_state_description_blocker.py +15 -0
  15. package/hooks/blocking/test_verified_commit_config_bootstrap.py +18 -0
  16. package/hooks/blocking/test_verified_commit_gate_additional_context.py +134 -0
  17. package/hooks/blocking/tests/test_verified_commit_gate.py +41 -0
  18. package/hooks/blocking/verified_commit_config_bootstrap.py +22 -10
  19. package/hooks/blocking/verified_commit_gate.py +113 -568
  20. package/hooks/blocking/verified_commit_gate_parts/CLAUDE.md +28 -0
  21. package/hooks/blocking/verified_commit_gate_parts/__init__.py +1 -0
  22. package/hooks/blocking/verified_commit_gate_parts/command_tokenization.py +174 -0
  23. package/hooks/blocking/verified_commit_gate_parts/deny_payload.py +53 -0
  24. package/hooks/blocking/verified_commit_gate_parts/deny_reason.py +80 -0
  25. package/hooks/blocking/verified_commit_gate_parts/directory_resolution.py +170 -0
  26. package/hooks/blocking/verified_commit_gate_parts/gated_invocations.py +205 -0
  27. package/hooks/blocking/verified_commit_gate_parts/tests/conftest.py +10 -0
  28. package/hooks/blocking/verified_commit_gate_parts/tests/test_command_tokenization.py +94 -0
  29. package/hooks/blocking/verified_commit_gate_parts/tests/test_deny_payload.py +17 -0
  30. package/hooks/blocking/verified_commit_gate_parts/tests/test_deny_reason.py +38 -0
  31. package/hooks/blocking/verified_commit_gate_parts/tests/test_directory_resolution.py +71 -0
  32. package/hooks/blocking/verified_commit_gate_parts/tests/test_gated_invocations.py +61 -0
  33. package/hooks/hooks_constants/CLAUDE.md +4 -1
  34. package/hooks/hooks_constants/code_rules_path_utils_constants.py +1 -0
  35. package/hooks/hooks_constants/convergence_gate_blocker_constants.py +36 -0
  36. package/hooks/hooks_constants/harness_scratchpad_constants.py +10 -9
  37. package/hooks/hooks_constants/mypy_integration_constants.py +16 -0
  38. package/hooks/validators/mypy_integration.py +145 -24
  39. package/hooks/validators/python_antipattern_checks.py +16 -0
  40. package/hooks/validators/run_all_validators.py +9 -3
  41. package/hooks/validators/test_mypy_integration.py +154 -0
  42. package/hooks/validators/test_python_antipattern_checks.py +112 -1
  43. package/hooks/validators/test_run_all_validators_pretooluse.py +16 -0
  44. package/package.json +1 -1
  45. package/rules/CLAUDE.md +1 -0
  46. package/rules/verified-commit-gate-skip.md +28 -0
  47. package/skills/auditing-claude-config/CLAUDE.md +2 -1
  48. package/skills/auditing-claude-config/SKILL.md +114 -176
  49. package/skills/auditing-claude-config/reference/probe-hook.md +74 -0
  50. package/skills/autoconverge/CLAUDE.md +1 -0
  51. package/skills/autoconverge/SKILL.md +310 -346
  52. package/skills/autoconverge/reference/CLAUDE.md +1 -0
  53. package/skills/autoconverge/reference/copilot-findings.md +51 -0
  54. package/skills/closeout/SKILL.md +7 -9
  55. package/skills/copilot-finding-triage/SKILL.md +5 -7
  56. package/skills/copilot-review/CLAUDE.md +3 -2
  57. package/skills/copilot-review/SKILL.md +119 -155
  58. package/skills/copilot-review/templates/subagent-prompt.md +49 -0
  59. package/skills/fresh-branch/CLAUDE.md +6 -9
  60. package/skills/fresh-branch/SKILL.md +84 -33
  61. package/skills/fresh-branch/scripts/create_fresh_branch.py +445 -0
  62. package/skills/fresh-branch/scripts/fresh_branch_scripts_constants/__init__.py +1 -0
  63. package/skills/fresh-branch/scripts/fresh_branch_scripts_constants/fresh_branch_cli_constants.py +74 -0
  64. package/skills/fresh-branch/scripts/test_create_fresh_branch.py +670 -0
  65. package/skills/pr-converge/SKILL.md +277 -422
  66. package/skills/pr-converge/reference/CLAUDE.md +1 -0
  67. package/skills/pr-converge/reference/progress-checklist.md +168 -0
  68. package/skills/pr-converge/test_step5_host_branch.py +8 -6
  69. package/skills/pr-loop-cloud-transport/SKILL.md +1 -1
  70. package/skills/privacy-hygiene/SKILL.md +68 -115
  71. package/skills/privacy-hygiene/reference/sweep-procedure.md +62 -0
  72. package/skills/session-log/CLAUDE.md +2 -1
  73. package/skills/session-log/SKILL.md +4 -26
  74. package/skills/session-log/templates/frontmatter.md +40 -0
  75. package/skills/skill-builder/CLAUDE.md +8 -7
  76. package/skills/skill-builder/SKILL.md +26 -11
  77. package/skills/skill-builder/references/CLAUDE.md +3 -1
  78. package/skills/skill-builder/references/delegation-map.md +21 -12
  79. package/skills/skill-builder/references/description-field.md +9 -11
  80. package/skills/skill-builder/references/deterministic-elements.md +218 -0
  81. package/skills/skill-builder/references/self-audit-checklist.md +62 -45
  82. package/skills/skill-builder/references/skill-modularity.md +8 -9
  83. package/skills/skill-builder/templates/CLAUDE.md +2 -2
  84. package/skills/skill-builder/templates/gap-analysis.md +15 -0
  85. package/skills/skill-builder/workflows/CLAUDE.md +5 -5
  86. package/skills/skill-builder/workflows/improve-skill.md +18 -9
  87. package/skills/skill-builder/workflows/new-skill.md +23 -15
  88. package/skills/skill-builder/workflows/polish-skill.md +28 -21
@@ -1,422 +1,277 @@
1
- ---
2
- name: pr-converge
3
- description: >-
4
- Loops Cursor Bugbot, a code review, a bug audit, and Copilot on the current
5
- PR, applying TDD fixes until all are clean on one HEAD. Use when the user says
6
- '/pr-converge', 'drive PR to convergence', 'loop bugbot and bugteam', 'babysit
7
- bugbot and bugteam', 'until both are clean', or 'converge this PR'.
8
- ---
9
-
10
- # PR Converge
11
-
12
- One tick per invocation. A code-review ↔ bugteam ↔ Bugbot ↔ Copilot loop on
13
- a draft PR: the internal code-review and bugteam passes drive the code to clean
14
- first, then Cursor Bugbot and Copilot run as terminal confirmation gates, until
15
- all are clean on the same `HEAD` and mergeable.
16
-
17
- ## Transport check (before any GitHub step)
18
-
19
- Run `command -v gh`; when it succeeds, run `gh auth status`; once the PR
20
- scope is resolved, run `gh api repos/<owner>/<repo> --jq .permissions.push`
21
- and take `true` as the pass. When any check fails, run the
22
- `pr-loop-cloud-transport` skill first and route every `gh` operation in this
23
- skill through its substitution matrix.
24
-
25
- ## Pre-flight
26
-
27
- Pause and physically scan the tool list at the top of this conversation
28
- for the literal string `ScheduleWakeup`. If you see it, proceed. If the
29
- string is absent after scanning, report `pr-converge requires
30
- ScheduleWakeup; aborting` and stop.
31
-
32
- Call `EnterWorktree` with no arguments before any API call, file read, or
33
- edit. Agent-view sessions start in the shared checkout; Bash (`gh`, `git`)
34
- does not auto-isolate. Do not proceed until the working directory contains
35
- `.claude/worktrees/`. If `EnterWorktree` fails, report the failure and stop.
36
-
37
- `EnterWorktree` isolates the session repo. When the PR lives in a different
38
- repo, Step 1.5 routes the working directory into a **PR worktree** of that
39
- repo on its head branch (routine, never a pause). See
40
- [`reference/per-tick.md` § Step 1.5](reference/per-tick.md).
41
-
42
- ## Resume from a prior run
43
-
44
- Before Step 0, check
45
- `~/.claude/runtime/pr-loop/bugteam-pr-<PR number>/handoff.json`. When
46
- `$CLAUDE_JOB_DIR/pr-converge-state.json` is absent but that handoff exists, seed
47
- `phase`, `tick_count`, and the clean-at SHAs from the run's `state-copy.json`, so
48
- a fresh session continues where the last one stopped rather than restarting at
49
- CODE_REVIEW.
50
-
51
- ## Copilot quota pre-check (start of run)
52
-
53
- On the first tick, apply the `reviewer-gates` skill's Copilot quota gate
54
- (`../reviewer-gates/SKILL.md` § Gate 2) — once per run, never per tick. The
55
- flag lives in `pr-converge-state.json` as `copilot_down`, and every tick reads
56
- it. While `copilot_down` is true, the tick skips all Copilot work — no fetch,
57
- no request, no poll, no agent — and exports
58
- `CLAUDE_REVIEWS_DISABLED="copilot"` in that tick's shell before
59
- `check_convergence.py`, so the check bypasses the Copilot review gate and the
60
- pending-requested-reviews gate and the run still marks ready on the remaining
61
- signals.
62
-
63
- ## Copilot findings — tier, verify, then route
64
-
65
- Tier, verify, and route each Copilot finding via
66
- [`copilot-finding-triage`](../copilot-finding-triage/SKILL.md) (self-healing
67
- auto-fix; code-concern verify then confirmed / refuted / inconclusive).
68
-
69
- **pr-converge phase routing after triage:**
70
-
71
- - Self-healing and **confirmed** findings join the fix tick on `current_head`;
72
- after push, reset clean-at SHAs, set `phase = CODE_REVIEW`, return to Step 5.
73
- - **Refuted** findings resolve clean on the thread; no phase change.
74
- - One or more **inconclusive** findings: do not mark ready. Run the triage
75
- skill's user gate (ntfy + 45-minute hold across ticks; persist the deadline so
76
- each tick reads it on entry). Act on the user's direction inside the window;
77
- on timeout, teardown and report the findings un-reviewed.
78
- - Enter `COPILOT_WAIT` only from gate (d) after requesting a Copilot review
79
- (Step 7 → 7a). Stay on `COPILOT_WAIT` until a review surfaces at
80
- `current_head`, `copilot_wait_count >= 3` hard-blocks, or `copilot_down`
81
- skips the Copilot path entirely.
82
-
83
- ## Budget-aware tick boundaries
84
-
85
- Before starting any tick, estimate whether the remaining session/usage
86
- budget covers one full clean tick (worst case: a BUGBOT fetch + a
87
- full-diff CODE_REVIEW + a fix commit + replies). If it does not, do not
88
- start the tick. Stop at the current tick boundary: write updated state to
89
- `$CLAUDE_JOB_DIR/pr-converge-state.json`, write the durable handoff (see
90
- [State persistence](#state-persistence)), then report the exact resume
91
- command (`/pr-converge <PR URL>`) and the persisted `phase`/`tick_count`.
92
- A tick cut off mid-flight poisons the resume state — clean SHAs recorded
93
- against work that never landed — so an unstarted tick is always cheaper
94
- than a half-finished one.
95
-
96
- ## Findings discipline
97
-
98
- Every finding, reply, and report states verified facts only — no hedging
99
- language (`likely`, `probably`, `should`, `appears to`). Verify each
100
- claim against the code on `current_head` before stating it; the
101
- anti-hallucination Stop hook rejects hedged output, forcing a rework
102
- pass. A claim that cannot be verified is reported as unverified, not
103
- softened.
104
-
105
- ## State persistence
106
-
107
- Single-PR mode persists loop state to `$CLAUDE_JOB_DIR/pr-converge-state.json`.
108
- On tick entry, read this file if it exists to restore phase, tick_count, and
109
- clean-at SHAs. On tick exit, write updated state before calling ScheduleWakeup
110
- so the next tick resumes with accurate state.
111
-
112
- After the state write and before ScheduleWakeup, write the durable handoff so a
113
- fresh session in a new job can resume this run:
114
-
115
- ```
116
- python "$HOME/.claude/skills/_shared/pr-loop/scripts/write_handoff.py" \
117
- --pr-number <N> --head-ref <branch> --phase <phase> \
118
- --resume-command "/pr-converge <PR URL>" \
119
- --state-file "$CLAUDE_JOB_DIR/pr-converge-state.json" \
120
- --completed-steps "<clean phases this run>"
121
- ```
122
-
123
- It writes `handoff.json`, `HANDOFF.md`, and `state-copy.json` under
124
- `~/.claude/runtime/pr-loop/<run-name>/`. The job-dir state stays the source of
125
- truth for a resumed tick; the handoff copy is the pointer a fresh session reads
126
- when `$CLAUDE_JOB_DIR` is gone.
127
-
128
- Fields: `phase`, `tick_count`, `bugbot_clean_at`, `code_review_clean_at`,
129
- `bugteam_clean_at`, `copilot_clean_at`, `merge_state_status`, `current_head`,
130
- `bugbot_acknowledged_at`, `bugbot_down`, `copilot_down`,
131
- `bugteam_skill_invoked_at_head`, `bugteam_skill_invoked_at_tick`,
132
- `agents_session_id`, `persistent_agents`.
133
-
134
- ## Persistent per-step agents
135
-
136
- Three step-scoped agents persist across ticks so their context carries
137
- forward: `fix_executor`, `thread_sweep`, and `copilot_watch`, recorded in
138
- the `persistent_agents` map
139
- ([`reference/state-schema.md`](reference/state-schema.md)).
140
-
141
- - **Resume:** read `persistent_agents.<key>`. When an entry exists,
142
- `SendMessage` to the stored `agent_id` with a tick payload that restates
143
- the PR scope, `current_head`, the PR worktree path, this tick's findings
144
- or threads, and the report-back contract. Bump `last_used_tick`, then
145
- await completion.
146
- - **First spawn:** `Agent(subagent_type: "clean-coder", name:
147
- "prc-fix-<PR#>")` — the `name` makes the agent a persistent teammate
148
- that idles awaiting messages. Record `{agent_id, created_tick,
149
- last_used_tick}` under the step key. Keep the spawn prompt fix-shaped,
150
- never audit-shaped: the `pr_converge_bugteam_enforcer` hook blocks
151
- audit-shaped clean-coder spawns during the BUGTEAM phase.
152
- - **Stale or dead id:** on a `SendMessage` failure, or no acknowledgment
153
- within one bounded wait, drop the map entry, spawn a fresh named agent,
154
- record it, and continue the tick. Never abort a tick on a stale id;
155
- never retry the same dead id.
156
- - **Fresh every round (never persisted):** the Step 5 host-aware
157
- `invoke_code_review.py` / `/code-review high --fix` pass and the Step 6
158
- bugteam audit (unbiased eyes each round; the enforcer needs the formal
159
- Skill call), and every `code-verifier` — a named code-verifier never fires
160
- `SubagentStop`, so no verdict mints (see the named-`code-verifier` entry
161
- in the Gotchas list below).
162
- - **Shutdown:** at loop end (convergence or a stop condition), send each
163
- persistent agent a shutdown request and clear `persistent_agents` before
164
- the `pr-loop-lifecycle` Close.
165
-
166
- ## Gotchas
167
-
168
- Highest-signal content. Append a bullet each time a tick fails in a new
169
- way — these are the hard-won lessons that keep the loop honest. Once this
170
- grows to 5 or more items, suggest spinning up a subagent to investigate, fix,
171
- post a fresh PR in a fresh branch based on origin main to the user.
172
-
173
- - **`ScheduleWakeup` not in subagent tool registries** — background
174
- `general-purpose` tick cannot schedule re-entry; only parent session
175
- with `ScheduleWakeup` in registry can call it.
176
- - **`state.json` without §Concurrency lock loses merges** when teammates
177
- finish in same wall-clock window.
178
- - **`tick_count` must not double-increment** — conversation state line
179
- only when **no** `state.json`; with `state.json`, only the
180
- orchestrator bump increments.
181
- - **Bugbot trigger and detection** — CI check-run based. Full flow at
182
- [`per-tick.md` Step 3](reference/per-tick.md); see also
183
- `~/.claude/skills/pr-converge/scripts/check_bugbot_ci.py --help`.
184
- - **Bot login fields differ by endpoint** — `get_reviews` returns
185
- `.user.login` (object), but `get_review_comments` returns `.author`
186
- (string, not an object). Always check the correct fields and use
187
- case-insensitive substring matching on login values, never strict
188
- equality.
189
- - **`isOutdated` has dual scope** — GitHub marks a thread `isOutdated=true`
190
- when the line it anchors to has changed since the comment was posted. The
191
- machine gate (`check_convergence.py` / [convergence-gates.md](reference/convergence-gates.md)
192
- gate (e)) excludes `isOutdated == true` bot threads from the fail count —
193
- only non-outdated unresolved bot threads fail the gate. The agent-side
194
- unresolved-thread sweep in the shared fix protocol
195
- ([`../../_shared/pr-loop/fix-protocol.md`](../../_shared/pr-loop/fix-protocol.md)
196
- step 12; skill deltas in [`reference/fix-protocol.md`](reference/fix-protocol.md))
197
- still verifies outdated unresolved threads against HEAD before resolve when
198
- the protocol requires it (the original concern can still apply when the fix
199
- moved rather than landed).
200
- - **Tilde paths fail on Windows Git Bash** — `~/.claude/skills/...`
201
- resolves to the wrong home directory in Bash-tool contexts. Use
202
- `$HOME/.claude/skills/...` in shell invocations or `Path.home() /
203
- ".claude/skills/..."` in Python scripts. Script invocations through
204
- Bash that reference `~` produce "file not found" errors
205
- indistinguishable from actual script failures.
206
- - **PowerShell cmdlets fail in Bash tool** — `.ps1` scripts and
207
- `pwsh` calls run through the PowerShell tool, not Bash. Bash on
208
- Windows is Git Bash which cannot execute PowerShell cmdlets. Route all
209
- PowerShell work through the PowerShell tool or `pwsh -NoProfile -File`.
210
- - **Cross-repo PR: route cwd into the PR worktree before Step 5 review** —
211
- `invoke_code_review.py` and `/code-review high --fix` audit the repo of the
212
- cwd (the helper's `--cwd`). When the session is rooted in a different repo
213
- than the PR, `EnterWorktree` cannot re-root (it is scoped to the session's
214
- repo); resolve the PR worktree and `cd` into it per
215
- [Step 1.5](reference/per-tick.md). Skipping this reviews and edits the
216
- wrong repo. The route is routine and automatic — never a material fork
217
- to pause on.
218
- - **A named/teammate `code-verifier` never mints a verdict** — In a background-job session, an `Agent`-tool `code-verifier` spawned with a `name` (or otherwise as a persistent teammate) goes idle/"available" awaiting messages rather than terminating, so its `SubagentStop` never fires. `verifier_verdict_minter.py` mints the verdict only on `SubagentStop`, so no verdict file is written and `verified_commit_gate` blocks the `git commit`/`git push` with "no passing verification verdict" even though the verifier emitted `all_pass`. A `shutdown_request` is ignored and `TaskStop` cannot resolve the teammate's id. Spawn the code-verifier as a one-shot agent with NO `name` (a plain async `Agent` call) so it runs to completion and fires `SubagentStop`, minting the verdict bound to the live surface. Keep the work tree frozen between verification and the commit so the minted surface hash still matches.
219
-
220
- ## Progress checklist
221
-
222
- State variables (`phase`, `bugbot_clean_at`, `code_review_clean_at`,
223
- `bugteam_clean_at`, `copilot_clean_at`, `merge_state_status`, counters) are
224
- defined in [`reference/state-schema.md`](reference/state-schema.md). Ground rules
225
- in [`reference/ground-rules.md`](reference/ground-rules.md).
226
-
227
- Each step references its spoke file for full procedural detail — MCP calls,
228
- script invocations, decision criteria. Every "return to Step N" means the next
229
- tick starts fresh from that step.
230
-
231
- **Hard gate: do not advance from any step while ANY unresolved review
232
- thread exists on the PR.** Sweep semantics and per-thread handling live in
233
- the shared fix protocol
234
- ([`../../_shared/pr-loop/fix-protocol.md`](../../_shared/pr-loop/fix-protocol.md)
235
- step 12; skill deltas in [`reference/fix-protocol.md`](reference/fix-protocol.md)).
236
-
237
- **Full-PR-diff rule: every CODE-REVIEW round (Step 5) and every BUGTEAM
238
- round (Step 6) covers the FULL `origin/main...HEAD` diff — every file
239
- the PR touches.** A round that scopes to a subset — only the last commit,
240
- only files touched since the prior clean SHA, only bugbot-flagged paths,
241
- or any other delta cut — does not satisfy the gate, and a "clean" verdict
242
- against a partial diff is not a valid clean. Re-run the round against the
243
- full diff before recording `code_review_clean_at` or treating the bugteam
244
- round as converged. This rule holds every tick, every loop, every PR.
245
-
246
- - [ ] **Step 0: Open the run**
247
- Apply the `pr-loop-lifecycle` skill's Open section
248
- (`../pr-loop-lifecycle/SKILL.md`): permission grant + worktree preflight.
249
-
250
- - [ ] **Step 1: Resolve PR scope + PR worktree**
251
- Apply Step 1.5 scope resolution in
252
- [`reference/per-tick.md`](reference/per-tick.md). Resolve the **PR
253
- worktree** the local checkout every local step this tick targets:
254
- the `EnterWorktree` checkout when the PR shares the session's repo,
255
- else a checkout of the PR's repo that the working directory routes
256
- into via `cd`. Cross-repo routing is automatic, not a fork.
257
- See: [`reference/per-tick.md` § Step 1](reference/per-tick.md)
258
- and [§ Step 1.5](reference/per-tick.md)
259
-
260
- - [ ] **Step 2: Initialize loop state**
261
- `phase = CODE_REVIEW`; all counters at zero; `run_name` resolved.
262
-
263
- - [ ] **Step 3: Mergeability check**
264
- See: [`reference/convergence-gates.md` § (c)](reference/convergence-gates.md)
265
-
266
- ```
267
- pull_request_read(method="get") .mergeable_state, .mergeable
268
- ```
269
-
270
- - [ ] mergeable advance to Step 4
271
- - [ ] not mergeable → rebase → force-push return to Step 1
272
-
273
- - [ ] **Step 4: BUGBOT — terminal Bugbot confirmation gate**
274
- Step 6 routes here after BUGTEAM converges. Bugbot confirms code the
275
- internal passes already drove to clean.
276
- See: [`reference/per-tick.md` § BUGBOT terminal gate + Step 3](reference/per-tick.md);
277
- availability and trigger via `reviewer-gates`
278
- (`../reviewer-gates/SKILL.md` § Gate 1 / Gate 3).
279
-
280
- - [ ] **disabled / down** → `bugbot_down = true` → Step 7
281
- - [ ] **dirty on `current_head`** → apply shared fix protocol
282
- ([`../../_shared/pr-loop/fix-protocol.md`](../../_shared/pr-loop/fix-protocol.md);
283
- skill deltas in [`reference/fix-protocol.md`](reference/fix-protocol.md))
284
- → push → reset push-invalidated markers → `phase = CODE_REVIEW` → Step 5
285
- - [ ] **clean on `current_head`** → zero unresolved threads (else fix + resolve first)
286
- → `bugbot_clean_at = current_head` → Step 7
287
- - [ ] **no review / commit_id mismatch** → `reviewer-gates` Bugbot flow (Gate 3):
288
- silent pass → stamp + Step 7; queued/triggered → 360s wakeup → Step 4;
289
- down → `bugbot_down = true` → Step 7
290
-
291
- - [ ] **Step 5: CODE-REVIEW — static sweep, review, fix, advance**
292
- Entry phase every tick; re-entered after any fix push.
293
- See: [`reference/per-tick.md` § CODE_REVIEW entry](reference/per-tick.md).
294
- Pre-condition: cwd is the Step 1.5 PR worktree on `current_head`.
295
- Scope: FULL `origin/main...HEAD` diff every tick (no path args, no delta cut).
296
- Review always runs at effort high on model opus through
297
- `invoke_code_review.py`. Mode decision inputs: host profile + session
298
- model. Call:
299
- `python "$HOME/.claude/scripts/invoke_code_review.py" --cwd <PR-worktree>
300
- --session-model <alias>`. Chain mode uses that cwd and empty stdin; the
301
- chain process never commits and never pushes. JSON stdout carries
302
- `mode` (`in_session` | `chain`), `served_command`, `returncode`, and
303
- `dirty_tree`. Config/host errors still emit that JSON with non-zero
304
- `returncode` (no traceback-only failure).
305
-
306
- - [ ] **Static sweep fails** → apply shared fix protocol → push → reset markers
307
- → stay CODE_REVIEW → Step 5
308
- - [ ] **`mode == in_session`** (Claude host, session model opus) → run
309
- `/code-review high --fix` in-session (no path args)
310
- - [ ] **`mode == chain`** (any other host or non-opus session) → helper
311
- already ran the headless review; read `returncode`,
312
- `served_command`, and `dirty_tree` from JSON
313
- - [ ] **failed review** (`returncode != 0`, or chain with null
314
- `served_command`) → do not set `code_review_clean_at` → stay
315
- CODE_REVIEW → Step 5
316
- - [ ] **fixes applied** (`dirty_tree` true / working tree dirty) →
317
- commit + push via shared fix protocol → reset markers → stay
318
- CODE_REVIEW → Step 5
319
- - [ ] **clean** (successful serve: `returncode == 0`, chain
320
- `served_command` non-null when chain, and `dirty_tree` false) →
321
- zero unresolved threads (else fix + resolve) →
322
- `code_review_clean_at = current_head` → `phase = BUGTEAM` → Step 6
323
-
324
- - [ ] **Step 6: BUGTEAM — run, decide, fix, reply, resolve**
325
- See: [`reference/per-tick.md` § Step 2 BUGTEAM](reference/per-tick.md);
326
- [`../bugteam/SKILL.md`](../bugteam/SKILL.md).
327
- Pre-condition: `code_review_clean_at == current_head`.
328
- Mandatory: `Skill({skill: "bugteam", args: "<PR URL>"})` this tick
329
- (enforcer-blocked otherwise; `qbug` is not a substitute). Scope: FULL
330
- `origin/main...HEAD` diff. Re-resolve HEAD after bugteam.
331
-
332
- - [ ] **bugteam pushed** → verify threads replied + resolved → reset markers
333
- → `phase = CODE_REVIEW` → 360s wakeup → Step 5
334
- - [ ] **converged, no push** → zero unresolved threads →
335
- `bugteam_clean_at = current_head` → `phase = BUGBOT` → Step 4
336
- - [ ] **findings without committed fixes** → apply shared fix protocol → push →
337
- reset markers → `phase = CODE_REVIEW` → Step 5
338
-
339
- - [ ] **Step 7: Convergence gates**
340
- Full procedure: [`reference/convergence-gates.md`](reference/convergence-gates.md).
341
-
342
- Pre-condition: Step 6 converged AND (`bugbot_clean_at == current_head` OR
343
- `bugbot_down`). The terminal Bugbot gate (Step 4) sets that state just
344
- before these gates run. Count unresolved threads before each gate.
345
- Every gate records evidence; gate (f) cites evidence from (a)–(e).
346
-
347
- - [ ] **(a) Copilot findings** — fetch Copilot on `current_head`; dirty → fix + return to Step 5; clean → stamp `copilot_clean_at`; absent → continue; when `copilot_down`, skip
348
- - [ ] **(b) Claude reviewer** — fetch Claude on `current_head`; dirty → fix + return to Step 5; clean or absent → continue
349
- - [ ] **(c) Mergeability** — `mergeable_state == "clean"` and `mergeable == true`; dirty → rebase + return to Step 1; blocked/behind/unknown/unstable → hard blocker
350
- - [ ] **(d) Post-convergence Copilot request** — request Copilot when not pending and not `copilot_down`; enter `COPILOT_WAIT` (Step 7a); when `copilot_down`, skip to (e)
351
- - [ ] **(e) Thread-resolution** — zero unresolved threads across the PR; else sweep + fix/resolve
352
- - [ ] **(f) Mark ready** — run `check_convergence.py`; exit 0 → `update_pull_request(draft=false)` → Step 8; exit 1 → fix path; exit 2 → retry/stop
353
-
354
- - [ ] **Step 7a: COPILOT_WAIT — fetch Copilot, decide**
355
- See: [`reference/per-tick.md` § Step 2 COPILOT_WAIT](reference/per-tick.md).
356
- Skipped entirely when `copilot_down` (gate (d) never enters this phase).
357
-
358
- - [ ] **clean** → `copilot_clean_at = current_head` → Step 7 (re-validate (b), (c), (e), (f))
359
- - [ ] **dirty** → apply shared fix protocol
360
- ([`../../_shared/pr-loop/fix-protocol.md`](../../_shared/pr-loop/fix-protocol.md);
361
- skill deltas in [`reference/fix-protocol.md`](reference/fix-protocol.md))
362
- → push → reset markers → `phase = CODE_REVIEW` → Step 5
363
- - [ ] **no review yet** → increment `copilot_wait_count` → ≥ 3 hard-blocks;
364
- else 360s wakeup → Step 7a next tick
365
-
366
- - [ ] **Step 8: Clean working tree**
367
- `pr-loop-lifecycle` Close (`../pr-loop-lifecycle/SKILL.md`).
368
- See: [`pr-loop-lifecycle/reference/teardown-publish-permissions.md` § Clean working tree](../pr-loop-lifecycle/reference/teardown-publish-permissions.md)
369
-
370
- - [ ] **Step 9: Rewrite PR description**
371
- `pr-loop-lifecycle` Close.
372
- See: [`pr-loop-lifecycle/reference/teardown-publish-permissions.md` § Publish the final PR description](../pr-loop-lifecycle/reference/teardown-publish-permissions.md)
373
-
374
- - [ ] **Step 10: Revoke project permissions (always)**
375
- `pr-loop-lifecycle` Close (`../pr-loop-lifecycle/SKILL.md` § Close).
376
-
377
- - [ ] **Step 11: Print final report**
378
- Print this block verbatim — no paraphrase, no extra commentary:
379
- ```
380
- /pr-converge exit: converged
381
- Loops: <N>
382
- Final commit: <SHA>
383
- ```
384
-
385
- ## Edge cases
386
-
387
- | Situation | Read |
388
- |---|---|
389
- | Multi-PR session (`state.json` exists) | [`reference/multi-pr-orchestration.md`](reference/multi-pr-orchestration.md) |
390
- | Hard blocker or user stops loop | [`reference/stop-conditions.md`](reference/stop-conditions.md) |
391
- | Tick is ambiguous against the steps above | [`reference/examples.md`](reference/examples.md) |
392
-
393
- ## Depends on / invokes
394
-
395
- | Skill / path | Role |
396
- |---|---|
397
- | `pr-loop-lifecycle` | Open (permission grant + worktree preflight) and Close (cleanup, PR description, revoke) |
398
- | `reviewer-gates` | Copilot quota gate, Bugbot availability, Bugbot trigger flow |
399
- | `copilot-finding-triage` | Tier, verify, and route each Copilot finding |
400
- | `bugteam` | Full-diff bug audit in Step 6 (Skill invocation mandatory) |
401
- | `pr-loop-cloud-transport` | When `gh` is unavailable or unauthenticated |
402
- | [`../../_shared/pr-loop/fix-protocol.md`](../../_shared/pr-loop/fix-protocol.md) | Shared 13-step fix sequence (TDD, commit, push, reply, resolve) |
403
- | [`reference/fix-protocol.md`](reference/fix-protocol.md) | pr-converge deltas on the shared fix protocol |
404
-
405
- ## Package file index
406
-
407
- | Path | Purpose |
408
- |---|---|
409
- | `SKILL.md` | Hub: pre-flight, state, progress checklist, gotchas |
410
- | `CLAUDE.md` | Package map for agents working in this skill |
411
- | `pr_converge_skill_constants/` | Importable constants for skill scripts |
412
- | `reference/per-tick.md` | Full per-tick procedure (phases, cwd routing, pacing) |
413
- | `reference/convergence-gates.md` | Six gates before mark-ready |
414
- | `reference/fix-protocol.md` | pr-converge fix-protocol deltas |
415
- | `reference/ground-rules.md` | Non-negotiable loop constraints |
416
- | `reference/state-schema.md` | `pr-converge-state.json` fields |
417
- | `reference/stop-conditions.md` | Hard stops without convergence |
418
- | `reference/multi-pr-orchestration.md` | Multi-PR session orchestration |
419
- | `reference/examples.md` | Worked tick sequences |
420
- | `reference/obstacles/` | Per-obstacle fix runbooks |
421
- | `scripts/` | Convergence helpers, Copilot fetch, fix-reply poster, tests |
422
- | `workflows/schedule-wakeup-loop.md` | ScheduleWakeup pacing |
1
+ ---
2
+ name: pr-converge
3
+ description: >-
4
+ Loops Cursor Bugbot, a code review, a bug audit, and Copilot on the current
5
+ PR, applying TDD fixes until all are clean on one HEAD. Use when the user says
6
+ '/pr-converge', 'drive PR to convergence', 'loop bugbot and bugteam', 'babysit
7
+ bugbot and bugteam', 'until both are clean', or 'converge this PR'.
8
+ ---
9
+
10
+ # PR Converge
11
+
12
+ One tick per invocation. A code-review ↔ bugteam ↔ Bugbot ↔ Copilot loop on
13
+ a draft PR: the internal code-review and bugteam passes drive the code to clean
14
+ first, then Cursor Bugbot and Copilot run as terminal confirmation gates, until
15
+ all are clean on the same `HEAD` and mergeable.
16
+
17
+ ## Transport check (before any GitHub step)
18
+
19
+ Run `command -v gh`; when it succeeds, run `gh auth status`; once the PR
20
+ scope is resolved, run `gh api repos/<owner>/<repo> --jq .permissions.push`
21
+ and take `true` as the pass. When any check fails, run the
22
+ `pr-loop-cloud-transport` skill first and route every `gh` operation in this
23
+ skill through its substitution matrix.
24
+
25
+ ## Pre-flight
26
+
27
+ Pause and physically scan the tool list at the top of this conversation
28
+ for the literal string `ScheduleWakeup`. If you see it, proceed. If the
29
+ string is absent after scanning, report `pr-converge requires
30
+ ScheduleWakeup; aborting` and stop.
31
+
32
+ Call `EnterWorktree` with no arguments before any API call, file read, or
33
+ edit. Agent-view sessions start in the shared checkout; Bash (`gh`, `git`)
34
+ does not auto-isolate. Do not proceed until the working directory contains
35
+ `.claude/worktrees/`. If `EnterWorktree` fails, report the failure and stop.
36
+
37
+ `EnterWorktree` isolates the session repo. When the PR lives in a different
38
+ repo, Step 1.5 routes the working directory into a **PR worktree** of that
39
+ repo on its head branch (routine, never a pause). See
40
+ [`reference/per-tick.md` § Step 1.5](reference/per-tick.md).
41
+
42
+ ## Resume from a prior run
43
+
44
+ Before Step 0, check
45
+ `~/.claude/runtime/pr-loop/bugteam-pr-<PR number>/handoff.json`. When
46
+ `$CLAUDE_JOB_DIR/pr-converge-state.json` is absent but that handoff exists, seed
47
+ `phase`, `tick_count`, and the clean-at SHAs from the run's `state-copy.json`, so
48
+ a fresh session continues where the last one stopped rather than restarting at
49
+ CODE_REVIEW.
50
+
51
+ ## Copilot quota pre-check (start of run)
52
+
53
+ On the first tick, apply the `reviewer-gates` skill's Copilot quota gate
54
+ (`../reviewer-gates/SKILL.md` § Gate 2) — once per run, never per tick. The
55
+ flag lives in `pr-converge-state.json` as `copilot_down`, and every tick reads
56
+ it. While `copilot_down` is true, the tick skips all Copilot work — no fetch,
57
+ no request, no poll, no agent — and exports
58
+ `CLAUDE_REVIEWS_DISABLED="copilot"` in that tick's shell before
59
+ `check_convergence.py`, so the check bypasses the Copilot review gate and the
60
+ pending-requested-reviews gate and the run still marks ready on the remaining
61
+ signals.
62
+
63
+ ## Copilot findings — tier, verify, then route
64
+
65
+ Tier, verify, and route each Copilot finding via
66
+ [`copilot-finding-triage`](../copilot-finding-triage/SKILL.md) (self-healing
67
+ auto-fix; code-concern verify then confirmed / refuted / inconclusive).
68
+
69
+ **pr-converge phase routing after triage:**
70
+
71
+ - Self-healing and **confirmed** findings join the fix tick on `current_head`;
72
+ after push, reset clean-at SHAs, set `phase = CODE_REVIEW`, return to Step 5.
73
+ - **Refuted** findings resolve clean on the thread; no phase change.
74
+ - One or more **inconclusive** findings: do not mark ready. Run the triage
75
+ skill's user gate (ntfy + 45-minute hold across ticks; persist the deadline so
76
+ each tick reads it on entry). Act on the user's direction inside the window;
77
+ on timeout, teardown and report the findings un-reviewed.
78
+ - Enter `COPILOT_WAIT` only from gate (d) after requesting a Copilot review
79
+ (Step 7 → 7a). Stay on `COPILOT_WAIT` until a review surfaces at
80
+ `current_head`, `copilot_wait_count >= 3` hard-blocks, or `copilot_down`
81
+ skips the Copilot path entirely.
82
+
83
+ ## Budget-aware tick boundaries
84
+
85
+ Before starting any tick, estimate whether the remaining session/usage
86
+ budget covers one full clean tick (worst case: a BUGBOT fetch + a
87
+ full-diff CODE_REVIEW + a fix commit + replies). If it does not, do not
88
+ start the tick. Stop at the current tick boundary: write updated state to
89
+ `$CLAUDE_JOB_DIR/pr-converge-state.json`, write the durable handoff (see
90
+ [State persistence](#state-persistence)), then report the exact resume
91
+ command (`/pr-converge <PR URL>`) and the persisted `phase`/`tick_count`.
92
+ A tick cut off mid-flight poisons the resume state — clean SHAs recorded
93
+ against work that never landed — so an unstarted tick is always cheaper
94
+ than a half-finished one.
95
+
96
+ ## Findings discipline
97
+
98
+ Every finding, reply, and report states verified facts only — no hedging
99
+ language (`likely`, `probably`, `should`, `appears to`). Verify each
100
+ claim against the code on `current_head` before stating it; the
101
+ anti-hallucination Stop hook rejects hedged output, forcing a rework
102
+ pass. A claim that cannot be verified is reported as unverified, not
103
+ softened.
104
+
105
+ ## State persistence
106
+
107
+ Single-PR mode persists loop state to `$CLAUDE_JOB_DIR/pr-converge-state.json`.
108
+ On tick entry, read this file if it exists to restore phase, tick_count, and
109
+ clean-at SHAs. On tick exit, write updated state before calling ScheduleWakeup
110
+ so the next tick resumes with accurate state.
111
+
112
+ After the state write and before ScheduleWakeup, write the durable handoff so a
113
+ fresh session in a new job can resume this run:
114
+
115
+ ```
116
+ python "$HOME/.claude/skills/_shared/pr-loop/scripts/write_handoff.py" \
117
+ --pr-number <N> --head-ref <branch> --phase <phase> \
118
+ --resume-command "/pr-converge <PR URL>" \
119
+ --state-file "$CLAUDE_JOB_DIR/pr-converge-state.json" \
120
+ --completed-steps "<clean phases this run>"
121
+ ```
122
+
123
+ It writes `handoff.json`, `HANDOFF.md`, and `state-copy.json` under
124
+ `~/.claude/runtime/pr-loop/<run-name>/`. The job-dir state stays the source of
125
+ truth for a resumed tick; the handoff copy is the pointer a fresh session reads
126
+ when `$CLAUDE_JOB_DIR` is gone.
127
+
128
+ Fields: `phase`, `tick_count`, `bugbot_clean_at`, `code_review_clean_at`,
129
+ `bugteam_clean_at`, `copilot_clean_at`, `merge_state_status`, `current_head`,
130
+ `bugbot_acknowledged_at`, `bugbot_down`, `copilot_down`,
131
+ `bugteam_skill_invoked_at_head`, `bugteam_skill_invoked_at_tick`,
132
+ `agents_session_id`, `persistent_agents`.
133
+
134
+ ## Persistent per-step agents
135
+
136
+ Three step-scoped agents persist across ticks so their context carries
137
+ forward: `fix_executor`, `thread_sweep`, and `copilot_watch`, recorded in
138
+ the `persistent_agents` map
139
+ ([`reference/state-schema.md`](reference/state-schema.md)).
140
+
141
+ - **Resume:** read `persistent_agents.<key>`. When an entry exists,
142
+ `SendMessage` to the stored `agent_id` with a tick payload that restates
143
+ the PR scope, `current_head`, the PR worktree path, this tick's findings
144
+ or threads, and the report-back contract. Bump `last_used_tick`, then
145
+ await completion.
146
+ - **First spawn:** `Agent(subagent_type: "clean-coder", name:
147
+ "prc-fix-<PR#>")` — the `name` makes the agent a persistent teammate
148
+ that idles awaiting messages. Record `{agent_id, created_tick,
149
+ last_used_tick}` under the step key. Keep the spawn prompt fix-shaped,
150
+ never audit-shaped: the `pr_converge_bugteam_enforcer` hook blocks
151
+ audit-shaped clean-coder spawns during the BUGTEAM phase.
152
+ - **Stale or dead id:** on a `SendMessage` failure, or no acknowledgment
153
+ within one bounded wait, drop the map entry, spawn a fresh named agent,
154
+ record it, and continue the tick. Never abort a tick on a stale id;
155
+ never retry the same dead id.
156
+ - **Fresh every round (never persisted):** the Step 5 host-aware
157
+ `invoke_code_review.py` / `/code-review high --fix` pass and the Step 6
158
+ bugteam audit (unbiased eyes each round; the enforcer needs the formal
159
+ Skill call), and every `code-verifier` — a named code-verifier never fires
160
+ `SubagentStop`, so no verdict mints (see the named-`code-verifier` entry
161
+ in the Gotchas list below).
162
+ - **Shutdown:** at loop end (convergence or a stop condition), send each
163
+ persistent agent a shutdown request and clear `persistent_agents` before
164
+ the `pr-loop-lifecycle` Close.
165
+
166
+ ## Gotchas
167
+
168
+ Highest-signal content. Append a bullet each time a tick fails in a new
169
+ way — these are the hard-won lessons that keep the loop honest. Once this
170
+ grows to 5 or more items, suggest spinning up a subagent to investigate, fix,
171
+ post a fresh PR in a fresh branch based on origin main to the user.
172
+
173
+ - **`ScheduleWakeup` not in subagent tool registries** — background
174
+ `general-purpose` tick cannot schedule re-entry; only parent session
175
+ with `ScheduleWakeup` in registry can call it.
176
+ - **`state.json` without §Concurrency lock loses merges** when teammates
177
+ finish in same wall-clock window.
178
+ - **`tick_count` must not double-increment** — conversation state line
179
+ only when **no** `state.json`; with `state.json`, only the
180
+ orchestrator bump increments.
181
+ - **Bugbot trigger and detection** — CI check-run based. Full flow at
182
+ [`per-tick.md` Step 3](reference/per-tick.md); see also
183
+ `~/.claude/skills/pr-converge/scripts/check_bugbot_ci.py --help`.
184
+ - **Bot login fields differ by endpoint** — `get_reviews` returns
185
+ `.user.login` (object), but `get_review_comments` returns `.author`
186
+ (string, not an object). Always check the correct fields and use
187
+ case-insensitive substring matching on login values, never strict
188
+ equality.
189
+ - **`isOutdated` has dual scope** — GitHub marks a thread `isOutdated=true`
190
+ when the line it anchors to has changed since the comment was posted. The
191
+ machine gate (`check_convergence.py` / [convergence-gates.md](reference/convergence-gates.md)
192
+ gate (e)) excludes `isOutdated == true` bot threads from the fail count —
193
+ only non-outdated unresolved bot threads fail the gate. The agent-side
194
+ unresolved-thread sweep in the shared fix protocol
195
+ ([`../../_shared/pr-loop/fix-protocol.md`](../../_shared/pr-loop/fix-protocol.md)
196
+ step 12; skill deltas in [`reference/fix-protocol.md`](reference/fix-protocol.md))
197
+ still verifies outdated unresolved threads against HEAD before resolve when
198
+ the protocol requires it (the original concern can still apply when the fix
199
+ moved rather than landed).
200
+ - **Tilde paths fail on Windows Git Bash** — `~/.claude/skills/...`
201
+ resolves to the wrong home directory in Bash-tool contexts. Use
202
+ `$HOME/.claude/skills/...` in shell invocations or `Path.home() /
203
+ ".claude/skills/..."` in Python scripts. Script invocations through
204
+ Bash that reference `~` produce "file not found" errors
205
+ indistinguishable from actual script failures.
206
+ - **PowerShell cmdlets fail in Bash tool** — `.ps1` scripts and
207
+ `pwsh` calls run through the PowerShell tool, not Bash. Bash on
208
+ Windows is Git Bash which cannot execute PowerShell cmdlets. Route all
209
+ PowerShell work through the PowerShell tool or `pwsh -NoProfile -File`.
210
+ - **Cross-repo PR: route cwd into the PR worktree before Step 5 review** —
211
+ `invoke_code_review.py` and `/code-review high --fix` audit the repo of the
212
+ cwd (the helper's `--cwd`). When the session is rooted in a different repo
213
+ than the PR, `EnterWorktree` cannot re-root (it is scoped to the session's
214
+ repo); resolve the PR worktree and `cd` into it per
215
+ [Step 1.5](reference/per-tick.md). Skipping this reviews and edits the
216
+ wrong repo. The route is routine and automatic — never a material fork
217
+ to pause on.
218
+ - **A named/teammate `code-verifier` never mints a verdict** — In a background-job session, an `Agent`-tool `code-verifier` spawned with a `name` (or otherwise as a persistent teammate) goes idle/"available" awaiting messages rather than terminating, so its `SubagentStop` never fires. `verifier_verdict_minter.py` mints the verdict only on `SubagentStop`, so no verdict file is written and `verified_commit_gate` blocks the `git commit`/`git push` with "no passing verification verdict" even though the verifier emitted `all_pass`. A `shutdown_request` is ignored and `TaskStop` cannot resolve the teammate's id. Spawn the code-verifier as a one-shot agent with NO `name` (a plain async `Agent` call) so it runs to completion and fires `SubagentStop`, minting the verdict bound to the live surface. Keep the work tree frozen between verification and the commit so the minted surface hash still matches.
219
+
220
+ ## Progress checklist
221
+
222
+ Run the eleven-step per-tick sequence in
223
+ [`reference/progress-checklist.md`](reference/progress-checklist.md): Step 0
224
+ (open the run) through Step 11 (final report), each step pointing to its spoke
225
+ file for MCP calls, script invocations, and decision criteria. State variables
226
+ live in [`reference/state-schema.md`](reference/state-schema.md); ground rules in
227
+ [`reference/ground-rules.md`](reference/ground-rules.md).
228
+
229
+ Two hard gates bind every step:
230
+
231
+ - **No unresolved threads.** Do not advance from any step while any unresolved
232
+ review thread exists on the PR (sweep semantics in the shared fix protocol,
233
+ [`../../_shared/pr-loop/fix-protocol.md`](../../_shared/pr-loop/fix-protocol.md)
234
+ step 12).
235
+ - **Full-PR-diff.** Every CODE-REVIEW (Step 5) and BUGTEAM (Step 6) round covers
236
+ the full `origin/main...HEAD` diff — a "clean" verdict against a partial diff
237
+ is not a valid clean.
238
+
239
+ ## Edge cases
240
+
241
+ | Situation | Read |
242
+ |---|---|
243
+ | Multi-PR session (`state.json` exists) | [`reference/multi-pr-orchestration.md`](reference/multi-pr-orchestration.md) |
244
+ | Hard blocker or user stops loop | [`reference/stop-conditions.md`](reference/stop-conditions.md) |
245
+ | Tick is ambiguous against the steps above | [`reference/examples.md`](reference/examples.md) |
246
+
247
+ ## Depends on / invokes
248
+
249
+ | Skill / path | Role |
250
+ |---|---|
251
+ | `pr-loop-lifecycle` | Open (permission grant + worktree preflight) and Close (cleanup, PR description, revoke) |
252
+ | `reviewer-gates` | Copilot quota gate, Bugbot availability, Bugbot trigger flow |
253
+ | `copilot-finding-triage` | Tier, verify, and route each Copilot finding |
254
+ | `bugteam` | Full-diff bug audit in Step 6 (Skill invocation mandatory) |
255
+ | `pr-loop-cloud-transport` | When `gh` is unavailable or unauthenticated |
256
+ | [`../../_shared/pr-loop/fix-protocol.md`](../../_shared/pr-loop/fix-protocol.md) | Shared 13-step fix sequence (TDD, commit, push, reply, resolve) |
257
+ | [`reference/fix-protocol.md`](reference/fix-protocol.md) | pr-converge deltas on the shared fix protocol |
258
+
259
+ ## Package file index
260
+
261
+ | Path | Purpose |
262
+ |---|---|
263
+ | `SKILL.md` | Hub: pre-flight, state, progress checklist, gotchas |
264
+ | `CLAUDE.md` | Package map for agents working in this skill |
265
+ | `pr_converge_skill_constants/` | Importable constants for skill scripts |
266
+ | `reference/progress-checklist.md` | Per-tick eleven-step checklist (Step 0 open → Step 11 report) |
267
+ | `reference/per-tick.md` | Full per-tick procedure (phases, cwd routing, pacing) |
268
+ | `reference/convergence-gates.md` | Six gates before mark-ready |
269
+ | `reference/fix-protocol.md` | pr-converge fix-protocol deltas |
270
+ | `reference/ground-rules.md` | Non-negotiable loop constraints |
271
+ | `reference/state-schema.md` | `pr-converge-state.json` fields |
272
+ | `reference/stop-conditions.md` | Hard stops without convergence |
273
+ | `reference/multi-pr-orchestration.md` | Multi-PR session orchestration |
274
+ | `reference/examples.md` | Worked tick sequences |
275
+ | `reference/obstacles/` | Per-obstacle fix runbooks |
276
+ | `scripts/` | Convergence helpers, Copilot fetch, fix-reply poster, tests |
277
+ | `workflows/schedule-wakeup-loop.md` | ScheduleWakeup pacing |