claude-dev-env 1.94.0 → 2.0.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 (280) hide show
  1. package/_shared/advisor/CLAUDE.md +2 -2
  2. package/_shared/advisor/advisor-protocol.md +41 -33
  3. package/_shared/advisor/scripts/config/advisor_scripts_constants/model_tier_run_validator_constants.py +17 -13
  4. package/_shared/advisor/scripts/model_tier_run_validator.py +27 -18
  5. package/_shared/advisor/scripts/tests/test_model_tier_run_validator.py +95 -25
  6. package/_shared/advisor/scripts/tests/test_tier_model_ids.py +17 -17
  7. package/_shared/advisor/scripts/tier_model_ids.py +18 -18
  8. package/_shared/pr-loop/CLAUDE.md +1 -0
  9. package/_shared/pr-loop/scripts/CLAUDE.md +2 -1
  10. package/_shared/pr-loop/scripts/README.md +1 -0
  11. package/_shared/pr-loop/scripts/code_rules_gate.py +253 -1980
  12. package/_shared/pr-loop/scripts/code_rules_gate_parts/CLAUDE.md +32 -0
  13. package/_shared/pr-loop/scripts/code_rules_gate_parts/__init__.py +7 -0
  14. package/_shared/pr-loop/scripts/code_rules_gate_parts/added_line_maps.py +268 -0
  15. package/_shared/pr-loop/scripts/code_rules_gate_parts/enforcer_loading.py +172 -0
  16. package/_shared/pr-loop/scripts/code_rules_gate_parts/gate_arguments.py +70 -0
  17. package/_shared/pr-loop/scripts/code_rules_gate_parts/gate_running.py +326 -0
  18. package/_shared/pr-loop/scripts/code_rules_gate_parts/git_blob_readers.py +85 -0
  19. package/_shared/pr-loop/scripts/code_rules_gate_parts/git_file_sets.py +331 -0
  20. package/_shared/pr-loop/scripts/code_rules_gate_parts/staged_test_running.py +369 -0
  21. package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/conftest.py +14 -0
  22. package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_added_line_maps.py +118 -0
  23. package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_enforcer_loading.py +17 -0
  24. package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_gate_arguments.py +29 -0
  25. package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_gate_running.py +99 -0
  26. package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_git_blob_readers.py +69 -0
  27. package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_git_file_sets.py +137 -0
  28. package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_staged_test_running.py +116 -0
  29. package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_violation_scoping.py +75 -0
  30. package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_wrapper_plumb_check.py +49 -0
  31. package/_shared/pr-loop/scripts/code_rules_gate_parts/violation_scoping.py +328 -0
  32. package/_shared/pr-loop/scripts/code_rules_gate_parts/wrapper_plumb_check.py +206 -0
  33. package/_shared/pr-loop/scripts/pr_loop_shared_constants/code_rules_gate_constants.py +24 -17
  34. package/_shared/pr-loop/scripts/pr_loop_shared_constants/reviews_disabled_constants.py +1 -0
  35. package/_shared/pr-loop/scripts/reviews_disabled.py +19 -2
  36. package/_shared/pr-loop/scripts/test_code_rules_gate.py +278 -0
  37. package/_shared/pr-loop/scripts/tests/test_code_rules_gate_constants.py +6 -39
  38. package/_shared/pr-loop/scripts/tests/test_reviews_disabled.py +43 -0
  39. package/_shared/pr-loop/worker-spawn.md +186 -0
  40. package/agents/code-verifier.md +1 -1
  41. package/bin/CLAUDE.md +10 -1
  42. package/bin/ever-shipped-skills.mjs +73 -0
  43. package/bin/expand_home_directory_tokens.mjs +1 -1
  44. package/bin/install.mjs +140 -7
  45. package/bin/install.prune.test.mjs +457 -0
  46. package/docs/CODE_RULES.md +1 -1
  47. package/hooks/advisory/refactor_guard.py +3 -4
  48. package/hooks/blocking/CLAUDE.md +7 -1
  49. package/hooks/blocking/block_main_commit.py +2 -2
  50. package/hooks/blocking/claude_md_orphan_file_blocker.py +75 -699
  51. package/hooks/blocking/claude_md_orphan_file_blocker_parts/CLAUDE.md +28 -0
  52. package/hooks/blocking/claude_md_orphan_file_blocker_parts/__init__.py +1 -0
  53. package/hooks/blocking/claude_md_orphan_file_blocker_parts/config/__init__.py +1 -0
  54. package/hooks/blocking/claude_md_orphan_file_blocker_parts/config/orphan_blocker_constants.py +18 -0
  55. package/hooks/blocking/claude_md_orphan_file_blocker_parts/decision.py +81 -0
  56. package/hooks/blocking/claude_md_orphan_file_blocker_parts/references.py +307 -0
  57. package/hooks/blocking/claude_md_orphan_file_blocker_parts/scan_plan.py +124 -0
  58. package/hooks/blocking/claude_md_orphan_file_blocker_parts/subtree_scan.py +179 -0
  59. package/hooks/blocking/claude_md_orphan_file_blocker_parts/tests/conftest.py +10 -0
  60. package/hooks/blocking/claude_md_orphan_file_blocker_parts/tests/test_decision.py +34 -0
  61. package/hooks/blocking/claude_md_orphan_file_blocker_parts/tests/test_references.py +42 -0
  62. package/hooks/blocking/claude_md_orphan_file_blocker_parts/tests/test_scan_plan.py +27 -0
  63. package/hooks/blocking/claude_md_orphan_file_blocker_parts/tests/test_subtree_scan.py +30 -0
  64. package/hooks/blocking/code_rules_boolean_mustcheck.py +1 -1
  65. package/hooks/blocking/code_rules_enforcer.py +4 -0
  66. package/hooks/blocking/code_rules_mock_completeness.py +1 -1
  67. package/hooks/blocking/code_rules_optional_params.py +2 -2
  68. package/hooks/blocking/code_rules_shared.py +83 -1
  69. package/hooks/blocking/code_rules_test_assertions.py +1 -1
  70. package/hooks/blocking/code_rules_test_layout.py +9 -3
  71. package/hooks/blocking/code_rules_typeddict_stub.py +1 -1
  72. package/hooks/blocking/gh_pr_author_enforcer.py +1 -1
  73. package/hooks/blocking/inventory_intent_records/CLAUDE.md +26 -0
  74. package/hooks/blocking/inventory_intent_records/__init__.py +1 -0
  75. package/hooks/blocking/inventory_intent_records/config/__init__.py +1 -0
  76. package/hooks/blocking/inventory_intent_records/config/intent_records_constants.py +20 -0
  77. package/hooks/blocking/inventory_intent_records/records.py +271 -0
  78. package/hooks/blocking/inventory_intent_records/tests/conftest.py +10 -0
  79. package/hooks/blocking/inventory_intent_records/tests/test_records.py +80 -0
  80. package/hooks/blocking/package_inventory_stale_blocker.py +54 -384
  81. package/hooks/blocking/package_inventory_stale_blocker_parts/CLAUDE.md +26 -0
  82. package/hooks/blocking/package_inventory_stale_blocker_parts/__init__.py +1 -0
  83. package/hooks/blocking/package_inventory_stale_blocker_parts/config/__init__.py +1 -0
  84. package/hooks/blocking/package_inventory_stale_blocker_parts/config/inventory_blocker_constants.py +16 -0
  85. package/hooks/blocking/package_inventory_stale_blocker_parts/decision.py +84 -0
  86. package/hooks/blocking/package_inventory_stale_blocker_parts/inventory_detection.py +307 -0
  87. package/hooks/blocking/package_inventory_stale_blocker_parts/tests/conftest.py +10 -0
  88. package/hooks/blocking/package_inventory_stale_blocker_parts/tests/test_decision.py +38 -0
  89. package/hooks/blocking/package_inventory_stale_blocker_parts/tests/test_inventory_detection.py +61 -0
  90. package/hooks/blocking/pii_payload_scan.py +138 -42
  91. package/hooks/blocking/pii_prevention_blocker.py +185 -291
  92. package/hooks/blocking/pii_prevention_blocker_parts/CLAUDE.md +24 -0
  93. package/hooks/blocking/pii_prevention_blocker_parts/__init__.py +1 -0
  94. package/hooks/blocking/pii_prevention_blocker_parts/config/__init__.py +1 -0
  95. package/hooks/blocking/pii_prevention_blocker_parts/config/repository_resolution_constants.py +28 -0
  96. package/hooks/blocking/pii_prevention_blocker_parts/repository_exemption.py +214 -0
  97. package/hooks/blocking/pii_prevention_blocker_parts/repository_resolution.py +208 -0
  98. package/hooks/blocking/plain_language_blocker.py +138 -4
  99. package/hooks/blocking/pr_description_command_parser.py +8 -4
  100. package/hooks/blocking/precommit_code_rules_gate.py +3 -3
  101. package/hooks/blocking/sensitive_file_protector.py +114 -48
  102. package/hooks/blocking/tdd_enforcer.py +97 -601
  103. package/hooks/blocking/tdd_enforcer_parts/CLAUDE.md +30 -0
  104. package/hooks/blocking/tdd_enforcer_parts/__init__.py +1 -0
  105. package/hooks/blocking/tdd_enforcer_parts/candidate_paths.py +142 -0
  106. package/hooks/blocking/tdd_enforcer_parts/config/__init__.py +1 -0
  107. package/hooks/blocking/tdd_enforcer_parts/config/tdd_enforcer_constants.py +32 -0
  108. package/hooks/blocking/tdd_enforcer_parts/content_analysis.py +268 -0
  109. package/hooks/blocking/tdd_enforcer_parts/decisions.py +92 -0
  110. package/hooks/blocking/tdd_enforcer_parts/freshness.py +80 -0
  111. package/hooks/blocking/tdd_enforcer_parts/git_tracking.py +63 -0
  112. package/hooks/blocking/tdd_enforcer_parts/path_classification.py +119 -0
  113. package/hooks/blocking/tdd_enforcer_parts/tests/conftest.py +10 -0
  114. package/hooks/blocking/tdd_enforcer_parts/tests/test_candidate_paths.py +31 -0
  115. package/hooks/blocking/tdd_enforcer_parts/tests/test_content_analysis.py +30 -0
  116. package/hooks/blocking/tdd_enforcer_parts/tests/test_decisions.py +34 -0
  117. package/hooks/blocking/tdd_enforcer_parts/tests/test_freshness.py +28 -0
  118. package/hooks/blocking/tdd_enforcer_parts/tests/test_git_tracking.py +48 -0
  119. package/hooks/blocking/tdd_enforcer_parts/tests/test_path_classification.py +36 -0
  120. package/hooks/blocking/test_code_rules_enforcer_scratchpad.py +105 -0
  121. package/hooks/blocking/test_code_rules_shared.py +181 -0
  122. package/hooks/blocking/test_inventory_deadlock_resolution.py +154 -0
  123. package/hooks/blocking/test_pii_payload_scan.py +168 -0
  124. package/hooks/blocking/test_plain_language_blocker_allowlist.py +184 -0
  125. package/hooks/blocking/test_sensitive_file_protector.py +185 -0
  126. package/hooks/blocking/test_tdd_enforcer_restore.py +108 -0
  127. package/hooks/blocking/test_tdd_enforcer_scratchpad.py +105 -0
  128. package/hooks/blocking/tests/conftest.py +10 -0
  129. package/hooks/blocking/tests/test_pii_prevention_blocker.py +260 -0
  130. package/hooks/blocking/tests/test_repository_exemption.py +105 -0
  131. package/hooks/blocking/tests/test_repository_resolution.py +108 -0
  132. package/hooks/diagnostic/hook_log_extractor.py +12 -10
  133. package/hooks/git-hooks/post_commit.py +3 -4
  134. package/hooks/hooks_constants/CLAUDE.md +4 -2
  135. package/hooks/hooks_constants/banned_identifiers_constants.py +0 -1
  136. package/hooks/hooks_constants/code_rules_path_utils_constants.py +1 -1
  137. package/hooks/hooks_constants/harness_scratchpad_constants.py +17 -0
  138. package/hooks/hooks_constants/local_identity.py +59 -8
  139. package/hooks/hooks_constants/pii_prevention_constants.py +0 -6
  140. package/hooks/hooks_constants/plain_language_blocker_constants.py +5 -0
  141. package/hooks/hooks_constants/sensitive_file_protector_constants.py +42 -0
  142. package/hooks/hooks_constants/test_local_identity.py +105 -3
  143. package/hooks/pyproject.toml +52 -4
  144. package/hooks/session/plugin_data_dir_cleanup.py +0 -1
  145. package/hooks/validation/mypy_validator.py +2 -2
  146. package/hooks/validators/CLAUDE.md +1 -1
  147. package/hooks/validators/README.md +2 -0
  148. package/hooks/validators/health_check.py +1 -0
  149. package/hooks/validators/mypy_integration.py +2 -0
  150. package/hooks/validators/python_style_checks.py +114 -136
  151. package/hooks/validators/python_style_helpers.py +95 -0
  152. package/hooks/validators/ruff_integration.py +3 -0
  153. package/hooks/validators/test_python_style_checks.py +0 -164
  154. package/hooks/validators/test_python_style_checks_decorator_gap.py +119 -0
  155. package/hooks/validators/test_python_style_fixes.py +251 -0
  156. package/hooks/validators/test_python_style_helpers.py +125 -0
  157. package/hooks/workflow/auto_formatter.py +5 -4
  158. package/package.json +1 -1
  159. package/rules/CLAUDE.md +1 -0
  160. package/rules/anti-corollary-tests.md +69 -0
  161. package/rules/bdd.md +1 -3
  162. package/rules/code-reviews.md +1 -1
  163. package/rules/gh-paginate.md +1 -1
  164. package/rules/plain-language.md +2 -0
  165. package/scripts/CLAUDE.md +4 -0
  166. package/scripts/dev_env_scripts_constants/CLAUDE.md +6 -4
  167. package/scripts/dev_env_scripts_constants/code_review_constants.py +71 -0
  168. package/scripts/dev_env_scripts_constants/grok_worker_constants.py +435 -0
  169. package/scripts/dev_env_scripts_constants/timing.py +7 -1
  170. package/scripts/grok_headless_runner.py +294 -0
  171. package/scripts/grok_worker_preflight.py +410 -0
  172. package/scripts/invoke_code_review.py +463 -0
  173. package/scripts/resolve_worker_spawn.py +619 -0
  174. package/scripts/spawn_grok_batch.py +672 -0
  175. package/scripts/test_grok_headless_runner.py +626 -0
  176. package/scripts/test_grok_worker_preflight.py +1054 -0
  177. package/scripts/test_invoke_code_review.py +672 -0
  178. package/scripts/test_resolve_worker_spawn.py +1014 -0
  179. package/scripts/test_spawn_grok_batch.py +1017 -0
  180. package/skills/CLAUDE.md +6 -3
  181. package/skills/_shared/pr-loop/scripts/build_audit_prompt.py +72 -13
  182. package/skills/_shared/pr-loop/scripts/build_fix_prompt.py +121 -14
  183. package/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/path_resolver_constants.py +78 -0
  184. package/skills/_shared/pr-loop/scripts/test_build_audit_prompt.py +121 -0
  185. package/skills/_shared/pr-loop/scripts/test_build_fix_prompt.py +196 -6
  186. package/skills/autoconverge/CLAUDE.md +3 -3
  187. package/skills/autoconverge/SKILL.md +9 -3
  188. package/skills/autoconverge/reference/CLAUDE.md +2 -2
  189. package/skills/autoconverge/reference/convergence.md +33 -11
  190. package/skills/autoconverge/reference/stop-conditions.md +16 -5
  191. package/skills/autoconverge/workflow/CLAUDE.md +2 -1
  192. package/skills/autoconverge/workflow/converge.clean-audit.test.mjs +7 -2
  193. package/skills/autoconverge/workflow/converge.codex-gate.test.mjs +300 -0
  194. package/skills/autoconverge/workflow/converge.contract.test.mjs +5 -5
  195. package/skills/autoconverge/workflow/converge.copilot-gate.test.mjs +29 -29
  196. package/skills/autoconverge/workflow/converge.fix-progress.test.mjs +1 -1
  197. package/skills/autoconverge/workflow/converge.mjs +202 -18
  198. package/skills/bugteam/CLAUDE.md +2 -2
  199. package/skills/bugteam/CONSTRAINTS.md +3 -2
  200. package/skills/bugteam/PROMPTS.md +7 -6
  201. package/skills/bugteam/SKILL.md +18 -13
  202. package/skills/bugteam/reference/README.md +2 -3
  203. package/skills/bugteam/reference/audit-and-teammates.md +215 -35
  204. package/skills/bugteam/reference/design-rationale.md +1 -1
  205. package/skills/bugteam/reference/obstacles/CLAUDE.md +1 -1
  206. package/skills/bugteam/reference/team-setup.md +8 -2
  207. package/skills/closeout/SKILL.md +153 -0
  208. package/skills/closeout/reference/handoff-prompt-template.md +72 -0
  209. package/skills/closeout/reference/issue-body-templates.md +108 -0
  210. package/skills/closeout/reference/pii-redaction-checklist.md +36 -0
  211. package/skills/codex-review/CLAUDE.md +46 -0
  212. package/skills/codex-review/SKILL.md +181 -0
  213. package/skills/codex-review/reference/CLAUDE.md +15 -0
  214. package/skills/codex-review/reference/cli-contract.md +253 -0
  215. package/skills/codex-review/reference/loop-integration.md +118 -0
  216. package/skills/codex-review/scripts/codex_down_classifier.py +98 -0
  217. package/skills/codex-review/scripts/codex_review_scripts_constants/CLAUDE.md +18 -0
  218. package/skills/codex-review/scripts/codex_review_scripts_constants/__init__.py +1 -0
  219. package/skills/codex-review/scripts/codex_review_scripts_constants/classifier_constants.py +35 -0
  220. package/skills/codex-review/scripts/codex_review_scripts_constants/codex_usage_probe_constants.py +86 -0
  221. package/skills/codex-review/scripts/codex_review_scripts_constants/findings_constants.py +18 -0
  222. package/skills/codex-review/scripts/codex_review_scripts_constants/run_constants.py +45 -0
  223. package/skills/codex-review/scripts/codex_usage_probe.py +573 -0
  224. package/skills/codex-review/scripts/fixtures/auth_failure_synthetic.txt +1 -0
  225. package/skills/codex-review/scripts/fixtures/config_load_failure_v0.125.0.txt +1 -0
  226. package/skills/codex-review/scripts/fixtures/freeform_findings_v0.144.3.txt +6 -0
  227. package/skills/codex-review/scripts/fixtures/model_rejection_v0.125.0.jsonl +5 -0
  228. package/skills/codex-review/scripts/fixtures/structured_findings.txt +13 -0
  229. package/skills/codex-review/scripts/fixtures/success_stream_v0.144.3.jsonl +6 -0
  230. package/skills/codex-review/scripts/fixtures/unknown_failure_synthetic.txt +1 -0
  231. package/skills/codex-review/scripts/fixtures/usage_limit_synthetic.txt +1 -0
  232. package/skills/codex-review/scripts/parse_codex_findings.py +207 -0
  233. package/skills/codex-review/scripts/run_codex_review.py +415 -0
  234. package/skills/codex-review/scripts/test_codex_down_classifier.py +143 -0
  235. package/skills/codex-review/scripts/test_codex_usage_probe.py +678 -0
  236. package/skills/codex-review/scripts/test_parse_codex_findings.py +130 -0
  237. package/skills/codex-review/scripts/test_run_codex_review.py +812 -0
  238. package/skills/codex-review/test_skill_scaffold.py +192 -0
  239. package/skills/grok-spawn/CLAUDE.md +28 -0
  240. package/skills/grok-spawn/SKILL.md +226 -0
  241. package/skills/grok-spawn/reference/flag-profiles.md +132 -0
  242. package/skills/grok-spawn/reference/worker-briefs.md +152 -0
  243. package/skills/grokify/SKILL.md +9 -1
  244. package/skills/grokify/capability-claims.test.mjs +28 -0
  245. package/skills/grokify/evals/README.md +72 -0
  246. package/skills/grokify/evals/parse-payload.test.mjs +171 -0
  247. package/skills/grokify/evals/run-capability-evals.mjs +545 -0
  248. package/skills/orchestrator/SKILL.md +32 -22
  249. package/skills/orchestrator-refresh/SKILL.md +12 -8
  250. package/skills/pr-converge/CLAUDE.md +1 -1
  251. package/skills/pr-converge/SKILL.md +34 -13
  252. package/skills/pr-converge/reference/convergence-gates.md +42 -15
  253. package/skills/pr-converge/reference/fix-protocol.md +1 -1
  254. package/skills/pr-converge/reference/ground-rules.md +1 -1
  255. package/skills/pr-converge/reference/per-tick.md +130 -42
  256. package/skills/pr-converge/reference/state-schema.md +10 -0
  257. package/skills/pr-converge/scripts/CLAUDE.md +2 -0
  258. package/skills/pr-converge/scripts/_pr_converge_path_setup.py +5 -1
  259. package/skills/pr-converge/scripts/check_convergence.py +605 -29
  260. package/skills/pr-converge/scripts/check_convergence_availability.py +232 -0
  261. package/skills/pr-converge/scripts/check_convergence_gates.py +279 -235
  262. package/skills/pr-converge/scripts/check_convergence_thread_gates.py +1 -1
  263. package/skills/pr-converge/scripts/pr_converge_scripts_constants/convergence_gate_constants.py +36 -2
  264. package/skills/pr-converge/scripts/test__pr_converge_path_setup.py +4 -0
  265. package/skills/pr-converge/scripts/test_check_convergence.py +71 -3
  266. package/skills/pr-converge/scripts/test_check_convergence_availability.py +326 -0
  267. package/skills/pr-converge/scripts/test_check_convergence_codex.py +507 -0
  268. package/skills/pr-converge/scripts/test_check_convergence_contract.py +89 -17
  269. package/skills/pr-converge/scripts/test_check_convergence_fixture.py +179 -0
  270. package/skills/pr-converge/scripts/test_check_convergence_gates.py +84 -68
  271. package/skills/pr-converge/scripts/test_check_convergence_thread_gates.py +24 -0
  272. package/skills/pr-converge/test_step5_host_branch.py +106 -0
  273. package/skills/pr-fix-protocol/SKILL.md +65 -0
  274. package/skills/pr-loop-cloud-transport/SKILL.md +2 -0
  275. package/skills/reviewer-gates/SKILL.md +7 -5
  276. package/skills/skill-builder/references/skill-modularity.md +1 -1
  277. package/skills/team-advisor/SKILL.md +16 -12
  278. package/system-prompts/software-engineer.xml +7 -6
  279. package/hooks/validators/test_verify_paths.py +0 -32
  280. package/hooks/validators/verify_paths.py +0 -57
