claude-dev-env 1.92.1 → 1.93.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +6 -2
- package/_shared/CLAUDE.md +2 -1
- package/_shared/advisor/CLAUDE.md +21 -0
- package/_shared/advisor/advisor-protocol.md +142 -0
- package/_shared/advisor/scripts/config/advisor_scripts_constants/__init__.py +1 -0
- package/_shared/advisor/scripts/config/advisor_scripts_constants/model_tier_run_validator_constants.py +86 -0
- package/_shared/advisor/scripts/model_tier_run_validator.py +246 -0
- package/_shared/advisor/scripts/pyproject.toml +3 -0
- package/_shared/advisor/scripts/tests/test_model_tier_run_validator.py +302 -0
- package/_shared/advisor/scripts/tests/test_tier_model_ids.py +180 -0
- package/_shared/advisor/scripts/tier_model_ids.py +164 -0
- package/_shared/pr-loop/CLAUDE.md +1 -0
- package/_shared/pr-loop/precatch-rubric.md +65 -0
- package/_shared/pr-loop/scripts/CLAUDE.md +1 -1
- package/_shared/pr-loop/scripts/code_rules_gate.py +137 -5
- package/_shared/pr-loop/scripts/post_audit_thread.py +1 -1
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/CLAUDE.md +1 -1
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/code_rules_gate_constants.py +16 -0
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/reviews_disabled_constants.py +2 -1
- package/_shared/pr-loop/scripts/reviewer_availability.py +42 -12
- package/_shared/pr-loop/scripts/reviews_disabled.py +65 -21
- package/_shared/pr-loop/scripts/terminology_sweep.py +69 -21
- package/_shared/pr-loop/scripts/tests/CLAUDE.md +1 -1
- package/_shared/pr-loop/scripts/tests/fixtures/{copilot_internal_user_jonecho.json → copilot_internal_user_example.json} +1 -1
- package/_shared/pr-loop/scripts/tests/test_agent_config_carveout.py +1 -1
- package/_shared/pr-loop/scripts/tests/test_code_rules_gate.py +146 -2
- package/_shared/pr-loop/scripts/tests/test_copilot_quota.py +8 -8
- package/_shared/pr-loop/scripts/tests/test_reviewer_availability.py +18 -5
- package/_shared/pr-loop/scripts/tests/test_reviews_disabled.py +56 -5
- package/_shared/pr-loop/scripts/tests/test_terminology_sweep.py +104 -17
- package/agents/CLAUDE.md +3 -2
- package/agents/clasp-deployment-orchestrator.md +2 -2
- package/agents/code-advisor.md +7 -5
- package/agents/code-verifier.md +6 -2
- package/agents/session-advisor.md +27 -0
- package/audit-rubrics/category_rubrics/category-j-code-rules-compliance.md +1 -1
- package/audit-rubrics/category_rubrics/category-k-codebase-conflicts.md +1 -1
- package/audit-rubrics/prompts/category-a-api-contracts.md +2 -2
- package/audit-rubrics/prompts/category-b-selector-engine-compat.md +2 -2
- package/audit-rubrics/prompts/category-c-resource-cleanup.md +2 -2
- package/audit-rubrics/prompts/category-d-scoping-and-ordering.md +2 -2
- package/audit-rubrics/prompts/category-e-dead-code.md +2 -2
- package/audit-rubrics/prompts/category-f-silent-failures.md +2 -2
- package/audit-rubrics/prompts/category-g-bounds-and-overflow.md +2 -2
- package/audit-rubrics/prompts/category-h-security-boundaries.md +2 -2
- package/audit-rubrics/prompts/category-i-concurrency.md +2 -2
- package/audit-rubrics/prompts/category-j-code-rules-compliance.md +2 -2
- package/audit-rubrics/prompts/category-k-codebase-conflicts.md +2 -2
- package/audit-rubrics/prompts/category-l-behavior-equivalence.md +2 -2
- package/audit-rubrics/prompts/category-m-producer-consumer-cardinality.md +2 -2
- package/audit-rubrics/prompts/category-n-test-name-scenario-verifier.md +2 -2
- package/audit-rubrics/prompts/category-o-docstring-vs-impl-drift.md +2 -2
- package/audit-rubrics/prompts/category-p-name-vs-behavior-contract.md +2 -2
- package/bin/CLAUDE.md +1 -0
- package/bin/expand_home_directory_tokens.mjs +75 -0
- package/bin/install.mjs +21 -7
- package/bin/install.test.mjs +220 -10
- package/hooks/CLAUDE.md +1 -1
- package/hooks/blocking/CLAUDE.md +4 -1
- package/hooks/blocking/_path_setup.py +13 -0
- package/hooks/blocking/bash_pre_tool_use_dispatcher.py +281 -0
- package/hooks/blocking/code_rules_dead_module_constant.py +88 -16
- package/hooks/blocking/code_rules_enforcer.py +6 -0
- package/hooks/blocking/code_rules_imports_logging.py +34 -1
- package/hooks/blocking/code_rules_paths_syspath.py +1 -1
- package/hooks/blocking/code_rules_test_layout.py +272 -0
- package/hooks/blocking/nas_ssh_binary_enforcer.py +22 -12
- package/hooks/blocking/pii_prevention_blocker.py +781 -0
- package/hooks/blocking/pii_scanner.py +340 -0
- package/hooks/blocking/pre_tool_use_dispatcher.py +3 -3
- package/hooks/blocking/stop_dispatcher.py +84 -0
- package/hooks/blocking/test__path_setup.py +39 -0
- package/hooks/blocking/test_bash_dispatcher_interpreter_starts.py +61 -0
- package/hooks/blocking/test_bash_pre_tool_use_dispatcher.py +294 -0
- package/hooks/blocking/test_code_rules_enforcer_cross_skill_duplicate.py +1 -1
- package/hooks/blocking/test_code_rules_enforcer_dead_module_constant.py +51 -0
- package/hooks/blocking/test_code_rules_enforcer_dead_module_constant_read_cap.py +103 -0
- package/hooks/blocking/test_code_rules_enforcer_dot_test_pattern.py +1 -1
- package/hooks/blocking/test_code_rules_enforcer_file_global_constants.py +1 -1
- package/hooks/blocking/test_code_rules_enforcer_hardcoded_user_path.py +11 -11
- package/hooks/blocking/test_code_rules_enforcer_naive_datetime.py +1 -1
- package/hooks/blocking/test_code_rules_enforcer_same_file_inline_duplicate.py +1 -1
- package/hooks/blocking/test_code_rules_enforcer_test_layout.py +111 -0
- package/hooks/blocking/test_code_rules_enforcer_type_checking_scope.py +76 -0
- package/hooks/blocking/test_destructive_command_blocker.py +29 -9
- package/hooks/blocking/test_gh_body_arg_blocker.py +3 -3
- package/hooks/blocking/test_nas_ssh_binary_enforcer.py +96 -39
- package/hooks/blocking/test_pii_prevention_blocker.py +905 -0
- package/hooks/blocking/test_pii_prevention_windows_git_path.py +41 -0
- package/hooks/blocking/test_pii_scanner.py +165 -0
- package/hooks/blocking/test_pr_description_enforcer_pr_number.py +1 -1
- package/hooks/blocking/test_pre_tool_use_dispatcher.py +14 -13
- package/hooks/blocking/test_stop_dispatcher.py +187 -0
- package/hooks/blocking/test_verdict_directory_write_blocker.py +1 -1
- package/hooks/blocking/test_volatile_path_in_post_blocker.py +3 -3
- package/hooks/blocking/volatile_path_in_post_blocker.py +54 -5
- package/hooks/diagnostic/migrations/README.md +25 -26
- package/hooks/diagnostic/test_hook_log_extractor.py +10 -10
- package/hooks/hooks.json +10 -120
- package/hooks/hooks_constants/CLAUDE.md +12 -3
- package/hooks/hooks_constants/bash_pre_tool_use_dispatcher_constants.py +78 -0
- package/hooks/hooks_constants/dead_module_constant_constants.py +1 -0
- package/hooks/hooks_constants/hosted_hook_runner.py +73 -0
- package/hooks/hooks_constants/local_identity.py +182 -0
- package/hooks/hooks_constants/nas_ssh_binary_enforcer_constants.py +4 -37
- package/hooks/hooks_constants/pii_prevention_constants.py +299 -0
- package/hooks/hooks_constants/pre_tool_use_dispatcher_constants.py +4 -0
- package/hooks/hooks_constants/python_style_checks_constants.py +15 -0
- package/hooks/hooks_constants/stop_dispatcher_constants.py +26 -0
- package/hooks/hooks_constants/test_bash_pre_tool_use_dispatcher_constants.py +87 -0
- package/hooks/hooks_constants/test_hardcoded_user_path_constants.py +2 -2
- package/hooks/hooks_constants/test_hosted_hook_runner.py +101 -0
- package/hooks/hooks_constants/test_layout_constants.py +28 -0
- package/hooks/hooks_constants/test_local_identity.py +88 -0
- package/hooks/hooks_constants/test_session_env_cleanup_constants.py +1 -1
- package/hooks/hooks_constants/test_stop_dispatcher_constants.py +32 -0
- package/hooks/validators/README.md +5 -6
- package/hooks/validators/__init__.py +2 -2
- package/hooks/validators/python_style_checks.py +298 -243
- package/hooks/validators/run_all_validators.py +6 -0
- package/hooks/validators/test_python_style_checks.py +278 -163
- package/package.json +2 -2
- package/rules/CLAUDE.md +2 -1
- package/rules/bdd.md +1 -1
- package/rules/nas-ssh-invocation.md +6 -4
- package/rules/no-justification-noise.md +61 -0
- package/scripts/test_setup_project_paths.py +1 -1
- package/skills/CLAUDE.md +6 -3
- package/skills/_shared/pr-loop/scripts/_path_resolver.py +2 -2
- package/skills/_shared/pr-loop/scripts/build_audit_prompt.py +1 -1
- package/skills/_shared/pr-loop/scripts/build_fix_prompt.py +1 -1
- package/skills/_shared/pr-loop/scripts/test__path_resolver.py +42 -3
- package/skills/_shared/pr-loop/scripts/test_build_audit_prompt.py +11 -11
- package/skills/_shared/pr-loop/scripts/test_build_fix_prompt.py +26 -3
- package/skills/_shared/pr-loop/scripts/test_preflight_worktree.py +49 -25
- package/skills/autoconverge/CLAUDE.md +3 -3
- package/skills/autoconverge/SKILL.md +113 -35
- package/skills/autoconverge/reference/CLAUDE.md +2 -2
- package/skills/autoconverge/reference/convergence.md +44 -22
- package/skills/autoconverge/reference/gotchas.md +11 -0
- package/skills/autoconverge/reference/stop-conditions.md +23 -13
- package/skills/autoconverge/workflow/CLAUDE.md +2 -1
- package/skills/autoconverge/workflow/converge.clean-audit.test.mjs +15 -19
- package/skills/autoconverge/workflow/converge.contract.test.mjs +43 -42
- package/skills/autoconverge/workflow/converge.copilot-gate.test.mjs +141 -16
- package/skills/autoconverge/workflow/converge.fix-recovery.test.mjs +2 -2
- package/skills/autoconverge/workflow/converge.mjs +329 -68
- package/skills/autoconverge/workflow/converge.path-aware.test.mjs +1 -1
- package/skills/autoconverge/workflow/converge.precatch.test.mjs +152 -0
- package/skills/autoconverge/workflow/converge.run-input.test.mjs +3 -3
- package/skills/autoconverge/workflow/converge_multi.run-input.test.mjs +15 -15
- package/skills/autoconverge/workflow/test_convergence_summary.py +6 -6
- package/skills/bdd-protocol/SKILL.md +4 -5
- package/skills/bdd-protocol/references/anti-patterns.md +1 -1
- package/skills/bugteam/SKILL.md +8 -0
- package/skills/bugteam/reference/copilot-gap-analysis.md +20 -20
- package/skills/bugteam/reference/obstacles/audit-walk-categories.md +1 -1
- package/skills/bugteam/reference/team-setup.md +7 -5
- package/skills/bugteam/scripts/reflow_skill_md.py +1 -1
- package/skills/copilot-finding-triage/SKILL.md +124 -0
- package/skills/copilot-finding-triage/reference/tier-rubric.md +49 -0
- package/skills/copilot-finding-triage/scripts/conftest.py +8 -0
- package/skills/copilot-finding-triage/scripts/copilot_finding_triage_constants/__init__.py +0 -0
- package/skills/copilot-finding-triage/scripts/copilot_finding_triage_constants/config/__init__.py +0 -0
- package/skills/copilot-finding-triage/scripts/copilot_finding_triage_constants/config/notify_ntfy_constants.py +32 -0
- package/skills/copilot-finding-triage/scripts/notify_ntfy.py +192 -0
- package/skills/copilot-finding-triage/scripts/test_notify_ntfy.py +141 -0
- package/skills/copilot-finding-triage/templates/notification.md +34 -0
- package/skills/copilot-review/SKILL.md +8 -6
- package/skills/findbugs/SKILL.md +4 -0
- package/skills/fixbugs/SKILL.md +8 -7
- package/skills/gotcha/CLAUDE.md +2 -2
- package/skills/gotcha/SKILL.md +4 -4
- package/skills/log-audit/SKILL.md +4 -6
- package/skills/monitor-open-prs/CLAUDE.md +1 -1
- package/skills/monitor-open-prs/SKILL.md +6 -1
- package/skills/orchestrator/SKILL.md +74 -78
- package/skills/orchestrator-refresh/SKILL.md +24 -12
- package/skills/post-audit-findings/SKILL.md +5 -9
- package/skills/pr-consistency-audit/SKILL.md +5 -1
- package/skills/pr-converge/CLAUDE.md +1 -1
- package/skills/pr-converge/SKILL.md +86 -47
- package/skills/pr-converge/reference/CLAUDE.md +1 -1
- package/skills/pr-converge/reference/convergence-gates.md +20 -17
- package/skills/pr-converge/reference/examples.md +63 -47
- package/skills/pr-converge/reference/fix-protocol.md +15 -15
- package/skills/pr-converge/reference/ground-rules.md +11 -7
- package/skills/pr-converge/reference/multi-pr-orchestration.md +6 -5
- package/skills/pr-converge/reference/per-tick.md +129 -107
- package/skills/pr-converge/reference/state-schema.md +15 -10
- package/skills/pr-converge/scripts/check_convergence.py +5 -4
- package/skills/pr-converge/scripts/test_check_convergence.py +6 -4
- package/skills/pr-fix-protocol/SKILL.md +3 -8
- package/skills/pr-loop-cloud-transport/SKILL.md +102 -0
- package/skills/pr-loop-cloud-transport/reference/identity-and-hooks.md +40 -0
- package/skills/pr-loop-cloud-transport/reference/substitution-matrix.md +48 -0
- package/skills/pr-loop-lifecycle/SKILL.md +5 -9
- package/skills/pr-scope-resolve/SKILL.md +3 -6
- package/skills/privacy-hygiene/SKILL.md +114 -0
- package/skills/qbug/SKILL.md +8 -8
- package/skills/rebase/SKILL.md +5 -1
- package/skills/refine/SKILL.md +4 -5
- package/skills/reviewer-gates/SKILL.md +7 -11
- package/skills/session-log/SKILL.md +4 -1
- package/skills/skill-builder/SKILL.md +3 -6
- package/skills/structure-prompt/SKILL.md +4 -5
- package/skills/team-advisor/SKILL.md +56 -0
- package/skills/test_markdown_link_integrity.py +10 -6
- package/skills/update/SKILL.md +5 -1
- package/skills/usage-pause/SKILL.md +14 -5
- package/skills/usage-pause/scripts/resolve_usage_window.py +83 -5
- package/skills/usage-pause/scripts/test_resolve_usage_window.py +185 -17
- package/skills/usage-pause/scripts/usage_pause_constants/resolve_usage_window_constants.py +4 -3
- package/skills/verified-build/SKILL.md +4 -9
|
@@ -1,20 +1,26 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: pr-converge
|
|
3
3
|
description: >-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
says
|
|
9
|
-
'/pr-converge', 'drive PR to convergence', 'loop bugbot and bugteam',
|
|
10
|
-
'babysit bugbot and bugteam', 'until both are clean', or 'converge this
|
|
11
|
-
PR'.
|
|
4
|
+
Loops Cursor Bugbot, a code review, a bug audit, and Copilot on the current
|
|
5
|
+
PR, applying TDD fixes until all are clean on one HEAD. Use when the user says
|
|
6
|
+
'/pr-converge', 'drive PR to convergence', 'loop bugbot and bugteam', 'babysit
|
|
7
|
+
bugbot and bugteam', 'until both are clean', or 'converge this PR'.
|
|
12
8
|
---
|
|
13
9
|
|
|
14
10
|
# PR Converge
|
|
15
11
|
|
|
16
|
-
One tick per invocation.
|
|
17
|
-
a draft PR
|
|
12
|
+
One tick per invocation. A code-review ↔ bugteam ↔ Bugbot ↔ Copilot loop on
|
|
13
|
+
a draft PR: the internal code-review and bugteam passes drive the code to clean
|
|
14
|
+
first, then Cursor Bugbot and Copilot run as terminal confirmation gates, until
|
|
15
|
+
all are clean on the same `HEAD` and mergeable.
|
|
16
|
+
|
|
17
|
+
## Transport check (before any GitHub step)
|
|
18
|
+
|
|
19
|
+
Run `command -v gh`; when it succeeds, run `gh auth status`; once the PR
|
|
20
|
+
scope is resolved, run `gh api repos/<owner>/<repo> --jq .permissions.push`
|
|
21
|
+
and take `true` as the pass. When any check fails, run the
|
|
22
|
+
`pr-loop-cloud-transport` skill first and route every `gh` operation in this
|
|
23
|
+
skill through its substitution matrix.
|
|
18
24
|
|
|
19
25
|
## Pre-flight
|
|
20
26
|
|
|
@@ -50,7 +56,7 @@ Before Step 0, check
|
|
|
50
56
|
`$CLAUDE_JOB_DIR/pr-converge-state.json` is absent but that handoff exists, seed
|
|
51
57
|
`phase`, `tick_count`, and the clean-at SHAs from the run's `state-copy.json`, so
|
|
52
58
|
a fresh session continues where the last one stopped rather than restarting at
|
|
53
|
-
|
|
59
|
+
CODE_REVIEW.
|
|
54
60
|
|
|
55
61
|
## Copilot quota pre-check (start of run)
|
|
56
62
|
|
|
@@ -64,6 +70,29 @@ no request, no poll, no agent — and exports
|
|
|
64
70
|
pending-requested-reviews gate and the run still marks ready on the remaining
|
|
65
71
|
signals.
|
|
66
72
|
|
|
73
|
+
## Copilot findings — two-tier triage
|
|
74
|
+
|
|
75
|
+
The Copilot step tiers each finding it surfaces. A **self-healing** finding is
|
|
76
|
+
pure style, type hints, misplaced or unused imports, formatting, magic-value
|
|
77
|
+
extraction, a test-only change, a doc-or-description vs code mismatch, or code
|
|
78
|
+
de-duplication — a fix that cannot change observable runtime behavior for
|
|
79
|
+
production callers. Self-healing findings flow into the existing fix tick and
|
|
80
|
+
count toward convergence, with no user alert. The tick-paced loop holds them
|
|
81
|
+
naturally: the fix lands on `current_head`, the next tick re-checks, and the run
|
|
82
|
+
converges when the Copilot step is clean.
|
|
83
|
+
|
|
84
|
+
A **code-concern** finding is behavior-changing or needs a product decision:
|
|
85
|
+
logic or correctness, security, data handling, error-handling semantics, or
|
|
86
|
+
concurrency. Tier a finding as code-concern whenever the tier is in doubt. On
|
|
87
|
+
one or more code-concern findings, do not auto-fix them and do not let the tick
|
|
88
|
+
mark the PR ready. Run the
|
|
89
|
+
[`copilot-finding-triage`](../copilot-finding-triage/SKILL.md) gate: send the
|
|
90
|
+
ntfy alert with the finding summary and the Copilot review link, then hold for
|
|
91
|
+
the user's response on a 45-minute deadline that spans ticks — carry the
|
|
92
|
+
deadline in the run's persisted state so each tick reads it on entry. Act on the
|
|
93
|
+
user's direction when it arrives inside the window; when the deadline passes
|
|
94
|
+
with no response, run teardown and report the code-concern findings un-reviewed.
|
|
95
|
+
|
|
67
96
|
## Budget-aware tick boundaries
|
|
68
97
|
|
|
69
98
|
Before starting any tick, estimate whether the remaining session/usage
|
|
@@ -137,7 +166,7 @@ the `persistent_agents` map
|
|
|
137
166
|
within one bounded wait, drop the map entry, spawn a fresh named agent,
|
|
138
167
|
record it, and continue the tick. Never abort a tick on a stale id;
|
|
139
168
|
never retry the same dead id.
|
|
140
|
-
- **Fresh every round (never persisted):** the Step 5 `/code-review --fix`
|
|
169
|
+
- **Fresh every round (never persisted):** the Step 5 `/code-review high --fix`
|
|
141
170
|
pass and the Step 6 bugteam audit (unbiased eyes each round; the
|
|
142
171
|
enforcer needs the formal Skill call), and every `code-verifier` — a
|
|
143
172
|
named code-verifier never fires `SubagentStop`, so no verdict mints (see
|
|
@@ -188,7 +217,7 @@ post a fresh PR in a fresh branch based on origin main to the user.
|
|
|
188
217
|
Windows is Git Bash which cannot execute PowerShell cmdlets. Route all
|
|
189
218
|
PowerShell work through the PowerShell tool or `pwsh -NoProfile -File`.
|
|
190
219
|
- **Cross-repo PR: route cwd into the PR worktree before `/code-review`** —
|
|
191
|
-
`/code-review --fix` (Step 5) audits the repo of the current working
|
|
220
|
+
`/code-review high --fix` (Step 5) audits the repo of the current working
|
|
192
221
|
directory. When the session is rooted in a different repo than the PR,
|
|
193
222
|
`EnterWorktree` cannot re-root (it is scoped to the session's repo);
|
|
194
223
|
resolve the PR worktree and `cd` into it per
|
|
@@ -237,7 +266,7 @@ round as converged. This rule holds every tick, every loop, every PR.
|
|
|
237
266
|
and [§ Step 1.5](reference/per-tick.md)
|
|
238
267
|
|
|
239
268
|
- [ ] **Step 2: Initialize loop state**
|
|
240
|
-
`phase =
|
|
269
|
+
`phase = CODE_REVIEW`; all counters at zero; `run_name` resolved.
|
|
241
270
|
|
|
242
271
|
- [ ] **Step 3: Mergeability check**
|
|
243
272
|
See: [`reference/convergence-gates.md` § (c)](reference/convergence-gates.md)
|
|
@@ -249,37 +278,38 @@ round as converged. This rule holds every tick, every loop, every PR.
|
|
|
249
278
|
- [ ] mergeable → advance to Step 4
|
|
250
279
|
- [ ] not mergeable → rebase → force-push → return to Step 1
|
|
251
280
|
|
|
252
|
-
- [ ] **Step 4: BUGBOT —
|
|
253
|
-
|
|
281
|
+
- [ ] **Step 4: BUGBOT — terminal Bugbot confirmation gate**
|
|
282
|
+
The terminal external gate. Step 6 routes here after BUGTEAM converges, so
|
|
283
|
+
Bugbot confirms code the internal passes already drove to clean.
|
|
284
|
+
See: [`reference/per-tick.md` § BUGBOT terminal gate + Step 3](reference/per-tick.md)
|
|
254
285
|
|
|
255
|
-
- [ ] **
|
|
286
|
+
- [ ] **Availability gate (runs first, every BUGBOT entry).**
|
|
256
287
|
Gate semantics live in the `reviewer-gates` skill
|
|
257
|
-
(`../reviewer-gates/SKILL.md` § Gate 1).
|
|
288
|
+
(`../reviewer-gates/SKILL.md` § Gate 1). Cursor Bugbot is off by default and runs only when `CLAUDE_REVIEWS_ENABLED` lists `bugbot`; a `bugbot` token in `CLAUDE_REVIEWS_DISABLED` keeps it off even then.
|
|
258
289
|
`python "$HOME/.claude/_shared/pr-loop/scripts/reviews_disabled.py" --reviewer bugbot`
|
|
259
|
-
- [ ] Exit 0 (
|
|
290
|
+
- [ ] Exit 0 (Bugbot disabled for this run — the default) → set `bugbot_down = true`, advance to the Step 7 convergence gates (no trigger, no wait, no agent). Cursor Bugbot is skipped for the entire run.
|
|
260
291
|
- [ ] Exit 1 → continue below.
|
|
261
292
|
|
|
262
293
|
Fetch bugbot reviews + inline comments on `current_head`.
|
|
263
294
|
|
|
264
295
|
- [ ] **dirty** (findings on `current_head`) →
|
|
265
296
|
- [ ] Apply the `pr-fix-protocol` skill (`../pr-fix-protocol/SKILL.md`) to this tick's findings
|
|
266
|
-
- [ ] Push → return to Step
|
|
297
|
+
- [ ] Push → reset `bugbot_clean_at = null`, `code_review_clean_at = null` → `phase = CODE_REVIEW` → return to Step 5
|
|
267
298
|
- [ ] **clean** (no findings on `current_head`) →
|
|
268
299
|
- [ ] Count ALL unresolved threads on PR (`is_resolved == false`) → zero? advance; >0? fix + resolve first
|
|
269
300
|
- [ ] `bugbot_clean_at = current_head`
|
|
270
|
-
- [ ]
|
|
271
|
-
- [ ] Advance to Step 5
|
|
301
|
+
- [ ] Advance to the Step 7 convergence gates
|
|
272
302
|
- [ ] **no review yet / commit_id mismatch** →
|
|
273
303
|
Apply the `reviewer-gates` skill's Bugbot flow
|
|
274
304
|
(`../reviewer-gates/SKILL.md` § Gate 3) against `current_head`,
|
|
275
305
|
then map its outcomes:
|
|
276
|
-
- [ ] Silent pass → `bugbot_clean_at = current_head` →
|
|
306
|
+
- [ ] Silent pass → `bugbot_clean_at = current_head` → advance to the Step 7 convergence gates
|
|
277
307
|
- [ ] Already queued, or trigger acknowledged → schedule 360s wakeup → return to Step 4 next tick
|
|
278
|
-
- [ ] Bugbot down → `bugbot_down = true` →
|
|
279
|
-
- [ ] **Step 5: CODE-REVIEW —
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
308
|
+
- [ ] Bugbot down → `bugbot_down = true` → advance to the Step 7 convergence gates (bypass)
|
|
309
|
+
- [ ] **Step 5: CODE-REVIEW — entry phase: static sweep, review, fix, advance**
|
|
310
|
+
The first internal step of every convergence tick (Step 2 seeds
|
|
311
|
+
`phase = CODE_REVIEW`), re-entered after any fix push.
|
|
312
|
+
See: [`reference/per-tick.md` § CODE_REVIEW entry](reference/per-tick.md)
|
|
283
313
|
|
|
284
314
|
Pre-condition: the working directory is the Step 1.5 PR worktree on
|
|
285
315
|
`current_head` (`git rev-parse --show-toplevel` is that checkout).
|
|
@@ -288,18 +318,28 @@ round as converged. This rule holds every tick, every loop, every PR.
|
|
|
288
318
|
current working directory, so this routing targets the real PR
|
|
289
319
|
diff. This `cd` is routine and automatic.
|
|
290
320
|
|
|
291
|
-
|
|
321
|
+
- [ ] **Static sweep — runs first, before `/code-review`.** Run the
|
|
322
|
+
deterministic gates over the full `origin/main...HEAD` changed files:
|
|
323
|
+
`python "$HOME/.claude/_shared/pr-loop/scripts/code_rules_gate.py" --base origin/main`,
|
|
324
|
+
`ruff`, `mypy`, and stem-matched `pytest`.
|
|
325
|
+
- [ ] Any failure → apply the `pr-fix-protocol` skill
|
|
326
|
+
(`../pr-fix-protocol/SKILL.md`), commit/push, reset
|
|
327
|
+
`bugbot_clean_at = null` and `code_review_clean_at = null`, stay
|
|
328
|
+
`phase = CODE_REVIEW`, and re-run (return to Step 5).
|
|
329
|
+
- [ ] Clean → run `/code-review` below.
|
|
330
|
+
|
|
331
|
+
Run Claude Code's built-in `/code-review high --fix` on the full
|
|
292
332
|
`origin/main...HEAD` diff —
|
|
293
333
|
the [local diff review](https://code.claude.com/docs/en/code-review#review-a-diff-locally)
|
|
294
334
|
— so it reviews the diff and applies its findings to the working
|
|
295
|
-
tree.
|
|
296
|
-
current effort.
|
|
335
|
+
tree. Invoke `/code-review high --fix` so the pre-catch pass gets broad
|
|
336
|
+
coverage regardless of the session's current effort.
|
|
297
337
|
|
|
298
338
|
**Scope: the FULL `origin/main...HEAD` diff every tick** — every file
|
|
299
339
|
the PR touches. Do not delta-scope to commits added since the prior
|
|
300
340
|
clean SHA, do not scope to a single file, do not scope to bugbot's
|
|
301
341
|
flagged paths. Before running, confirm the working tree is on the
|
|
302
|
-
PR's HEAD with no uncommitted edits, then invoke `/code-review --fix`
|
|
342
|
+
PR's HEAD with no uncommitted edits, then invoke `/code-review high --fix`
|
|
303
343
|
with no path arguments so it audits the whole branch diff against
|
|
304
344
|
`origin/main`. A partial-scope round does not count and cannot set
|
|
305
345
|
`code_review_clean_at`.
|
|
@@ -307,8 +347,7 @@ round as converged. This rule holds every tick, every loop, every PR.
|
|
|
307
347
|
- [ ] **fixes applied** (working tree changed) →
|
|
308
348
|
- [ ] Commit the applied fixes (one commit) → push
|
|
309
349
|
- [ ] reset `bugbot_clean_at = null`, `code_review_clean_at = null`
|
|
310
|
-
- [ ]
|
|
311
|
-
- [ ] `phase = BUGBOT` → schedule 360s wakeup → return to Step 4
|
|
350
|
+
- [ ] stay `phase = CODE_REVIEW` → return to Step 5 (internal-first)
|
|
312
351
|
- [ ] **clean** (no changes applied) →
|
|
313
352
|
- [ ] Zero unresolved threads per the `pr-fix-protocol` sweep (`../pr-fix-protocol/SKILL.md`) → advance; else fix + resolve first (same skill)
|
|
314
353
|
- [ ] `code_review_clean_at = current_head`
|
|
@@ -338,21 +377,21 @@ round as converged. This rule holds every tick, every loop, every PR.
|
|
|
338
377
|
|
|
339
378
|
- [ ] **bugteam pushed new commits** →
|
|
340
379
|
- [ ] Verify all bugteam review threads replied + resolved
|
|
341
|
-
- [ ]
|
|
342
|
-
- [ ] `phase =
|
|
343
|
-
- [ ] **converged (zero findings)
|
|
380
|
+
- [ ] reset `bugbot_clean_at = null`, `code_review_clean_at = null`
|
|
381
|
+
- [ ] `phase = CODE_REVIEW` → schedule 360s wakeup → return to Step 5
|
|
382
|
+
- [ ] **converged (zero findings), no push** →
|
|
344
383
|
- [ ] Count ALL unresolved threads on PR (`is_resolved == false`) → zero? advance; >0? fix + resolve first
|
|
345
|
-
- [ ]
|
|
346
|
-
- [ ] **converged + `bugbot_clean_at ≠ current_head`** →
|
|
347
|
-
`phase = BUGBOT` → schedule 360s wakeup → return to Step 4
|
|
384
|
+
- [ ] `phase = BUGBOT` → advance to Step 4 (terminal Bugbot gate)
|
|
348
385
|
- [ ] **findings without committed fixes** →
|
|
349
386
|
- [ ] Apply the `pr-fix-protocol` skill (`../pr-fix-protocol/SKILL.md`) to the findings
|
|
350
|
-
- [ ] Push → `phase =
|
|
387
|
+
- [ ] Push → reset `bugbot_clean_at = null`, `code_review_clean_at = null` → `phase = CODE_REVIEW` → return to Step 5
|
|
351
388
|
|
|
352
389
|
- [ ] **Step 7: Convergence gates**
|
|
353
390
|
See: [`reference/convergence-gates.md`](reference/convergence-gates.md)
|
|
354
391
|
|
|
355
|
-
Pre-condition: Step 6 converged AND `bugbot_clean_at == current_head
|
|
392
|
+
Pre-condition: Step 6 converged AND (`bugbot_clean_at == current_head` OR
|
|
393
|
+
`bugbot_down`). The terminal Bugbot gate (Step 4) sets that state just
|
|
394
|
+
before these gates run.
|
|
356
395
|
Count unresolved threads before each gate.
|
|
357
396
|
|
|
358
397
|
**(a) Universal unresolved-thread sweep**
|
|
@@ -361,13 +400,13 @@ round as converged. This rule holds every tick, every loop, every PR.
|
|
|
361
400
|
pull_request_read(method="get_review_comments")
|
|
362
401
|
→ filter threads where is_resolved == false
|
|
363
402
|
```
|
|
364
|
-
- [ ] Any unresolved? → apply the `pr-fix-protocol` skill's unresolved-thread sweep (`../pr-fix-protocol/SKILL.md`). Push if any code changed → return to Step
|
|
403
|
+
- [ ] Any unresolved? → apply the `pr-fix-protocol` skill's unresolved-thread sweep (`../pr-fix-protocol/SKILL.md`). Push if any code changed → reset markers → `phase = CODE_REVIEW` → return to Step 5
|
|
365
404
|
- [ ] When `copilot_down == true` (start-of-run quota pre-check), skip the Copilot fetch below — no request, no poll, no agent — and continue to gate (b); the Copilot gate is bypassed for the whole run.
|
|
366
405
|
- [ ] Fetch Copilot review on `current_head` (top-level review state — uses get_reviews, identifies by reviewer):
|
|
367
406
|
```
|
|
368
407
|
python ~/.claude/skills/pr-converge/scripts/fetch_copilot_reviews.py --owner <O> --repo <R> --pr-number <N>
|
|
369
408
|
```
|
|
370
|
-
- [ ] dirty → apply the `pr-fix-protocol` skill (`../pr-fix-protocol/SKILL.md`) → push → return to Step
|
|
409
|
+
- [ ] dirty → apply the `pr-fix-protocol` skill (`../pr-fix-protocol/SKILL.md`) → push → reset markers → `phase = CODE_REVIEW` → return to Step 5
|
|
371
410
|
- [ ] clean (no findings) → `copilot_clean_at = current_head` → gate (b)
|
|
372
411
|
- [ ] no review yet → gate (b)
|
|
373
412
|
|
|
@@ -399,7 +438,7 @@ round as converged. This rule holds every tick, every loop, every PR.
|
|
|
399
438
|
→ count threads where is_resolved == false
|
|
400
439
|
```
|
|
401
440
|
- [ ] zero unresolved → gate (e)
|
|
402
|
-
- [ ] unresolved → apply the `pr-fix-protocol` skill's unresolved-thread sweep (`../pr-fix-protocol/SKILL.md`). Push if code changed → return to Step
|
|
441
|
+
- [ ] unresolved → apply the `pr-fix-protocol` skill's unresolved-thread sweep (`../pr-fix-protocol/SKILL.md`). Push if code changed → reset markers → `phase = CODE_REVIEW` → return to Step 5
|
|
403
442
|
|
|
404
443
|
**(e) Mark ready**
|
|
405
444
|
- [ ] When `copilot_down == true`, export `CLAUDE_REVIEWS_DISABLED="copilot"` in this tick's shell before the check below, so it bypasses the Copilot review gate and the pending-requested-reviews gate.
|
|
@@ -409,7 +448,7 @@ round as converged. This rule holds every tick, every loop, every PR.
|
|
|
409
448
|
--owner <O> --repo <R> --pr-number <N>
|
|
410
449
|
```
|
|
411
450
|
- [ ] Exit 0 (all pass) → `update_pull_request(draft=false)` → advance to Step 8
|
|
412
|
-
- [ ] Exit 1 (FAIL lines) → address each failure → return to Step
|
|
451
|
+
- [ ] Exit 1 (FAIL lines) → address each failure → reset markers → `phase = CODE_REVIEW` → return to Step 5
|
|
413
452
|
- [ ] Exit 2 (gh error) → retry once; persistent → stop
|
|
414
453
|
|
|
415
454
|
- [ ] **Step 7a: COPILOT_WAIT — fetch Copilot, decide**
|
|
@@ -424,7 +463,7 @@ round as converged. This rule holds every tick, every loop, every PR.
|
|
|
424
463
|
`copilot_clean_at = current_head` → return to Step 7 (re-validate gates b, d, e)
|
|
425
464
|
- [ ] **dirty (findings present)** →
|
|
426
465
|
- [ ] Apply the `pr-fix-protocol` skill (`../pr-fix-protocol/SKILL.md`) to the findings
|
|
427
|
-
- [ ] Push → `phase =
|
|
466
|
+
- [ ] Push → reset markers → `phase = CODE_REVIEW` → return to Step 5
|
|
428
467
|
- [ ] **no review yet** →
|
|
429
468
|
increment `copilot_wait_count` → ≥ 3 = hard blocker → stop
|
|
430
469
|
schedule 360s wakeup → return to Step 7a next tick
|
|
@@ -6,7 +6,7 @@ Reference documents for the `pr-converge` skill. These files define the per-tick
|
|
|
6
6
|
|
|
7
7
|
| File | Purpose |
|
|
8
8
|
|---|---|
|
|
9
|
-
| `per-tick.md` | Step-by-step procedure for one tick (resolve HEAD, run
|
|
9
|
+
| `per-tick.md` | Step-by-step procedure for one tick (resolve HEAD, run the internal CODE_REVIEW and BUGTEAM phases, then the terminal BUGBOT and COPILOT_WAIT gates, schedule next wakeup) |
|
|
10
10
|
| `convergence-gates.md` | Six gates that must all pass before the PR is marked ready for review |
|
|
11
11
|
| `fix-protocol.md` | pr-converge deltas on the `pr-fix-protocol` skill: multi-PR teammate obligations and the same-tick bugbot re-trigger rule |
|
|
12
12
|
| `ground-rules.md` | Non-negotiable constraints for the convergence loop |
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
# Convergence gates
|
|
2
2
|
|
|
3
|
-
Run **only**
|
|
4
|
-
`bugbot_clean_at == current_head`
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
Run **only** after the terminal Bugbot gate confirms the HEAD
|
|
4
|
+
(`bugbot_clean_at == current_head` OR `bugbot_down`), which runs just before
|
|
5
|
+
these gates once Step 2 BUGTEAM reports `convergence (zero findings)` with no
|
|
6
|
+
push during the bugteam tick. Gates run in order; first failure determines
|
|
7
|
+
next-tick behavior. Mark PR ready only when all six pass.
|
|
7
8
|
|
|
8
9
|
**Mandatory evidence rule:** Every gate that fetches data MUST produce a
|
|
9
10
|
summary of its findings before proceeding to the next gate. Gate (f) MUST
|
|
@@ -36,19 +37,20 @@ Decide (four branches; match first whose predicate holds):
|
|
|
36
37
|
- **`classification == "dirty"` with non-empty inline comments matching
|
|
37
38
|
`pull_request_review_id`:** Fix protocol input (same shape as bugbot
|
|
38
39
|
dirty). Apply the `pr-fix-protocol` skill
|
|
39
|
-
(`../../pr-fix-protocol/SKILL.md`)
|
|
40
|
-
Reset `bugbot_clean_at = null
|
|
41
|
-
|
|
42
|
-
plus all six gates must hold again on
|
|
40
|
+
(`../../pr-fix-protocol/SKILL.md`) in the same tick.
|
|
41
|
+
Reset `bugbot_clean_at = null`, `code_review_clean_at = null`, AND
|
|
42
|
+
`copilot_clean_at = null`, `phase = CODE_REVIEW`, schedule next wakeup,
|
|
43
|
+
return. Full back-to-back-clean cycle plus all six gates must hold again on
|
|
44
|
+
new HEAD.
|
|
43
45
|
- **`classification == "dirty"` with empty inline comments matching
|
|
44
46
|
`pull_request_review_id`:** Copilot posted findings only in review body
|
|
45
47
|
(`CHANGES_REQUESTED` or `COMMENTED` with non-empty body, no inline
|
|
46
48
|
threads). Parse body for actionable findings. Apply the
|
|
47
49
|
`pr-fix-protocol` skill (`../../pr-fix-protocol/SKILL.md`), whose reply
|
|
48
50
|
step for body-only findings posts a top-level review reply citing the
|
|
49
|
-
new HEAD SHA
|
|
50
|
-
`bugbot_clean_at = null` AND
|
|
51
|
-
`copilot_clean_at = null`, `phase =
|
|
51
|
+
new HEAD SHA. Reset
|
|
52
|
+
`bugbot_clean_at = null`, `code_review_clean_at = null`, AND
|
|
53
|
+
`copilot_clean_at = null`, `phase = CODE_REVIEW`,
|
|
52
54
|
schedule next wakeup, return. Convergence needs full
|
|
53
55
|
back-to-back-clean on new HEAD.
|
|
54
56
|
- **`classification == "clean"` (state `APPROVED`):** Set
|
|
@@ -78,14 +80,14 @@ Decide (four branches; match first whose predicate holds):
|
|
|
78
80
|
`pull_request_review_id`:** Treat identically to gate (a) dirty+inline
|
|
79
81
|
path — apply the `pr-fix-protocol` skill
|
|
80
82
|
(`../../pr-fix-protocol/SKILL.md`). Reset
|
|
81
|
-
`bugbot_clean_at = null` AND `copilot_clean_at = null`, `phase =
|
|
83
|
+
`bugbot_clean_at = null` AND `copilot_clean_at = null`, `phase = CODE_REVIEW`,
|
|
82
84
|
schedule next wakeup, return.
|
|
83
85
|
- **`classification == "dirty"` with empty inline comments matching
|
|
84
86
|
`pull_request_review_id`:** Claude posted findings only in review body
|
|
85
87
|
(`CHANGES_REQUESTED` or `COMMENTED` with non-empty body, no inline
|
|
86
88
|
threads). Treat identically to gate (a) dirty+body path — apply the
|
|
87
89
|
`pr-fix-protocol` skill (`../../pr-fix-protocol/SKILL.md`). Reset
|
|
88
|
-
`bugbot_clean_at = null` AND `copilot_clean_at = null`, `phase =
|
|
90
|
+
`bugbot_clean_at = null` AND `copilot_clean_at = null`, `phase = CODE_REVIEW`,
|
|
89
91
|
schedule next wakeup, return.
|
|
90
92
|
- **`classification == "clean"` (state `APPROVED`):** Record evidence:
|
|
91
93
|
"Claude APPROVED at <SHA>". Continue to gate (c).
|
|
@@ -111,8 +113,9 @@ Persist `mergeable_state` into `merge_state_status`. Decide:
|
|
|
111
113
|
([`../../rebase/SKILL.md`](../../rebase/SKILL.md)) Phase 1–4 against PR's
|
|
112
114
|
base ref. After rebase + force-with-lease push, new HEAD invalidates
|
|
113
115
|
every prior clean state — reset `bugbot_clean_at = null`,
|
|
114
|
-
`
|
|
115
|
-
|
|
116
|
+
`code_review_clean_at = null`, `copilot_clean_at = null`,
|
|
117
|
+
`merge_state_status = null`, `phase = CODE_REVIEW`,
|
|
118
|
+
schedule next wakeup, return. Loop re-runs from
|
|
116
119
|
scratch on new HEAD.
|
|
117
120
|
- **`mergeable_state` is `"blocked"`, `"behind"`, `"unknown"`, or `"unstable"` for
|
|
118
121
|
non-conflict reasons** (required checks pending/failing for "unstable",
|
|
@@ -157,7 +160,7 @@ against `current_head`. Decide:
|
|
|
157
160
|
- `state: CHANGES_REQUESTED` or `COMMENTED` with non-empty body → dirty.
|
|
158
161
|
Treat identically to gate (a) dirty path — spawn Agent (subagent_type: clean-coder) to fix,
|
|
159
162
|
reset `bugbot_clean_at = null` AND `copilot_clean_at = null`,
|
|
160
|
-
`phase =
|
|
163
|
+
`phase = CODE_REVIEW`, schedule next wakeup, return.
|
|
161
164
|
- **No Copilot review at `current_head` yet:** Record evidence: "No Copilot
|
|
162
165
|
review at <SHA> (wait count: <N>)". Increment `copilot_wait_count`
|
|
163
166
|
(init 0 on first COPILOT_WAIT entry; reset to 0 on every push and on every
|
|
@@ -187,7 +190,7 @@ Decide:
|
|
|
187
190
|
`pr-fix-protocol` skill's unresolved-thread sweep
|
|
188
191
|
(`../../pr-fix-protocol/SKILL.md`). Push if any code changed → reset
|
|
189
192
|
`bugbot_clean_at = null` AND `copilot_clean_at = null`,
|
|
190
|
-
`phase =
|
|
193
|
+
`phase = CODE_REVIEW`, schedule next wakeup, return. If only resolutions
|
|
191
194
|
(no code changes), re-check this gate without resetting.
|
|
192
195
|
|
|
193
196
|
## (f) Mark ready and report
|
|
@@ -4,40 +4,60 @@ Worked examples for `pr-converge`. Read on demand when a tick's
|
|
|
4
4
|
classification is novel or ambiguous against the in-skill rules. Cross-refs
|
|
5
5
|
into `SKILL.md` use `§Section name` notation.
|
|
6
6
|
|
|
7
|
-
<example> User: `/pr-converge` Claude: [PR context + one tick
|
|
8
|
-
work
|
|
9
|
-
convergence or
|
|
7
|
+
<example> User: `/pr-converge` Claude: [PR context + one tick of internal
|
|
8
|
+
code-review/bugteam work, then the terminal Bugbot and Copilot gates; Step 4
|
|
9
|
+
per `workflows/schedule-wakeup-loop.md` — default loop until convergence or
|
|
10
|
+
stop]
|
|
10
11
|
</example>
|
|
11
12
|
|
|
12
|
-
<example>
|
|
13
|
-
|
|
14
|
-
`
|
|
13
|
+
<example> CODE_REVIEW tick (the entry phase), the static sweep raises a
|
|
14
|
+
`ruff` failure on a changed file. Claude: [fixes it TDD, one commit, pushes,
|
|
15
|
+
resets `bugbot_clean_at = null` and `code_review_clean_at = null`, stays
|
|
16
|
+
`phase = CODE_REVIEW`, Step 4 at 270s, re-runs the sweep next tick]
|
|
15
17
|
</example>
|
|
16
18
|
|
|
17
|
-
<example>
|
|
18
|
-
|
|
19
|
-
`
|
|
19
|
+
<example> CODE_REVIEW tick, static sweep clean, `/code-review high --fix`
|
|
20
|
+
applies fixes to the working tree. Claude: [commits the applied fixes in one
|
|
21
|
+
commit, pushes, resets `bugbot_clean_at = null` and `code_review_clean_at =
|
|
22
|
+
null`, stays `phase = CODE_REVIEW`, Step 4 at 270s, returns]
|
|
20
23
|
</example>
|
|
21
24
|
|
|
22
|
-
<example>
|
|
23
|
-
|
|
24
|
-
in same tick]
|
|
25
|
+
<example> CODE_REVIEW tick, static sweep clean and `/code-review high --fix`
|
|
26
|
+
clean (no changes applied). Claude: [sets `code_review_clean_at = HEAD`,
|
|
27
|
+
`phase = BUGTEAM`, runs `Skill({skill: "bugteam", ...})` in same tick]
|
|
25
28
|
</example>
|
|
26
29
|
|
|
27
|
-
<example>
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
<example> BUGTEAM phase, bugteam pushed a fix commit during its run. Claude:
|
|
31
|
+
[re-resolves HEAD, resets `bugbot_clean_at = null` and `code_review_clean_at =
|
|
32
|
+
null`, `phase = CODE_REVIEW`, Step 4 at 270s, re-enters the internal passes on
|
|
33
|
+
the new HEAD]
|
|
31
34
|
</example>
|
|
32
35
|
|
|
33
|
-
<example>
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
<example> BUGTEAM phase, bugteam reports convergence with no push. Claude:
|
|
37
|
+
[the internal passes are clean on `current_head`; `phase = BUGBOT` — routes into
|
|
38
|
+
the terminal Bugbot gate in the same tick]
|
|
36
39
|
</example>
|
|
37
40
|
|
|
38
|
-
<example>
|
|
39
|
-
|
|
40
|
-
|
|
41
|
+
<example> Terminal BUGBOT gate, Bugbot disabled for the run (the default).
|
|
42
|
+
Claude: [availability gate exits 0, sets `bugbot_down = true`, advances to the
|
|
43
|
+
`convergence-gates.md` gates with the Bugbot gate bypassed — no trigger, no
|
|
44
|
+
wait, no agent]
|
|
45
|
+
</example>
|
|
46
|
+
|
|
47
|
+
<example> Terminal BUGBOT gate, Bugbot enabled and clean on HEAD. Claude:
|
|
48
|
+
[sets `bugbot_clean_at = HEAD`, advances to the `convergence-gates.md` gates in
|
|
49
|
+
the same tick]
|
|
50
|
+
</example>
|
|
51
|
+
|
|
52
|
+
<example> Terminal BUGBOT gate, Bugbot has 2 unaddressed findings on HEAD.
|
|
53
|
+
Claude: [TDD-fixes both, one commit, pushes, replies inline on both threads,
|
|
54
|
+
resets `bugbot_clean_at = null` and `code_review_clean_at = null`, `phase =
|
|
55
|
+
CODE_REVIEW`, Step 4 at 270s, re-enters the internal passes on the new HEAD]
|
|
56
|
+
</example>
|
|
57
|
+
|
|
58
|
+
<example> Convergence gates after the terminal Bugbot gate confirms
|
|
59
|
+
(`bugbot_clean_at == current_head`). Claude: [runs `convergence-gates.md` gates
|
|
60
|
+
in order:
|
|
41
61
|
Gate (a): two calls — `pull_request_read(method="get_reviews")` +
|
|
42
62
|
`pull_request_read(method="get_review_comments")`
|
|
43
63
|
→ filter Copilot → APPROVED at `current_head`
|
|
@@ -53,7 +73,7 @@ sufficient. Runs `convergence-gates.md` gates in order:
|
|
|
53
73
|
→ schedule next wakeup, return.
|
|
54
74
|
Next tick: re-run gate (a) fetch → Copilot `APPROVED` at `current_head`
|
|
55
75
|
→ set `copilot_clean_at = current_head`, record evidence: "Copilot
|
|
56
|
-
APPROVED at <SHA>",
|
|
76
|
+
APPROVED at <SHA>", re-validate gates (b) and (c).
|
|
57
77
|
Gate (e): the `pr-fix-protocol` unresolved-thread sweep
|
|
58
78
|
(`../../pr-fix-protocol/SKILL.md`) → zero across PR → record evidence.
|
|
59
79
|
Gate (f): all six gates pass → `update_pull_request(pullNumber=NUMBER,
|
|
@@ -64,40 +84,35 @@ mergeable_state clean, copilot CLEAN at <SHA>, claude absent at <SHA>,
|
|
|
64
84
|
applies **Convergence** from `workflows/schedule-wakeup-loop.md`]
|
|
65
85
|
</example>
|
|
66
86
|
|
|
67
|
-
<example>
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
<example> BUGBOT tick, review body says "found 3 potential issues" against
|
|
73
|
-
HEAD but inline API returns zero matching for `current_head`. Claude:
|
|
74
|
-
[increments `inline_lag_streak` to 1, Step 4 inline-lag rules (90s
|
|
75
|
-
`ScheduleWakeup`), returns]
|
|
87
|
+
<example> CODE_REVIEW tick, review body says "found 3 potential issues"
|
|
88
|
+
against HEAD (a stale prior finding) but the diff is clean. Claude: [the static
|
|
89
|
+
sweep and `/code-review high --fix` both pass, sets `code_review_clean_at =
|
|
90
|
+
HEAD`, `phase = BUGTEAM`]
|
|
76
91
|
</example>
|
|
77
92
|
|
|
78
|
-
<example>
|
|
93
|
+
<example> Convergence gates reached, but `mergeStateStatus: DIRTY` (base
|
|
79
94
|
advanced, merge conflicts). Claude: [runs §Convergence gate (c); does NOT
|
|
80
95
|
mark ready; invokes `rebase` skill per `../../rebase/SKILL.md` Phase 1–4;
|
|
81
96
|
after force-with-lease push, resets `bugbot_clean_at = null`,
|
|
82
|
-
`
|
|
83
|
-
|
|
97
|
+
`code_review_clean_at = null`, `copilot_clean_at = null`, `merge_state_status
|
|
98
|
+
= null`, `phase = CODE_REVIEW`, schedules next wakeup]
|
|
84
99
|
</example>
|
|
85
100
|
|
|
86
|
-
<example>
|
|
101
|
+
<example> Convergence gates reached, mergeability CLEAN, Copilot review at
|
|
87
102
|
`current_head` `state == "CHANGES_REQUESTED"` with two unaddressed inline
|
|
88
103
|
findings. Claude: [runs §Convergence gates (a); applies Fix protocol (TDD
|
|
89
|
-
test → fix → push → reply inline both threads), resets `bugbot_clean_at
|
|
90
|
-
and `copilot_clean_at` null, `phase =
|
|
91
|
-
|
|
104
|
+
test → fix → push → reply inline both threads), resets `bugbot_clean_at`,
|
|
105
|
+
`code_review_clean_at`, and `copilot_clean_at` null, `phase = CODE_REVIEW`,
|
|
106
|
+
schedules next wakeup, re-enters the internal passes on the new HEAD]
|
|
92
107
|
</example>
|
|
93
108
|
|
|
94
|
-
<example>
|
|
109
|
+
<example> Convergence gates reached, mergeability CLEAN, no Copilot review on
|
|
95
110
|
`current_head`. Claude sets `phase = COPILOT_WAIT`, runs gate (d):
|
|
96
111
|
`request_copilot_review(owner=OWNER, repo=REPO, pullNumber=NUMBER)`,
|
|
97
112
|
schedules next wakeup, returns. Next tick:
|
|
98
113
|
Copilot review `state: APPROVED` at `current_head`. Claude: [re-runs
|
|
99
114
|
gate (a) fetch → APPROVED → sets `copilot_clean_at = current_head`,
|
|
100
|
-
records evidence: "Copilot APPROVED at <SHA>"
|
|
115
|
+
records evidence: "Copilot APPROVED at <SHA>";
|
|
101
116
|
re-validates gates (b) Claude absent and (c) mergeability clean,
|
|
102
117
|
records evidence for both; gate (e) — the `pr-fix-protocol`
|
|
103
118
|
unresolved-thread sweep — passes trivially, record evidence:
|
|
@@ -108,12 +123,13 @@ at <SHA>, bugteam CLEAN at <SHA>, mergeable_state clean, copilot CLEAN at
|
|
|
108
123
|
<SHA>, claude absent at <SHA>, 0 unresolved threads across PR; marked ready for review"]
|
|
109
124
|
</example>
|
|
110
125
|
|
|
111
|
-
<example>
|
|
112
|
-
review returned `state: CHANGES_REQUESTED` with inline findings on
|
|
126
|
+
<example> Convergence gates reached, mergeability CLEAN, post-convergence
|
|
127
|
+
Copilot review returned `state: CHANGES_REQUESTED` with inline findings on
|
|
113
128
|
`current_head`. Claude: [does NOT mark PR ready — gate (d) failed;
|
|
114
129
|
applies Fix protocol on every confirmed Copilot finding (TDD test → fix →
|
|
115
|
-
push → reply inline on each thread); resets `bugbot_clean_at = null
|
|
116
|
-
`
|
|
117
|
-
|
|
118
|
-
gates must hold again on new
|
|
130
|
+
push → reply inline on each thread); resets `bugbot_clean_at = null`,
|
|
131
|
+
`code_review_clean_at = null`, and `copilot_clean_at = null`; `phase =
|
|
132
|
+
CODE_REVIEW`; schedules next wakeup, re-enters the internal passes on the new
|
|
133
|
+
HEAD. Full back-to-back-clean cycle plus all six gates must hold again on new
|
|
134
|
+
HEAD.]
|
|
119
135
|
</example>
|
|
@@ -8,7 +8,7 @@ sequence in `../../../_shared/pr-loop/fix-protocol.md`. Hook handling
|
|
|
8
8
|
per [ground-rules.md](ground-rules.md).
|
|
9
9
|
|
|
10
10
|
This file holds only the pr-converge deltas: the multi-PR teammate
|
|
11
|
-
obligations and the same-tick re-
|
|
11
|
+
obligations and the same-tick re-entry rule.
|
|
12
12
|
|
|
13
13
|
**Multi-PR (`state.json`) teammate obligations** (plus TDD, commit, push):
|
|
14
14
|
|
|
@@ -17,21 +17,21 @@ obligations and the same-tick re-trigger rule.
|
|
|
17
17
|
(what changed + commit identifier), matching §Audit result → fix worker step 4 — **before** writing
|
|
18
18
|
`state.json` and going idle.
|
|
19
19
|
- Writes `last_action: "fix_pushed"`, `current_head: <new SHA>`,
|
|
20
|
-
`bugbot_clean_at: null`, `
|
|
21
|
-
`status: "
|
|
22
|
-
`state.json` (per §Concurrency).
|
|
23
|
-
- Goes idle. Orchestrator spawns follow-up `general-purpose` agent for
|
|
24
|
-
|
|
20
|
+
`bugbot_clean_at: null`, `code_review_clean_at: null`, `bugbot_down: false`,
|
|
21
|
+
`phase: "CODE_REVIEW"`, `status: "awaiting_code_review"`, `last_updated`
|
|
22
|
+
(ISO-8601 UTC) to `state.json` (per §Concurrency).
|
|
23
|
+
- Goes idle. Orchestrator spawns a follow-up `general-purpose` agent for the
|
|
24
|
+
CODE_REVIEW re-entry on the new HEAD.
|
|
25
25
|
|
|
26
|
-
Orchestrator does not reply inline,
|
|
26
|
+
Orchestrator does not reply inline, re-enter code-review, or read repo source
|
|
27
27
|
files during fix phase in multi-PR mode.
|
|
28
28
|
|
|
29
|
-
### Same-tick re-
|
|
29
|
+
### Same-tick re-entry rule
|
|
30
30
|
|
|
31
|
-
**After pushing a fix,
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
count toward convergence on the new `HEAD`. Re-
|
|
35
|
-
`current_head`, then bugteam
|
|
36
|
-
|
|
37
|
-
|
|
31
|
+
**After pushing a fix, re-enter the CODE_REVIEW phase in the same tick**
|
|
32
|
+
regardless of phase. A new commit **resets the full convergence cycle**: a
|
|
33
|
+
code-review clean, a bugteam clean, and a Bugbot clean on an older SHA do
|
|
34
|
+
**not** count toward convergence on the new `HEAD`. Re-run the static sweep and
|
|
35
|
+
`/code-review high --fix` on `current_head`, then bugteam, then the terminal
|
|
36
|
+
Bugbot gate, all on the same `HEAD` with no intervening push. Re-entering in the
|
|
37
|
+
same tick saves a wakeup cycle.
|
|
@@ -1,24 +1,28 @@
|
|
|
1
1
|
# Ground rules
|
|
2
2
|
|
|
3
|
+
- **Internal-first.** The internal code-review and bugteam passes drive the code
|
|
4
|
+
to clean each tick; Cursor Bugbot and Copilot run only after that, as terminal
|
|
5
|
+
confirmation gates.
|
|
3
6
|
- **Append commits.** Each tick adds at most one fix commit.
|
|
4
|
-
- **Bugbot findings on current SHA mean fix-then-push-then
|
|
5
|
-
|
|
7
|
+
- **Bugbot findings on the current SHA mean fix-then-push-then-re-enter
|
|
8
|
+
CODE_REVIEW,** so the internal passes re-clear the new HEAD before the terminal
|
|
9
|
+
Bugbot gate runs again.
|
|
6
10
|
- **All `*_clean_at`, `merge_state_status`, and `bugbot_down` reset on every push.**
|
|
7
11
|
- **`bugbot run` comment is load-bearing.** Literal phrase exactly —
|
|
8
12
|
empirically the only re-trigger Cursor Bugbot recognizes.
|
|
9
|
-
- **Production edits go through `clean-coder`, except `/code-review --fix`.**
|
|
13
|
+
- **Production edits go through `clean-coder`, except `/code-review high --fix`.**
|
|
10
14
|
The lead never hand-edits production files. Every bugbot, bugteam,
|
|
11
15
|
Copilot, or Claude finding spawns `Agent(subagent_type="clean-coder")` to
|
|
12
|
-
|
|
13
|
-
--fix` applies its own findings to the working tree, which the next
|
|
14
|
-
|
|
16
|
+
apply the fix. The CODE_REVIEW phase is the one exception: `/code-review
|
|
17
|
+
high --fix` applies its own findings to the working tree, which the next
|
|
18
|
+
CODE_REVIEW/BUGTEAM cycle re-reviews after the loop resets.
|
|
15
19
|
- **Adapt when reality contradicts on-disk state.** If `state.json`,
|
|
16
20
|
`git`, or `gh` disagree with live PR, escalate as hard blocker per
|
|
17
21
|
[stop-conditions.md](stop-conditions.md).
|
|
18
22
|
- **Cross-repo cwd routing is routine, not a fork.** When the PR under
|
|
19
23
|
convergence lives in a different repo than the session is rooted in, route
|
|
20
24
|
the working directory into a checkout of the PR's repo automatically —
|
|
21
|
-
`/code-review --fix`, `git`, and every `clean-coder` fix spawn act on the
|
|
25
|
+
`/code-review high --fix`, `git`, and every `clean-coder` fix spawn act on the
|
|
22
26
|
repo of the current working directory. The resolution is fixed
|
|
23
27
|
([per-tick.md § Step 1.5](per-tick.md)): resolve the PR worktree, `cd` into
|
|
24
28
|
it, run local work there. Do not pause, ask, or raise it as a material fork.
|