claude-dev-env 2.8.0 → 2.10.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 (323) hide show
  1. package/CLAUDE.md +8 -2
  2. package/_shared/pr-loop/CLAUDE.md +1 -1
  3. package/_shared/pr-loop/audit-contract.md +17 -6
  4. package/_shared/pr-loop/audit-reply-template.md +4 -4
  5. package/_shared/pr-loop/code-rules-gate.md +3 -5
  6. package/_shared/pr-loop/fix-protocol.md +2 -3
  7. package/_shared/pr-loop/gh-payloads.md +1 -1
  8. package/_shared/pr-loop/scripts/CLAUDE.md +1 -1
  9. package/_shared/pr-loop/scripts/README.md +1 -1
  10. package/_shared/pr-loop/scripts/code_rules_gate.py +2 -0
  11. package/_shared/pr-loop/scripts/code_rules_gate_parts/gate_running.py +16 -1
  12. package/_shared/pr-loop/scripts/code_rules_gate_parts/git_blob_readers.py +11 -5
  13. package/_shared/pr-loop/scripts/preflight.py +9 -4
  14. package/_shared/pr-loop/scripts/reviews_disabled.py +50 -22
  15. package/_shared/pr-loop/scripts/tests/conftest.py +20 -0
  16. package/_shared/pr-loop/scripts/tests/test_claude_permissions_common.py +6 -6
  17. package/_shared/pr-loop/scripts/tests/test_reviews_disabled.py +50 -6
  18. package/_shared/pr-loop/scripts/tests/test_revoke_project_claude_permissions.py +1 -1
  19. package/_shared/pr-loop/state-schema.md +5 -14
  20. package/agents/CLAUDE.md +2 -2
  21. package/agents/clean-coder.md +62 -562
  22. package/agents/code-quality-agent.md +10 -2
  23. package/agents/code-verifier.md +1 -1
  24. package/agents/test_agent_frontmatter.py +58 -40
  25. package/audit-rubrics/CLAUDE.md +2 -1
  26. package/audit-rubrics/audit-categories.json +704 -0
  27. package/audit-rubrics/prompts/category-i-concurrency.md +1 -1
  28. package/bin/CLAUDE.md +16 -5
  29. package/bin/ever-shipped-skills.mjs +2 -0
  30. package/bin/install-plan.mjs +402 -0
  31. package/bin/install-transaction.mjs +455 -0
  32. package/bin/install.mjs +593 -147
  33. package/bin/install.plan.test.mjs +194 -0
  34. package/bin/install.profile-root.test.mjs +154 -0
  35. package/bin/install.profiles.test.mjs +253 -0
  36. package/bin/install.settings-defaults.test.mjs +200 -0
  37. package/bin/install.transaction.test.mjs +400 -0
  38. package/bin/install.uninstall-transaction.test.mjs +418 -0
  39. package/bin/merge_managed_permissions.mjs +130 -0
  40. package/bin/resolve-install-root.mjs +181 -0
  41. package/bin/select-install-targets.mjs +401 -0
  42. package/commands/CLAUDE.md +0 -2
  43. package/docs/CODE_RULES.md +4 -2
  44. package/docs/references/CLAUDE.md +3 -2
  45. package/docs/references/advisor-tool.md +44 -6
  46. package/docs/references/prose-style-enforcement.md +25 -0
  47. package/docs/references/team-advisor-skill.md +14 -8
  48. package/hooks/blocking/CLAUDE.md +6 -6
  49. package/hooks/blocking/_path_setup.py +9 -5
  50. package/hooks/blocking/code_rules_docstrings.py +124 -30
  51. package/hooks/blocking/code_rules_enforcer.py +161 -16
  52. package/hooks/blocking/code_rules_shared.py +40 -23
  53. package/hooks/blocking/config/CLAUDE.md +3 -5
  54. package/hooks/blocking/config/prose_style_enforcement_constants.py +38 -0
  55. package/hooks/blocking/config/test_prose_style_enforcement_constants.py +45 -0
  56. package/hooks/blocking/eli11_reply_enforcer.py +70 -113
  57. package/hooks/blocking/hedging_language_blocker.py +103 -20
  58. package/hooks/blocking/hook_prose_detector_consistency.py +6 -0
  59. package/hooks/blocking/intent_only_ending_blocker.py +6 -0
  60. package/hooks/blocking/plain_language_blocker.py +139 -20
  61. package/hooks/blocking/pre_tool_use_dispatcher.py +102 -20
  62. package/hooks/blocking/state_description_blocker.py +7 -1
  63. package/hooks/blocking/tdd_enforcer.py +8 -0
  64. package/hooks/blocking/test__path_setup.py +28 -0
  65. package/hooks/blocking/test_code_rules_enforcer_agent_home_tooling.py +99 -0
  66. package/hooks/blocking/test_code_rules_enforcer_docstring_args_span_scope.py +232 -10
  67. package/hooks/blocking/test_code_rules_enforcer_ephemeral.py +1 -1
  68. package/hooks/blocking/test_code_rules_enforcer_join_separator_magic.py +41 -0
  69. package/hooks/blocking/test_code_rules_enforcer_string_magic.py +98 -0
  70. package/hooks/blocking/test_eli11_reply_enforcer.py +98 -165
  71. package/hooks/blocking/test_hedging_language_blocker.py +120 -1
  72. package/hooks/blocking/test_hook_prose_detector_consistency.py +28 -8
  73. package/hooks/blocking/test_intent_only_ending_blocker.py +27 -2
  74. package/hooks/blocking/test_package_inventory_stale_blocker.py +11 -4
  75. package/hooks/blocking/test_plain_language_blocker.py +129 -19
  76. package/hooks/blocking/test_plain_language_blocker_allowlist.py +70 -26
  77. package/hooks/blocking/test_pre_tool_use_dispatcher.py +99 -26
  78. package/hooks/blocking/test_pre_tool_use_dispatcher_native.py +87 -50
  79. package/hooks/blocking/test_state_description_blocker.py +45 -2
  80. package/hooks/blocking/test_stop_dispatcher.py +11 -7
  81. package/hooks/blocking/test_volatile_path_in_post_blocker.py +12 -12
  82. package/hooks/blocking/volatile_path_in_post_blocker.py +2 -2
  83. package/hooks/hooks.json +15 -0
  84. package/hooks/hooks_constants/CLAUDE.md +14 -3
  85. package/hooks/hooks_constants/ask_user_question_shape.py +281 -0
  86. package/hooks/hooks_constants/code_rules_enforcer_constants.py +2 -1
  87. package/hooks/hooks_constants/code_rules_path_utils_constants.py +1 -0
  88. package/hooks/hooks_constants/eli11_reply_enforcer_constants.py +5 -12
  89. package/hooks/hooks_constants/hedging_uncertainty_constants.py +42 -0
  90. package/hooks/hooks_constants/issue_tracker_session_starter_constants.py +23 -0
  91. package/hooks/hooks_constants/orchestrator_auto_starter_constants.py +23 -0
  92. package/hooks/hooks_constants/piped_pytest_blocker_constants.py +4 -1
  93. package/hooks/hooks_constants/plain_language_blocker_constants.py +4 -1
  94. package/hooks/hooks_constants/pre_tool_use_dispatcher_constants.py +6 -0
  95. package/hooks/hooks_constants/project_paths_reader.py +31 -4
  96. package/hooks/hooks_constants/prose_matcher_precision_constants.py +40 -0
  97. package/hooks/hooks_constants/pytest_invocation.py +354 -0
  98. package/hooks/hooks_constants/session_start_injector.py +163 -0
  99. package/hooks/hooks_constants/session_start_injector_constants.py +46 -0
  100. package/hooks/hooks_constants/shell_command_pipeline.py +397 -0
  101. package/hooks/hooks_constants/shell_command_segments.py +5 -0
  102. package/hooks/hooks_constants/test_ask_user_question_shape.py +167 -0
  103. package/hooks/hooks_constants/test_project_paths_reader.py +29 -0
  104. package/hooks/hooks_constants/test_prose_metrics_parity.py +8 -0
  105. package/hooks/hooks_constants/test_pytest_invocation.py +130 -0
  106. package/hooks/hooks_constants/test_session_start_injector.py +168 -0
  107. package/hooks/hooks_constants/test_shell_command_pipeline.py +135 -0
  108. package/hooks/hooks_constants/volatile_path_in_post_blocker_constants.py +1 -1
  109. package/hooks/hooks_constants/working_style_prompt_constants.py +30 -0
  110. package/hooks/observability/CLAUDE.md +2 -0
  111. package/hooks/observability/prose_matcher_advisory.py +237 -0
  112. package/hooks/observability/test_prose_matcher_advisory.py +143 -0
  113. package/hooks/session/CLAUDE.md +9 -1
  114. package/hooks/session/_path_setup.py +13 -0
  115. package/hooks/session/issue_tracker_session_starter.py +135 -0
  116. package/hooks/session/orchestrator_auto_starter.py +100 -0
  117. package/hooks/session/test__path_setup.py +28 -0
  118. package/hooks/session/test_issue_tracker_session_starter.py +104 -0
  119. package/hooks/session/test_orchestrator_auto_starter.py +99 -0
  120. package/hooks/session/test_working_style_prompt.py +47 -0
  121. package/hooks/session/untracked_repo_detector.py +1 -24
  122. package/hooks/session/working_style_prompt.py +36 -0
  123. package/hooks/validators/_path_setup.py +19 -0
  124. package/hooks/validators/run_all_validators.py +8 -13
  125. package/installable-surfaces.manifest.json +21 -0
  126. package/output-styles/CLAUDE.md +15 -0
  127. package/package.json +5 -2
  128. package/rules/CLAUDE.md +1 -0
  129. package/rules/code-standards.md +33 -7
  130. package/rules/durable-post-artifacts.md +2 -2
  131. package/rules/eli11-replies.md +7 -2
  132. package/rules/hedging-claims.md +4 -2
  133. package/rules/long-horizon-autonomy.md +3 -1
  134. package/rules/opus5-communication-contract.md +45 -0
  135. package/rules/plain-language.md +2 -2
  136. package/rules/research-mode.md +1 -1
  137. package/scripts/CLAUDE.md +13 -2
  138. package/scripts/Sync-RepoMain.ps1 +215 -0
  139. package/scripts/active_capability_references.py +218 -0
  140. package/scripts/ci/windows-installer-lifecycle.ps1 +78 -0
  141. package/scripts/claude_chain_runner.py +394 -6
  142. package/scripts/claude_chain_usage.py +1 -1
  143. package/scripts/codex_compat_materializer.py +105 -85
  144. package/scripts/dev_env_scripts_constants/CLAUDE.md +3 -1
  145. package/scripts/dev_env_scripts_constants/active_capability_constants.py +46 -0
  146. package/scripts/dev_env_scripts_constants/claude_chain_constants.py +74 -0
  147. package/scripts/dev_env_scripts_constants/grok_run_ledger_constants.py +50 -0
  148. package/scripts/dev_env_scripts_constants/grok_worker_constants.py +104 -0
  149. package/scripts/dev_env_scripts_constants/verify_installable_package_constants.py +116 -0
  150. package/scripts/grok_patch_artifacts.py +123 -0
  151. package/scripts/grok_run_ledger.py +318 -0
  152. package/scripts/profile-isolation-launchers/config/mcp-bundles.json +25 -0
  153. package/scripts/profile-isolation-launchers/config/profile-isolation-constants.mjs +60 -0
  154. package/scripts/profile-isolation-launchers/config/profiles.manifest.json +54 -0
  155. package/scripts/profile-isolation-launchers/config/shared-allowlist.json +64 -0
  156. package/scripts/profile-isolation-launchers/launcher-runtime.mjs +180 -0
  157. package/scripts/profile-isolation-launchers/lib/profile-manifest.mjs +288 -0
  158. package/scripts/profile-isolation-launchers/mcp-bundles.mjs +275 -0
  159. package/scripts/profile-isolation-launchers/profile-isolation-contract.test.mjs +221 -0
  160. package/scripts/profile-isolation-launchers/tests/launcher-runtime.test.mjs +108 -0
  161. package/scripts/profile-isolation-launchers/tests/mcp-bundles.test.mjs +147 -0
  162. package/scripts/profile-isolation-launchers/tests/shortcut-contract.test.ps1 +102 -0
  163. package/scripts/profile-isolation-launchers/tests/version-compatibility.test.mjs +210 -0
  164. package/scripts/profile-isolation-launchers/version-compatibility.mjs +299 -0
  165. package/scripts/profile-isolation-launchers/windows/shortcut-inventory.ps1 +127 -0
  166. package/scripts/profile-isolation-launchers/windows/shortcut-manifest.json +51 -0
  167. package/scripts/profile-isolation-launchers/windows/shortcut-reconcile.ps1 +77 -0
  168. package/scripts/spawn_grok_batch.py +556 -9
  169. package/scripts/test_active_capability_references.py +108 -0
  170. package/scripts/test_claude_chain_runner.py +414 -82
  171. package/scripts/test_claude_chain_usage.py +12 -12
  172. package/scripts/test_grok_patch_artifacts.py +82 -0
  173. package/scripts/test_grok_run_ledger.py +116 -0
  174. package/scripts/test_resolve_worker_spawn.py +2 -2
  175. package/scripts/test_spawn_grok_batch.py +295 -0
  176. package/scripts/test_verify_installable_package.py +208 -0
  177. package/scripts/tests/test_codex_compat_materializer.py +33 -0
  178. package/scripts/verify_installable_package.py +612 -0
  179. package/settings.json +10 -0
  180. package/skills/CLAUDE.md +6 -2
  181. package/skills/_shared/CLAUDE.md +37 -4
  182. package/skills/_shared/advisor/CLAUDE.md +9 -0
  183. package/skills/_shared/advisor/advisor-protocol.md +5 -0
  184. package/skills/_shared/advisor/scripts/README.md +9 -0
  185. package/skills/_shared/end-of-run-gotcha-recommendations.md +156 -0
  186. package/skills/_shared/pr-loop/CLAUDE.md +18 -1
  187. package/skills/_shared/pr-loop/audit-contract.md +5 -0
  188. package/skills/_shared/pr-loop/audit-reply-template.md +5 -0
  189. package/skills/_shared/pr-loop/code-rules-gate.md +5 -0
  190. package/skills/_shared/pr-loop/fix-protocol.md +5 -0
  191. package/skills/_shared/pr-loop/gh-payloads.md +5 -0
  192. package/skills/_shared/pr-loop/post-audit-thread-contract.md +5 -0
  193. package/skills/_shared/pr-loop/precatch-rubric.md +5 -0
  194. package/skills/_shared/pr-loop/scripts/CLAUDE.md +9 -1
  195. package/skills/_shared/pr-loop/scripts/RUNTIME_SCRIPTS.md +29 -0
  196. package/skills/_shared/pr-loop/scripts/audit_category_schema.py +355 -0
  197. package/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/CLAUDE.md +1 -0
  198. package/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/audit_category_schema_constants.py +32 -0
  199. package/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/path_resolver_constants.py +7 -19
  200. package/skills/_shared/pr-loop/scripts/test_audit_category_schema.py +94 -0
  201. package/skills/_shared/pr-loop/scripts/test_build_audit_prompt.py +21 -0
  202. package/skills/_shared/pr-loop/state-schema.md +5 -0
  203. package/skills/_shared/pr-loop/worker-spawn.md +5 -0
  204. package/skills/autoconverge/reference/convergence.md +2 -1
  205. package/skills/autoconverge/reference/stop-conditions.md +5 -3
  206. package/skills/beat-sheet/SKILL.md +54 -0
  207. package/skills/beat-sheet/reference/visual-beats.md +29 -0
  208. package/skills/bugteam/CONSTRAINTS.md +4 -4
  209. package/skills/bugteam/EXAMPLES.md +1 -1
  210. package/skills/bugteam/reference/README.md +1 -1
  211. package/skills/e-code-review/SKILL.md +29 -3
  212. package/skills/e-code-review/reference/effort-evaluation.md +35 -0
  213. package/skills/e-code-review/reference/medium.md +15 -4
  214. package/skills/e-code-review/reference/runner-selection.md +40 -0
  215. package/skills/e-code-review/scripts/config/e_code_review_effort_constants/__init__.py +41 -0
  216. package/skills/e-code-review/scripts/config/e_code_review_effort_constants/effort_constants.py +40 -0
  217. package/skills/e-code-review/scripts/e_code_review_scripts_constants/__init__.py +1 -0
  218. package/skills/e-code-review/scripts/e_code_review_scripts_constants/finding_pipeline_constants.py +49 -0
  219. package/skills/e-code-review/scripts/e_code_review_scripts_constants/grok_code_review_constants.py +55 -0
  220. package/skills/e-code-review/scripts/effort_defaults_evidence.json +186 -0
  221. package/skills/e-code-review/scripts/effort_evaluation.py +362 -0
  222. package/skills/e-code-review/scripts/finding_pipeline.py +140 -0
  223. package/skills/e-code-review/scripts/fixtures/demanding.json +26 -0
  224. package/skills/e-code-review/scripts/fixtures/easy.json +14 -0
  225. package/skills/e-code-review/scripts/fixtures/medium.json +20 -0
  226. package/skills/e-code-review/scripts/grok_code_review.py +230 -0
  227. package/skills/e-code-review/scripts/test_effort_evaluation.py +180 -0
  228. package/skills/e-code-review/scripts/test_finding_pipeline.py +197 -0
  229. package/skills/e-code-review/scripts/test_grok_code_review.py +289 -0
  230. package/skills/grok-spawn/SKILL.md +5 -0
  231. package/skills/orchestrator/SKILL.md +5 -0
  232. package/skills/plan-to-pr/scripts/create_packet.py +4 -4
  233. package/skills/plan-to-pr/scripts/load_skill_constants.py +41 -0
  234. package/skills/plan-to-pr/scripts/validate_packet.py +4 -4
  235. package/skills/plan-to-pr/scripts/validate_protocol.py +4 -1
  236. package/skills/plan-to-pr/scripts/validate_run.py +4 -1
  237. package/skills/pr-converge/scripts/check_convergence.py +21 -19
  238. package/skills/pr-converge/scripts/check_convergence_availability.py +50 -7
  239. package/skills/pr-converge/scripts/conftest.py +35 -0
  240. package/skills/pr-converge/scripts/test_check_convergence_availability.py +65 -0
  241. package/skills/pr-converge/scripts/test_check_convergence_codex.py +11 -1
  242. package/skills/pr-converge/scripts/test_check_convergence_contract.py +9 -2
  243. package/skills/pr-loop-cloud-transport/SKILL.md +1 -1
  244. package/skills/rebase/SKILL.md +15 -3
  245. package/skills/reviewer-gates/SKILL.md +2 -2
  246. package/skills/show/SKILL.md +51 -0
  247. package/skills/show/references/accessibility.md +7 -0
  248. package/skills/show/references/art.md +3 -0
  249. package/skills/show/references/charts.md +3 -0
  250. package/skills/show/references/core-design.md +14 -0
  251. package/skills/show/references/erds.md +3 -0
  252. package/skills/show/references/flowcharts.md +3 -0
  253. package/skills/show/references/host-and-html.md +3 -0
  254. package/skills/show/references/illustrative-diagrams.md +10 -0
  255. package/skills/show/references/interaction.md +3 -0
  256. package/skills/show/references/mockups.md +3 -0
  257. package/skills/show/references/quality-gates.md +7 -0
  258. package/skills/show/references/structural-diagrams.md +3 -0
  259. package/skills/show/references/subject-inventory.md +21 -0
  260. package/skills/show/references/svg-contract.md +22 -0
  261. package/skills/show/routing.yaml +30 -0
  262. package/skills/show/samples/pr1262-v2.svg +222 -0
  263. package/skills/show/scripts/README.md +6 -0
  264. package/skills/show/scripts/validate-artifact.py +91 -0
  265. package/skills/show/scripts/validate-package.py +18 -0
  266. package/skills/show/templates/html-widget.html +4 -0
  267. package/skills/show/templates/svg-base.svg +19 -0
  268. package/skills/show/tests/fixtures/css-var.svg +6 -0
  269. package/skills/show/tests/fixtures/dead-ref.svg +7 -0
  270. package/skills/show/tests/fixtures/filled-glyph.svg +8 -0
  271. package/skills/show/tests/fixtures/inherited-fill.svg +18 -0
  272. package/skills/show/tests/fixtures/invalid.svg +1 -0
  273. package/skills/show/tests/fixtures/large-canvas.svg +21 -0
  274. package/skills/show/tests/fixtures/unfilled-connector.svg +15 -0
  275. package/skills/show/tests/fixtures/valid.html +1 -0
  276. package/skills/show/tests/test_validate-artifact.py +74 -0
  277. package/skills/show/tests/test_validators.py +59 -0
  278. package/skills/show/workflows/create-visual.md +13 -0
  279. package/skills/show/workflows/review-visual.md +20 -0
  280. package/skills/split-pr/SKILL.md +85 -0
  281. package/skills/split-pr/reference/path-layers.md +16 -0
  282. package/skills/split-pr/reference/proposal-format.md +15 -0
  283. package/skills/split-pr/reference/split-further-loop.md +10 -0
  284. package/skills/split-pr/reference/splitting-principles.md +26 -0
  285. package/skills/split-pr/scripts/analyze_pr.py +279 -0
  286. package/skills/split-pr/scripts/categorize_files.py +106 -0
  287. package/skills/split-pr/scripts/config/__init__.py +1 -0
  288. package/skills/split-pr/scripts/config/dependency_constants.py +14 -0
  289. package/skills/split-pr/scripts/config/git_operations_constants.py +36 -0
  290. package/skills/split-pr/scripts/config/packing_constants.py +61 -0
  291. package/skills/split-pr/scripts/config/plan_constants.py +49 -0
  292. package/skills/split-pr/scripts/config/split_pr_constants.py +110 -0
  293. package/skills/split-pr/scripts/execute_split_slices.py +82 -0
  294. package/skills/split-pr/scripts/pack_files_into_slices.py +212 -0
  295. package/skills/split-pr/scripts/split_pr_dependency_graph.py +70 -0
  296. package/skills/split-pr/scripts/split_pr_git_operations.py +184 -0
  297. package/skills/split-pr/scripts/split_pr_layer_order.py +58 -0
  298. package/skills/split-pr/scripts/split_pr_paginate.py +119 -0
  299. package/skills/split-pr/scripts/split_pr_process_runner.py +52 -0
  300. package/skills/split-pr/scripts/split_pr_script_types.py +126 -0
  301. package/skills/split-pr/scripts/split_pr_title.py +41 -0
  302. package/skills/split-pr/scripts/test_analyze_pr.py +228 -0
  303. package/skills/split-pr/scripts/test_categorize_files.py +55 -0
  304. package/skills/split-pr/scripts/test_categorize_files_packing.py +59 -0
  305. package/skills/split-pr/scripts/test_execute_split_slices.py +99 -0
  306. package/skills/split-pr/scripts/test_split_pr_dependency_graph.py +47 -0
  307. package/skills/split-pr/scripts/test_split_pr_git_operations.py +125 -0
  308. package/skills/split-pr/scripts/test_split_pr_layer_order.py +36 -0
  309. package/skills/split-pr/scripts/test_split_pr_paginate.py +65 -0
  310. package/skills/split-pr/scripts/test_split_pr_script_types.py +73 -0
  311. package/skills/split-pr/scripts/test_split_pr_title.py +28 -0
  312. package/skills/split-pr/scripts/test_verify_dependency_graph.py +46 -0
  313. package/skills/split-pr/scripts/test_verify_plan.py +56 -0
  314. package/skills/split-pr/scripts/test_verify_plan_contract.py +50 -0
  315. package/skills/split-pr/scripts/test_verify_plan_path_normalization.py +45 -0
  316. package/skills/split-pr/scripts/verify_dependency_graph.py +111 -0
  317. package/skills/split-pr/scripts/verify_plan.py +139 -0
  318. package/skills/task-build/reference/tool-routing.md +3 -0
  319. package/skills/team-advisor/SKILL.md +23 -44
  320. package/system-prompts/software-engineer.xml +17 -5
  321. package/commands/initialize.md +0 -90
  322. package/commands/stubcheck.md +0 -88
  323. package/skills/test_markdown_link_integrity.py +0 -107