@@ -0,0 +1,65 @@
1
+ ---
2
+ name: pr-fix-protocol
3
+ description: >-
4
+ Applies reviewer findings to a PR as verified fixes and drives unresolved
5
+ review threads to zero. Invoked by PR-loop orchestrators (pr-converge,
6
+ autoconverge, bugteam, qbug, copilot-review) when a reviewer reports
7
+ findings; not for ad-hoc 'fix this bug' requests outside a PR loop.
8
+ ---
9
+
10
+ # PR Fix Protocol
11
+
12
+ **Core principle:** a finding is addressed only when the fix is pushed, the thread carries a reply, and the thread is resolved — as one unit of work. Anything short of all three leaves a convergence gate stalled.
13
+
14
+ ## How callers invoke this
15
+
16
+ - **Skill-capable contexts** (a lead session that holds the `Skill` tool): `Skill({skill: "pr-fix-protocol", args: "--skill <caller> --pr <URL> --worktree <path> [findings payload or 'sweep']"})`.
17
+ - **Fallback** (a subagent or teammate without the `Skill` tool): the caller's spawn prompt says to read `~/.claude/skills/pr-fix-protocol/SKILL.md` and apply it with the parameters below.
18
+
19
+ The caller passes: its identity, the PR scope, the PR worktree path, this round's findings (or `sweep` for a thread sweep with no fresh findings), and its post-push obligations — which clean-SHA state fields to reset and which reviewers to re-trigger.
20
+
21
+ ## Executor choice
22
+
23
+ - **Single-PR loops** (no shared `state.json`): the lead spawns `Agent(subagent_type: "clean-coder")` to write the fix. Stop when `Agent` is unavailable. A spawned clean-coder starts in its own working directory, so its prompt names the PR worktree path and directs it to edit, stage, and commit there.
24
+ - **Multi-PR orchestration** (shared `state.json`): a per-PR clean-coder teammate owns edits, replies, and state writes; the orchestrator holds back from inline edits. The teammate obligations — reply before writing state, which state fields to set, idle handoff — live in the calling skill's multi-PR reference.
25
+
26
+ Run every git command in the PR worktree. `git add`, `git commit`, and `git push` act on the repo of the current working directory, so a cross-repo PR's fix lands in the PR's repo only when the working directory is its worktree.
27
+
28
+ ## The fix sequence
29
+
30
+ Follow the shared 13-step sequence in [`_shared/pr-loop/fix-protocol.md`](../../_shared/pr-loop/fix-protocol.md) exactly: read each file:line, capture the pre-fix SHA and contents, write a failing test first where the finding has behavior, apply the fix narrowly, `py_compile`, run the post-fix self-audit, stage by explicit path, make one commit, fast-forward push, then reply and resolve atomically per thread. Its Constraints section — narrow scope, keep the commit hooks, preserve helpers — binds every executor.
31
+
32
+ **Reply transport:** the GitHub MCP `add_reply_to_pull_request_comment` is primary. For a script-only context or a multi-PR teammate, the fallback is `python "$HOME/.claude/skills/pr-converge/scripts/post_fix_reply.py" --owner <O> --repo <R> --pr-number <N> --in-reply-to <COMMENT_ID> --body "Fixed in <SHA> — <what changed>"`. Both carry the body shape from [`_shared/pr-loop/audit-reply-template.md`](../../_shared/pr-loop/audit-reply-template.md). For a body-only finding with no inline thread, post a top-level review reply that cites the new HEAD SHA.
33
+
34
+ **Thread resolution:** call `pull_request_review_write(method="resolve_thread", threadId=<PRRT node id>)` right after each reply. Harvest the thread node ids (`PRRT_…`) from `get_review_comments` at fetch time.
35
+
36
+ ## The unresolved-thread sweep (hard gate)
37
+
38
+ A caller advances a phase, records a clean SHA, or marks a PR ready only when the PR carries zero unresolved review threads.
39
+
40
+ ```
41
+ pull_request_read(method="get_review_comments") → filter threads where is_resolved == false
42
+ ```
43
+
44
+ - The filter is purely `is_resolved == false`. Author, anchor commit, and `is_outdated` play no part in the count.
45
+ - `is_outdated` is informational, not a skip flag. GitHub marks a thread outdated when its anchor line changes, yet the concern can still apply to current HEAD — the fix may have moved rather than landed. Verify each outdated thread against current HEAD like any other.
46
+ - Per unresolved thread: verify the concern against current HEAD. The concern holds → fix (this protocol) → reply → resolve. The concern does not hold on current HEAD → reply with a note that explains why → resolve.
47
+ - Code changed during the sweep → push and hand control back to the caller's re-entry phase. Only resolutions and no code → re-run the sweep and keep the caller's state.
48
+
49
+ ## Post-push obligations
50
+
51
+ Every push through this protocol:
52
+
53
+ 1. Re-resolve `current_head` — `git rev-parse HEAD` locally, and the PR `get` call for API-visible state.
54
+ 2. Reset the caller-named clean-SHA fields to null (`bugbot_clean_at`, `code_review_clean_at`, `copilot_clean_at` — whichever the caller tracks). A new HEAD invalidates every prior clean.
55
+ 3. Re-trigger reviewers per the caller's parameter — for Cursor Bugbot the `reviewer-gates` Bugbot flow, for Copilot the caller's request step. Audit-family callers (`bugteam`, `qbug`) skip re-triggering, since their next loop iteration is the reviewer.
56
+
57
+ ## Gotchas
58
+
59
+ - **Reply, then resolve, atomic per thread.** Batching every reply ahead of any resolve, or yielding to the orchestrator between the two, leaves threads half-addressed when a run dies mid-loop.
60
+ - **An unchanged HEAD after step 11 means no commit landed.** Exit `stuck — could not address findings` rather than report the findings as fixed.
61
+ - **A resolved thread with no reply reads as dismissed.** Reviewers and the humans reading the PR need the one-paragraph explanation the template carries.
62
+
63
+ ## Folder map
64
+
65
+ - `SKILL.md` — this file. The step sequence, reply template, and payload shapes live in `_shared/pr-loop/` (`fix-protocol.md`, `audit-reply-template.md`, `gh-payloads.md`); the reply fallback script lives in `pr-converge/scripts/`.
@@ -20,6 +20,8 @@ Three checks, in order; the first failure routes to the cloud transport:
20
20
 
