claude-dev-env 2.12.0 → 2.14.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 (399) hide show
  1. package/AGENTS.md +61 -0
  2. package/CLAUDE.md +1 -57
  3. package/_shared/AGENTS.md +15 -0
  4. package/_shared/CLAUDE.md +1 -15
  5. package/_shared/advisor/AGENTS.md +22 -0
  6. package/_shared/advisor/CLAUDE.md +1 -22
  7. package/_shared/pr-loop/AGENTS.md +27 -0
  8. package/_shared/pr-loop/CLAUDE.md +1 -27
  9. package/_shared/pr-loop/scripts/AGENTS.md +35 -0
  10. package/_shared/pr-loop/scripts/CLAUDE.md +1 -35
  11. package/_shared/pr-loop/scripts/code_rules_gate.py +2 -3
  12. package/_shared/pr-loop/scripts/code_rules_gate_parts/AGENTS.md +42 -0
  13. package/_shared/pr-loop/scripts/code_rules_gate_parts/CLAUDE.md +1 -42
  14. package/_shared/pr-loop/scripts/pr_loop_shared_constants/AGENTS.md +26 -0
  15. package/_shared/pr-loop/scripts/pr_loop_shared_constants/CLAUDE.md +1 -26
  16. package/_shared/pr-loop/scripts/test_code_rules_gate.py +0 -26
  17. package/_shared/pr-loop/scripts/tests/AGENTS.md +44 -0
  18. package/_shared/pr-loop/scripts/tests/CLAUDE.md +1 -44
  19. package/_shared/process-tree/AGENTS.md +41 -0
  20. package/_shared/process-tree/CLAUDE.md +1 -41
  21. package/agents/AGENTS.md +31 -0
  22. package/agents/CLAUDE.md +1 -32
  23. package/agents/clean-coder.md +6 -6
  24. package/agents/pr-description-writer.md +11 -81
  25. package/agents/test_agent_frontmatter.py +4 -4
  26. package/audit-rubrics/AGENTS.md +43 -0
  27. package/audit-rubrics/CLAUDE.md +1 -43
  28. package/audit-rubrics/category_rubrics/AGENTS.md +37 -0
  29. package/audit-rubrics/category_rubrics/CLAUDE.md +1 -37
  30. package/audit-rubrics/prompts/AGENTS.md +37 -0
  31. package/audit-rubrics/prompts/CLAUDE.md +1 -37
  32. package/bin/AGENTS.md +112 -0
  33. package/bin/CLAUDE.md +1 -112
  34. package/bin/ever-shipped-skills.mjs +1 -0
  35. package/bin/install-constants.mjs +6 -7
  36. package/bin/install.mjs +71 -13
  37. package/bin/install.prune.test.mjs +26 -0
  38. package/bin/install.settings-defaults.test.mjs +60 -33
  39. package/bin/install.test.mjs +36 -4
  40. package/commands/AGENTS.md +23 -0
  41. package/commands/CLAUDE.md +1 -23
  42. package/commands/hook-log-extract.md +3 -3
  43. package/commands/sr-loop.md +9 -5
  44. package/docs/AGENTS.md +32 -0
  45. package/docs/CLAUDE.md +1 -33
  46. package/docs/CODE_RULES.md +1 -1
  47. package/docs/imagegen.md +22 -0
  48. package/docs/references/AGENTS.md +17 -0
  49. package/docs/references/CLAUDE.md +1 -18
  50. package/hooks/AGENTS.md +31 -0
  51. package/hooks/CLAUDE.md +1 -31
  52. package/hooks/_gh_pr_author_swap_utils.py +14 -0
  53. package/hooks/advisory/AGENTS.md +16 -0
  54. package/hooks/advisory/CLAUDE.md +1 -16
  55. package/hooks/blocking/AGENTS.md +123 -0
  56. package/hooks/blocking/CLAUDE.md +1 -148
  57. package/hooks/blocking/claude_md_orphan_file_blocker_parts/AGENTS.md +28 -0
  58. package/hooks/blocking/claude_md_orphan_file_blocker_parts/CLAUDE.md +1 -28
  59. package/hooks/blocking/code_rules_banned_identifiers.py +1 -1
  60. package/hooks/blocking/code_rules_dead_module_constant.py +149 -37
  61. package/hooks/blocking/code_rules_probe_chains.py +6 -2
  62. package/hooks/blocking/config/AGENTS.md +10 -0
  63. package/hooks/blocking/config/CLAUDE.md +1 -22
  64. package/hooks/blocking/conventional_pr_title_gate.py +1 -2
  65. package/hooks/blocking/gh_pr_author_restore.py +7 -2
  66. package/hooks/blocking/intent_only_ending_blocker.py +11 -16
  67. package/hooks/blocking/inventory_intent_records/AGENTS.md +26 -0
  68. package/hooks/blocking/inventory_intent_records/CLAUDE.md +1 -26
  69. package/hooks/blocking/package_inventory_stale_blocker_parts/AGENTS.md +26 -0
  70. package/hooks/blocking/package_inventory_stale_blocker_parts/CLAUDE.md +1 -26
  71. package/hooks/blocking/pii_prevention_blocker_parts/AGENTS.md +24 -0
  72. package/hooks/blocking/pii_prevention_blocker_parts/CLAUDE.md +1 -24
  73. package/hooks/blocking/send_user_file_open_locally_blocker.py +1 -1
  74. package/hooks/blocking/stop_dispatcher.py +4 -4
  75. package/hooks/blocking/tdd_enforcer_parts/AGENTS.md +30 -0
  76. package/hooks/blocking/tdd_enforcer_parts/CLAUDE.md +1 -30
  77. package/hooks/blocking/test_bash_pre_tool_use_dispatcher.py +0 -3
  78. package/hooks/blocking/test_code_rules_enforcer_banned_prefixes.py +1 -1
  79. package/hooks/blocking/test_code_rules_enforcer_dead_module_constant.py +171 -0
  80. package/hooks/blocking/test_code_rules_enforcer_magic_allowlist.py +1 -1
  81. package/hooks/blocking/test_gh_pr_author_restore.py +2 -1
  82. package/hooks/blocking/test_intent_only_ending_blocker.py +4 -0
  83. package/hooks/blocking/test_pre_tool_use_dispatcher.py +6 -7
  84. package/hooks/blocking/test_send_user_file_open_locally_blocker.py +4 -3
  85. package/hooks/blocking/test_shared_stdin_adoption.py +0 -2
  86. package/hooks/diagnostic/AGENTS.md +43 -0
  87. package/hooks/diagnostic/CLAUDE.md +1 -43
  88. package/hooks/diagnostic/hook_log_extractor.py +4 -38
  89. package/hooks/diagnostic/hook_log_stop_wrapper.py +6 -155
  90. package/hooks/diagnostic/migrations/AGENTS.md +16 -0
  91. package/hooks/diagnostic/migrations/CLAUDE.md +1 -16
  92. package/hooks/diagnostic/queries/AGENTS.md +19 -0
  93. package/hooks/diagnostic/queries/CLAUDE.md +1 -19
  94. package/hooks/diagnostic/test_hook_log_extractor.py +10 -23
  95. package/hooks/diagnostic/test_hook_log_stop_wrapper.py +3 -331
  96. package/hooks/git-hooks/AGENTS.md +31 -0
  97. package/hooks/git-hooks/CLAUDE.md +1 -31
  98. package/hooks/git-hooks/git_hooks_constants/AGENTS.md +21 -0
  99. package/hooks/git-hooks/git_hooks_constants/CLAUDE.md +1 -21
  100. package/hooks/git-hooks/git_hooks_constants/__init__.py +4 -12
  101. package/hooks/git-hooks/pre_push.py +49 -118
  102. package/hooks/git-hooks/test_pre_push.py +111 -137
  103. package/hooks/hooks.json +0 -35
  104. package/hooks/hooks_constants/AGENTS.md +104 -0
  105. package/hooks/hooks_constants/CLAUDE.md +1 -113
  106. package/hooks/hooks_constants/bash_pre_tool_use_dispatcher_constants.py +0 -11
  107. package/hooks/hooks_constants/convergence_branch_constants.py +0 -1
  108. package/hooks/hooks_constants/fable_spawn_gate_constants.py +3 -4
  109. package/hooks/hooks_constants/hook_log_extractor_constants.py +1 -2
  110. package/hooks/hooks_constants/pre_tool_use_dispatcher_constants.py +0 -8
  111. package/hooks/hooks_constants/send_user_file_open_locally_blocker_constants.py +1 -6
  112. package/hooks/hooks_constants/stop_dispatcher_constants.py +0 -1
  113. package/hooks/hooks_constants/task_list_loop_starter_constants.py +4 -3
  114. package/hooks/hooks_constants/test_bash_pre_tool_use_dispatcher_constants.py +1 -26
  115. package/hooks/hooks_constants/test_pre_tool_use_dispatcher_constants.py +0 -5
  116. package/hooks/hooks_constants/test_stop_dispatcher_constants.py +0 -1
  117. package/hooks/hooks_constants/working_style_prompt_constants.py +29 -20
  118. package/hooks/lifecycle/AGENTS.md +18 -0
  119. package/hooks/lifecycle/CLAUDE.md +1 -20
  120. package/hooks/observability/AGENTS.md +20 -0
  121. package/hooks/observability/CLAUDE.md +1 -20
  122. package/hooks/session/AGENTS.md +33 -0
  123. package/hooks/session/CLAUDE.md +1 -33
  124. package/hooks/session/gh_pr_author_session_cleanup.py +7 -2
  125. package/hooks/session/task_list_loop_starter.py +3 -3
  126. package/hooks/session/test_gh_pr_author_session_cleanup.py +2 -1
  127. package/hooks/session/test_task_list_loop_starter.py +10 -2
  128. package/hooks/session/test_working_style_prompt.py +9 -4
  129. package/hooks/validation/AGENTS.md +20 -0
  130. package/hooks/validation/CLAUDE.md +1 -20
  131. package/hooks/validators/AGENTS.md +51 -0
  132. package/hooks/validators/CLAUDE.md +1 -51
  133. package/hooks/validators/health_check.py +52 -19
  134. package/hooks/validators/python_style_checks.py +1 -1
  135. package/hooks/validators/test_health_check.py +112 -27
  136. package/hooks/workflow/AGENTS.md +16 -0
  137. package/hooks/workflow/CLAUDE.md +1 -16
  138. package/installable-surfaces.manifest.json +1 -0
  139. package/output-styles/AGENTS.md +15 -0
  140. package/output-styles/CLAUDE.md +1 -15
  141. package/package.json +2 -1
  142. package/rules/AGENTS.md +61 -0
  143. package/rules/CLAUDE.md +1 -63
  144. package/rules/code-standards.md +5 -9
  145. package/rules/doc-prose-cuts.md +1 -1
  146. package/rules/gh-cli-conventions.md +0 -1
  147. package/rules/git-workflow.md +1 -3
  148. package/scripts/AGENTS.md +62 -0
  149. package/scripts/CLAUDE.md +1 -63
  150. package/scripts/_code_review_test_support.py +0 -95
  151. package/scripts/codex_compat_materializer.py +4 -0
  152. package/scripts/dev_env_scripts_constants/AGENTS.md +21 -0
  153. package/scripts/dev_env_scripts_constants/CLAUDE.md +1 -21
  154. package/scripts/dev_env_scripts_constants/code_review_constants.py +9 -98
  155. package/scripts/dev_env_scripts_constants/test_code_review_constants.py +1 -44
  156. package/scripts/invoke_code_review.py +8 -451
  157. package/scripts/sync_to_cursor/AGENTS.md +23 -0
  158. package/scripts/sync_to_cursor/CLAUDE.md +1 -23
  159. package/scripts/test_invoke_code_review.py +5 -61
  160. package/scripts/test_invoke_code_review_cli.py +1 -45
  161. package/scripts/test_invoke_code_review_contract.py +1 -118
  162. package/scripts/test_validate_instruction_pairs.py +90 -0
  163. package/scripts/test_verify_installable_package.py +5 -1
  164. package/scripts/tests/AGENTS.md +33 -0
  165. package/scripts/tests/CLAUDE.md +1 -33
  166. package/scripts/tests/test_codex_compat_materializer.py +36 -1
  167. package/scripts/validate_instruction_pairs.py +183 -0
  168. package/settings.json +1 -10
  169. package/skills/AGENTS.md +72 -0
  170. package/skills/CLAUDE.md +1 -64
  171. package/skills/_shared/AGENTS.md +44 -0
  172. package/skills/_shared/CLAUDE.md +1 -44
  173. package/skills/_shared/advisor/AGENTS.md +9 -0
  174. package/skills/_shared/advisor/CLAUDE.md +1 -9
  175. package/skills/_shared/pr-loop/AGENTS.md +50 -0
  176. package/skills/_shared/pr-loop/CLAUDE.md +1 -50
  177. package/skills/_shared/pr-loop/prompts/AGENTS.md +9 -0
  178. package/skills/_shared/pr-loop/prompts/CLAUDE.md +1 -9
  179. package/skills/_shared/pr-loop/scripts/AGENTS.md +35 -0
  180. package/skills/_shared/pr-loop/scripts/CLAUDE.md +1 -35
  181. package/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/AGENTS.md +24 -0
  182. package/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/CLAUDE.md +1 -24
  183. package/skills/anthropic-plan/AGENTS.md +34 -0
  184. package/skills/anthropic-plan/CLAUDE.md +1 -34
  185. package/skills/anthropic-plan/scripts/AGENTS.md +11 -0
  186. package/skills/anthropic-plan/scripts/CLAUDE.md +1 -11
  187. package/skills/anthropic-plan/scripts/anthropic_plan_scripts_constants/AGENTS.md +16 -0
  188. package/skills/anthropic-plan/scripts/anthropic_plan_scripts_constants/CLAUDE.md +1 -16
  189. package/skills/anthropic-plan/templates/AGENTS.md +13 -0
  190. package/skills/anthropic-plan/templates/CLAUDE.md +1 -13
  191. package/skills/anthropic-plan/workflow/AGENTS.md +14 -0
  192. package/skills/anthropic-plan/workflow/CLAUDE.md +1 -14
  193. package/skills/auditing-claude-config/AGENTS.md +21 -0
  194. package/skills/auditing-claude-config/CLAUDE.md +1 -21
  195. package/skills/autoconverge/AGENTS.md +36 -0
  196. package/skills/autoconverge/CLAUDE.md +1 -36
  197. package/skills/autoconverge/reference/AGENTS.md +16 -0
  198. package/skills/autoconverge/reference/CLAUDE.md +1 -16
  199. package/skills/autoconverge/reference/convergence.md +7 -7
  200. package/skills/autoconverge/reference/gotchas.md +3 -10
  201. package/skills/autoconverge/workflow/AGENTS.md +26 -0
  202. package/skills/autoconverge/workflow/CLAUDE.md +1 -26
  203. package/skills/autoconverge/workflow/autoconverge_report_constants/AGENTS.md +16 -0
  204. package/skills/autoconverge/workflow/autoconverge_report_constants/CLAUDE.md +1 -16
  205. package/skills/autoconverge/workflow/converge.contract.test.mjs +53 -1388
  206. package/skills/autoconverge/workflow/converge.copilot-gate.test.mjs +4 -3
  207. package/skills/autoconverge/workflow/converge.fix-recovery.test.mjs +33 -493
  208. package/skills/autoconverge/workflow/converge.merge-conflict.test.mjs +15 -97
  209. package/skills/autoconverge/workflow/converge.mjs +201 -238
  210. package/skills/autoconverge/workflow/converge.precatch.test.mjs +1 -1
  211. package/skills/bugteam/AGENTS.md +30 -0
  212. package/skills/bugteam/CLAUDE.md +1 -30
  213. package/skills/bugteam/CONSTRAINTS.md +1 -1
  214. package/skills/bugteam/SKILL.md +9 -0
  215. package/skills/bugteam/reference/AGENTS.md +20 -0
  216. package/skills/bugteam/reference/CLAUDE.md +1 -20
  217. package/skills/bugteam/reference/audit-and-teammates.md +10 -6
  218. package/skills/bugteam/reference/obstacles/AGENTS.md +24 -0
  219. package/skills/bugteam/reference/obstacles/CLAUDE.md +1 -24
  220. package/skills/bugteam/scripts/AGENTS.md +30 -0
  221. package/skills/bugteam/scripts/CLAUDE.md +1 -30
  222. package/skills/bugteam/scripts/bugteam_scripts_constants/AGENTS.md +18 -0
  223. package/skills/bugteam/scripts/bugteam_scripts_constants/CLAUDE.md +1 -18
  224. package/skills/bugteam/test_skill_additions.py +9 -0
  225. package/skills/closeout/reference/handoff-prompt-template.md +1 -1
  226. package/skills/codex-review/AGENTS.md +46 -0
  227. package/skills/codex-review/CLAUDE.md +1 -46
  228. package/skills/codex-review/reference/AGENTS.md +15 -0
  229. package/skills/codex-review/reference/CLAUDE.md +1 -15
  230. package/skills/codex-review/scripts/codex_review_scripts_constants/AGENTS.md +18 -0
  231. package/skills/codex-review/scripts/codex_review_scripts_constants/CLAUDE.md +1 -18
  232. package/skills/codex-review/test_skill_scaffold.py +3 -3
  233. package/skills/comments/SKILL.md +65 -0
  234. package/skills/copilot-review/AGENTS.md +18 -0
  235. package/skills/copilot-review/CLAUDE.md +1 -18
  236. package/skills/descriptions/SKILL.md +51 -0
  237. package/skills/emergencies/SKILL.md +42 -0
  238. package/skills/everything-search/AGENTS.md +17 -0
  239. package/skills/everything-search/CLAUDE.md +1 -17
  240. package/skills/fresh-branch/AGENTS.md +14 -0
  241. package/skills/fresh-branch/CLAUDE.md +1 -14
  242. package/skills/grok-spawn/AGENTS.md +28 -0
  243. package/skills/grok-spawn/CLAUDE.md +1 -28
  244. package/skills/orchestrator/SKILL.md +2 -4
  245. package/skills/plan-to-pr/SKILL.md +6 -7
  246. package/skills/plan-to-pr/reference/final-validation-tasks.md +1 -1
  247. package/skills/plan-to-pr/reference/process-inventory.md +2 -2
  248. package/skills/plan-to-pr/reference/review-loop.md +2 -2
  249. package/skills/plan-to-pr/reference/run-record.schema.json +1 -1
  250. package/skills/plan-to-pr/reference/task-seeds.md +1 -1
  251. package/skills/plan-to-pr/reference/task-ticket.md +3 -4
  252. package/skills/plan-to-pr/scripts/config/constants.py +1 -2
  253. package/skills/plan-to-pr/scripts/test_validate_protocol.py +1 -1
  254. package/skills/plan-to-pr/test_skill_contract.py +2 -2
  255. package/skills/pr-converge/AGENTS.md +32 -0
  256. package/skills/pr-converge/CLAUDE.md +1 -32
  257. package/skills/pr-converge/SKILL.md +13 -16
  258. package/skills/pr-converge/pr_converge_skill_constants/AGENTS.md +26 -0
  259. package/skills/pr-converge/pr_converge_skill_constants/CLAUDE.md +1 -26
  260. package/skills/pr-converge/reference/AGENTS.md +28 -0
  261. package/skills/pr-converge/reference/CLAUDE.md +1 -28
  262. package/skills/pr-converge/reference/obstacles/AGENTS.md +23 -0
  263. package/skills/pr-converge/reference/obstacles/CLAUDE.md +1 -23
  264. package/skills/pr-converge/reference/progress-checklist.md +6 -5
  265. package/skills/pr-converge/reference/state-schema.md +1 -27
  266. package/skills/pr-converge/scripts/AGENTS.md +46 -0
  267. package/skills/pr-converge/scripts/CLAUDE.md +1 -46
  268. package/skills/pr-converge/scripts/pr_converge_scripts_constants/AGENTS.md +18 -0
  269. package/skills/pr-converge/scripts/pr_converge_scripts_constants/CLAUDE.md +1 -18
  270. package/skills/pr-converge/workflows/AGENTS.md +16 -0
  271. package/skills/pr-converge/workflows/CLAUDE.md +1 -16
  272. package/skills/pr-loop-cloud-transport/SKILL.md +1 -1
  273. package/skills/pr-loop-cloud-transport/reference/identity-and-hooks.md +3 -3
  274. package/skills/pr-loop-lifecycle/SKILL.md +1 -1
  275. package/skills/pr-loop-lifecycle/reference/teardown-publish-permissions.md +1 -1
  276. package/skills/prototype/SKILL.md +4 -4
  277. package/skills/prototype/reference/honest-limitations.md +5 -5
  278. package/skills/prototype/reference/promotion-tasks.md +2 -2
  279. package/skills/prototype/workflows/promotion.md +4 -6
  280. package/skills/rebase/AGENTS.md +32 -0
  281. package/skills/rebase/CLAUDE.md +1 -32
  282. package/skills/recall/AGENTS.md +30 -0
  283. package/skills/recall/CLAUDE.md +1 -30
  284. package/skills/remember/AGENTS.md +31 -0
  285. package/skills/remember/CLAUDE.md +1 -31
  286. package/skills/reviews/SKILL.md +85 -0
  287. package/skills/session-log/AGENTS.md +32 -0
  288. package/skills/session-log/CLAUDE.md +1 -32
  289. package/skills/session-tidy/AGENTS.md +36 -0
  290. package/skills/session-tidy/CLAUDE.md +1 -36
  291. package/skills/skill-builder/AGENTS.md +49 -0
  292. package/skills/skill-builder/CLAUDE.md +1 -49
  293. package/skills/skill-builder/references/AGENTS.md +25 -0
  294. package/skills/skill-builder/references/CLAUDE.md +1 -25
  295. package/skills/skill-builder/references/deterministic-elements.md +1 -1
  296. package/skills/skill-builder/templates/AGENTS.md +14 -0
  297. package/skills/skill-builder/templates/CLAUDE.md +1 -14
  298. package/skills/skill-builder/workflows/AGENTS.md +19 -0
  299. package/skills/skill-builder/workflows/CLAUDE.md +1 -19
  300. package/skills/small-cl/SKILL.md +52 -0
  301. package/skills/task-build/AGENTS.md +29 -0
  302. package/skills/task-build/CLAUDE.md +1 -29
  303. package/skills/update/AGENTS.md +38 -0
  304. package/skills/update/CLAUDE.md +1 -38
  305. package/system-prompts/AGENTS.md +17 -0
  306. package/system-prompts/CLAUDE.md +1 -17
  307. package/system-prompts/software-engineer.xml +3 -3
  308. package/agents/code-verifier.md +0 -74
  309. package/docs/PR_DESCRIPTION_GUIDE.md +0 -157
  310. package/docs/references/code-review-enforcement.md +0 -132
  311. package/hooks/blocking/code_review_enforcement_config_bootstrap.py +0 -53
  312. package/hooks/blocking/code_review_gate_deny.py +0 -74
  313. package/hooks/blocking/code_review_pr_create_gate.py +0 -198
  314. package/hooks/blocking/code_review_push_gate.py +0 -145
  315. package/hooks/blocking/code_review_stamp_directory_write_blocker.py +0 -348
  316. package/hooks/blocking/code_review_stamp_store.py +0 -233
  317. package/hooks/blocking/code_review_stamp_write_blocker_parts/__init__.py +0 -7
  318. package/hooks/blocking/code_review_stamp_write_blocker_parts/conftest.py +0 -15
  319. package/hooks/blocking/code_review_stamp_write_blocker_parts/obfuscated_stamp_path_reference.py +0 -212
  320. package/hooks/blocking/code_review_stamp_write_blocker_parts/split_directory_change_into_stamp.py +0 -138
  321. package/hooks/blocking/code_review_stamp_write_blocker_parts/test_obfuscated_stamp_path_reference.py +0 -49
  322. package/hooks/blocking/code_review_stamp_write_blocker_parts/test_split_directory_change_into_stamp.py +0 -38
  323. package/hooks/blocking/code_verifier_spawn_preflight_gate.py +0 -483
  324. package/hooks/blocking/config/code_review_enforcement_constants.py +0 -143
  325. package/hooks/blocking/config/test_code_review_enforcement_constants.py +0 -166
  326. package/hooks/blocking/config/verified_commit_constants.py +0 -160
  327. package/hooks/blocking/config/verified_commit_context_constants.py +0 -21
  328. package/hooks/blocking/config/verified_commit_gate_output_constants.py +0 -14
  329. package/hooks/blocking/conftest.py +0 -123
  330. package/hooks/blocking/convergence_gate_blocker.py +0 -310
  331. package/hooks/blocking/pr_converge_bugteam_enforcer.py +0 -170
  332. package/hooks/blocking/pr_description_body_audit.py +0 -148
  333. package/hooks/blocking/pr_description_command_parser.py +0 -237
  334. package/hooks/blocking/pr_description_enforcer.py +0 -227
  335. package/hooks/blocking/pr_description_pr_number.py +0 -155
  336. package/hooks/blocking/pr_description_proof_of_work.py +0 -385
  337. package/hooks/blocking/pr_description_readability.py +0 -364
  338. package/hooks/blocking/reviewer_spawn_gate.py +0 -182
  339. package/hooks/blocking/test_code_review_enforcement_config_bootstrap.py +0 -62
  340. package/hooks/blocking/test_code_review_gate_deny.py +0 -54
  341. package/hooks/blocking/test_code_review_pr_create_gate.py +0 -199
  342. package/hooks/blocking/test_code_review_push_gate.py +0 -205
  343. package/hooks/blocking/test_code_review_stamp_directory_write_blocker.py +0 -199
  344. package/hooks/blocking/test_code_review_stamp_store.py +0 -205
  345. package/hooks/blocking/test_code_verifier_spawn_preflight_gate.py +0 -710
  346. package/hooks/blocking/test_code_verifier_tools_contract.py +0 -28
  347. package/hooks/blocking/test_convergence_gate_blocker.py +0 -428
  348. package/hooks/blocking/test_pr_converge_bugteam_enforcer.py +0 -311
  349. package/hooks/blocking/test_pr_converge_bugteam_enforcer_state_tolerance.py +0 -184
  350. package/hooks/blocking/test_pr_description_enforcer.py +0 -221
  351. package/hooks/blocking/test_pr_description_enforcer_body_audit.py +0 -247
  352. package/hooks/blocking/test_pr_description_enforcer_body_rules.py +0 -493
  353. package/hooks/blocking/test_pr_description_enforcer_command_parser.py +0 -366
  354. package/hooks/blocking/test_pr_description_enforcer_pr_number.py +0 -159
  355. package/hooks/blocking/test_pr_description_enforcer_proof_gate.py +0 -175
  356. package/hooks/blocking/test_pr_description_enforcer_readability.py +0 -443
  357. package/hooks/blocking/test_pr_description_proof_of_work.py +0 -313
  358. package/hooks/blocking/test_reviewer_spawn_gate.py +0 -230
  359. package/hooks/blocking/test_verdict_directory_write_blocker.py +0 -804
  360. package/hooks/blocking/test_verification_verdict_store.py +0 -974
  361. package/hooks/blocking/test_verified_commit_config_bootstrap.py +0 -67
  362. package/hooks/blocking/test_verified_commit_docs_delta.py +0 -176
  363. package/hooks/blocking/test_verified_commit_gate.py +0 -581
  364. package/hooks/blocking/test_verified_commit_gate_additional_context.py +0 -134
  365. package/hooks/blocking/test_verified_commit_message_accuracy_blocker.py +0 -131
  366. package/hooks/blocking/test_verifier_verdict_minter.py +0 -299
  367. package/hooks/blocking/tests/test_verified_commit_gate.py +0 -41
  368. package/hooks/blocking/verdict_directory_write_blocker.py +0 -687
  369. package/hooks/blocking/verification_verdict_store.py +0 -1039
  370. package/hooks/blocking/verified_commit_config_bootstrap.py +0 -63
  371. package/hooks/blocking/verified_commit_gate.py +0 -113
  372. package/hooks/blocking/verified_commit_gate_parts/CLAUDE.md +0 -28
  373. package/hooks/blocking/verified_commit_gate_parts/__init__.py +0 -1
  374. package/hooks/blocking/verified_commit_gate_parts/command_tokenization.py +0 -174
  375. package/hooks/blocking/verified_commit_gate_parts/deny_payload.py +0 -53
  376. package/hooks/blocking/verified_commit_gate_parts/deny_reason.py +0 -80
  377. package/hooks/blocking/verified_commit_gate_parts/directory_resolution.py +0 -170
  378. package/hooks/blocking/verified_commit_gate_parts/gated_invocations.py +0 -217
  379. package/hooks/blocking/verified_commit_gate_parts/tests/conftest.py +0 -10
  380. package/hooks/blocking/verified_commit_gate_parts/tests/test_command_tokenization.py +0 -94
  381. package/hooks/blocking/verified_commit_gate_parts/tests/test_deny_payload.py +0 -17
  382. package/hooks/blocking/verified_commit_gate_parts/tests/test_deny_reason.py +0 -38
  383. package/hooks/blocking/verified_commit_gate_parts/tests/test_directory_resolution.py +0 -71
  384. package/hooks/blocking/verified_commit_gate_parts/tests/test_gated_invocations.py +0 -96
  385. package/hooks/blocking/verified_commit_message_accuracy_blocker.py +0 -167
  386. package/hooks/blocking/verifier_verdict_minter.py +0 -280
  387. package/hooks/hooks_constants/code_verifier_spawn_preflight_gate_constants.py +0 -64
  388. package/hooks/hooks_constants/convergence_gate_blocker_constants.py +0 -53
  389. package/hooks/hooks_constants/pr_converge_bugteam_enforcer_constants.py +0 -55
  390. package/hooks/hooks_constants/pr_converge_bugteam_enforcer_state.py +0 -67
  391. package/hooks/hooks_constants/pr_description_enforcer_constants.py +0 -167
  392. package/hooks/hooks_constants/pr_description_proof_of_work_constants.py +0 -107
  393. package/hooks/hooks_constants/reviewer_spawn_gate_constants.py +0 -41
  394. package/hooks/hooks_constants/test_pr_description_enforcer_constants.py +0 -292
  395. package/hooks/lifecycle/pr_converge_bugteam_skill_tracker.py +0 -198
  396. package/hooks/lifecycle/test_pr_converge_bugteam_skill_tracker.py +0 -283
  397. package/rules/proof-of-work-pr-comments.md +0 -22
  398. package/rules/verified-commit-gate-skip.md +0 -4
  399. package/scripts/Show-Asset.ps1 +0 -106
