claude-dev-env 1.93.0 → 1.94.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (220) hide show
  1. package/_shared/pr-loop/CLAUDE.md +1 -0
  2. package/_shared/pr-loop/audit-contract.md +1 -1
  3. package/_shared/pr-loop/gh-payloads.md +3 -3
  4. package/_shared/pr-loop/post-audit-thread-contract.md +51 -0
  5. package/_shared/pr-loop/scripts/README.md +2 -2
  6. package/_shared/pr-loop/scripts/code_rules_gate.py +127 -13
  7. package/_shared/pr-loop/scripts/fix_hookspath.py +47 -12
  8. package/_shared/pr-loop/scripts/pr_loop_shared_constants/code_rules_gate_constants.py +4 -0
  9. package/_shared/pr-loop/scripts/tests/test_code_rules_gate.py +146 -69
  10. package/_shared/pr-loop/scripts/tests/test_fix_hookspath.py +497 -374
  11. package/_shared/pr-loop/state-schema.md +3 -22
  12. package/bin/CLAUDE.md +1 -1
  13. package/bin/install.mjs +2 -7
  14. package/bin/install.test.mjs +10 -4
  15. package/hooks/blocking/CLAUDE.md +2 -0
  16. package/hooks/blocking/pii_commit_command.py +398 -0
  17. package/hooks/blocking/pii_payload_scan.py +133 -0
  18. package/hooks/blocking/pii_prevention_blocker.py +151 -449
  19. package/hooks/blocking/pii_scanner.py +26 -1
  20. package/hooks/blocking/test_code_rules_enforcer_dead_config_field.py +2 -2
  21. package/hooks/blocking/test_pii_prevention_blocker.py +299 -0
  22. package/hooks/blocking/test_pii_scanner.py +27 -2
  23. package/hooks/blocking/test_verdict_directory_write_blocker.py +42 -7
  24. package/hooks/hooks_constants/CLAUDE.md +2 -2
  25. package/hooks/hooks_constants/code_rules_path_utils_constants.py +0 -2
  26. package/hooks/hooks_constants/local_identity.py +65 -15
  27. package/hooks/hooks_constants/pii_prevention_constants.py +20 -8
  28. package/hooks/hooks_constants/pr_description_enforcer_constants.py +1 -1
  29. package/hooks/hooks_constants/test_local_identity.py +68 -0
  30. package/package.json +1 -1
  31. package/scripts/CLAUDE.md +10 -1
  32. package/scripts/Get-SessionAccount.ps1 +210 -0
  33. package/scripts/tests/CLAUDE.md +15 -1
  34. package/scripts/tests/Get-SessionAccount.Tests.ps1 +350 -0
  35. package/skills/CLAUDE.md +3 -25
  36. package/skills/anthropic-plan/SKILL.md +1 -13
  37. package/skills/autoconverge/CLAUDE.md +5 -2
  38. package/skills/autoconverge/SKILL.md +112 -387
  39. package/skills/autoconverge/reference/CLAUDE.md +4 -1
  40. package/skills/autoconverge/reference/closing-report.md +9 -2
  41. package/skills/autoconverge/reference/convergence.md +26 -22
  42. package/skills/autoconverge/reference/headless-safety.md +44 -0
  43. package/skills/autoconverge/reference/multi-pr.md +88 -0
  44. package/skills/autoconverge/reference/self-closing-loop.md +84 -0
  45. package/skills/autoconverge/reference/stop-conditions.md +21 -13
  46. package/skills/autoconverge/workflow/converge.clean-audit.test.mjs +87 -27
  47. package/skills/autoconverge/workflow/converge.contract.test.mjs +40 -10
  48. package/skills/autoconverge/workflow/converge.copilot-gate.test.mjs +179 -47
  49. package/skills/autoconverge/workflow/converge.fix-progress.test.mjs +1 -1
  50. package/skills/autoconverge/workflow/converge.mjs +284 -94
  51. package/skills/bugteam/CLAUDE.md +1 -1
  52. package/skills/bugteam/CONSTRAINTS.md +3 -3
  53. package/skills/bugteam/PROMPTS.md +8 -19
  54. package/skills/bugteam/SKILL.md +13 -14
  55. package/skills/bugteam/reference/CLAUDE.md +1 -1
  56. package/skills/bugteam/reference/audit-and-teammates.md +2 -2
  57. package/skills/bugteam/reference/copilot-gap-analysis.md +2 -0
  58. package/skills/bugteam/reference/github-pr-reviews.md +56 -38
  59. package/skills/bugteam/reference/team-setup.md +11 -11
  60. package/skills/bugteam/scripts/CLAUDE.md +6 -6
  61. package/skills/bugteam/scripts/README.md +20 -8
  62. package/skills/bugteam/scripts/bugteam_code_rules_gate.py +13 -1463
  63. package/skills/bugteam/scripts/bugteam_fix_hookspath.py +23 -358
  64. package/skills/bugteam/scripts/bugteam_preflight.py +13 -315
  65. package/skills/bugteam/scripts/bugteam_scripts_constants/CLAUDE.md +2 -3
  66. package/skills/bugteam/scripts/test_bugteam_code_rules_gate.py +34 -1053
  67. package/skills/bugteam/scripts/test_bugteam_fix_hookspath.py +30 -347
  68. package/skills/bugteam/scripts/test_bugteam_preflight.py +30 -305
  69. package/skills/copilot-finding-triage/SKILL.md +80 -28
  70. package/skills/copilot-finding-triage/reference/tier-rubric.md +70 -11
  71. package/skills/copilot-finding-triage/templates/notification.md +8 -3
  72. package/skills/everything-search/SKILL.md +1 -2
  73. package/skills/grokify/SKILL.md +58 -0
  74. package/skills/grokify/templates/handoff-template.md +92 -0
  75. package/skills/orchestrator/SKILL.md +12 -8
  76. package/skills/orchestrator-refresh/SKILL.md +3 -3
  77. package/skills/pr-converge/SKILL.md +132 -233
  78. package/skills/pr-converge/reference/convergence-gates.md +102 -66
  79. package/skills/pr-converge/reference/examples.md +37 -25
  80. package/skills/pr-converge/reference/fix-protocol.md +7 -7
  81. package/skills/pr-converge/reference/multi-pr-orchestration.md +10 -4
  82. package/skills/pr-converge/reference/per-tick.md +64 -41
  83. package/skills/pr-converge/reference/state-schema.md +27 -2
  84. package/skills/pr-converge/scripts/CLAUDE.md +8 -0
  85. package/skills/pr-converge/scripts/README.md +4 -3
  86. package/skills/pr-converge/scripts/_pr_converge_path_setup.py +23 -0
  87. package/skills/pr-converge/scripts/check_convergence.py +189 -645
  88. package/skills/pr-converge/scripts/check_convergence_gates.py +235 -0
  89. package/skills/pr-converge/scripts/check_convergence_thread_gates.py +219 -0
  90. package/skills/pr-converge/scripts/conftest.py +8 -0
  91. package/skills/pr-converge/scripts/pr_converge_scripts_constants/CLAUDE.md +1 -0
  92. package/skills/pr-converge/scripts/pr_converge_scripts_constants/convergence_gate_constants.py +36 -0
  93. package/skills/pr-converge/scripts/test__pr_converge_path_setup.py +26 -0
  94. package/skills/pr-converge/scripts/test_check_convergence.py +73 -228
  95. package/skills/pr-converge/scripts/test_check_convergence_contract.py +321 -0
  96. package/skills/pr-converge/scripts/test_check_convergence_gates.py +68 -0
  97. package/skills/pr-converge/scripts/test_check_convergence_thread_gates.py +75 -0
  98. package/skills/privacy-hygiene/SKILL.md +8 -7
  99. package/skills/reviewer-gates/SKILL.md +26 -8
  100. package/skills/session-log/SKILL.md +11 -12
  101. package/skills/session-tidy/SKILL.md +40 -30
  102. package/skills/skill-builder/CLAUDE.md +13 -10
  103. package/skills/skill-builder/SKILL.md +31 -31
  104. package/skills/skill-builder/references/CLAUDE.md +10 -6
  105. package/skills/skill-builder/references/delegation-map.md +13 -4
  106. package/skills/skill-builder/references/description-field.md +113 -0
  107. package/skills/skill-builder/references/self-audit-checklist.md +21 -4
  108. package/skills/skill-builder/references/skill-modularity.md +113 -0
  109. package/skills/skill-builder/references/skill-types.md +4 -0
  110. package/skills/skill-builder/templates/CLAUDE.md +4 -4
  111. package/skills/skill-builder/templates/gap-analysis.md +25 -1
  112. package/skills/skill-builder/workflows/CLAUDE.md +6 -4
  113. package/skills/skill-builder/workflows/improve-skill.md +17 -16
  114. package/skills/skill-builder/workflows/new-skill.md +34 -10
  115. package/skills/skill-builder/workflows/polish-skill.md +59 -43
  116. package/skills/usage-pause/SKILL.md +10 -14
  117. package/skills/bdd-protocol/CLAUDE.md +0 -26
  118. package/skills/bdd-protocol/SKILL.md +0 -30
  119. package/skills/bdd-protocol/references/CLAUDE.md +0 -10
  120. package/skills/bdd-protocol/references/anti-patterns.md +0 -26
  121. package/skills/bdd-protocol/references/example-mapping.md +0 -23
  122. package/skills/bg-agent/CLAUDE.md +0 -17
  123. package/skills/bg-agent/SKILL.md +0 -69
  124. package/skills/bugteam/scripts/bugteam_scripts_constants/bugteam_code_rules_gate_constants.py +0 -55
  125. package/skills/bugteam/scripts/bugteam_scripts_constants/bugteam_fix_hookspath_constants.py +0 -26
  126. package/skills/bugteam/scripts/bugteam_scripts_constants/bugteam_preflight_constants.py +0 -35
  127. package/skills/caveman/CLAUDE.md +0 -15
  128. package/skills/caveman/SKILL.md +0 -38
  129. package/skills/code/CLAUDE.md +0 -17
  130. package/skills/code/SKILL.md +0 -178
  131. package/skills/deep-research/CLAUDE.md +0 -17
  132. package/skills/deep-research/SKILL.md +0 -80
  133. package/skills/findbugs/CLAUDE.md +0 -20
  134. package/skills/findbugs/SKILL.md +0 -241
  135. package/skills/fixbugs/CLAUDE.md +0 -19
  136. package/skills/fixbugs/SKILL.md +0 -142
  137. package/skills/gh-paginate/CLAUDE.md +0 -18
  138. package/skills/gh-paginate/SKILL.md +0 -84
  139. package/skills/gotcha/CLAUDE.md +0 -33
  140. package/skills/gotcha/SKILL.md +0 -73
  141. package/skills/implement/CLAUDE.md +0 -27
  142. package/skills/implement/SKILL.md +0 -66
  143. package/skills/implement/scripts/CLAUDE.md +0 -22
  144. package/skills/implement/scripts/append_note.py +0 -133
  145. package/skills/implement/scripts/implement_scripts_constants/CLAUDE.md +0 -22
  146. package/skills/implement/scripts/implement_scripts_constants/__init__.py +0 -0
  147. package/skills/implement/scripts/implement_scripts_constants/notes_constants.py +0 -12
  148. package/skills/implement/scripts/test_append_note.py +0 -191
  149. package/skills/log-audit/CLAUDE.md +0 -20
  150. package/skills/log-audit/SKILL.md +0 -66
  151. package/skills/log-audit/reference/CLAUDE.md +0 -9
  152. package/skills/log-audit/reference/charter.md +0 -52
  153. package/skills/log-audit/scripts/CLAUDE.md +0 -27
  154. package/skills/log-audit/scripts/cluster_recurrences.py +0 -261
  155. package/skills/log-audit/scripts/collect_log_window.py +0 -199
  156. package/skills/log-audit/scripts/log_audit_constants/CLAUDE.md +0 -12
  157. package/skills/log-audit/scripts/log_audit_constants/__init__.py +0 -0
  158. package/skills/log-audit/scripts/log_audit_constants/cluster_recurrences_constants.py +0 -23
  159. package/skills/log-audit/scripts/log_audit_constants/collect_log_window_constants.py +0 -24
  160. package/skills/log-audit/scripts/log_audit_constants/mine_copilot_findings_constants.py +0 -49
  161. package/skills/log-audit/scripts/mine_copilot_findings.py +0 -302
  162. package/skills/log-audit/scripts/test_cluster_recurrences.py +0 -160
  163. package/skills/log-audit/scripts/test_collect_log_window.py +0 -111
  164. package/skills/log-audit/scripts/test_mine_copilot_findings.py +0 -126
  165. package/skills/logifix/CLAUDE.md +0 -36
  166. package/skills/logifix/SKILL.md +0 -69
  167. package/skills/logifix/scripts/CLAUDE.md +0 -16
  168. package/skills/logifix/scripts/logifix.ps1 +0 -205
  169. package/skills/monitor-open-prs/CLAUDE.md +0 -34
  170. package/skills/monitor-open-prs/SKILL.md +0 -88
  171. package/skills/monitor-open-prs/scripts/CLAUDE.md +0 -17
  172. package/skills/monitor-open-prs/scripts/discover_open_prs.py +0 -69
  173. package/skills/monitor-open-prs/scripts/test_discover_open_prs.py +0 -149
  174. package/skills/monitor-open-prs/test_skill_contract.py +0 -27
  175. package/skills/post-audit-findings/SKILL.md +0 -80
  176. package/skills/pr-consistency-audit/CLAUDE.md +0 -34
  177. package/skills/pr-consistency-audit/SKILL.md +0 -116
  178. package/skills/pr-consistency-audit/reference/CLAUDE.md +0 -16
  179. package/skills/pr-consistency-audit/reference/detection-rules.md +0 -96
  180. package/skills/pr-consistency-audit/reference/illustrations.md +0 -78
  181. package/skills/pr-fix-protocol/SKILL.md +0 -65
  182. package/skills/pr-review-responder/CLAUDE.md +0 -35
  183. package/skills/pr-review-responder/EXAMPLES.md +0 -590
  184. package/skills/pr-review-responder/PRINCIPLES.md +0 -533
  185. package/skills/pr-review-responder/README.md +0 -168
  186. package/skills/pr-review-responder/SKILL.md +0 -203
  187. package/skills/pr-review-responder/TESTING.md +0 -350
  188. package/skills/pr-scope-resolve/SKILL.md +0 -45
  189. package/skills/pre-compact/CLAUDE.md +0 -24
  190. package/skills/pre-compact/SKILL.md +0 -134
  191. package/skills/qbug/CLAUDE.md +0 -40
  192. package/skills/qbug/SKILL.md +0 -387
  193. package/skills/qbug/test_qbug_skill_audit_schema.py +0 -152
  194. package/skills/qbug/test_qbug_skill_post_fix_audit.py +0 -103
  195. package/skills/refine/CLAUDE.md +0 -44
  196. package/skills/refine/SKILL.md +0 -262
  197. package/skills/refine/templates/CLAUDE.md +0 -17
  198. package/skills/refine/templates/implementation-notes-template.html +0 -56
  199. package/skills/refine/templates/plan-template.md +0 -60
  200. package/skills/research-mode/CLAUDE.md +0 -35
  201. package/skills/research-mode/SKILL.md +0 -53
  202. package/skills/structure-prompt/CLAUDE.md +0 -42
  203. package/skills/structure-prompt/SKILL.md +0 -44
  204. package/skills/structure-prompt/reference/CLAUDE.md +0 -28
  205. package/skills/structure-prompt/reference/adversarial-tuning.md +0 -62
  206. package/skills/structure-prompt/reference/block-classification.md +0 -27
  207. package/skills/structure-prompt/reference/canonical-case.md +0 -48
  208. package/skills/structure-prompt/reference/citation-depth.md +0 -70
  209. package/skills/structure-prompt/reference/cleanup.md +0 -33
  210. package/skills/structure-prompt/reference/constraints.md +0 -33
  211. package/skills/structure-prompt/reference/directives.md +0 -37
  212. package/skills/structure-prompt/reference/examples.md +0 -72
  213. package/skills/structure-prompt/reference/instantiation.md +0 -51
  214. package/skills/structure-prompt/reference/output-contract.md +0 -72
  215. package/skills/structure-prompt/reference/per-category.md +0 -23
  216. package/skills/structure-prompt/reference/persona.md +0 -38
  217. package/skills/structure-prompt/reference/research.md +0 -33
  218. package/skills/structure-prompt/reference/structure.md +0 -28
  219. package/skills/verified-build/CLAUDE.md +0 -33
  220. package/skills/verified-build/SKILL.md +0 -33