@@ -0,0 +1,32 @@
1
+ """Constants for audit_category_schema path resolution and parity checks."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import re
6
+ from pathlib import Path
7
+
8
+ SCRIPTS_DIRECTORY = Path(__file__).resolve().parent.parent
9
+ PACKAGE_ROOT = SCRIPTS_DIRECTORY.parents[3]
10
+ SCHEMA_RELATIVE_PATH = Path("audit-rubrics") / "audit-categories.json"
11
+ CATEGORY_RUBRICS_DIRECTORY = PACKAGE_ROOT / "audit-rubrics" / "category_rubrics"
12
+ PROMPTS_DIRECTORY = PACKAGE_ROOT / "audit-rubrics" / "prompts"
13
+ HEADING_PATTERN = re.compile(r"^# Category ([A-Q]) — (.+)$")
14
+ HEADING_LETTER_GROUP = 1
15
+ HEADING_TITLE_GROUP = 2
16
+ EXPECTED_CATEGORY_IDS = tuple("ABCDEFGHIJKLMNOPQ")
17
+ SCHEMA_VERSION = 1
18
+ JSON_INDENT = 2
19
+ NEWLINE = "\n"
20
+ UTF8_ENCODING = "utf-8"
21
+ RUBRIC_SUB_BUCKET_ROW_TEMPLATE = r"^\| ({category_id}\d+) \| ([^|]+) \|"
22
+ SKELETON_COUNT_PATTERN = re.compile(r"decomposed into (\d+) sub-buckets")
23
+ SKELETON_PLACEHOLDER_FRAGMENT = "decomposed into [N] sub-buckets"
24
+ SKELETON_SEPARATOR_LINE = "---"
25
+ CATEGORY_SLUG_PREFIX_TEMPLATE = "category-{letter}-"
26
+ CATEGORY_ID_KEY = "id"
27
+ CATEGORY_TITLE_KEY = "title"
28
+ CATEGORY_SLUG_KEY = "slug"
29
+ CATEGORY_SUB_BUCKETS_KEY = "sub_buckets"
30
+ SUB_BUCKET_AXIS_KEY = "axis_name"
31
+ SCHEMA_CATEGORIES_KEY = "categories"
32
+ SCHEMA_VERSION_KEY = "schema_version"
@@ -2,6 +2,8 @@
2
2
 
3
3
  import re
4
4
 
5
+ from audit_category_schema import category_id_title_entries
6
+
5
7
  RUN_NAME_TEMPLATE_SINGLE = "bugteam-pr-{number}"
6
8
  RUN_NAME_TEMPLATE_MULTI = "bugteam-{sanitized_branch}"
7
9
  PER_PR_WORKSPACE_TEMPLATE = "pr-{number}"
@@ -24,30 +26,16 @@ ALL_AUDIT_CONSTRAINT_TEXTS = [
24
26
  "Work exclusively within the worktree directory.",
25
27
  "Every finding must cite file:line.",
26
28
  "Document each finding with severity, file, line, and suggested fix.",
29
+ "Report every real finding. Collection retains all severities "
30
+ "(P0, P1, P2). Do not drop findings by severity during collection; "
31
+ "severity or action filtering is a separate consumer stage after the "
32
+ "collection record is complete.",
27
33
  "Read each file in the diff before reporting on it.",
28
34
  "Double-quote every path in shell commands and write paths with "
29
35
  "forward slashes (e.g. C:/Users/...), even on Windows.",
30
36
  ]
31
37
 
32
- ALL_AUDIT_CATEGORY_ENTRIES = [
33
- ("A", "API contract verification"),
34
- ("B", "Selector / query / engine compatibility"),
35
- ("C", "Resource cleanup and lifecycle"),
36
- ("D", "Variable scoping, ordering, and unbound references"),
37
- ("E", "Dead code and unused imports"),
38
- ("F", "Silent failures"),
39
- ("G", "Off-by-one, bounds, integer overflow"),
40
- ("H", "Security boundaries"),
41
- ("I", "Concurrency hazards"),
42
- ("J", "CODE_RULES.md compliance"),
43
- ("K", "Codebase conflicts (incomplete propagation)"),
44
- ("L", "Behavior-equivalence for refactors"),
45
- ("M", "Producer/consumer cardinality vs collection-type contract"),
46
- ("N", "Test-name scenario verifier"),
47
- ("O", "Docstring / fixture-prose vs implementation drift"),
48
- ("P", "Name / regex / word-list vs behavior-contract precision"),
49
- ("Q", "Cross-surface claim consistency (terminology, PR-description claims, message-vs-guard)"),
50
- ]
38
+ ALL_AUDIT_CATEGORY_ENTRIES = category_id_title_entries()
51
39
 
52
40
  AUDIT_RUBRIC_REFERENCE_TEXT = (
53
41
  "The category list above is a summary. The binding definition of each "
@@ -0,0 +1,94 @@
1
+ """Parity tests for the A-Q audit-category schema and projections."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import importlib.util
6
+ import json
7
+ import sys
8
+ from pathlib import Path
9
+ from types import ModuleType
10
+
11
+ _SCRIPTS_DIR = Path(__file__).resolve().parent
12
+ if str(_SCRIPTS_DIR) not in sys.path:
13
+ sys.path.insert(0, str(_SCRIPTS_DIR))
14
+
15
+ from skills_pr_loop_constants.audit_category_schema_constants import (
16
+ CATEGORY_SLUG_KEY,
17
+ CATEGORY_SUB_BUCKETS_KEY,
18
+ PROMPTS_DIRECTORY,
19
+ SCHEMA_CATEGORIES_KEY,
20
+ SKELETON_PLACEHOLDER_FRAGMENT,
21
+ SKELETON_SEPARATOR_LINE,
22
+ UTF8_ENCODING,
23
+ )
24
+ from skills_pr_loop_constants.path_resolver_constants import ALL_AUDIT_CATEGORY_ENTRIES
25
+
26
+
27
+ def _load_audit_category_schema() -> ModuleType:
28
+ module_path = _SCRIPTS_DIR / "audit_category_schema.py"
29
+ spec = importlib.util.spec_from_file_location("audit_category_schema", module_path)
30
+ assert spec is not None
31
+ assert spec.loader is not None
32
+ module = importlib.util.module_from_spec(spec)
33
+ sys.modules["audit_category_schema"] = module
34
+ spec.loader.exec_module(module)
35
+ return module
36
+
37
+
38
+ audit_category_schema = _load_audit_category_schema()
39
+
40
+
41
+ def test_schema_lists_a_through_q_in_order() -> None:
42
+ schema = audit_category_schema.load_audit_category_schema()
43
+ all_ids = [each_category["id"] for each_category in schema["categories"]]
44
+ assert all_ids == list("ABCDEFGHIJKLMNOPQ")
45
+
46
+
47
+ def test_schema_entries_match_constant_export() -> None:
48
+ assert (
49
+ audit_category_schema.category_id_title_entries()
50
+ == list(ALL_AUDIT_CATEGORY_ENTRIES)
51
+ )
52
+
53
+
54
+ def test_validate_projections_matches_rubrics_and_prompts() -> None:
55
+ all_findings = audit_category_schema.validate_projections()
56
+ assert all_findings == [], all_findings
57
+
58
+
59
+ def test_skeleton_projection_is_byte_stable() -> None:
60
+ schema = audit_category_schema.load_audit_category_schema()
61
+ first_render = audit_category_schema.render_skeleton_projections(schema)
62
+ second_render = audit_category_schema.render_skeleton_projections(
63
+ json.loads(json.dumps(schema))
64
+ )
65
+ assert first_render == second_render
66
+ assert "A1" in first_render["A"]
67
+ assert first_render["A"].count("\n") >= 1
68
+
69
+
70
+ def test_schema_omits_worked_example_prose() -> None:
71
+ schema_path = audit_category_schema.audit_category_schema_path()
72
+ schema_text = schema_path.read_text(encoding="utf-8")
73
+ assert "Examples of Category" not in schema_text
74
+ assert "Sample prompt" not in schema_text
75
+
76
+
77
+ def test_no_prompt_skeleton_uses_placeholder_count() -> None:
78
+ """Migrated prompts state a numeric sub-bucket count, never [N]."""
79
+ schema = audit_category_schema.load_audit_category_schema()
80
+ all_findings = audit_category_schema.validate_projections()
81
+ assert all_findings == [], all_findings
82
+ for each_category in schema[SCHEMA_CATEGORIES_KEY]:
83
+ slug = each_category[CATEGORY_SLUG_KEY]
84
+ assert isinstance(slug, str)
85
+ prompt_path = PROMPTS_DIRECTORY / f"{slug}.md"
86
+ all_skeleton_lines: list[str] = []
87
+ for each_line in prompt_path.read_text(encoding=UTF8_ENCODING).splitlines():
88
+ if each_line == SKELETON_SEPARATOR_LINE:
89
+ break
90
+ all_skeleton_lines.append(each_line)
91
+ skeleton_text = "\n".join(all_skeleton_lines)
92
+ assert SKELETON_PLACEHOLDER_FRAGMENT not in skeleton_text, slug
93
+ sub_bucket_count = len(each_category[CATEGORY_SUB_BUCKETS_KEY])
94
+ assert f"decomposed into {sub_bucket_count} sub-buckets" in skeleton_text, slug
@@ -424,3 +424,24 @@ def test_precatch_rubric_adversarial_lane_uses_a_through_q() -> None:
424
424
  rubric_text = _PRECATCH_RUBRIC_PATH.read_text(encoding="utf-8")
