claude-dev-env 4.3.0 → 7.1.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 (480) hide show
  1. package/.agents/agents/pr-description-writer.md +2 -2
  2. package/.agents/agents/test_agent_frontmatter.py +2 -2
  3. package/.agents/agents/test_pr_description_writer_style.py +1 -3
  4. package/.agents/skills/e-code-review/SKILL.md +12 -12
  5. package/.agents/skills/e-code-review/preflight-proposal.contract.test.mjs +20 -0
  6. package/.agents/skills/e-code-review/reference/fix.md +15 -17
  7. package/.agents/skills/e-code-review/reference/loop.md +35 -39
  8. package/.agents/skills/e-code-review/reference/mode-contract.test.mjs +2 -1
  9. package/.agents/skills/e-code-review/reference/preflight-proposal.md +44 -9
  10. package/.agents/skills/e-code-review/reference/runner-selection.md +13 -14
  11. package/.agents/skills/issue-tracker/SKILL.md +5 -4
  12. package/.agents/skills/pull-request/SKILL.md +11 -13
  13. package/.agents/skills/pull-request/reference/publication-tasks.md +3 -3
  14. package/.agents/skills/pull-request/scripts/github_pr_command_constants/config/constants.py +9 -1
  15. package/.agents/skills/pull-request/scripts/pull_request.py +35 -44
  16. package/.agents/skills/pull-request/scripts/test_github_pr_command_constants.py +9 -0
  17. package/.agents/skills/pull-request/scripts/test_pull_request.py +35 -3
  18. package/.agents/skills/session-continuity/README.md +189 -0
  19. package/.agents/skills/session-continuity/SKILL.md +114 -0
  20. package/.agents/skills/session-continuity/continuity.mjs +375 -0
  21. package/.agents/skills/session-continuity/continuity.test.mjs +303 -0
  22. package/.agents/skills/skill-builder/SKILL.md +3 -196
  23. package/.agents/skills/syncing-submodules/scripts/test_sync_parent_pointer.py +0 -7
  24. package/.agents/skills/windows-scheduled-task/SKILL.md +153 -0
  25. package/_shared/pr-loop/scripts/pr_loop_shared_constants/terminology_sweep_constants.py +6 -0
  26. package/_shared/pr-loop/scripts/terminology_sweep.py +64 -19
  27. package/_shared/pr-loop/scripts/tests/test_terminology_sweep.py +59 -0
  28. package/bin/cde.mjs +36 -8
  29. package/bin/cde.test.mjs +48 -0
  30. package/bin/ever-shipped-skills.mjs +2 -20
  31. package/bin/ever-shipped-skills.test.mjs +8 -0
  32. package/bin/expand_home_directory_tokens.mjs +4 -5
  33. package/bin/expand_home_directory_tokens.test.mjs +128 -0
  34. package/bin/git_hooks_installer.mjs +22 -3
  35. package/bin/git_hooks_installer.test.mjs +159 -5
  36. package/bin/install-session-continuity.mjs +78 -0
  37. package/bin/install-session-continuity.test.mjs +42 -0
  38. package/bin/install.agents-home.test.mjs +15 -13
  39. package/bin/install.codex-rules.test.mjs +5 -2
  40. package/bin/install.cursor-rules.test.mjs +5 -2
  41. package/bin/install.mjs +506 -63
  42. package/bin/install.policy-lint.test.mjs +130 -0
  43. package/bin/install.profiles.test.mjs +10 -0
  44. package/bin/install.prune.test.mjs +286 -37
  45. package/bin/install.pstack-plugin.test.mjs +114 -0
  46. package/bin/install.test.mjs +537 -120
  47. package/bin/install.transaction.test.mjs +3 -3
  48. package/bin/refresh-pstack-plugin-skills.test.mjs +211 -0
  49. package/docs/CODE_RULES.md +1 -1
  50. package/hooks/advisory/pr_done_reminder.py +342 -0
  51. package/hooks/advisory/test_pr_done_reminder.py +249 -0
  52. package/hooks/blocking/bash_post_call_dispatcher.py +53 -6
  53. package/hooks/blocking/code_rules_banned_identifiers.py +3 -0
  54. package/hooks/blocking/code_rules_paired_test.py +22 -15
  55. package/hooks/blocking/precommit_code_rules_gate.py +5 -8
  56. package/hooks/blocking/test_bash_dispatcher_interpreter_starts.py +7 -52
  57. package/hooks/blocking/test_bash_post_call_dispatcher.py +65 -4
  58. package/hooks/blocking/test_bash_pre_tool_use_dispatcher.py +0 -69
  59. package/hooks/blocking/test_code_rules_banned_identifiers.py +64 -0
  60. package/hooks/blocking/test_code_rules_enforcer_paired_test.py +36 -29
  61. package/hooks/blocking/test_code_rules_js_resume_task_enumeration.py +4 -4
  62. package/hooks/blocking/test_code_rules_js_returns_object_schemaless.py +5 -5
  63. package/hooks/blocking/test_pre_tool_use_dispatcher.py +43 -342
  64. package/hooks/blocking/test_pre_tool_use_dispatcher_native.py +20 -51
  65. package/hooks/blocking/test_shared_stdin_adoption.py +1 -47
  66. package/hooks/git-hooks/git_hooks_constants/staged_policy_lint.py +12 -0
  67. package/hooks/git-hooks/git_hooks_constants/verification_notice_constants.py +116 -0
  68. package/hooks/git-hooks/post_commit.py +33 -0
  69. package/hooks/git-hooks/pre_commit.py +18 -49
  70. package/hooks/git-hooks/pre_push.py +45 -541
  71. package/hooks/git-hooks/test_installed_policy_lint.py +208 -0
  72. package/hooks/git-hooks/test_native_hook_support.py +129 -0
  73. package/hooks/git-hooks/test_native_policy_commit.py +120 -0
  74. package/hooks/git-hooks/test_post_commit.py +43 -0
  75. package/hooks/git-hooks/test_pre_commit.py +38 -148
  76. package/hooks/git-hooks/test_pre_push.py +48 -1631
  77. package/hooks/git-hooks/test_verification_notice.py +60 -0
  78. package/hooks/git-hooks/test_verification_start.py +173 -0
  79. package/hooks/git-hooks/verification_notice.py +192 -0
  80. package/hooks/git-hooks/verification_notice_context.py +253 -0
  81. package/hooks/git-hooks/verification_notice_state.py +237 -0
  82. package/hooks/git-hooks/verification_start.py +100 -0
  83. package/hooks/hooks.json +1 -120
  84. package/hooks/hooks_constants/banned_identifiers_constants.py +4 -0
  85. package/hooks/hooks_constants/bash_post_call_dispatcher_constants.py +14 -1
  86. package/hooks/hooks_constants/bash_pre_tool_use_dispatcher_constants.py +1 -15
  87. package/hooks/hooks_constants/post_tool_use_dispatcher_constants.py +0 -4
  88. package/hooks/hooks_constants/pr_done_reminder_constants.py +98 -0
  89. package/hooks/hooks_constants/pre_tool_use_dispatcher_constants.py +10 -93
  90. package/hooks/hooks_constants/stop_dispatcher_constants.py +1 -4
  91. package/hooks/hooks_constants/test_bash_post_call_dispatcher_constants.py +19 -2
  92. package/hooks/hooks_constants/test_bash_pre_tool_use_dispatcher_constants.py +3 -66
  93. package/hooks/hooks_constants/test_pr_done_reminder_constants.py +40 -0
  94. package/hooks/hooks_constants/test_pre_tool_use_dispatcher_constants.py +46 -201
  95. package/hooks/hooks_constants/test_stop_dispatcher_constants.py +3 -25
  96. package/hooks/validation/test_post_tool_use_dispatcher.py +35 -298
  97. package/hooks/validators/run_all_validators.py +5 -1
  98. package/hooks/validators/security_checks.py +57 -2
  99. package/hooks/validators/test_hook_timing_harness.py +2 -5
  100. package/hooks/validators/test_run_all_validators_mutation_tool_parity.py +3 -11
  101. package/hooks/validators/test_run_all_validators_policy_lint.py +36 -0
  102. package/hooks/validators/test_security_checks.py +57 -0
  103. package/package.json +2 -2
  104. package/rules/confirm-implementation-forks.md +2 -0
  105. package/rules/durable-post-artifacts.md +2 -1
  106. package/rules/git-workflow.md +18 -6
  107. package/rules/pstack-host-mapping.md +48 -0
  108. package/rules/vault-context.md +3 -5
  109. package/rules/verify-runtime-state.md +7 -0
  110. package/scripts/audit-hooks-cli.mjs +5 -0
  111. package/scripts/audit-hooks.mjs +72 -16
  112. package/scripts/automatic_advisory/__init__.py +1 -0
  113. package/scripts/automatic_advisory/checkout.py +51 -0
  114. package/scripts/automatic_advisory/cli.py +334 -0
  115. package/scripts/automatic_advisory/config/__init__.py +1 -0
  116. package/scripts/automatic_advisory/config/constants.py +93 -0
  117. package/scripts/automatic_advisory/config/timing.py +4 -0
  118. package/scripts/automatic_advisory/configuration.py +197 -0
  119. package/scripts/automatic_advisory/execution.py +350 -0
  120. package/scripts/automatic_advisory/git.py +69 -0
  121. package/scripts/automatic_advisory/model.py +107 -0
  122. package/scripts/automatic_advisory/process_host.py +32 -0
  123. package/scripts/automatic_advisory/publisher.py +84 -0
  124. package/scripts/automatic_advisory/runner.py +399 -0
  125. package/scripts/automatic_advisory/state.py +116 -0
  126. package/scripts/automatic_advisory/window_flags.py +41 -0
  127. package/scripts/automatic_advisory/windows_job.py +122 -0
  128. package/scripts/check.ps1 +0 -1
  129. package/{.agents/skills/run-claude-dev-env/driver.mjs → scripts/ci/installer-lifecycle.mjs} +3 -28
  130. package/scripts/ci/installer-lifecycle.test.mjs +26 -0
  131. package/scripts/ci/windows-installer-lifecycle.ps1 +1 -11
  132. package/scripts/codex_compat_materializer.py +99 -13
  133. package/scripts/dev_env_scripts_constants/shared_tree_constants.py +4 -5
  134. package/{.agents/skills/_shared/pr-loop/scripts → scripts}/durable_post_lint.py +35 -43
  135. package/{.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/durable_post_lint_constants.py → scripts/durable_post_lint_config/config/constants.py} +10 -10
  136. package/{.agents/skills/_shared/pr-loop/scripts/test_durable_post_lint_constants.py → scripts/durable_post_lint_config/config/test_constants.py} +14 -1
  137. package/scripts/local_report_cli.py +184 -0
  138. package/scripts/local_report_core.py +247 -0
  139. package/scripts/local_report_publisher.py +12 -0
  140. package/scripts/local_report_validation.py +357 -0
  141. package/scripts/local_verification/__init__.py +23 -0
  142. package/scripts/local_verification/check_runner.py +364 -0
  143. package/scripts/local_verification/check_support.py +99 -0
  144. package/scripts/local_verification/cli.py +158 -0
  145. package/scripts/local_verification/command_runner.py +84 -0
  146. package/scripts/local_verification/config/__init__.py +1 -0
  147. package/scripts/local_verification/config/constants.py +89 -0
  148. package/scripts/local_verification/config/timing.py +1 -0
  149. package/scripts/local_verification/git_state.py +146 -0
  150. package/scripts/local_verification/manifest.py +224 -0
  151. package/scripts/local_verification/model.py +174 -0
  152. package/scripts/local_verification/runner.py +234 -0
  153. package/scripts/policy_lint/adapter_detectors.py +13 -6
  154. package/scripts/policy_lint/adapter_pairing.py +58 -3
  155. package/scripts/policy_lint/adapters.py +7 -4
  156. package/scripts/policy_lint/config/approved_test_pairs.py +323 -0
  157. package/scripts/policy_lint/config/constants.py +5 -0
  158. package/scripts/policy_lint/engine.py +48 -4
  159. package/scripts/policy_lint/model.py +1 -0
  160. package/scripts/policy_lint/registry.py +1 -1
  161. package/scripts/policy_lint/selection.py +2 -1
  162. package/scripts/policy_lint/selection_git.py +2 -0
  163. package/scripts/pr_verification/__init__.py +1 -0
  164. package/scripts/pr_verification/branch_refs.py +114 -0
  165. package/scripts/pr_verification/config/__init__.py +1 -0
  166. package/scripts/pr_verification/config/constants.py +84 -0
  167. package/scripts/pr_verification/config/timing.py +5 -0
  168. package/scripts/pr_verification/github.py +137 -0
  169. package/scripts/pr_verification/github_api.py +376 -0
  170. package/scripts/pr_verification/github_labels.py +88 -0
  171. package/scripts/pr_verification/github_parsing.py +182 -0
  172. package/scripts/pr_verification/github_transport.py +91 -0
  173. package/scripts/pr_verification/lock.py +122 -0
  174. package/scripts/pr_verification/model.py +43 -0
  175. package/scripts/pr_verification/requirements.txt +1 -0
  176. package/scripts/refresh_pstack_plugin_skills.mjs +200 -0
  177. package/scripts/shared_tree_paths.py +32 -3
  178. package/{.agents/skills/_shared/pr-loop/scripts → scripts}/test_durable_post_lint.py +97 -0
  179. package/scripts/test_shared_tree_paths.py +33 -0
  180. package/scripts/tests/test-audit-hooks-cli.mjs +150 -0
  181. package/scripts/tests/test-audit-hooks.mjs +94 -2
  182. package/scripts/tests/test_automatic_advisory.py +376 -0
  183. package/scripts/tests/test_automatic_advisory_job_cleanup.py +71 -0
  184. package/scripts/tests/test_automatic_advisory_polling.py +216 -0
  185. package/scripts/tests/test_automatic_advisory_recovery.py +320 -0
  186. package/scripts/tests/test_automatic_advisory_repairs.py +400 -0
  187. package/scripts/tests/test_automatic_advisory_settings.py +48 -0
  188. package/scripts/tests/test_automatic_advisory_window_flags.py +163 -0
  189. package/scripts/tests/test_closed_pr_label.py +157 -0
  190. package/scripts/tests/test_codex_compat_materializer.py +189 -6
  191. package/scripts/tests/test_github_labels.py +101 -0
  192. package/scripts/tests/test_github_transport.py +125 -0
  193. package/scripts/tests/test_local_report_publisher.py +396 -0
  194. package/scripts/tests/test_local_report_publisher_cli.py +85 -0
  195. package/scripts/tests/test_local_verification.py +348 -0
  196. package/scripts/tests/test_local_verification_cli.py +98 -0
  197. package/scripts/tests/test_policy_lint_rules_archive.py +120 -0
  198. package/scripts/tests/test_policy_lint_rules_engine.py +25 -4
  199. package/scripts/tests/test_policy_lint_rules_installed_loader.py +29 -0
  200. package/scripts/tests/test_policy_lint_rules_pairing.py +163 -0
  201. package/scripts/tests/test_policy_lint_rules_registry.py +227 -13
  202. package/scripts/tests/test_policy_lint_selection.py +25 -2
  203. package/scripts/tests/test_policy_lint_selection_native_index.py +30 -0
  204. package/scripts/tests/test_pr_verification_github.py +392 -0
  205. package/scripts/tests/test_pr_verification_lock.py +168 -0
  206. package/scripts/tests/test_rules.py +3 -7
  207. package/scripts/tests/test_verification_notice.py +347 -0
  208. package/.agents/skills/_shared/pr-loop/.claude/CLAUDE.md +0 -1
  209. package/.agents/skills/_shared/pr-loop/audit-contract.md +0 -5
  210. package/.agents/skills/_shared/pr-loop/audit-reply-template.md +0 -5
  211. package/.agents/skills/_shared/pr-loop/code-rules-gate.md +0 -5
  212. package/.agents/skills/_shared/pr-loop/fix-protocol.md +0 -5
  213. package/.agents/skills/_shared/pr-loop/gh-payloads.md +0 -5
  214. package/.agents/skills/_shared/pr-loop/portable-driver.md +0 -149
  215. package/.agents/skills/_shared/pr-loop/post-audit-thread-contract.md +0 -5
  216. package/.agents/skills/_shared/pr-loop/precatch-rubric.md +0 -5
  217. package/.agents/skills/_shared/pr-loop/preflight-proposal.contract.test.mjs +0 -119
  218. package/.agents/skills/_shared/pr-loop/preflight-proposal.md +0 -5
  219. package/.agents/skills/_shared/pr-loop/prompts/.claude/CLAUDE.md +0 -1
  220. package/.agents/skills/_shared/pr-loop/prompts/AGENTS.md +0 -1
  221. package/.agents/skills/_shared/pr-loop/prompts/pr-consistency-audit.xml +0 -324
  222. package/.agents/skills/_shared/pr-loop/scripts/.claude/CLAUDE.md +0 -1
  223. package/.agents/skills/_shared/pr-loop/scripts/AGENTS.md +0 -1
  224. package/.agents/skills/_shared/pr-loop/scripts/RUNTIME_SCRIPTS.md +0 -29
  225. package/.agents/skills/_shared/pr-loop/scripts/_cli_utils.py +0 -22
  226. package/.agents/skills/_shared/pr-loop/scripts/_path_resolver.py +0 -186
  227. package/.agents/skills/_shared/pr-loop/scripts/_xml_utils.py +0 -20
  228. package/.agents/skills/_shared/pr-loop/scripts/audit_category_schema.py +0 -355
  229. package/.agents/skills/_shared/pr-loop/scripts/build_audit_prompt.py +0 -289
  230. package/.agents/skills/_shared/pr-loop/scripts/build_converge_task_list.py +0 -310
  231. package/.agents/skills/_shared/pr-loop/scripts/build_fix_prompt.py +0 -292
  232. package/.agents/skills/_shared/pr-loop/scripts/init_loop_state.py +0 -134
  233. package/.agents/skills/_shared/pr-loop/scripts/portable_converge_driver.py +0 -1646
  234. package/.agents/skills/_shared/pr-loop/scripts/preflight_worktree.py +0 -392
  235. package/.agents/skills/_shared/pr-loop/scripts/select_converge_pacer.py +0 -215
  236. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/.claude/CLAUDE.md +0 -1
  237. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/AGENTS.md +0 -1
  238. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/__init__.py +0 -0
  239. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/audit_category_schema_constants.py +0 -37
  240. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/converge_task_list_constants.py +0 -56
  241. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/handoff_constants.py +0 -45
  242. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/pacer_constants.py +0 -47
  243. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/path_resolver_constants.py +0 -157
  244. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/portable_driver_constants.py +0 -177
  245. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/preflight_constants.py +0 -70
  246. package/.agents/skills/_shared/pr-loop/scripts/teardown_worktrees.py +0 -172
  247. package/.agents/skills/_shared/pr-loop/scripts/test__path_resolver.py +0 -106
  248. package/.agents/skills/_shared/pr-loop/scripts/test_audit_category_schema.py +0 -94
  249. package/.agents/skills/_shared/pr-loop/scripts/test_build_audit_prompt.py +0 -499
  250. package/.agents/skills/_shared/pr-loop/scripts/test_build_converge_task_list.py +0 -140
  251. package/.agents/skills/_shared/pr-loop/scripts/test_build_fix_prompt.py +0 -262
  252. package/.agents/skills/_shared/pr-loop/scripts/test_init_loop_state.py +0 -71
  253. package/.agents/skills/_shared/pr-loop/scripts/test_portable_converge_driver.py +0 -1119
  254. package/.agents/skills/_shared/pr-loop/scripts/test_preflight_worktree.py +0 -287
  255. package/.agents/skills/_shared/pr-loop/scripts/test_select_converge_pacer.py +0 -207
  256. package/.agents/skills/_shared/pr-loop/scripts/test_teardown_worktrees.py +0 -59
  257. package/.agents/skills/_shared/pr-loop/scripts/test_write_handoff.py +0 -201
  258. package/.agents/skills/_shared/pr-loop/scripts/write_audit_outcomes.py +0 -182
  259. package/.agents/skills/_shared/pr-loop/scripts/write_fix_outcomes.py +0 -206
  260. package/.agents/skills/_shared/pr-loop/scripts/write_handoff.py +0 -309
  261. package/.agents/skills/_shared/pr-loop/state-schema.md +0 -5
  262. package/.agents/skills/_shared/pr-loop/worker-spawn.md +0 -5
  263. package/.agents/skills/autoconverge/.claude/CLAUDE.md +0 -1
  264. package/.agents/skills/autoconverge/AGENTS.md +0 -1
  265. package/.agents/skills/autoconverge/SKILL.md +0 -431
  266. package/.agents/skills/autoconverge/reference/.claude/CLAUDE.md +0 -1
  267. package/.agents/skills/autoconverge/reference/AGENTS.md +0 -1
  268. package/.agents/skills/autoconverge/reference/closing-report.md +0 -93
  269. package/.agents/skills/autoconverge/reference/convergence-gates.md +0 -31
  270. package/.agents/skills/autoconverge/reference/convergence.md +0 -219
  271. package/.agents/skills/autoconverge/reference/copilot-findings.md +0 -51
  272. package/.agents/skills/autoconverge/reference/gotchas.md +0 -66
  273. package/.agents/skills/autoconverge/reference/headless-safety.md +0 -44
  274. package/.agents/skills/autoconverge/reference/multi-pr.md +0 -128
  275. package/.agents/skills/autoconverge/reference/self-closing-loop.md +0 -84
  276. package/.agents/skills/autoconverge/reference/stop-conditions.md +0 -127
  277. package/.agents/skills/autoconverge/test_portable_pacer_gate.py +0 -54
  278. package/.agents/skills/autoconverge/workflow/.claude/CLAUDE.md +0 -1
  279. package/.agents/skills/autoconverge/workflow/AGENTS.md +0 -1
  280. package/.agents/skills/autoconverge/workflow/aggregate_runs.py +0 -371
  281. package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/.claude/CLAUDE.md +0 -1
  282. package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/AGENTS.md +0 -1
  283. package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/__init__.py +0 -0
  284. package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/render_report_constants.py +0 -250
  285. package/.agents/skills/autoconverge/workflow/converge.clean-audit.test.mjs +0 -665
  286. package/.agents/skills/autoconverge/workflow/converge.codex-gate.test.mjs +0 -472
  287. package/.agents/skills/autoconverge/workflow/converge.contract.test.mjs +0 -64
  288. package/.agents/skills/autoconverge/workflow/converge.copilot-gate.test.mjs +0 -1009
  289. package/.agents/skills/autoconverge/workflow/converge.fix-progress.test.mjs +0 -107
  290. package/.agents/skills/autoconverge/workflow/converge.fix-recovery.test.mjs +0 -33
  291. package/.agents/skills/autoconverge/workflow/converge.merge-conflict.test.mjs +0 -15
  292. package/.agents/skills/autoconverge/workflow/converge.mjs +0 -3132
  293. package/.agents/skills/autoconverge/workflow/converge.p2-advance.test.mjs +0 -202
  294. package/.agents/skills/autoconverge/workflow/converge.path-aware.test.mjs +0 -47
  295. package/.agents/skills/autoconverge/workflow/converge.precatch.test.mjs +0 -152
  296. package/.agents/skills/autoconverge/workflow/converge.run-input.test.mjs +0 -116
  297. package/.agents/skills/autoconverge/workflow/converge_multi.mjs +0 -169
  298. package/.agents/skills/autoconverge/workflow/converge_multi.run-input.test.mjs +0 -173
  299. package/.agents/skills/autoconverge/workflow/convergence_summary.py +0 -110
  300. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a11d903476b803493.jsonl +0 -2
  301. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a26213978adeef6fb.jsonl +0 -2
  302. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a3def0d15ed9d9110.jsonl +0 -2
  303. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a41f41b1b708ee3b7.jsonl +0 -2
  304. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a758b880abecc3ff7.jsonl +0 -2
  305. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a8897b89656b1bd16.jsonl +0 -2
  306. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-ab1c2d3e4f5a6b7c8.jsonl +0 -2
  307. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-abd463d744a1437bc.jsonl +0 -2
  308. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-ad19d027ae8ee1816.jsonl +0 -2
  309. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/workflows/wf_881252e6-700.json +0 -266
  310. package/.agents/skills/autoconverge/workflow/render_report.py +0 -1024
  311. package/.agents/skills/autoconverge/workflow/test_aggregate_runs.py +0 -134
  312. package/.agents/skills/autoconverge/workflow/test_convergence_summary.py +0 -149
  313. package/.agents/skills/autoconverge/workflow/test_render_report.py +0 -812
  314. package/.agents/skills/hitl/SKILL.md +0 -45
  315. package/.agents/skills/pr-cleanup/SKILL.md +0 -140
  316. package/.agents/skills/pr-cleanup/reference/process-inventory.md +0 -17
  317. package/.agents/skills/pr-cleanup/reference/task-seeds.md +0 -22
  318. package/.agents/skills/pr-name-by-capability/SKILL.md +0 -73
  319. package/.agents/skills/pr-name-by-capability/reference/fetch-commands.md +0 -29
  320. package/.agents/skills/pr-name-by-capability/reference/offense-examples.md +0 -32
  321. package/.agents/skills/pr-name-by-capability/reference/report-template.md +0 -29
  322. package/.agents/skills/pr-name-by-capability/reference/rule-checklist.md +0 -38
  323. package/.agents/skills/pr-name-by-capability/reference/task-seeds.md +0 -10
  324. package/.agents/skills/pr-plain-language-cleanup/SKILL.md +0 -93
  325. package/.agents/skills/pr-refinement/SKILL.md +0 -31
  326. package/.agents/skills/pr-shared-extraction/SKILL.md +0 -177
  327. package/.agents/skills/pr-shared-extraction/reference/examples.md +0 -46
  328. package/.agents/skills/pr-shared-extraction/reference/offense-taxonomy.md +0 -100
  329. package/.agents/skills/pr-small-cl/SKILL.md +0 -52
  330. package/.agents/skills/pr-title-description/SKILL.md +0 -96
  331. package/.agents/skills/prototype/SKILL.md +0 -85
  332. package/.agents/skills/prototype/reference/honest-limitations.md +0 -23
  333. package/.agents/skills/prototype/reference/promotion-tasks.md +0 -23
  334. package/.agents/skills/prototype/scripts/build_sandbox_settings.py +0 -249
  335. package/.agents/skills/prototype/scripts/conftest.py +0 -15
  336. package/.agents/skills/prototype/scripts/launch_sandbox.py +0 -205
  337. package/.agents/skills/prototype/scripts/probe_sandbox_safety.py +0 -311
  338. package/.agents/skills/prototype/scripts/prototype_scripts_constants/__init__.py +0 -1
  339. package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/__init__.py +0 -0
  340. package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/build_sandbox_settings_constants.py +0 -41
  341. package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/launch_sandbox_constants.py +0 -23
  342. package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/probe_sandbox_safety_constants.py +0 -45
  343. package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/prototype_common_constants.py +0 -10
  344. package/.agents/skills/prototype/scripts/test_build_sandbox_settings.py +0 -275
  345. package/.agents/skills/prototype/scripts/test_launch_sandbox.py +0 -303
  346. package/.agents/skills/prototype/scripts/test_probe_sandbox_safety.py +0 -312
  347. package/.agents/skills/prototype/workflows/promotion.md +0 -25
  348. package/.agents/skills/prototype/workflows/sandbox.md +0 -35
  349. package/.agents/skills/rebase/.claude/CLAUDE.md +0 -1
  350. package/.agents/skills/rebase/AGENTS.md +0 -1
  351. package/.agents/skills/rebase/SKILL.md +0 -178
  352. package/.agents/skills/review-router/SKILL.md +0 -51
  353. package/.agents/skills/review-router/reference/route-policy.json +0 -7
  354. package/.agents/skills/review-router/reference/task-seeds.md +0 -1
  355. package/.agents/skills/review-router/scripts/conftest.py +0 -4
  356. package/.agents/skills/review-router/scripts/review_router.py +0 -50
  357. package/.agents/skills/review-router/scripts/review_router_cli.py +0 -211
  358. package/.agents/skills/review-router/scripts/review_router_constants/__init__.py +0 -1
  359. package/.agents/skills/review-router/scripts/review_router_constants/config/__init__.py +0 -0
  360. package/.agents/skills/review-router/scripts/review_router_constants/config/constants.py +0 -13
  361. package/.agents/skills/review-router/scripts/test_review_router.py +0 -23
  362. package/.agents/skills/review-router/scripts/test_review_router_cli.py +0 -47
  363. package/.agents/skills/review-tier/SKILL.md +0 -56
  364. package/.agents/skills/review-tier/reference/task-seeds.md +0 -1
  365. package/.agents/skills/review-tier/reference/tier-policy.json +0 -9
  366. package/.agents/skills/review-tier/scripts/conftest.py +0 -4
  367. package/.agents/skills/review-tier/scripts/review_tier.py +0 -359
  368. package/.agents/skills/review-tier/scripts/review_tier_constants/__init__.py +0 -1
  369. package/.agents/skills/review-tier/scripts/review_tier_constants/config/__init__.py +0 -0
  370. package/.agents/skills/review-tier/scripts/review_tier_constants/config/constants.py +0 -29
  371. package/.agents/skills/review-tier/scripts/test_generation.py +0 -159
  372. package/.agents/skills/review-tier/scripts/test_review_tier.py +0 -33
  373. package/.agents/skills/run-claude-dev-env/SKILL.md +0 -84
  374. package/.agents/skills/session-log/.claude/CLAUDE.md +0 -1
  375. package/.agents/skills/session-log/AGENTS.md +0 -1
  376. package/.agents/skills/session-log/SKILL.md +0 -170
  377. package/.agents/skills/session-log/templates/frontmatter.md +0 -40
  378. package/.agents/skills/session-tidy/.claude/CLAUDE.md +0 -1
  379. package/.agents/skills/session-tidy/AGENTS.md +0 -1
  380. package/.agents/skills/session-tidy/SKILL.md +0 -191
  381. package/.agents/skills/skill-builder/references/.claude/CLAUDE.md +0 -1
  382. package/.agents/skills/skill-builder/references/AGENTS.md +0 -1
  383. package/.agents/skills/skill-builder/references/delegation-map.md +0 -130
  384. package/.agents/skills/skill-builder/references/description-field.md +0 -111
  385. package/.agents/skills/skill-builder/references/deterministic-elements.md +0 -218
  386. package/.agents/skills/skill-builder/references/progressive-disclosure.md +0 -122
  387. package/.agents/skills/skill-builder/references/self-audit-checklist.md +0 -126
  388. package/.agents/skills/skill-builder/references/skill-modularity.md +0 -111
  389. package/.agents/skills/skill-builder/references/skill-types.md +0 -232
  390. package/.agents/skills/skill-builder/references/thariq-x-post-skills.json +0 -33
  391. package/.agents/skills/skill-builder/templates/.claude/CLAUDE.md +0 -1
  392. package/.agents/skills/skill-builder/templates/AGENTS.md +0 -1
  393. package/.agents/skills/skill-builder/templates/gap-analysis.md +0 -87
  394. package/.agents/skills/skill-builder/workflows/.claude/CLAUDE.md +0 -1
  395. package/.agents/skills/skill-builder/workflows/AGENTS.md +0 -1
  396. package/.agents/skills/skill-builder/workflows/improve-skill.md +0 -136
  397. package/.agents/skills/skill-builder/workflows/new-skill.md +0 -179
  398. package/.agents/skills/skill-builder/workflows/polish-skill.md +0 -139
  399. package/.agents/skills/source-command-sr-loop/SKILL.md +0 -82
  400. package/.agents/skills/update/.claude/CLAUDE.md +0 -1
  401. package/.agents/skills/update/AGENTS.md +0 -1
  402. package/.agents/skills/update/SKILL.md +0 -190
  403. package/_shared/pr-loop/AGENTS.md +0 -1
  404. package/_shared/pr-loop/audit-contract.md +0 -183
  405. package/_shared/pr-loop/audit-reply-template.md +0 -151
  406. package/_shared/pr-loop/code-rules-gate.md +0 -65
  407. package/_shared/pr-loop/fix-protocol.md +0 -60
  408. package/_shared/pr-loop/gh-payloads.md +0 -75
  409. package/_shared/pr-loop/post-audit-thread-contract.md +0 -51
  410. package/_shared/pr-loop/precatch-rubric.md +0 -66
  411. package/_shared/pr-loop/preflight-proposal.md +0 -56
  412. package/_shared/pr-loop/scripts/post_audit_thread.py +0 -1242
  413. package/_shared/pr-loop/scripts/pr_loop_shared_constants/post_audit_thread_constants.py +0 -199
  414. package/_shared/pr-loop/scripts/tests/test_post_audit_thread.py +0 -1115
  415. package/_shared/pr-loop/scripts/tests/test_post_audit_thread_constants.py +0 -129
  416. package/_shared/pr-loop/state-schema.md +0 -45
  417. package/_shared/pr-loop/worker-spawn.md +0 -189
  418. package/hooks/blocking/ask_user_question_shape_blocker.py +0 -83
  419. package/hooks/blocking/bot_mention_comment_blocker.py +0 -76
  420. package/hooks/blocking/claude_md_orphan_file_blocker.py +0 -129
  421. package/hooks/blocking/cursor_cli_python_misfire_blocker.py +0 -108
  422. package/hooks/blocking/destructive_command_blocker.py +0 -2073
  423. package/hooks/blocking/fable_spawn_gate.py +0 -187
  424. package/hooks/blocking/luna_fast_mode_gate.py +0 -160
  425. package/hooks/blocking/nas_ssh_binary_enforcer.py +0 -163
  426. package/hooks/blocking/orchestrator_refresh_reschedule_gate.py +0 -260
  427. package/hooks/blocking/package_inventory_stale_blocker.py +0 -107
  428. package/hooks/blocking/pii_prevention_blocker.py +0 -365
  429. package/hooks/blocking/piped_pytest_blocker.py +0 -1223
  430. package/hooks/blocking/question_to_user_enforcer.py +0 -130
  431. package/hooks/blocking/send_user_file_open_locally_blocker.py +0 -71
  432. package/hooks/blocking/sensitive_file_protector.py +0 -167
  433. package/hooks/blocking/session_edit_stage_gate.py +0 -684
  434. package/hooks/blocking/session_handoff_blocker.py +0 -182
  435. package/hooks/blocking/shell_substitution_blocker.py +0 -350
  436. package/hooks/blocking/test_ask_user_question_shape.py +0 -69
  437. package/hooks/blocking/test_bot_mention_comment_blocker.py +0 -131
  438. package/hooks/blocking/test_claude_md_orphan_file_blocker.py +0 -1277
  439. package/hooks/blocking/test_cursor_cli_python_misfire_blocker.py +0 -208
  440. package/hooks/blocking/test_destructive_command_blocker.py +0 -2024
  441. package/hooks/blocking/test_destructive_command_blocker_deny_mode.py +0 -105
  442. package/hooks/blocking/test_destructive_command_blocker_no_verify.py +0 -122
  443. package/hooks/blocking/test_destructive_command_blocker_patterns.py +0 -133
  444. package/hooks/blocking/test_fable_spawn_gate.py +0 -381
  445. package/hooks/blocking/test_inventory_deadlock_resolution.py +0 -154
  446. package/hooks/blocking/test_luna_fast_mode_gate.py +0 -211
  447. package/hooks/blocking/test_nas_ssh_binary_enforcer.py +0 -225
  448. package/hooks/blocking/test_orchestrator_refresh_reschedule_gate.py +0 -231
  449. package/hooks/blocking/test_package_inventory_stale_blocker.py +0 -382
  450. package/hooks/blocking/test_pii_prevention_blocker.py +0 -1222
  451. package/hooks/blocking/test_pii_prevention_windows_git_path.py +0 -41
  452. package/hooks/blocking/test_pii_write_surface_ephemeral.py +0 -221
  453. package/hooks/blocking/test_piped_pytest_blocker.py +0 -587
  454. package/hooks/blocking/test_precommit_code_rules_gate_native_owner.py +0 -233
  455. package/hooks/blocking/test_question_to_user_enforcer.py +0 -169
  456. package/hooks/blocking/test_send_user_file_open_locally_blocker.py +0 -118
  457. package/hooks/blocking/test_sensitive_file_protector.py +0 -365
  458. package/hooks/blocking/test_session_edit_stage_gate.py +0 -537
  459. package/hooks/blocking/test_session_edit_stage_gate_staging.py +0 -64
  460. package/hooks/blocking/test_session_edit_stage_gate_support.py +0 -204
  461. package/hooks/blocking/test_session_edit_stage_gate_tracker.py +0 -116
  462. package/hooks/blocking/test_session_handoff_blocker.py +0 -318
  463. package/hooks/blocking/test_shell_substitution_blocker.py +0 -298
  464. package/hooks/blocking/test_unscoped_search_blocker.py +0 -102
  465. package/hooks/blocking/test_write_existing_file_blocker.py +0 -122
  466. package/hooks/blocking/tests/test_pii_prevention_blocker.py +0 -259
  467. package/hooks/blocking/unscoped_search_blocker.py +0 -391
  468. package/hooks/blocking/write_existing_file_blocker.py +0 -124
  469. package/hooks/hooks_constants/bot_mention_comment_blocker_constants.py +0 -19
  470. package/hooks/hooks_constants/cursor_cli_python_misfire_blocker_constants.py +0 -79
  471. package/hooks/hooks_constants/fable_spawn_gate_constants.py +0 -61
  472. package/hooks/hooks_constants/luna_fast_mode_gate_constants.py +0 -45
  473. package/hooks/hooks_constants/nas_ssh_binary_enforcer_constants.py +0 -20
  474. package/hooks/hooks_constants/orchestrator_refresh_reschedule_gate_constants.py +0 -57
  475. package/hooks/hooks_constants/send_user_file_open_locally_blocker_constants.py +0 -17
  476. package/hooks/hooks_constants/sensitive_file_protector_constants.py +0 -40
  477. package/hooks/hooks_constants/session_handoff_blocker_constants.py +0 -10
  478. package/hooks/hooks_constants/shell_substitution_blocker_constants.py +0 -80
  479. /package/.agents/skills/{_shared/pr-loop → session-continuity}/AGENTS.md +0 -0
  480. /package/{_shared/pr-loop → .agents/skills/session-continuity}/CLAUDE.md +0 -0
