pi-dev-team 0.2.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 (780) hide show
  1. package/LICENSE +21 -0
  2. package/PORTING.md +134 -0
  3. package/README.md +207 -0
  4. package/UPSTREAM.json +64 -0
  5. package/agents/Explore.md +15 -0
  6. package/agents/a11y-review.md +118 -0
  7. package/agents/adr-author.md +70 -0
  8. package/agents/ai-provenance-review.md +120 -0
  9. package/agents/angular-reactivity-review.md +95 -0
  10. package/agents/arch-review.md +135 -0
  11. package/agents/architect.md +78 -0
  12. package/agents/autoship-batch-proposer.md +69 -0
  13. package/agents/claude-setup-review.md +136 -0
  14. package/agents/codebase-recon.md +184 -0
  15. package/agents/component-architecture-review.md +119 -0
  16. package/agents/concurrency-review.md +109 -0
  17. package/agents/correctness-review.md +290 -0
  18. package/agents/data-flow-tracer.md +120 -0
  19. package/agents/doc-review.md +165 -0
  20. package/agents/domain-review.md +136 -0
  21. package/agents/general-purpose.md +10 -0
  22. package/agents/gherkin-quality-critic.md +113 -0
  23. package/agents/js-fp-review.md +114 -0
  24. package/agents/mutation-kill.md +684 -0
  25. package/agents/naming-review.md +142 -0
  26. package/agents/orchestrator.md +339 -0
  27. package/agents/performance-review.md +105 -0
  28. package/agents/plan-review-acceptance.md +115 -0
  29. package/agents/plan-review-design.md +90 -0
  30. package/agents/plan-review-parallelization.md +84 -0
  31. package/agents/plan-review-strategic.md +96 -0
  32. package/agents/plan-review-ux.md +110 -0
  33. package/agents/platform-engineer.md +64 -0
  34. package/agents/product-manager.md +68 -0
  35. package/agents/progress-guardian.md +79 -0
  36. package/agents/qa-engineer.md +289 -0
  37. package/agents/quality-reviewer.md +132 -0
  38. package/agents/react-reactivity-review.md +102 -0
  39. package/agents/refactor-opportunity-review.md +128 -0
  40. package/agents/security-engineer.md +60 -0
  41. package/agents/security-review.md +218 -0
  42. package/agents/session-analysis.md +95 -0
  43. package/agents/software-engineer.md +105 -0
  44. package/agents/spec-compliance-review.md +100 -0
  45. package/agents/spec-reviewer.md +114 -0
  46. package/agents/structure-review.md +146 -0
  47. package/agents/tech-writer.md +84 -0
  48. package/agents/test-review.md +246 -0
  49. package/agents/test-smell-review.md +188 -0
  50. package/agents/token-efficiency-review.md +139 -0
  51. package/agents/ui-ux-designer.md +54 -0
  52. package/agents/vue-reactivity-review.md +95 -0
  53. package/bin/__pycache__/claudecpython-314.pyc +0 -0
  54. package/bin/claude +258 -0
  55. package/docs/upstream/.pages +1 -0
  56. package/docs/upstream/CHANGELOG.md +2586 -0
  57. package/docs/upstream/README.md +155 -0
  58. package/docs/upstream/agent-architecture.md +214 -0
  59. package/docs/upstream/agent_info.md +187 -0
  60. package/docs/upstream/artifact-migration.md +124 -0
  61. package/docs/upstream/code-intelligence-nudge.md +149 -0
  62. package/docs/upstream/code-review-process.md +294 -0
  63. package/docs/upstream/concurrent-use.md +73 -0
  64. package/docs/upstream/context-management.md +111 -0
  65. package/docs/upstream/developer-notes.md +280 -0
  66. package/docs/upstream/diagrams/architecture-overview.svg +101 -0
  67. package/docs/upstream/diagrams/review-dispatch.svg +139 -0
  68. package/docs/upstream/diagrams/team-agents.svg +128 -0
  69. package/docs/upstream/diagrams/test-improve-flow.svg +166 -0
  70. package/docs/upstream/diagrams/workflow-linear.svg +66 -0
  71. package/docs/upstream/diagrams/workflow-three-phase.svg +200 -0
  72. package/docs/upstream/eval-maintenance.md +95 -0
  73. package/docs/upstream/eval-running-guide.md +147 -0
  74. package/docs/upstream/eval-system.md +291 -0
  75. package/docs/upstream/session-review-oss-complements.md +75 -0
  76. package/docs/upstream/session-review.md +212 -0
  77. package/docs/upstream/skills.md +188 -0
  78. package/docs/upstream/team-structure.md +21 -0
  79. package/docs/upstream/telemetry-ci-access.md +129 -0
  80. package/docs/upstream/telemetry-repo-security.md +120 -0
  81. package/docs/upstream/test-evaluation.md +277 -0
  82. package/docs/upstream/test-improve.md +154 -0
  83. package/docs/upstream/triage-workflow.md +282 -0
  84. package/docs/upstream/workflows.md +289 -0
  85. package/extensions/dev-team/index.ts +539 -0
  86. package/extensions/dev-team/lib/agents.ts +272 -0
  87. package/extensions/dev-team/lib/ai-credits.ts +92 -0
  88. package/extensions/dev-team/lib/autocompact.ts +81 -0
  89. package/extensions/dev-team/lib/child-run.ts +102 -0
  90. package/extensions/dev-team/lib/config.ts +236 -0
  91. package/extensions/dev-team/lib/gh-command.ts +103 -0
  92. package/extensions/dev-team/lib/github-style.ts +307 -0
  93. package/extensions/dev-team/lib/hooks.ts +350 -0
  94. package/extensions/dev-team/lib/metrics.ts +115 -0
  95. package/extensions/dev-team/lib/safe-read.ts +49 -0
  96. package/extensions/dev-team/lib/session-files.ts +57 -0
  97. package/extensions/dev-team/lib/session-spend.ts +123 -0
  98. package/extensions/dev-team/lib/shell-scan.ts +205 -0
  99. package/extensions/dev-team/lib/skills.ts +213 -0
  100. package/extensions/dev-team/lib/subagent-render.ts +245 -0
  101. package/extensions/dev-team/lib/subagent-types.ts +164 -0
  102. package/extensions/dev-team/lib/subagent.ts +596 -0
  103. package/extensions/dev-team/lib/terminal-text.ts +54 -0
  104. package/extensions/dev-team/lib/tools-misc.ts +152 -0
  105. package/extensions/dev-team/lib/transcript.ts +110 -0
  106. package/extensions/dev-team/lib/trust.ts +52 -0
  107. package/extensions/dev-team/lib/usage-breakdown.ts +176 -0
  108. package/extensions/dev-team/lib/usage-chart.ts +153 -0
  109. package/extensions/dev-team/lib/usage-command.ts +107 -0
  110. package/extensions/dev-team/lib/usage-history.ts +203 -0
  111. package/extensions/dev-team/lib/usage-render.ts +225 -0
  112. package/extensions/dev-team/lib/usage-split-bar.ts +127 -0
  113. package/extensions/dev-team/lib/usage-state.ts +116 -0
  114. package/extensions/dev-team/lib/usage-text.ts +159 -0
  115. package/extensions/dev-team/lib/usage-view.ts +109 -0
  116. package/hooks/__pycache__/refactor_test_freeze_guard.cpython-314.pyc +0 -0
  117. package/hooks/agent_dispatch_ledger.py +190 -0
  118. package/hooks/autocompact_setup_nudge.py +99 -0
  119. package/hooks/bash_retry_guard.py +228 -0
  120. package/hooks/boundary_events_write_guard.py +352 -0
  121. package/hooks/code_intelligence_nudge.py +293 -0
  122. package/hooks/code_intelligence_turn_mark.py +317 -0
  123. package/hooks/codegraph_bootstrap.py +139 -0
  124. package/hooks/contract_version_guard.py +362 -0
  125. package/hooks/cost_meter.py +106 -0
  126. package/hooks/destructive-commands.json +62 -0
  127. package/hooks/destructive_guard.py +477 -0
  128. package/hooks/eval_compliance_check.py +440 -0
  129. package/hooks/guards.json +17 -0
  130. package/hooks/hooks.json +323 -0
  131. package/hooks/internal_double_gate.py +296 -0
  132. package/hooks/js_fp_review.py +212 -0
  133. package/hooks/knowledge_index.py +119 -0
  134. package/hooks/lib/__pycache__/artifact_paths.cpython-314.pyc +0 -0
  135. package/hooks/lib/__pycache__/atomic_state.cpython-314.pyc +0 -0
  136. package/hooks/lib/__pycache__/autocompact_config.cpython-314.pyc +0 -0
  137. package/hooks/lib/__pycache__/boundary_events.cpython-314.pyc +0 -0
  138. package/hooks/lib/__pycache__/doc_classification.cpython-314.pyc +0 -0
  139. package/hooks/lib/__pycache__/gh_pr_create_detect.cpython-314.pyc +0 -0
  140. package/hooks/lib/__pycache__/git_safe_diff.cpython-314.pyc +0 -0
  141. package/hooks/lib/__pycache__/instrument_log.cpython-314.pyc +0 -0
  142. package/hooks/lib/__pycache__/metrics_query.cpython-314.pyc +0 -0
  143. package/hooks/lib/__pycache__/plugin_version.cpython-314.pyc +0 -0
  144. package/hooks/lib/__pycache__/pre_commit_doc_classifier.cpython-314.pyc +0 -0
  145. package/hooks/lib/__pycache__/review_agent_registry.cpython-314.pyc +0 -0
  146. package/hooks/lib/__pycache__/review_gate_corroboration.cpython-314.pyc +0 -0
  147. package/hooks/lib/__pycache__/review_gate_hash.cpython-314.pyc +0 -0
  148. package/hooks/lib/__pycache__/review_verdicts.cpython-314.pyc +0 -0
  149. package/hooks/lib/__pycache__/stdin_json.cpython-314.pyc +0 -0
  150. package/hooks/lib/__pycache__/stryker_invocation.cpython-314.pyc +0 -0
  151. package/hooks/lib/__pycache__/telemetry_consent.cpython-314.pyc +0 -0
  152. package/hooks/lib/__pycache__/test_file_classify.cpython-314.pyc +0 -0
  153. package/hooks/lib/__pycache__/token_efficiency_limits.cpython-314.pyc +0 -0
  154. package/hooks/lib/__pycache__/verify_guard_state.cpython-314.pyc +0 -0
  155. package/hooks/lib/__pycache__/xunit_v3_operator_gate.cpython-314.pyc +0 -0
  156. package/hooks/lib/agent_skill_hints.py +74 -0
  157. package/hooks/lib/artifact_paths.py +263 -0
  158. package/hooks/lib/atomic_state.py +557 -0
  159. package/hooks/lib/autocompact_config.py +103 -0
  160. package/hooks/lib/autoship_log.py +106 -0
  161. package/hooks/lib/banned_scripts_policy.py +51 -0
  162. package/hooks/lib/boundary_events.py +436 -0
  163. package/hooks/lib/build_knowledge_index.py +504 -0
  164. package/hooks/lib/build_skills_index.py +361 -0
  165. package/hooks/lib/build_state.py +116 -0
  166. package/hooks/lib/classify_ship_outcome.py +126 -0
  167. package/hooks/lib/config_changelog_schema.py +115 -0
  168. package/hooks/lib/cost_meter.py +955 -0
  169. package/hooks/lib/doc_classification.py +116 -0
  170. package/hooks/lib/gh_pr_create_detect.py +136 -0
  171. package/hooks/lib/git_safe_diff.py +123 -0
  172. package/hooks/lib/instrument_log.py +66 -0
  173. package/hooks/lib/iteration_journal_gate.py +197 -0
  174. package/hooks/lib/knowledge_index_paths.py +88 -0
  175. package/hooks/lib/mcp_json_repowise.py +177 -0
  176. package/hooks/lib/metrics_query.py +202 -0
  177. package/hooks/lib/minimal_yaml.py +434 -0
  178. package/hooks/lib/plugin_version.py +142 -0
  179. package/hooks/lib/pre_commit_detect.py +537 -0
  180. package/hooks/lib/pre_commit_doc_classifier.py +126 -0
  181. package/hooks/lib/pricing.py +118 -0
  182. package/hooks/lib/report_pdf.py +371 -0
  183. package/hooks/lib/review_agent_registry.py +142 -0
  184. package/hooks/lib/review_dispatch_ledger.py +101 -0
  185. package/hooks/lib/review_gate_corroboration.py +521 -0
  186. package/hooks/lib/review_gate_hash.py +252 -0
  187. package/hooks/lib/review_gate_normalized_hash.py +1115 -0
  188. package/hooks/lib/review_verdicts.py +301 -0
  189. package/hooks/lib/run_report.py +160 -0
  190. package/hooks/lib/skill_categories.yaml +125 -0
  191. package/hooks/lib/stdin_json.py +57 -0
  192. package/hooks/lib/stryker_invocation.py +102 -0
  193. package/hooks/lib/telemetry_consent.py +41 -0
  194. package/hooks/lib/telemetry_report.py +108 -0
  195. package/hooks/lib/test_file_classify.py +160 -0
  196. package/hooks/lib/token_efficiency_limits.py +51 -0
  197. package/hooks/lib/turn_identity.py +77 -0
  198. package/hooks/lib/verify_guard_state.py +110 -0
  199. package/hooks/lib/workflow_state.py +206 -0
  200. package/hooks/lib/xunit_v3_operator_gate.py +596 -0
  201. package/hooks/mcp_json_repowise_nudge.py +74 -0
  202. package/hooks/mutation_adapters/__init__.py +7 -0
  203. package/hooks/mutation_adapters/__pycache__/__init__.cpython-314.pyc +0 -0
  204. package/hooks/mutation_adapters/__pycache__/lib.cpython-314.pyc +0 -0
  205. package/hooks/mutation_adapters/__pycache__/mutmut.cpython-314.pyc +0 -0
  206. package/hooks/mutation_adapters/__pycache__/pitest.cpython-314.pyc +0 -0
  207. package/hooks/mutation_adapters/__pycache__/stryker.cpython-314.pyc +0 -0
  208. package/hooks/mutation_adapters/__pycache__/stryker_net.cpython-314.pyc +0 -0
  209. package/hooks/mutation_adapters/lib.py +478 -0
  210. package/hooks/mutation_adapters/mutmut.py +188 -0
  211. package/hooks/mutation_adapters/pitest.py +266 -0
  212. package/hooks/mutation_adapters/stryker.py +157 -0
  213. package/hooks/mutation_adapters/stryker_net.py +264 -0
  214. package/hooks/mutation_gate.py +193 -0
  215. package/hooks/mutation_testing_smoke_gate.py +371 -0
  216. package/hooks/pending_review_notify.py +121 -0
  217. package/hooks/phase_marker.py +138 -0
  218. package/hooks/post_compact_state_reinject.py +180 -0
  219. package/hooks/post_format.py +115 -0
  220. package/hooks/pre_commit_knowledge_index.py +128 -0
  221. package/hooks/pre_commit_review.py +66 -0
  222. package/hooks/pre_pr_review.py +694 -0
  223. package/hooks/pre_tool_guard.py +405 -0
  224. package/hooks/py.sh +73 -0
  225. package/hooks/refactor-bash-write-patterns.json +29 -0
  226. package/hooks/refactor_test_bash_guard.py +253 -0
  227. package/hooks/refactor_test_freeze_guard.py +139 -0
  228. package/hooks/refactor_test_revert_guard.py +186 -0
  229. package/hooks/repo_review_nudge.py +287 -0
  230. package/hooks/review_verdict_recorder.py +464 -0
  231. package/hooks/scan_bash_command_for_banned_scripts.py +428 -0
  232. package/hooks/scan_worktree_for_banned_scripts.py +238 -0
  233. package/hooks/session_learning_trigger.py +248 -0
  234. package/hooks/skills_index.py +126 -0
  235. package/hooks/stryker_xunit_shim_guard.py +571 -0
  236. package/hooks/subagent_completion_guard.py +309 -0
  237. package/hooks/subagent_skill_context.py +139 -0
  238. package/hooks/task_completion_metrics.py +216 -0
  239. package/hooks/tdd_guard.py +229 -0
  240. package/hooks/telemetry.py +341 -0
  241. package/hooks/token_efficiency_review.py +194 -0
  242. package/hooks/verify_guard.py +183 -0
  243. package/hooks/verify_guard_edit_marker.py +73 -0
  244. package/hooks/version_check.py +173 -0
  245. package/knowledge/accepted-risks-schema.md +98 -0
  246. package/knowledge/adr-decision-criteria.md +64 -0
  247. package/knowledge/adversarial-review-protocol.md +139 -0
  248. package/knowledge/agent-registry.md +228 -0
  249. package/knowledge/agent-review-methodology.md +80 -0
  250. package/knowledge/ai-friendly-repo-guidelines.md +67 -0
  251. package/knowledge/architecture-assessment.md +96 -0
  252. package/knowledge/artifact-lifecycle.md +57 -0
  253. package/knowledge/cd-maturity-model.md +82 -0
  254. package/knowledge/cd-test-architecture.md +190 -0
  255. package/knowledge/ci-cd-file-scope.md +24 -0
  256. package/knowledge/codegraph-vs-graphify.md +192 -0
  257. package/knowledge/component-test-patterns.md +139 -0
  258. package/knowledge/database-change-management.md +80 -0
  259. package/knowledge/database-test-patterns.md +79 -0
  260. package/knowledge/decision-defaults.md +88 -0
  261. package/knowledge/dependency-breaking-techniques.md +116 -0
  262. package/knowledge/deployment-pipeline.md +86 -0
  263. package/knowledge/design-smells.md +122 -0
  264. package/knowledge/directory-enumeration.md +38 -0
  265. package/knowledge/domain-modeling.md +123 -0
  266. package/knowledge/evidence-bundle.md +90 -0
  267. package/knowledge/exploratory-testing-field-guide.md +122 -0
  268. package/knowledge/failure-routing.md +28 -0
  269. package/knowledge/fixture-construction.md +56 -0
  270. package/knowledge/frontend-component-architecture.md +139 -0
  271. package/knowledge/gherkin-quality-review-dispatch.md +135 -0
  272. package/knowledge/index.json +6766 -0
  273. package/knowledge/internal-collaborator-doubling.md +101 -0
  274. package/knowledge/legacy-test-strategy.md +71 -0
  275. package/knowledge/long-run-waiting.md +66 -0
  276. package/knowledge/microservice-testing.md +71 -0
  277. package/knowledge/model-pricing.json +23 -0
  278. package/knowledge/mutation-score-formulas.md +60 -0
  279. package/knowledge/object-calisthenics.md +147 -0
  280. package/knowledge/oracle-provenance.md +94 -0
  281. package/knowledge/orchestrator-script-implementation.md +185 -0
  282. package/knowledge/owasp-detection.md +148 -0
  283. package/knowledge/plan-review-rubric.md +56 -0
  284. package/knowledge/proxy-connectivity.md +62 -0
  285. package/knowledge/reactive-effect-patterns.md +73 -0
  286. package/knowledge/recon-inventory-excludes.txt +32 -0
  287. package/knowledge/references/bdd-value-guide.md +61 -0
  288. package/knowledge/references/csharp-http-client-testing.md +264 -0
  289. package/knowledge/release-strategies.md +74 -0
  290. package/knowledge/report-output-location.md +117 -0
  291. package/knowledge/report-pdf-integration.md +63 -0
  292. package/knowledge/report-print.css +129 -0
  293. package/knowledge/report-template.md +114 -0
  294. package/knowledge/report-to-pdf.md +69 -0
  295. package/knowledge/request-processing-flow.md +63 -0
  296. package/knowledge/result-verification.md +52 -0
  297. package/knowledge/review-agent-output-contract.md +121 -0
  298. package/knowledge/review-lens-classification.md +113 -0
  299. package/knowledge/review-rubric.md +62 -0
  300. package/knowledge/review-template.md +104 -0
  301. package/knowledge/rule-fixtures/A02.insecure-random-js/negative.js +1 -0
  302. package/knowledge/rule-fixtures/A02.insecure-random-js/positive.js +1 -0
  303. package/knowledge/rule-fixtures/A02.weak-hashing-md5/negative.py +1 -0
  304. package/knowledge/rule-fixtures/A02.weak-hashing-md5/positive.py +1 -0
  305. package/knowledge/rule-fixtures/A03.command-injection/negative.js +1 -0
  306. package/knowledge/rule-fixtures/A03.command-injection/positive.js +1 -0
  307. package/knowledge/rule-fixtures/A03.sql-injection/negative.js +1 -0
  308. package/knowledge/rule-fixtures/A03.sql-injection/positive.js +1 -0
  309. package/knowledge/rule-fixtures/A03.xss-innerhtml/negative.js +1 -0
  310. package/knowledge/rule-fixtures/A03.xss-innerhtml/positive.js +1 -0
  311. package/knowledge/rule-fixtures/A05.cors-wildcard/negative.js +1 -0
  312. package/knowledge/rule-fixtures/A05.cors-wildcard/positive.js +1 -0
  313. package/knowledge/rule-fixtures/A05.default-credentials/negative.js +1 -0
  314. package/knowledge/rule-fixtures/A05.default-credentials/positive.js +1 -0
  315. package/knowledge/rule-fixtures/A07.jwt-alg-none/negative.js +1 -0
  316. package/knowledge/rule-fixtures/A07.jwt-alg-none/positive.js +1 -0
  317. package/knowledge/rule-fixtures/A08.binary-formatter/negative.cs +1 -0
  318. package/knowledge/rule-fixtures/A08.binary-formatter/positive.cs +1 -0
  319. package/knowledge/rule-fixtures/A08.js-eval/negative.js +1 -0
  320. package/knowledge/rule-fixtures/A08.js-eval/positive.js +1 -0
  321. package/knowledge/rule-fixtures/A08.object-input-stream/negative.java +1 -0
  322. package/knowledge/rule-fixtures/A08.object-input-stream/positive.java +1 -0
  323. package/knowledge/schemas/disposition-register-v1.json +65 -0
  324. package/knowledge/schemas/recon-envelope-v1.json +198 -0
  325. package/knowledge/schemas/unified-finding-v1.json +72 -0
  326. package/knowledge/security-primitives-contract.md +301 -0
  327. package/knowledge/security-review-rule-map.yaml +107 -0
  328. package/knowledge/skills-registry.md +72 -0
  329. package/knowledge/task-size-classifier.md +103 -0
  330. package/knowledge/telemetry-schema.md +881 -0
  331. package/knowledge/test-automation-maturity.md +56 -0
  332. package/knowledge/test-automation-principles.md +71 -0
  333. package/knowledge/test-cadence-tradeoffs.md +68 -0
  334. package/knowledge/test-doubles.md +105 -0
  335. package/knowledge/test-file-indicators.md +22 -0
  336. package/knowledge/test-layer-gates.md +35 -0
  337. package/knowledge/test-matrix-examples/django-batch.md +24 -0
  338. package/knowledge/test-matrix-examples/dotnet-grpc-fronting-api.md +90 -0
  339. package/knowledge/test-matrix-examples/dotnet-http-consumer.md +131 -0
  340. package/knowledge/test-matrix-examples/react-node-spa.md +24 -0
  341. package/knowledge/test-matrix-examples/spring-boot-service.md +25 -0
  342. package/knowledge/test-matrix-examples/ssr-htmx.md +24 -0
  343. package/knowledge/test-organization.md +70 -0
  344. package/knowledge/test-pyramid.md +84 -0
  345. package/knowledge/test-refactoring.md +67 -0
  346. package/knowledge/test-review-division-of-labor.md +85 -0
  347. package/knowledge/test-smells.md +80 -0
  348. package/knowledge/test-stack-profiles/bdd-frameworks.md +235 -0
  349. package/knowledge/test-stack-profiles/django.md +13 -0
  350. package/knowledge/test-stack-profiles/dotnet.md +18 -0
  351. package/knowledge/test-stack-profiles/go.md +16 -0
  352. package/knowledge/test-stack-profiles/node.md +16 -0
  353. package/knowledge/test-stack-profiles/react.md +12 -0
  354. package/knowledge/test-stack-profiles/spring-boot.md +16 -0
  355. package/knowledge/test-stack-profiles/ssr-htmx.md +14 -0
  356. package/knowledge/test-stack-profiles/vue.md +12 -0
  357. package/knowledge/test-strategy.md +70 -0
  358. package/knowledge/testability-patterns.md +240 -0
  359. package/knowledge/testing-quadrants.md +44 -0
  360. package/knowledge/testing-techniques/approval.md +15 -0
  361. package/knowledge/testing-techniques/chaos.md +17 -0
  362. package/knowledge/testing-techniques/fuzz.md +15 -0
  363. package/knowledge/testing-techniques/property-based.md +15 -0
  364. package/knowledge/testing-techniques/schema-validation.md +15 -0
  365. package/knowledge/testing-techniques/screenshot.md +15 -0
  366. package/knowledge/three-phase-workflow.md +198 -0
  367. package/knowledge/value-patterns.md +55 -0
  368. package/knowledge/verification-mode.md +116 -0
  369. package/knowledge/virtual-service-libraries.md +75 -0
  370. package/knowledge/wave-consolidation-guidance.md +21 -0
  371. package/overrides/agents/Explore.md +15 -0
  372. package/overrides/agents/general-purpose.md +10 -0
  373. package/overrides/notes/autoship.md +6 -0
  374. package/overrides/notes/issues-from-assessment.md +3 -0
  375. package/overrides/notes/issues-from-plan.md +3 -0
  376. package/overrides/notes/mutation-night-watch.md +3 -0
  377. package/overrides/notes/mutation-testing.md +3 -0
  378. package/overrides/notes/pr.md +7 -0
  379. package/overrides/notes/project-init.md +6 -0
  380. package/overrides/notes/setup.md +13 -0
  381. package/overrides/notes/specs.md +3 -0
  382. package/overrides/skills/headless-run/SKILL.md +45 -0
  383. package/overrides/skills/upgrade/SKILL.md +30 -0
  384. package/overrides/skills/version/SKILL.md +25 -0
  385. package/package.json +36 -0
  386. package/scripts/authoring_digest.py +93 -0
  387. package/scripts/autoship_discover.py +121 -0
  388. package/scripts/autoship_group.py +409 -0
  389. package/scripts/autoship_proposals.py +494 -0
  390. package/scripts/autoship_queue.py +291 -0
  391. package/scripts/autoship_reclaim.py +495 -0
  392. package/scripts/build_jobs.py +108 -0
  393. package/scripts/build_rollback_point.py +240 -0
  394. package/scripts/build_slice_scope.py +157 -0
  395. package/scripts/build_wave.py +109 -0
  396. package/scripts/build_wave_reconcile.py +252 -0
  397. package/scripts/build_worktree_baseref.py +113 -0
  398. package/scripts/check_agent_scope.py +117 -0
  399. package/scripts/check_agent_tool_mapping.py +213 -0
  400. package/scripts/check_review_agent_mcp_tools.py +317 -0
  401. package/scripts/check_security_assessment_mcp_tools.py +165 -0
  402. package/scripts/checkpoint_abort.py +502 -0
  403. package/scripts/claude_setup_review.py +438 -0
  404. package/scripts/codebase_recon.py +556 -0
  405. package/scripts/coverage_config.py +623 -0
  406. package/scripts/coverage_delta_steering.py +330 -0
  407. package/scripts/coverage_discovery_dotnet.py +315 -0
  408. package/scripts/coverage_discovery_java.py +742 -0
  409. package/scripts/coverage_discovery_js.py +546 -0
  410. package/scripts/coverage_gap_ranking.py +556 -0
  411. package/scripts/coverage_readiness.py +455 -0
  412. package/scripts/coverage_report_parse.py +521 -0
  413. package/scripts/detect_bdd_convention.py +252 -0
  414. package/scripts/eval_ablation.py +376 -0
  415. package/scripts/gherkin_analysis_coverage_gate.py +306 -0
  416. package/scripts/gherkin_cross_feature_duplicate_titles_gate.py +173 -0
  417. package/scripts/gherkin_effectiveness_rollup.py +238 -0
  418. package/scripts/gherkin_failure_path_gate.py +206 -0
  419. package/scripts/gherkin_feature_merge.py +720 -0
  420. package/scripts/gherkin_stub_gate.py +163 -0
  421. package/scripts/gherkin_stub_merge.py +479 -0
  422. package/scripts/git_origin_host.py +88 -0
  423. package/scripts/install-java-static-analysis.py +110 -0
  424. package/scripts/issue_deps.py +74 -0
  425. package/scripts/lib/_bdd_markers.py +28 -0
  426. package/scripts/lib/_gherkin_text.py +93 -0
  427. package/scripts/lib/_vendored_tree.py +70 -0
  428. package/scripts/lib/autoship_state.py +397 -0
  429. package/scripts/lib/claude_md_guard.py +226 -0
  430. package/scripts/lib/deterministic_recon.py +446 -0
  431. package/scripts/lib/mcp_tool_grants.py +211 -0
  432. package/scripts/lib/plan_parse.py +386 -0
  433. package/scripts/lib/review_result.py +84 -0
  434. package/scripts/lib/review_roster.py +86 -0
  435. package/scripts/lib/session_log/__init__.py +34 -0
  436. package/scripts/lib/session_log/__pycache__/__init__.cpython-314.pyc +0 -0
  437. package/scripts/lib/session_log/__pycache__/records.cpython-314.pyc +0 -0
  438. package/scripts/lib/session_log/classify.py +231 -0
  439. package/scripts/lib/session_log/corrections.py +194 -0
  440. package/scripts/lib/session_log/discovery.py +108 -0
  441. package/scripts/lib/session_log/records.py +218 -0
  442. package/scripts/lib/session_log/redact.py +76 -0
  443. package/scripts/lib/session_log/signals.py +373 -0
  444. package/scripts/lib/session_report_downstream.py +614 -0
  445. package/scripts/lib/session_report_maintainer.py +1273 -0
  446. package/scripts/lib/session_report_shared.py +262 -0
  447. package/scripts/lib/settings_hook_guard.py +157 -0
  448. package/scripts/lib/slug.py +33 -0
  449. package/scripts/lib/stub_extractors/__init__.py +82 -0
  450. package/scripts/lib/stub_extractors/_common.py +328 -0
  451. package/scripts/lib/stub_extractors/csharp.py +19 -0
  452. package/scripts/lib/stub_extractors/go.py +173 -0
  453. package/scripts/lib/stub_extractors/java.py +18 -0
  454. package/scripts/lib/stub_extractors/jsts.py +126 -0
  455. package/scripts/mutation_stack_sections.py +149 -0
  456. package/scripts/mutation_yield_steering.py +345 -0
  457. package/scripts/orchestrator.py +895 -0
  458. package/scripts/plan_gherkin_export.py +227 -0
  459. package/scripts/plan_waves.py +208 -0
  460. package/scripts/pr_close_keyword_lint.py +108 -0
  461. package/scripts/progress_guardian.py +888 -0
  462. package/scripts/recon_inventory.py +273 -0
  463. package/scripts/review_findings_log.py +93 -0
  464. package/scripts/run_invariants.py +124 -0
  465. package/scripts/select_lenses.py +640 -0
  466. package/scripts/session_report.py +486 -0
  467. package/scripts/set_autocompact_env.py +221 -0
  468. package/scripts/ship_resume_guard.py +135 -0
  469. package/scripts/ship_review_gate.py +63 -0
  470. package/scripts/specs_convention_marker.py +103 -0
  471. package/scripts/test_improve_resume.py +277 -0
  472. package/scripts/test_review_mechanics.py +958 -0
  473. package/scripts/token_efficiency_review.py +322 -0
  474. package/scripts/verdict_scope.py +285 -0
  475. package/scripts/verify_gherkin_quality_critic_isolation.py +296 -0
  476. package/scripts/verify_tier.py +157 -0
  477. package/skills/adr-tools/SKILL.md +118 -0
  478. package/skills/agent-readiness/SKILL.md +105 -0
  479. package/skills/agent-readiness/ai_friendly_analyzers.py +326 -0
  480. package/skills/agent-readiness/scanner.py +441 -0
  481. package/skills/agent-readiness/scorecard.yaml +88 -0
  482. package/skills/api-design/SKILL.md +115 -0
  483. package/skills/apply-fixes/SKILL.md +171 -0
  484. package/skills/apply-test-doubles/SKILL.md +321 -0
  485. package/skills/artifact-lifecycle/SKILL.md +127 -0
  486. package/skills/autoship/SKILL.md +1124 -0
  487. package/skills/benchmark/SKILL.md +105 -0
  488. package/skills/branch-workflow/SKILL.md +89 -0
  489. package/skills/browse/SKILL.md +184 -0
  490. package/skills/browser-testing/SKILL.md +62 -0
  491. package/skills/browser-testing/references/playwright-patterns.md +216 -0
  492. package/skills/build/SKILL.md +422 -0
  493. package/skills/build/references/static-self-heal.md +245 -0
  494. package/skills/careful/SKILL.md +72 -0
  495. package/skills/cd-test-architecture/SKILL.md +371 -0
  496. package/skills/ci-debugging/SKILL.md +105 -0
  497. package/skills/co-evolution-audit/SKILL.md +269 -0
  498. package/skills/code-review/SKILL.md +1015 -0
  499. package/skills/code-review/examples/aggregated-sample.json +56 -0
  500. package/skills/code-review/examples/sample-report.md +41 -0
  501. package/skills/code-review/output-format.md +478 -0
  502. package/skills/code-review/scripts/activation.py +86 -0
  503. package/skills/code-review/scripts/change_impact.py +357 -0
  504. package/skills/code-review/scripts/change_shape.py +372 -0
  505. package/skills/code-review/scripts/change_size.py +212 -0
  506. package/skills/code-review/scripts/changed_file_list.py +141 -0
  507. package/skills/code-review/scripts/closing_pass.py +187 -0
  508. package/skills/code-review/scripts/consolidate.py +277 -0
  509. package/skills/code-review/scripts/contract_failure_report.py +185 -0
  510. package/skills/code-review/scripts/dispatch_reconcile.py +66 -0
  511. package/skills/code-review/scripts/dispatch_waves.py +164 -0
  512. package/skills/code-review/scripts/finding_signature.py +446 -0
  513. package/skills/code-review/scripts/ledger.py +283 -0
  514. package/skills/code-review/scripts/partition.py +169 -0
  515. package/skills/code-review/scripts/render_tiered_findings.py +274 -0
  516. package/skills/code-review/scripts/repo_invariants.py +1066 -0
  517. package/skills/code-review/scripts/review_context_pack.py +306 -0
  518. package/skills/code-review/scripts/review_round_log.py +345 -0
  519. package/skills/code-review/scripts/review_value_coverage.py +297 -0
  520. package/skills/code-review/scripts/validate_review_output.py +467 -0
  521. package/skills/code-review/sliced-mode.md +205 -0
  522. package/skills/competitive-analysis/SKILL.md +191 -0
  523. package/skills/context-loading-protocol/SKILL.md +157 -0
  524. package/skills/continue/SKILL.md +90 -0
  525. package/skills/cost-report/SKILL.md +178 -0
  526. package/skills/coverage-baseline/SKILL.md +335 -0
  527. package/skills/coverage-baseline/references/multi-project-discovery.md +202 -0
  528. package/skills/coverage-delta/SKILL.md +181 -0
  529. package/skills/coverage-delta/references/mutation-gate.md +70 -0
  530. package/skills/design-doc/SKILL.md +95 -0
  531. package/skills/design-interrogation/SKILL.md +89 -0
  532. package/skills/design-it-twice/SKILL.md +91 -0
  533. package/skills/docker-image-audit/SKILL.md +108 -0
  534. package/skills/docker-image-audit/references/install-guide.md +64 -0
  535. package/skills/docker-image-audit/references/report-template.md +73 -0
  536. package/skills/docker-image-create/SKILL.md +185 -0
  537. package/skills/domain-analysis/SKILL.md +183 -0
  538. package/skills/domain-driven-design/SKILL.md +194 -0
  539. package/skills/exploratory-testing/SKILL.md +108 -0
  540. package/skills/explore/SKILL.md +51 -0
  541. package/skills/farley-score/SKILL.md +165 -0
  542. package/skills/feature-file-validation/SKILL.md +78 -0
  543. package/skills/feature-file-validation/references/validation-rules.md +115 -0
  544. package/skills/feedback-learning/SKILL.md +414 -0
  545. package/skills/fix/SKILL.md +450 -0
  546. package/skills/freeze/SKILL.md +68 -0
  547. package/skills/frontend-architecture/SKILL.md +113 -0
  548. package/skills/gherkin-derive/SKILL.md +630 -0
  549. package/skills/gherkin-public/SKILL.md +266 -0
  550. package/skills/governance-compliance/SKILL.md +150 -0
  551. package/skills/guard/SKILL.md +75 -0
  552. package/skills/handoff/SKILL.md +139 -0
  553. package/skills/handoff/references/summary-templates.md +242 -0
  554. package/skills/harness-audit/SKILL.md +751 -0
  555. package/skills/harness-audit/scripts/lesson_validate.py +386 -0
  556. package/skills/harness-audit/scripts/redundancy_criterion.py +188 -0
  557. package/skills/headless-run/SKILL.md +45 -0
  558. package/skills/headless-run/scripts/isolated_dispatch.py +381 -0
  559. package/skills/help/SKILL.md +72 -0
  560. package/skills/hexagonal-architecture/SKILL.md +85 -0
  561. package/skills/human-oversight-protocol/SKILL.md +224 -0
  562. package/skills/issues-from-assessment/SKILL.md +223 -0
  563. package/skills/issues-from-plan/SKILL.md +133 -0
  564. package/skills/legacy-code/SKILL.md +132 -0
  565. package/skills/mermaid-diagramming/SKILL.md +120 -0
  566. package/skills/mutation-night-watch/SKILL.md +154 -0
  567. package/skills/mutation-night-watch/references/scheduling.md +135 -0
  568. package/skills/mutation-testing/SKILL.md +396 -0
  569. package/skills/mutation-testing/references/languages/csharp-stryker-net.md +676 -0
  570. package/skills/mutation-testing/references/languages/go-go-mutesting.md +95 -0
  571. package/skills/mutation-testing/references/languages/java-pitest.md +77 -0
  572. package/skills/mutation-testing/references/languages/javascript-stryker.md +188 -0
  573. package/skills/mutation-testing/references/languages/python-mutmut.md +97 -0
  574. package/skills/mutation-testing/references/time-estimation.md +34 -0
  575. package/skills/mutation-testing/references/tool-detection.md +15 -0
  576. package/skills/mutation-testing/references/workflow-callers.md +23 -0
  577. package/skills/mutation-testing/scripts/__pycache__/xunit_v3_feature_detector.cpython-314.pyc +0 -0
  578. package/skills/mutation-testing/scripts/csharp_stryker_net_slice_runner.py +635 -0
  579. package/skills/mutation-testing/scripts/csharp_stryker_net_status_loop.py +525 -0
  580. package/skills/mutation-testing/scripts/csharp_stryker_net_wrapper.py +681 -0
  581. package/skills/mutation-testing/scripts/mutation_baseline_reuse.py +292 -0
  582. package/skills/mutation-testing/scripts/mutation_exclude_policy.py +268 -0
  583. package/skills/mutation-testing/scripts/mutation_feasibility_gate.py +463 -0
  584. package/skills/mutation-testing/scripts/mutation_kill_headless.py +331 -0
  585. package/skills/mutation-testing/scripts/mutation_kill_insert.py +199 -0
  586. package/skills/mutation-testing/scripts/mutation_kill_insert_python.py +150 -0
  587. package/skills/mutation-testing/scripts/mutation_kill_loop.py +869 -0
  588. package/skills/mutation-testing/scripts/mutation_kill_loop_python.py +949 -0
  589. package/skills/mutation-testing/scripts/mutation_kill_retry.py +592 -0
  590. package/skills/mutation-testing/scripts/mutation_kill_shared.py +620 -0
  591. package/skills/mutation-testing/scripts/mutation_nightwatch.py +462 -0
  592. package/skills/mutation-testing/scripts/mutation_nightwatch_stacks.py +425 -0
  593. package/skills/mutation-testing/scripts/mutation_report.py +743 -0
  594. package/skills/mutation-testing/scripts/mutation_report_cli.py +175 -0
  595. package/skills/mutation-testing/scripts/mutation_safety_gate.py +69 -0
  596. package/skills/mutation-testing/scripts/stryker_shard_pipeline.py +847 -0
  597. package/skills/mutation-testing/scripts/stryker_shard_setup.py +440 -0
  598. package/skills/mutation-testing/scripts/stryker_timeout_retry.py +142 -0
  599. package/skills/mutation-testing/scripts/xunit_v3_feature_detector.py +341 -0
  600. package/skills/performance-benchmark/SKILL.md +174 -0
  601. package/skills/performance-benchmark/examples/report-format.md +43 -0
  602. package/skills/performance-benchmark/references/benchmark-script.md +169 -0
  603. package/skills/performance-metrics/SKILL.md +265 -0
  604. package/skills/plan/SKILL.md +199 -0
  605. package/skills/plan/references/gherkin-persistence.md +43 -0
  606. package/skills/plan/references/plan-template.md +182 -0
  607. package/skills/pr/SKILL.md +289 -0
  608. package/skills/pr/scripts/gate_retry_state.py +368 -0
  609. package/skills/project-init/README.md +141 -0
  610. package/skills/project-init/SKILL.md +1197 -0
  611. package/skills/project-init/evals/evals.json +200 -0
  612. package/skills/project-init/references/capability-tools.md +55 -0
  613. package/skills/project-init/references/configs.md +221 -0
  614. package/skills/property-based-testing/SKILL.md +121 -0
  615. package/skills/property-based-testing/fixtures/invariant_fixture.py +15 -0
  616. package/skills/property-based-testing/fixtures/js-roundtrip/README.md +42 -0
  617. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/LICENSE +21 -0
  618. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/README.md +263 -0
  619. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/lib/cjs/fast-check.d.ts +5165 -0
  620. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/lib/cjs/fast-check.js +12147 -0
  621. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/lib/cjs/package.json +3 -0
  622. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/lib/cjs/types57/fast-check.d.ts +5165 -0
  623. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/lib/fast-check.d.ts +5165 -0
  624. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/lib/fast-check.js +12011 -0
  625. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/lib/rolldown-runtime-D7D4PA-g.js +13 -0
  626. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/lib/types57/fast-check.d.ts +5165 -0
  627. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/package.json +94 -0
  628. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/LICENSE +21 -0
  629. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/README.md +168 -0
  630. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/RandomGenerator-DcXj09Ch.d.ts +14 -0
  631. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/distribution/uniformBigInt.d.ts +15 -0
  632. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/distribution/uniformBigInt.js +38 -0
  633. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/distribution/uniformFloat32.d.ts +15 -0
  634. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/distribution/uniformFloat32.js +18 -0
  635. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/distribution/uniformFloat64.d.ts +15 -0
  636. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/distribution/uniformFloat64.js +22 -0
  637. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/distribution/uniformInt.d.ts +15 -0
  638. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/distribution/uniformInt.js +134 -0
  639. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/RandomGenerator-DcXj09Ch.d.ts +14 -0
  640. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/distribution/uniformBigInt.d.ts +15 -0
  641. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/distribution/uniformBigInt.js +37 -0
  642. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/distribution/uniformFloat32.d.ts +15 -0
  643. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/distribution/uniformFloat32.js +17 -0
  644. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/distribution/uniformFloat64.d.ts +15 -0
  645. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/distribution/uniformFloat64.js +21 -0
  646. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/distribution/uniformInt.d.ts +15 -0
  647. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/distribution/uniformInt.js +133 -0
  648. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/generator/congruential32.d.ts +7 -0
  649. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/generator/congruential32.js +44 -0
  650. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/generator/mersenne.d.ts +7 -0
  651. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/generator/mersenne.js +90 -0
  652. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/generator/xoroshiro128plus.d.ts +7 -0
  653. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/generator/xoroshiro128plus.js +80 -0
  654. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/generator/xorshift128plus.d.ts +7 -0
  655. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/generator/xorshift128plus.js +78 -0
  656. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/package.json +3 -0
  657. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/types/JumpableRandomGenerator.d.ts +16 -0
  658. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/types/JumpableRandomGenerator.js +0 -0
  659. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/types/RandomGenerator.d.ts +2 -0
  660. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/types/RandomGenerator.js +0 -0
  661. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/utils/generateN.d.ts +6 -0
  662. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/utils/generateN.js +8 -0
  663. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/utils/purify.d.ts +12 -0
  664. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/utils/purify.js +9 -0
  665. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/utils/skipN.d.ts +6 -0
  666. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/utils/skipN.js +6 -0
  667. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/generator/congruential32.d.ts +7 -0
  668. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/generator/congruential32.js +46 -0
  669. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/generator/mersenne.d.ts +7 -0
  670. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/generator/mersenne.js +92 -0
  671. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/generator/xoroshiro128plus.d.ts +7 -0
  672. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/generator/xoroshiro128plus.js +82 -0
  673. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/generator/xorshift128plus.d.ts +7 -0
  674. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/generator/xorshift128plus.js +80 -0
  675. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/types/JumpableRandomGenerator.d.ts +16 -0
  676. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/types/JumpableRandomGenerator.js +0 -0
  677. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/types/RandomGenerator.d.ts +2 -0
  678. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/types/RandomGenerator.js +0 -0
  679. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/utils/generateN.d.ts +6 -0
  680. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/utils/generateN.js +9 -0
  681. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/utils/purify.d.ts +12 -0
  682. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/utils/purify.js +10 -0
  683. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/utils/skipN.d.ts +6 -0
  684. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/utils/skipN.js +7 -0
  685. package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/package.json +133 -0
  686. package/skills/property-based-testing/fixtures/js-roundtrip/package-lock.json +1179 -0
  687. package/skills/property-based-testing/fixtures/js-roundtrip/package.json +14 -0
  688. package/skills/property-based-testing/fixtures/js-roundtrip/roundtrip.js +29 -0
  689. package/skills/property-based-testing/fixtures/js-roundtrip/roundtrip.properties.test.js +16 -0
  690. package/skills/property-based-testing/fixtures/no_property_fixture.py +10 -0
  691. package/skills/property-based-testing/fixtures/roundtrip_fixture.py +16 -0
  692. package/skills/property-based-testing/references/languages/javascript.md +54 -0
  693. package/skills/property-based-testing/scripts/detect_and_dispatch.py +80 -0
  694. package/skills/property-based-testing/scripts/hypothesis_scaffold.py +276 -0
  695. package/skills/proxy-resilience/SKILL.md +84 -0
  696. package/skills/quality-gate-pipeline/SKILL.md +184 -0
  697. package/skills/quality-targets-converge/SKILL.md +254 -0
  698. package/skills/repo-review/SKILL.md +159 -0
  699. package/skills/report-pdf/SKILL.md +66 -0
  700. package/skills/review/SKILL.md +47 -0
  701. package/skills/review-agent/SKILL.md +152 -0
  702. package/skills/review-summary/SKILL.md +73 -0
  703. package/skills/run-report/SKILL.md +70 -0
  704. package/skills/semantic-duplication-scan/SKILL.md +337 -0
  705. package/skills/semantic-scan/SKILL.md +53 -0
  706. package/skills/semgrep-analyze/SKILL.md +139 -0
  707. package/skills/setup/SKILL.md +1122 -0
  708. package/skills/ship/SKILL.md +240 -0
  709. package/skills/source-verification/SKILL.md +210 -0
  710. package/skills/source-verification/scripts/claim_extractor.py +155 -0
  711. package/skills/specs/.size-baseline.json +4 -0
  712. package/skills/specs/SKILL.md +243 -0
  713. package/skills/specs/references/completeness-checklist.md +83 -0
  714. package/skills/specs/references/extraction.md +58 -0
  715. package/skills/specs/references/glossary.md +59 -0
  716. package/skills/specs/references/persistence.md +115 -0
  717. package/skills/specs/references/predictability-check.md +77 -0
  718. package/skills/static-analysis-integration/SKILL.md +235 -0
  719. package/skills/static-analysis-integration/adapters/_envelope.py +26 -0
  720. package/skills/static-analysis-integration/adapters/jscpd-adapter.py +66 -0
  721. package/skills/static-analysis-integration/adapters/lizard-adapter.py +81 -0
  722. package/skills/static-analysis-integration/adapters/mypy-adapter.py +50 -0
  723. package/skills/static-analysis-integration/adapters/mypy-src-layout.py +93 -0
  724. package/skills/static-analysis-integration/adapters/security-review-adapter.py +212 -0
  725. package/skills/static-analysis-integration/maintenance.md +23 -0
  726. package/skills/static-analysis-integration/references/language-setup.md +228 -0
  727. package/skills/static-analysis-integration/references/sarif-parser.md +124 -0
  728. package/skills/static-analysis-integration/references/security-review-adapter.md +118 -0
  729. package/skills/static-analysis-integration/references/tool-configs.md +617 -0
  730. package/skills/static-analysis-integration/rulesets/pmd-quickstart.xml +24 -0
  731. package/skills/stryker-xunit-v2-shim/SKILL.md +274 -0
  732. package/skills/stryker-xunit-v2-shim/references/shim-howto.md +256 -0
  733. package/skills/stryker-xunit-v2-shim/scripts/generate_shim.py +143 -0
  734. package/skills/systematic-debugging/SKILL.md +130 -0
  735. package/skills/telemetry/SKILL.md +75 -0
  736. package/skills/test-audit-disable/SKILL.md +129 -0
  737. package/skills/test-design/SKILL.md +177 -0
  738. package/skills/test-design/scripts/__pycache__/internal_double_detector.cpython-314.pyc +0 -0
  739. package/skills/test-design/scripts/internal_double_detector.py +631 -0
  740. package/skills/test-design-advisor/SKILL.md +166 -0
  741. package/skills/test-driven-development/SKILL.md +169 -0
  742. package/skills/test-health/SKILL.md +262 -0
  743. package/skills/test-improve/SKILL.md +239 -0
  744. package/skills/test-improve/references/phase-0-approach-contract.md +228 -0
  745. package/skills/test-improve/references/phase-1-analyze.md +131 -0
  746. package/skills/test-improve/references/phase-2-baseline.md +121 -0
  747. package/skills/test-improve/references/phase-3-derive-gherkin.md +53 -0
  748. package/skills/test-improve/references/phase-4-plan-fixes.md +34 -0
  749. package/skills/test-improve/references/phase-5-improve.md +215 -0
  750. package/skills/test-improve/references/phase-6-refactor-decision.md +45 -0
  751. package/skills/test-improve/references/phase-7-refactor.md +44 -0
  752. package/skills/test-improve/references/phase-8-validate.md +66 -0
  753. package/skills/test-improve/references/phase-9-close-out-prompt.md +11 -0
  754. package/skills/test-improve/references/phase-9-report.md +62 -0
  755. package/skills/test-improve/references/review-loop.md +92 -0
  756. package/skills/test-improve/templates/executive-summary.md +123 -0
  757. package/skills/threat-modeling/SKILL.md +108 -0
  758. package/skills/triage/SKILL.md +211 -0
  759. package/skills/ubiquitous-language/SKILL.md +192 -0
  760. package/skills/ubiquitous-language/scripts/collect_domain_signals.py +300 -0
  761. package/skills/unfreeze/SKILL.md +37 -0
  762. package/skills/upgrade/SKILL.md +31 -0
  763. package/skills/upgrade/scripts/check_version_drift.py +113 -0
  764. package/skills/upgrade/scripts/enable_autoupdate.py +149 -0
  765. package/skills/version/SKILL.md +25 -0
  766. package/sync/__pycache__/sync_upstream.cpython-314.pyc +0 -0
  767. package/sync/sync_upstream.py +293 -0
  768. package/templates/ACCEPTED-RISKS.md.tmpl +46 -0
  769. package/templates/agents/agent-template.md +151 -0
  770. package/templates/agents/angular-testing.md +66 -0
  771. package/templates/agents/csharp-quality.md +63 -0
  772. package/templates/agents/esm-enforcer.md +52 -0
  773. package/templates/agents/front-end-testing.md +65 -0
  774. package/templates/agents/go-quality.md +65 -0
  775. package/templates/agents/python-quality.md +62 -0
  776. package/templates/agents/react-testing.md +61 -0
  777. package/templates/agents/ts-enforcer.md +60 -0
  778. package/templates/agents/twelve-factor-audit.md +49 -0
  779. package/tools/entropy-check.py +250 -0
  780. package/tools/model-hash-verify.py +213 -0