425
425
  assert _A_THROUGH_Q_PATTERN.search(rubric_text) is not None
426
426
  assert _STALE_A_THROUGH_P_PATTERN.search(rubric_text) is None
427
+
428
+
429
+ def test_audit_prompt_constraints_require_collection_before_severity_filter() -> None:
430
+ root = _build_audit_root()
431
+ constraints = root.find("constraints")
432
+ assert constraints is not None
433
+ all_constraint_texts = [
434
+ each_constraint.text or "" for each_constraint in constraints
435
+ ]
436
+ joined = "\n".join(all_constraint_texts)
437
+ assert "Report every real finding" in joined
438
+ assert "Do not drop findings by severity during collection" in joined
439
+ assert "separate consumer stage" in joined
440
+ assert "P0" in joined and "P1" in joined and "P2" in joined
441
+
442
+
443
+ def test_audit_contract_documents_collection_before_severity_filtering() -> None:
444
+ contract_text = _AUDIT_CONTRACT_PATH.read_text(encoding="utf-8")
445
+ assert "## Collection before severity filtering" in contract_text
446
+ assert "separate consumer stage" in contract_text
447
+ assert "Do not drop a real finding because its severity is low" in contract_text
@@ -0,0 +1,5 @@
1
+ # State schema
2
+
3
+ **Canonical home:**
4
+
5
+ @~/.claude/_shared/pr-loop/state-schema.md
@@ -0,0 +1,5 @@
1
+ # Worker spawn
2
+
3
+ **Canonical home:**
4
+
5
+ @~/.claude/_shared/pr-loop/worker-spawn.md
@@ -152,7 +152,8 @@ existing fix + re-converge path.
152
152
  - Runs after Bugbot and Copilot. Honors `reviews_disabled.py --reviewer codex`,