@@ -0,0 +1,237 @@
1
+ """Evaluate local verification state for the native Git notice."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import Callable, Mapping
6
+ from pathlib import Path
7
+ from typing import Protocol
8
+
9
+ from git_hooks_constants.verification_notice_constants import (
10
+ ALL_GIT_BASE_QUERY_PREFIX,
11
+ GIT_COMMAND_SUCCESS_EXIT_CODE,
12
+ HEX_DIGITS,
13
+ NOTICE_FAILED_LINE,
14
+ NOTICE_NO_PASS_LINE,
15
+ NOTICE_PASSED_LINE,
16
+ NOTICE_SETUP_PENDING_LINE,
17
+ NOTICE_STALE_LINE,
18
+ REPORT_AGGREGATE_FIELD,
19
+ REPORT_BASE_FIELD,
20
+ REPORT_EXIT_CODE_FIELD,
21
+ REPORT_FAILED_FIELD,
22
+ REPORT_HEAD_FIELD,
23
+ REPORT_INCOMPLETE_FIELD,
24
+ REPORT_INPUTS_UNCHANGED_FIELD,
25
+ REPORT_MANIFEST_DIGEST_FIELD,
26
+ REPORT_PASSED_FIELD,
27
+ REPORT_PUBLISHABLE_FIELD,
28
+ REPORT_STATUS_FIELD,
29
+ REPORT_TOTAL_FIELD,
30
+ REPORT_WORKTREE_CLEAN_FIELD,
31
+ RESOLVED_SHA_LENGTH,
32
+ STATUS_FAILED,
33
+ STATUS_PASSED,
34
+ STATUS_PENDING,
35
+ STATUS_STALE,
36
+ STATUS_UNVERIFIED,
37
+ )
38
+ from local_verification.manifest import (
39
+ ManifestRunFatal,
40
+ compute_manifest_digest,
41
+ load_manifest,
42
+ )
43
+
44
+
45
+ class _VerificationNoticeContext(Protocol):
46
+ @property
47
+ def current_head(self) -> str | None: ...
48
+
49
+ @property
50
+ def repository_root(self) -> Path: ...
51
+
52
+ @property
53
+ def manifest_path(self) -> Path | None: ...
54
+
55
+ @property
56
+ def manifest_is_available(self) -> bool: ...
57
+
58
+ @property
59
+ def report_is_present(self) -> bool: ...
60
+
61
+ @property
62
+ def all_report_fields(self) -> Mapping[str, object] | None: ...
63
+
64
+
65
+ def _evaluate_context(
66
+ context: _VerificationNoticeContext,
67
+ run_git_query: Callable[[Path, tuple[str, ...], bool], str | None],
68
+ ) -> tuple[str, str | None]:
69
+ context_state = _context_setup_state(context)
70
+ if context_state is not None:
71
+ return context_state, None
72
+ if context.current_head is None or context.all_report_fields is None:
73
+ return STATUS_UNVERIFIED, None
74
+ reported_head = _read_text_field(context.all_report_fields, REPORT_HEAD_FIELD)
75
+ if reported_head is None:
76
+ return STATUS_UNVERIFIED, None
77
+ if reported_head != context.current_head:
78
+ return STATUS_STALE, None
79
+ if _read_report_status(context.all_report_fields) == STATUS_FAILED:
80
+ return STATUS_FAILED, None
81
+ if _is_complete_pass(context, run_git_query):
82
+ return STATUS_PASSED, context.current_head
83
+ return STATUS_UNVERIFIED, None
84
+
85
+
86
+ def _context_setup_state(context: _VerificationNoticeContext) -> str | None:
87
+ if context.all_report_fields is None:
88
+ return STATUS_UNVERIFIED if context.report_is_present else STATUS_PENDING
89
+ if context.all_report_fields is not None and context.manifest_path is None:
90
+ return STATUS_UNVERIFIED
91
+ if not context.manifest_is_available:
92
+ return STATUS_PENDING
93
+ return None
94
+
95
+
96
+ def _read_text_field(
97
+ all_fields: Mapping[str, object],
98
+ field_name: str,
99
+ ) -> str | None:
100
+ field_text = all_fields.get(field_name)
101
+ if not isinstance(field_text, str):
102
+ return None
103
+ return field_text.strip() or None
104
+
105
+
106
+ def _read_report_status(all_report_fields: Mapping[str, object]) -> str | None:
107
+ status_text = _read_text_field(all_report_fields, REPORT_STATUS_FIELD)
108
+ if status_text:
109
+ return status_text
110
+ all_aggregate_fields = all_report_fields.get(REPORT_AGGREGATE_FIELD)
111
+ if isinstance(all_aggregate_fields, Mapping):
112
+ return _read_text_field(all_aggregate_fields, REPORT_STATUS_FIELD)
113
+ return None
114
+
115
+
116
+ def _build_state_message(state: str, is_manifest_available: bool) -> str:
117
+ if not is_manifest_available:
118
+ return NOTICE_SETUP_PENDING_LINE
119
+ message_by_state = {
120
+ STATUS_STALE: NOTICE_STALE_LINE,
121
+ STATUS_FAILED: NOTICE_FAILED_LINE,
122
+ STATUS_PASSED: NOTICE_PASSED_LINE,
123
+ }
124
+ return message_by_state.get(state, NOTICE_NO_PASS_LINE)
125
+
126
+
127
+ def _is_complete_pass(
128
+ context: _VerificationNoticeContext,
129
+ run_git_query: Callable[[Path, tuple[str, ...], bool], str | None],
130
+ ) -> bool:
131
+ all_report_fields = context.all_report_fields
132
+ if all_report_fields is None or context.manifest_path is None:
133
+ return False
134
+ base_revision = _read_text_field(all_report_fields, REPORT_BASE_FIELD)
135
+ if not _report_has_complete_pass(all_report_fields, base_revision):
136
+ return False
137
+ if base_revision is None or not _base_matches_current(
138
+ context.repository_root,
139
+ base_revision,
140
+ run_git_query,
141
+ ):
142
+ return False
143
+ if not _worktree_is_clean(context.repository_root, run_git_query):
144
+ return False
145
+ if not _manifest_digest_matches(all_report_fields, context.manifest_path):
146
+ return False
147
+ all_aggregate_fields = all_report_fields.get(REPORT_AGGREGATE_FIELD)
148
+ return isinstance(all_aggregate_fields, Mapping) and _aggregate_is_complete_pass(
149
+ all_aggregate_fields
150
+ )
151
+
152
+
153
+ def _report_has_complete_pass(
154
+ all_report_fields: Mapping[str, object],
155
+ base_revision: str | None,
156
+ ) -> bool:
157
+ return (
158
+ _read_report_status(all_report_fields) == STATUS_PASSED
159
+ and _report_is_publishable(all_report_fields)
160
+ and base_revision is not None
161
+ and _is_resolved_sha(base_revision)
162
+ )
163
+
164
+
165
+ def _report_is_publishable(all_report_fields: Mapping[str, object]) -> bool:
166
+ return all(
167
+ all_report_fields.get(each_field) is True
168
+ for each_field in (
169
+ REPORT_PUBLISHABLE_FIELD,
170
+ REPORT_WORKTREE_CLEAN_FIELD,
171
+ REPORT_INPUTS_UNCHANGED_FIELD,
172
+ )
173
+ )
174
+
175
+
176
+ def _base_matches_current(
177
+ repository_root: Path,
178
+ base_revision: str,
179
+ run_git_query: Callable[[Path, tuple[str, ...], bool], str | None],
180
+ ) -> bool:
181
+ current_base_revision = run_git_query(
182
+ repository_root,
183
+ (*ALL_GIT_BASE_QUERY_PREFIX, "origin/main^{commit}"),
184
+ False,
185
+ )
186
+ return current_base_revision == base_revision
187
+
188
+
189
+ def _worktree_is_clean(
190
+ repository_root: Path,
191
+ run_git_query: Callable[[Path, tuple[str, ...], bool], str | None],
192
+ ) -> bool:
193
+ status_text = run_git_query(
194
+ repository_root,
195
+ ("status", "--porcelain=v1", "--untracked-files=all"),
196
+ True,
197
+ )
198
+ return status_text == ""
199
+
200
+
201
+ def _is_resolved_sha(revision_text: str) -> bool:
202
+ return len(revision_text) == RESOLVED_SHA_LENGTH and all(
203
+ each_character.casefold() in HEX_DIGITS for each_character in revision_text
204
+ )
205
+
206
+
207
+ def _manifest_digest_matches(
208
+ all_report_fields: Mapping[str, object],
209
+ manifest_path: Path | None,
210
+ ) -> bool:
211
+ manifest_digest = _read_text_field(all_report_fields, REPORT_MANIFEST_DIGEST_FIELD)
212
+ if not manifest_digest or manifest_path is None:
213
+ return False
214
+ try:
215
+ loaded_manifest = load_manifest(manifest_path)
216
+ actual_digest = compute_manifest_digest(loaded_manifest)
217
+ except (ManifestRunFatal, OSError, UnicodeError, ValueError):
218
+ return False
219
+ return actual_digest == manifest_digest.casefold()
220
+
221
+
222
+ def _aggregate_is_complete_pass(
223
+ all_aggregate_fields: Mapping[str, object],
224
+ ) -> bool:
225
+ total_checks = all_aggregate_fields.get(REPORT_TOTAL_FIELD)
226
+ passed_checks = all_aggregate_fields.get(REPORT_PASSED_FIELD)
227
+ failed_checks = all_aggregate_fields.get(REPORT_FAILED_FIELD)
228
+ incomplete_checks = all_aggregate_fields.get(REPORT_INCOMPLETE_FIELD)
229
+ exit_code = all_aggregate_fields.get(REPORT_EXIT_CODE_FIELD)
230
+ return (
231
+ isinstance(total_checks, int)
232
+ and total_checks > 0
233
+ and passed_checks == total_checks
234
+ and failed_checks == 0
235
+ and incomplete_checks == 0
236
+ and exit_code == GIT_COMMAND_SUCCESS_EXIT_CODE
237
+ )
@@ -0,0 +1,100 @@
1
+ """Start automatic local verification for a supported native Git event."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import subprocess
7
+ import sys
8
+ from pathlib import Path
9
+ from typing import Mapping
10
+
11
+ from git_hooks_constants.verification_notice_constants import (
12
+ ALL_NOTICE_EVENTS,
13
+ ALL_RUNNER_FIELDS,
14
+ AUTOMATIC_ADVISORY_CLI_FILE_NAME,
15
+ AUTOMATIC_ADVISORY_DIRECTORY_NAME,
16
+ CREATE_NO_WINDOW_ATTRIBUTE,
17
+ EXECUTOR_DIRECTORY_NAME,
18
+ GIT_DIRECTORY_NAME,
19
+ JSON_ENCODING,
20
+ LOCAL_VERIFICATION_DIRECTORY_NAME,
21
+ RUNNER_FILE_NAME,
22
+ RUNNER_PYTHON_FIELD,
23
+ RUNNER_SETTINGS_FIELD,
24
+ TARGET_REPOSITORY_REMOTE,
25
+ WINDOWS_PLATFORM,
26
+ )
27
+ from verification_notice_context import VerificationNoticeContext
28
+
29
+
30
+ def start_automatic_advisory(context: VerificationNoticeContext) -> None:
31
+ """Start the detached advisory poller when native metadata is valid."""
32
+ if context.repository_remote != TARGET_REPOSITORY_REMOTE:
33
+ return
34
+ if context.event not in ALL_NOTICE_EVENTS:
35
+ return
36
+ runner_configuration = load_runner_configuration(context)
37
+ if runner_configuration is None:
38
+ return
39
+ python_path, settings_path = runner_configuration
40
+ advisory_cli_path = (
41
+ Path(__file__).resolve().parents[2]
42
+ / EXECUTOR_DIRECTORY_NAME
43
+ / AUTOMATIC_ADVISORY_DIRECTORY_NAME
44
+ / AUTOMATIC_ADVISORY_CLI_FILE_NAME
45
+ )
46
+ try:
47
+ _launch_advisory(
48
+ context,
49
+ python_path,
50
+ settings_path,
51
+ advisory_cli_path,
52
+ )
53
+ except (OSError, subprocess.SubprocessError):
54
+ return
55
+
56
+
57
+ def _launch_advisory(
58
+ context: VerificationNoticeContext,
59
+ python_path: str,
60
+ settings_path: str,
61
+ advisory_cli_path: Path,
62
+ ) -> None:
63
+ subprocess.Popen(
64
+ [python_path, str(advisory_cli_path), "--settings", settings_path, "--start"],
65
+ cwd=context.repository_root,
66
+ stdin=subprocess.DEVNULL,
67
+ stdout=subprocess.DEVNULL,
68
+ stderr=subprocess.DEVNULL,
69
+ creationflags=_windows_creation_flags(),
70
+ )
71
+
72
+
73
+ def load_runner_configuration(
74
+ context: VerificationNoticeContext,
75
+ ) -> tuple[str, str] | None:
76
+ git_directory = context.git_directory or context.repository_root / GIT_DIRECTORY_NAME
77
+ runner_path = git_directory / LOCAL_VERIFICATION_DIRECTORY_NAME / RUNNER_FILE_NAME
78
+ try:
79
+ runner_document = json.loads(runner_path.read_text(encoding=JSON_ENCODING))
80
+ except (OSError, UnicodeError, ValueError):
81
+ return None
82
+ if not isinstance(runner_document, Mapping):
83
+ return None
84
+ if set(runner_document) != ALL_RUNNER_FIELDS:
85
+ return None
86
+ python_path = runner_document.get(RUNNER_PYTHON_FIELD)
87
+ settings_path = runner_document.get(RUNNER_SETTINGS_FIELD)
88
+ if not isinstance(python_path, str) or not python_path.strip():
89
+ return None
90
+ if not isinstance(settings_path, str) or not settings_path.strip():
91
+ return None
92
+ if not Path(python_path).is_absolute() or not Path(settings_path).is_absolute():
93
+ return None
94
+ return python_path, settings_path
95
+
96
+
97
+ def _windows_creation_flags() -> int:
98
+ if sys.platform != WINDOWS_PLATFORM:
99
+ return 0
100
+ return getattr(subprocess, CREATE_NO_WINDOW_ATTRIBUTE, 0)
package/hooks/hooks.json CHANGED
@@ -2,16 +2,6 @@
2
2
  "description": "Code standards enforcement, safety guards, and development workflow hooks",