@@ -1,5 +1,13 @@
1
1
  # Convergence gates
2
2
 
3
+ ## Contents
4
+
5
+ - [(a) Copilot findings gate](#a-copilot-findings-gate)
6
+ - [(b) Claude reviewer gate (agent-side)](#b-claude-reviewer-gate-agent-side)
7
+ - [(c) Mergeability gate](#c-mergeability-gate)
8
+ - [(d) Post-convergence Copilot review request](#d-post-convergence-copilot-review-request)
9
+ - [(e) Thread-resolution gate](#e-thread-resolution-gate)
10
+ - [(f) Mark ready and report](#f-mark-ready-and-report)
3
11
  Run **only** after the terminal Bugbot gate confirms the HEAD
4
12
  (`bugbot_clean_at == current_head` OR `bugbot_down`), which runs just before
5
13
  these gates once Step 2 BUGTEAM reports `convergence (zero findings)` with no
@@ -36,33 +44,34 @@ Decide (four branches; match first whose predicate holds):
36
44
 
37
45
  - **`classification == "dirty"` with non-empty inline comments matching
38
46
  `pull_request_review_id`:** Fix protocol input (same shape as bugbot
39
- dirty). Apply the `pr-fix-protocol` skill
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.
47
+ dirty). Apply the shared fix protocol ([`../../../_shared/pr-loop/fix-protocol.md`](../../../_shared/pr-loop/fix-protocol.md); skill deltas in [`fix-protocol.md`](fix-protocol.md)) in the same tick.
48
+ Reset push-invalidated markers per [ground-rules.md](ground-rules.md) /
49
+ [state-schema.md](state-schema.md) (all `*_clean_at`, `merge_state_status`,
50
+ `bugbot_down`, `bugbot_acknowledged_at`), `phase = CODE_REVIEW`, schedule
51
+ next wakeup, return. Full back-to-back-clean cycle plus all six gates must
52
+ hold again on new HEAD.
45
53
  - **`classification == "dirty"` with empty inline comments matching
46
54
  `pull_request_review_id`:** Copilot posted findings only in review body
47
55
  (`CHANGES_REQUESTED` or `COMMENTED` with non-empty body, no inline
48
56
  threads). Parse body for actionable findings. Apply the
49
- `pr-fix-protocol` skill (`../../pr-fix-protocol/SKILL.md`), whose reply
57
+ shared fix protocol ([`../../../_shared/pr-loop/fix-protocol.md`](../../../_shared/pr-loop/fix-protocol.md); skill deltas in [`fix-protocol.md`](fix-protocol.md)), whose reply
50
58
  step for body-only findings posts a top-level review reply citing the
51
- new HEAD SHA. Reset
52
- `bugbot_clean_at = null`, `code_review_clean_at = null`, AND
53
- `copilot_clean_at = null`, `phase = CODE_REVIEW`,
54
- schedule next wakeup, return. Convergence needs full
55
- back-to-back-clean on new HEAD.
59
+ new HEAD SHA. Reset push-invalidated markers per
60
+ [ground-rules.md](ground-rules.md) / [state-schema.md](state-schema.md)
61
+ (all `*_clean_at`, `merge_state_status`, `bugbot_down`,
62
+ `bugbot_acknowledged_at`), `phase = CODE_REVIEW`, schedule next wakeup,
63
+ return. Convergence needs full back-to-back-clean on new HEAD.
56
64
  - **`classification == "clean"` (state `APPROVED`):** Set
57
65
  `copilot_clean_at = current_head`. Record evidence: "Copilot APPROVED at <SHA>".
58
66
  Continue to gate (b).
59
67
  - **No Copilot review on `current_head` yet:** Record evidence: "No Copilot review at <SHA>".
60
68
  Skip — gate (d) issues proactive request. Continue to gate (b).
61
69
 
62
- ## (b) Claude reviewer gate
70
+ ## (b) Claude reviewer gate (agent-side)
63
71
 
64
- Fetch latest Claude reviewer (`claude[bot]`) review plus inline comments
65
- anchored to most recent Claude review on `current_head`:
72
+ Agent-side only not a `check_convergence.py` condition. Fetch latest Claude
73
+ reviewer (`claude[bot]`) review plus inline comments anchored to most recent
74
+ Claude review on `current_head`:
66
75
 
67
76
  ```
68
77
  pull_request_read(owner=OWNER, repo=REPO, pullNumber=NUMBER, method="get_reviews")
@@ -78,17 +87,20 @@ Decide (four branches; match first whose predicate holds):
78
87
 
79
88
  - **`classification == "dirty"` with non-empty inline comments matching
80
89
  `pull_request_review_id`:** Treat identically to gate (a) dirty+inline
81
- path — apply the `pr-fix-protocol` skill
82
- (`../../pr-fix-protocol/SKILL.md`). Reset
83
- `bugbot_clean_at = null` AND `copilot_clean_at = null`, `phase = CODE_REVIEW`,
84
- schedule next wakeup, return.
90
+ path — apply the shared fix protocol ([`../../../_shared/pr-loop/fix-protocol.md`](../../../_shared/pr-loop/fix-protocol.md); skill deltas in [`fix-protocol.md`](fix-protocol.md)). Reset push-invalidated markers per
91
+ [ground-rules.md](ground-rules.md) / [state-schema.md](state-schema.md)
92
+ (all `*_clean_at`, `merge_state_status`, `bugbot_down`,
93
+ `bugbot_acknowledged_at`), `phase = CODE_REVIEW`, schedule next wakeup,
94
+ return.
85
95
  - **`classification == "dirty"` with empty inline comments matching
86
96
  `pull_request_review_id`:** Claude posted findings only in review body
87
97
  (`CHANGES_REQUESTED` or `COMMENTED` with non-empty body, no inline
88
98
  threads). Treat identically to gate (a) dirty+body path — apply the
89
- `pr-fix-protocol` skill (`../../pr-fix-protocol/SKILL.md`). Reset
90
- `bugbot_clean_at = null` AND `copilot_clean_at = null`, `phase = CODE_REVIEW`,
91
- schedule next wakeup, return.
99
+ shared fix protocol ([`../../../_shared/pr-loop/fix-protocol.md`](../../../_shared/pr-loop/fix-protocol.md); skill deltas in [`fix-protocol.md`](fix-protocol.md)). Reset
100
+ push-invalidated markers per [ground-rules.md](ground-rules.md) /
101
+ [state-schema.md](state-schema.md) (all `*_clean_at`, `merge_state_status`,
102
+ `bugbot_down`, `bugbot_acknowledged_at`), `phase = CODE_REVIEW`, schedule
103
+ next wakeup, return.
92
104
  - **`classification == "clean"` (state `APPROVED`):** Record evidence:
93
105
  "Claude APPROVED at <SHA>". Continue to gate (c).
94
106
  - **No Claude review on `current_head` yet:** Record evidence:
@@ -112,11 +124,11 @@ Persist `mergeable_state` into `merge_state_status`. Decide:
112
124
  **not** mark ready. Invoke **`rebase`** skill
113
125
  ([`../../rebase/SKILL.md`](../../rebase/SKILL.md)) Phase 1–4 against PR's
114
126
  base ref. After rebase + force-with-lease push, new HEAD invalidates
115
- every prior clean state — reset `bugbot_clean_at = null`,
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
119
- scratch on new HEAD.
127
+ every prior clean state — reset push-invalidated markers per
128
+ [ground-rules.md](ground-rules.md) / [state-schema.md](state-schema.md)
129
+ (all `*_clean_at`, `merge_state_status`, `bugbot_down`,
130
+ `bugbot_acknowledged_at`), `phase = CODE_REVIEW`, schedule next wakeup,
131
+ return. Loop re-runs from scratch on new HEAD.
120
132
  - **`mergeable_state` is `"blocked"`, `"behind"`, `"unknown"`, or `"unstable"` for
121
133
  non-conflict reasons** (required checks pending/failing for "unstable",
122
134
  branch behind base without conflicts for "behind", GitHub indeterminate
@@ -155,12 +167,14 @@ against `current_head`. Decide:
155
167
  - `state: APPROVED` → set `copilot_clean_at = current_head`. Record
156
168
  evidence: "Copilot APPROVED at <SHA>". Re-validate gates (b) and (c)
157
169
  on same tick (Claude status and mergeability may have changed while
158
- waiting). Set `phase = BUGTEAM`.
170
+ waiting). Stay on `COPILOT_WAIT` do not re-enter BUGTEAM.
159
171
  Continue to gate (e) when (b) and (c) still pass.
160
172
  - `state: CHANGES_REQUESTED` or `COMMENTED` with non-empty body → dirty.
161
- Treat identically to gate (a) dirty path — spawn Agent (subagent_type: clean-coder) to fix,
162
- reset `bugbot_clean_at = null` AND `copilot_clean_at = null`,
163
- `phase = CODE_REVIEW`, schedule next wakeup, return.
173
+ Treat identically to gate (a) dirty path — apply the shared fix protocol ([`../../../_shared/pr-loop/fix-protocol.md`](../../../_shared/pr-loop/fix-protocol.md); skill deltas in [`fix-protocol.md`](fix-protocol.md)).
174
+ Reset push-invalidated markers per [ground-rules.md](ground-rules.md) /
175
+ [state-schema.md](state-schema.md) (all `*_clean_at`, `merge_state_status`,
176
+ `bugbot_down`, `bugbot_acknowledged_at`), `phase = CODE_REVIEW`, schedule
177
+ next wakeup, return.
164
178
  - **No Copilot review at `current_head` yet:** Record evidence: "No Copilot
165
179
  review at <SHA> (wait count: <N>)". Increment `copilot_wait_count`
166
180
  (init 0 on first COPILOT_WAIT entry; reset to 0 on every push and on every
@@ -171,48 +185,72 @@ against `current_head`. Decide:
171
185
 
172
186
  ## (e) Thread-resolution gate
173
187
 
174
- Before marking ready, count ALL unresolved review threads on the PR:
188
+ Agent-side prep before the machine checklist in gate (f). The script label
189
+ `zero unresolved bot threads` is what marks ready; this gate clears those
190
+ threads first.
175
191
 
176
- ```
177
- pull_request_read(owner=OWNER, repo=REPO, pullNumber=NUMBER, method="get_review_comments")
178
- → filter threads where `is_resolved == false`
179
- → count
180
- ```
192
+ Machine filter (same as `check_convergence.py`):
181
193
 
182
- This count is the `pr-fix-protocol` unresolved-thread sweep
183
- (`../../pr-fix-protocol/SKILL.md`).
194
+ - `isResolved == false`
195
+ - `isOutdated == true` → thread **excluded** (does not fail the gate)
196
+ - first-comment author login contains `cursor`, `claude`, or `copilot`
197
+ (case-insensitive substrings only)
198
+
199
+ Broader unresolved-thread sweeps (all authors, including human reviewers) are
200
+ agent-side via the shared fix protocol ([`../../../_shared/pr-loop/fix-protocol.md`](../../../_shared/pr-loop/fix-protocol.md); skill deltas in [`fix-protocol.md`](fix-protocol.md)) and are not script conditions.
184
201
 
185
202
  Decide:
186
203
 
187
- - **Zero unresolved threads:** Record evidence:
188
- "0 unresolved threads across PR at <SHA>". Continue to gate (f).
189
- - **One or more unresolved threads:** Do **not** mark ready. Apply the
190
- `pr-fix-protocol` skill's unresolved-thread sweep
191
- (`../../pr-fix-protocol/SKILL.md`). Push if any code changed → reset
192
- `bugbot_clean_at = null` AND `copilot_clean_at = null`,
193
- `phase = CODE_REVIEW`, schedule next wakeup, return. If only resolutions
194
- (no code changes), re-check this gate without resetting.
204
+ - **Zero unresolved bot threads** under the filter above: Record evidence:
205
+ "0 unresolved bot threads at <SHA>". Continue to gate (f).
206
+ - **One or more unresolved bot threads:** Do **not** mark ready. Apply the
207
+ shared fix protocol unresolved-thread sweep ([`../../../_shared/pr-loop/fix-protocol.md`](../../../_shared/pr-loop/fix-protocol.md) step 12; skill deltas in [`fix-protocol.md`](fix-protocol.md)). Push if any code changed → reset
208
+ push-invalidated markers per [ground-rules.md](ground-rules.md) /
209
+ [state-schema.md](state-schema.md) (all `*_clean_at`, `merge_state_status`,
210
+ `bugbot_down`, `bugbot_acknowledged_at`), `phase = CODE_REVIEW`, schedule
211
+ next wakeup, return. If only resolutions (no code changes), re-check this
212
+ gate without resetting.
195
213
 
196
214
  ## (f) Mark ready and report
197
215
 
198
- **Mandatory pre-condition checklist.** Before calling `update_pull_request`,
199
- verify ALL seven conditions below. Three are preconditions from the main
200
- loop (bugbot clean, bugteam convergence, no intervening push); four are
201
- evidence from gates (a)–(e) above. All seven must be confirmed:
216
+ **Machine pre-condition checklist.** Run the script — do not hand-check labels:
217
+
218
+ ```
219
+ python $HOME/.claude/skills/pr-converge/scripts/check_convergence.py \
220
+ --owner <O> --repo <R> --pr-number <N> \
221
+ [--bugbot-down] [--copilot-down]
222
+ ```
223
+
224
+ Ready means exit `0` and the line:
225
+
226
+ ```
227
+ All pre-conditions met — PR is ready to mark ready.
228
+ ```
229
+
230
+ Exact printed labels (script order):
231
+
232
+ 1. `bugbot_clean_at == current_head`
233
+ 2. `bugbot review body clean` (omitted when `bugbot_down`)
234
+ 3. `bugteam_clean_at == current_head`
235
+ 4. `copilot_clean_at == current_head`
236
+ 5. `zero unresolved bot threads`
237
+ 6. `PR is mergeable`
238
+ 7. `no pending requested reviews`
239
+
240
+ On label 5: `isOutdated == true` excludes the thread; bot filter is login
241
+ substrings `cursor` | `claude` | `copilot` only. The script has no Claude
242
+ APPROVED review gate.
202
243
 
203
- - [ ] `bugbot_clean_at == current_head` (from per-tick.md Step 2 BUGBOT §c)
204
- - [ ] bugteam `convergence (zero findings)` at `current_head` (from per-tick.md Step 2 BUGTEAM §d)
205
- - [ ] `copilot_clean_at == current_head` (from gate (a) or gate (d)), or the Copilot gate bypassed for the run via `copilot_down`
206
- - [ ] Claude `APPROVED` or absent at `current_head` (from gate (b))
207
- - [ ] `mergeable_state == "clean"` AND `mergeable == true` (from gate (c))
208
- - [ ] Zero unresolved review threads anywhere on the PR (from gate (e))
209
- - [ ] No push since bugteam convergence (from per-tick.md Step 2 BUGTEAM §b)
244
+ **Agent-side only (not script conditions):** Claude reviewer presence or
245
+ APPROVED state (gate (b)); broader non-bot thread sweeps; loop preconditions
246
+ such as no push since bugteam convergence. Confirm those in the agent path
247
+ before invoking the script; they never appear as `check_convergence.py` labels.
210
248
 
211
- If ANY checkbox cannot be confirmed with evidence, do NOT mark ready.
212
- Report the specific missing condition and route through the appropriate
213
- fix path (BUGBOT for dirty reviews, rebase for merge conflicts, etc.).
249
+ When the script fails (exit 1), do NOT mark ready. Report the FAIL label and
250
+ route through the matching fix path (BUGBOT for dirty reviews, rebase for
251
+ merge conflicts, and so on).
214
252
 
215
- Only when ALL seven conditions are confirmed:
253
+ When the script passes (exit 0):
216
254
 
217
255
  Use the `update_pull_request` MCP tool:
218
256
 
@@ -220,7 +258,5 @@ Use the `update_pull_request` MCP tool:
220
258
 
221
259
  With `state.json`, append convergence row to
222
260
  `<TMPDIR>/pr-converge-<session_id>/converged.log` per `multi-pr-orchestration.md` §Memory; else skip.
223
- Report: `PR #<NUMBER> converged: bugbot CLEAN at <SHA>, bugteam CLEAN at
224
- <SHA>, mergeable_state clean, copilot CLEAN at <SHA>, claude <APPROVED|absent>
225
- at <SHA>, 0 unresolved threads across PR; marked ready for review`.
226
- **Omit loop pacing** per **Convergence** of active pacing workflow.
261
+ Report from the script's PASS lines (the seven labels above). **Omit loop
262
+ pacing** per **Convergence** of active pacing workflow.
@@ -12,14 +12,18 @@ stop]
12
12
 
13
13
  <example> CODE_REVIEW tick (the entry phase), the static sweep raises a
14
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
+ resets push-invalidated markers per [ground-rules.md](ground-rules.md) /
16
+ [state-schema.md](state-schema.md) (all `*_clean_at`, `merge_state_status`,
17
+ `bugbot_down`, `bugbot_acknowledged_at`), stays `phase = CODE_REVIEW`, Step 4
18
+ at 270s, re-runs the sweep next tick]
17
19
  </example>
18
20
 
19
21
  <example> CODE_REVIEW tick, static sweep clean, `/code-review high --fix`
20
22
  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]
23
+ commit, pushes, resets push-invalidated markers per
24
+ [ground-rules.md](ground-rules.md) / [state-schema.md](state-schema.md) (all
25
+ `*_clean_at`, `merge_state_status`, `bugbot_down`, `bugbot_acknowledged_at`),
26
+ stays `phase = CODE_REVIEW`, Step 4 at 270s, returns]
23
27
  </example>
24
28
 
25
29
  <example> CODE_REVIEW tick, static sweep clean and `/code-review high --fix`
@@ -28,14 +32,17 @@ clean (no changes applied). Claude: [sets `code_review_clean_at = HEAD`,
28
32
  </example>
29
33
 
30
34
  <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]
35
+ [re-resolves HEAD, resets push-invalidated markers per
36
+ [ground-rules.md](ground-rules.md) / [state-schema.md](state-schema.md) (all
37
+ `*_clean_at`, `merge_state_status`, `bugbot_down`, `bugbot_acknowledged_at`),
38
+ `phase = CODE_REVIEW`, Step 4 at 270s, re-enters the internal passes on the
39
+ new HEAD]
34
40
  </example>
35
41
 
36
42
  <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]
43
+ [the internal passes are clean on `current_head`; stamps `bugteam_clean_at =
44
+ current_head`, then `phase = BUGBOT` — routes into the terminal Bugbot gate in
45
+ the same tick]
39
46
  </example>
40
47
 
41
48
  <example> Terminal BUGBOT gate, Bugbot disabled for the run (the default).
@@ -51,8 +58,10 @@ the same tick]
51
58
 
52
59
  <example> Terminal BUGBOT gate, Bugbot has 2 unaddressed findings on HEAD.
53
60
  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]
61
+ resets push-invalidated markers per [ground-rules.md](ground-rules.md) /
62
+ [state-schema.md](state-schema.md) (all `*_clean_at`, `merge_state_status`,
63
+ `bugbot_down`, `bugbot_acknowledged_at`), `phase = CODE_REVIEW`, Step 4 at
64
+ 270s, re-enters the internal passes on the new HEAD]
56
65
  </example>
57
66
 
58
67
  <example> Convergence gates after the terminal Bugbot gate confirms
@@ -74,8 +83,7 @@ in order:
74
83
  Next tick: re-run gate (a) fetch → Copilot `APPROVED` at `current_head`
75
84
  → set `copilot_clean_at = current_head`, record evidence: "Copilot
76
85
  APPROVED at <SHA>", re-validate gates (b) and (c).
77
- Gate (e): the `pr-fix-protocol` unresolved-thread sweep
78
- (`../../pr-fix-protocol/SKILL.md`) → zero across PR → record evidence.
86
+ Gate (e): the shared fix protocol unresolved-thread sweep ([`../../../_shared/pr-loop/fix-protocol.md`](../../../_shared/pr-loop/fix-protocol.md) step 12; skill deltas in [`fix-protocol.md`](fix-protocol.md)) → zero across PR → record evidence.
79
87
  Gate (f): all six gates pass → `update_pull_request(pullNumber=NUMBER,
80
88
  owner=OWNER, repo=REPO, draft=false)`.
81
89
  Reports "PR #N converged: bugbot CLEAN at <SHA>, bugteam CLEAN at <SHA>,
@@ -93,17 +101,20 @@ HEAD`, `phase = BUGTEAM`]
93
101
  <example> Convergence gates reached, but `mergeStateStatus: DIRTY` (base
94
102
  advanced, merge conflicts). Claude: [runs §Convergence gate (c); does NOT
95
103
  mark ready; invokes `rebase` skill per `../../rebase/SKILL.md` Phase 1–4;
96
- after force-with-lease push, resets `bugbot_clean_at = null`,
97
- `code_review_clean_at = null`, `copilot_clean_at = null`, `merge_state_status
98
- = null`, `phase = CODE_REVIEW`, schedules next wakeup]
104
+ after force-with-lease push, resets push-invalidated markers per
105
+ [ground-rules.md](ground-rules.md) / [state-schema.md](state-schema.md) (all
106
+ `*_clean_at`, `merge_state_status`, `bugbot_down`, `bugbot_acknowledged_at`),
107
+ `phase = CODE_REVIEW`, schedules next wakeup]
99
108
  </example>
100
109
 
101
110
  <example> Convergence gates reached, mergeability CLEAN, Copilot review at
102
111
  `current_head` `state == "CHANGES_REQUESTED"` with two unaddressed inline
103
112
  findings. Claude: [runs §Convergence gates (a); applies Fix protocol (TDD
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]
113
+ test → fix → push → reply inline both threads), resets push-invalidated
114
+ markers per [ground-rules.md](ground-rules.md) /
115
+ [state-schema.md](state-schema.md) (all `*_clean_at`, `merge_state_status`,
116
+ `bugbot_down`, `bugbot_acknowledged_at`), `phase = CODE_REVIEW`, schedules
117
+ next wakeup, re-enters the internal passes on the new HEAD]
107
118
  </example>
108
119
 
109
120
  <example> Convergence gates reached, mergeability CLEAN, no Copilot review on
@@ -114,7 +125,7 @@ Copilot review `state: APPROVED` at `current_head`. Claude: [re-runs
114
125
  gate (a) fetch → APPROVED → sets `copilot_clean_at = current_head`,
115
126
  records evidence: "Copilot APPROVED at <SHA>";
116
127
  re-validates gates (b) Claude absent and (c) mergeability clean,
117
- records evidence for both; gate (e) — the `pr-fix-protocol`
128
+ records evidence for both; gate (e) — the shared fix protocol
118
129
  unresolved-thread sweep — passes trivially, record evidence:
119
130
  "0 unresolved threads across PR at <SHA>";
120
131
  runs `update_pull_request(pullNumber=NUMBER,
@@ -127,9 +138,10 @@ at <SHA>, bugteam CLEAN at <SHA>, mergeable_state clean, copilot CLEAN at
127
138
  Copilot review returned `state: CHANGES_REQUESTED` with inline findings on
128
139
  `current_head`. Claude: [does NOT mark PR ready — gate (d) failed;
129
140
  applies Fix protocol on every confirmed Copilot finding (TDD test → fix →
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.]
141
+ push → reply inline on each thread); resets push-invalidated markers per
142
+ [ground-rules.md](ground-rules.md) / [state-schema.md](state-schema.md) (all
143
+ `*_clean_at`, `merge_state_status`, `bugbot_down`, `bugbot_acknowledged_at`);
144
+ `phase = CODE_REVIEW`; schedules next wakeup, re-enters the internal passes
145
+ on the new HEAD. Full back-to-back-clean cycle plus all six gates must hold
146
+ again on new HEAD.]
135
147
  </example>
@@ -1,11 +1,9 @@
1
1
  # Fix protocol
2
2
 
3
- The full fix protocol — executor choice, the shared 13-step sequence,
4
- reply transport, thread resolution, the unresolved-thread sweep, and
5
- post-push resets lives in the `pr-fix-protocol` skill
6
- (`../../pr-fix-protocol/SKILL.md`), which follows the shared step
7
- sequence in `../../../_shared/pr-loop/fix-protocol.md`. Hook handling
8
- per [ground-rules.md](ground-rules.md).
3
+ Open and apply the shared fix sequence in
4
+ [`../../../_shared/pr-loop/fix-protocol.md`](../../../_shared/pr-loop/fix-protocol.md)
5
+ executor choice, the 13-step sequence, reply transport, thread resolution,
6
+ and post-push resets. Hook handling per [ground-rules.md](ground-rules.md).
9
7
 
10
8
  This file holds only the pr-converge deltas: the multi-PR teammate
11
9
  obligations and the same-tick re-entry rule.
@@ -17,7 +15,9 @@ obligations and the same-tick re-entry rule.
17
15
  (what changed + commit identifier), matching §Audit result → fix worker step 4 — **before** writing
18
16
  `state.json` and going idle.
19
17
  - Writes `last_action: "fix_pushed"`, `current_head: <new SHA>`,
20
- `bugbot_clean_at: null`, `code_review_clean_at: null`, `bugbot_down: false`,
18
+ `bugbot_clean_at: null`, `code_review_clean_at: null`,
19
+ `bugteam_clean_at: null`, `copilot_clean_at: null`,
20
+ `merge_state_status: null`, `bugbot_down: false`,
21
21
  `phase: "CODE_REVIEW"`, `status: "awaiting_code_review"`, `last_updated`
22
22
  (ISO-8601 UTC) to `state.json` (per §Concurrency).
23
23
  - Goes idle. Orchestrator spawns a follow-up `general-purpose` agent for the
@@ -41,6 +41,10 @@ Create once at session start. Each teammate writes result before going idle.
41
41
  "phase": "BUGBOT",
42
42
  "current_head": "f9a7d49e",
43
43
  "bugbot_clean_at": null,
44
+ "code_review_clean_at": null,
45
+ "bugteam_clean_at": null,
46
+ "copilot_clean_at": null,
47
+ "merge_state_status": null,
44
48
  "inline_lag_streak": 0,
45
49
  "bugbot_down": false,
46
50
  "tick_count": 5,
@@ -52,8 +56,8 @@ Create once at session start. Each teammate writes result before going idle.
52
56
  }
53
57
  ```
54
58
 
55
- **`status` values:** `fresh` | `in_progress` | `awaiting_bugbot` |
56
- `awaiting_bugteam` | `converged` | `blocked`
59
+ **`status` values:** `fresh` | `in_progress` | `awaiting_code_review` |
60
+ `awaiting_bugbot` | `awaiting_bugteam` | `converged` | `blocked`
57
61
 
58
62
  **Write rule:** Subagents read current file, merge **only** their PR's entry
59
63
  under `prs`, write back. Writes keyed on `pr_number`; other PRs untouched.
@@ -112,8 +116,10 @@ Bugfind subagent completes (findings or clean):
112
116
  `add_reply_to_pull_request_comment(owner, repo, pullNumber, commentId, body)`.
113
117
  5. Writes `state.json` (per §Concurrency): `last_action: "fix_pushed"`,
114
118
  `current_head: <new SHA>`, `bugbot_clean_at: null`,
115
- `bugbot_down: false`, `phase:
116
- "BUGBOT"`, `status: "awaiting_bugbot"`, `last_updated` ISO-8601 UTC.
119
+ `code_review_clean_at: null`, `bugteam_clean_at: null`,
120
+ `copilot_clean_at: null`, `merge_state_status: null`,
121
+ `bugbot_down: false`, `phase: "CODE_REVIEW"`,
122
+ `status: "awaiting_code_review"`, `last_updated` ISO-8601 UTC.
117
123
  6. Goes idle.
118
124
 
119
125
  - **PRs with zero findings:** spawn one `general-purpose` subagent per PR via
@@ -1,5 +1,16 @@
1
1
  # Per-tick work
2
2
 
3
+ ## Contents
4
+
5
+ - [Invocation modes](#invocation-modes)
6
+ - [Pacing workflow](#pacing-workflow)
7
+ - [Step 1: Resolve current HEAD and PR context](#step-1-resolve-current-head-and-pr-context)
8
+ - [Step 1.5: Resolve the PR worktree (cwd routing)](#step-15-resolve-the-pr-worktree-cwd-routing)
9
+ - [Step 2: Branch on phase](#step-2-branch-on-phase)
10
+ - [Step 3: Re-trigger bugbot](#step-3-re-trigger-bugbot)
11
+ - [Step 4: Loop pacing](#step-4-loop-pacing)
12
+ - [Bugteam execution](#bugteam-execution)
13
+
3
14
  Use on **draft PR**. Cursor Bugbot and `/bugteam` re-run after each push. Fix
4
15
  findings between rounds until back-to-back clean on same `HEAD`, then mark
5
16
  PR ready for review.
@@ -40,8 +51,10 @@ pull_request_read(owner=OWNER, repo=REPO, pullNumber=NUMBER, method="get") → `
40
51
  ```
41
52
 
42
53
  If owner/repo/number are not yet known, extract them from the PR URL.
43
- If `current_head` changed since last tick, reset `bugbot_down` to `false`
44
- (new HEAD invalidates prior down-detection state).
54
+ If `current_head` changed since last tick, reset push-invalidated markers
55
+ per [ground-rules.md](ground-rules.md) / [state-schema.md](state-schema.md)
56
+ (all `*_clean_at`, `merge_state_status`, `bugbot_down`, `bugbot_acknowledged_at`) —
57
+ new HEAD invalidates prior clean and down-detection state.
45
58
 
46
59
  Capture `number`, `head.sha` (= `current_head`), owner/repo, branch.
47
60
 
@@ -166,10 +179,11 @@ a. **Static sweep — runs first, before `/code-review`.** Run the deterministic
166
179
  gates over the full `origin/main...HEAD` changed files:
167
180
  `python "$HOME/.claude/_shared/pr-loop/scripts/code_rules_gate.py" --base origin/main`,
168
181
  `ruff`, `mypy`, and stem-matched `pytest`. On any failure, apply the
169
- `pr-fix-protocol` skill (`../../pr-fix-protocol/SKILL.md`), commit and push,
170
- reset `bugbot_clean_at = null` and `code_review_clean_at = null`, stay
171
- `phase = CODE_REVIEW`, and re-run the sweep. When the sweep is clean, run
172
- `/code-review` below.
182
+ shared fix protocol ([`../../../_shared/pr-loop/fix-protocol.md`](../../../_shared/pr-loop/fix-protocol.md); skill deltas in [`fix-protocol.md`](fix-protocol.md)), commit and push,
183
+ reset push-invalidated markers per [ground-rules.md](ground-rules.md) /
184
+ [state-schema.md](state-schema.md) (all `*_clean_at`, `merge_state_status`,
185
+ `bugbot_down`, `bugbot_acknowledged_at`), stay `phase = CODE_REVIEW`, and
186
+ re-run the sweep. When the sweep is clean, run `/code-review` below.
173
187
 
174
188
  b. Run Claude Code's built-in `/code-review high --fix` on the FULL
175
189
  `origin/main...HEAD` diff — every file the PR touches — via the
@@ -192,11 +206,13 @@ b. Run Claude Code's built-in `/code-review high --fix` on the FULL
192
206
  c. Decide (two branches; match first whose predicate holds):
193
207
 
194
208
  - **`/code-review` applied fixes (working tree changed):** Commit the
195
- applied fixes in one commit → push, following the `pr-fix-protocol`
196
- skill's commit and push steps (`../../pr-fix-protocol/SKILL.md`). Reset
197
- `bugbot_clean_at = null` AND `code_review_clean_at = null`. Stay
198
- `phase = CODE_REVIEW`, schedule next wakeup, return. Every fix push
199
- re-enters the internal passes on the new HEAD.
209
+ applied fixes in one commit → push, following the shared fix protocol
210
+ commit and push steps ([`../../../_shared/pr-loop/fix-protocol.md`](../../../_shared/pr-loop/fix-protocol.md)). Reset
211
+ push-invalidated markers per [ground-rules.md](ground-rules.md) /
212
+ [state-schema.md](state-schema.md) (all `*_clean_at`, `merge_state_status`,
213
+ `bugbot_down`, `bugbot_acknowledged_at`). Stay `phase = CODE_REVIEW`,
214
+ schedule next wakeup, return. Every fix push re-enters the internal
215
+ passes on the new HEAD.
200
216
  - **Clean (no changes applied):** Set
201
217
  `code_review_clean_at = current_head`, `phase = BUGTEAM`. Continue
202
218
  BUGTEAM in same tick — back-to-back convergence requires code-review and
@@ -244,9 +260,11 @@ pushed commits during its run. `current_head` from Step 1 is stale:
244
260
  proceed with convergence-gates — schedule a 90s wakeup and return.
245
261
  Re-resolve HEAD next tick.
246
262
 
247
- If `new_head != current_head`, set `current_head = new_head`,
248
- `bugbot_clean_at = null`, `bugbot_down = false`. New commits invalidate
249
- bugbot's prior clean and down-detection state.
263
+ If `new_head != current_head`, set `current_head = new_head` and reset
264
+ push-invalidated markers per [ground-rules.md](ground-rules.md) /
265
+ [state-schema.md](state-schema.md) (all `*_clean_at`, `merge_state_status`,
266
+ `bugbot_down`, `bugbot_acknowledged_at`). New commits invalidate prior
267
+ clean and down-detection state.
250
268
 
251
269
  c. Inspect bugteam outcome. Reports `convergence (zero findings)` or list
252
270
  of unfixed findings with file:line.
@@ -254,17 +272,19 @@ of unfixed findings with file:line.
254
272
  d. Decide based on post-bugteam state — order matters. Check
255
273
  pushed-during-bugteam FIRST so a convergence report against a stale HEAD
256
274
  never falsely terminates:
257
- - **Audit pushed this tick (`bugbot_clean_at` reset in step b):**
258
- Reset `code_review_clean_at = null`, `phase = CODE_REVIEW`, schedule next
259
- wakeup, return. Every fix push re-enters the internal passes on the new
260
- HEAD.
275
+ - **Audit pushed this tick (clean-at fields reset in step b):**
276
+ `phase = CODE_REVIEW`, schedule next wakeup, return. Every fix push
277
+ re-enters the internal passes on the new HEAD.
261
278
  - **Convergence AND no push:** the internal passes are clean on
262
- `current_head`. `phase = BUGBOT` — route into the terminal Bugbot gate,
263
- which confirms and then runs the convergence gates. Continue BUGBOT in the
264
- same tick.
265
- - **Findings without committed fixes:** apply the `pr-fix-protocol`
266
- skill (`../../pr-fix-protocol/SKILL.md`). Reset `code_review_clean_at =
267
- null`, `phase = CODE_REVIEW`, schedule next wakeup, return.
279
+ `current_head`. Stamp `bugteam_clean_at = current_head`, then
280
+ `phase = BUGBOT` route into the terminal Bugbot gate, which confirms
281
+ and then runs the convergence gates. Continue BUGBOT in the same tick.
282
+ - **Findings without committed fixes:** apply the shared fix protocol
283
+ ([`../../../_shared/pr-loop/fix-protocol.md`](../../../_shared/pr-loop/fix-protocol.md); skill deltas in [fix-protocol.md](fix-protocol.md)). Reset push-invalidated markers
284
+ per [ground-rules.md](ground-rules.md) / [state-schema.md](state-schema.md)
285
+ (all `*_clean_at`, `merge_state_status`, `bugbot_down`,
286
+ `bugbot_acknowledged_at`), `phase = CODE_REVIEW`, schedule next wakeup,
287
+ return.
268
288
 
269
289
  ### `phase == BUGBOT` (terminal gate)
270
290
 
@@ -314,8 +334,8 @@ pull_request_read(owner=OWNER, repo=REPO, pullNumber=NUMBER, method="get_review_
314
334
  → filter threads where `is_resolved == false`
315
335
  ```
316
336
 
317
- Per-thread handling lives in the `pr-fix-protocol` skill's
318
- unresolved-thread sweep (`../../pr-fix-protocol/SKILL.md`).
337
+ Per-thread handling lives in the shared fix protocol's
338
+ unresolved-thread sweep (`../../../_shared/pr-loop/fix-protocol.md`).
319
339
 
320
340
  c. Decide (four branches; match first whose predicate holds):
321
341
  - **No bugbot review yet, OR latest review's `commit_id` ≠
@@ -327,11 +347,13 @@ c. Decide (four branches; match first whose predicate holds):
327
347
  `inline_lag_streak = 0`, advance to the [convergence
328
348
  gates](convergence-gates.md) in the same tick.
329
349
  - **`commit_id == current_head` with unaddressed inline findings:**
330
- Apply the `pr-fix-protocol` skill (`../../pr-fix-protocol/SKILL.md`).
331
- Reset `inline_lag_streak = 0`, `bugbot_clean_at = null`,
332
- `code_review_clean_at = null`, `phase = CODE_REVIEW`. With `state.json`:
333
- the clean-coder teammate executes the fix, writes `state.json`, goes idle;
334
- the next tick re-enters CODE_REVIEW on the new HEAD. No `state.json`
350
+ Apply the shared fix protocol ([`../../../_shared/pr-loop/fix-protocol.md`](../../../_shared/pr-loop/fix-protocol.md); skill deltas in [`fix-protocol.md`](fix-protocol.md)).
351
+ Reset `inline_lag_streak = 0` and push-invalidated markers per
352
+ [ground-rules.md](ground-rules.md) / [state-schema.md](state-schema.md)
353
+ (all `*_clean_at`, `merge_state_status`, `bugbot_down`,
354
+ `bugbot_acknowledged_at`), `phase = CODE_REVIEW`. With `state.json`: the
355
+ clean-coder teammate executes the fix, writes `state.json`, goes idle; the
356
+ next tick re-enters CODE_REVIEW on the new HEAD. No `state.json`
335
357
  (single-PR): the lead executes it, stays `phase = CODE_REVIEW`. Schedule
336
358
  next wakeup, return.
337
359
 
@@ -355,17 +377,18 @@ python ~/.claude/skills/pr-converge/scripts/fetch_copilot_inline_comments.py --o
355
377
  b. Decide (three branches; match first whose predicate holds):
356
378
 
357
379
  - **Copilot review `state: APPROVED` at `current_head`:** Set
358
- `copilot_clean_at = current_head`. Record "Copilot APPROVED". Set
359
- `phase = BUGTEAM`. Continue to convergence-gates.md gate (b) in same
360
- tick back-to-back convergence requires all gates on same HEAD.
380
+ `copilot_clean_at = current_head`. Record "Copilot APPROVED". Stay on
381
+ `COPILOT_WAIT` do not re-enter BUGTEAM. Continue to
382
+ convergence-gates.md gate (b) in same tick; re-validate gates (b), (c),
383
+ then (e), (f) on the same HEAD.
361
384
  - **Copilot review dirty (CHANGES_REQUESTED or COMMENTED with findings)
362
- at `current_head`:** Apply the `pr-fix-protocol` skill
363
- (`../../pr-fix-protocol/SKILL.md`) it covers body-only findings with
364
- no inline threads. Reset
365
- `bugbot_clean_at = null`, `code_review_clean_at = null`, AND
366
- `copilot_clean_at = null`. **Set `phase = CODE_REVIEW`** (NOT
367
- COPILOT_WAIT) — every fix push re-enters the internal passes on the new
368
- HEAD. Schedule next wakeup, return.
385
+ at `current_head`:** Apply the shared fix protocol ([`../../../_shared/pr-loop/fix-protocol.md`](../../../_shared/pr-loop/fix-protocol.md); skill deltas in [`fix-protocol.md`](fix-protocol.md)) — it covers body-only findings with
386
+ no inline threads. Reset push-invalidated markers per
387
+ [ground-rules.md](ground-rules.md) / [state-schema.md](state-schema.md)
388
+ (all `*_clean_at`, `merge_state_status`, `bugbot_down`,
389
+ `bugbot_acknowledged_at`). **Set `phase = CODE_REVIEW`** (NOT COPILOT_WAIT)
390
+ — every fix push re-enters the internal passes on the new HEAD. Schedule
391
+ next wakeup, return.
369
392
  - **No Copilot review at `current_head` yet:** Increment
370
393
  `copilot_wait_count` (init 0 on COPILOT_WAIT entry; reset to 0 on
371
394
  every push and on every successful Copilot review). `>= 3` → hard