@@ -16,19 +16,15 @@ the spawn does not wait for interactive input. Result JSON on stdout only::
16
16
 
17
17
  {"mode", "served_command", "returncode", "dirty_tree"}
18
18
 
19
- ``--record-stamp`` forces chain mode, loops a capped number of review passes,
20
- and mints a clean stamp only when a pass exits 0 with a stable surface hash.
21
-
22
19
  Import ``invoke_code_review`` for the outcome object, or run as a CLI::
23
20
 
24
21
  python invoke_code_review.py --cwd <dir> --session-model <alias>
25
- [--timeout-seconds N] [--record-stamp] [effort]
22
+ [--timeout-seconds N] [effort]
26
23
  """
27
24
 
28
25
  from __future__ import annotations
29
26
 
30
27
  import argparse
31
- import importlib.util
32
28
  import json
33
29
  import subprocess
34
30
  import sys
@@ -36,7 +32,6 @@ import threading
36
32
  from collections.abc import Callable, Sequence
37
33
  from dataclasses import dataclass
38
34
  from pathlib import Path
39
- from types import ModuleType
40
35
 
41
36
  if str(Path(__file__).resolve().parent) not in sys.path:
42
37
  sys.path.insert(0, str(Path(__file__).resolve().parent))
@@ -64,7 +59,6 @@ from dev_env_scripts_constants.code_review_constants import ( # noqa: E402
64
59
  ALL_EFFORT_TOKENS_IN_ASCENDING_ORDER,
65
60
  CLI_EFFORT_HELP,
66
61
  CLI_EFFORT_METAVAR,
67
- CLI_RECORD_STAMP_HELP,
68
62
  CLI_SESSION_MODEL_FLAG,
69
63
  CODE_REVIEW_FIX_FLAG,
70
64
  CODE_REVIEW_MODEL_ALIAS,
@@ -78,27 +72,14 @@ from dev_env_scripts_constants.code_review_constants import ( # noqa: E402
78
72
  IN_SESSION_RETURNCODE,
79
73
  INVALID_EFFORT_MESSAGE,
80
74
  INVALID_EFFORT_RETURNCODE,
81
- MAXIMUM_STAMP_MINT_PASSES,
82
75
  MODE_CHAIN,
83
76
  MODE_IN_SESSION,
84
77
  REVIEW_PERMISSION_MODE as PERMISSION_MODE_BYPASS,
85
78
  PERMISSION_MODE_FLAG,
86
- RECORD_STAMP_FLAG,
87
- RESULT_KEY_BOUND_HASH,
88
79
  RESULT_KEY_DIRTY_TREE,
89
80
  RESULT_KEY_MODE,
90
- RESULT_KEY_PASS_COUNT,
91
81
  RESULT_KEY_RETURNCODE,
92
82
  RESULT_KEY_SERVED_COMMAND,
93
- RESULT_KEY_STAMP_MINTED,
94
- STAMP_DID_NOT_CONVERGE_MESSAGE,
95
- STAMP_DID_NOT_CONVERGE_RETURNCODE,
96
- STAMP_STORE_IMPORT_FAILURE_MESSAGE,
97
- STAMP_STORE_LIVE_SURFACE_HASH_NAME,
98
- STAMP_STORE_MODULE_FILE_NAME,
99
- STAMP_STORE_MODULE_NAME,
100
- STAMP_STORE_RECORD_CLEAN_STAMP_NAME,
101
- STAMP_STORE_RESOLVE_REPO_ROOT_NAME,
102
83
  SUCCESSFUL_REVIEW_RETURNCODE,
103
84
  )
104
85
  from dev_env_scripts_constants.grok_worker_constants import ( # noqa: E402
@@ -139,25 +120,6 @@ class CodeReviewOutcome:
139
120
  is_dirty_tree: bool
140
121
 
141
122
 
142
- @dataclass(frozen=True)
143
- class StampMintOutcome:
144
- """Outcome of a ``--record-stamp`` minting run.
145
-
146
- ::
147
-
148
- stable rc 0 pass -> is_stamp_minted True, bound_hash set
149
- cap hit / unstable -> is_stamp_minted False, non-zero returncode
150
-
151
- The attributes carry the last review, whether a stamp was minted, the pass
152
- count, and the surface hash the stamp was bound to when minted.
153
- """
154
-
155
- review_outcome: CodeReviewOutcome
156
- is_stamp_minted: bool
157
- pass_count: int
158
- bound_hash: str | None
159
-
160
-
161
123
  review_claude_runner = run_claude
162
124
  review_host_profile_detector = detect_host_profile
163
125
  review_git_status_runner = subprocess.run
@@ -168,65 +130,6 @@ TextCapturingSubprocessRunner = Callable[
168
130
  ]
169
131
 
170
132
 
171
- def _stamp_store_file_path() -> Path:
172
- """Return the stamp store module path in the sibling hooks/blocking tree."""
173
- blocking_directory = Path(__file__).resolve().parent.parent / "hooks" / "blocking"
174
- return blocking_directory / STAMP_STORE_MODULE_FILE_NAME
175
-
176
-
177
- def _load_store_from_spec(store_file_path: Path) -> ModuleType:
178
- """Import the stamp store from *store_file_path*, re-raising a missing dep."""
179
- blocking_directory_string = str(store_file_path.parent)
180
- if blocking_directory_string not in sys.path:
181
- sys.path.insert(0, blocking_directory_string)
182
- module_spec = importlib.util.spec_from_file_location(
183
- STAMP_STORE_MODULE_NAME, store_file_path
184
- )
185
- if module_spec is None or module_spec.loader is None:
186
- raise ModuleNotFoundError(
187
- f"could not create import spec for {store_file_path}",
188
- name=STAMP_STORE_MODULE_NAME,
189
- )
190
- store_module = importlib.util.module_from_spec(module_spec)
191
- sys.modules[STAMP_STORE_MODULE_NAME] = store_module
192
- try:
193
- module_spec.loader.exec_module(store_module)
194
- except ModuleNotFoundError:
195
- del sys.modules[STAMP_STORE_MODULE_NAME]
196
- raise
197
- return store_module
198
-
199
-
200
- def load_code_review_stamp_store() -> ModuleType:
201
- """Import the stamp store module from the installed or repo hooks tree.
202
-
203
- ::
204
-
205
- code_review_stamp_store.py present -> module with record_clean_stamp
206
- module file missing -> ModuleNotFoundError (loud)
207
-
208
- A genuine missing dependency of the store still raises rather than being
209
- swallowed, so ``--record-stamp`` fails loudly when it cannot mint.
210
-
211
- Returns:
212
- The loaded ``code_review_stamp_store`` module.
213
-
214
- Raises:
215
- ModuleNotFoundError: When the store file is absent or a real import
216
- dependency of the store is missing.
217
- """
218
- store_file_path = _stamp_store_file_path()
219
- if not store_file_path.is_file():
220
- raise ModuleNotFoundError(
221
- f"code review stamp store not found at {store_file_path}",
222
- name=STAMP_STORE_MODULE_NAME,
223
- )
224
- cached_module = sys.modules.get(STAMP_STORE_MODULE_NAME)
225
- if cached_module is not None:
226
- return cached_module
227
- return _load_store_from_spec(store_file_path)
228
-
229
-
230
133
  def is_opus_session_model(session_model: str) -> bool:
231
134
  """Return True when *session_model* is the opus short alias (any letter case).
