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
@@ -1,355 +0,0 @@
1
- """Load and validate the A-Q audit-category schema.
2
-
3
- One machine-readable source under audit-rubrics/audit-categories.json holds
4
- each category id, title, slug, and sub-bucket id/axis pairs. Worked examples
5
- stay in the rubric markdown files only.
6
-
7
- ::
8
-
9
- schema = load_audit_category_schema()
10
- entries = category_id_title_entries()
11
- # entries[0] == ("A", "API contract verification")
12
- findings = validate_projections()
13
- # findings == [] when rubrics and prompt skeletons match the schema
14
-
15
- Use validate_projections before shipping a rubric or prompt change so the
16
- three surfaces cannot drift.
17
- """
18
-
19
- from __future__ import annotations
20
-
21
- import argparse
22
- import json
23
- import re
24
- import sys
25
- from pathlib import Path
26
-
27
- from skills_pr_loop_constants.audit_category_schema_constants import (
28
- CATEGORY_ID_KEY,
29
- CATEGORY_RUBRICS_DIRECTORY,
30
- CATEGORY_SLUG_KEY,
31
- CATEGORY_SLUG_PREFIX_TEMPLATE,
32
- CATEGORY_SUB_BUCKETS_KEY,
33
- CATEGORY_TITLE_KEY,
34
- EXPECTED_CATEGORY_IDS,
35
- HEADING_LETTER_GROUP,
36
- HEADING_PATTERN,
37
- HEADING_TITLE_GROUP,
38
- JSON_INDENT,
39
- NEWLINE,
40
- PACKAGE_ROOT,
41
- PROMPTS_DIRECTORY,
42
- RUBRIC_SUB_BUCKET_ROW_TEMPLATE,
43
- SCHEMA_CATEGORIES_KEY,
44
- SCHEMA_RELATIVE_PATH,
45
- SCHEMA_VERSION,
46
- SCHEMA_VERSION_KEY,
47
- SKELETON_COUNT_PATTERN,
48
- SKELETON_PLACEHOLDER_FRAGMENT,
49
- SKELETON_SEPARATOR_LINE,
50
- SUB_BUCKET_AXIS_KEY,
51
- UTF8_ENCODING,
52
- )
53
-
54
- CategoryMapping = dict[str, object]
55
- SchemaMapping = dict[str, object]
56
-
57
-
58
- def audit_category_schema_path() -> Path:
59
- """Return the path to the committed A-Q schema JSON file.
60
-
61
- Returns:
62
- Absolute path to audit-categories.json under the package root.
63
- """
64
- return PACKAGE_ROOT / SCHEMA_RELATIVE_PATH
65
-
66
-
67
- def load_audit_category_schema() -> SchemaMapping:
68
- """Load and structurally check the A-Q schema document.
69
-
70
- Returns:
71
- The schema object with schema_version and categories.
72
-
73
- Raises:
74
- FileNotFoundError: When the schema file is missing.
75
- ValueError: When required fields or order are wrong.
76
- json.JSONDecodeError: When the schema file is not valid JSON.
77
- """
78
- schema_path = audit_category_schema_path()
79
- loaded_document = json.loads(schema_path.read_text(encoding=UTF8_ENCODING))
80
- if not isinstance(loaded_document, dict):
81
- raise ValueError("schema root must be an object")
82
- if loaded_document.get(SCHEMA_VERSION_KEY) != SCHEMA_VERSION:
83
- raise ValueError(
84
- f"schema_version must be {SCHEMA_VERSION}, "
85
- f"got {loaded_document.get(SCHEMA_VERSION_KEY)!r}"
86
- )
87
- all_categories = loaded_document.get(SCHEMA_CATEGORIES_KEY)
88
- if not isinstance(all_categories, list) or not all_categories:
89
- raise ValueError("categories must be a non-empty list")
90
- all_ids = [
91
- each_category.get(CATEGORY_ID_KEY)
92
- for each_category in all_categories
93
- if isinstance(each_category, dict)
94
- ]
95
- if all_ids != list(EXPECTED_CATEGORY_IDS):
96
- raise ValueError(f"categories must list A-Q in order, got {all_ids!r}")
97
- all_checked_categories: list[CategoryMapping] = []
98
- for each_category in all_categories:
99
- if not isinstance(each_category, dict):
100
- raise ValueError("each category must be an object")
101
- all_checked_categories.append(_require_category_shape(each_category))
102
- return {
103
- SCHEMA_VERSION_KEY: SCHEMA_VERSION,
104
- SCHEMA_CATEGORIES_KEY: all_checked_categories,
105
- }
106
-
107
-
108
- def _require_category_shape(all_category_fields: CategoryMapping) -> CategoryMapping:
109
- category_id = all_category_fields.get(CATEGORY_ID_KEY)
110
- if not isinstance(category_id, str) or len(category_id) != 1:
111
- raise ValueError(f"category id must be a single letter, got {category_id!r}")
112
- title = all_category_fields.get(CATEGORY_TITLE_KEY)
113
- if not isinstance(title, str) or not title.strip():
114
- raise ValueError(f"category {category_id} title must be a non-empty string")
115
- slug = all_category_fields.get(CATEGORY_SLUG_KEY)
116
- expected_slug_prefix = CATEGORY_SLUG_PREFIX_TEMPLATE.format(letter=category_id.lower())
117
- if not isinstance(slug, str) or not slug.startswith(expected_slug_prefix):
118
- raise ValueError(
119
- f"category {category_id} slug must start with {expected_slug_prefix!r}, "
120
- f"got {slug!r}"
121
- )
122
- all_sub_bucket_fields = all_category_fields.get(CATEGORY_SUB_BUCKETS_KEY)
123
- if not isinstance(all_sub_bucket_fields, list) or not all_sub_bucket_fields:
124
- raise ValueError(f"category {category_id} needs a non-empty sub_buckets list")
125
- all_sub_buckets: list[CategoryMapping] = []
126
- for each_index, each_sub_bucket in enumerate(all_sub_bucket_fields):
127
- if not isinstance(each_sub_bucket, dict):
128
- raise ValueError(f"category {category_id} sub_bucket {each_index} must be object")
129
- expected_id = f"{category_id}{each_index + 1}"
130
- sub_bucket_id = each_sub_bucket.get(CATEGORY_ID_KEY)
131
- if sub_bucket_id != expected_id:
132
- raise ValueError(
133
- f"category {category_id} sub_bucket {each_index} id must be "
134
- f"{expected_id}, got {sub_bucket_id!r}"
135
- )
136
- axis_name = each_sub_bucket.get(SUB_BUCKET_AXIS_KEY)
137
- if not isinstance(axis_name, str) or not axis_name.strip():
138
- raise ValueError(
139
- f"category {category_id} sub_bucket {sub_bucket_id} needs axis_name"
140
- )
141
- all_sub_buckets.append(
142
- {CATEGORY_ID_KEY: expected_id, SUB_BUCKET_AXIS_KEY: axis_name}
143
- )
144
- return {
145
- CATEGORY_ID_KEY: category_id,
146
- CATEGORY_TITLE_KEY: title,
147
- CATEGORY_SLUG_KEY: slug,
148
- CATEGORY_SUB_BUCKETS_KEY: all_sub_buckets,
149
- }
150
-
151
-
152
- def category_id_title_entries() -> list[tuple[str, str]]:
153
- """Return (id, title) pairs in A-Q order from the schema.
154
-
155
- Returns:
156
- List of (category letter, title) tuples from the schema file.
157
- """
158
- all_schema = load_audit_category_schema()
159
- all_categories = all_schema[SCHEMA_CATEGORIES_KEY]
160
- assert isinstance(all_categories, list)
161
- all_entries: list[tuple[str, str]] = []
162
- for each_category in all_categories:
163
- assert isinstance(each_category, dict)
164
- category_id = each_category[CATEGORY_ID_KEY]
165
- title = each_category[CATEGORY_TITLE_KEY]
166
- assert isinstance(category_id, str)
167
- assert isinstance(title, str)
168
- all_entries.append((category_id, title))
169
- return all_entries
170
-
171
-
172
- def render_skeleton_projections(all_schema: SchemaMapping) -> dict[str, str]:
173
- """Build deterministic skeleton text per category from the schema only.
174
-
175
- Args:
176
- all_schema: Loaded audit-category schema.
177
-
178
- Returns:
179
- Map of category letter to a stable multi-line skeleton projection.
180
- """
181
- projection_by_letter: dict[str, str] = {}
182
- all_categories = all_schema[SCHEMA_CATEGORIES_KEY]
183
- assert isinstance(all_categories, list)
184
- for each_category in all_categories:
185
- assert isinstance(each_category, dict)
186
- category_id = each_category[CATEGORY_ID_KEY]
187
- title = each_category[CATEGORY_TITLE_KEY]
188
- slug = each_category[CATEGORY_SLUG_KEY]
189
- all_sub_buckets = each_category[CATEGORY_SUB_BUCKETS_KEY]
190
- assert isinstance(category_id, str)
191
- assert isinstance(title, str)
192
- assert isinstance(slug, str)
193
- assert isinstance(all_sub_buckets, list)
194
- sub_bucket_count = len(all_sub_buckets)
195
- all_lines = [
196
- f"Category {category_id} — {title}",
197
- f"slug: {slug}",
198
- f"decomposed into {sub_bucket_count} sub-buckets",
199
- f"For each sub-bucket {category_id}1-{category_id}{sub_bucket_count}:",
200
- ]
201
- for each_sub_bucket in all_sub_buckets:
202
- assert isinstance(each_sub_bucket, dict)
203
- sub_bucket_id = each_sub_bucket[CATEGORY_ID_KEY]
204
- axis_name = each_sub_bucket[SUB_BUCKET_AXIS_KEY]
205
- all_lines.append(f"{sub_bucket_id}. {axis_name}")
206
- projection_by_letter[category_id] = NEWLINE.join(all_lines) + NEWLINE
207
- return projection_by_letter
208
-
209
-
210
- def _validate_one_category(each_category: CategoryMapping) -> list[str]:
211
- category_id = each_category[CATEGORY_ID_KEY]
212
- slug = each_category[CATEGORY_SLUG_KEY]
213
- title = each_category[CATEGORY_TITLE_KEY]
214
- all_sub_buckets = each_category[CATEGORY_SUB_BUCKETS_KEY]
215
- assert isinstance(category_id, str)
216
- assert isinstance(slug, str)
217
- assert isinstance(title, str)
218
- assert isinstance(all_sub_buckets, list)
219
- all_findings: list[str] = []
220
- rubric_path = CATEGORY_RUBRICS_DIRECTORY / f"{slug}.md"
221
- prompt_path = PROMPTS_DIRECTORY / f"{slug}.md"
222
- if not rubric_path.is_file():
223
- return [f"{category_id}: missing rubric {rubric_path.name}"]
224
- if not prompt_path.is_file():
225
- return [f"{category_id}: missing prompt {prompt_path.name}"]
226
- rubric_text = rubric_path.read_text(encoding=UTF8_ENCODING)
227
- all_rubric_lines = rubric_text.splitlines()
228
- if not all_rubric_lines:
229
- return [f"{category_id}: empty rubric"]
230
- heading_match = HEADING_PATTERN.match(all_rubric_lines[0])
231
- if heading_match is None:
232
- return [f"{category_id}: rubric heading does not match pattern"]
233
- heading_letter = heading_match.group(HEADING_LETTER_GROUP)
234
- heading_title = heading_match.group(HEADING_TITLE_GROUP)
235
- if heading_letter != category_id:
236
- all_findings.append(f"{category_id}: rubric heading letter {heading_letter!r}")
237
- if heading_title != title:
238
- all_findings.append(
239
- f"{category_id}: rubric title {heading_title!r} != schema {title!r}"
240
- )
241
- row_pattern = re.compile(
242
- RUBRIC_SUB_BUCKET_ROW_TEMPLATE.format(category_id=re.escape(category_id)),
243
- re.MULTILINE,
244
- )
245
- all_rubric_rows = row_pattern.findall(rubric_text)
246
- all_schema_rows: list[tuple[str, str]] = []
247
- for each_sub_bucket in all_sub_buckets:
248
- assert isinstance(each_sub_bucket, dict)
249
- sub_bucket_id = each_sub_bucket[CATEGORY_ID_KEY]
250
- axis_name = each_sub_bucket[SUB_BUCKET_AXIS_KEY]
251
- assert isinstance(sub_bucket_id, str)
252
- assert isinstance(axis_name, str)
253
- all_schema_rows.append((sub_bucket_id, axis_name))
254
- all_rubric_pairs = [(row_id, axis.strip()) for row_id, axis in all_rubric_rows]
255
- if all_rubric_pairs != all_schema_rows:
256
- all_findings.append(
257
- f"{category_id}: rubric sub-buckets {all_rubric_pairs!r} "
258
- f"!= schema {all_schema_rows!r}"
259
- )
260
- all_findings.extend(
261
- _validate_prompt_skeleton_count(category_id, prompt_path, len(all_sub_buckets))
262
- )
263
- return all_findings
264
-
265
-
266
- def _validate_prompt_skeleton_count(
267
- category_id: str,
268
- prompt_path: Path,
269
- sub_bucket_count: int,
270
- ) -> list[str]:
271
- prompt_text = prompt_path.read_text(encoding=UTF8_ENCODING)
272
- all_skeleton_lines: list[str] = []
273
- for each_line in prompt_text.splitlines():
274
- if each_line == SKELETON_SEPARATOR_LINE:
275
- break
276
- all_skeleton_lines.append(each_line)
277
- skeleton_text = NEWLINE.join(all_skeleton_lines)
278
- if SKELETON_PLACEHOLDER_FRAGMENT in skeleton_text:
279
- return [
280
- f"{category_id}: prompt skeleton still uses [N] placeholder; "
281
- f"use numeric count {sub_bucket_count}"
282
- ]
283
- count_match = SKELETON_COUNT_PATTERN.search(skeleton_text)
284
- if count_match is None:
285
- return [f"{category_id}: prompt skeleton missing sub-bucket count form"]
286
- skeleton_count = int(count_match.group(HEADING_LETTER_GROUP))
287
- if skeleton_count != sub_bucket_count:
288
- return [
289
- f"{category_id}: prompt skeleton count {skeleton_count} "
290
- f"!= schema {sub_bucket_count}"
291
- ]
292
- return []
293
-
294
-
295
- def validate_projections() -> list[str]:
296
- """Compare schema against on-disk rubric and prompt skeleton projections.
297
-
298
- Returns:
299
- Finding strings; empty when every category is in parity.
300
- """
301
- all_schema = load_audit_category_schema()
302
- all_categories = all_schema[SCHEMA_CATEGORIES_KEY]
303
- assert isinstance(all_categories, list)
304
- all_findings: list[str] = []
305
- for each_category in all_categories:
306
- assert isinstance(each_category, dict)
307
- all_findings.extend(_validate_one_category(each_category))
308
- return all_findings
309
-
310
-
311
- def main(all_argv: list[str]) -> int:
312
- """CLI: validate projections or print deterministic skeleton projections.
313
-
314
- Args:
315
- all_argv: Argument list without the program name.
316
-
317
- Returns:
318
- Process exit code (0 success, 1 validation findings).
319
- """
320
- parser = argparse.ArgumentParser(description=__doc__)
321
- parser.add_argument(
322
- "--validate",
323
- action="store_true",
324
- help="Validate rubric and prompt projections against the schema.",
325
- )
326
- parser.add_argument(
327
- "--render-skeletons",
328
- action="store_true",
329
- help="Print deterministic skeleton projections as JSON.",
330
- )
331
- arguments = parser.parse_args(all_argv)
332
- if arguments.validate:
333
- all_findings = validate_projections()
334
- if all_findings:
335
- for each_finding in all_findings:
336
- print(each_finding, file=sys.stderr)
337
- return 1
338
- print("OK")
339
- return 0
340
- if arguments.render_skeletons:
341
- all_schema = load_audit_category_schema()
342
- print(
343
- json.dumps(
344
- render_skeleton_projections(all_schema),
345
- indent=JSON_INDENT,
346
- ensure_ascii=False,
347
- )
348
- )
349
- return 0
350
- parser.print_help()
351
- return 0
352
-
353
-
354
- if __name__ == "__main__":
355
- raise SystemExit(main(sys.argv[1:]))
@@ -1,289 +0,0 @@
1
- """Emit the complete AUDIT spawn prompt XML to stdout.
2
-
3
- Builds <context> and <scope> from CLI args; <bug_categories>,
4
- <rubric_reference>, and <constraints> come from the shared constants in
5
- skills_pr_loop_constants; <comment_posting> and <output_format> follow
6
- ``--flavor`` (agent or headless). <pr_description> carries the PR body
7
- text read from --pr-body-file, and stays empty when that argument is
8
- absent or the file cannot be read.
9
-
10
- Usage:
11
- python scripts/build_audit_prompt.py --owner jl-cmd --repo claude-dev-env --pr-number 422 --loop 1 --head-ref feat/branch --base-ref main --worktree-path <PATH> --run-temp-dir <PATH> [--flavor agent|headless]
12
- """
13
-
14
- from __future__ import annotations
15
-
16
- import argparse
17
- import sys
18
- from xml.etree.ElementTree import Element, SubElement
19
- from pathlib import Path
20
-
21
- _self_dir = Path(__file__).resolve().parent
22
- if str(_self_dir) not in sys.path:
23
- sys.path.insert(0, str(_self_dir))
24
-
25
- from _path_resolver import outcome_xml_path
26
- from _xml_utils import emit_pretty_xml
27
- from skills_pr_loop_constants.path_resolver_constants import (
28
- ALL_AUDIT_CATEGORY_ENTRIES,
29
- ALL_AUDIT_CONSTRAINT_TEXTS,
30
- ALL_AUDIT_PROMPT_FLAVORS,
31
- AUDIT_COMMENT_POSTING_AGENT_TEXT,
32
- AUDIT_COMMENT_POSTING_HEADLESS_TEXT,
33
- AUDIT_OUTPUT_FORMAT_AGENT_TEXT,
34
- AUDIT_OUTPUT_FORMAT_HEADLESS_TEMPLATE,
35
- AUDIT_PROMPT_FLAVOR_AGENT,
36
- AUDIT_PROMPT_FLAVOR_HEADLESS,
37
- AUDIT_RUBRIC_REFERENCE_TEXT,
38
- )
39
-
40
-
41
- def read_pr_body_text(pr_body_file: Path | None) -> str | None:
42
- """Read the PR description body from a file when given and readable.
43
-
44
- Args:
45
- pr_body_file: Path to a file holding the PR description body, or None.
46
-
47
- Returns:
48
- The file's text when the path is given and readable, otherwise None.
49
- """
50
- if pr_body_file is None:
51
- return None
52
- try:
53
- return pr_body_file.read_text(encoding="utf-8")
54
- except OSError:
55
- return None
56
-
57
-
58
- def _append_pr_description(root: Element, pr_body_text: str | None) -> None:
59
- """Append a <pr_description> element carrying the PR body text.
60
-
61
- Args:
62
- root: Root element the <pr_description> child is appended to.
63
- pr_body_text: PR description body text, or None when unavailable.
64
-
65
- Returns:
66
- None.
67
- """
68
- pr_description = SubElement(root, "pr_description")
69
- if pr_body_text:
70
- pr_description.text = pr_body_text
71
-
72
-
73
- def _comment_posting_text(flavor: str) -> str:
74
- """Return the <comment_posting> body for the given prompt flavor.
75
-
76
- Args:
77
- flavor: ``agent`` or ``headless`` prompt flavor.
78
-
79
- Returns:
80
- Comment-posting instruction text for that flavor.
81
- """
82
- if flavor == AUDIT_PROMPT_FLAVOR_HEADLESS:
83
- return AUDIT_COMMENT_POSTING_HEADLESS_TEXT
84
- return AUDIT_COMMENT_POSTING_AGENT_TEXT
85
-
86
-
87
- def _format_instruction_text(
88
- *,
89
- flavor: str,
90
- worktree_path: Path,
91
- pr_number: int,
92
- loop: int,
93
- ) -> str:
94
- """Return the <output_format> body for the given prompt flavor.
95
-
96
- Args:
97
- flavor: ``agent`` or ``headless`` prompt flavor.
98
- worktree_path: Path to the git worktree.
99
- pr_number: Pull request number.
100
- loop: Loop iteration number.
101
-
102
- Returns:
103
- Format-instruction text for that flavor.
104
- """
105
- if flavor == AUDIT_PROMPT_FLAVOR_HEADLESS:
106
- outcome_path = outcome_xml_path(worktree_path, pr_number, loop)
107
- return AUDIT_OUTPUT_FORMAT_HEADLESS_TEMPLATE.format(
108
- outcome_path=outcome_path.as_posix(),
109
- )
110
- return AUDIT_OUTPUT_FORMAT_AGENT_TEXT
111
-
112
-
113
- def build_audit_prompt_xml(
114
- *,
115
- owner: str,
116
- repo: str,
117
- pr_number: int,
118
- loop: int,
119
- head_ref: str,
120
- base_ref: str,
121
- worktree_path: Path,
122
- run_temp_dir: Path,
123
- pr_body_text: str | None = None,
124
- flavor: str = AUDIT_PROMPT_FLAVOR_AGENT,
125
- ) -> Element:
126
- """Build the complete AUDIT spawn prompt XML.
127
-
128
- Args:
129
- owner: GitHub repository owner.
130
- repo: GitHub repository name.
131
- pr_number: Pull request number.
132
- loop: Loop iteration number.
133
- head_ref: Head branch ref.
134
- base_ref: Base branch ref.
135
- worktree_path: Path to the git worktree.
136
- run_temp_dir: Path to the run temp directory.
137
- pr_body_text: PR description body text, or None when unavailable.
138
- flavor: Prompt flavor — ``agent`` (MCP posting) or ``headless``
139
- (outcome file, lead-owned posting).
140
-
141
- Returns:
142
- Root <spawn_prompt> element.
143
- """
144
- root = Element("spawn_prompt", {"role": "audit", "loop": str(loop)})
145
-
146
- context = SubElement(root, "context")
147
- SubElement(context, "owner").text = owner
148
- SubElement(context, "repo").text = repo
149
- SubElement(context, "pr_number").text = str(pr_number)
150
- SubElement(context, "head_ref").text = head_ref
151
- SubElement(context, "base_ref").text = base_ref
152
- SubElement(context, "worktree_path").text = worktree_path.as_posix()
153
- SubElement(context, "run_temp_dir").text = run_temp_dir.as_posix()
154
-
155
- scope = SubElement(root, "scope")
156
- scope.text = (
157
- f"Audit the full diff of {owner}/{repo}#{pr_number} "
158
- f"({head_ref} against {base_ref}) for CODE_RULES violations, "
159
- f"bugs, and anti-patterns. Work in {worktree_path.as_posix()}."
160
- )
161
-
162
- _append_pr_description(root, pr_body_text)
163
-
164
- bug_categories = SubElement(root, "bug_categories")
165
- for each_category_id, each_category_label in ALL_AUDIT_CATEGORY_ENTRIES:
166
- cat_elem = SubElement(bug_categories, "category", {"id": each_category_id})
167
- cat_elem.text = each_category_label
168
-
169
- rubric_reference = SubElement(root, "rubric_reference")
170
- rubric_reference.text = AUDIT_RUBRIC_REFERENCE_TEXT
171
-
172
- constraints = SubElement(root, "constraints")
173
- for each_constraint in ALL_AUDIT_CONSTRAINT_TEXTS:
174
- SubElement(constraints, "constraint").text = each_constraint
175
-
176
- comment_posting = SubElement(root, "comment_posting")
177
- comment_posting.text = _comment_posting_text(flavor)
178
-
179
- format_section = SubElement(root, "output_format")
180
- format_section.text = _format_instruction_text(
181
- flavor=flavor,
182
- worktree_path=worktree_path,
183
- pr_number=pr_number,
184
- loop=loop,
185
- )
186
-
187
- return root
188
-
189
-
190
- def emit_audit_prompt(
191
- *,
192
- owner: str,
193
- repo: str,
194
- pr_number: int,
195
- loop: int,
196
- head_ref: str,
197
- base_ref: str,
198
- worktree_path: Path,
199
- run_temp_dir: Path,
200
- pr_body_text: str | None = None,
201
- flavor: str = AUDIT_PROMPT_FLAVOR_AGENT,
202
- ) -> str:
203
- """Build and serialize the AUDIT spawn prompt to a pretty-printed XML string.
204
-
205
- Args:
206
- owner: GitHub repository owner.
207
- repo: GitHub repository name.
208
- pr_number: Pull request number.
209
- loop: Loop iteration number.
210
- head_ref: Head branch ref.
211
- base_ref: Base branch ref.
212
- worktree_path: Path to the git worktree.
213
- run_temp_dir: Path to the run temp directory.
214
- pr_body_text: PR description body text, or None when unavailable.
215
- flavor: Prompt flavor — ``agent`` or ``headless``.
216
-
217
- Returns:
218
- Pretty-printed XML string.
219
- """
220
- root = build_audit_prompt_xml(
221
- owner=owner,
222
- repo=repo,
223
- pr_number=pr_number,
224
- loop=loop,
225
- head_ref=head_ref,
226
- base_ref=base_ref,
227
- worktree_path=worktree_path,
228
- run_temp_dir=run_temp_dir,
229
- pr_body_text=pr_body_text,
230
- flavor=flavor,
231
- )
232
- return emit_pretty_xml(root)
233
-
234
-
235
- def parse_arguments(all_argv: list[str]) -> argparse.Namespace:
236
- """Parse command-line arguments.
237
-
238
- Args:
239
- all_argv: Command-line argument list.
240
-
241
- Returns:
242
- Parsed namespace with all required audit prompt parameters.
243
- """
244
- parser = argparse.ArgumentParser(description=__doc__)
245
- parser.add_argument("--owner", required=True)
246
- parser.add_argument("--repo", required=True)
247
- parser.add_argument("--pr-number", type=int, required=True)
248
- parser.add_argument("--loop", type=int, required=True)
249
- parser.add_argument("--head-ref", required=True)
250
- parser.add_argument("--base-ref", required=True)
251
- parser.add_argument("--worktree-path", type=Path, required=True)
252
- parser.add_argument("--run-temp-dir", type=Path, required=True)
253
- parser.add_argument("--pr-body-file", type=Path, default=None)
254
- parser.add_argument(
255
- "--flavor",
256
- choices=sorted(ALL_AUDIT_PROMPT_FLAVORS),
257
- default=AUDIT_PROMPT_FLAVOR_AGENT,
258
- )
259
- return parser.parse_args(all_argv)
260
-
261
-
262
- def main(all_arguments: list[str]) -> int:
263
- """Entry point: emit AUDIT spawn prompt XML to stdout.
264
-
265
- Args:
266
- all_arguments: Command-line arguments.
267
-
268
- Returns:
269
- 0 on success.
270
- """
271
- arguments = parse_arguments(all_arguments)
272
- xml_output = emit_audit_prompt(
273
- owner=arguments.owner,
274
- repo=arguments.repo,
275
- pr_number=arguments.pr_number,
276
- loop=arguments.loop,
277
- head_ref=arguments.head_ref,
278
- base_ref=arguments.base_ref,
279
- worktree_path=arguments.worktree_path,
280
- run_temp_dir=arguments.run_temp_dir,
281
- pr_body_text=read_pr_body_text(arguments.pr_body_file),
282
- flavor=arguments.flavor,
283
- )
284
- sys.stdout.write(xml_output)
285
- return 0
286
-
287
-
288
- if __name__ == "__main__":
289
- raise SystemExit(main(sys.argv[1:]))