3
3
  "hooks": {
4
4
  "PreToolUse": [
5
- {
6
- "matcher": "Write|Edit|MultiEdit|apply_patch",
7
- "hooks": [
8
- {
9
- "type": "command",
10
- "command": "python3 -c \"import sys; sys.path.insert(0, r'${CLAUDE_PLUGIN_ROOT}/hooks'); from validators.run_all_validators import main; sys.exit(main())\" --pre-tool-use",
11
- "timeout": 30
12
- }
13
- ]
14
- },
15
5
  {
16
6
  "matcher": "Write|Edit|MultiEdit|apply_patch",
17
7
  "hooks": [
@@ -22,91 +12,6 @@
22
12
  }
23
13
  ]
24
14
  },
25
- {
26
- "matcher": "Bash|PowerShell",
27
- "hooks": [
28
- {
29
- "type": "command",
30
- "command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/blocking/bash_pre_tool_use_dispatcher.py",
31
- "timeout": 400
32
- }
33
- ]
34
- },
35
- {
36
- "matcher": "mcp__plugin_github_github__add_issue_comment",
37
- "hooks": [
38
- {
39
- "type": "command",
40
- "command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/blocking/bot_mention_comment_blocker.py",
41
- "timeout": 10
42
- }
43
- ]
44
- },
45
- {
46
- "matcher": "mcp__plugin_github_github__.*",
47
- "hooks": [
48
- {
49
- "type": "command",
50
- "command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/blocking/pii_prevention_blocker.py",
51
- "timeout": 20
52
- }
53
- ]
54
- },
55
- {
56
- "matcher": "Agent|Task",
57
- "hooks": [
58
- {
59
- "type": "command",
60
- "command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/blocking/fable_spawn_gate.py",
61
- "timeout": 10
62
- }
63
- ]
64
- },
65
- {
66
- "matcher": "Agent|Task|multi_agent_v1__spawn_agent",
67
- "hooks": [
68
- {
69
- "type": "command",
70
- "command": "python ${CLAUDE_PLUGIN_ROOT}/hooks/blocking/luna_fast_mode_gate.py",
71
- "timeout": 10
72
- }
73
- ]
74
- },
75
- {
76
- "matcher": "ScheduleWakeup|CronCreate",
77
- "hooks": [
78
- {
79
- "type": "command",
80
- "command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/blocking/orchestrator_refresh_reschedule_gate.py",
81
- "timeout": 15
82
- }
83
- ]
84
- },
85
- {
86
- "matcher": "AskUserQuestion",
87
- "hooks": [
88
- {
89
- "type": "command",
90
- "command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/blocking/plain_language_blocker.py",
91
- "timeout": 10
92
- },
93
- {
94
- "type": "command",
95
- "command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/blocking/ask_user_question_shape_blocker.py",
96
- "timeout": 10
97
- }
98
- ]
99
- },
100
- {
101
- "matcher": "SendUserFile",
102
- "hooks": [
103
- {
104
- "type": "command",
105
- "command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/blocking/send_user_file_open_locally_blocker.py",
106
- "timeout": 10
107
- }
108
- ]
109
- },
110
15
  {
111
16
  "matcher": "EnterWorktree",
112
17
  "hooks": [
@@ -172,18 +77,6 @@
172
77
  ]
173
78
  }
174
79
  ],