232
135
 
@@ -345,8 +248,7 @@ def is_working_tree_dirty(working_directory: Path) -> bool:
345
248
  is_working_tree_dirty(dirty_repo) # ok: True
346
249
  is_working_tree_dirty(broken_git) # ok: True (non-zero status)
347
250
 
348
- A non-zero ``git status`` return code must not report clean: the caller
349
- treats an unknown tree as dirty so a clean stamp cannot bypass the gate.
251
+ A non-zero ``git status`` return code reports a dirty tree.
350
252
 
351
253
  Args:
352
254
  working_directory: Git working tree to inspect.
@@ -384,8 +286,7 @@ def is_successful_code_review(review_outcome: CodeReviewOutcome) -> bool:
384
286
  review_outcome: Structured outcome from ``invoke_code_review``.
385
287
 
386
288
  Returns:
387
- True when the outcome is a successful serve that may stamp clean if
388
- the working tree is also clean.
289
+ True when the outcome is a successful review serve.
389
290
  """
390
291
  if review_outcome.returncode != SUCCESSFUL_REVIEW_RETURNCODE:
391
292
  return False
@@ -394,32 +295,6 @@ def is_successful_code_review(review_outcome: CodeReviewOutcome) -> bool:
394
295
  return True
395
296
 
396
297
 
397
- def is_code_review_clean_stamp_allowed(review_outcome: CodeReviewOutcome) -> bool:
398
- """Return True when the outcome may set ``code_review_clean_at``.
399
-
400
- ::
401
-
402
- is_code_review_clean_stamp_allowed(chain_clean_ok) # ok: True
403
- is_code_review_clean_stamp_allowed(chain_failed) # ok: False
404
- is_code_review_clean_stamp_allowed(chain_dirty_ok) # ok: False
405
-
406
- Clean stamp requires a successful serve and a clean working tree.
407
- ``dirty_tree`` alone is not enough: a failed chain leaves the tree clean
408
- and must stay in CODE_REVIEW.
409
-
410
- Args:
411
- review_outcome: Structured outcome from ``invoke_code_review``.
412
-
413
- Returns:
414
- True only when the review succeeded and ``is_dirty_tree`` is False.
415
- """
416
- if not is_successful_code_review(review_outcome):
417
- return False
418
- if review_outcome.is_dirty_tree:
419
- return False
420
- return True
421
-
422
-
423
298
  def _run_claude_with_empty_stdin(
424
299
  all_claude_arguments: list[str],
425
300
  *,
@@ -521,34 +396,24 @@ def invoke_code_review(
521
396
  session_model: str,
522
397
  timeout_seconds: int,
523
398
  effort: str = DEFAULT_CODE_REVIEW_EFFORT,
524
- is_force_chain: bool = False,
525
399
  ) -> CodeReviewOutcome:
526
400
  """Run or hand off ``/code-review`` based on host profile and session model.
