claude-dev-env 2.11.0 → 2.13.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 (203) hide show
  1. package/_shared/advisor/reference/sol-rung.md +5 -2
  2. package/_shared/advisor/reference/warm-up.md +1 -0
  3. package/_shared/advisor/scripts/codex_sol_advisor.py +96 -31
  4. package/_shared/advisor/scripts/config/advisor_scripts_constants/sol_advisor_constants.py +5 -0
  5. package/_shared/advisor/scripts/tests/test_codex_sol_advisor.py +173 -11
  6. package/_shared/pr-loop/scripts/code_rules_gate.py +2 -3
  7. package/_shared/pr-loop/scripts/test_code_rules_gate.py +0 -26
  8. package/agents/CLAUDE.md +1 -2
  9. package/agents/pr-description-writer.md +11 -81
  10. package/bin/install.mjs +48 -9
  11. package/bin/install.prune.test.mjs +26 -0
  12. package/bin/install.settings-defaults.test.mjs +60 -33
  13. package/bin/install.test.mjs +2 -4
  14. package/commands/CLAUDE.md +1 -0
  15. package/commands/sr-loop.md +52 -0
  16. package/docs/CLAUDE.md +0 -1
  17. package/docs/references/CLAUDE.md +0 -1
  18. package/hooks/CLAUDE.md +1 -1
  19. package/hooks/blocking/CLAUDE.md +2 -27
  20. package/hooks/blocking/config/CLAUDE.md +1 -13
  21. package/hooks/blocking/conventional_pr_title_gate.py +1 -2
  22. package/hooks/blocking/send_user_file_open_locally_blocker.py +1 -1
  23. package/hooks/blocking/stop_dispatcher.py +4 -4
  24. package/hooks/blocking/test_bash_pre_tool_use_dispatcher.py +0 -3
  25. package/hooks/blocking/test_pre_tool_use_dispatcher.py +6 -7
  26. package/hooks/blocking/test_send_user_file_open_locally_blocker.py +4 -3
  27. package/hooks/blocking/test_shared_stdin_adoption.py +0 -2
  28. package/hooks/diagnostic/CLAUDE.md +3 -3
  29. package/hooks/diagnostic/hook_log_extractor.py +2 -36
  30. package/hooks/diagnostic/hook_log_stop_wrapper.py +6 -155
  31. package/hooks/diagnostic/test_hook_log_extractor.py +8 -21
  32. package/hooks/diagnostic/test_hook_log_stop_wrapper.py +3 -331
  33. package/hooks/git-hooks/git_hooks_constants/__init__.py +0 -6
  34. package/hooks/git-hooks/pre_push.py +3 -85
  35. package/hooks/git-hooks/test_pre_push.py +0 -130
  36. package/hooks/hooks.json +0 -35
  37. package/hooks/hooks_constants/CLAUDE.md +0 -9
  38. package/hooks/hooks_constants/bash_pre_tool_use_dispatcher_constants.py +0 -11
  39. package/hooks/hooks_constants/convergence_branch_constants.py +0 -1
  40. package/hooks/hooks_constants/fable_spawn_gate_constants.py +3 -4
  41. package/hooks/hooks_constants/pre_tool_use_dispatcher_constants.py +0 -8
  42. package/hooks/hooks_constants/send_user_file_open_locally_blocker_constants.py +1 -6
  43. package/hooks/hooks_constants/stop_dispatcher_constants.py +0 -1
  44. package/hooks/hooks_constants/test_bash_pre_tool_use_dispatcher_constants.py +1 -26
  45. package/hooks/hooks_constants/test_pre_tool_use_dispatcher_constants.py +0 -5
  46. package/hooks/hooks_constants/test_stop_dispatcher_constants.py +0 -1
  47. package/hooks/lifecycle/CLAUDE.md +1 -3
  48. package/package.json +1 -1
  49. package/rules/CLAUDE.md +0 -2
  50. package/rules/gh-cli-conventions.md +0 -1
  51. package/rules/git-workflow.md +1 -3
  52. package/scripts/CLAUDE.md +0 -1
  53. package/scripts/_code_review_test_support.py +0 -95
  54. package/scripts/dev_env_scripts_constants/code_review_constants.py +9 -98
  55. package/scripts/dev_env_scripts_constants/test_code_review_constants.py +1 -44
  56. package/scripts/invoke_code_review.py +8 -451
  57. package/scripts/test_invoke_code_review.py +5 -61
  58. package/scripts/test_invoke_code_review_cli.py +1 -45
  59. package/scripts/test_invoke_code_review_contract.py +1 -118
  60. package/settings.json +1 -10
  61. package/skills/CLAUDE.md +8 -0
  62. package/skills/autoconverge/reference/CLAUDE.md +1 -1
  63. package/skills/autoconverge/reference/convergence.md +7 -7
  64. package/skills/autoconverge/reference/gotchas.md +3 -10
  65. package/skills/autoconverge/workflow/converge.contract.test.mjs +53 -1388
  66. package/skills/autoconverge/workflow/converge.copilot-gate.test.mjs +4 -3
  67. package/skills/autoconverge/workflow/converge.fix-recovery.test.mjs +33 -493
  68. package/skills/autoconverge/workflow/converge.merge-conflict.test.mjs +15 -97
  69. package/skills/autoconverge/workflow/converge.mjs +201 -238
  70. package/skills/autoconverge/workflow/converge.precatch.test.mjs +1 -1
  71. package/skills/bugteam/CONSTRAINTS.md +1 -1
  72. package/skills/bugteam/SKILL.md +9 -0
  73. package/skills/bugteam/reference/audit-and-teammates.md +10 -6
  74. package/skills/bugteam/test_skill_additions.py +9 -0
  75. package/skills/comments/SKILL.md +65 -0
  76. package/skills/descriptions/SKILL.md +51 -0
  77. package/skills/emergencies/SKILL.md +42 -0
  78. package/skills/imagegen/SKILL.md +21 -0
  79. package/skills/imagegen/scripts/config/__init__.py +1 -0
  80. package/skills/imagegen/scripts/config/constants.py +28 -0
  81. package/skills/imagegen/scripts/imagegen.py +45 -0
  82. package/skills/imagegen/scripts/imagegen_core.py +528 -0
  83. package/skills/imagegen/scripts/test_imagegen.py +204 -0
  84. package/skills/orchestrator/SKILL.md +2 -4
  85. package/skills/plan-to-pr/SKILL.md +6 -7
  86. package/skills/plan-to-pr/reference/final-validation-tasks.md +1 -1
  87. package/skills/plan-to-pr/reference/process-inventory.md +2 -2
  88. package/skills/plan-to-pr/reference/review-loop.md +2 -2
  89. package/skills/plan-to-pr/reference/run-record.schema.json +1 -1
  90. package/skills/plan-to-pr/reference/task-seeds.md +1 -1
  91. package/skills/plan-to-pr/reference/task-ticket.md +3 -4
  92. package/skills/plan-to-pr/scripts/config/constants.py +1 -2
  93. package/skills/plan-to-pr/scripts/test_validate_protocol.py +1 -1
  94. package/skills/plan-to-pr/test_skill_contract.py +2 -2
  95. package/skills/pr-converge/SKILL.md +13 -16
  96. package/skills/pr-converge/reference/progress-checklist.md +6 -5
  97. package/skills/pr-converge/reference/state-schema.md +1 -27
  98. package/skills/pr-loop-cloud-transport/SKILL.md +1 -1
  99. package/skills/pr-loop-cloud-transport/reference/identity-and-hooks.md +3 -3
  100. package/skills/pr-loop-lifecycle/SKILL.md +1 -1
  101. package/skills/pr-loop-lifecycle/reference/teardown-publish-permissions.md +1 -1
  102. package/skills/prototype/SKILL.md +4 -4
  103. package/skills/prototype/reference/honest-limitations.md +4 -4
  104. package/skills/prototype/reference/promotion-tasks.md +2 -2
  105. package/skills/prototype/workflows/promotion.md +4 -6
  106. package/skills/reviews/SKILL.md +85 -0
  107. package/skills/small-cl/SKILL.md +52 -0
  108. package/skills/usage-pause/SKILL.md +1 -1
  109. package/skills/usage-pause/scripts/resolve_usage_window.py +32 -4
  110. package/skills/usage-pause/scripts/test_resolve_usage_window.py +26 -0
  111. package/skills/usage-pause/scripts/usage_pause_constants/resolve_usage_window_constants.py +3 -1
  112. package/agents/code-verifier.md +0 -74
  113. package/docs/PR_DESCRIPTION_GUIDE.md +0 -157
  114. package/docs/references/code-review-enforcement.md +0 -132
  115. package/hooks/blocking/code_review_enforcement_config_bootstrap.py +0 -53
  116. package/hooks/blocking/code_review_gate_deny.py +0 -74
  117. package/hooks/blocking/code_review_pr_create_gate.py +0 -198
  118. package/hooks/blocking/code_review_push_gate.py +0 -145
  119. package/hooks/blocking/code_review_stamp_directory_write_blocker.py +0 -348
  120. package/hooks/blocking/code_review_stamp_store.py +0 -233
  121. package/hooks/blocking/code_review_stamp_write_blocker_parts/__init__.py +0 -7
  122. package/hooks/blocking/code_review_stamp_write_blocker_parts/conftest.py +0 -15
  123. package/hooks/blocking/code_review_stamp_write_blocker_parts/obfuscated_stamp_path_reference.py +0 -212
  124. package/hooks/blocking/code_review_stamp_write_blocker_parts/split_directory_change_into_stamp.py +0 -138
  125. package/hooks/blocking/code_review_stamp_write_blocker_parts/test_obfuscated_stamp_path_reference.py +0 -49
  126. package/hooks/blocking/code_review_stamp_write_blocker_parts/test_split_directory_change_into_stamp.py +0 -38
  127. package/hooks/blocking/code_verifier_spawn_preflight_gate.py +0 -483
  128. package/hooks/blocking/config/code_review_enforcement_constants.py +0 -143
  129. package/hooks/blocking/config/test_code_review_enforcement_constants.py +0 -166
  130. package/hooks/blocking/config/verified_commit_constants.py +0 -160
  131. package/hooks/blocking/config/verified_commit_context_constants.py +0 -21
  132. package/hooks/blocking/config/verified_commit_gate_output_constants.py +0 -14
  133. package/hooks/blocking/conftest.py +0 -123
  134. package/hooks/blocking/convergence_gate_blocker.py +0 -310
  135. package/hooks/blocking/pr_converge_bugteam_enforcer.py +0 -170
  136. package/hooks/blocking/pr_description_body_audit.py +0 -148
  137. package/hooks/blocking/pr_description_command_parser.py +0 -237
  138. package/hooks/blocking/pr_description_enforcer.py +0 -227
  139. package/hooks/blocking/pr_description_pr_number.py +0 -155
  140. package/hooks/blocking/pr_description_proof_of_work.py +0 -385
  141. package/hooks/blocking/pr_description_readability.py +0 -364
  142. package/hooks/blocking/reviewer_spawn_gate.py +0 -182
  143. package/hooks/blocking/test_code_review_enforcement_config_bootstrap.py +0 -62
  144. package/hooks/blocking/test_code_review_gate_deny.py +0 -54
  145. package/hooks/blocking/test_code_review_pr_create_gate.py +0 -199
  146. package/hooks/blocking/test_code_review_push_gate.py +0 -205
  147. package/hooks/blocking/test_code_review_stamp_directory_write_blocker.py +0 -199
  148. package/hooks/blocking/test_code_review_stamp_store.py +0 -205
  149. package/hooks/blocking/test_code_verifier_spawn_preflight_gate.py +0 -710
  150. package/hooks/blocking/test_code_verifier_tools_contract.py +0 -28
  151. package/hooks/blocking/test_convergence_gate_blocker.py +0 -428
  152. package/hooks/blocking/test_pr_converge_bugteam_enforcer.py +0 -311
  153. package/hooks/blocking/test_pr_converge_bugteam_enforcer_state_tolerance.py +0 -184
  154. package/hooks/blocking/test_pr_description_enforcer.py +0 -221
  155. package/hooks/blocking/test_pr_description_enforcer_body_audit.py +0 -247
  156. package/hooks/blocking/test_pr_description_enforcer_body_rules.py +0 -493
  157. package/hooks/blocking/test_pr_description_enforcer_command_parser.py +0 -366
  158. package/hooks/blocking/test_pr_description_enforcer_pr_number.py +0 -159
  159. package/hooks/blocking/test_pr_description_enforcer_proof_gate.py +0 -175
  160. package/hooks/blocking/test_pr_description_enforcer_readability.py +0 -443
  161. package/hooks/blocking/test_pr_description_proof_of_work.py +0 -313
  162. package/hooks/blocking/test_reviewer_spawn_gate.py +0 -230
  163. package/hooks/blocking/test_verdict_directory_write_blocker.py +0 -804
  164. package/hooks/blocking/test_verification_verdict_store.py +0 -974
  165. package/hooks/blocking/test_verified_commit_config_bootstrap.py +0 -67
  166. package/hooks/blocking/test_verified_commit_docs_delta.py +0 -176
  167. package/hooks/blocking/test_verified_commit_gate.py +0 -581
  168. package/hooks/blocking/test_verified_commit_gate_additional_context.py +0 -134
  169. package/hooks/blocking/test_verified_commit_message_accuracy_blocker.py +0 -131
  170. package/hooks/blocking/test_verifier_verdict_minter.py +0 -299
  171. package/hooks/blocking/tests/test_verified_commit_gate.py +0 -41
  172. package/hooks/blocking/verdict_directory_write_blocker.py +0 -687
  173. package/hooks/blocking/verification_verdict_store.py +0 -1039
  174. package/hooks/blocking/verified_commit_config_bootstrap.py +0 -63
  175. package/hooks/blocking/verified_commit_gate.py +0 -113
  176. package/hooks/blocking/verified_commit_gate_parts/CLAUDE.md +0 -28
  177. package/hooks/blocking/verified_commit_gate_parts/__init__.py +0 -1
  178. package/hooks/blocking/verified_commit_gate_parts/command_tokenization.py +0 -174
  179. package/hooks/blocking/verified_commit_gate_parts/deny_payload.py +0 -53
  180. package/hooks/blocking/verified_commit_gate_parts/deny_reason.py +0 -80
  181. package/hooks/blocking/verified_commit_gate_parts/directory_resolution.py +0 -170
  182. package/hooks/blocking/verified_commit_gate_parts/gated_invocations.py +0 -217
  183. package/hooks/blocking/verified_commit_gate_parts/tests/conftest.py +0 -10
  184. package/hooks/blocking/verified_commit_gate_parts/tests/test_command_tokenization.py +0 -94
  185. package/hooks/blocking/verified_commit_gate_parts/tests/test_deny_payload.py +0 -17
  186. package/hooks/blocking/verified_commit_gate_parts/tests/test_deny_reason.py +0 -38
  187. package/hooks/blocking/verified_commit_gate_parts/tests/test_directory_resolution.py +0 -71
  188. package/hooks/blocking/verified_commit_gate_parts/tests/test_gated_invocations.py +0 -96
  189. package/hooks/blocking/verified_commit_message_accuracy_blocker.py +0 -167
  190. package/hooks/blocking/verifier_verdict_minter.py +0 -280
  191. package/hooks/hooks_constants/code_verifier_spawn_preflight_gate_constants.py +0 -64
  192. package/hooks/hooks_constants/convergence_gate_blocker_constants.py +0 -53
  193. package/hooks/hooks_constants/pr_converge_bugteam_enforcer_constants.py +0 -55
  194. package/hooks/hooks_constants/pr_converge_bugteam_enforcer_state.py +0 -67
  195. package/hooks/hooks_constants/pr_description_enforcer_constants.py +0 -167
  196. package/hooks/hooks_constants/pr_description_proof_of_work_constants.py +0 -107
  197. package/hooks/hooks_constants/reviewer_spawn_gate_constants.py +0 -41
  198. package/hooks/hooks_constants/test_pr_description_enforcer_constants.py +0 -292
  199. package/hooks/lifecycle/pr_converge_bugteam_skill_tracker.py +0 -198
  200. package/hooks/lifecycle/test_pr_converge_bugteam_skill_tracker.py +0 -283
  201. package/rules/proof-of-work-pr-comments.md +0 -22
  202. package/rules/verified-commit-gate-skip.md +0 -4
  203. package/scripts/Show-Asset.ps1 +0 -106