153
153
  the weekly usage probe via `is_codex_review_required` (shared threshold
154
154
  constant — no inline percent), and the wrapper's `codex_down` class.
155
- - Opt-out token or `codex_down` → set `codexDown`, no stamp, move to the
155
+ - Missing opt-in (the default), opt-out token, or `codex_down` → set
156
+ `codexDown`, no stamp, move to the
156
157
  convergence check with `--codex-down`. A `codex_down` classification also
157
158
  records a `codexNote` so the skip stays visible in the final report.
158
159
  - Usage at/below threshold or null → skip with no stamp; the machine checklist
@@ -88,10 +88,12 @@ Each reviewer-down condition below skips its own convergence-check gate. The fla
88
88
  `--copilot-down` (the Copilot review gate and the pending-requested-reviews
89
89
  gate bypassed), then mark-ready. `copilotNote` records the bypass for the
90
90
  final report.
91
- - **Terminal Codex gate skipped (opt-out, usage, or `codex_down`)** — the
91
+ - **Terminal Codex gate skipped (no opt-in, opt-out, usage, or `codex_down`)** — the
92
92
  conditional-required Codex gate runs after Bugbot and Copilot. When
93
- `CLAUDE_REVIEWS_DISABLED` lists `codex` (`reviews_disabled.py --reviewer codex`
94
- exit 0), the gate sets `codexDown` and advances with no review. When the weekly
93
+ `reviews_disabled.py --reviewer codex` exits 0 — which it does whenever
94
+ `CLAUDE_REVIEWS_ENABLED` omits `codex`, the default, and whenever
95
+ `CLAUDE_REVIEWS_DISABLED` lists it — the gate sets `codexDown` and advances
96
+ with no review. When the weekly
95
97
  usage probe reports `percent_left` null or at/below the shared threshold