527
401
 
528
402
  ::
529
403
 
530
- Claude + opus, is_force_chain False -> in_session (no spawn)
531
- Claude + opus, is_force_chain True -> chain (headless spawn)
532
- any host with sonnet -> chain
404
+ Claude + opus -> in_session (no spawn)
405
+ any host with sonnet -> chain (headless spawn)
533
406
 
534
407
  Args:
535
408
  working_directory: PR working tree used as cwd for the chain spawn.
536
409
  session_model: Caller-stated session model short alias.
537
410
  timeout_seconds: Timeout applied to each chain binary invocation.
538
411
  effort: Effort token embedded in the ``/code-review`` prompt.
539
- is_force_chain: When True, always spawn chain mode (used by
540
- ``--record-stamp`` so the invoker observes the review).
541
412
 
542
413
  Returns:
543
414
  Structured outcome including mode, served binary, return code, and
544
415
  whether the working tree is dirty after a chain run.
545
416
  """
546
- if is_force_chain:
547
- return _run_chain_review(
548
- working_directory=working_directory,
549
- timeout_seconds=timeout_seconds,
550
- effort=effort,
551
- )
552
417
  host_profile = review_host_profile_detector()
553
418
  review_mode = decide_review_mode(
554
419
  host_profile=host_profile,
@@ -563,188 +428,6 @@ def invoke_code_review(
563
428
  )
564
429
 
565
430
 
566
- def _surface_hash_before_and_after_are_stable(
567
- before_hash: str | None,
568
- after_hash: str | None,
569
- ) -> bool:
570
- if before_hash is None:
571
- return False
572
- if after_hash is None:
573
- return False
574
- return before_hash == after_hash
575
-
576
-
577
- def _mint_stamp_for_stable_pass(
578
- *,
579
- store_module: ModuleType,
580
- working_directory: Path,
581
- surface_hash: str,
582
- effort: str,
583
- ) -> bool:
584
- resolve_repo_root = getattr(store_module, STAMP_STORE_RESOLVE_REPO_ROOT_NAME)
585
- record_clean_stamp = getattr(store_module, STAMP_STORE_RECORD_CLEAN_STAMP_NAME)
586
- repo_root = resolve_repo_root(str(working_directory))
587
- if repo_root is None:
588
- return False
589
- record_clean_stamp(repo_root, surface_hash, effort)
590
- return True
591
-
592
-
593
- def _mint_outcome_when_stable_clean(
594
- *,
595
- store_module: ModuleType,
596
- working_directory: Path,
597
- effort: str,
598
- pass_number: int,
599
- before_hash: str,
600
- review_outcome: CodeReviewOutcome,
601
- ) -> StampMintOutcome | None:
602
- is_minted = _mint_stamp_for_stable_pass(
603
- store_module=store_module,
604
- working_directory=working_directory,
605
- surface_hash=before_hash,
606
- effort=effort,
607
- )
608
- if not is_minted:
609
- return None
610
- return StampMintOutcome(
611
- review_outcome=review_outcome,
612
- is_stamp_minted=True,
613
- pass_count=pass_number,
614
- bound_hash=before_hash,
615
- )
616
-
617
-
618
- def _unminted_pass_outcome(
619
- review_outcome: CodeReviewOutcome, pass_number: int
620
- ) -> StampMintOutcome:
621
- return StampMintOutcome(
622
- review_outcome=review_outcome,
623
- is_stamp_minted=False,
624
- pass_count=pass_number,
625
- bound_hash=None,
626
- )
627
-
628
-
629
- def _stamp_outcome_for_pass(
630
- *,
631
- store_module: ModuleType,
632
- working_directory: Path,
633
- effort: str,
634
- pass_number: int,
635
- before_hash: str | None,
636
- after_hash: str | None,
637
- review_outcome: CodeReviewOutcome,
638
- ) -> StampMintOutcome | None:
639
- is_stable = _surface_hash_before_and_after_are_stable(before_hash, after_hash)
640
- is_successful = is_successful_code_review(review_outcome)
641
- is_empty_surface = before_hash is None and after_hash is None
642
- if is_successful and is_empty_surface:
643
- return _unminted_pass_outcome(review_outcome, pass_number)
644
- if is_successful and is_stable and before_hash is not None:
645
- minted = _mint_outcome_when_stable_clean(
646
- store_module=store_module,
647
- working_directory=working_directory,
648
- effort=effort,
649
- pass_number=pass_number,
650
- before_hash=before_hash,
651
- review_outcome=review_outcome,
652
- )
653
- if minted is not None:
654
- return minted
655
- if is_stable:
656
- return _unminted_pass_outcome(review_outcome, pass_number)
657
- return None
658
-
659
-
660
- def _run_one_stamp_mint_pass(
661
- *,
662
- store_module: ModuleType,
663
- live_surface_hash: Callable[..., str | None],
664
- working_directory: Path,
665
- timeout_seconds: int,
666
- effort: str,
667
- pass_number: int,
668
- ) -> tuple[CodeReviewOutcome, StampMintOutcome | None]:
669
- before_hash = live_surface_hash(str(working_directory))
670
- review_outcome = invoke_code_review(
671
- working_directory=working_directory,
672
- session_model=CODE_REVIEW_MODEL_ALIAS,
673
- timeout_seconds=timeout_seconds,
674
- effort=effort,
675
- is_force_chain=True,
676
- )
677
- after_hash = live_surface_hash(str(working_directory))
678
- maybe_outcome = _stamp_outcome_for_pass(
679
- store_module=store_module,
680
- working_directory=working_directory,
681
- effort=effort,
682
- pass_number=pass_number,
683
- before_hash=before_hash,
684
- after_hash=after_hash,
685
- review_outcome=review_outcome,
686
- )
687
- return review_outcome, maybe_outcome
688
-
689
-
690
- def _iterate_stamp_mint_passes(
691
- *,
692
- store_module: ModuleType,
693
- live_surface_hash: Callable[..., str | None],
694
- working_directory: Path,
695
- timeout_seconds: int,
696
- effort: str,
697
- maximum_passes: int,
698
- ) -> StampMintOutcome:
699
- last_review_outcome = _failure_code_review_outcome(
700
- STAMP_DID_NOT_CONVERGE_RETURNCODE
701
- )
702
- for each_pass_number in range(1, maximum_passes + 1):
703
- last_review_outcome, maybe_mint_outcome = _run_one_stamp_mint_pass(
704
- store_module=store_module,
705
- live_surface_hash=live_surface_hash,
706
- working_directory=working_directory,
707
- timeout_seconds=timeout_seconds,
708
- effort=effort,
709
- pass_number=each_pass_number,
710
- )
711
- if maybe_mint_outcome is not None:
712
- return maybe_mint_outcome
713
- return _unminted_pass_outcome(last_review_outcome, maximum_passes)
714
-
715
-
716
- def invoke_code_review_and_record_stamp(
717
- *,
718
- working_directory: Path,
719
- session_model: str,
720
- timeout_seconds: int,
721
- effort: str,
722
- maximum_passes: int = MAXIMUM_STAMP_MINT_PASSES,
723
- ) -> StampMintOutcome:
724
- """Force chain review passes until the surface is stable, then mint a stamp.
725
-
726
- Args:
727
- working_directory: PR working tree used as cwd for each chain spawn.
728
- session_model: Session model short alias (unused; chain mode forced).
729
- timeout_seconds: Timeout applied to each chain binary invocation.
730
- effort: Effort token the clean review records on the stamp.
731
- maximum_passes: Hard cap on review passes before giving up.
732
-
733
- Returns:
734
- A StampMintOutcome for the last review and whether a stamp was minted.
735
- """
736
- del session_model
737
- store_module = load_code_review_stamp_store()
738
- return _iterate_stamp_mint_passes(
739
- store_module=store_module,
740
- live_surface_hash=getattr(store_module, STAMP_STORE_LIVE_SURFACE_HASH_NAME),
741
- working_directory=working_directory,
742
- timeout_seconds=timeout_seconds,
743
- effort=effort,
744
- maximum_passes=maximum_passes,
745
- )
746
-
747
-
748
431
  def encode_code_review_outcome(
749
432
  review_outcome: CodeReviewOutcome,
750
433
  ) -> dict[str, object]:
@@ -764,27 +447,6 @@ def encode_code_review_outcome(
764
447
  }
765
448
 
766
449
 
767
- def encode_stamp_mint_outcome(
768
- mint_outcome: StampMintOutcome,
769
- ) -> dict[str, object]:
770
- """Encode a stamp-mint outcome as the JSON-serializable payload.
771
-
772
- Args:
773
- mint_outcome: The ``--record-stamp`` outcome to encode.
774
-
775
- Returns:
776
- A plain dict with the review fields plus mint metadata.
777
- """
778
- encoded_payload = encode_code_review_outcome(mint_outcome.review_outcome)
779
- encoded_payload[RESULT_KEY_STAMP_MINTED] = mint_outcome.is_stamp_minted
780
- encoded_payload[RESULT_KEY_PASS_COUNT] = mint_outcome.pass_count
781
- encoded_payload[RESULT_KEY_BOUND_HASH] = mint_outcome.bound_hash
782
- if not mint_outcome.is_stamp_minted:
783
- if mint_outcome.pass_count >= MAXIMUM_STAMP_MINT_PASSES:
784
- encoded_payload[RESULT_KEY_RETURNCODE] = STAMP_DID_NOT_CONVERGE_RETURNCODE
785
- return encoded_payload
786
-
787
-
788
450
  def _add_review_arguments(parser: argparse.ArgumentParser) -> None:
789
451
  parser.add_argument(
790
452
  CWD_FLAG,
@@ -808,13 +470,7 @@ def _add_review_arguments(parser: argparse.ArgumentParser) -> None:
808
470
  )
809
471
 
810
472
 
811
- def _add_stamp_and_effort_arguments(parser: argparse.ArgumentParser) -> None:
812
- parser.add_argument(
813
- RECORD_STAMP_FLAG,
814
- dest="is_record_stamp",
815
- action="store_true",
816
- help=CLI_RECORD_STAMP_HELP,
817
- )
473
+ def _add_effort_argument(parser: argparse.ArgumentParser) -> None:
818
474
  parser.add_argument(
819
475
  CLI_EFFORT_METAVAR,
820
476
  nargs="?",
@@ -830,7 +486,7 @@ def _build_argument_parser() -> argparse.ArgumentParser:
830
486
  )
831
487
  )
832
488
  _add_review_arguments(parser)
833
- _add_stamp_and_effort_arguments(parser)
489
+ _add_effort_argument(parser)
834
490
  return parser
835
491
 
836
492
 
@@ -842,96 +498,6 @@ def _emit_invalid_effort_and_exit_code(effort: str) -> int:
842
498
  return INVALID_EFFORT_RETURNCODE
843
499
 
844
500
 
845
- def _import_failure_payload() -> dict[str, object]:
846
- failure_outcome = _failure_code_review_outcome(INVALID_EFFORT_RETURNCODE)
847
- encoded_payload = encode_code_review_outcome(failure_outcome)
848
- encoded_payload[RESULT_KEY_STAMP_MINTED] = False
849
- encoded_payload[RESULT_KEY_PASS_COUNT] = 0
850
- encoded_payload[RESULT_KEY_BOUND_HASH] = None
851
- return encoded_payload
852
-
853
-
854
- def _no_mint_outcome(returncode: int) -> StampMintOutcome:
855
- return StampMintOutcome(
856
- review_outcome=_failure_code_review_outcome(returncode),
857
- is_stamp_minted=False,
858
- pass_count=0,
859
- bound_hash=None,
860
- )
861
-
862
-
863
- def _mint_or_config_outcome(
864
- *,
865
- working_directory: Path,
866
- session_model: str,
867
- timeout_seconds: int,
868
- effort: str,
869
- ) -> StampMintOutcome:
870
- try:
871
- return invoke_code_review_and_record_stamp(
872
- working_directory=working_directory,
873
- session_model=session_model,
874
- timeout_seconds=timeout_seconds,
875
- effort=effort,
876
- )
877
- except ChainConfigurationError as configuration_error:
878
- sys.stderr.write(str(configuration_error) + "\n")
879
- return _no_mint_outcome(CHAIN_CONFIG_ERROR_EXIT_CODE)
880
- except ValueError as host_profile_error:
881
- sys.stderr.write(str(host_profile_error) + "\n")
882
- return _no_mint_outcome(HOST_PROFILE_ERROR_RETURNCODE)
883
-
884
-
885
- def _emit_import_failure(import_error: ModuleNotFoundError) -> int:
886
- sys.stderr.write(
887
- STAMP_STORE_IMPORT_FAILURE_MESSAGE.format(error=import_error) + "\n"
888
- )
889
- sys.stdout.write(json.dumps(_import_failure_payload()) + "\n")
890
- return INVALID_EFFORT_RETURNCODE
891
-
892
-
893
- def _record_stamp_exit_code(mint_outcome: StampMintOutcome) -> int:
894
- if mint_outcome.is_stamp_minted:
895
- return mint_outcome.review_outcome.returncode
896
- if mint_outcome.pass_count >= MAXIMUM_STAMP_MINT_PASSES:
897
- return STAMP_DID_NOT_CONVERGE_RETURNCODE
898
- return mint_outcome.review_outcome.returncode
899
-
900
-
901
- def _emit_mint_outcome(mint_outcome: StampMintOutcome) -> int:
902
- encoded_payload = encode_stamp_mint_outcome(mint_outcome)
903
- did_not_converge = (
904
- not mint_outcome.is_stamp_minted
905
- and mint_outcome.pass_count >= MAXIMUM_STAMP_MINT_PASSES
906
- )
907
- if did_not_converge:
908
- sys.stderr.write(
909
- STAMP_DID_NOT_CONVERGE_MESSAGE.format(pass_count=mint_outcome.pass_count)
910
- + "\n"
911
- )
912
- sys.stdout.write(json.dumps(encoded_payload) + "\n")
913
- return _record_stamp_exit_code(mint_outcome)
914
-
915
-
916
- def _run_record_stamp_cli(
917
- *,
918
- working_directory: Path,
919
- session_model: str,
920
- timeout_seconds: int,
921
- effort: str,
922
- ) -> int:
923
- try:
924
- mint_outcome = _mint_or_config_outcome(
925
- working_directory=working_directory,
926
- session_model=session_model,
927
- timeout_seconds=timeout_seconds,
928
- effort=effort,
929
- )
930
- except ModuleNotFoundError as import_error:
931
- return _emit_import_failure(import_error)
932
- return _emit_mint_outcome(mint_outcome)
933
-
934
-
935
501
  def _run_plain_review_cli(*, parsed_arguments: argparse.Namespace, effort: str) -> int:
936
502
  try:
937
503
  review_outcome = invoke_code_review(
@@ -951,9 +517,7 @@ def _run_plain_review_cli(*, parsed_arguments: argparse.Namespace, effort: str)
951
517
  def main(all_command_arguments: list[str]) -> int:
952
518
  """Run the invoker for CLI arguments and print the JSON outcome.
