claude-dev-env 1.93.1 → 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.
- package/_shared/pr-loop/CLAUDE.md +1 -0
- package/_shared/pr-loop/audit-contract.md +1 -1
- package/_shared/pr-loop/gh-payloads.md +3 -3
- package/_shared/pr-loop/post-audit-thread-contract.md +51 -0
- package/_shared/pr-loop/scripts/README.md +2 -2
- package/_shared/pr-loop/scripts/fix_hookspath.py +47 -12
- package/_shared/pr-loop/scripts/tests/test_code_rules_gate.py +0 -69
- package/_shared/pr-loop/scripts/tests/test_fix_hookspath.py +497 -374
- package/_shared/pr-loop/state-schema.md +3 -22
- package/bin/CLAUDE.md +1 -1
- package/bin/install.mjs +2 -7
- package/bin/install.test.mjs +10 -4
- package/hooks/blocking/CLAUDE.md +2 -0
- package/hooks/blocking/pii_commit_command.py +398 -0
- package/hooks/blocking/pii_payload_scan.py +133 -0
- package/hooks/blocking/pii_prevention_blocker.py +151 -449
- package/hooks/blocking/test_pii_prevention_blocker.py +299 -0
- package/hooks/blocking/test_verdict_directory_write_blocker.py +42 -7
- package/hooks/hooks_constants/CLAUDE.md +2 -2
- package/hooks/hooks_constants/code_rules_path_utils_constants.py +0 -2
- package/hooks/hooks_constants/local_identity.py +65 -15
- package/hooks/hooks_constants/pii_prevention_constants.py +16 -0
- package/hooks/hooks_constants/pr_description_enforcer_constants.py +1 -1
- package/hooks/hooks_constants/test_local_identity.py +68 -0
- package/package.json +1 -1
- package/scripts/CLAUDE.md +10 -1
- package/scripts/Get-SessionAccount.ps1 +210 -0
- package/scripts/tests/CLAUDE.md +15 -1
- package/scripts/tests/Get-SessionAccount.Tests.ps1 +350 -0
- package/skills/CLAUDE.md +3 -25
- package/skills/anthropic-plan/SKILL.md +1 -13
- package/skills/autoconverge/CLAUDE.md +5 -2
- package/skills/autoconverge/SKILL.md +112 -387
- package/skills/autoconverge/reference/CLAUDE.md +4 -1
- package/skills/autoconverge/reference/closing-report.md +9 -2
- package/skills/autoconverge/reference/convergence.md +26 -22
- package/skills/autoconverge/reference/headless-safety.md +44 -0
- package/skills/autoconverge/reference/multi-pr.md +88 -0
- package/skills/autoconverge/reference/self-closing-loop.md +84 -0
- package/skills/autoconverge/reference/stop-conditions.md +21 -13
- package/skills/autoconverge/workflow/converge.clean-audit.test.mjs +87 -27
- package/skills/autoconverge/workflow/converge.contract.test.mjs +40 -10
- package/skills/autoconverge/workflow/converge.copilot-gate.test.mjs +179 -47
- package/skills/autoconverge/workflow/converge.fix-progress.test.mjs +1 -1
- package/skills/autoconverge/workflow/converge.mjs +284 -94
- package/skills/bugteam/CLAUDE.md +1 -1
- package/skills/bugteam/CONSTRAINTS.md +3 -3
- package/skills/bugteam/PROMPTS.md +8 -19
- package/skills/bugteam/SKILL.md +13 -14
- package/skills/bugteam/reference/CLAUDE.md +1 -1
- package/skills/bugteam/reference/audit-and-teammates.md +2 -2
- package/skills/bugteam/reference/copilot-gap-analysis.md +2 -0
- package/skills/bugteam/reference/github-pr-reviews.md +56 -38
- package/skills/bugteam/reference/team-setup.md +11 -11
- package/skills/bugteam/scripts/CLAUDE.md +6 -6
- package/skills/bugteam/scripts/README.md +20 -8
- package/skills/bugteam/scripts/bugteam_code_rules_gate.py +13 -1463
- package/skills/bugteam/scripts/bugteam_fix_hookspath.py +23 -358
- package/skills/bugteam/scripts/bugteam_preflight.py +13 -315
- package/skills/bugteam/scripts/bugteam_scripts_constants/CLAUDE.md +2 -3
- package/skills/bugteam/scripts/test_bugteam_code_rules_gate.py +34 -1053
- package/skills/bugteam/scripts/test_bugteam_fix_hookspath.py +30 -347
- package/skills/bugteam/scripts/test_bugteam_preflight.py +30 -305
- package/skills/copilot-finding-triage/SKILL.md +80 -28
- package/skills/copilot-finding-triage/reference/tier-rubric.md +70 -11
- package/skills/copilot-finding-triage/templates/notification.md +8 -3
- package/skills/everything-search/SKILL.md +1 -2
- package/skills/grokify/SKILL.md +58 -0
- package/skills/grokify/templates/handoff-template.md +92 -0
- package/skills/orchestrator/SKILL.md +12 -8
- package/skills/orchestrator-refresh/SKILL.md +3 -3
- package/skills/pr-converge/SKILL.md +132 -233
- package/skills/pr-converge/reference/convergence-gates.md +102 -66
- package/skills/pr-converge/reference/examples.md +37 -25
- package/skills/pr-converge/reference/fix-protocol.md +7 -7
- package/skills/pr-converge/reference/multi-pr-orchestration.md +10 -4
- package/skills/pr-converge/reference/per-tick.md +64 -41
- package/skills/pr-converge/reference/state-schema.md +27 -2
- package/skills/pr-converge/scripts/CLAUDE.md +8 -0
- package/skills/pr-converge/scripts/README.md +4 -3
- package/skills/pr-converge/scripts/_pr_converge_path_setup.py +23 -0
- package/skills/pr-converge/scripts/check_convergence.py +189 -645
- package/skills/pr-converge/scripts/check_convergence_gates.py +235 -0
- package/skills/pr-converge/scripts/check_convergence_thread_gates.py +219 -0
- package/skills/pr-converge/scripts/conftest.py +8 -0
- package/skills/pr-converge/scripts/pr_converge_scripts_constants/CLAUDE.md +1 -0
- package/skills/pr-converge/scripts/pr_converge_scripts_constants/convergence_gate_constants.py +36 -0
- package/skills/pr-converge/scripts/test__pr_converge_path_setup.py +26 -0
- package/skills/pr-converge/scripts/test_check_convergence.py +73 -228
- package/skills/pr-converge/scripts/test_check_convergence_contract.py +321 -0
- package/skills/pr-converge/scripts/test_check_convergence_gates.py +68 -0
- package/skills/pr-converge/scripts/test_check_convergence_thread_gates.py +75 -0
- package/skills/privacy-hygiene/SKILL.md +4 -3
- package/skills/reviewer-gates/SKILL.md +26 -8
- package/skills/session-log/SKILL.md +11 -12
- package/skills/session-tidy/SKILL.md +40 -30
- package/skills/skill-builder/CLAUDE.md +13 -10
- package/skills/skill-builder/SKILL.md +31 -31
- package/skills/skill-builder/references/CLAUDE.md +10 -6
- package/skills/skill-builder/references/delegation-map.md +13 -4
- package/skills/skill-builder/references/description-field.md +113 -0
- package/skills/skill-builder/references/self-audit-checklist.md +21 -4
- package/skills/skill-builder/references/skill-modularity.md +113 -0
- package/skills/skill-builder/references/skill-types.md +4 -0
- package/skills/skill-builder/templates/CLAUDE.md +4 -4
- package/skills/skill-builder/templates/gap-analysis.md +25 -1
- package/skills/skill-builder/workflows/CLAUDE.md +6 -4
- package/skills/skill-builder/workflows/improve-skill.md +17 -16
- package/skills/skill-builder/workflows/new-skill.md +34 -10
- package/skills/skill-builder/workflows/polish-skill.md +59 -43
- package/skills/usage-pause/SKILL.md +10 -14
- package/skills/bdd-protocol/CLAUDE.md +0 -26
- package/skills/bdd-protocol/SKILL.md +0 -30
- package/skills/bdd-protocol/references/CLAUDE.md +0 -10
- package/skills/bdd-protocol/references/anti-patterns.md +0 -26
- package/skills/bdd-protocol/references/example-mapping.md +0 -23
- package/skills/bg-agent/CLAUDE.md +0 -17
- package/skills/bg-agent/SKILL.md +0 -69
- package/skills/bugteam/scripts/bugteam_scripts_constants/bugteam_code_rules_gate_constants.py +0 -55
- package/skills/bugteam/scripts/bugteam_scripts_constants/bugteam_fix_hookspath_constants.py +0 -26
- package/skills/bugteam/scripts/bugteam_scripts_constants/bugteam_preflight_constants.py +0 -35
- package/skills/caveman/CLAUDE.md +0 -15
- package/skills/caveman/SKILL.md +0 -38
- package/skills/code/CLAUDE.md +0 -17
- package/skills/code/SKILL.md +0 -178
- package/skills/deep-research/CLAUDE.md +0 -17
- package/skills/deep-research/SKILL.md +0 -80
- package/skills/findbugs/CLAUDE.md +0 -20
- package/skills/findbugs/SKILL.md +0 -241
- package/skills/fixbugs/CLAUDE.md +0 -19
- package/skills/fixbugs/SKILL.md +0 -142
- package/skills/gh-paginate/CLAUDE.md +0 -18
- package/skills/gh-paginate/SKILL.md +0 -84
- package/skills/gotcha/CLAUDE.md +0 -33
- package/skills/gotcha/SKILL.md +0 -73
- package/skills/implement/CLAUDE.md +0 -27
- package/skills/implement/SKILL.md +0 -66
- package/skills/implement/scripts/CLAUDE.md +0 -22
- package/skills/implement/scripts/append_note.py +0 -133
- package/skills/implement/scripts/implement_scripts_constants/CLAUDE.md +0 -22
- package/skills/implement/scripts/implement_scripts_constants/__init__.py +0 -0
- package/skills/implement/scripts/implement_scripts_constants/notes_constants.py +0 -12
- package/skills/implement/scripts/test_append_note.py +0 -191
- package/skills/log-audit/CLAUDE.md +0 -20
- package/skills/log-audit/SKILL.md +0 -66
- package/skills/log-audit/reference/CLAUDE.md +0 -9
- package/skills/log-audit/reference/charter.md +0 -52
- package/skills/log-audit/scripts/CLAUDE.md +0 -27
- package/skills/log-audit/scripts/cluster_recurrences.py +0 -261
- package/skills/log-audit/scripts/collect_log_window.py +0 -199
- package/skills/log-audit/scripts/log_audit_constants/CLAUDE.md +0 -12
- package/skills/log-audit/scripts/log_audit_constants/__init__.py +0 -0
- package/skills/log-audit/scripts/log_audit_constants/cluster_recurrences_constants.py +0 -23
- package/skills/log-audit/scripts/log_audit_constants/collect_log_window_constants.py +0 -24
- package/skills/log-audit/scripts/log_audit_constants/mine_copilot_findings_constants.py +0 -49
- package/skills/log-audit/scripts/mine_copilot_findings.py +0 -302
- package/skills/log-audit/scripts/test_cluster_recurrences.py +0 -160
- package/skills/log-audit/scripts/test_collect_log_window.py +0 -111
- package/skills/log-audit/scripts/test_mine_copilot_findings.py +0 -126
- package/skills/logifix/CLAUDE.md +0 -36
- package/skills/logifix/SKILL.md +0 -69
- package/skills/logifix/scripts/CLAUDE.md +0 -16
- package/skills/logifix/scripts/logifix.ps1 +0 -205
- package/skills/monitor-open-prs/CLAUDE.md +0 -34
- package/skills/monitor-open-prs/SKILL.md +0 -88
- package/skills/monitor-open-prs/scripts/CLAUDE.md +0 -17
- package/skills/monitor-open-prs/scripts/discover_open_prs.py +0 -69
- package/skills/monitor-open-prs/scripts/test_discover_open_prs.py +0 -149
- package/skills/monitor-open-prs/test_skill_contract.py +0 -27
- package/skills/post-audit-findings/SKILL.md +0 -80
- package/skills/pr-consistency-audit/CLAUDE.md +0 -34
- package/skills/pr-consistency-audit/SKILL.md +0 -116
- package/skills/pr-consistency-audit/reference/CLAUDE.md +0 -16
- package/skills/pr-consistency-audit/reference/detection-rules.md +0 -96
- package/skills/pr-consistency-audit/reference/illustrations.md +0 -78
- package/skills/pr-fix-protocol/SKILL.md +0 -65
- package/skills/pr-review-responder/CLAUDE.md +0 -35
- package/skills/pr-review-responder/EXAMPLES.md +0 -590
- package/skills/pr-review-responder/PRINCIPLES.md +0 -533
- package/skills/pr-review-responder/README.md +0 -168
- package/skills/pr-review-responder/SKILL.md +0 -203
- package/skills/pr-review-responder/TESTING.md +0 -350
- package/skills/pr-scope-resolve/SKILL.md +0 -45
- package/skills/pre-compact/CLAUDE.md +0 -24
- package/skills/pre-compact/SKILL.md +0 -134
- package/skills/qbug/CLAUDE.md +0 -40
- package/skills/qbug/SKILL.md +0 -387
- package/skills/qbug/test_qbug_skill_audit_schema.py +0 -152
- package/skills/qbug/test_qbug_skill_post_fix_audit.py +0 -103
- package/skills/refine/CLAUDE.md +0 -44
- package/skills/refine/SKILL.md +0 -262
- package/skills/refine/templates/CLAUDE.md +0 -17
- package/skills/refine/templates/implementation-notes-template.html +0 -56
- package/skills/refine/templates/plan-template.md +0 -60
- package/skills/research-mode/CLAUDE.md +0 -35
- package/skills/research-mode/SKILL.md +0 -53
- package/skills/structure-prompt/CLAUDE.md +0 -42
- package/skills/structure-prompt/SKILL.md +0 -44
- package/skills/structure-prompt/reference/CLAUDE.md +0 -28
- package/skills/structure-prompt/reference/adversarial-tuning.md +0 -62
- package/skills/structure-prompt/reference/block-classification.md +0 -27
- package/skills/structure-prompt/reference/canonical-case.md +0 -48
- package/skills/structure-prompt/reference/citation-depth.md +0 -70
- package/skills/structure-prompt/reference/cleanup.md +0 -33
- package/skills/structure-prompt/reference/constraints.md +0 -33
- package/skills/structure-prompt/reference/directives.md +0 -37
- package/skills/structure-prompt/reference/examples.md +0 -72
- package/skills/structure-prompt/reference/instantiation.md +0 -51
- package/skills/structure-prompt/reference/output-contract.md +0 -72
- package/skills/structure-prompt/reference/per-category.md +0 -23
- package/skills/structure-prompt/reference/persona.md +0 -38
- package/skills/structure-prompt/reference/research.md +0 -33
- package/skills/structure-prompt/reference/structure.md +0 -28
- package/skills/verified-build/CLAUDE.md +0 -33
- package/skills/verified-build/SKILL.md +0 -33
|
@@ -48,19 +48,7 @@ The workflow writes the packet into the live checkout under `docs/plans/<slug>/`
|
|
|
48
48
|
|
|
49
49
|
## Workflow Contract
|
|
50
50
|
|
|
51
|
-
The workflow
|
|
52
|
-
|
|
53
|
-
1. Resolve repo root and packet path.
|
|
54
|
-
2. Read project instructions, rules, relevant skills, manifests, docs, tests, hooks, agents, commands, configs, and workflows.
|
|
55
|
-
3. Build a source inventory and extract source facts into `context/source-map.md`.
|
|
56
|
-
4. Write the packet under `docs/plans/<slug>/`.
|
|
57
|
-
5. Run `packages/claude-dev-env/skills/anthropic-plan/scripts/validate_packet.py`.
|
|
58
|
-
6. Spawn `plan-packet-validator` in fresh context.
|
|
59
|
-
7. Repair packet findings up to the workflow cap.
|
|
60
|
-
8. Run the reuse audit: search the codebase for existing equivalents of each new file/symbol the packet introduces, write `validation/reuse-audit.md`, and gate approval on any unjustified reproduction.
|
|
61
|
-
9. Build a single-file offline visual HTML of the finished packet from `templates/visual-plan.template.html` and write it beside the packet as `visual-plan.html`.
|
|
62
|
-
10. Return packet path, validation state, and findings.
|
|
63
|
-
11. Stop before implementation.
|
|
51
|
+
Phases run inside `workflow/plan-packet.mjs` (Discover → Write packet under `docs/plans/<slug>/` → Validate with `validate_packet.py` and `plan-packet-validator` → Reuse audit → Visualize → Approval). The workflow returns the packet path and validation state, then **stop before implementation**. Phase detail lives in that script's `phases` list.
|
|
64
52
|
|
|
65
53
|
## Packet Shape
|
|
66
54
|
|
|
@@ -21,9 +21,12 @@ Drives one draft PR to convergence in a single autonomous workflow run. Each rou
|
|
|
21
21
|
| `workflow/convergence_summary.py` | Builds the convergence-summary agent prompt over the merged findings. |
|
|
22
22
|
| `workflow/render_report.py` | Builds the closing HTML report from the merged journal and summary. |
|
|
23
23
|
| `reference/convergence.md` | Round shape: the static sweep, the three parallel internal lenses, deduplication, fix commit, the terminal Bugbot and Copilot gates, and the ready definition. |
|
|
24
|
-
| `reference/stop-conditions.md` | Every way the run ends short of ready. |
|
|
24
|
+
| `reference/stop-conditions.md` | Every way the run ends short of ready, including the budget stop. |
|
|
25
25
|
| `reference/gotchas.md` | Hard-won failure lessons. |
|
|
26
|
-
| `reference/closing-report.md` |
|
|
26
|
+
| `reference/closing-report.md` | The closing HTML report: data source, build steps, publishing. |
|
|
27
|
+
| `reference/multi-pr.md` | The several-PRs path: per-PR worktrees, the `converge_multi.mjs` launch, per-PR teardown. |
|
|
28
|
+
| `reference/self-closing-loop.md` | The deferred-PR generations and the Conventional-Commit title rule. |
|
|
29
|
+
| `reference/headless-safety.md` | The agent-prompt headless-safety preamble and the rm auto-allow paths. |
|
|
27
30
|
|
|
28
31
|
## Entry point
|
|
29
32
|
|
|
@@ -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](
|
|
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
|
|
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](
|
|
151
|
-
|
|
152
|
-
## Copilot findings —
|
|
153
|
-
|
|
154
|
-
The Copilot gate tiers each finding
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
`
|
|
167
|
-
`
|
|
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`
|
|
173
|
-
then hold with a 45-minute `ScheduleWakeup` for the user's
|
|
174
|
-
user answers within the window, follow their direction. When
|
|
175
|
-
with no response, run normal teardown and report the
|
|
176
|
-
un-reviewed.
|
|
177
|
-
|
|
178
|
-
## Budget
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
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,
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
the
|
|
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
|
|
236
|
-
workflow returned a non-null `blocker`.
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
a
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
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
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
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
|
|
358
|
-
agents
|
|
359
|
-
|
|
360
|
-
|
|
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 paths — specified in
|
|
303
|
+
[`reference/headless-safety.md`](reference/headless-safety.md).
|
|
434
304
|
|
|
435
305
|
## Multiple PRs
|
|
436
306
|
|
|
437
|
-
|
|
438
|
-
`
|
|
439
|
-
`
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
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
|
|
526
|
-
|
|
527
|
-
`
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
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
|
|
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` |
|
|
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. |
|