175
- "Stop": [
176
- {
177
- "matcher": "",
178
- "hooks": [
179
- {
180
- "type": "command",
181
- "command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/blocking/stop_dispatcher.py",
182
- "timeout": 90
183
- }
184
- ]
185
- }
186
- ],
187
80
  "SessionEnd": [
188
81
  {
189
82
  "matcher": "",
@@ -201,18 +94,6 @@
201
94
  ]
202
95
  }
203
96
  ],
204
- "ConfigChange": [
205
- {
206
- "matcher": "user_settings",
207
- "hooks": [
208
- {
209
- "type": "command",
210
- "command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/lifecycle/config_change_guard.py",
211
- "timeout": 10
212
- }
213
- ]
214
- }
215
- ],
216
97
  "PostToolUse": [
217
98
  {
218
99
  "matcher": "Write|Edit",
@@ -245,7 +126,7 @@
245
126
  ]
246
127
  },
247
128
  {
248
- "matcher": "Bash",
129
+ "matcher": "Bash|PowerShell",
249
130
  "hooks": [
250
131
  {
251
132
  "type": "command",
@@ -2,6 +2,10 @@
2
2
 
3
3
  import re
4
4
 
5
+ from hooks_constants.blast_radius_constants import ALL_BLAST_RADIUS_SUFFIXES
6
+
7
+ ALL_BLAST_RADIUS_EXCEPTION_SUFFIXES: tuple[str, ...] = ALL_BLAST_RADIUS_SUFFIXES
8
+
5
9
  ALL_BANNED_IDENTIFIERS: frozenset[str] = frozenset(
6
10
  {
7
11
  "result",
@@ -10,12 +10,25 @@ no second copy of either.
10
10
  from __future__ import annotations
11
11
 
12
12
  from hooks_constants.bash_pre_tool_use_dispatcher_constants import (
13
+ ALL_BASH_AND_POWERSHELL_TOOL_NAMES,
13
14
  ALL_BASH_ONLY_TOOL_NAMES,
14
15
  BashHostedHookEntry,
15
16
  )
16
17
 
17
- __all__ = ["ALL_BASH_POST_TOOL_USE_HOSTED_HOOK_ENTRIES"]
18
+ __all__ = [
19
+ "ALL_BASH_POST_TOOL_USE_HOSTED_HOOK_ENTRIES",
20
+ "POST_TOOL_USE_HOOK_EVENT_NAME",
21
+ "HOOK_SPECIFIC_OUTPUT_KEY",
22
+ "ADDITIONAL_CONTEXT_KEY",
23
+ "ADDITIONAL_CONTEXT_JOIN_SEPARATOR",
24
+ ]
18
25
 
19
26
  ALL_BASH_POST_TOOL_USE_HOSTED_HOOK_ENTRIES: tuple[BashHostedHookEntry, ...] = (
20
27
  BashHostedHookEntry("observability/test_failure_recorder.py", ALL_BASH_ONLY_TOOL_NAMES),
28
+ BashHostedHookEntry("advisory/pr_done_reminder.py", ALL_BASH_AND_POWERSHELL_TOOL_NAMES),
21
29
  )
30
+
31
+ POST_TOOL_USE_HOOK_EVENT_NAME: str = "PostToolUse"
32
+ HOOK_SPECIFIC_OUTPUT_KEY: str = "hookSpecificOutput"
33
+ ADDITIONAL_CONTEXT_KEY: str = "additionalContext"
34
+ ADDITIONAL_CONTEXT_JOIN_SEPARATOR: str = "\n\n"
@@ -54,18 +54,4 @@ class BashHostedHookEntry:
54
54
  applicable_tool_names: frozenset[str]
55
55
 
56
56
 
57
- ALL_BASH_HOSTED_HOOK_ENTRIES: tuple[BashHostedHookEntry, ...] = (
58
- BashHostedHookEntry("blocking/destructive_command_blocker.py", ALL_BASH_ONLY_TOOL_NAMES),
59
- BashHostedHookEntry("blocking/shell_substitution_blocker.py", ALL_BASH_ONLY_TOOL_NAMES),
60
- BashHostedHookEntry("blocking/piped_pytest_blocker.py", ALL_BASH_ONLY_TOOL_NAMES),
61
- BashHostedHookEntry(
62
- "blocking/cursor_cli_python_misfire_blocker.py",
63
- ALL_BASH_AND_POWERSHELL_TOOL_NAMES,
64
- ),
65
- BashHostedHookEntry("blocking/unscoped_search_blocker.py", ALL_BASH_AND_POWERSHELL_TOOL_NAMES),
66
- BashHostedHookEntry("blocking/nas_ssh_binary_enforcer.py", ALL_BASH_ONLY_TOOL_NAMES),
67
- BashHostedHookEntry("blocking/pii_prevention_blocker.py", ALL_BASH_AND_POWERSHELL_TOOL_NAMES),
68
- BashHostedHookEntry("blocking/block_main_commit.py", ALL_BASH_ONLY_TOOL_NAMES),
69
- BashHostedHookEntry("blocking/session_edit_stage_gate.py", ALL_BASH_ONLY_TOOL_NAMES),
70
- BashHostedHookEntry("blocking/windows_rmtree_blocker.py", ALL_BASH_ONLY_TOOL_NAMES),
71
- )
57
+ ALL_BASH_HOSTED_HOOK_ENTRIES: tuple[BashHostedHookEntry, ...] = ()
@@ -54,10 +54,6 @@ class PostHostedHookEntry:
54
54
 
55
55
 
56
56
  ALL_POST_HOSTED_HOOK_ENTRIES: tuple[PostHostedHookEntry, ...] = (
57
- PostHostedHookEntry(
58
- script_relative_path="validation/mypy_validator.py",
59
- is_blocking=True,
60
- ),
61
57
  PostHostedHookEntry(
62
58
  script_relative_path="workflow/auto_formatter.py",
63
59
  is_blocking=False,
@@ -0,0 +1,98 @@
1
+ """Constants for the PR done-checklist context reminder.
2
+
3
+ The reminder is a PostToolUse observer on Bash. It never blocks. After a
4
+ successful ``git push`` or ``gh pr create`` it probes the branch's pull request
5
+ through ``gh`` and adds one loud checklist to the agent's context.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ __all__ = [
11
+ "GIT_PROGRAM_NAME",
12
+ "GIT_PUSH_SUBCOMMAND",
13
+ "GH_PROGRAM_NAME",
14
+ "GH_PR_SUBCOMMAND",
15
+ "GH_PR_CREATE_ACTION",
16
+ "ALL_GIT_OPTIONS_WITH_VALUE",
17
+ "ALL_POWERSHELL_PROGRAM_NAMES",
18
+ "ALL_POWERSHELL_COMMAND_FLAGS",
19
+ "ALL_GH_PR_VIEW_ARGUMENTS",
20
+ "GH_PR_VIEW_TIMEOUT_SECONDS",
21
+ "NO_PULL_REQUEST_MARKER",
22
+ "EXIT_CODE_ERROR_PREFIX",
23
+ "DONE_LABEL_NAME",
24
+ "MERGEABLE_CLEAN_VALUE",
25
+ "MERGEABLE_CONFLICTING_VALUE",
26
+ "MERGEABLE_UNKNOWN_VALUE",
27
+ "ALL_FAILING_CHECK_CONCLUSIONS",
28
+ "ALL_PASSING_CHECK_CONCLUSIONS",
29
+ "CHECK_COMPLETED_STATUS",
30
+ "STATUS_CONTEXT_STATE_KEY",
31
+ "REMINDER_HEADER",
32
+ "REMINDER_FOOTER",
33
+ "REMINDER_LINE_SEPARATOR",
34
+ "ALL_REMINDER_HINTS_BY_MERGEABLE",
35
+ "VERDICT_DONE",
36
+ "VERDICT_NOT_DONE",
37
+ "NO_PULL_REQUEST_REMINDER",
38
+ "RECHECK_COMMAND_TEMPLATE",
39
+ "ADD_LABEL_COMMAND_TEMPLATE",
40
+ ]
41
+
42
+ GIT_PROGRAM_NAME: str = "git"
43
+ GIT_PUSH_SUBCOMMAND: str = "push"
44
+ GH_PROGRAM_NAME: str = "gh"
45
+ GH_PR_SUBCOMMAND: str = "pr"
46
+ GH_PR_CREATE_ACTION: str = "create"
47
+ ALL_GIT_OPTIONS_WITH_VALUE: frozenset[str] = frozenset({"-C", "-c"})
48
+ ALL_POWERSHELL_PROGRAM_NAMES: frozenset[str] = frozenset(
49
+ {"pwsh", "pwsh.exe", "powershell", "powershell.exe"}
50
+ )
51
+ ALL_POWERSHELL_COMMAND_FLAGS: frozenset[str] = frozenset({"-command", "-c"})
52
+
53
+ ALL_GH_PR_VIEW_ARGUMENTS: tuple[str, ...] = (
54
+ "gh",
55
+ "pr",
56
+ "view",
57
+ "--json",
58
+ "number,url,isDraft,mergeable,mergeStateStatus,statusCheckRollup,labels",
59
+ )
60
+ GH_PR_VIEW_TIMEOUT_SECONDS: int = 20
61
+ NO_PULL_REQUEST_MARKER: str = "no pull requests found"
62
+ EXIT_CODE_ERROR_PREFIX: str = "Error: Exit code "
63
+
64
+ DONE_LABEL_NAME: str = "done"
65
+
66
+ MERGEABLE_CLEAN_VALUE: str = "MERGEABLE"
67
+ MERGEABLE_CONFLICTING_VALUE: str = "CONFLICTING"
68
+ MERGEABLE_UNKNOWN_VALUE: str = "UNKNOWN"
69
+
70
+ ALL_FAILING_CHECK_CONCLUSIONS: frozenset[str] = frozenset(
71
+ {"FAILURE", "ERROR", "CANCELLED", "TIMED_OUT", "ACTION_REQUIRED", "STARTUP_FAILURE"}
72
+ )
73
+ ALL_PASSING_CHECK_CONCLUSIONS: frozenset[str] = frozenset({"SUCCESS", "NEUTRAL", "SKIPPED"})
74
+ CHECK_COMPLETED_STATUS: str = "COMPLETED"
75
+ STATUS_CONTEXT_STATE_KEY: str = "state"
76
+
77
+ REMINDER_HEADER: str = "=== PR DONE CHECKLIST (context reminder, never a block) ==="
78
+ REMINDER_FOOTER: str = "A PR is done only when every line above is clean."
79
+ REMINDER_LINE_SEPARATOR: str = "\n"
80
+ ALL_REMINDER_HINTS_BY_MERGEABLE: dict[str, str] = {
81
+ MERGEABLE_CLEAN_VALUE: "no conflicts with the base branch",
82
+ MERGEABLE_CONFLICTING_VALUE: (
83
+ "CONFLICTS with the base branch. Merge origin/main into this branch, "
84
+ "resolve every conflict, run the tests, push again."
85
+ ),
86
+ MERGEABLE_UNKNOWN_VALUE: "GitHub is still computing. Re-run the re-check command in a minute.",
87
+ }
88
+ VERDICT_DONE: str = "DONE. Add the label now:"
89
+ VERDICT_NOT_DONE: str = "NOT DONE. Do not add the done label yet."
90
+ NO_PULL_REQUEST_REMINDER: str = (
91
+ "=== PR DONE CHECKLIST (context reminder, never a block) ===\n"
92
+ "No open pull request found for this branch. Open a draft PR with gh pr create --draft.\n"
93
+ "A branch is done only when its PR has clean CI, no merge conflicts, and the done label."
94
+ )
95
+ RECHECK_COMMAND_TEMPLATE: str = (
96
+ "gh pr view {number} --json mergeable,mergeStateStatus,statusCheckRollup,labels"
97
+ )
98
+ ADD_LABEL_COMMAND_TEMPLATE: str = "gh pr edit {number} --add-label {label}"