953
519
 
954
- ``--record-stamp`` forces chain mode and mints only on a surface-stable
955
- returncode-0 pass; an unknown or ``ultra`` effort exits non-zero before any
956
- review runs.
520
+ An unknown or ``ultra`` effort exits non-zero before any review runs.
957
521
 
958
522
  Args:
959
523
  all_command_arguments: The argument vector after the program name.
@@ -968,13 +532,6 @@ def main(all_command_arguments: list[str]) -> int:
968
532
  invalid_effort_exit_code = _emit_invalid_effort_and_exit_code(effort_token)
969
533
  if invalid_effort_exit_code != SUCCESSFUL_REVIEW_RETURNCODE:
970
534
  return invalid_effort_exit_code
971
- if parsed_arguments.is_record_stamp:
972
- return _run_record_stamp_cli(
973
- working_directory=parsed_arguments.working_directory,
974
- session_model=parsed_arguments.session_model,
975
- timeout_seconds=parsed_arguments.timeout_seconds,
976
- effort=effort_token,
977
- )
978
535
  return _run_plain_review_cli(parsed_arguments=parsed_arguments, effort=effort_token)
979
536
 
980
537
 
@@ -0,0 +1,23 @@
1
+ # sync_to_cursor
2
+
3
+ Python package that syncs Claude rules and docs to Cursor `.mdc` files. Entry point is `packages/claude-dev-env/scripts/sync_to_cursor.py`; this package holds the implementation modules.
4
+
5
+ ## Modules
6
+
7
+ | File | Purpose |
8
+ |---|---|
9
+ | `engine.py` | Main sync logic: loads the manifest, builds rule mappings, hashes sources, writes `.mdc` files, and updates the manifest |
10
+ | `rules.py` | Builds `RuleMapping` objects from Claude rule markdown files; applies transforms to fit Cursor's `.mdc` format |
11
+ | `canonical_docs.py` | Checks and syncs canonical documentation files (`CODE_RULES.md`, `TEST_QUALITY.md`) to the Cursor rules directory |
12
+ | `paths.py` | Resolves the Claude and Cursor layout paths; respects the `LLM_SETTINGS_ROOT` env var for non-home layouts |
13
+ | `hashing.py` | SHA-256 helpers that detect whether source files changed since the last sync run |
14
+ | `config.py` | Package-level constants: `GENERATOR_VERSION`, `CANONICAL_DOC_FILES`, `MAX_RULE_BODY_LINES` |
15
+ | `__init__.py` | Empty package marker |
16
+
17
+ ## Layout resolution
18
+
19
+ `paths.py` reads `LLM_SETTINGS_ROOT` from the environment. When set, it uses that path as the base for both `.claude/` and `.cursor/`. When unset, it falls back to `Path.home()`.
20
+
21
+ ## Tests
22
+
23
+ Tests live in `packages/claude-dev-env/scripts/tests/test_sync_to_cursor.py`.
@@ -1,23 +1 @@
1
- # sync_to_cursor
2
-
3
- Python package that syncs Claude rules and docs to Cursor `.mdc` files. Entry point is `packages/claude-dev-env/scripts/sync_to_cursor.py`; this package holds the implementation modules.
4
-
5
- ## Modules
6
-
7
- | File | Purpose |
8
- |---|---|
9
- | `engine.py` | Main sync logic: loads the manifest, builds rule mappings, hashes sources, writes `.mdc` files, and updates the manifest |
10
- | `rules.py` | Builds `RuleMapping` objects from Claude rule markdown files; applies transforms to fit Cursor's `.mdc` format |
11
- | `canonical_docs.py` | Checks and syncs canonical documentation files (`CODE_RULES.md`, `TEST_QUALITY.md`) to the Cursor rules directory |
12
- | `paths.py` | Resolves the Claude and Cursor layout paths; respects the `LLM_SETTINGS_ROOT` env var for non-home layouts |
13
- | `hashing.py` | SHA-256 helpers that detect whether source files changed since the last sync run |
14
- | `config.py` | Package-level constants: `GENERATOR_VERSION`, `CANONICAL_DOC_FILES`, `MAX_RULE_BODY_LINES` |
15
- | `__init__.py` | Empty package marker |
16
-
17
- ## Layout resolution
18
-
19
- `paths.py` reads `LLM_SETTINGS_ROOT` from the environment. When set, it uses that path as the base for both `.claude/` and `.cursor/`. When unset, it falls back to `Path.home()`.
20
-
21
- ## Tests
22
-
23
- Tests live in `packages/claude-dev-env/scripts/tests/test_sync_to_cursor.py`.
1
+ @AGENTS.md