96
98
  (`is_codex_review_required` false), the gate skips without a stamp; the
97
99
  convergence check applies the same rule. When the codex-review wrapper
@@ -0,0 +1,54 @@
1
+ ---
2
+ name: beat-sheet
3
+ description: "Formats a reply as single-line beats in plain everyday words. Triggers: '/beat-sheet', 'beat sheet this', 'give me the beats', 'write this as beats', 'too long', 'shorter', 'what?', 'english', 'no sense', 'jargon', 'huh?'."
4
+ ---
5
+
6
+ # beat-sheet
7
+
8
+ Write in single-line beats. Make each line one complete thought,
9
+ under 12 words, with a blank line between lines. Keep it to ten
10
+ lines, each one covering a new point. Order: situation, problem,
11
+ fix, how it works. Put any command in its own code fence. Start
12
+ with one short bold title line. Use plain everyday words a tired
13
+ reader can skim.
14
+
15
+ ## Plain words
16
+
17
+ Name the real thing first — a file, an image, a control, a
18
+ screen, a size, an id, a proof. Prefer a word the reader can point
19
+ at over an abstract one. When a word only makes sense on this
20
+ project, say what it is in the app or on disk (a Theme Studio
21
+ control, a package file name).
22
+
23
+ ## What the reader gets
24
+
25
+ Lead with the answer. Put most of the reply on what they asked;
26
+ keep warnings short. For "what's wrong" or "what's missing",
27
+ answer in this order: what's wrong, what's missing, what follows.
28
+ For an explain request, give a short summary unless they ask for
29
+ more.
30
+
31
+ ## Around the work
32
+
33
+ Before the first tool call, say in one sentence what you'll do.
34
+ While working, speak up only on an important find or a change of
35
+ course. When you finish, open with the result — what happened or
36
+ what you found — then add detail only if it helps.
37
+
38
+ ## Job size
39
+
40
+ Do the job asked, at the size asked. Decide small things
41
+ yourself; ask only when two readings would change the work. When
42
+ the ask looks off or a better path is clear, say so in one
43
+ sentence, then do what was asked. Finish the whole job.
44
+
45
+ ## Before sending
46
+
47
+ Read the reply as someone new to the project. Replace any word
48
+ that needs a glossary with the thing itself.
49
+
50
+ ## Visual beats
51
+
52
+ Add a visual only when it earns its space beyond what the beats
53
+ already show on their own. See `reference/visual-beats.md` for the
54
+ shape picker, the `rich` setup, and a working example.
@@ -0,0 +1,29 @@
1
+ # Visual beats
2
+
3
+ Use one visual per reply, at most, sitting between beats in place
4
+ of the beat it explains.
5
+
6
+ Build it with `rich` (`pip install rich`), then paste the printed
7
+ text into a fenced block. Set `no_color=True` and a fixed `width`
8
+ so the output holds its shape in a terminal and on GitHub.
9
+
10
+ Pick the shape by what the beat carries:
11
+
12
+ | Shape | Carries |
13
+ |---|---|
14
+ | `Panel` | one claim worth framing |
15
+ | `Table` | values a reader compares |
16
+ | `Tree` | a stack, or parts inside a whole |
17
+
18
+ ```python
19
+ from rich.console import Console
20
+ from rich.table import Table
21
+ from rich import box
22
+
23
+ console = Console(width=64, no_color=True, force_terminal=False)
24
+ table = Table(box=box.SIMPLE_HEAVY, title="Slice budget")
25
+ table.add_column("slice")
26
+ table.add_column("lines", justify="right")
27
+ table.add_row("tests", "200")
28
+ console.print(table)
29
+ ```
@@ -19,10 +19,10 @@
19
19
 
