claude-dev-env 1.93.0 → 1.94.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 (220) hide show
  1. package/_shared/pr-loop/CLAUDE.md +1 -0
  2. package/_shared/pr-loop/audit-contract.md +1 -1
  3. package/_shared/pr-loop/gh-payloads.md +3 -3
  4. package/_shared/pr-loop/post-audit-thread-contract.md +51 -0
  5. package/_shared/pr-loop/scripts/README.md +2 -2
  6. package/_shared/pr-loop/scripts/code_rules_gate.py +127 -13
  7. package/_shared/pr-loop/scripts/fix_hookspath.py +47 -12
  8. package/_shared/pr-loop/scripts/pr_loop_shared_constants/code_rules_gate_constants.py +4 -0
  9. package/_shared/pr-loop/scripts/tests/test_code_rules_gate.py +146 -69
  10. package/_shared/pr-loop/scripts/tests/test_fix_hookspath.py +497 -374
  11. package/_shared/pr-loop/state-schema.md +3 -22
  12. package/bin/CLAUDE.md +1 -1
  13. package/bin/install.mjs +2 -7
  14. package/bin/install.test.mjs +10 -4
  15. package/hooks/blocking/CLAUDE.md +2 -0
  16. package/hooks/blocking/pii_commit_command.py +398 -0
  17. package/hooks/blocking/pii_payload_scan.py +133 -0
  18. package/hooks/blocking/pii_prevention_blocker.py +151 -449
  19. package/hooks/blocking/pii_scanner.py +26 -1
  20. package/hooks/blocking/test_code_rules_enforcer_dead_config_field.py +2 -2
  21. package/hooks/blocking/test_pii_prevention_blocker.py +299 -0
  22. package/hooks/blocking/test_pii_scanner.py +27 -2
  23. package/hooks/blocking/test_verdict_directory_write_blocker.py +42 -7
  24. package/hooks/hooks_constants/CLAUDE.md +2 -2
  25. package/hooks/hooks_constants/code_rules_path_utils_constants.py +0 -2
  26. package/hooks/hooks_constants/local_identity.py +65 -15
  27. package/hooks/hooks_constants/pii_prevention_constants.py +20 -8
  28. package/hooks/hooks_constants/pr_description_enforcer_constants.py +1 -1
  29. package/hooks/hooks_constants/test_local_identity.py +68 -0
  30. package/package.json +1 -1
  31. package/scripts/CLAUDE.md +10 -1
  32. package/scripts/Get-SessionAccount.ps1 +210 -0
  33. package/scripts/tests/CLAUDE.md +15 -1
  34. package/scripts/tests/Get-SessionAccount.Tests.ps1 +350 -0
  35. package/skills/CLAUDE.md +3 -25
  36. package/skills/anthropic-plan/SKILL.md +1 -13
  37. package/skills/autoconverge/CLAUDE.md +5 -2
  38. package/skills/autoconverge/SKILL.md +112 -387
  39. package/skills/autoconverge/reference/CLAUDE.md +4 -1
  40. package/skills/autoconverge/reference/closing-report.md +9 -2
  41. package/skills/autoconverge/reference/convergence.md +26 -22
  42. package/skills/autoconverge/reference/headless-safety.md +44 -0
  43. package/skills/autoconverge/reference/multi-pr.md +88 -0
  44. package/skills/autoconverge/reference/self-closing-loop.md +84 -0
  45. package/skills/autoconverge/reference/stop-conditions.md +21 -13
  46. package/skills/autoconverge/workflow/converge.clean-audit.test.mjs +87 -27
  47. package/skills/autoconverge/workflow/converge.contract.test.mjs +40 -10
  48. package/skills/autoconverge/workflow/converge.copilot-gate.test.mjs +179 -47
  49. package/skills/autoconverge/workflow/converge.fix-progress.test.mjs +1 -1
  50. package/skills/autoconverge/workflow/converge.mjs +284 -94
  51. package/skills/bugteam/CLAUDE.md +1 -1
  52. package/skills/bugteam/CONSTRAINTS.md +3 -3
  53. package/skills/bugteam/PROMPTS.md +8 -19
  54. package/skills/bugteam/SKILL.md +13 -14
  55. package/skills/bugteam/reference/CLAUDE.md +1 -1
  56. package/skills/bugteam/reference/audit-and-teammates.md +2 -2
  57. package/skills/bugteam/reference/copilot-gap-analysis.md +2 -0
  58. package/skills/bugteam/reference/github-pr-reviews.md +56 -38
  59. package/skills/bugteam/reference/team-setup.md +11 -11
  60. package/skills/bugteam/scripts/CLAUDE.md +6 -6
  61. package/skills/bugteam/scripts/README.md +20 -8
  62. package/skills/bugteam/scripts/bugteam_code_rules_gate.py +13 -1463
  63. package/skills/bugteam/scripts/bugteam_fix_hookspath.py +23 -358
  64. package/skills/bugteam/scripts/bugteam_preflight.py +13 -315
  65. package/skills/bugteam/scripts/bugteam_scripts_constants/CLAUDE.md +2 -3
  66. package/skills/bugteam/scripts/test_bugteam_code_rules_gate.py +34 -1053
  67. package/skills/bugteam/scripts/test_bugteam_fix_hookspath.py +30 -347
  68. package/skills/bugteam/scripts/test_bugteam_preflight.py +30 -305
  69. package/skills/copilot-finding-triage/SKILL.md +80 -28
  70. package/skills/copilot-finding-triage/reference/tier-rubric.md +70 -11
  71. package/skills/copilot-finding-triage/templates/notification.md +8 -3
  72. package/skills/everything-search/SKILL.md +1 -2
  73. package/skills/grokify/SKILL.md +58 -0
  74. package/skills/grokify/templates/handoff-template.md +92 -0
  75. package/skills/orchestrator/SKILL.md +12 -8
  76. package/skills/orchestrator-refresh/SKILL.md +3 -3
  77. package/skills/pr-converge/SKILL.md +132 -233
  78. package/skills/pr-converge/reference/convergence-gates.md +102 -66
  79. package/skills/pr-converge/reference/examples.md +37 -25
  80. package/skills/pr-converge/reference/fix-protocol.md +7 -7
  81. package/skills/pr-converge/reference/multi-pr-orchestration.md +10 -4
  82. package/skills/pr-converge/reference/per-tick.md +64 -41
  83. package/skills/pr-converge/reference/state-schema.md +27 -2
  84. package/skills/pr-converge/scripts/CLAUDE.md +8 -0
  85. package/skills/pr-converge/scripts/README.md +4 -3
  86. package/skills/pr-converge/scripts/_pr_converge_path_setup.py +23 -0
  87. package/skills/pr-converge/scripts/check_convergence.py +189 -645
  88. package/skills/pr-converge/scripts/check_convergence_gates.py +235 -0
  89. package/skills/pr-converge/scripts/check_convergence_thread_gates.py +219 -0
  90. package/skills/pr-converge/scripts/conftest.py +8 -0
  91. package/skills/pr-converge/scripts/pr_converge_scripts_constants/CLAUDE.md +1 -0
  92. package/skills/pr-converge/scripts/pr_converge_scripts_constants/convergence_gate_constants.py +36 -0
  93. package/skills/pr-converge/scripts/test__pr_converge_path_setup.py +26 -0
  94. package/skills/pr-converge/scripts/test_check_convergence.py +73 -228
  95. package/skills/pr-converge/scripts/test_check_convergence_contract.py +321 -0
  96. package/skills/pr-converge/scripts/test_check_convergence_gates.py +68 -0
  97. package/skills/pr-converge/scripts/test_check_convergence_thread_gates.py +75 -0
  98. package/skills/privacy-hygiene/SKILL.md +8 -7
  99. package/skills/reviewer-gates/SKILL.md +26 -8
  100. package/skills/session-log/SKILL.md +11 -12
  101. package/skills/session-tidy/SKILL.md +40 -30
  102. package/skills/skill-builder/CLAUDE.md +13 -10
  103. package/skills/skill-builder/SKILL.md +31 -31
  104. package/skills/skill-builder/references/CLAUDE.md +10 -6
  105. package/skills/skill-builder/references/delegation-map.md +13 -4
  106. package/skills/skill-builder/references/description-field.md +113 -0
  107. package/skills/skill-builder/references/self-audit-checklist.md +21 -4
  108. package/skills/skill-builder/references/skill-modularity.md +113 -0
  109. package/skills/skill-builder/references/skill-types.md +4 -0
  110. package/skills/skill-builder/templates/CLAUDE.md +4 -4
  111. package/skills/skill-builder/templates/gap-analysis.md +25 -1
  112. package/skills/skill-builder/workflows/CLAUDE.md +6 -4
  113. package/skills/skill-builder/workflows/improve-skill.md +17 -16
  114. package/skills/skill-builder/workflows/new-skill.md +34 -10
  115. package/skills/skill-builder/workflows/polish-skill.md +59 -43
  116. package/skills/usage-pause/SKILL.md +10 -14
  117. package/skills/bdd-protocol/CLAUDE.md +0 -26
  118. package/skills/bdd-protocol/SKILL.md +0 -30
  119. package/skills/bdd-protocol/references/CLAUDE.md +0 -10
  120. package/skills/bdd-protocol/references/anti-patterns.md +0 -26
  121. package/skills/bdd-protocol/references/example-mapping.md +0 -23
  122. package/skills/bg-agent/CLAUDE.md +0 -17
  123. package/skills/bg-agent/SKILL.md +0 -69
  124. package/skills/bugteam/scripts/bugteam_scripts_constants/bugteam_code_rules_gate_constants.py +0 -55
  125. package/skills/bugteam/scripts/bugteam_scripts_constants/bugteam_fix_hookspath_constants.py +0 -26
  126. package/skills/bugteam/scripts/bugteam_scripts_constants/bugteam_preflight_constants.py +0 -35
  127. package/skills/caveman/CLAUDE.md +0 -15
  128. package/skills/caveman/SKILL.md +0 -38
  129. package/skills/code/CLAUDE.md +0 -17
  130. package/skills/code/SKILL.md +0 -178
  131. package/skills/deep-research/CLAUDE.md +0 -17
  132. package/skills/deep-research/SKILL.md +0 -80
  133. package/skills/findbugs/CLAUDE.md +0 -20
  134. package/skills/findbugs/SKILL.md +0 -241
  135. package/skills/fixbugs/CLAUDE.md +0 -19
  136. package/skills/fixbugs/SKILL.md +0 -142
  137. package/skills/gh-paginate/CLAUDE.md +0 -18
  138. package/skills/gh-paginate/SKILL.md +0 -84
  139. package/skills/gotcha/CLAUDE.md +0 -33
  140. package/skills/gotcha/SKILL.md +0 -73
  141. package/skills/implement/CLAUDE.md +0 -27
  142. package/skills/implement/SKILL.md +0 -66
  143. package/skills/implement/scripts/CLAUDE.md +0 -22
  144. package/skills/implement/scripts/append_note.py +0 -133
  145. package/skills/implement/scripts/implement_scripts_constants/CLAUDE.md +0 -22
  146. package/skills/implement/scripts/implement_scripts_constants/__init__.py +0 -0
  147. package/skills/implement/scripts/implement_scripts_constants/notes_constants.py +0 -12
  148. package/skills/implement/scripts/test_append_note.py +0 -191
  149. package/skills/log-audit/CLAUDE.md +0 -20
  150. package/skills/log-audit/SKILL.md +0 -66
  151. package/skills/log-audit/reference/CLAUDE.md +0 -9
  152. package/skills/log-audit/reference/charter.md +0 -52
  153. package/skills/log-audit/scripts/CLAUDE.md +0 -27
  154. package/skills/log-audit/scripts/cluster_recurrences.py +0 -261
  155. package/skills/log-audit/scripts/collect_log_window.py +0 -199
  156. package/skills/log-audit/scripts/log_audit_constants/CLAUDE.md +0 -12
  157. package/skills/log-audit/scripts/log_audit_constants/__init__.py +0 -0
  158. package/skills/log-audit/scripts/log_audit_constants/cluster_recurrences_constants.py +0 -23
  159. package/skills/log-audit/scripts/log_audit_constants/collect_log_window_constants.py +0 -24
  160. package/skills/log-audit/scripts/log_audit_constants/mine_copilot_findings_constants.py +0 -49
  161. package/skills/log-audit/scripts/mine_copilot_findings.py +0 -302
  162. package/skills/log-audit/scripts/test_cluster_recurrences.py +0 -160
  163. package/skills/log-audit/scripts/test_collect_log_window.py +0 -111
  164. package/skills/log-audit/scripts/test_mine_copilot_findings.py +0 -126
  165. package/skills/logifix/CLAUDE.md +0 -36
  166. package/skills/logifix/SKILL.md +0 -69
  167. package/skills/logifix/scripts/CLAUDE.md +0 -16
  168. package/skills/logifix/scripts/logifix.ps1 +0 -205
  169. package/skills/monitor-open-prs/CLAUDE.md +0 -34
  170. package/skills/monitor-open-prs/SKILL.md +0 -88
  171. package/skills/monitor-open-prs/scripts/CLAUDE.md +0 -17
  172. package/skills/monitor-open-prs/scripts/discover_open_prs.py +0 -69
  173. package/skills/monitor-open-prs/scripts/test_discover_open_prs.py +0 -149
  174. package/skills/monitor-open-prs/test_skill_contract.py +0 -27
  175. package/skills/post-audit-findings/SKILL.md +0 -80
  176. package/skills/pr-consistency-audit/CLAUDE.md +0 -34
  177. package/skills/pr-consistency-audit/SKILL.md +0 -116
  178. package/skills/pr-consistency-audit/reference/CLAUDE.md +0 -16
  179. package/skills/pr-consistency-audit/reference/detection-rules.md +0 -96
  180. package/skills/pr-consistency-audit/reference/illustrations.md +0 -78
  181. package/skills/pr-fix-protocol/SKILL.md +0 -65
  182. package/skills/pr-review-responder/CLAUDE.md +0 -35
  183. package/skills/pr-review-responder/EXAMPLES.md +0 -590
  184. package/skills/pr-review-responder/PRINCIPLES.md +0 -533
  185. package/skills/pr-review-responder/README.md +0 -168
  186. package/skills/pr-review-responder/SKILL.md +0 -203
  187. package/skills/pr-review-responder/TESTING.md +0 -350
  188. package/skills/pr-scope-resolve/SKILL.md +0 -45
  189. package/skills/pre-compact/CLAUDE.md +0 -24
  190. package/skills/pre-compact/SKILL.md +0 -134
  191. package/skills/qbug/CLAUDE.md +0 -40
  192. package/skills/qbug/SKILL.md +0 -387
  193. package/skills/qbug/test_qbug_skill_audit_schema.py +0 -152
  194. package/skills/qbug/test_qbug_skill_post_fix_audit.py +0 -103
  195. package/skills/refine/CLAUDE.md +0 -44
  196. package/skills/refine/SKILL.md +0 -262
  197. package/skills/refine/templates/CLAUDE.md +0 -17
  198. package/skills/refine/templates/implementation-notes-template.html +0 -56
  199. package/skills/refine/templates/plan-template.md +0 -60
  200. package/skills/research-mode/CLAUDE.md +0 -35
  201. package/skills/research-mode/SKILL.md +0 -53
  202. package/skills/structure-prompt/CLAUDE.md +0 -42
  203. package/skills/structure-prompt/SKILL.md +0 -44
  204. package/skills/structure-prompt/reference/CLAUDE.md +0 -28
  205. package/skills/structure-prompt/reference/adversarial-tuning.md +0 -62
  206. package/skills/structure-prompt/reference/block-classification.md +0 -27
  207. package/skills/structure-prompt/reference/canonical-case.md +0 -48
  208. package/skills/structure-prompt/reference/citation-depth.md +0 -70
  209. package/skills/structure-prompt/reference/cleanup.md +0 -33
  210. package/skills/structure-prompt/reference/constraints.md +0 -33
  211. package/skills/structure-prompt/reference/directives.md +0 -37
  212. package/skills/structure-prompt/reference/examples.md +0 -72
  213. package/skills/structure-prompt/reference/instantiation.md +0 -51
  214. package/skills/structure-prompt/reference/output-contract.md +0 -72
  215. package/skills/structure-prompt/reference/per-category.md +0 -23
  216. package/skills/structure-prompt/reference/persona.md +0 -38
  217. package/skills/structure-prompt/reference/research.md +0 -33
  218. package/skills/structure-prompt/reference/structure.md +0 -28
  219. package/skills/verified-build/CLAUDE.md +0 -33
  220. package/skills/verified-build/SKILL.md +0 -33
