claude-dev-env 2.0.2 → 2.2.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.
- package/CLAUDE.md +1 -1
- package/hooks/blocking/CLAUDE.md +1 -0
- package/hooks/blocking/code_rules_shared.py +126 -47
- package/hooks/blocking/config/CLAUDE.md +2 -0
- package/hooks/blocking/config/verified_commit_context_constants.py +21 -0
- package/hooks/blocking/config/verified_commit_gate_output_constants.py +14 -0
- package/hooks/blocking/conftest.py +36 -30
- package/hooks/blocking/convergence_gate_blocker.py +76 -8
- package/hooks/blocking/plain_language_blocker.py +8 -0
- package/hooks/blocking/state_description_blocker.py +4 -1
- package/hooks/blocking/test_code_rules_shared.py +120 -20
- package/hooks/blocking/test_convergence_gate_blocker.py +146 -0
- package/hooks/blocking/test_plain_language_blocker.py +15 -0
- package/hooks/blocking/test_state_description_blocker.py +15 -0
- package/hooks/blocking/test_verified_commit_config_bootstrap.py +18 -0
- package/hooks/blocking/test_verified_commit_gate_additional_context.py +134 -0
- package/hooks/blocking/tests/test_verified_commit_gate.py +41 -0
- package/hooks/blocking/verified_commit_config_bootstrap.py +22 -10
- package/hooks/blocking/verified_commit_gate.py +113 -568
- package/hooks/blocking/verified_commit_gate_parts/CLAUDE.md +28 -0
- package/hooks/blocking/verified_commit_gate_parts/__init__.py +1 -0
- package/hooks/blocking/verified_commit_gate_parts/command_tokenization.py +174 -0
- package/hooks/blocking/verified_commit_gate_parts/deny_payload.py +53 -0
- package/hooks/blocking/verified_commit_gate_parts/deny_reason.py +80 -0
- package/hooks/blocking/verified_commit_gate_parts/directory_resolution.py +170 -0
- package/hooks/blocking/verified_commit_gate_parts/gated_invocations.py +205 -0
- package/hooks/blocking/verified_commit_gate_parts/tests/conftest.py +10 -0
- package/hooks/blocking/verified_commit_gate_parts/tests/test_command_tokenization.py +94 -0
- package/hooks/blocking/verified_commit_gate_parts/tests/test_deny_payload.py +17 -0
- package/hooks/blocking/verified_commit_gate_parts/tests/test_deny_reason.py +38 -0
- package/hooks/blocking/verified_commit_gate_parts/tests/test_directory_resolution.py +71 -0
- package/hooks/blocking/verified_commit_gate_parts/tests/test_gated_invocations.py +61 -0
- package/hooks/hooks_constants/CLAUDE.md +4 -1
- package/hooks/hooks_constants/code_rules_path_utils_constants.py +1 -0
- package/hooks/hooks_constants/convergence_gate_blocker_constants.py +36 -0
- package/hooks/hooks_constants/harness_scratchpad_constants.py +10 -9
- package/hooks/hooks_constants/mypy_integration_constants.py +16 -0
- package/hooks/validators/mypy_integration.py +145 -24
- package/hooks/validators/python_antipattern_checks.py +16 -0
- package/hooks/validators/run_all_validators.py +9 -3
- package/hooks/validators/test_mypy_integration.py +154 -0
- package/hooks/validators/test_python_antipattern_checks.py +112 -1
- package/hooks/validators/test_run_all_validators_pretooluse.py +16 -0
- package/package.json +1 -1
- package/rules/CLAUDE.md +1 -0
- package/rules/verified-commit-gate-skip.md +28 -0
- package/skills/_shared/pr-loop/CLAUDE.md +18 -13
- package/skills/_shared/pr-loop/portable-driver.md +150 -0
- package/skills/_shared/pr-loop/scripts/CLAUDE.md +3 -0
- package/skills/_shared/pr-loop/scripts/build_converge_task_list.py +310 -0
- package/skills/_shared/pr-loop/scripts/portable_converge_driver.py +1637 -0
- package/skills/_shared/pr-loop/scripts/select_converge_pacer.py +215 -0
- package/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/CLAUDE.md +3 -0
- package/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/converge_task_list_constants.py +56 -0
- package/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/pacer_constants.py +47 -0
- package/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/portable_driver_constants.py +181 -0
- package/skills/_shared/pr-loop/scripts/test_build_converge_task_list.py +140 -0
- package/skills/_shared/pr-loop/scripts/test_portable_converge_driver.py +1119 -0
- package/skills/_shared/pr-loop/scripts/test_select_converge_pacer.py +207 -0
- package/skills/auditing-claude-config/CLAUDE.md +2 -1
- package/skills/auditing-claude-config/SKILL.md +114 -176
- package/skills/auditing-claude-config/reference/probe-hook.md +74 -0
- package/skills/autoconverge/CLAUDE.md +6 -3
- package/skills/autoconverge/SKILL.md +421 -346
- package/skills/autoconverge/reference/CLAUDE.md +1 -0
- package/skills/autoconverge/reference/convergence.md +5 -5
- package/skills/autoconverge/reference/copilot-findings.md +51 -0
- package/skills/autoconverge/reference/multi-pr.md +33 -2
- package/skills/autoconverge/reference/stop-conditions.md +9 -6
- package/skills/autoconverge/test_portable_pacer_gate.py +54 -0
- package/skills/closeout/SKILL.md +7 -9
- package/skills/copilot-finding-triage/SKILL.md +21 -11
- package/skills/copilot-review/CLAUDE.md +3 -2
- package/skills/copilot-review/SKILL.md +119 -155
- package/skills/copilot-review/templates/subagent-prompt.md +49 -0
- package/skills/fresh-branch/CLAUDE.md +6 -9
- package/skills/fresh-branch/SKILL.md +84 -33
- package/skills/fresh-branch/scripts/create_fresh_branch.py +445 -0
- package/skills/fresh-branch/scripts/fresh_branch_scripts_constants/__init__.py +1 -0
- package/skills/fresh-branch/scripts/fresh_branch_scripts_constants/fresh_branch_cli_constants.py +74 -0
- package/skills/fresh-branch/scripts/test_create_fresh_branch.py +670 -0
- package/skills/pr-converge/CLAUDE.md +4 -3
- package/skills/pr-converge/SKILL.md +469 -422
- package/skills/pr-converge/reference/CLAUDE.md +1 -0
- package/skills/pr-converge/reference/multi-pr-orchestration.md +5 -1
- package/skills/pr-converge/reference/per-tick.md +51 -24
- package/skills/pr-converge/reference/progress-checklist.md +168 -0
- package/skills/pr-converge/test_portable_pacer_gate.py +67 -0
- package/skills/pr-converge/test_step5_host_branch.py +8 -6
- package/skills/pr-converge/workflows/schedule-wakeup-loop.md +5 -3
- package/skills/pr-loop-cloud-transport/SKILL.md +1 -1
- package/skills/privacy-hygiene/SKILL.md +68 -115
- package/skills/privacy-hygiene/reference/sweep-procedure.md +62 -0
- package/skills/session-log/CLAUDE.md +2 -1
- package/skills/session-log/SKILL.md +4 -26
- package/skills/session-log/templates/frontmatter.md +40 -0
- package/skills/skill-builder/CLAUDE.md +8 -7
- package/skills/skill-builder/SKILL.md +26 -11
- package/skills/skill-builder/references/CLAUDE.md +3 -1
- package/skills/skill-builder/references/delegation-map.md +21 -12
- package/skills/skill-builder/references/description-field.md +9 -11
- package/skills/skill-builder/references/deterministic-elements.md +218 -0
- package/skills/skill-builder/references/self-audit-checklist.md +62 -45
- package/skills/skill-builder/references/skill-modularity.md +8 -9
- package/skills/skill-builder/templates/CLAUDE.md +2 -2
- package/skills/skill-builder/templates/gap-analysis.md +15 -0
- package/skills/skill-builder/workflows/CLAUDE.md +5 -5
- package/skills/skill-builder/workflows/improve-skill.md +18 -9
- package/skills/skill-builder/workflows/new-skill.md +23 -15
- package/skills/skill-builder/workflows/polish-skill.md +28 -21
|
@@ -1,346 +1,421 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: autoconverge
|
|
3
|
-
description: >-
|
|
4
|
-
Drives one draft PR to convergence in one autonomous run
|
|
5
|
-
|
|
6
|
-
commit
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
the
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
launch
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
`pr-loop-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
`
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
`
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
the workflow
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
`blocker: "user-review"
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
`
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
[
|
|
203
|
-
|
|
204
|
-
Copilot
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
the
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
the
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
`
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
read
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
-
|
|
1
|
+
---
|
|
2
|
+
name: autoconverge
|
|
3
|
+
description: >-
|
|
4
|
+
Drives one draft PR to convergence in one autonomous run with a host-selected
|
|
5
|
+
pacer. On workflow: three parallel lenses (code-review, bug-audit, self-review)
|
|
6
|
+
and one-commit fixes via converge.mjs. On portable: pr-converge continuous ticks
|
|
7
|
+
via portable-driver.md. Bugbot, Copilot, and Codex as terminal confirmation
|
|
8
|
+
gates before ready. Use when the user says '/autoconverge', 'autoconverge this
|
|
9
|
+
PR', 'converge this PR in one run', 'run the converge workflow', or 'drive the
|
|
10
|
+
PR to ready autonomously'.
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Autoconverge
|
|
14
|
+
|
|
15
|
+
One launch drives the whole loop to convergence. The `/autoconverge` skill
|
|
16
|
+
scans the tool list, selects a **pacer** (Workflow or portable), then resolves
|
|
17
|
+
PR scope, enters a worktree, grants project permissions, and drives the shared
|
|
18
|
+
converge product to ready (or a named blocker).
|
|
19
|
+
|
|
20
|
+
| Pacer | Host surface | How the loop runs |
|
|
21
|
+
|---|---|---|
|
|
22
|
+
| `workflow` | Tool list includes `Workflow` | `converge.mjs` background pass; state in the workflow journal |
|
|
23
|
+
| `portable` | `Workflow` absent | Continuous in-session ticks per [`../_shared/pr-loop/portable-driver.md`](../_shared/pr-loop/portable-driver.md); same helpers and `check_convergence.py` ready definition |
|
|
24
|
+
|
|
25
|
+
`pr-converge` selects `schedule_wakeup` or `portable` the same way. Both
|
|
26
|
+
entry skills share the helper scripts and the convergence gate.
|
|
27
|
+
|
|
28
|
+
## Run scope: one PR or several
|
|
29
|
+
|
|
30
|
+
Decide the scope from how many PRs the user named, then follow that path:
|
|
31
|
+
|
|
32
|
+
1. **One PR** → the single-PR run described below: one worktree, one pacer
|
|
33
|
+
launch (`converge.mjs` on `pacer=workflow`, portable continuous ticks on
|
|
34
|
+
`pacer=portable`), one teardown.
|
|
35
|
+
2. **Several PRs** → the [Multiple PRs](reference/multi-pr.md) run: on
|
|
36
|
+
`pacer=workflow`, `workflow/converge_multi.mjs` drives every PR in parallel;
|
|
37
|
+
on `pacer=portable`, run the portable driver once per PR (serial or host
|
|
38
|
+
fan-out), then one teardown per PR.
|
|
39
|
+
|
|
40
|
+
The single-PR sections (Requirements, Pre-flight, Run the workflow or portable
|
|
41
|
+
driver, Teardown) each describe one converge run. The multi-PR reference reuses
|
|
42
|
+
them once per PR and adds only what fanning out needs: a per-PR worktree and a
|
|
43
|
+
per-PR teardown loop.
|
|
44
|
+
|
|
45
|
+
## Requirements
|
|
46
|
+
|
|
47
|
+
Scan the tool list for `Workflow` and `ScheduleWakeup`, then select the pacer:
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
python "$HOME/.claude/skills/_shared/pr-loop/scripts/select_converge_pacer.py" \
|
|
51
|
+
--skill autoconverge \
|
|
52
|
+
--has-workflow <0|1> \
|
|
53
|
+
--has-schedule-wakeup <0|1>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
- `pacer=workflow` — continue with Pre-flight and **Run the workflow** below.
|
|
57
|
+
- `pacer=portable` — continue with Pre-flight (portable worktree rules when
|
|
58
|
+
`EnterWorktree` is absent), then the continuous driver in
|
|
59
|
+
[`../_shared/pr-loop/portable-driver.md`](../_shared/pr-loop/portable-driver.md).
|
|
60
|
+
**Do not abort** because the Workflow tool is missing.
|
|
61
|
+
|
|
62
|
+
Transport still needs authenticated GitHub access for the PR's owner (`gh` or
|
|
63
|
+
`pr-loop-cloud-transport`).
|
|
64
|
+
|
|
65
|
+
## Review-lens boundary
|
|
66
|
+
|
|
67
|
+
The code-review lens boundary (workflow agent versus the built-in `/code-review`
|
|
68
|
+
command) is defined on the **Code-review lens** bullet in
|
|
69
|
+
[`reference/convergence.md`](reference/convergence.md).
|
|
70
|
+
|
|
71
|
+
## Transport check (before any GitHub step)
|
|
72
|
+
|
|
73
|
+
Run `command -v gh`; when it succeeds, run `gh auth status`; once the PR
|
|
74
|
+
scope is resolved, run `gh api repos/<owner>/<repo> --jq .permissions.push`
|
|
75
|
+
and take `true` as the pass. When any check fails, run the
|
|
76
|
+
`pr-loop-cloud-transport` skill first and route every `gh` operation in this
|
|
77
|
+
skill through its substitution matrix. The workflow script
|
|
78
|
+
(`workflow/converge.mjs`) embeds `gh` commands and gh-backed helper scripts in
|
|
79
|
+
its agent prompts, so a cloud run also applies the same substitution to those
|
|
80
|
+
agent prompts when it authors the launch — the transport skill covers the
|
|
81
|
+
orchestrating session's own steps, and the script's agent-prompt text carries
|
|
82
|
+
`gh` calls the spawned agents cannot run in a cloud session.
|
|
83
|
+
|
|
84
|
+
## Pre-flight (main session)
|
|
85
|
+
|
|
86
|
+
0. **Build the task list (step 1 of every run).** After Copilot quota / down
|
|
87
|
+
flags and Codex required/down are known, run only:
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
python "$HOME/.claude/skills/_shared/pr-loop/scripts/build_converge_task_list.py" \
|
|
91
|
+
--bugbot-down <0|1> --copilot-down <0|1> \
|
|
92
|
+
--codex-down <0|1> --codex-required <0|1>
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Register every `tasks[]` entry on the session task list. **Final task** is
|
|
96
|
+
always `all_runnable_reviews_clean_same_head` (`done_when` in the JSON).
|
|
97
|
+
The run is complete only when that final task is completed — all runnable
|
|
98
|
+
code reviews CLEAN on the same HEAD. Do not invent tasks in prose. On
|
|
99
|
+
`pacer=portable`, `open-run` returns the same list; still register it as
|
|
100
|
+
step 1 before driving reviews.
|
|
101
|
+
|
|
102
|
+
1. **Enter a worktree.** When `EnterWorktree` is in the tool list, call it with
|
|
103
|
+
no arguments before any `gh`, `git`, file read, or edit. `gh`/`git` Bash
|
|
104
|
+
calls do not auto-isolate, so isolation is mandatory. If it fails, report
|
|
105
|
+
and stop. A bare `EnterWorktree` branches from `origin/main`; step 2
|
|
106
|
+
positions the worktree on the PR's head ref. When `EnterWorktree` is
|
|
107
|
+
absent, isolate with git worktree machinery per
|
|
108
|
+
[`../_shared/pr-loop/portable-driver.md`](../_shared/pr-loop/portable-driver.md)
|
|
109
|
+
§ Isolation and worktree, then continue step 2.
|
|
110
|
+
|
|
111
|
+
2. **Resolve PR scope.** When the user passed a PR URL or number, parse owner,
|
|
112
|
+
repo, and number from it. Otherwise read the current branch's PR:
|
|
113
|
+
`gh pr view --json number,headRefName,url,isDraft,baseRefName`. Capture
|
|
114
|
+
`owner`, `repo`, `prNumber`. Confirm the PR is a draft; if it is already
|
|
115
|
+
ready, mark it draft first (`gh pr ready <n> --repo <o>/<r> --undo`) so the
|
|
116
|
+
loop owns the ready transition.
|
|
117
|
+
|
|
118
|
+
**Position the worktree on the PR branch.** The run reviews
|
|
119
|
+
`git diff origin/main...HEAD` against this worktree's local `HEAD` and pushes
|
|
120
|
+
each fix to the PR branch, so the worktree sits on the PR's head ref at the PR
|
|
121
|
+
HEAD before the loop starts. A worktree fresh off `origin/main` has
|
|
122
|
+
`HEAD == origin/main`, shows an empty diff, and reports a false convergence
|
|
123
|
+
with zero findings. When a local worktree already tracks the PR branch, enter
|
|
124
|
+
that one (pass its path to `EnterWorktree` when that tool exists; otherwise
|
|
125
|
+
`cd` into it). Otherwise put the checkout on the branch with
|
|
126
|
+
`gh pr checkout <number> --repo <owner>/<repo>`
|
|
127
|
+
(or `git fetch origin <headRefName>` then `git switch <headRefName>`). Confirm
|
|
128
|
+
before launching: `git rev-parse --abbrev-ref HEAD` equals the PR's head ref
|
|
129
|
+
and local `HEAD` equals the PR head SHA.
|
|
130
|
+
|
|
131
|
+
3. **Verify the worktree is the PR's repo (strict pre-flight).** Run
|
|
132
|
+
`python "$HOME/.claude/skills/_shared/pr-loop/scripts/preflight_worktree.py" --owner <owner> --repo <repo> --mode strict`.
|
|
133
|
+
It confirms the working directory is a checkout of the PR's own repo and
|
|
134
|
+
that `git worktree` machinery is healthy. A non-zero exit prints a
|
|
135
|
+
`PREFLIGHT_OUTCOME` line and an `ABORT` line: report that line and stop.
|
|
136
|
+
Autoconverge runs inside the PR's own repo, so a working directory rooted in
|
|
137
|
+
a different repo (for example, `claude-dev-env` while the PR lives in
|
|
138
|
+
`llm-settings`) or in no git checkout at all cannot continue.
|
|
139
|
+
|
|
140
|
+
4. **Grant project permissions.** Apply the `pr-loop-lifecycle` skill's Open
|
|
141
|
+
section (`../pr-loop-lifecycle/SKILL.md`) — the grant command
|
|
142
|
+
(`grant_project_claude_permissions.py`) and the auto-mode `AskUserQuestion`
|
|
143
|
+
escalation for a blocked grant both live there.
|
|
144
|
+
|
|
145
|
+
5. **Copilot quota pre-check.** Before the pacer starts the loop, apply the
|
|
146
|
+
`reviewer-gates` skill's Copilot quota gate (`../reviewer-gates/SKILL.md`)
|
|
147
|
+
once. Exit 0 maps to `copilotDisabled: false` / `copilot_down=false`; any
|
|
148
|
+
non-zero exit maps to `copilotDisabled: true` / `copilot_down=true`, and the
|
|
149
|
+
run skips the Copilot gate with no agent spawned.
|
|
150
|
+
|
|
151
|
+
6. **Branch on pacer.** When `pacer=portable`, follow
|
|
152
|
+
[`../_shared/pr-loop/portable-driver.md`](../_shared/pr-loop/portable-driver.md)
|
|
153
|
+
§ Continuous tick loop and § Autoconverge entry on portable pacer, then
|
|
154
|
+
skip **Run the workflow** (no Workflow tool). When `pacer=workflow`,
|
|
155
|
+
continue with **Run the workflow**.
|
|
156
|
+
|
|
157
|
+
## Run the workflow
|
|
158
|
+
|
|
159
|
+
(`pacer=workflow` only.) Call the `Workflow` tool against the colocated script:
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
Workflow({
|
|
163
|
+
scriptPath: "<this skill dir>/workflow/converge.mjs",
|
|
164
|
+
args: { owner: "<O>", repo: "<R>", prNumber: <N>, bugbotDisabled: false, copilotDisabled: false }
|
|
165
|
+
})
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
`scriptPath` is the absolute path to `workflow/converge.mjs` inside this skill's
|
|
169
|
+
own directory (on this install,
|
|
170
|
+
`<home>/.claude/skills/autoconverge/workflow/converge.mjs`). Set
|
|
171
|
+
`bugbotDisabled: true` only when the user has opted Cursor Bugbot out for the
|
|
172
|
+
run; otherwise the workflow detects an opt-out or an unreachable Bugbot on its
|
|
173
|
+
own. Set `copilotDisabled: true` when the step 5 quota pre-check exits non-zero,
|
|
174
|
+
and `false` when it exits 0; on `true` the workflow skips the Copilot gate with
|
|
175
|
+
no agent spawned. The workflow runs in the background and notifies this session
|
|
176
|
+
on completion. Watch live progress with `/workflows`.
|
|
177
|
+
|
|
178
|
+
The moment the `Workflow` call returns its run id, write the durable handoff so a
|
|
179
|
+
fresh session can resume the same run:
|
|
180
|
+
|
|
181
|
+
```
|
|
182
|
+
python "$HOME/.claude/skills/_shared/pr-loop/scripts/write_handoff.py" \
|
|
183
|
+
--pr-number <N> --head-ref <branch> --phase workflow \
|
|
184
|
+
--resume-command "Workflow({scriptPath, resumeFromRunId: '<runId>'})" \
|
|
185
|
+
--run-id <runId>
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Write it again when the result lands, so the handoff carries the final run id and
|
|
189
|
+
names the teardown phase the fresh session picks up from.
|
|
190
|
+
|
|
191
|
+
The workflow returns
|
|
192
|
+
`{ converged, rounds, finalSha, blocker, standardsNote, copilotNote, cleanAuditNote, reuseNote, deferredPrs }`,
|
|
193
|
+
plus a `userReview` field on a `blocker: "user-review"` return. `cleanAuditNote` is
|
|
194
|
+
non-null when the environment refused the CLEAN bugteam review post and the run
|
|
195
|
+
recorded the bypass — see
|
|
196
|
+
[`reference/stop-conditions.md`](reference/stop-conditions.md) § Clean-audit post
|
|
197
|
+
bypassed.
|
|
198
|
+
`deferredPrs` is the list of draft environment-hardening PRs the standards-deferral
|
|
199
|
+
path opened this run, each as `{ owner, repo, prNumber, copilotDisabled, bugbotDisabled }`.
|
|
200
|
+
The two flags carry this run's Copilot and Bugbot availability, so the next generation
|
|
201
|
+
skips a reviewer that is down or out of quota without re-probing. This list is the seed the
|
|
202
|
+
[self-closing loop](reference/self-closing-loop.md) converges next.
|
|
203
|
+
|
|
204
|
+
## Copilot findings — tier, verify, then route
|
|
205
|
+
|
|
206
|
+
The Copilot gate tiers each finding: a **self-healing** finding (style, type
|
|
207
|
+
hints, imports, formatting, magic-value extraction, test-only or doc-vs-code
|
|
208
|
+
fixes — nothing that changes observable runtime behavior) flows into the fix
|
|
209
|
+
round with no user notification. A **code-concern** finding (logic, security,
|
|
210
|
+
data handling, error-handling semantics, concurrency — the tier whenever in
|
|
211
|
+
doubt) goes to a verification stage before any routing.
|
|
212
|
+
|
|
213
|
+
Each code-concern finding gets its own verifier agent, all in parallel, inside
|
|
214
|
+
the workflow. A verdict is conclusive only when an actual check ran: the verifier
|
|
215
|
+
executes a command against the flagged HEAD — running the code path with crafted
|
|
216
|
+
inputs, forcing the claimed error condition, or running a purpose-built test —
|
|
217
|
+
and captures its output. The verdict carries
|
|
218
|
+
`{ verdict, checkCommand, checkOutput, evidence }`; a conclusive verdict with an
|
|
219
|
+
empty `checkCommand` or `checkOutput` downgrades to inconclusive.
|
|
220
|
+
|
|
221
|
+
- **confirmed** — the check reproduces the defect. The finding becomes
|
|
222
|
+
self-healing: it joins the fix round carrying its repro, and the fix re-runs
|
|
223
|
+
that same check, adds a regression test where the suite covers the surface,
|
|
224
|
+
lands in one commit, pushes, and replies on the thread with the fix SHA and the
|
|
225
|
+
before/after output. No page.
|
|
226
|
+
- **refuted** — the check shows the code already behaves correctly in the exact
|
|
227
|
+
scenario the finding claims is broken. The workflow replies on the thread with
|
|
228
|
+
the command and output, resolves it, and counts it clean. No page.
|
|
229
|
+
- **inconclusive** — everything else, and the verifier's default: no runnable
|
|
230
|
+
check exists, the check is infeasible here, the results are ambiguous, or the
|
|
231
|
+
fix needs a product decision. Any doubt sorts here. Only inconclusive findings
|
|
232
|
+
page the user.
|
|
233
|
+
|
|
234
|
+
A round whose code concerns all confirm or refute never returns
|
|
235
|
+
`blocker: "user-review"`. On one or more inconclusive findings, the workflow
|
|
236
|
+
stops with `converged: false`, `blocker: "user-review"`, and a `userReview`
|
|
237
|
+
field carrying
|
|
238
|
+
`{ reviewUrl, findings: [{ file, line, severity, tier, title, evidence }] }` —
|
|
239
|
+
`evidence` is the verifier's one-line note stating what check was attempted and
|
|
240
|
+
why it was not decisive.
|
|
241
|
+
|
|
242
|
+
The wait for a human belongs to the orchestrating session. On a
|
|
243
|
+
`blocker: "user-review"` return, run the
|
|
244
|
+
[`copilot-finding-triage`](../copilot-finding-triage/SKILL.md) skill for the ntfy
|
|
245
|
+
page only (the per-finding summary and evidence note plus the `reviewUrl`
|
|
246
|
+
Copilot review link), then hold for the user's response by pacer. On
|
|
247
|
+
`pacer=portable`, override triage's hold step — ntfy plus the portable hold
|
|
248
|
+
below; do not follow triage's `ScheduleWakeup` / `send_later` path.
|
|
249
|
+
|
|
250
|
+
- **`pacer=workflow`** — triage hold: 45-minute `ScheduleWakeup` (or
|
|
251
|
+
`send_later` when that is the host arm).
|
|
252
|
+
- **`pacer=portable`** — portable hold only: in-session poll or handoff per
|
|
253
|
+
[`../_shared/pr-loop/portable-driver.md`](../_shared/pr-loop/portable-driver.md);
|
|
254
|
+
never `ScheduleWakeup` or `send_later`.
|
|
255
|
+
|
|
256
|
+
When the user answers within the window, follow their direction. When the
|
|
257
|
+
window closes with no response, run normal teardown and report the
|
|
258
|
+
inconclusive findings un-reviewed.
|
|
259
|
+
|
|
260
|
+
## Budget stop
|
|
261
|
+
|
|
262
|
+
Branch the stop and resume path on the selected pacer. Full rule:
|
|
263
|
+
[`reference/stop-conditions.md`](reference/stop-conditions.md) § Budget stop.
|
|
264
|
+
|
|
265
|
+
- **`pacer=workflow`** — `converge.mjs` paces against the workflow `budget` API
|
|
266
|
+
and stops at a round boundary when a full round does not fit. On a
|
|
267
|
+
`blocker: "budget"` return, write the durable handoff with the run id and the
|
|
268
|
+
`Workflow({scriptPath, resumeFromRunId})` resume command before stopping, so a
|
|
269
|
+
fresh session resumes the paced run without the stopped session's transcript.
|
|
270
|
+
- **`pacer=portable`** — stop at a tick boundary when the session cannot cover a
|
|
271
|
+
full clean tick; write the durable handoff and resume with
|
|
272
|
+
`/autoconverge <PR URL>` (see
|
|
273
|
+
[`../_shared/pr-loop/portable-driver.md`](../_shared/pr-loop/portable-driver.md)).
|
|
274
|
+
Do not instruct a Workflow resume on the portable path.
|
|
275
|
+
|
|
276
|
+
## Teardown
|
|
277
|
+
|
|
278
|
+
### `pacer=portable`
|
|
279
|
+
|
|
280
|
+
Skip Workflow-only report steps that need a workflow run id (journal merge,
|
|
281
|
+
HTML closing report, Artifact publish). Run `pr-loop-lifecycle` Close
|
|
282
|
+
(description rewrite when converged, working-tree clean, permission revoke)
|
|
283
|
+
and print the final report block using tick/`check_convergence` outcomes.
|
|
284
|
+
User-review holds use the portable in-session poll (or handoff) from
|
|
285
|
+
[`../_shared/pr-loop/portable-driver.md`](../_shared/pr-loop/portable-driver.md)
|
|
286
|
+
— not `ScheduleWakeup`. Resume command: `/autoconverge <PR URL>`.
|
|
287
|
+
|
|
288
|
+
### `pacer=workflow` (on workflow completion)
|
|
289
|
+
|
|
290
|
+
Teardown runs as an ordered checkpoint list. After each checkpoint finishes,
|
|
291
|
+
re-write the durable handoff with `--phase teardown`, the run id, and the
|
|
292
|
+
checkpoints done so far, so a fresh session that resumes reads `handoff.json`
|
|
293
|
+
`completed_steps` and skips the checkpoints already done:
|
|
294
|
+
|
|
295
|
+
```
|
|
296
|
+
python "$HOME/.claude/skills/_shared/pr-loop/scripts/write_handoff.py" \
|
|
297
|
+
--pr-number <N> --head-ref <branch> --phase teardown \
|
|
298
|
+
--resume-command "/autoconverge <PR URL>" \
|
|
299
|
+
--run-id <runId> \
|
|
300
|
+
--completed-steps "<checkpoints done so far>"
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
The checkpoints run in this order: `report`, `close`. Write the
|
|
304
|
+
handoff after each one finishes.
|
|
305
|
+
|
|
306
|
+
On teardown entry, when `~/.claude/runtime/pr-loop/bugteam-pr-<N>/handoff.json`
|
|
307
|
+
exists, read its `completed_steps` and skip any checkpoint the list already
|
|
308
|
+
names, so a resumed run performs only the checkpoints left.
|
|
309
|
+
|
|
310
|
+
On a `blocker: "user-review"` return under `pacer=workflow`, the workflow held
|
|
311
|
+
one or more code-concern findings that stayed inconclusive after the
|
|
312
|
+
executed-check verification stage. Run the
|
|
313
|
+
[`copilot-finding-triage`](../copilot-finding-triage/SKILL.md) gate before
|
|
314
|
+
teardown: send the ntfy alert with the per-finding summary and evidence note and
|
|
315
|
+
the `userReview.reviewUrl` link, then hold with a 45-minute `ScheduleWakeup` (or
|
|
316
|
+
`send_later` when that is the host arm). Act on the user's direction when it
|
|
317
|
+
arrives inside the window; when the window closes with no response, fall through
|
|
318
|
+
to normal teardown and report the `userReview.findings` un-reviewed. The PR
|
|
319
|
+
stays a draft in this path — the workflow marked nothing ready. Under
|
|
320
|
+
`pacer=portable`, use the portable teardown hold above (ntfy plus in-session
|
|
321
|
+
poll or handoff; never `ScheduleWakeup`).
|
|
322
|
+
|
|
323
|
+
Before the checkpoints, when the workflow returned a non-null `copilotNote`
|
|
324
|
+
(the Copilot gate was bypassed), query the PR's reviews once more for a
|
|
325
|
+
`copilot-pull-request-reviewer[bot]` review on the final HEAD
|
|
326
|
+
(`fetch_copilot_reviews.py`, or the GitHub MCP `pull_request_read` method
|
|
327
|
+
`get_reviews`). Copilot typically posts within 10–15 minutes of a request, so
|
|
328
|
+
a review can land between the bypass and teardown. When one exists and
|
|
329
|
+
carries findings, mark the PR draft, route the findings through one fix
|
|
330
|
+
round per the `pr-fix-protocol` skill, re-verify, push, and mark the PR
|
|
331
|
+
ready again — then run the checkpoints.
|
|
332
|
+
|
|
333
|
+
1. **When `converged` is true — build and publish the closing report.**
|
|
334
|
+
Skip this entire step (report, artifact publish, comment, Chrome open) when
|
|
335
|
+
the workflow returned a non-null `blocker`. Follow
|
|
336
|
+
[`reference/closing-report.md`](reference/closing-report.md) § Building the
|
|
337
|
+
report and § Publishing: resolve the seed journal from the run id, merge the
|
|
338
|
+
PR's runs with `aggregate_runs.py`, spawn the `convergence-summary` agent
|
|
339
|
+
(a `general-purpose` subagent) on the prompt it builds, draw the report with
|
|
340
|
+
`render_report.py`, publish the HTML via the `Artifact` tool, post the
|
|
341
|
+
one marker-keyed `<!-- autoconverge-report -->` PR comment, and open the
|
|
342
|
+
artifact URL in Chrome. After the report is published, write the handoff
|
|
343
|
+
with `--completed-steps "report"`.
|
|
344
|
+
|
|
345
|
+
2. **Close the run.** Apply the `pr-loop-lifecycle` skill's Close section
|
|
346
|
+
(`../pr-loop-lifecycle/SKILL.md`): when `converged` is true, rewrite the PR
|
|
347
|
+
description and clean the working tree — see
|
|
348
|
+
[`pr-loop-lifecycle/reference/teardown-publish-permissions.md` § Clean working tree and § Publish the final PR description](../pr-loop-lifecycle/reference/teardown-publish-permissions.md);
|
|
349
|
+
the workflow already marked the PR ready. The permission revoke always runs,
|
|
350
|
+
including on a blocker exit. Write the handoff with
|
|
351
|
+
`--completed-steps "report,close"`.
|
|
352
|
+
|
|
353
|
+
3. **Print the final report:**
|
|
354
|
+
|
|
355
|
+
```
|
|
356
|
+
/autoconverge exit: <converged | blocked>
|
|
357
|
+
Rounds: <N>
|
|
358
|
+
Final commit: <finalSha>
|
|
359
|
+
Blocker: <blocker> # only when blocked
|
|
360
|
+
Standards: <standardsNote> # only when a round deferred code-standard findings
|
|
361
|
+
Copilot: <copilotNote> # only when Copilot was down or out of quota
|
|
362
|
+
Clean-audit: <cleanAuditNote> # only when the CLEAN bugteam post was bypassed
|
|
363
|
+
Reuse: <reuseNote> # only when the reuse pass identified an improvement
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
## What the workflow does each round
|
|
367
|
+
|
|
368
|
+
[`reference/convergence.md`](reference/convergence.md) defines the whole loop:
|
|
369
|
+
the merge-conflict pre-flight, the reuse pass and its three landing criteria,
|
|
370
|
+
the round shape (static sweep, the three parallel reading lenses, dedup, the
|
|
371
|
+
one-commit fix flow, the standards-deferral path), the terminal Bugbot, Copilot,
|
|
372
|
+
and Codex gates, the per-role model tiers, the full-diff rule, and the exact
|
|
373
|
+
ready definition `check_convergence.py` enforces.
|
|
374
|
+
[`reference/stop-conditions.md`](reference/stop-conditions.md) lists every way
|
|
375
|
+
the run ends short of ready. Hard-won failure lessons live in
|
|
376
|
+
[`reference/gotchas.md`](reference/gotchas.md).
|
|
377
|
+
|
|
378
|
+
Every agent prompt the workflow authors carries a headless-safety preamble —
|
|
379
|
+
read-only agents get a trimmed form, edit agents the full form with the rm
|
|
380
|
+
auto-allow paths — specified in
|
|
381
|
+
[`reference/headless-safety.md`](reference/headless-safety.md).
|
|
382
|
+
|
|
383
|
+
## Multiple PRs
|
|
384
|
+
|
|
385
|
+
When the user names several PRs, run the multi-PR path in
|
|
386
|
+
[`reference/multi-pr.md`](reference/multi-pr.md): one worktree per PR
|
|
387
|
+
(`git worktree add` on each head ref, strict pre-flight per worktree, one
|
|
388
|
+
permission grant per repository, one Copilot quota check for the whole run),
|
|
389
|
+
then launch by pacer — `pacer=workflow`: one `workflow/converge_multi.mjs`
|
|
390
|
+
call with one entry per PR; `pacer=portable`: portable driver once per PR
|
|
391
|
+
(serial or host fan-out) — then single-PR teardown once per PR and a
|
|
392
|
+
one-line-per-PR summary.
|
|
393
|
+
|
|
394
|
+
## Self-closing loop: converge the deferred PRs
|
|
395
|
+
|
|
396
|
+
Every autoconverge run — single-PR and multi-PR alike — ends with the
|
|
397
|
+
self-closing loop in
|
|
398
|
+
[`reference/self-closing-loop.md`](reference/self-closing-loop.md): the
|
|
399
|
+
orchestrating session converges the draft environment-hardening PRs the run
|
|
400
|
+
deferred (`deferredPrs` on a single-PR run, `allDeferredPrs` on a multi-PR
|
|
401
|
+
run), then the PRs those runs defer, generation by generation, until a
|
|
402
|
+
generation opens none. An empty seed list ends the loop at once. The reference
|
|
403
|
+
also carries the Conventional-Commit title rule each hardening PR must meet.
|
|
404
|
+
|
|
405
|
+
## Folder map
|
|
406
|
+
|
|
407
|
+
- `SKILL.md` — this hub.
|
|
408
|
+
- [`../_shared/pr-loop/portable-driver.md`](../_shared/pr-loop/portable-driver.md) — portable pacer when `Workflow` is absent.
|
|
409
|
+
- `workflow/converge.mjs` — the convergence workflow script.
|
|
410
|
+
- `workflow/converge_multi.mjs` — the multi-PR fan-out driver: one `converge.mjs` child run per PR in parallel, each pinned to its PR worktree via `repoPath`.
|
|
411
|
+
- `workflow/aggregate_runs.py` — merges every autoconverge journal for a PR into one journal and returns its deduped findings, fix summaries, round count, and final SHA.
|
|
412
|
+
- `workflow/convergence_summary.py` — builds the convergence-summary agent prompt over a PR's merged findings.
|
|
413
|
+
- `workflow/render_report.py` — builds the closing convergence insights HTML report, taking the summary from `--summary-file`.
|
|
414
|
+
- `workflow/autoconverge_report_constants/` — named constants for the report builder and the summary prompt.
|
|
415
|
+
- `reference/convergence.md` — the whole loop: reuse pass, round shape, terminal gates, model tiers, ready definition.
|
|
416
|
+
- `reference/stop-conditions.md` — every way the run ends short of ready, including the budget stop.
|
|
417
|
+
- `reference/gotchas.md` — hard-won failure lessons.
|
|
418
|
+
- `reference/closing-report.md` — the closing HTML report: data source, build steps, publishing.
|
|
419
|
+
- `reference/multi-pr.md` — the several-PRs path: per-PR worktrees, the `converge_multi.mjs` launch, per-PR teardown.
|
|
420
|
+
- `reference/self-closing-loop.md` — the deferred-PR generations and the Conventional-Commit title rule.
|
|
421
|
+
- `reference/headless-safety.md` — the agent-prompt preamble and the rm auto-allow paths.
|