20
20
  The three sibling skills compose, but `/bugteam` solves a problem they cannot solve in sequence:
21
21
 
22
- - `/findbugs` audits once and stops.
23
- - `/fixbugs` fixes the findings of one audit and stops.
24
- - A human-driven `/findbugs` → `/fixbugs` → `/findbugs` → `/fixbugs` cycle works but requires the user to drive it.
22
+ - `clean-room audit (code-quality-agent)` audits once and stops.
23
+ - `/pr-fix-protocol` fixes the findings of one audit and stops.
24
+ - A human-driven `clean-room audit (code-quality-agent)` → `/pr-fix-protocol` → `clean-room audit (code-quality-agent)` → `/pr-fix-protocol` cycle works but requires the user to drive it.
25
25
 
26
26
  `/bugteam` automates that cycle. The clean-room property is preserved by spawning a fresh audit agent each loop with no inherited context — every audit is independent of the prior loop's verdict. The 20-loop cap is the safety: pathological cases (audit agent oscillating, fix agent regressing) cannot run away.
27
27
 
28
- The single up-front confirmation is the explicit trade — `/bugteam` is more autonomous than `/findbugs`+`/fixbugs` chained manually. The user accepts that autonomy by typing the command. Stop conditions and the loop log give the user full visibility on exit.
28
+ The single up-front confirmation is the explicit trade — `/bugteam` is more autonomous than `clean-room audit (code-quality-agent)`+`/pr-fix-protocol` chained manually. The user accepts that autonomy by typing the command. Stop conditions and the loop log give the user full visibility on exit.
@@ -25,7 +25,7 @@ Claude: [runs 20 loops without convergence]
25
25
 
26
26
  `/bugteam exit: cap reached`
27
27
  `Loops: 20`
28
- `Remaining: 0P0 / 1P1 / 2P2 — run /findbugs for human triage`
28
+ `Remaining: 0P0 / 1P1 / 2P2 — run /pr-converge for human triage`
29
29
  </example>
30
30
 
31
31
  <example>
@@ -20,7 +20,7 @@ The `pre-push-review` skill was retired. Its mechanical checks are now covered a
20
20
 
21
21
  - **Mechanical pre-push checks** (magic values, boolean naming, imports, constants location, and other CODE_RULES checks) — handled by the `code_rules_enforcer.py` PreToolUse hook (blocks at write time) and by the git pre-push hook installed via `npx claude-dev-env`. The git pre-push hook is the gate that runs at `git push` time; no manual invocation is needed.
22
22
 
23
- - **`/qbug`** — a full PR audit-fix cycle that spawns subagents, runs multiple audit loops, and produces a structured report. It is NOT a lightweight pre-push gate. Do not use `/qbug` as a substitute for `git push` (the hook fires automatically). Use `/qbug` when you want a thorough multi-loop review of a PR before requesting human review.
23
+ - **`/bugteam`** — a full PR audit-fix cycle that spawns subagents, runs multiple audit loops, and produces a structured report. It is NOT a lightweight pre-push gate. Do not use `/bugteam` as a substitute for `git push` (the hook fires automatically). Use `/bugteam` when you want a thorough multi-loop review of a PR before requesting human review.
24
24
 
25
25
  References:
26
26
  - `hooks/git-hooks/pre_push.py` — the git pre-push hook that runs the CODE_RULES gate over the commits about to be pushed
@@ -14,8 +14,9 @@ description: >-
14
14
  ## Gotchas
15
15
 
16
16
  - **`low` stays single-pass.** No subagents, no full-file reads: one read pass per target item, one findings pass.