@@ -0,0 +1,372 @@
1
+ #!/usr/bin/env python3
2
+ """Classify a changeset's shape to gate low-yield review lenses (#1254).
3
+
4
+ Running the full review panel unconditionally wastes tokens on diffs with no
5
+ runtime/logic surface. The 2026-07-20 audit found `performance-review` fired
6
+ 0/10 and `correctness-review` 1/10 — on doc/config-dominated commits most lenses
7
+ no-op. `/code-review` (invoked directly) applies no complexity gate the way
8
+ `/build` and `/plan` do, so every lens runs on every changed file regardless of
9
+ change shape.
10
+
11
+ This module is the deterministic gate. Given the changed-file list it decides
12
+ whether the changeset has any **runtime surface** — a file that could hold
13
+ executable logic. When it does not (every file is documentation or config),
14
+ the two low-yield code lenses (`performance-review`, `correctness-review`) are
15
+ skipped; the rest of the panel still runs.
16
+
17
+ **Fail-safe by construction.** A file is "no runtime surface" only when it is
18
+ *provably* documentation or config (matches an explicit allowlist). Anything
19
+ else — an unknown extension, a source file, functional Claude-config markdown —
20
+ counts as runtime surface, so the lenses run. A misclassification can only ever
21
+ *add* a lens, never silently drop one on real code.
22
+
23
+ Pure policy — no filesystem, no globals. Mirrors the documentation-only
24
+ short-circuit's classification in `code-review/SKILL.md` (this gate is the
25
+ weaker sibling: the short-circuit skips *everything* when every file is
26
+ documentation; this skips only the two low-yield lenses when every file is
27
+ documentation *or* config, which the doc-only short-circuit does not cover).
28
+
29
+ Test-only classification (#1964)
30
+ --------------------------------
31
+ This module answers a second, independent question: is *every* changed file
32
+ provably a test file (per `knowledge/test-file-indicators.md`)? A diff of that
33
+ shape is structurally incapable of exhibiting what several expensive lenses
34
+ look for — and under `/test-improve`'s default `refactor-mode: no-refactor`,
35
+ Phase 5's diff is *guaranteed* to have it, because `/build` rejects
36
+ production-code changes in that mode.
37
+
38
+ `testOnly` is reported but currently skips **nothing**: `TEST_ONLY_SKIP_LENSES`
39
+ ships empty on purpose. Which lens is safe to drop on a test-only diff is an
40
+ empirical question, and the evidence (per-lens outcomes split by `diff_shape`
41
+ in `review-value.jsonl`) is still being collected. This mirrors the
42
+ architectural-impact gate's own rule — "widen `GATED_LENSES` from #1624's
43
+ measured per-agent data, not from intuition about which lens probably no-ops."
44
+ Two lenses in particular must NOT be added without data: `security-review`
45
+ (tests embed credentials and injection payloads) and `correctness-review`
46
+ (an inverted assertion is precisely its subject).
47
+
48
+ Test-only classification is **include-biased in the same direction** as the
49
+ runtime-surface check: a changeset is test-only only when every file is
50
+ *provably* a test. Anything unproven — a fixture, a `conftest.py`, a helper, a
51
+ `.cs` file whose test-ness needs its contents — makes the answer `False`, so
52
+ the full panel runs. Because this module is filesystem-free by contract, the
53
+ content-probing branches of the shared classifier are deliberately starved
54
+ (`content=""`), which can only ever move the answer toward "not test-only".
55
+
56
+ Scope note: this is a filename-shape gate. Annotation-only edits *inside* a
57
+ source file (e.g. adding a C# attribute) still count as runtime surface — that
58
+ would require diff parsing and is deliberately out of scope for v1.
59
+
60
+ Shared literal tables (#1477): the documentation-extension, doc-root-word,
61
+ and functional-config-name/segment literals below are byte-identical to
62
+ `hooks/pre_commit_review.py`'s own doc-only classifier and were previously
63
+ hand-duplicated between the two, kept in sync only by comment convention.
64
+ They now live in `hooks/lib/doc_classification.py`, imported here via the
65
+ same `sys.path.insert` cross-boundary pattern `pre_commit_review.py` already
66
+ uses for its own `hooks/lib/` imports — see that module's docstring for why
67
+ this location was chosen and why the *matching logic* (prefix vs. exact
68
+ match) intentionally stays local to each caller rather than being unified
69
+ too.
70
+ """
71
+
72
+ from __future__ import annotations
73
+
74
+ import argparse
75
+ import json
76
+ import sys
77
+ from collections.abc import Iterable
78
+ from pathlib import Path, PurePosixPath
79
+
80
+ # skills/code-review/scripts -> skills/code-review -> skills -> plugin root
81
+ # -> hooks/lib
82
+ _HOOKS_LIB_DIR = Path(__file__).resolve().parents[3] / "hooks" / "lib"
83
+ if str(_HOOKS_LIB_DIR) not in sys.path:
84
+ sys.path.insert(0, str(_HOOKS_LIB_DIR))
85
+
86
+ # Both shared modules are imported, never re-implemented. There is deliberately
87
+ # no `except ImportError` fallback (#1968): a hand-written stand-in for a shared
88
+ # classifier is a second copy of the logic that can drift from its source
89
+ # silently, and one already did — the `is_test_file` fallback added in #1964
90
+ # shipped folding all four indicator families into one `re.IGNORECASE` pattern
91
+ # while `test_file_classify` compiles its step-definition regex
92
+ # case-sensitively, so `backsteps.py` read as a step definition and an ordinary
93
+ # source file could pass as a test. The whole suite stayed green, because every
94
+ # other test exercised the import path that succeeds.
95
+ #
96
+ # `hooks/lib/` ships inside this same plugin, so an unreachable one is a broken
97
+ # install or a moved file, not a supported degraded mode. Failing here — loudly,
98
+ # naming the path that was searched — surfaces that immediately instead of
99
+ # silently answering classification questions from a divergent copy.
100
+ def _require_shared(module: str) -> ImportError:
101
+ """Build the diagnostic for a shared-module import that could not resolve.
102
+
103
+ The parent-count in `_HOOKS_LIB_DIR` is the fragile part (a moved file
104
+ changes it), so the message names the resolved path rather than leaving a
105
+ bare `No module named ...` to be reverse-engineered.
106
+ """
107
+ return ImportError(
108
+ f"{__name__} requires the shared classifier {module!r} from the "
109
+ f"dev-team plugin's hooks/lib, which could not be imported.\n"
110
+ f" searched: {_HOOKS_LIB_DIR}\n"
111
+ f" exists: {_HOOKS_LIB_DIR.is_dir()}\n"
112
+ "This module deliberately has no fallback copy of the classifier "
113
+ "(#1968) — a divergent stand-in silently mis-classifies files. Fix the "
114
+ "install or the path rather than re-adding a local implementation."
115
+ )
116
+
117
+
118
+ try:
119
+ from doc_classification import ( # type: ignore[import-not-found]
120
+ DOC_EXTENSIONS,
121
+ DOC_ROOT_WORDS,
122
+ is_functional_config,
123
+ )
124
+ except ImportError as exc: # pragma: no cover - broken install, not a supported mode
125
+ raise _require_shared("doc_classification") from exc
126
+
127
+ # `knowledge/test-file-indicators.md`'s single encoding, shared with the
128
+ # refactor test-freeze guards (#1964).
129
+ try:
130
+ from test_file_classify import is_test_file # type: ignore[import-not-found]
131
+ except ImportError as exc: # pragma: no cover - broken install, not a supported mode
132
+ raise _require_shared("test_file_classify") from exc
133
+
134
+
135
+ LOW_YIELD_LENSES = ["performance-review", "correctness-review"]
136
+
137
+ # Lenses to skip when EVERY changed file is provably prose (`.md`/`.mdx`),
138
+ # including functional Claude-config markdown (#2104). `has_runtime_surface`
139
+ # correctly treats agents/skills/knowledge/.claude markdown as runtime
140
+ # surface — it drives agent behavior, so `performance-review` and
141
+ # `correctness-review` still run against it above. But a handful of lenses
142
+ # review a *code-level* property no markdown file, functional or not, can
143
+ # exhibit: an injection/auth/data-exposure vulnerability, a domain-boundary
144
+ # leak, a test-coverage gap, or a resource leak/N+1 query. Dispatching a
145
+ # 9-agent panel (including these four) against a single-file skill-markdown
146
+ # diff produced elaborate findings framed as security/domain/test/performance
147
+ # issues that were really prose/spec-consistency nitpicks belonging to
148
+ # doc-review/spec-compliance-review/correctness-review instead. Each of these
149
+ # four agents' own `## Skip` clause already self-reports skip on a
150
+ # documentation-only target (security-review: "static assets, images, or
151
+ # documentation"; domain-review: "no business logic or domain entities
152
+ # present"; test-review: "no test files in target"; performance-review:
153
+ # "configuration, documentation, or type definitions") — dispatching them
154
+ # anyway just pays for a self-reported skip, or worse, an ungrounded finding
155
+ # stretched to fit the lens.
156
+ #
157
+ # Deliberately NARROWER than `select_lenses.py`'s own
158
+ # `NON_EXECUTABLE_SKIP_ELIGIBLE` allowlist, which considered and REJECTED
159
+ # adding security-review/domain-review/arch-review for its broader
160
+ # "non-executable" category (docs **and** config/lockfiles/assets): that
161
+ # module's own comment documents why — security-review's Skip clause does not
162
+ # cover config/lockfiles (its Scope mandates scanning them for hardcoded
163
+ # credentials) and domain-review's is a content judgment a config file's type
164
+ # alone can't answer. This module's prose-only signal is strictly `.md`/
165
+ # `.mdx` — it never widens to config, so neither rejection applies here.
166
+ # `arch-review` and `correctness-review` are deliberately absent from this
167
+ # list for the same reason `select_lenses.py` keeps `arch-review` unfiltered:
168
+ # a pure-markdown ADR update, or a functional-config skill/agent file, is
169
+ # exactly the content their own `## Detect` sections exist to review.
170
+ PROSE_ONLY_SKIP_LENSES = [
171
+ "security-review", "domain-review", "test-review", "performance-review",
172
+ ]
173
+
174
+ # Extensions provably incapable of holding anything but prose (lower-cased).
175
+ _PROSE_EXTENSIONS = {".md", ".mdx"}
176
+
177
+ # Lenses to skip when EVERY changed file is provably a test file (#1964).
178
+ # Deliberately EMPTY until per-lens `diff_shape` outcome data justifies each
179
+ # entry — see this module's docstring. Adding a name here without citing that
180
+ # measurement is the mistake the docstring names; `security-review` and
181
+ # `correctness-review` are explicitly not candidates on intuition.
182
+ TEST_ONLY_SKIP_LENSES: list[str] = []
183
+
184
+ # Documentation extensions (lower-cased). Mirrors SKILL.md's doc-only rule.
185
+ _DOC_EXTENSIONS = DOC_EXTENSIONS
186
+
187
+ # Documentation root-file stems (matched case-insensitively on the stem
188
+ # prefix) — same word list `pre_commit_review.py`'s doc-only classifier uses
189
+ # for its own (exact-match) root-doc check.
190
+ _DOC_ROOT_PREFIXES = DOC_ROOT_WORDS
191
+
192
+ # Config / data extensions with no executable logic surface (lower-cased).
193
+ # Unique to this gate — `pre_commit_review.py` has no equivalent "config"
194
+ # concept, so this stays local (nothing to extract against).
195
+ _CONFIG_EXTENSIONS = {
196
+ ".json", ".yaml", ".yml", ".toml", ".ini", ".cfg", ".conf",
197
+ ".properties", ".lock", ".csv", ".tsv",
198
+ }
199
+
200
+ # Config dotfiles carry no suffix (``PurePosixPath(".gitignore").suffix == ""``),
201
+ # so they are matched by full name instead (lower-cased).
202
+ _CONFIG_NAMES = {
203
+ ".gitignore", ".gitattributes", ".editorconfig", ".env", ".dockerignore",
204
+ ".npmignore", ".prettierignore",
205
+ }
206
+
207
+ # Functional-config classification (markdown/paths that drive agent/skill/
208
+ # command behavior and always count as runtime surface, same exclusion as
209
+ # SKILL.md) now lives in `is_functional_config` above — shared with
210
+ # `select_lenses.py` (#1923), including the "templates" addition this gate
211
+ # has always applied on top of the shared core set (`pre_commit_review.py`'s
212
+ # doc-only classifier deliberately does not include it; see that module's
213
+ # docstring on staying a strict subset — unaffected by this extraction).
214
+
215
+
216
+ def _is_documentation(path: PurePosixPath) -> bool:
217
+ if path.suffix.lower() in _DOC_EXTENSIONS:
218
+ return True
219
+ if "docs" in path.parts:
220
+ return True
221
+ stem = path.name.lower()
222
+ return any(stem.startswith(prefix) for prefix in _DOC_ROOT_PREFIXES)
223
+
224
+
225
+ def _is_config(path: PurePosixPath) -> bool:
226
+ return (
227
+ path.suffix.lower() in _CONFIG_EXTENSIONS
228
+ or path.name.lower() in _CONFIG_NAMES
229
+ )
230
+
231
+
232
+ def _has_runtime_surface_file(file: str) -> bool:
233
+ """True when a single file could hold executable logic (fail-safe default)."""
234
+ path = PurePosixPath(str(file).strip())
235
+ if not path.name:
236
+ return False # empty entry contributes nothing
237
+ if is_functional_config(path):
238
+ return True
239
+ # Provably non-runtime only when documentation or config; anything else
240
+ # (source, unknown extension) is treated as runtime surface.
241
+ return not (_is_documentation(path) or _is_config(path))
242
+
243
+
244
+ def has_runtime_surface(files: Iterable[str]) -> bool:
245
+ """True when *any* changed file could hold executable logic.
246
+
247
+ An empty changeset has no runtime surface (returns False).
248
+ """
249
+ return any(_has_runtime_surface_file(f) for f in files if str(f).strip())
250
+
251
+
252
+ def _is_provably_test_file(file: str) -> bool:
253
+ """True when a single file is provably a test (fail-safe default: False).
254
+
255
+ `content=""` starves the shared classifier's content-probing branches (C#
256
+ attributes, Java annotations) rather than touching the filesystem, keeping
257
+ this module's no-I/O contract. That can only ever answer "not a test",
258
+ which biases the changeset toward "not test-only" — i.e. toward running
259
+ every lens. Java's class-name convention (`FooTest.java`) still resolves
260
+ by name and is unaffected.
261
+ """
262
+ name = str(file).strip()
263
+ if not name:
264
+ return False
265
+ return bool(is_test_file(name, content=""))
266
+
267
+
268
+ def is_test_only(files: Iterable[str]) -> bool:
269
+ """True when *every* changed file is provably a test file.
270
+
271
+ An empty changeset is not test-only (there is nothing to prove), matching
272
+ `has_runtime_surface`'s treatment of the empty case.
273
+ """
274
+ file_list = [f for f in files if str(f).strip()]
275
+ if not file_list:
276
+ return False
277
+ return all(_is_provably_test_file(f) for f in file_list)
278
+
279
+
280
+ def _is_prose_file(file: str) -> bool:
281
+ return PurePosixPath(str(file).strip()).suffix.lower() in _PROSE_EXTENSIONS
282
+
283
+
284
+ def is_prose_only(files: Iterable[str]) -> bool:
285
+ """True when *every* changed file is `.md`/`.mdx` prose (#2104).
286
+
287
+ Unlike `has_runtime_surface`, this makes no exception for functional
288
+ Claude-config markdown: a `.md` file cannot exhibit an injection
289
+ vulnerability, a domain-boundary leak, a test-coverage gap, or an N+1
290
+ query regardless of whether it also drives agent behavior. An empty
291
+ changeset is not prose-only, matching the other predicates' empty-case
292
+ convention.
293
+ """
294
+ file_list = [f for f in files if str(f).strip()]
295
+ if not file_list:
296
+ return False
297
+ return all(_is_prose_file(f) for f in file_list)
298
+
299
+
300
+ def lenses_to_skip(files: Iterable[str]) -> list[str]:
301
+ """Return the low-yield lenses to skip for this changeset.
302
+
303
+ Empty when the changeset has any runtime surface and is not prose-only.
304
+ A doc/config-only changeset (no runtime surface) skips `performance-review`
305
+ and `correctness-review`; a prose-only changeset (every file `.md`/`.mdx`,
306
+ including functional Claude-config markdown) additionally skips
307
+ `security-review`, `domain-review`, and `test-review` (#2104) — the two
308
+ sets are independent and union together, since a prose-only diff is
309
+ always also a no-runtime-surface diff unless it is functional config.
310
+ """
311
+ file_list = [f for f in files if str(f).strip()]
312
+ if not file_list:
313
+ return [] # nothing to review — the caller handles empty scope
314
+
315
+ # Ordered, deduplicated union — preserves each source list's own order and
316
+ # never lists a lens twice (e.g. `performance-review` is in both
317
+ # LOW_YIELD_LENSES and PROSE_ONLY_SKIP_LENSES for a plain-docs-only diff).
318
+ skip: list[str] = []
319
+ seen: set[str] = set()
320
+
321
+ def _extend(names: Iterable[str]) -> None:
322
+ for name in names:
323
+ if name not in seen:
324
+ seen.add(name)
325
+ skip.append(name)
326
+
327
+ if not has_runtime_surface(file_list):
328
+ _extend(LOW_YIELD_LENSES)
329
+ # Runtime surface present. A test-only changeset may still narrow the
330
+ # roster once TEST_ONLY_SKIP_LENSES is populated from measured data; it is
331
+ # empty today, so this contributes nothing (#1964).
332
+ elif is_test_only(file_list):
333
+ _extend(TEST_ONLY_SKIP_LENSES)
334
+ if is_prose_only(file_list):
335
+ _extend(PROSE_ONLY_SKIP_LENSES)
336
+ return skip
337
+
338
+
339
+ def main(argv=None) -> int:
340
+ parser = argparse.ArgumentParser(description=__doc__)
341
+ parser.add_argument(
342
+ "--files", nargs="*", default=[],
343
+ help="changed file paths (space-separated)",
344
+ )
345
+ parser.add_argument(
346
+ "--files-from", default=None,
347
+ help="read newline-separated file paths from this file ('-' for stdin)",
348
+ )
349
+ args = parser.parse_args(argv)
350
+
351
+ files = list(args.files)
352
+ if args.files_from:
353
+ if args.files_from == "-":
354
+ text = sys.stdin.read()
355
+ else:
356
+ with open(args.files_from) as f:
357
+ text = f.read()
358
+ files.extend(line for line in text.splitlines() if line.strip())
359
+
360
+ skip = lenses_to_skip(files)
361
+ result = {
362
+ "hasRuntimeSurface": has_runtime_surface(files),
363
+ "isTestOnly": is_test_only(files),
364
+ "isProseOnly": is_prose_only(files),
365
+ "skipLenses": skip,
366
+ }
367
+ print(json.dumps(result, sort_keys=True))
368
+ return 0
369
+
370
+
371
+ if __name__ == "__main__":
372
+ raise SystemExit(main(sys.argv[1:]))
@@ -0,0 +1,212 @@
1
+ #!/usr/bin/env python3
2
+ """Classify a changeset's size to gate the /code-review agent panel (#1339).
3
+
4
+ `/code-review` Step 3 dispatches the full ~17-agent `Scope: always` panel on
5
+ every review regardless of diff size — a 2-line registry-table-row removal
6
+ (issue #1331's fix: 2 files, ~1 added line) pays the same review cost as a
7
+ 25-file structural migration (issue #1334's fix: 537 added lines). The
8
+ pre-PR hook (`hooks/pre_pr_review.py`, #1886) has no coupling to which or how
9
+ many agents ran — it only checks that `/code-review` produced a matching
10
+ `.pr-review-passed` hash — so the panel-size decision is entirely Step 3's to
11
+ make, and today it makes no such distinction.
12
+
13
+ This module is the deterministic gate, sibling to `change_shape.py` (#1254,
14
+ which gates by file *type*). This gate gates by file *size*: given the target
15
+ files' `git diff --numstat` lines, it decides whether the changeset qualifies
16
+ for a narrowed agent panel.
17
+
18
+ **Added lines only, not deleted.** Added lines are unverified, newly
19
+ introduced content a reviewer must actually check; deleted lines are
20
+ comparatively low-risk (a dangling reference from a large deletion breaks the
21
+ build/tests, not silently). This is what lets issue #1331's fix (97 deleted
22
+ lines, ~1 added) qualify while issue #1334's fix (537 added lines) does not —
23
+ weighting total added+deleted would keep #1331's fix on the slow path,
24
+ defeating this gate's own motivating example.
25
+
26
+ **Gate-machinery carve-out.** Any file under `hooks/` or `skills/code-review/`
27
+ — the enforcement mechanism and this gate's own review orchestration —
28
+ always disqualifies, at any size. A change to the gate's own logic is exactly
29
+ the case where a cheap, self-certifying review would be a problem, so it is
30
+ excluded from ever qualifying for the shortcut it defines.
31
+
32
+ **Fail-safe by construction**, mirroring `change_shape.py`'s own philosophy:
33
+ a `git diff --numstat` failure, a binary-file marker (`-\t-\tpath`), or any
34
+ line this module cannot parse disqualifies the gate for that run (full
35
+ panel) — never counts as "small enough" by omission.
36
+
37
+ **Applicability is Step 3's job, not this module's.** This gate only makes
38
+ sense when there is an actual diff to measure (auto-scoped uncommitted
39
+ changes, or `--since <ref>`) — `--path`, `--all`, and the full-repository
40
+ fallback review complete files, not a diff, so `SKILL.md` never invokes this
41
+ module for those scopes. That decision is documented in `SKILL.md` Step 3's
42
+ "Change-size gate" subsection, not enforced here.
43
+
44
+ Pure policy — no filesystem, no globals. Stdlib-only.
45
+ """
46
+
47
+ from __future__ import annotations
48
+
49
+ import argparse
50
+ import json
51
+ import sys
52
+ from collections.abc import Iterable
53
+ from typing import NamedTuple
54
+
55
+ # Thresholds calibrated against two real commits cited in spec #1345:
56
+ # issue #1331's fix (2 files, ~1 added line — should qualify) and issue
57
+ # #1334's fix (25 files, 537 added lines — should not). Hardcoded, not a new
58
+ # review-config.json surface — smallest change that solves the stated
59
+ # problem; revisit if real usage shows these miscalibrated.
60
+ MAX_FILES = 3
61
+ MAX_ADDED_LINES = 20
62
+
63
+ # The agents that stay meaningful at any diff size and survive the fast path:
64
+ # a single line can introduce a vulnerability (security-review), a logic
65
+ # defect (correctness-review), a spec mismatch (spec-compliance-review), or
66
+ # doc drift (doc-review). Every other `Scope: always` agent is primarily a
67
+ # code-quality-at-scale concern a diff this small essentially cannot exhibit
68
+ # meaningfully.
69
+ #
70
+ # KEEP THIS IN SYNC with the identically-named list restated in English in
71
+ # `code-review/SKILL.md`'s "Change-size gate" subsection (Step 3) — same
72
+ # single-source-of-truth risk `change_shape.py`'s `LOW_YIELD_LENSES` already
73
+ # carries against its own `SKILL.md` restatement.
74
+ FAST_PATH_AGENTS = [
75
+ "security-review",
76
+ "correctness-review",
77
+ "spec-compliance-review",
78
+ "doc-review",
79
+ ]
80
+
81
+ # Path segments marking the review/gate machinery itself. A change here is
82
+ # exactly the case where a cheap, self-certifying review is a safety problem,
83
+ # so it always disqualifies, regardless of size. Narrower than
84
+ # `change_shape.py`'s "functional Claude-config" carve-out (agents/,
85
+ # knowledge/, .claude/, templates/) — those stay eligible for the fast path
86
+ # when small enough, since issue #1331's own motivating example touches
87
+ # `knowledge/agent-registry.md` and an `agents/` file and is exactly the case
88
+ # this gate must unblock.
89
+ _GATE_MACHINERY_PREFIXES = ("hooks/", "skills/code-review/")
90
+
91
+
92
+ class NumstatResult(NamedTuple):
93
+ file_count: int
94
+ added_lines: int
95
+ ok: bool
96
+ files: tuple[str, ...]
97
+
98
+
99
+ def parse_numstat(lines: Iterable[str]) -> NumstatResult:
100
+ """Parse `git diff --numstat` lines into a size signal.
101
+
102
+ Each line is `<added>\\t<deleted>\\t<path>`. A binary file reports `-` for
103
+ both counts; any line that isn't exactly that shape, or whose added/
104
+ deleted fields aren't parseable as non-negative integers (or `-`), marks
105
+ the whole result not-ok (fail-safe — a partial read is not "small").
106
+ """
107
+ files: list[str] = []
108
+ added_total = 0
109
+ ok = True
110
+ for raw in lines:
111
+ line = raw.rstrip("\n")
112
+ if not line.strip():
113
+ continue
114
+ parts = line.split("\t")
115
+ if len(parts) != 3:
116
+ ok = False
117
+ continue
118
+ added_field, deleted_field, path = parts
119
+ if not path.strip():
120
+ ok = False
121
+ continue
122
+ if added_field == "-" and deleted_field == "-":
123
+ # Binary file — numstat can't report line counts. Fail-safe: we
124
+ # cannot prove this file is small, so disqualify the whole run.
125
+ ok = False
126
+ files.append(path)
127
+ continue
128
+ if not added_field.isdigit() or not deleted_field.isdigit():
129
+ ok = False
130
+ continue
131
+ added_total += int(added_field)
132
+ files.append(path)
133
+ return NumstatResult(
134
+ file_count=len(files), added_lines=added_total, ok=ok, files=tuple(files)
135
+ )
136
+
137
+
138
+ def is_gate_machinery(path: str) -> bool:
139
+ """True when `path` is under the review/gate enforcement machinery."""
140
+ normalized = str(path).strip().replace("\\", "/")
141
+ return any(normalized.startswith(prefix) for prefix in _GATE_MACHINERY_PREFIXES)
142
+
143
+
144
+ def qualifies_for_fast_path(result: NumstatResult) -> bool:
145
+ """True when this changeset qualifies for the narrowed fast-path panel.
146
+
147
+ Requires: numstat parsed cleanly, file count and added-line count both
148
+ within threshold, and no file is gate machinery. Any single failing
149
+ condition disqualifies (fail-safe by construction).
150
+ """
151
+ if not result.ok:
152
+ return False
153
+ if result.file_count == 0:
154
+ return False
155
+ if result.file_count > MAX_FILES:
156
+ return False
157
+ if result.added_lines > MAX_ADDED_LINES:
158
+ return False
159
+ return not any(is_gate_machinery(f) for f in result.files)
160
+
161
+
162
+ def evaluate(lines: Iterable[str]) -> dict:
163
+ """Evaluate numstat lines and return the full decision as a dict."""
164
+ result = parse_numstat(lines)
165
+ qualifies = qualifies_for_fast_path(result)
166
+ return {
167
+ "filesChanged": result.file_count,
168
+ "addedLines": result.added_lines,
169
+ "qualifiesForFastPath": qualifies,
170
+ "keepAgents": list(FAST_PATH_AGENTS) if qualifies else [],
171
+ }
172
+
173
+
174
+ def main(argv=None) -> int:
175
+ parser = argparse.ArgumentParser(description=__doc__)
176
+ parser.add_argument(
177
+ "--numstat", nargs="*", default=[],
178
+ help="git diff --numstat lines, one per arg (space-separated)",
179
+ )
180
+ parser.add_argument(
181
+ "--numstat-from", default=None,
182
+ help="read newline-separated numstat lines from this file ('-' for stdin)",
183
+ )
184
+ args = parser.parse_args(argv)
185
+
186
+ lines = list(args.numstat)
187
+ if args.numstat_from:
188
+ if args.numstat_from == "-":
189
+ text = sys.stdin.read()
190
+ else:
191
+ with open(args.numstat_from) as handle:
192
+ text = handle.read()
193
+ lines.extend(line for line in text.splitlines() if line.strip())
194
+
195
+ print(json.dumps(evaluate(lines), sort_keys=True))
196
+ return 0
197
+
198
+
199
+ if __name__ == "__main__":
200
+ raise SystemExit(main(sys.argv[1:]))
201
+
202
+
203
+ __all__ = (
204
+ "FAST_PATH_AGENTS",
205
+ "MAX_ADDED_LINES",
206
+ "MAX_FILES",
207
+ "NumstatResult",
208
+ "evaluate",
209
+ "is_gate_machinery",
210
+ "parse_numstat",
211
+ "qualifies_for_fast_path",
212
+ )