21
21
  A read-scoped account passes checks 1 and 2 and fails check 3 — the PR-loop skills push fix commits, so `push: false` means the local path stalls at its first push while the MCP transport carries the run.
22
22
 
23
+ GitHub MCP substitution covers `gh` operations only. It does not make Claude-only slash commands (for example `/code-review`) runnable. Those steps go through the chain-spawn helper documented in [`worker-spawn.md`](../../_shared/pr-loop/worker-spawn.md#code-review-host-routing) (`detect_host_profile` + `invoke_code_review`). Transport (`gh` vs MCP) and harness (Claude vs third-party) are separate axes.
24
+
23
25
  ## Cloud transport workflow
24
26
 
25
27
  Copy this checklist and check off items as you complete them:
@@ -20,23 +20,24 @@ Every invocation carries the caller's identity (`--skill <caller>`, e.g. `pr-con
20
20
 
21
21
  ## Gate 1: Reviewer opt-out (`CLAUDE_REVIEWS_DISABLED`)
22
22
 
23
- The `CLAUDE_REVIEWS_DISABLED` environment variable is a comma-separated token list (case-insensitive, whitespace-tolerant). Three tokens exist:
23
+ The `CLAUDE_REVIEWS_DISABLED` environment variable is a comma-separated token list (case-insensitive, whitespace-tolerant). Four tokens exist:
24
24
 
25
25
  | Token | Disables |
26
26
  |---|---|
27
27
  | `bugteam` | The whole bug-audit family: `/bugteam`, `/qbug`, `/findbugs`, and audit dispatch in `/monitor-open-prs` |
28
28
  | `bugbot` | Cursor Bugbot triggering and polling |
29
29
  | `copilot` | GitHub Copilot review requests and polling |
30
+ | `codex` | Codex reviewer requests and polling |
30
31
 
31
32
  Cursor Bugbot is off by default: it runs only when `CLAUDE_REVIEWS_ENABLED` lists `bugbot`, and a `bugbot` token in `CLAUDE_REVIEWS_DISABLED` keeps it off even when the opt-in lists it.
32
33
 
33
34
  Run the shared parser — never an inline shell parse:
34
35
 
35
36
  ```bash
36
- python "$HOME/.claude/_shared/pr-loop/scripts/reviews_disabled.py" --reviewer <bugbot|bugteam|copilot>
37
+ python "$HOME/.claude/_shared/pr-loop/scripts/reviews_disabled.py" --reviewer <bugbot|bugteam|copilot|codex>
37
38
  ```
38
39
 
39
- - **Exit 0** — the named reviewer is disabled for this run (opted out, or, for Bugbot, off by default without the `CLAUDE_REVIEWS_ENABLED` opt-in). A skill whose whole run depends on that reviewer responds with its refusal line and stops. A copilot- or bugteam-dependent caller names the opt-out: `/<caller> is disabled via CLAUDE_REVIEWS_DISABLED.` A Bugbot-dependent caller off by default names the opt-in the run needs: `/<caller> is disabled: Cursor Bugbot needs a bugbot token in CLAUDE_REVIEWS_ENABLED.` A loop that merely includes the reviewer as one gate marks the reviewer down (`bugbot_down = true`, `copilot_down = true`) and continues on its remaining signals.
40
+ - **Exit 0** — the named reviewer is disabled for this run (opted out, or, for Bugbot, off by default without the `CLAUDE_REVIEWS_ENABLED` opt-in). A skill whose whole run depends on that reviewer responds with its refusal line and stops. A copilot- or bugteam-dependent caller names the opt-out: `/<caller> is disabled via CLAUDE_REVIEWS_DISABLED.` A Bugbot-dependent caller off by default names the opt-in the run needs: `/<caller> is disabled: Cursor Bugbot needs a bugbot token in CLAUDE_REVIEWS_ENABLED.` A loop that merely includes the reviewer as one gate marks the reviewer down (`bugbot_down = true`, `copilot_down = true`, `codex_down = true`) and continues on its remaining signals.
40
41
  - **Exit 1** — the reviewer is available; continue.
41
42
 
42
43
  ## Gate 2: Copilot quota pre-check (once per run)
@@ -93,11 +94,12 @@ When a reviewer is down, `check_convergence.py` must skip that reviewer's gate s
93
94
  |---|---|---|
94
95
  | Bugbot down or off | `--bugbot-down` | `bugbot` |
95
96
  | Copilot down or opted out | `--copilot-down` | `copilot` |
97
+ | Codex down or opted out | `--codex-down` | `codex` |
96
98
  | Bugteam CLEAN post blocked | `--bugteam-post-blocked` | `bugteam` |
97
99
 
98
- The caller passes the flag on its own `check_convergence.py` run. The flag alone does not reach the independent mark-ready blocker hook, which re-runs `check_convergence.py` with no flags on `gh pr ready`. Each flag also honors its token: `check_convergence.py` reads the same bypass from `CLAUDE_REVIEWS_DISABLED`. So export the matching token in the same shell before `gh pr ready`, and the hook's no-flag re-check inherits the bypass through the env. Combine tokens with commas when more than one reviewer is down (`CLAUDE_REVIEWS_DISABLED="copilot,bugteam"`).
100
+ The caller passes the flag on its own `check_convergence.py` run. The flag alone does not reach the independent mark-ready blocker hook, which re-runs `check_convergence.py` with no flags on `gh pr ready`. Each flag also honors its token: `check_convergence.py` reads the same bypass from `CLAUDE_REVIEWS_DISABLED`. So export the matching token in the same shell before `gh pr ready`, and the hook's no-flag re-check inherits the bypass through the env. Combine tokens with commas when more than one reviewer is down (`CLAUDE_REVIEWS_DISABLED="copilot,bugteam,codex"`).
99
101
 
100
- The `bugteam` token here means the bugteam CLEAN-review gate is skipped for this convergence check. It does not disable the bugbot or copilot gates: each token is scoped to its own reviewer.
102
+ The `bugteam` token here means the bugteam CLEAN-review gate is skipped for this convergence check. It does not disable the bugbot, copilot, or codex gates: each token is scoped to its own reviewer.
101
103
 
102
104
  ## Gotchas
103
105
 
@@ -84,7 +84,7 @@ In Process or a dedicated **Sub-skills** section:
84
84
 
85
85
  | Skill | When | Produces |
86
86
  |---|---|---|
87
- | `/pr-scope-resolve` | Step 1 — resolve the PR target | owner, repo, PR number, head ref |
87
+ | `/reviewer-gates` | Step 1 — gate external reviewers | opt-out, Copilot quota, Bugbot trigger decisions |
88
88
  | `/skill-writer` | Step 4 — author SKILL.md | skill package files |
89
89
 
90
90
  If a listed skill is not installed, respond: `[exact refusal or degrade line]`.
@@ -17,7 +17,7 @@ One warm, addressable advisor available at the strongest model tier the session
17
17
 
18
18
  **Detect the host profile first** (Host profiles in
19
19
  [`_shared/advisor/advisor-protocol.md`](../../_shared/advisor/advisor-protocol.md)
20
- — e.g. `ADVISOR_HOST_PROFILE` or `GROK_BUILD`). Do not start a model-floor
20
+ — e.g. `ADVISOR_HOST_PROFILE` or `THIRD_PARTY`). Do not start a model-floor
21
21
  walk until the host is known.