17
- - **`medium` favors precision, `xhigh` favors recall.** At `medium` (8 angles) surface only findings a maintainer would act on. At `xhigh` (10 angles plus a gap sweep) a single non-REFUTED vote carries the finding; do not drop on uncertainty.
18
- - **Every retained finding carries `severity` and `verdict`.** Severity is one of `blocker`, `high`, `medium`, `low`, `nit`. Verdict is `CONFIRMED` or `PLAUSIBLE`. Drop REFUTED candidates; never emit an unclassified retained finding.
17
+ - **Collection reports every real finding.** Keep every CONFIRMED or PLAUSIBLE finding at its assigned severity (`blocker`, `high`, `medium`, `low`, `nit`). Do not drop low or nit findings during collection. Severity or action filtering is a separate consumer stage after the collection record is complete (`scripts/finding_pipeline.py`).
18
+ - **`medium` favors precision, `xhigh` favors recall.** At `medium` (8 angles) assign severity carefully so a later filter can pick maintainer-action findings. At `xhigh` (10 angles plus a gap sweep) a single non-REFUTED vote carries the finding; do not drop on uncertainty.
19
+ - **Every retained finding carries `severity` and `verdict`.** Severity is one of `blocker`, `high`, `medium`, `low`, `nit`. Verdict is `CONFIRMED` or `PLAUSIBLE`. Drop REFUTED candidates only; never emit an unclassified retained finding.
19
20
  - **`--fix` applies findings once.** Load `reference/fix.md` and follow it — it owns the fix agent, the code-rules gate, skip logging, and outcome reporting. Commits are lead-owned; fix agents never commit or push.
20
21
  - **`loop` never asks.** A round with bug findings validates them with an advisor, fixes, and re-reviews. Terminals are exactly `clean`, `nits_fixed`, and `advisor_blocked`. There is no reviewed-head count limit; a new head increments the count once, a re-review of the same head does not. Load `reference/loop.md` and follow it.
21
22
  - **`--fix` and `loop` combine.** With both, each loop round runs the level file, and the round's fixing happens inside `reference/loop.md`'s gate sequence, which loads `reference/fix.md` for the mechanics. There is no separate fix pass around the round.
@@ -28,6 +29,20 @@ Triggers: `/e-code-review <level> [--fix] [loop]`. `<level>` is `low`, `medium`,
28
29
 
29
30
  - **No level, or an unknown level.** Respond exactly: `Which effort level — low, medium, or xhigh?`
30
31
 
32
+ ## Evaluation-backed defaults (e-code-review family)
33
+
34
+ When the caller asks which level to pick for a known fixture band (easy / medium / demanding scope), use the committed OP-02B evaluation evidence — not an inherited hard-coded preference. Thinking stays on; **effort** is the only cost/latency lever.
35
+
36
+ | Fixture band | Skill effort | Source |
37
+ |---|---|---|
38
+ | easy | `medium` | `scripts/effort_defaults_evidence.json` → `skill_defaults.default_by_band.easy` |
39
+ | medium | `xhigh` | same file → `medium` (maps evaluation `high`) |
40
+ | demanding | `xhigh` | same file → `demanding` (maps evaluation `max`) |
41
+
42
+ Resolve programmatically with `scripts/effort_evaluation.py` → `resolve_skill_effort_for_band`. Every default cites a completed evaluation row. The user-facing command still requires an explicit level flag; these defaults answer "what should I pick?" for this workflow family only.
43
+
44
+ Detail: `reference/effort-evaluation.md`.
45
+
31
46
  ## The process
32
47
 
33
48
  1. Read `<level>` and the optional `--fix` and `loop` flags. Apply the refusal first.
@@ -46,8 +61,19 @@ Triggers: `/e-code-review <level> [--fix] [loop]`. `<level>` is `low`, `medium`,
46
61
  | `reference/xhigh.md` | xhigh review procedure — 10 angles, 1-vote verify, gap sweep |
47
62
  | `reference/fix.md` | Fix application, code-rules gate, skip logging, outcome reporting |
48
63
  | `reference/loop.md` | Repeat review/fix rounds until clean |
64
+ | `reference/effort-evaluation.md` | Effort evaluation fixtures, evidence, and skill defaults |
65
+ | `reference/runner-selection.md` | Runner selection map |
66
+ | `scripts/finding_pipeline.py` | Collect every real finding; filter severity only later |
67
+ | `scripts/test_finding_pipeline.py` | Collection and filter-stage behavioral tests |
68
+ | `scripts/e_code_review_scripts_constants/finding_pipeline_constants.py` | Named constants for the collect-then-filter pipeline |
69
+ | `scripts/effort_evaluation.py` | Effort rows, recommendation, skill default resolver |
70
+ | `scripts/effort_defaults_evidence.json` | Committed evaluation rows + e-code-review skill defaults |
71
+ | `scripts/grok_code_review.py` | Grok medium-review discovery and verification |
72
+ | `scripts/test_grok_code_review.py` | Behavioral tests for the Grok medium-review module |
73
+ | `scripts/e_code_review_scripts_constants/` | Skill-local constants (unique package name; avoids bare `config` import shadow) |
49
74
 
50
75
  ## Folder map
51
76
 
52
77
  - `SKILL.md` — route and dispatch.
53
- - `reference/` — one procedure per level, plus `fix.md` and `loop.md`.
78
+ - `reference/` — level procedures, fix/loop, effort evaluation, runner selection.
79
+ - `scripts/` — collect-then-filter finding pipeline, effort evaluation, Grok medium-review module, tests, and `e_code_review_scripts_constants/`.
@@ -0,0 +1,35 @@
1
+ # Effort evaluation sweep (Opus)
2
+
3
+ Offline-first harness for choosing e-code-review effort and publishing cited skill defaults.
4
+
5
+ ## What it holds
6
+
7
+ | Piece | Path |
8
+ |---|---|
9
+ | Fixtures | `scripts/fixtures/{easy,medium,demanding}.json` |
10
+ | Schema + recommend | `scripts/effort_evaluation.py` |
11
+ | Constants | `scripts/config/e_code_review_effort_constants/` |
12
+ | Tests | `scripts/test_effort_evaluation.py` |
13
+
14
+ ## How to run offline tests
15
+
16
+ ```
17
+ python -m pytest packages/claude-dev-env/skills/e-code-review/scripts/test_effort_evaluation.py -q
18
+ ```
19
+
20
+ ## Skill defaults (OP-02C — e-code-review family)
21
+
22
+ Committed evidence: `scripts/effort_defaults_evidence.json`.
23
+
24
+ - `resolve_skill_effort_for_band("easy"|"medium"|"demanding")` → `low`|`medium`|`xhigh`
25
+ - Evaluation `high` / `max` map to skill `xhigh` (skill surface has three levels only)
26
+ - Every skill default cites a completed evaluation row with `thinking_enabled: true`
27
+
28
+ ## Paid / live runs (optional)
29
+
30
+ 1. For each fixture, run the matching e-code-review level at each CLI-supported effort (`low` … `max`) with thinking on.
31
+ 2. Score quality, finding recall, finding precision; record visible tokens and latency.
32
+ 3. Feed completed rows into `recommend_effort_by_band` and `skill_defaults_from_recommendation`.
33
+ 4. Replace `effort_defaults_evidence.json` when live rows supersede the offline baseline.
34
+
35
+ Stop if the Opus 5 CLI model is unavailable, or if results cannot separate quality from cost/latency.
@@ -1,7 +1,10 @@
1
1
  `medium effort → 3+5 angles → 1-vote verify`
2
2
 
3
- You are reviewing for **precision** at medium effort: every finding you surface
4
- should be one a maintainer would act on.
3
+ You are reviewing for **precision** at medium effort: assign severity carefully
4
+ so a later consumer can select maintainer-action findings. **Collection
5
+ reports every real finding** (including `low` and `nit`); do not drop by
6
+ severity during collection. Severity filtering is a separate consumer stage
7
+ after the collection record is complete.
5
8
 
6
9
  ## Phase 0 — Gather the diff
7
10
 
@@ -121,11 +124,19 @@ Keep candidates where the vote is CONFIRMED or PLAUSIBLE.
121
124
 
122
125
  ## Output
123
126
 