@@ -28,13 +28,13 @@ Decide the scope from how many PRs the user named, then follow that path:
28
28
 
29
29
  1. **One PR** → the single-PR run described below (`workflow/converge.mjs`): one
30
30
  worktree, one workflow launch, one teardown.
31
- 2. **Several PRs** → the [Multiple PRs](#multiple-prs) run
31
+ 2. **Several PRs** → the [Multiple PRs](reference/multi-pr.md) run
32
32
  (`workflow/converge_multi.mjs`): one worktree per PR and a single workflow
33
33
  launch that drives every PR's converge run in parallel, then one teardown per
34
34
  PR.
35
35
 
36
36
  The single-PR sections (Requirements, Pre-flight, Run the workflow, Teardown)
37
- each describe one converge run. The Multiple PRs section reuses them once per PR
37
+ each describe one converge run. The multi-PR reference reuses them once per PR
38
38
  and adds only what fanning out needs: a per-PR worktree and a per-PR teardown
39
39
  loop.
40
40
 
@@ -141,54 +141,74 @@ Write it again when the result lands, so the handoff carries the final run id an
141
141
  names the teardown phase the fresh session picks up from.
142
142
 
143
143
  The workflow returns
144
- `{ converged, rounds, finalSha, blocker, standardsNote, copilotNote, reuseNote, deferredPrs }`,
145
- plus a `userReview` field on a `blocker: "user-review"` return.
144
+ `{ converged, rounds, finalSha, blocker, standardsNote, copilotNote, cleanAuditNote, reuseNote, deferredPrs }`,
145
+ plus a `userReview` field on a `blocker: "user-review"` return. `cleanAuditNote` is
146
+ non-null when the environment refused the CLEAN bugteam review post and the run
147
+ recorded the bypass — see
148
+ [`reference/stop-conditions.md`](reference/stop-conditions.md) § Clean-audit post
149
+ bypassed.
146
150
  `deferredPrs` is the list of draft environment-hardening PRs the standards-deferral
147
151
  path opened this run, each as `{ owner, repo, prNumber, copilotDisabled, bugbotDisabled }`.
148
152
  The two flags carry this run's Copilot and Bugbot availability, so the next generation
149
153
  skips a reviewer that is down or out of quota without re-probing. This list is the seed the
150
- [self-closing loop](#self-closing-loop-converge-the-deferred-prs) converges next.
151
-
152
- ## Copilot findings — two-tier triage
153
-
154
- The Copilot gate tiers each finding it surfaces. A **self-healing** finding is
155
- pure style, type hints, misplaced or unused imports, formatting, magic-value
156
- extraction, a test-only change, a doc-or-description vs code mismatch, or code
157
- de-duplication a fix that cannot change observable runtime behavior for
158
- production callers. Self-healing findings flow into the fix round and count
159
- toward convergence, with no user notification.
160
-
161
- A **code-concern** finding is behavior-changing or needs a product decision:
162
- logic or correctness, security, data handling, error-handling semantics, or
163
- concurrency. Copilot tiers a finding as code-concern whenever the tier is in
164
- doubt. When one or more code-concern findings land, the workflow neither
165
- auto-fixes them nor marks the PR ready. It returns `converged: false`,
166
- `blocker: "user-review"`, and a `userReview` field carrying
167
- `{ reviewUrl, findings: [{ file, line, severity, tier, title }] }`.
154
+ [self-closing loop](reference/self-closing-loop.md) converges next.
155
+
156
+ ## Copilot findings — tier, verify, then route
157
+
158
+ The Copilot gate tiers each finding: a **self-healing** finding (style, type
159
+ hints, imports, formatting, magic-value extraction, test-only or doc-vs-code
160
+ fixes nothing that changes observable runtime behavior) flows into the fix
161
+ round with no user notification. A **code-concern** finding (logic, security,
162
+ data handling, error-handling semantics, concurrency the tier whenever in
163
+ doubt) goes to a verification stage before any routing.
164
+
165
+ Each code-concern finding gets its own verifier agent, all in parallel, inside
166
+ the workflow. A verdict is conclusive only when an actual check ran: the verifier
167
+ executes a command against the flagged HEAD running the code path with crafted
168
+ inputs, forcing the claimed error condition, or running a purpose-built test —
169
+ and captures its output. The verdict carries
170
+ `{ verdict, checkCommand, checkOutput, evidence }`; a conclusive verdict with an
171
+ empty `checkCommand` or `checkOutput` downgrades to inconclusive.
172
+
173
+ - **confirmed** — the check reproduces the defect. The finding becomes
174
+ self-healing: it joins the fix round carrying its repro, and the fix re-runs
175
+ that same check, adds a regression test where the suite covers the surface,
176
+ lands in one commit, pushes, and replies on the thread with the fix SHA and the
177
+ before/after output. No page.
178
+ - **refuted** — the check shows the code already behaves correctly in the exact
179
+ scenario the finding claims is broken. The workflow replies on the thread with
180
+ the command and output, resolves it, and counts it clean. No page.
181
+ - **inconclusive** — everything else, and the verifier's default: no runnable
182
+ check exists, the check is infeasible here, the results are ambiguous, or the
183
+ fix needs a product decision. Any doubt sorts here. Only inconclusive findings
184
+ page the user.
185
+
186
+ A round whose code concerns all confirm or refute never returns
187
+ `blocker: "user-review"`. On one or more inconclusive findings, the workflow
188
+ stops with `converged: false`, `blocker: "user-review"`, and a `userReview`
189
+ field carrying
190
+ `{ reviewUrl, findings: [{ file, line, severity, tier, title, evidence }] }` —
191
+ `evidence` is the verifier's one-line note stating what check was attempted and
192
+ why it was not decisive.
168
193
 
169
194
  A background workflow cannot hold for a human, so the wait belongs to the
170
195
  orchestrating session. On a `blocker: "user-review"` return, run the
171
196
  [`copilot-finding-triage`](../copilot-finding-triage/SKILL.md) skill: send the
172
- ntfy notification (the finding summary plus the `reviewUrl` Copilot review link),
173
- then hold with a 45-minute `ScheduleWakeup` for the user's response. When the
174
- user answers within the window, follow their direction. When the window closes
175
- with no response, run normal teardown and report the code-concern findings
176
- un-reviewed.
177
-
178
- ## Budget-aware round boundaries
179
-
180
- The workflow's `budget` API is the pacing signal: when a usage target is
181
- set, `converge.mjs` checks `budget.remaining()` before each round and
182
- stops at the round boundary when one full round (three parallel lenses +
183
- one fix commit + re-verify) does not fit. On a budget stop the workflow
184
- returns `blocker: "budget"` with the run id; resume with
185
- `Workflow({scriptPath, resumeFromRunId})` completed rounds replay from
186
- the journal. Never start a round the budget cannot finish: a half-run
187
- round records nothing resumable and replays dirty.
188
-
189
- On a `blocker: "budget"` return, write the durable handoff with the run id and the
190
- `Workflow({scriptPath, resumeFromRunId})` resume command before stopping, so a
191
- fresh session resumes the paced run without the stopped session's transcript.
197
+ ntfy notification (the per-finding summary and evidence note plus the `reviewUrl`
198
+ Copilot review link), then hold with a 45-minute `ScheduleWakeup` for the user's
199
+ response. When the user answers within the window, follow their direction. When
200
+ the window closes with no response, run normal teardown and report the
201
+ inconclusive findings un-reviewed.
202
+
203
+ ## Budget stop
204
+
205
+ `converge.mjs` paces itself against the workflow `budget` API and stops at a
206
+ round boundary when a full round does not fit —
207
+ [`reference/stop-conditions.md`](reference/stop-conditions.md) § Budget stop
208
+ gives the rule. On a `blocker: "budget"` return, write the durable handoff with
209
+ the run id and the `Workflow({scriptPath, resumeFromRunId})` resume command
210
+ before stopping, so a fresh session resumes the paced run without the stopped
211
+ session's transcript.
192
212
 
193
213
  ## Teardown (on workflow completion)
194
214
 
@@ -212,11 +232,12 @@ On teardown entry, when `~/.claude/runtime/pr-loop/bugteam-pr-<N>/handoff.json`
212
232
  exists, read its `completed_steps` and skip any checkpoint the list already
213
233
  names, so a resumed run performs only the checkpoints left.
214
234
 
215
- On a `blocker: "user-review"` return, run the
216
- [`copilot-finding-triage`](../copilot-finding-triage/SKILL.md) gate before
217
- teardown: send the ntfy alert with the finding summary and the
218
- `userReview.reviewUrl` link, then hold with a 45-minute `ScheduleWakeup`. Act on
219
- the user's direction when it arrives inside the window; when the window closes
235
+ On a `blocker: "user-review"` return, the workflow held one or more code-concern
236
+ findings that stayed inconclusive after the executed-check verification stage.
237
+ Run the [`copilot-finding-triage`](../copilot-finding-triage/SKILL.md) gate before
238
+ teardown: send the ntfy alert with the per-finding summary and evidence note and
239
+ the `userReview.reviewUrl` link, then hold with a 45-minute `ScheduleWakeup`. Act
240
+ on the user's direction when it arrives inside the window; when the window closes
220
241
  with no response, fall through to normal teardown and report the
221
242
  `userReview.findings` un-reviewed. The PR stays a draft in this path — the
222
243
  workflow marked nothing ready.
@@ -232,77 +253,16 @@ round per the `pr-fix-protocol` skill, re-verify, push, and mark the PR
232
253
  ready again — then run the checkpoints.
233
254
 
234
255
  1. **When `converged` is true — build and publish the closing report.**
235
- Skip this entire step (report, artifact publish, comment, Chrome open) when the
236
- workflow returned a non-null `blocker`. Per-round live-dashboard refresh is out of
237
- scope here; this step builds the one-shot closing report and the seam (marker
238
- comment + artifact URL) a future live-dashboard reuses.
239
-
240
- a. **Resolve a seed journal path.** Glob
241
- `~/.claude/projects/**/workflows/wf_<runId>.json` (where `runId` is the run id
242
- the `Workflow` result returned) and take the match. It seeds the merge, which
243
- finds every other autoconverge journal for the same PR.
244
-
245
- b. **Merge the PR's runs and build the summary prompt.**
246
- ```
247
- python "<skill>/workflow/aggregate_runs.py" \
248
- --journal "<seed journal>" \
249
- --pr <owner>/<repo>#<n> \
250
- --work-dir "$CLAUDE_JOB_DIR/tmp/autoconverge-agg-<prNumber>" \
251
- --out-prompt "$CLAUDE_JOB_DIR/tmp/autoconverge-summary-prompt-<prNumber>.txt" \
252
- [--standards-note "<standardsNote>"] [--copilot-note "<copilotNote>"]
253
- ```
254
- It prints a JSON line with `combinedJournal`, `roundCount`, `finalSha`, and
255
- `findingCount`. Pass `--standards-note`/`--copilot-note` only when the workflow
256
- returned those notes.
257
-
258
- c. **Write the summary.** Spawn a `convergence-summary` agent (a `general-purpose`
259
- subagent) on the text of the prompt file from step b. The agent answers with the
260
- `prProblem`/`prFix`/`problemScenes`/`fixScenes`/`verdictLine`/`issueClasses` JSON
261
- object; write that object to
262
- `$CLAUDE_JOB_DIR/tmp/autoconverge-summary-<prNumber>.json`.
263
-
264
- d. **Build the report.**
265
- ```
266
- python "<skill>/workflow/render_report.py" \
267
- --journal "<combinedJournal>" \
268
- --summary-file "<summary json>" \
269
- --out "$CLAUDE_JOB_DIR/tmp/autoconverge-report-<prNumber>.html" \
270
- --pr <owner>/<repo>#<n> \
271
- --final-sha <finalSha> \
272
- --rounds <roundCount>
273
- ```
274
- Use the `combinedJournal`, `finalSha`, and `roundCount` from step b. Capture the
275
- output path from stdout.
276
-
277
- e. **Publish via the Artifact tool.** Load the `artifact-design` skill first, then
278
- call `Artifact` with `file_path` set to the report path from step d, `favicon`
279
- set to the fixed autoconverge favicon `✅` (keep this favicon stable across
280
- every autoconverge report — never swap it per run), and `description` set to
281
- a one-sentence subtitle naming the PR. Capture the returned URL.
282
-
283
- f. **Post one idempotent PR comment.** List the PR's issue comments; if one
284
- carries the marker `<!-- autoconverge-report -->`, edit it in place, otherwise
285
- create a new one. The body begins with `<!-- autoconverge-report -->`, then
286
- the artifact URL, then a plain-language summary that mirrors the report:
287
- lead with the one-sentence `verdictLine`; then the plain Problem and Fix
288
- sentences (`prProblem`, `prFix`); then the issue-class list — one bullet per
289
- class as `plainName (×count, status)`. Place the raw finding list as
290
- `file:line — P# — title` inside a collapsed
291
- `<details><summary>Raw findings</summary>…</details>` block so the comment leads
292
- with the human summary. Honor the gh-body-file rule: write a BOM-free temp file
293
- and pass `--body-file` to `gh issue comment`/`gh issue comment edit`, or use the
294
- GitHub MCP `add_issue_comment` tool (body as a structured parameter, no
295
- `--body` flag).
296
-
297
- g. **Open the published report in Chrome.** Use the artifact URL captured in
298
- step e.
299
- ```
300
- Start-Process chrome -ArgumentList '--new-window', '<artifact URL>'
301
- ```
302
- Skip a missing Chrome without aborting the rest of teardown.
303
-
304
- After the report is published, write the handoff with
305
- `--completed-steps "report"`.
256
+ Skip this entire step (report, artifact publish, comment, Chrome open) when
257
+ the workflow returned a non-null `blocker`. Follow
258
+ [`reference/closing-report.md`](reference/closing-report.md) § Building the
259
+ report and § Publishing: resolve the seed journal from the run id, merge the
260
+ PR's runs with `aggregate_runs.py`, spawn the `convergence-summary` agent
261
+ (a `general-purpose` subagent) on the prompt it builds, draw the report with
262
+ `render_report.py`, publish the HTML via the `Artifact` tool, post the
263
+ one marker-keyed `<!-- autoconverge-report -->` PR comment, and open the
264
+ artifact URL in Chrome. After the report is published, write the handoff
265
+ with `--completed-steps "report"`.
306
266
 
307
267
  2. **Close the run.** Apply the `pr-loop-lifecycle` skill's Close section
308
268
  (`../pr-loop-lifecycle/SKILL.md`): when `converged` is true, rewrite the PR
@@ -321,287 +281,46 @@ ready again — then run the checkpoints.
321
281
  Blocker: <blocker> # only when blocked
322
282
  Standards: <standardsNote> # only when a round deferred code-standard findings
323
283
  Copilot: <copilotNote> # only when Copilot was down or out of quota
284
+ Clean-audit: <cleanAuditNote> # only when the CLEAN bugteam post was bypassed
324
285
  Reuse: <reuseNote> # only when the reuse pass identified an improvement
325
286
  ```
326
287
 
327
- ## Reuse pass (before convergence)
328
-
329
- Before the first round, one reuse lens (`code-quality-agent`) scans the full
330
- `origin/main...HEAD` diff for places the PR re-implements behavior the codebase
331
- already provides. It reports a reuse improvement only when all three criteria
332
- hold, and drops any case where even one is in doubt:
333
-
334
- - **Certain** — an existing symbol or module unquestionably covers the new
335
- code's behavior, cited at `file:line`.
336
- - **Behaviorally identical** — swapping the new code for the existing one
337
- changes no observable behavior: same inputs, outputs, side effects, and error
338
- handling.
339
- - **Autonomously implementable** — the replacement is a mechanical edit (import
340
- and call the existing symbol, delete the duplicate) needing no product
341
- decision and no human judgment.
342
-
343
- The reuse lens reports without editing. Qualifying improvements then run through
344
- the same edit → verify → commit fix flow the rounds use, so they land in one
345
- verified commit before convergence starts. The pass is best-effort: when no case
346
- clears all three criteria, the run proceeds straight to convergence, and
347
- `reuseNote` records what landed.
348
-
349
288
  ## What the workflow does each round
350
289
 
351
- See [`reference/convergence.md`](reference/convergence.md) for the full round
352
- shape and the exact convergence definition, and
353
- [`reference/stop-conditions.md`](reference/stop-conditions.md) for every way the
354
- run ends short of ready. Hard-won failure lessons live in
290
+ [`reference/convergence.md`](reference/convergence.md) defines the whole loop:
291
+ the merge-conflict pre-flight, the reuse pass and its three landing criteria,
292
+ the round shape (static sweep, the three parallel reading lenses, dedup, the
293
+ one-commit fix flow, the standards-deferral path), the terminal Bugbot and
294
+ Copilot gates, the per-role model tiers, the full-diff rule, and the exact
295
+ ready definition `check_convergence.py` enforces.
296
+ [`reference/stop-conditions.md`](reference/stop-conditions.md) lists every way
297
+ the run ends short of ready. Hard-won failure lessons live in
355
298
  [`reference/gotchas.md`](reference/gotchas.md).
356
299
 
357
- Every agent prompt carries a headless-safety preamble: the run is unattended, so
358
- agents never inline a destructive-command literal (`rm -rf`, `git reset --hard`,
359
- `dd`) into a Bash command the `destructive_command_blocker` hook matches those
360
- patterns as raw text, and a confirmation prompt no human can answer would stall
361
- the run. The preamble has two forms. Read-only agents — the review, verify, and
362
- utility spawns that edit nothing — receive a trimmed form that drops the rm-shape
363
- rules, since a read-only agent never runs `rm`. Edit agents — the fix and commit
364
- spawns — receive the full form that carries the rm-shape rules described below.
365
- Agents verify destructive-blocker behavior through the committed test
366
- suite (`python -m pytest`) and keep scratch work in the OS temp dir. The full
367
- preamble describes the narrowest rm auto-allow path — a standalone Bash call whose target
368
- resolves inside the ephemeral namespace (`/tmp`, `/temp`, the OS temp root, or the
369
- run worktree) — and a compound path that accepts an rm joined with benign
370
- reporting segments when every rm target is an absolute ephemeral path. Both of
371
- those paths fail closed on `$(...)` substitution and backtick subshells. The
372
- compound path also fails closed on any `$` in the target — including
373
- `$CLAUDE_JOB_DIR`. The standalone path declines a `$`-bearing target only when
374
- the literal path is not already under an ephemeral root, so it does not by
375
- itself stop a `$VAR` that expands inside an ephemeral root. A third, broad path
376
- matches only when the command itself declares an
377
- ephemeral working directory (it `cd`s into one, or runs under one): that
378
- cwd-scoped path resolves the target against the declared cwd, fails closed on
379
- `$(...)`, backticks, and unknown variables, and resolves the known temporary
380
- variables `TEMP`, `TMP`, `TMPDIR`, and `CLAUDE_JOB_DIR` to the OS temp root, so
381
- under that declared ephemeral cwd a bare `$CLAUDE_JOB_DIR/tmp/<name>` target and a
382
- relative target after a `cd` are auto-allowed. Even so, for any cleanup whose path
383
- is variable-built or whose teardown spans multiple steps, agents author a Python
384
- helper file and run it as `python <file>.py` — keeping every destructive literal
385
- out of a Bash command string entirely and independent of which auto-allow path
386
- matches.
387
-
388
- - **Static sweep:** each round opens with a deterministic static-sweep lens that
389
- runs the CODE_RULES gate (`code_rules_gate.py --base origin/main`), `ruff`,
390
- `mypy`, and stem-matched `pytest` over the changed files. Any failure routes
391
- through the same fix flow and the round re-runs, so the reading lenses only ever
392
- review sweep-clean code. The sweep uses local commands only, so it runs in any
393
- session.
394
- - **Converge:** `parallel([code-review lens, bug-audit lens, self-review lens])`
395
- on the current HEAD, full `origin/main...HEAD` diff. The bug-audit lens applies
396
- the A-P rubric and then its adversarial second pass; the self-review lens covers
397
- the doc-vs-code parity, test-assertion completeness, and PR-description-vs-diff
398
- parity lanes. The preflight step fetches `origin/main` once for the round and
399
- enumerates the diff (changed-file list plus diffstat); each lens receives that
400
- list and reads only the files it needs rather than re-deriving the diff, forming
401
- its own review judgment. Dedup findings; one `clean-coder` applies the round's
402
- fixes per the `pr-fix-protocol` skill (`../pr-fix-protocol/SKILL.md`) — fix,
403
- reply, resolve — landing every fix in one commit per round, which the workflow
404
- journal records; re-verify next round on the new HEAD. Every edit step ends with
405
- a pre-commit gate check: before its turn ends, the fixer dry-runs the CODE_RULES
406
- commit gate (`code_rules_gate.py --staged`) and keeps fixing until that gate
407
- would accept the commit — it makes no commit itself. When all three internal
408
- lenses are clean on a stable HEAD, post the CLEAN bugteam audit artifact.
409
- A round whose findings are ALL code-standard violations (pure CODE_RULES/style,
410
- no behavioral impact) passes for convergence purposes: the workflow files a
411
- follow-up issue listing the findings, opens a draft environment-hardening PR
412
- (hooks/rules that block those violation classes at Write/Edit time), resolves
413
- any bot threads with a deferral note, and reports the deferral in
414
- `standardsNote`.
415
- - **Bugbot gate:** the terminal Cursor Bugbot confirmation gate runs once the
416
- internal lenses are clean. When Bugbot is disabled or opted out for the run (the
417
- default) or unreachable, the gate spawns no agent and passes straight to the
418
- Copilot gate. Otherwise it fetches Bugbot's verdict on the HEAD; findings route
419
- back into Converge, and a clean verdict advances to the Copilot gate.
420
- - **Copilot gate:** the terminal GitHub Copilot confirmation gate. Request a
421
- Copilot review, poll up to the configured cap; findings route back into
422
- Converge. When Copilot is down or out of quota — it posts an out-of-usage notice
423
- (the requester hit their quota) on the HEAD, or surfaces no review at all after
424
- the configured cap — the gate logs a notice and the run marks the PR ready with
425
- the Copilot gate bypassed. `copilotNote` records the bypass.
426
- - **Convergence check:** `check_convergence.py` is the authoritative gate; one
427
- agent runs it and, on a full pass, marks `draft=false` in the same turn. Each
428
- spawned agent runs on the model tier its role needs — sonnet/medium for the
429
- deterministic static sweep, opus/medium for the code-review, bug-audit,
430
- self-review, reuse, and terminal Bugbot lenses and the code-editing fix steps,
431
- sonnet/medium for the verify, commit, and recovery steps, and haiku/low for the
432
- mechanical probes (preflight, Copilot gate, CLEAN-audit post, convergence
433
- check).
300
+ Every agent prompt the workflow authors carries a headless-safety preamble
301
+ read-only agents get a trimmed form, edit agents the full form with the rm
302
+ auto-allow pathsspecified in
303
+ [`reference/headless-safety.md`](reference/headless-safety.md).
434
304
 
435
305
  ## Multiple PRs
436
306
 
437
- The multi-PR run drives several draft PRs to ready in one launch:
438
- `workflow/converge_multi.mjs` fans out one `converge.mjs` child run per PR with
439
- `parallel()`, and every child is pinned to its own PR's worktree through the
440
- `repoPath` it receives, so the children never share a checkout. Each child run is
441
- the exact single-PR convergence loop same rounds, same reuse pass, same Copilot
442
- gate, same convergence check — one per PR at once. The children share the run's
443
- concurrency cap, so the fan-out self-throttles rather than spawning every PR's
444
- lenses at the same instant.
445
-
446
- ### Multi-PR pre-flight (main session)
447
-
448
- `EnterWorktree` puts the session on one branch only, so the multi-PR path gives
449
- each PR its own checkout with `git worktree add`. For each PR the user named:
450
-
451
- 1. **Resolve PR scope** as the single-PR pre-flight step 2 does: capture `owner`,
452
- `repo`, `prNumber`, and `headRefName`; confirm the PR is a draft, and mark it
453
- draft (`gh pr ready <n> --repo <o>/<r> --undo`) when it is already ready so the
454
- loop owns the ready transition.
455
- 2. **Create a worktree on the PR's head ref** and capture its absolute path. From
456
- inside the PR's repository checkout:
457
- `git worktree add <abs worktree path> <headRefName>` (run `git fetch origin
458
- <headRefName>` first when the ref is not local). Put each PR's worktree under a
459
- path carrying its PR number so the fan-out keeps them distinct. Confirm
460
- `git -C <abs worktree path> rev-parse --abbrev-ref HEAD` equals the head ref
461
- and its `HEAD` equals the PR head SHA.
462
- 3. **Verify each worktree is the PR's repo (strict pre-flight):**
463
- `python "$HOME/.claude/skills/_shared/pr-loop/scripts/preflight_worktree.py" --owner <owner> --repo <repo> --mode strict`,
464
- run with that worktree as the working directory. A non-zero exit prints a
465
- `PREFLIGHT_OUTCOME` line and an `ABORT` line: report it and drop that PR from
466
- the run rather than aborting every PR.
467
- 4. **Grant project permissions once per repository** — the single-PR pre-flight
468
- step 4 grant covers every worktree of the same repo, so run it one time for
469
- the repo the PRs live in.
470
- 5. **Copilot quota pre-check once for the whole run** — run the single-PR
471
- pre-flight step 5 check one time:
472
- `python "$HOME/.claude/_shared/pr-loop/scripts/copilot_quota.py"`. Every PR in
473
- the run shares one account's Copilot premium-request quota, so one check covers
474
- them all. Exit 0 sets `copilotDisabled: false` on every PR entry below; any
475
- non-zero exit sets `copilotDisabled: true` on every entry, so each child skips
476
- the Copilot gate with no agent spawned.
477
-
478
- ### Launch the multi-PR workflow
479
-
480
- Call the `Workflow` tool against the fan-out script, passing the absolute path of
481
- `converge.mjs` and one entry per PR:
482
-
483
- ```
484
- Workflow({
485
- scriptPath: "<this skill dir>/workflow/converge_multi.mjs",
486
- args: {
487
- convergeScriptPath: "<this skill dir>/workflow/converge.mjs",
488
- prs: [
489
- { owner: "<O>", repo: "<R>", prNumber: <N1>, repoPath: "<abs worktree 1>", bugbotDisabled: false, copilotDisabled: false },
490
- { owner: "<O>", repo: "<R>", prNumber: <N2>, repoPath: "<abs worktree 2>", bugbotDisabled: false, copilotDisabled: false }
491
- ]
492
- }
493
- })
494
- ```
495
-
496
- `convergeScriptPath` is the absolute path to `workflow/converge.mjs` in this same
497
- skill directory; each `repoPath` is the absolute path of the worktree that PR is
498
- checked out in. The workflow runs in the background and notifies this session on
499
- completion; watch live progress with `/workflows`, where each PR's child run
500
- appears under its own group.
501
-
502
- The workflow returns
503
- `{ converged, prCount, convergedCount, results, allDeferredPrs, blocker }`, where
504
- `results` is one record per PR carrying
505
- `{ owner, repo, prNumber, converged, rounds, finalSha, blocker, deferredPrs }`.
506
- Each record's `deferredPrs` is that PR's own list of draft hardening PRs, and
507
- `allDeferredPrs` is every record's `deferredPrs` flattened into one list. The
508
- top-level `converged` is true only when every PR converged.
509
-
510
- ### Multi-PR teardown (on workflow completion)
511
-
512
- Run the single-PR [Teardown](#teardown-on-workflow-completion) once per entry in
513
- `results`, using that PR's `owner`, `repo`, `prNumber`, and `finalSha`, and its
514
- own worktree as the working directory. Write one durable handoff per PR entry —
515
- each with that PR's own `--pr-number` — so a fresh session can resume any PR on
516
- its own. Build and publish a PR's closing report
517
- only for a PR whose `converged` is true; for a PR that returned a blocker, skip
518
- its report and carry the blocker into the final summary. Revoke project
519
- permissions once per repository after every PR's teardown. Then print one summary
520
- report — a line per PR as
521
- `#<prNumber>: <converged | blocked> — rounds <N>, final <finalSha>[, blocker <blocker>]`.
307
+ When the user names several PRs, run the multi-PR path in
308
+ [`reference/multi-pr.md`](reference/multi-pr.md): one worktree per PR
309
+ (`git worktree add` on each head ref, strict pre-flight per worktree, one
310
+ permission grant per repository, one Copilot quota check for the whole run),
311
+ then a single `workflow/converge_multi.mjs` launch with one entry per PR, then
312
+ the single-PR teardown once per `results` entry and a one-line-per-PR summary.
522
313
 
523
314
  ## Self-closing loop: converge the deferred PRs
524
315
 
525
- Every run leaves work behind. When a round holds only code-standard findings, the
526
- standards-deferral path opens a draft environment-hardening PR and reports it in
527
- `deferredPrs`. That PR is itself a draft that needs to reach ready, and its own
528
- convergence can defer more standard findings, opening more hardening PRs. The
529
- self-closing loop drives that chain to the ground: after teardown, the
530
- orchestrator (this session, which launched the workflow) converges the deferred
531
- PRs, then the PRs their runs defer, and so on until a generation opens none.
532
-
533
- This loop runs by default at the end of every autoconverge run — single-PR and
534
- multi-PR alike. It stops only when a generation's deferred-PR list comes back
535
- empty.
536
-
537
- ### Seed the loop
538
-
539
- Collect the first generation of deferred PRs from the run that just finished:
540
-
541
- - A single-PR run seeds from its `deferredPrs`.
542
- - A multi-PR run seeds from its `allDeferredPrs`.
543
-
544
- When the seed list is empty, the loop is already done — the run deferred nothing,
545
- so there is nothing to converge. Report that and stop.
546
-
547
- ### Each generation
548
-
549
- Given a non-empty list of deferred PRs `{ owner, repo, prNumber, copilotDisabled, bugbotDisabled }`
550
- (a generation may span more than one repository — a hardening PR lands in whichever repo owns
551
- the surface that blocks the deferred class, so `JonEcho/llm-settings` for hooks
552
- and `jl-cmd/claude-dev-env` for rules and skills both appear):
553
-
554
- 1. **Check out each deferred PR.** Run the
555
- [Multi-PR pre-flight](#multi-pr-pre-flight-main-session) once per deferred PR.
556
- Because a deferred PR can live in a repo the first run never touched, first
557
- find a local checkout of that PR's repo; when none exists, clone it under the
558
- session temp dir, then add the per-PR worktree on the PR's head ref. Drop any
559
- PR whose strict pre-flight fails rather than stopping the whole generation.
560
- Grant project permissions once per repository the generation spans.
561
- 2. **Converge the generation.** Launch `workflow/converge_multi.mjs` with one
562
- entry per checked-out deferred PR, exactly as the
563
- [multi-PR launch](#launch-the-multi-pr-workflow) describes. Each child run
564
- checks Copilot and Bugbot availability through the workflow's own preflight-git
565
- probe, carried across rounds, so a reviewer that is down or out of quota is never
566
- spawned in any generation; the `copilotDisabled`/`bugbotDisabled` flags each
567
- deferred PR carries seed that check for the first round.
568
- 3. **Tear down.** Run the [multi-PR teardown](#multi-pr-teardown-on-workflow-completion)
569
- over the generation's `results`, and revoke project permissions once per
570
- repository.
571
- 4. **Take the next seed.** The generation's `allDeferredPrs` is the next
572
- generation's seed list. When it is empty, the loop is done.
573
-
574
- Repeat from step 1 with each new seed. The depth is unbounded: the loop keeps
575
- opening generations until one converges every deferred PR without deferring
576
- anything new.
577
-
578
- ### Report each generation
579
-
580
- Log one line as each generation finishes, so a watcher sees the chain close:
581
-
582
- ```
583
- Self-closing generation <k>: <converged>/<total> deferred PR(s) converged, <new> new deferred PR(s) opened
584
- ```
585
-
586
- When the loop ends, print a final line naming the generation count and the total
587
- deferred PRs converged across every generation.
588
-
589
- ### Conventional titles on deferred PRs
590
-
591
- Each hardening PR the loop opens targets a repo whose CI validates the PR title
592
- as a Conventional Commit. The commit step's prompt directs the agent to title
593
- the hardening PR as a Conventional Commit — a type prefix, an optional scope,
594
- then a colon and a short summary — so a deferred PR carries a conforming title
595
- (`feat(hooks): …`, `chore(rules): …`) before it exists. That prompt is where the
596
- conforming title is enforced.
597
-
598
- The `conventional_pr_title_gate` hook is a best-effort backstop on that title,
599
- not the guarantee. It blocks a `gh pr create` with a non-conforming `--title`
600
- only for a repo whose semantic-pull-request workflow leaves the action's
601
- `types:` input at the default Conventional Commits list. For a repo that pins
602
- its own explicit `types:` list — which the main target repo does in
603
- `.github/workflows/pr-check.yml` — the hook fails open and lets the title
604
- through, and the CI title check on GitHub has the final say.
316
+ Every autoconverge run single-PR and multi-PR alike ends with the
317
+ self-closing loop in
318
+ [`reference/self-closing-loop.md`](reference/self-closing-loop.md): the
319
+ orchestrating session converges the draft environment-hardening PRs the run
320
+ deferred (`deferredPrs` on a single-PR run, `allDeferredPrs` on a multi-PR
321
+ run), then the PRs those runs defer, generation by generation, until a
322
+ generation opens none. An empty seed list ends the loop at once. The reference
323
+ also carries the Conventional-Commit title rule each hardening PR must meet.
605
324
 
606
325
  ## Folder map
607
326
 
@@ -612,4 +331,10 @@ through, and the CI title check on GitHub has the final say.
612
331
  - `workflow/convergence_summary.py` — builds the convergence-summary agent prompt over a PR's merged findings.
613
332
  - `workflow/render_report.py` — builds the closing convergence insights HTML report, taking the summary from `--summary-file`.
614
333
  - `workflow/autoconverge_report_constants/` — named constants for the report builder and the summary prompt.
615
- - `reference/`convergence definition, stop conditions, gotchas, closing report.
334
+ - `reference/convergence.md`the whole loop: reuse pass, round shape, terminal gates, model tiers, ready definition.
335
+ - `reference/stop-conditions.md` — every way the run ends short of ready, including the budget stop.
336
+ - `reference/gotchas.md` — hard-won failure lessons.
337
+ - `reference/closing-report.md` — the closing HTML report: data source, build steps, publishing.
338
+ - `reference/multi-pr.md` — the several-PRs path: per-PR worktrees, the `converge_multi.mjs` launch, per-PR teardown.
339
+ - `reference/self-closing-loop.md` — the deferred-PR generations and the Conventional-Commit title rule.
340
+ - `reference/headless-safety.md` — the agent-prompt preamble and the rm auto-allow paths.
@@ -9,4 +9,7 @@ Reference documentation for the `autoconverge` skill. The `converge.mjs` workflo
9
9
  | `convergence.md` | Round shape: the static sweep, the three parallel internal lenses (code-review, bug-audit, self-review), deduplication, the fix commit step, the terminal Bugbot and Copilot gates, and the definition of a clean convergence. |
10
10
  | `stop-conditions.md` | Every condition that ends the run short of ready: budget cap, iteration cap, blocker exit, static-sweep stall, Bugbot and Copilot bypass. |
11
11
  | `gotchas.md` | Hard-won lessons from failed runs: PR title validation, conflicting PRs, worktree branch lock, resumed sessions rerooting, and minter issues. |
12
- | `closing-report.md` | Specification for the closing HTML convergence report the teardown step builds and publishes. |
12
+ | `closing-report.md` | The closing HTML convergence report the teardown step builds and publishes: data source, build steps, publishing. |
13
+ | `multi-pr.md` | The several-PRs path: per-PR worktrees, the `converge_multi.mjs` launch, per-PR teardown. |
14
+ | `self-closing-loop.md` | The deferred-PR generations the orchestrator converges after teardown, and the Conventional-Commit title rule on hardening PRs. |
15
+ | `headless-safety.md` | The headless-safety preamble every agent prompt carries, and the rm auto-allow paths. |
@@ -40,7 +40,12 @@ When the summary is absent, the report falls back to a minimal layout: the title
40
40
 
41
41
  ## Building the report
42
42
 
43
- Three steps run at teardown, each a separate process:
43
+ Three steps run at teardown, each a separate process. Working files go under
44
+ `$CLAUDE_JOB_DIR/tmp/` named by PR number — the work dir as
45
+ `autoconverge-agg-<prNumber>`, the prompt as
46
+ `autoconverge-summary-prompt-<prNumber>.txt`, the summary as
47
+ `autoconverge-summary-<prNumber>.json`, and the report as
48
+ `autoconverge-report-<prNumber>.html`:
44
49
 
45
50
  1. **Merge the runs and build the summary prompt.**
46
51
  ```
@@ -51,7 +56,9 @@ Three steps run at teardown, each a separate process:
51
56
  --out-prompt "<prompt path>.txt" \
52
57
  [--standards-note "<note>"] [--copilot-note "<note>"]
53
58
  ```
54
- `--journal` is any one of the PR's journals — the seed that locates the rest. The script prints a JSON line carrying `combinedJournal`, `roundCount`, `finalSha`, and `findingCount`.
59
+ `--journal` is any one of the PR's journals — the seed that locates the rest.
60
+ Resolve it by globbing `~/.claude/projects/**/workflows/wf_<runId>.json`,
61
+ where `runId` is the run id the `Workflow` result returned. The script prints a JSON line carrying `combinedJournal`, `roundCount`, `finalSha`, and `findingCount`.
55
62
 
56
63
  2. **Write the summary.** Spawn a `convergence-summary` agent on the prompt file's text. Its JSON answer — the `prProblem`/`prFix`/`problemScenes`/`fixScenes`/`verdictLine`/`issueClasses` object — goes to a `.json` file.
57
64