22
22
 
23
23
  This session is the shared advisor's sole consumer, so its model floor is
@@ -29,21 +29,25 @@ the CLI fallback — using `team-advisor-agent` as the name and this session as
29
29
  the only consumer (skip the "who you are and your assignment" opener in each
30
30
  consult; a single-consumer session doesn't need it).
31
31
 
32
- **Grok host:** use the self-as-advisor path in the shared protocol: this
33
- session answers ENDORSE / CORRECTION / PLAN / STOP itself. Do not spawn a
34
- Claude `session-advisor` subagent and do not walk the Claude multi-tier
35
- ladder.
32
+ **Third-party host:** bind a max-tier Claude advisor through the shared CLI Claude-chain
33
+ in the protocol (Fable max, then Opus max; `claude_chain_runner.py` walks
34
+ `~/.claude/claude-chain.json` for account usage failover). Consult via
35
+ `--resume <session_id>` on that bind. This session is the sole consumer of that
36
+ CLI advisor; skip the multi-consumer opener. When the chain cannot bind or
37
+ reply, fail closed and report to the user — do **not** answer ENDORSE /
38
+ CORRECTION / PLAN / STOP as this third-party session.
36
39
 
37
40
  ## Constraints
38
41
 
39
- - One `team-advisor-agent` per session, owned by this session for its whole
40
- lifecycle (spawn, drift-respawn, shutdown) see
42
+ - One advisor bind per session (`team-advisor-agent` on Claude; one CLI
43
+ `session_id` on a third-party host), owned by this session for its whole lifecycle
44
+ (spawn or CLI bind, drift re-bind, shutdown) — see
41
45
  [`_shared/advisor/advisor-protocol.md`](../../_shared/advisor/advisor-protocol.md).
42
- - Never spawn the warm agent, or its CLI fallback, at a tier below this
43
- session's own tier.
44
- - The warm agent (or its CLI equivalent) only answers. It never edits a
45
- file, never runs a build or test, and never posts anything on the
46
- session's behalf.
46
+ - Never bind the advisor, or its CLI path, at a tier below the protocol floor
47
+ for this host (Claude: this session's own tier; a third-party host: Opus floor
48
+ with Fable first).
49
+ - The advisor only answers. It never edits a file, never runs a build or
50
+ test, and never posts anything on the session's behalf.
47
51
 
48
52
  ## File Index
49
53
 
@@ -140,7 +140,8 @@
140
140
  Apply an outside-in BDD reasoning protocol before writing any code. Outside-in BDD is the
141
141
  required development protocol; apply it in place of any Red-Green-Refactor heuristic. The
142
142
  full anti-pattern catalog, Example Mapping algorithm, and solo-developer guidance live in
143
- the bdd-protocol skill; this section carries the core four-phase sequence.
143
+ the long-form BDD references (`~/.claude/docs/BDD_DISCOVERY_PROTOCOL.md`,
144
+ `~/.claude/docs/BDD_SCENARIO_QUALITY.md`); this section carries the core four-phase sequence.
144
145
 
145
146
  Deliberate Discovery. Before writing any specification or code, reason explicitly about
146
147
  what the code should do, what constraints apply, and what concrete examples demonstrate the
@@ -159,8 +160,9 @@
159
160
  it pass. Assess each green state for structural improvement; refactor when a specific
160
161
  naming, cohesion, or duplication problem is identified.
161
162
 
162
- Reference the bdd-protocol skill for Smart and Molak §7.6 patterns, the Example Mapping
163
- algorithm, and guidance on applying this protocol in a solo-developer context.
163
+ Reference `~/.claude/docs/BDD_SCENARIO_QUALITY.md` and `~/.claude/docs/BDD_DISCOVERY_PROTOCOL.md`
164
+ for Smart and Molak §7.6 patterns, the Example Mapping algorithm, and guidance on applying this
165
+ protocol in a solo-developer context.
164
166
  </behavior_protocol>
165
167
 
166
168
  <scope_discipline>
@@ -231,11 +233,10 @@
231
233
  </agent_workflow>
232
234
 
233
235
  <code_review_response>
234
- When responding to GitHub PR review feedback, follow this mandatory protocol using the
235
- pr-review-responder skill.
236
+ When responding to GitHub PR review feedback, follow this mandatory protocol.
236
237
 
237
238
  Fetch all reviewer comments before making any fixes. Obtain the full comment set from the
238
- PR using `gh pr view --comments` or the pr-review-responder skill.
239
+ PR using `gh pr view --comments`.
239
240
 
240
241
  Create a TodoWrite checklist with one item per comment.
241
242
 
@@ -1,32 +0,0 @@
1
- """Tests for validator path verification script."""
2
-
3
- import pytest
4
-
5
- from .verify_paths import extract_validator_paths
6
-
7
-
8
- def test_extract_validator_paths_finds_validator_references() -> None:
9
- """Test that validator references are extracted from markdown content."""
10
- content = """
11
- **Validator:** `validators/import_checks.py`
12
- Some text here.
13
- **Validator:** `validators/style_checks.py`
14
- """
15
-
16
- result = extract_validator_paths(content)
17
-
18
- assert "import_checks.py" in result
19
- assert "style_checks.py" in result
20
-
21
-
22
- def test_extract_validator_paths_deduplicates() -> None:
23
- """Test that duplicate validator references are deduplicated."""
24
- content = """
25
- **Validator:** `validators/import_checks.py`
26
- **Validator:** `validators/import_checks.py`
27
- **Validator:** `validators/import_checks.py`
28
- """
29
-
30
- result = extract_validator_paths(content)
31
-
32
- assert result.count("import_checks.py") == 1
@@ -1,57 +0,0 @@
1
- """Verify all validator paths referenced in SKILL.md exist."""
2
-
3
- import re
4
- import sys
5
- from pathlib import Path
6
-
7
-
8
- SKILL_MD_PATH = Path(__file__).parent.parent.parent / "skills" / "pr-review-responder" / "SKILL.md"
9
- VALIDATORS_DIR = Path(__file__).parent
10
-
11
-
12
- def extract_validator_paths(content: str) -> list[str]:
13
- """Extract validator file paths from SKILL.md content."""
14
- pattern = r"validators[/\\](\w+\.py)"
15
- matches = re.findall(pattern, content)
16
- return list(set(matches))
17
-
18
-
19
- def verify_validators() -> int:
20
- """Verify all referenced validators exist.
21
-
22
- Returns:
23
- Exit code: 0 if all exist, 1 if any missing
24
- """
25
- if not SKILL_MD_PATH.exists():
26
- print(f"ERROR: SKILL.md not found at {SKILL_MD_PATH}")
27
- return 1
28
-
29
- content = SKILL_MD_PATH.read_text(encoding="utf-8")
30
- referenced_validators = extract_validator_paths(content)
31
-
32
- print(f"Found {len(referenced_validators)} validator references in SKILL.md")
33
- print()
34
-
35
- missing = []
36
- for validator_file in sorted(referenced_validators):
37
- validator_path = VALIDATORS_DIR / validator_file
38
- if validator_path.exists():
39
- print(f" [OK] {validator_file}")
40
- else:
41
- print(f" [MISSING] {validator_file}")
42
- missing.append(validator_file)
43
-
44
- print()
45
-
46
- if missing:
47
- print(f"ERROR: {len(missing)} validator(s) missing:")
48
- for validator_file in missing:
49
- print(f" - {validator_file}")
50
- return 1
51
-
52
- print("All referenced validators exist.")
53
- return 0
54
-
55
-
56
- if __name__ == "__main__":
57
- sys.exit(verify_validators())