@@ -17,8 +17,6 @@ SCRIPT_DIRECTORY = Path(__file__).resolve().parent
17
17
  REAL_RUN_GIT_TEXT_COMMAND = pre_push.run_git_text_command
18
18
 
19
19
 
20
- CODE_REVIEW_ENFORCEMENT_ENV_VAR: str = "CLAUDE_CODE_REVIEW_ENFORCEMENT"
21
- ENFORCEMENT_CONSTANTS_MODULE_NAME: str = "config.code_review_enforcement_constants"
22
20
  ALL_ZEROS_OBJECT_NAME: str = "0" * 40
23
21
  NON_ZERO_LOCAL_SHA: str = "a" * 40
24
22
  NON_ZERO_REMOTE_SHA_ONE: str = "1" * 40
@@ -111,7 +109,6 @@ def _write_gate_that_allows_every_push(
111
109
  passing_gate_path = tmp_path / "code_rules_gate.py"
112
110
  passing_gate_path.write_text("import sys\nsys.exit(0)\n", encoding="utf-8")
113
111
  monkeypatch.setenv("CODE_RULES_GATE_PATH", str(passing_gate_path))
114
- _isolate_code_review_gate(tmp_path, monkeypatch)
115
112
  monkeypatch.setattr(sys, "stdin", io.StringIO(NEW_BRANCH_PUSH_STDIN))
116
113
 
117
114
 
@@ -244,11 +241,6 @@ def resolve_remote_head_reference(monkeypatch: pytest.MonkeyPatch) -> None:
244
241
  monkeypatch.setattr(pre_push, "run_git_text_command", fake_run_git_text_command)
245
242
 
246
243
 
247
- def _isolate_code_review_gate(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
248
- monkeypatch.setenv(
249
- "CODE_REVIEW_PUSH_GATE_PATH", str(tmp_path / "no_code_review_gate.py")
250
- )
251
-
252
244
 
253
245
  def test_resolve_base_reference_from_stdin_uses_remote_object_when_non_zero() -> None:
254
246
  stdin_text = (
@@ -295,7 +287,6 @@ def test_main_exits_zero_when_gate_script_missing(
295
287
  "CODE_RULES_GATE_PATH",
296
288
  str(tmp_path / "does_not_exist.py"),
297
289
  )
298
- _isolate_code_review_gate(tmp_path, monkeypatch)
299
290
  monkeypatch.setattr(sys, "stdin", io.StringIO(""))
300
291
 
301
292
  exit_code = pre_push.main()
@@ -317,7 +308,6 @@ def test_main_invokes_gate_with_resolved_base_reference(
317
308
  encoding="utf-8",
318
309
  )
319
310
  monkeypatch.setenv("CODE_RULES_GATE_PATH", str(recording_gate_script_path))
320
- _isolate_code_review_gate(tmp_path, monkeypatch)
321
311
  _isolate_from_default_branch_refs(tmp_path, monkeypatch)
322
312
  remote_sha = "9" * 40
323
313
  monkeypatch.setattr(
@@ -345,7 +335,6 @@ def test_main_passes_the_pushed_remote_name_to_base_resolution(
345
335
  # No default-branch ref so the gate base is the stdin remote object, not a
346
336
  # merge-base skip; usable-base resolution then sees the pushed remote name.
347
337
  _isolate_repository_and_write_passing_code_rules_gate(tmp_path, monkeypatch)
348
- _isolate_code_review_gate(tmp_path, monkeypatch)
349
338
  all_recorded_remote_names: list[str] = []
350
339
 
351
340
  def recording_resolve_usable_base_reference(
@@ -566,7 +555,6 @@ def test_invoke_gate_uses_resolved_path(
566
555
  symlink_gate_path.symlink_to(real_gate_path)
567
556
  resolved_path = symlink_gate_path.resolve()
568
557
  monkeypatch.setenv("CODE_RULES_GATE_PATH", str(symlink_gate_path))
569
- _isolate_code_review_gate(tmp_path, monkeypatch)
570
558
  _isolate_from_default_branch_refs(tmp_path, monkeypatch)
571
559
  monkeypatch.setattr(sys, "stdin", io.StringIO(
572
560
  f"refs/heads/feature {NON_ZERO_LOCAL_SHA} refs/heads/feature {NON_ZERO_REMOTE_SHA_ONE}\n"
@@ -684,7 +672,6 @@ def test_main_allows_main_onto_main_push(
684
672
  passing_gate_path = tmp_path / "gate.py"
685
673
  passing_gate_path.write_text("import sys\nsys.exit(0)\n", encoding="utf-8")
686
674
  monkeypatch.setenv("CODE_RULES_GATE_PATH", str(passing_gate_path))
687
- _isolate_code_review_gate(tmp_path, monkeypatch)
688
675
  monkeypatch.setattr(
689
676
  sys,
690
677
  "stdin",
@@ -698,8 +685,6 @@ def test_main_allows_main_onto_main_push(
698
685
  assert exit_code == 0
699
686
 
700
687
 
701
- CODE_REVIEW_STUB_BLOCK_REASON: str = "CODE_REVIEW_STUB_BLOCK_REASON"
702
-
703
688
 
704
689
  def _write_passing_code_rules_gate(
705
690
  tmp_path: Path, monkeypatch: pytest.MonkeyPatch
@@ -725,83 +710,6 @@ def _isolate_repository_and_write_passing_code_rules_gate(
725
710
  _write_passing_code_rules_gate(tmp_path, monkeypatch)
726
711
 
727
712
 
728
- def _write_code_review_gate_stub(tmp_path: Path, returned_reason_literal: str) -> Path:
729
- stub_gate_path = tmp_path / "code_review_push_gate.py"
730
- stub_gate_path.write_text(
731
- "def deny_reason_for_directory(target_directory):\n"
732
- f" return {returned_reason_literal}\n",
733
- encoding="utf-8",
734
- )
735
- return stub_gate_path
736
-
737
-
738
- def test_main_blocks_when_code_review_gate_returns_reason(
739
- tmp_path: Path,
740
- monkeypatch: pytest.MonkeyPatch,
741
- capsys: pytest.CaptureFixture[str],
742
- ) -> None:
743
- _isolate_repository_and_write_passing_code_rules_gate(tmp_path, monkeypatch)
744
- stub_gate_path = _write_code_review_gate_stub(
745
- tmp_path, repr(CODE_REVIEW_STUB_BLOCK_REASON)
746
- )
747
- monkeypatch.setenv("CODE_REVIEW_PUSH_GATE_PATH", str(stub_gate_path))
748
-
749
- exit_code = pre_push.main()
750
-
751
- assert exit_code == git_hooks_constants.CODE_REVIEW_STAMP_BLOCK_EXIT_CODE
752
- captured = capsys.readouterr()
753
- assert CODE_REVIEW_STUB_BLOCK_REASON in captured.err
754
-
755
-
756
- def test_main_allows_when_code_review_gate_returns_none(
757
- tmp_path: Path,
758
- monkeypatch: pytest.MonkeyPatch,
759
- ) -> None:
760
- _isolate_repository_and_write_passing_code_rules_gate(tmp_path, monkeypatch)
761
- stub_gate_path = _write_code_review_gate_stub(tmp_path, "None")
762
- monkeypatch.setenv("CODE_REVIEW_PUSH_GATE_PATH", str(stub_gate_path))
763
-
764
- exit_code = pre_push.main()
765
-
766
- assert exit_code == 0
767
-
768
-
769
- def test_main_code_review_check_fails_open_when_gate_module_absent(
770
- tmp_path: Path,
771
- monkeypatch: pytest.MonkeyPatch,
772
- ) -> None:
773
- _isolate_repository_and_write_passing_code_rules_gate(tmp_path, monkeypatch)
774
- monkeypatch.setenv(
775
- "CODE_REVIEW_PUSH_GATE_PATH", str(tmp_path / "does_not_exist.py")
776
- )
777
-
778
- exit_code = pre_push.main()
779
-
780
- assert exit_code == 0
781
-
782
-
783
- def test_main_allows_deletion_push_even_when_code_review_gate_would_block(
784
- tmp_path: Path,
785
- monkeypatch: pytest.MonkeyPatch,
786
- ) -> None:
787
- passing_gate_path = tmp_path / "code_rules_gate.py"
788
- passing_gate_path.write_text("import sys\nsys.exit(0)\n", encoding="utf-8")
789
- monkeypatch.setenv("CODE_RULES_GATE_PATH", str(passing_gate_path))
790
- stub_gate_path = _write_code_review_gate_stub(
791
- tmp_path, repr(CODE_REVIEW_STUB_BLOCK_REASON)
792
- )
793
- monkeypatch.setenv("CODE_REVIEW_PUSH_GATE_PATH", str(stub_gate_path))
794
- deletion_stdin = (
795
- f"refs/heads/feature {ALL_ZEROS_OBJECT_NAME} "
796
- f"refs/heads/feature {ALL_ZEROS_OBJECT_NAME}\n"
797
- )
798
- monkeypatch.setattr(sys, "stdin", io.StringIO(deletion_stdin))
799
-
800
- exit_code = pre_push.main()
801
-
802
- assert exit_code == 0
803
-
804
-
805
713
  DEFAULT_BRANCH_NAME: str = "main"
806
714
  FEATURE_BRANCH_NAME: str = "feature/example"
807
715
  UNPROTECTED_DEFAULT_BRANCH_NAME: str = "develop"
@@ -1267,7 +1175,6 @@ def test_main_allows_the_push_when_origin_head_names_an_absent_reference(
1267
1175
  encoding="utf-8",
1268
1176
  )
1269
1177
  monkeypatch.setenv("CODE_RULES_GATE_PATH", str(recording_gate_script_path))
1270
- _isolate_code_review_gate(tmp_path, monkeypatch)
1271
1178
  monkeypatch.chdir(repository)
1272
1179
  monkeypatch.setattr(
1273
1180
  sys,
@@ -1307,7 +1214,6 @@ def test_main_skips_the_gate_when_no_merge_base_resolves(
1307
1214
  encoding="utf-8",
1308
1215
  )
1309
1216
  monkeypatch.setenv("CODE_RULES_GATE_PATH", str(recording_gate_script_path))
1310
- _isolate_code_review_gate(tmp_path, monkeypatch)
1311
1217
  monkeypatch.chdir(repository)
1312
1218
  monkeypatch.setattr(
1313
1219
  sys,
@@ -1342,7 +1248,6 @@ def test_main_allows_default_branch_file_the_rebase_replayed_onto(
1342
1248
  )
1343
1249
  _set_origin_head(repository, ORIGIN_DEFAULT_BRANCH_REFERENCE)
1344
1250
  _write_diff_scoped_gate(tmp_path, monkeypatch)
1345
- _isolate_code_review_gate(tmp_path, monkeypatch)
1346
1251
  monkeypatch.chdir(repository)
1347
1252
  monkeypatch.setattr(
1348
1253
  sys,
@@ -1370,7 +1275,6 @@ def test_main_blocks_violation_the_branch_itself_adds(
1370
1275
  )
1371
1276
  _set_origin_head(repository, ORIGIN_DEFAULT_BRANCH_REFERENCE)
1372
1277
  _write_diff_scoped_gate(tmp_path, monkeypatch)
1373
- _isolate_code_review_gate(tmp_path, monkeypatch)
1374
1278
  monkeypatch.chdir(repository)
1375
1279
  monkeypatch.setattr(
1376
1280
  sys,
@@ -1407,7 +1311,6 @@ def test_main_uses_remote_object_when_no_default_branch_reference_resolves(
1407
1311
  encoding="utf-8",
1408
1312
  )
1409
1313
  monkeypatch.setenv("CODE_RULES_GATE_PATH", str(recording_gate_script_path))
1410
- _isolate_code_review_gate(tmp_path, monkeypatch)
1411
1314
  monkeypatch.chdir(repository)
1412
1315
  monkeypatch.setattr(
1413
1316
  sys,
@@ -1446,7 +1349,6 @@ def test_main_uses_remote_object_when_the_default_branch_is_pushed(
1446
1349
  )
1447
1350
  _set_origin_head(repository, ORIGIN_DEFAULT_BRANCH_REFERENCE)
1448
1351
  _write_diff_scoped_gate(tmp_path, monkeypatch)
1449
- _isolate_code_review_gate(tmp_path, monkeypatch)
1450
1352
  monkeypatch.chdir(repository)
1451
1353
  monkeypatch.setattr(
1452
1354
  sys,
@@ -1481,7 +1383,6 @@ def test_main_uses_merge_base_when_a_default_named_local_branch_updates_a_topic_
1481
1383
  )
1482
1384
  _set_origin_head(repository, ORIGIN_UNPROTECTED_DEFAULT_BRANCH_REFERENCE)
1483
1385
  _write_diff_scoped_gate(tmp_path, monkeypatch)
1484
- _isolate_code_review_gate(tmp_path, monkeypatch)
1485
1386
  monkeypatch.chdir(repository)
1486
1387
  monkeypatch.setattr(
1487
1388
  sys,
@@ -1517,7 +1418,6 @@ def test_main_uses_remote_object_when_a_renamed_local_branch_updates_the_default
1517
1418
  )
1518
1419
  _set_origin_head(repository, ORIGIN_UNPROTECTED_DEFAULT_BRANCH_REFERENCE)
1519
1420
  _write_diff_scoped_gate(tmp_path, monkeypatch)
1520
- _isolate_code_review_gate(tmp_path, monkeypatch)
1521
1421
  monkeypatch.chdir(repository)
1522
1422
  monkeypatch.setattr(
1523
1423
  sys,
@@ -1547,7 +1447,6 @@ def test_main_reads_default_branch_tracking_reference_when_origin_head_is_unset(
1547
1447
  branch_file_name=BRANCH_FILE_NAME,
1548
1448
  )
1549
1449
  _write_diff_scoped_gate(tmp_path, monkeypatch)
1550
- _isolate_code_review_gate(tmp_path, monkeypatch)
1551
1450
  monkeypatch.chdir(repository)
1552
1451
  monkeypatch.setattr(
1553
1452
  sys,
@@ -1575,7 +1474,6 @@ def test_main_skips_a_deletion_line_to_reach_the_branch_update(
1575
1474
  )
1576
1475
  _set_origin_head(repository, ORIGIN_DEFAULT_BRANCH_REFERENCE)
1577
1476
  _write_diff_scoped_gate(tmp_path, monkeypatch)
1578
- _isolate_code_review_gate(tmp_path, monkeypatch)
1579
1477
  monkeypatch.chdir(repository)
1580
1478
  deletion_line = (
1581
1479
  f"(delete) {ALL_ZEROS_OBJECT_NAME} refs/heads/retired {NON_ZERO_REMOTE_SHA_ONE}\n"
@@ -1594,31 +1492,3 @@ def test_main_skips_a_deletion_line_to_reach_the_branch_update(
1594
1492
  exit_code = pre_push.main()
1595
1493
 
1596
1494
  assert exit_code == 0
1597
-
1598
-
1599
- def test_main_allows_when_code_review_enforcement_flag_is_off(
1600
- tmp_path: Path,
1601
- monkeypatch: pytest.MonkeyPatch,
1602
- ) -> None:
1603
- """Native pre-push honors the real gate with enforcement off.
1604
-
1605
- Points at the production push gate (not a reason stub). The gate resolves
1606
- its flag when its config module first executes, so this test clears the
1607
- environment variable and evicts that one module if a sibling suite cached
1608
- it earlier in the same session. The gate then returns no deny reason and
1609
- the backstop allows the push.
1610
- """
1611
- monkeypatch.delenv(CODE_REVIEW_ENFORCEMENT_ENV_VAR, raising=False)
1612
- monkeypatch.delitem(sys.modules, ENFORCEMENT_CONSTANTS_MODULE_NAME, raising=False)
1613
- _isolate_repository_and_write_passing_code_rules_gate(tmp_path, monkeypatch)
1614
- real_gate_path = (
1615
- Path(__file__).resolve().parent.parent
1616
- / "blocking"
1617
- / "code_review_push_gate.py"
1618
- )
1619
- assert real_gate_path.is_file()
1620
- monkeypatch.setenv("CODE_REVIEW_PUSH_GATE_PATH", str(real_gate_path))
1621
-
1622
- exit_code = pre_push.main()
1623
-
1624
- assert exit_code == 0
package/hooks/hooks.json CHANGED
@@ -42,16 +42,6 @@
42
42
  }
43
43
  ]
44
44
  },
45
- {
46
- "matcher": "mcp__plugin_github_github__create_pull_request",
47
- "hooks": [
48
- {
49
- "type": "command",
50
- "command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/blocking/code_review_pr_create_gate.py",
51
- "timeout": 20
52
- }
53
- ]
54
- },
55
45
  {
56
46
  "matcher": "mcp__plugin_github_github__.*",
57
47
  "hooks": [
@@ -67,24 +57,9 @@
67
57
  }
68
58
  ]
69
59
  },
70
- {
71
- "matcher": "Agent",
72
- "hooks": [
73
- {
74
- "type": "command",
75
- "command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/blocking/pr_converge_bugteam_enforcer.py",
76
- "timeout": 10
77
- }
78
- ]
79
- },
80
60
  {
81
61
  "matcher": "Agent|Task",
82
62
  "hooks": [
83
- {
84
- "type": "command",
85
- "command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/blocking/code_verifier_spawn_preflight_gate.py",
86
- "timeout": 30
87
- },
88
63
  {
89
64
  "type": "command",
90
65
  "command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/blocking/fable_spawn_gate.py",
@@ -102,16 +77,6 @@
102
77
  }
103
78
  ]
104
79
  },
105
- {
106
- "matcher": "Skill",
107
- "hooks": [
108
- {
109
- "type": "command",
110
- "command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/lifecycle/pr_converge_bugteam_skill_tracker.py",
111
- "timeout": 10
112
- }
113
- ]
114
- },
115
80
  {
116
81
  "matcher": "AskUserQuestion",
117
82
  "hooks": [
@@ -18,10 +18,7 @@ Shared constant modules imported by hooks throughout the `hooks/` tree. Each fil
18
18
  | `enter_worktree_prefetch_constants.py` | Tool name, origin-remote ref names, and git-command timeouts for the EnterWorktree origin-prefetch hook |
19
19
  | `env_var_table_code_drift_constants.py` | Table patterns, env-var-name and code-file recognizers, scan budget, and block-message text for the env-var-table code-drift blocker |
20
20
  | `code_rules_path_utils_constants.py` | Path-matching helpers used by the code-rules check modules |
21
- | `code_verifier_spawn_preflight_gate_constants.py` | Subagent type, merge-tree command flags, timeouts, and deny-message text for the code-verifier spawn pre-flight gate |
22
21
  | `command_dispatch_constants.py` | Command-word regex, command-key access pattern, tokenization pattern, and anchors for the unanchored command-dispatch meta-gate |
23
- | `convergence_branch_constants.py` | Branch and worktree naming patterns for the convergence gate |
24
- | `convergence_gate_blocker_constants.py` | The full-PR-URL and `--repo`/`-R` flag parse patterns that key the convergence gate to the PR its command names |
25
22
  | `conventional_pr_title_gate_constants.py` | Bash tool name, gh executable basenames and pr create/edit subcommand tokens, title/repo flag names, semantic-title-CI workflow markers, the Conventional Commits type list and title pattern, the semantic-pull-request action `types:` input pattern, and block-message text for the conventional-PR-title gate |
26
23
  | `dead_argparse_argument_constants.py` | Patterns for detecting unused argparse arguments |
27
24
  | `dead_config_field_constants.py` | Patterns for detecting unused `*Config` / `*Selectors` dataclass fields |
@@ -59,10 +56,6 @@ Shared constant modules imported by hooks throughout the `hooks/` tree. Each fil
59
56
  | `piped_pytest_blocker_constants.py` | Bash tool name, pytest program basenames and the python-interpreter basename pattern, the pipe and segment-reset operator token sets, and the deny message for the piped-pytest blocker; classification that consumes those program and wrapper constants lives in `pytest_invocation.py` |
60
57
  | `pytest_invocation.py` | Pure parsed-segment classifier for pytest runs through interpreters, shims, wrappers, and shell string-exec forms; no pipeline deny decision |
61
58
  | `plain_language_blocker_constants.py` | The list of heavy words and their everyday replacements |
62
- | `pr_converge_bugteam_enforcer_constants.py` | State keys and timing config for the bugteam-parallel enforcer |
63
- | `pr_converge_bugteam_enforcer_state.py` | State-file helpers for the bugteam enforcer |
64
- | `pr_description_enforcer_constants.py` | PR-description shape rules and command patterns |
65
- | `pr_description_proof_of_work_constants.py` | Proof-part detection patterns, gh command tokens, and corrective messages for the proof-of-work comment audit |
66
59
  | `prose_matcher_precision_constants.py` | Sample floor, keep/narrow precision floors, matcher ids, label decisions, advisory log path, emit caps, and context fingerprint length for OP-07B prose-matcher advisory telemetry |
67
60
  | `pre_tool_use_stdin.py` | `read_hook_input_dictionary_from_stdin()` — shared stdin parser for PreToolUse hooks |
68
61
  | `precommit_code_rules_gate_constants.py` | Scope argument and exit-code constants for the precommit gate |
@@ -70,7 +63,6 @@ Shared constant modules imported by hooks throughout the `hooks/` tree. Each fil
70
63
  | `pyproject_config_discovery_constants.py` | Table names (``tool`` key, ``mypy``, ``ruff``) for resolving a validator's config from a pyproject.toml `[tool.<name>]` table |
71
64
  | `pytest_testpaths_orphan_blocker_constants.py` | Marker filename, section and key names, test-file pattern, search budget, and block-message text for the pytest unregistered-test-directory blocker |
72
65
  | `python_style_checks_constants.py` | Command-line argument count and blank-line count between top-level functions for the style validator |
73
- | `reviewer_spawn_gate_constants.py` | Bash tool name, the sentinel marker, the Copilot and Bugbot trigger markers, the availability-script relative path and override env-var name, and the deny-message template for the reviewer-spawn gate |
74
66
  | `ruff_integration_constants.py` | ``NO_COLOR`` / ``FORCE_COLOR`` environment variable names for plain ruff diagnostics |
75
67
  | `send_user_file_open_locally_blocker_constants.py` | Tool name, proactive status, and the block message for the open-locally attach blocker |
76
68
  | `sensitive_file_protector_constants.py` | Sensitive filename patterns, the committed-template suffixes that earn an exemption, the write/edit tool names, and the deny decision and message template for `sensitive_file_protector` |
@@ -110,4 +102,3 @@ Shared constant modules imported by hooks throughout the `hooks/` tree. Each fil
110
102
  - Tests for these modules live beside them as `test_<module>.py`. Run with `python -m pytest hooks_constants/test_<name>.py`.
111
103
  - `dynamic_stderr_handler.py`, `pre_tool_use_stdin.py`, `multi_edit_reconstruction.py`, `hosted_hook_runner.py`, and `text_stripping.py` are utility modules (not pure constants) but live here because they hold logic shared across hook surfaces.
112
104
  - `local_identity.py` is a loader: it reads the environment or `~/.claude/local-identity.json` (its path overridable via `CLAUDE_LOCAL_IDENTITY_PATH`) to resolve private NAS values (with committed placeholder defaults), the PII commit-scan exempt-repo slug set (`CLAUDE_PII_EXEMPT_REPOS` / `pii_exempt_repositories`), and the per-repository allowlisted-values mapping (`pii_allowlisted_values`).
113
-
@@ -67,21 +67,10 @@ ALL_BASH_HOSTED_HOOK_ENTRIES: tuple[BashHostedHookEntry, ...] = (
67
67
  "blocking/pii_prevention_blocker.py", ALL_BASH_AND_POWERSHELL_TOOL_NAMES
68
68
  ),
69
69
  BashHostedHookEntry("blocking/conventional_pr_title_gate.py", ALL_BASH_ONLY_TOOL_NAMES),
70
- BashHostedHookEntry("blocking/reviewer_spawn_gate.py", ALL_BASH_ONLY_TOOL_NAMES),
71
70
  BashHostedHookEntry("blocking/block_main_commit.py", ALL_BASH_ONLY_TOOL_NAMES),
72
71
  BashHostedHookEntry("blocking/precommit_code_rules_gate.py", ALL_BASH_ONLY_TOOL_NAMES),
73
72
  BashHostedHookEntry("blocking/session_edit_stage_gate.py", ALL_BASH_ONLY_TOOL_NAMES),
74
- BashHostedHookEntry("blocking/pr_description_enforcer.py", ALL_BASH_ONLY_TOOL_NAMES),
75
73
  BashHostedHookEntry("blocking/test_preflight_check.py", ALL_BASH_ONLY_TOOL_NAMES),
76
- BashHostedHookEntry("blocking/convergence_gate_blocker.py", ALL_BASH_ONLY_TOOL_NAMES),
77
74
  BashHostedHookEntry("blocking/windows_rmtree_blocker.py", ALL_BASH_ONLY_TOOL_NAMES),
78
75
  BashHostedHookEntry("blocking/gh_pr_author_enforcer.py", ALL_BASH_ONLY_TOOL_NAMES),
79
- BashHostedHookEntry("blocking/code_review_push_gate.py", ALL_BASH_AND_POWERSHELL_TOOL_NAMES),
80
- BashHostedHookEntry(
81
- "blocking/code_review_pr_create_gate.py", ALL_BASH_AND_POWERSHELL_TOOL_NAMES
82
- ),
83
- BashHostedHookEntry(
84
- "blocking/code_review_stamp_directory_write_blocker.py",
85
- ALL_BASH_AND_POWERSHELL_TOOL_NAMES,
86
- ),
87
76
  )
@@ -1,7 +1,6 @@
1
1
  """Convergence branch naming policy constants.
2
2
 
3
3
  Shared by destructive_command_blocker convergence-branch exemptions
4
- and convergence_gate_blocker pre-flight checks.
5
4
  """
6
5
 
7
6
  ALL_CONVERGENCE_BRANCH_PREFIXES: tuple[str, ...] = ("claude/", "worktree-")
@@ -11,16 +11,15 @@ into a retry prompt authorizes nothing.
11
11
  claude-sonnet-4 -> ['claude', 'sonnet', '4'] ok: another tier
12
12
 
13
13
  Every literal the gate body reads lives here. ``AGENT_TOOL_NAME`` and
14
- ``TASK_TOOL_NAME`` come from the sibling spawn-gate constants, so the spawn
15
- gates share one source for both tool names.
14
+ ``TASK_TOOL_NAME`` name the spawn tools the gate evaluates.
16
15
  """
17
16
 
18
17
  from __future__ import annotations
19
18
 
20
19
  import re
21
20
 
22
- from hooks_constants.code_verifier_spawn_preflight_gate_constants import TASK_TOOL_NAME
23
- from hooks_constants.pr_converge_bugteam_enforcer_constants import AGENT_TOOL_NAME
21
+ AGENT_TOOL_NAME: str = "Agent"
22
+ TASK_TOOL_NAME: str = "Task"
24
23
 
25
24
  ALL_SPAWN_TOOL_NAMES: frozenset[str] = frozenset({AGENT_TOOL_NAME, TASK_TOOL_NAME})
26
25
 
@@ -86,10 +86,6 @@ ALL_HOSTED_HOOK_ENTRIES: tuple[HostedHookEntry, ...] = (
86
86
  script_relative_path="blocking/sensitive_file_protector.py",
87
87
  applicable_tool_names=ALL_WRITE_AND_EDIT_TOOL_NAMES,
88
88
  ),
89
- HostedHookEntry(
90
- script_relative_path="blocking/code_review_stamp_directory_write_blocker.py",
91
- applicable_tool_names=ALL_WRITE_EDIT_MULTI_EDIT_TOOL_NAMES,
92
- ),
93
89
  HostedHookEntry(
94
90
  script_relative_path="blocking/pii_prevention_blocker.py",
95
91
  applicable_tool_names=ALL_WRITE_EDIT_MULTI_EDIT_TOOL_NAMES,
@@ -131,10 +127,6 @@ ALL_HOSTED_HOOK_ENTRIES: tuple[HostedHookEntry, ...] = (
131
127
  script_relative_path="blocking/hook_prose_detector_consistency.py",
132
128
  applicable_tool_names=ALL_WRITE_AND_EDIT_TOOL_NAMES,
133
129
  ),
134
- HostedHookEntry(
135
- script_relative_path="blocking/verified_commit_message_accuracy_blocker.py",
136
- applicable_tool_names=ALL_WRITE_AND_EDIT_TOOL_NAMES,
137
- ),
138
130
  HostedHookEntry(
139
131
  script_relative_path="blocking/workflow_substitution_slot_blocker.py",
140
132
  applicable_tool_names=ALL_WRITE_EDIT_MULTI_EDIT_TOOL_NAMES,
@@ -7,12 +7,7 @@ PROACTIVE_STATUS: str = "proactive"
7
7
  CORRECTIVE_MESSAGE: str = (
8
8
  "BLOCKED [open-locally]: SendUserFile attaches a file to the session, which "
9
9
  "does not let the user see it while they are at the terminal. Open the file on "
10
- "screen in its own viewer:\n"
11
- " Start-Process pwsh -WindowStyle Hidden -ArgumentList "
12
- "'-NoProfile','-File',\"$HOME\\.claude\\scripts\\Show-Asset.ps1\","
13
- "'<path 1>','<path 2>'\n"
14
- "Show-Asset.ps1 sizes each image window to the image and opens every other file "
15
- "type in its default app. Pass every path the user named.\n"
10
+ "screen with its native Windows app. Open every path the user named.\n"
16
11
  "The one allowed attach is a phone push: when the user has stepped away and you "
17
12
  'want the file to reach their phone, call SendUserFile with status "proactive".'
18
13
  )
@@ -23,5 +23,4 @@ ALL_STOP_HOSTED_HOOK_PATHS: tuple[str, ...] = (
23
23
  "blocking/intent_only_ending_blocker.py",
24
24
  "blocking/session_handoff_blocker.py",
25
25
  "blocking/eli11_reply_enforcer.py",
26
- "diagnostic/hook_log_stop_wrapper.py",
27
26
  )
@@ -32,26 +32,17 @@ _EXPECTED_BASH_ORDER = (
32
32
  "blocking/volatile_path_in_post_blocker.py",
33
33
  "blocking/pii_prevention_blocker.py",
34
34
  "blocking/conventional_pr_title_gate.py",
35
- "blocking/reviewer_spawn_gate.py",
36
35
  "blocking/block_main_commit.py",
37
36
  "blocking/precommit_code_rules_gate.py",
38
37
  "blocking/session_edit_stage_gate.py",
39
- "blocking/pr_description_enforcer.py",
40
38
  "blocking/test_preflight_check.py",
41
- "blocking/convergence_gate_blocker.py",
42
39
  "blocking/windows_rmtree_blocker.py",
43
40
  "blocking/gh_pr_author_enforcer.py",
44
- "blocking/code_review_push_gate.py",
45
- "blocking/code_review_pr_create_gate.py",
46
- "blocking/code_review_stamp_directory_write_blocker.py",
47
41
  )
48
42
 
49
43
  _POWERSHELL_APPLICABLE = (
50
44
  "blocking/unscoped_search_blocker.py",
51
45
  "blocking/pii_prevention_blocker.py",
52
- "blocking/code_review_push_gate.py",
53
- "blocking/code_review_pr_create_gate.py",
54
- "blocking/code_review_stamp_directory_write_blocker.py",
55
46
  )
56
47
 
57
48
 
@@ -70,7 +61,7 @@ def test_every_hook_applies_to_the_bash_tool() -> None:
70
61
 
71
62
 
72
63
  def test_powershell_applicable_hooks_include_the_shared_gates() -> None:
73
- """PowerShell runs the unscoped-search and PII gates plus the review family."""
64
+ """PowerShell runs the shared unscoped-search and PII gates."""
74
65
  powershell_hooks = tuple(
75
66
  each_entry.script_relative_path
76
67
  for each_entry in ALL_BASH_HOSTED_HOOK_ENTRIES
@@ -86,22 +77,6 @@ def test_powershell_hooks_carry_the_shared_tool_set() -> None:
86
77
  assert each_entry.applicable_tool_names == ALL_BASH_AND_POWERSHELL_TOOL_NAMES
87
78
 
88
79
 
89
- def test_code_review_gate_family_registered_for_bash_and_powershell() -> None:
90
- """The three code-review shell gates run on both Bash and PowerShell."""
91
- code_review_gate_paths = (
92
- "blocking/code_review_push_gate.py",
93
- "blocking/code_review_pr_create_gate.py",
94
- "blocking/code_review_stamp_directory_write_blocker.py",
95
- )
96
- entry_by_path = {
97
- each_entry.script_relative_path: each_entry
98
- for each_entry in ALL_BASH_HOSTED_HOOK_ENTRIES
99
- }
100
- for each_gate_path in code_review_gate_paths:
101
- assert each_gate_path in entry_by_path
102
- assert entry_by_path[each_gate_path].applicable_tool_names == (
103
- ALL_BASH_AND_POWERSHELL_TOOL_NAMES
104
- )
105
80
 
106
81
 
107
82
  def test_every_roster_path_points_at_an_existing_hook() -> None:
@@ -63,11 +63,6 @@ def test_duplicate_rmtree_helper_blocker_runs_via_runpy() -> None:
63
63
  assert entry.native_module_name is None
64
64
 
65
65
 
66
- def test_code_review_stamp_write_blocker_registered_for_all_file_tools() -> None:
67
- entry = _entry_for("blocking/code_review_stamp_directory_write_blocker.py")
68
- assert entry is not None
69
- assert {"Write", "Edit", "MultiEdit"} <= entry.applicable_tool_names
70
-
71
66
 
72
67
  def test_windows_rmtree_blocker_still_registered() -> None:
73
68
  entry = _entry_for("blocking/windows_rmtree_blocker.py")
@@ -17,7 +17,6 @@ _EXPECTED_STOP_ORDER = (
17
17
  "blocking/intent_only_ending_blocker.py",
18
18
  "blocking/session_handoff_blocker.py",
19
19
  "blocking/eli11_reply_enforcer.py",
20
- "diagnostic/hook_log_stop_wrapper.py",
21
20
  )
22
21
 
23
22
 
@@ -8,13 +8,11 @@ Hooks that run at session or config-change boundaries rather than on individual
8
8
  |---|---|---|
9
9
  | `config_change_guard.py` | PostToolUse (Write/Edit on `settings.json`) | Counts hooks in the edited `settings.json` and logs any change to `~/.claude/cache/config-change-audit.log`; alerts when the hook count drops below the last known value |
10
10
  | `enter_worktree_origin_prefetch.py` | PreToolUse (EnterWorktree) | Fetches origin's default branch before a worktree creation call, keeping the `refs/remotes/origin/<default-branch>` ref that `fresh` mode reads current; never blocks on fetch failure |
11
- | `pr_converge_bugteam_skill_tracker.py` | PreToolUse (Skill) | Tracks which bugteam skill runs have completed within a pr-converge loop, so the enforcer can verify parallel execution |
12
11
  | `session_end_cleanup.py` | SessionEnd | Purges stale cache entries from `~/.claude/cache/` (entries older than the configured threshold) and old backup files |
13
12
  | `test_config_change_guard.py` | — | Tests for `config_change_guard.py` |
14
13
  | `test_enter_worktree_origin_prefetch.py` | — | Tests for `enter_worktree_origin_prefetch.py` |
15
- | `test_pr_converge_bugteam_skill_tracker.py` | — | Tests for `pr_converge_bugteam_skill_tracker.py` |
16
14
 
17
15
  ## Conventions
18
16
 
19
- - Constants for these hooks (stale-age threshold, cache directory, known-hook-count file, EnterWorktree prefetch tuning) live in `hooks_constants/session_env_cleanup_constants.py`, `hooks_constants/pr_converge_bugteam_enforcer_constants.py`, and `hooks_constants/enter_worktree_prefetch_constants.py`.
17
+ - Constants for these hooks (stale-age threshold, cache directory, known-hook-count file, EnterWorktree prefetch tuning) live in `hooks_constants/session_env_cleanup_constants.py` and `hooks_constants/enter_worktree_prefetch_constants.py`.
20
18
  - Tests run with `python -m pytest lifecycle/test_<name>.py`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-dev-env",
3
- "version": "2.11.0",
3
+ "version": "2.13.0",
4
4
  "description": "Claude Code development standards — rules, hooks, agents, commands, and skills",
5
5
  "type": "module",
6
6
  "bin": {
package/rules/CLAUDE.md CHANGED
@@ -45,13 +45,11 @@ Rule files installed into `~/.claude/rules/` by `bin/install.mjs`. A rule withou
45
45
  | `plain-illustrative-docstrings.md` | Public docstring narrative reads plainly and shows behavior with a diagram block (a `::` example or a doctest), painting a concrete scene a general developer follows on first read; a run-on backstop hook, a prose-wall backstop hook, and Category O9 audit enforce it |
46
46
  | `plain-language.md` | Everyday words, short active sentences, lead with the answer |
47
47
  | `prompt-workflow-context-controls.md` | Keep prompt-workflow instruction layers small and stable; load heavy skills on demand |
48
- | `proof-of-work-pr-comments.md` | Every PR carries one five-part proof-of-work comment before it leaves draft; the `pr_description_enforcer` hook audits proof-shaped comments and gates `gh pr ready` |
49
48
  | `re-stage-before-commit.md` | Stage the files edited this session before `git commit`; the session edit stage gate denies a commit that leaves a tracked session edit unstaged, with `-a`, a pathspec, a preceding `git add`, and `# partial-commit` as escapes |
50
49
  | `research-mode.md` | Three anti-hallucination constraints: say "I don't know", verify with citations, quote for factual grounding |
51
50
  | `shell-invocation.md` | Windows shell commands run through `pwsh`; no `$(...)`, backtick, or process substitution in a Bash tool command |
52
51
  | `testing.md` | Test quality and infrastructure standards |
53
52
  | `vault-context.md` | Search Obsidian vault for prior sessions and decisions before substantive project work |
54
- | `verified-commit-gate-skip.md` | Code-verifier review is optional; commits and pushes use the checks selected for the task |
55
53
  | `verify-before-asking.md` | Answer questions by inspecting files or running tools before asking; recalled facts expire until re-checked this session |
56
54
  | `verify-runtime-state.md` | A "component is fine / not at fault" verdict rests on a live probe this session, never code reading or prior-session memory |
57
55
  | `windows-filesystem-safe.md` | Use safe `rmtree` patterns on Windows; `mkdirSync` with `recursive: true` on possibly-existing paths |
@@ -24,4 +24,3 @@ Single-object endpoints (`pulls/<n>`, `issues/<n>`) skip pagination and may use
24
24
 
25
25
  - [`destructive-commands.md`](destructive-commands.md) — why a body describing `rm -rf` must travel by file path.
26
26
  - [`durable-post-artifacts.md`](durable-post-artifacts.md) — what a post body may reference.
27
- - [`proof-of-work-pr-comments.md`](proof-of-work-pr-comments.md) — what the proof comment must contain.
@@ -41,7 +41,7 @@ User-level rule: applies to **every** git repo that uses GitHub with `gh` (no ex
41
41
  | `SESSION_STATE.md` | Local session state |
42
42
  | `*.png *.jpg *.jpeg *.gif *.webp *.avif *.svg *.ico` | Images go to external storage, not GitHub |
43
43
 
44
- An image a PR needs as visual evidence is not an exception to that row. Upload it to the repository's durable `artifacts` release with `python3 ~/.claude/scripts/gh_artifact_upload.py <file> <owner/repo>` and embed the permanent URL in the proof comment. The image lives on GitHub without entering the repository tree.
44
+ An image a PR needs as visual evidence is not an exception to that row. Upload it to the repository's durable `artifacts` release with `python3 ~/.claude/scripts/gh_artifact_upload.py <file> <owner/repo>` and embed the permanent URL in the PR comment. The image lives on GitHub without entering the repository tree.
45
45
 
46
46
  ## Responding to review feedback
47
47
 
@@ -60,9 +60,7 @@ Repair only reported findings, then re-verify after every repair.
60
60
  | Rule | Covers |
61
61
  |---|---|
62
62
  | [`gh-cli-conventions.md`](gh-cli-conventions.md) | `--body-file` for post bodies; `--paginate --slurp` for list reads |
63
- | [`proof-of-work-pr-comments.md`](proof-of-work-pr-comments.md) | The five-part proof comment every PR carries before leaving draft |
64
63
  | [`re-stage-before-commit.md`](re-stage-before-commit.md) | Staging session edits so a commit does not drop them |
65
- | [`verified-commit-gate-skip.md`](verified-commit-gate-skip.md) | Optional code-verifier review guidance |
66
64
  | [`durable-post-artifacts.md`](durable-post-artifacts.md) | Keeping volatile scratch paths out of a post body |
67
65
  | [`destructive-commands.md`](destructive-commands.md) | Allowed removal forms; destructive literals in commit and post bodies |
68
66
  | [`code-standards.md`](code-standards.md) | The code standards a PR's diff is reviewed against |
package/scripts/CLAUDE.md CHANGED
@@ -28,7 +28,6 @@ Utility scripts installed into `~/.claude/scripts/` by `bin/install.mjs`. Each s
28
28
  | `Install-SweepEmptyDirs.ps1` | Registers `sweep_empty_dirs.py` as a scheduled task on Windows |
29
29
  | `Sync-RepoMain.ps1` | Fast-forwards a main-tracking mirror (`-RepoPath`, required) to its remote main using `merge --ff-only`; refuses a different checkout or a diverged branch, logs each run to `-LogPath`, and exits non-zero so a scheduled-task history row surfaces the problem. `-StashDirty` stashes tracked changes right before the fast-forward under a dated `pre-sync stash` message and leaves the stash in the list |
30
30
  | `check.ps1` | Runs the full code-quality check suite |
31
- | `Show-Asset.ps1` | Opens files on screen, sizing each image window to the image's pixel dimensions (scaled to fit the screen); non-image files open in their default application |
32
31
  | `Get-SessionAccount.ps1` | Reports which Claude account the current session is actually logged into by comparing `~/.claude.json`'s CLI login against a `CLAUDE_USER_DATA_DIR` desktop profile's `lastKnownAccountUuid`, recovering the desktop account's email from profile storage when the two accounts differ |
33
32
  | `Capture-PoolHealth.ps1` | Captures Windows memory pool counters, high-handle processes, and kernel pool tags (via `NtQuerySystemInformation` class 22), prints a threshold verdict with a remediation map, and exits non-zero when any alert threshold fires |
34
33