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