127
+ **Collection stage first.** Keep every CONFIRMED or PLAUSIBLE finding in the
128
+ collection record, including `low` and `nit`. Drop only REFUTED candidates.
129
+ Do not drop a real finding because its severity is low.
130
+
124
131
  Report this review's results — `{level, findings}` — through the structured
125
132
  findings-report call: the mechanism that renders a review's results as a typed
126
133
  list in the host UI, ranked most-severe first. Each **retained** entry carries
127
- every field below. Drop REFUTED candidates before this report; do not emit a
128
- finding that lacks `severity` or `verdict`.
134
+ every field below. Do not emit a finding that lacks `severity` or `verdict`.
135
+
136
+ **Severity filter stage (later consumer).** After the collection record is
137
+ complete, a separate consumer may filter by minimum severity for action or
138
+ display. That filter must not rewrite or discard fields on the collection
139
+ record itself.
129
140
 
130
141
  | Field | Required | Value |
131
142
  |---|---|---|
@@ -0,0 +1,40 @@
1
+ # Runner selection (medium review)
2
+
3
+ How `/e-code-review medium` (and loop) should pick a **harness runner** for
4
+ finder/verify work. This file is the map; `SKILL.md` only points here.
5
+
6
+ ## What lives here
7
+
8
+ | Topic | Content |
9
+ |---|---|
10
+ | Goal | One skill surface; many possible runners (Grok, Codex, Claude headless, …) |
11
+ | Today | `scripts/grok_code_review.py` is the Grok medium orchestration module |
12
+ | Target | A thin selector chooses a runner by availability and task flags |
13
+ | Non-goals | Reimplementing every harness inside this skill |
14
+
15
+ ## Today
16
+
17
+ - Medium procedure: `reference/medium.md` (angles, verify, output fields).
18
+ - Grok orchestration API: `scripts/grok_code_review.py` (discovery, dedupe,
19
+ retain, head-drift).
20
+ - Constants: `scripts/e_code_review_scripts_constants/`.
21
+
22
+ ## Target shape (tracked separately)
23
+
24
+ 1. **Runner protocol** — shared inputs (diff base, head, angles) and outputs
25
+ (candidates, verdicts, severities).
26
+ 2. **Detection** — which runners are installed/configured (PATH, skills,
27
+ account chain).
28
+ 3. **Selection** — pick one runner without baking a single vendor into
29
+ `SKILL.md` process steps.
30
+ 4. **Adapters** — thin wrappers: Grok (current module), Codex, Claude, …
31
+
32
+ Open issue for implementation work should link this file and keep PRs small
33
+ (Google small-CL practice: one concern per PR).
34
+
35
+ ## Related always-on docs
36
+
37
+ - Skill hub: `../SKILL.md` (levels, fix, loop — not runner internals).
38
+ - Medium procedure: `medium.md`.
39
+ - Shared worker spawn (when applicable):
40
+ `packages/claude-dev-env/_shared/pr-loop/worker-spawn.md` in the package tree.
@@ -0,0 +1,41 @@
1
+ """Constants for the e-code-review effort evaluation harness."""
2
+
3
+ from e_code_review_effort_constants.effort_constants import (
4
+ ALL_EFFORT_LEVELS,
5
+ ALL_EFFORT_RANK_BY_NAME,
6
+ ALL_FIXTURE_BANDS,
7
+ ALL_REQUIRED_ROW_KEYS,
8
+ ALL_SCORE_ROW_KEYS,
9
+ ALL_SKILL_EFFORT_FOR_EVALUATION_EFFORT,
10
+ ALL_SKILL_EFFORT_LEVELS,
11
+ COST_LATENCY_LEVER,
12
+ EVALUATION_EVIDENCE_FILENAME,
13
+ EVALUATION_SCHEMA_VERSION,
14
+ FIXTURES_DIRECTORY_NAME,
15
+ JSON_SUFFIX,
16
+ LATENCY_MS_ROW_KEY,
17
+ MINIMUM_QUALITY_HOLD_SCORE,
18
+ THINKING_ENABLED_DEFAULT,
19
+ VISIBLE_TOKENS_ROW_KEY,
20
+ WORKFLOW_FAMILY_E_CODE_REVIEW,
21
+ )
22
+
23
+ __all__ = [
24
+ "ALL_EFFORT_LEVELS",
25
+ "ALL_EFFORT_RANK_BY_NAME",
26
+ "ALL_FIXTURE_BANDS",
27
+ "ALL_REQUIRED_ROW_KEYS",
28
+ "ALL_SCORE_ROW_KEYS",
29
+ "ALL_SKILL_EFFORT_FOR_EVALUATION_EFFORT",
30
+ "ALL_SKILL_EFFORT_LEVELS",
31
+ "COST_LATENCY_LEVER",
32
+ "EVALUATION_EVIDENCE_FILENAME",
33
+ "EVALUATION_SCHEMA_VERSION",
34
+ "FIXTURES_DIRECTORY_NAME",
35
+ "JSON_SUFFIX",
36
+ "LATENCY_MS_ROW_KEY",
37
+ "MINIMUM_QUALITY_HOLD_SCORE",
38
+ "THINKING_ENABLED_DEFAULT",
39
+ "VISIBLE_TOKENS_ROW_KEY",
40
+ "WORKFLOW_FAMILY_E_CODE_REVIEW",
41
+ ]
@@ -0,0 +1,40 @@
1
+ """Named values for the Opus effort evaluation sweep."""
2
+
3
+ EVALUATION_SCHEMA_VERSION: str = "1"
4
+ THINKING_ENABLED_DEFAULT: bool = True
5
+ MINIMUM_QUALITY_HOLD_SCORE: float = 0.8
6
+ COST_LATENCY_LEVER: str = "effort"
7
+ ALL_EFFORT_LEVELS: tuple[str, ...] = ("low", "medium", "high", "xhigh", "max")
8
+ ALL_FIXTURE_BANDS: tuple[str, ...] = ("easy", "medium", "demanding")
9
+ ALL_SCORE_ROW_KEYS: tuple[str, ...] = (
10
+ "quality_score",
11
+ "finding_recall",
12
+ "finding_precision",
13
+ )
14
+ FIXTURES_DIRECTORY_NAME: str = "fixtures"
15
+ JSON_SUFFIX: str = ".json"
16
+ VISIBLE_TOKENS_ROW_KEY: str = "visible_tokens"
17
+ LATENCY_MS_ROW_KEY: str = "latency_ms"
18
+ ALL_REQUIRED_ROW_KEYS: tuple[str, ...] = (
19
+ "fixture_id",
20
+ "fixture_band",
21
+ "effort",
22
+ *ALL_SCORE_ROW_KEYS,
23
+ VISIBLE_TOKENS_ROW_KEY,
24
+ LATENCY_MS_ROW_KEY,
25
+ "thinking_enabled",
26
+ )
27
+ ALL_EFFORT_RANK_BY_NAME: dict[str, int] = {
28
+ each_effort: each_index
29
+ for each_index, each_effort in enumerate(ALL_EFFORT_LEVELS)
30
+ }
31
+ ALL_SKILL_EFFORT_LEVELS: tuple[str, ...] = ("low", "medium", "xhigh")
32
+ EVALUATION_EVIDENCE_FILENAME: str = "effort_defaults_evidence.json"
33
+ WORKFLOW_FAMILY_E_CODE_REVIEW: str = "e-code-review"
34
+ ALL_SKILL_EFFORT_FOR_EVALUATION_EFFORT: dict[str, str] = {
35
+ "low": "low",
36
+ "medium": "medium",
37
+ "high": "xhigh",
38
+ "xhigh": "xhigh",
39
+ "max": "xhigh",
40
+ }
@@ -0,0 +1 @@
1
+ """Constants package for e-code-review scripts."""