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,571 @@
1
+ #!/usr/bin/env python3
2
+ """Stryker xunit.v3 shim gate — PreToolUse hook (#1083, version-gated #2184).
3
+
4
+ Stryker.NET **< 5.0.0** cannot observe mutant kills through xunit.v3:
5
+ xunit.v3 runs on the Microsoft Testing Platform (MTP) and Stryker's per-test
6
+ coverage/kill mapping does not work across it (stryker-net issues 3237/3629/3094).
7
+ A run against a real xunit.v3 test project completes but reports a false near-zero
8
+ score with almost everything "Survived" — silently, since the initial test run
9
+ passes. The fix, on those versions, is a xunit.v2 shim project (see the
10
+ stryker-xunit-v2-shim skill).
11
+
12
+ **Stryker.NET >= 5.0.0 closed this gap** (stryker-net#3752: MTP `perTest`/
13
+ `perTestInIsolation` coverage analysis) — `-t mtp` alone now gives a real
14
+ per-test score against the real xunit.v3 suite, no shim needed. This gate
15
+ detects the installed version via `hooks/mutation_adapters/stryker_net.py`'s
16
+ `stryker_net_version()` and silent-passes an xunit.v3 run on >= 5.0.0 rather
17
+ than scaffolding a shim or blocking (`_version_exempt()`). An undetermined
18
+ version (no `dotnet` on PATH, or unparseable `--version` output) fails closed
19
+ to the < 5.0.0 behavior below, with a note in the block body saying so. See
20
+ `skills/mutation-testing/references/languages/csharp-stryker-net.md`'s
21
+ "Stryker >= 5.0.0" section for the `-t mtp` + `coverage-analysis: perTest` +
22
+ `concurrency: 1` recommendation this gate's silent-pass hands off to
23
+ (the `concurrency: 1` pin is for the OPEN stryker-net#3832 regression).
24
+
25
+ On a `dotnet stryker` run that would produce the false score, this gate
26
+ **auto-scaffolds the shim and reports what it wrote** (it is not silent), then
27
+ blocks the current invocation — a PreToolUse hook cannot change the directory the
28
+ in-flight command runs in, so the shim must be run from its own directory as the
29
+ next step. It guards the two invocations that produce the false score:
30
+
31
+ * `dotnet stryker` in a directory whose test project references xunit.v3
32
+ (project mode bound to v3);
33
+ * `dotnet stryker` at a solution root whose solution contains a xunit.v3 test
34
+ project (solution mode binds to it).
35
+
36
+ It does NOT scaffold blindly: it runs the scope probe first and refuses when the
37
+ sources use v3-only constructs that need manual porting, and it never regenerates
38
+ over a shim that already exists. A run launched from a `*.Mutation` xunit.v2 shim
39
+ directory passes untouched.
40
+
41
+ When those constructs are present the block body is the **operator decision
42
+ gate** (#1791), not just a file list: `xunit_v3_feature_detector.py` classifies
43
+ each construct, `hooks/lib/xunit_v3_operator_gate.py` renders what is blocking
44
+ plus the four remediation options (port / exclude / skip / degrade) with their
45
+ tradeoffs, and the guard **stays blocked until the operator's choice is
46
+ recorded**. That recording is what makes the gate a guarantee rather than hook
47
+ stdout an agent may paraphrase or skip: before #1791 the shim could be silently
48
+ built, silently declined, or silently degraded, and the operator found out from
49
+ a report — if at all. Once recorded, the choice drives the outcome: `exclude`
50
+ scaffolds with `--compile-exclude` on the flagged files, `port`/`skip` block
51
+ until the sources are clean, `degrade` hands back the no-shim floor command.
52
+
53
+ Contract (docs/python-hook-contract.md):
54
+ Input : PreToolUse JSON on stdin
55
+ Output: exit 2 + `[BLOCK]`-prefixed body on stdout to BLOCK
56
+ exit 0 + no stdout for SILENT-PASS
57
+ Env : DEV_TEAM_STRYKER_XUNIT3_GATE_SKIP=1 -> silent bypass
58
+
59
+ Stdlib-only.
60
+ """
61
+ from __future__ import annotations
62
+
63
+ import os
64
+ import re
65
+ import subprocess
66
+ import sys
67
+ from pathlib import Path
68
+
69
+ _HOOK_DIR = Path(__file__).resolve().parent
70
+ _PLUGIN_DIR = _HOOK_DIR.parent
71
+ _LIB_DIR = _HOOK_DIR / "lib"
72
+
73
+ sys.path.insert(0, str(_LIB_DIR))
74
+ sys.path.insert(0, str(_HOOK_DIR))
75
+ try:
76
+ from stdin_json import read_stdin_json # type: ignore[import-not-found]
77
+ except ImportError: # pragma: no cover - fallback keeps the hook self-contained
78
+
79
+ def read_stdin_json() -> dict | None: # type: ignore[misc]
80
+ import json
81
+
82
+ try:
83
+ return json.loads(sys.stdin.read() or "{}")
84
+ except (ValueError, OSError):
85
+ return None
86
+
87
+ try:
88
+ from mutation_adapters.stryker_net import ( # type: ignore[import-not-found]
89
+ stryker_net_version,
90
+ )
91
+ except ImportError: # pragma: no cover - degraded fallback, adapter package unreachable
92
+ stryker_net_version = None # type: ignore[assignment]
93
+
94
+ #: Stryker.NET 5.0.0 (stryker-net#3752) restored real MTP per-test coverage,
95
+ #: closing the gap the xunit.v2 shim exists to work around (#2184).
96
+ _MTP_PER_TEST_COVERAGE_FLOOR = (5, 0, 0)
97
+
98
+
99
+ try:
100
+ from stryker_invocation import ( # type: ignore[import-not-found]
101
+ is_stryker_invocation as _is_stryker_invocation,
102
+ )
103
+ except ImportError: # pragma: no cover - degraded fallback, hooks/lib unreachable
104
+ # `dotnet stryker`, `dotnet-stryker`, or the plugin's wrapper — mirror the
105
+ # smoke-gate's pre-#2185 fallback so both gates degrade identically.
106
+ _STRYKER_TRIGGER_FALLBACK = re.compile(
107
+ r"(?:^|[^a-zA-Z0-9])dotnet[ \t-]+stryker(?:\b|$)|csharp[_-]stryker[_-]net[_-]wrapper"
108
+ )
109
+
110
+ def _is_stryker_invocation(cmd: str) -> bool: # type: ignore[misc]
111
+ return bool(cmd) and bool(_STRYKER_TRIGGER_FALLBACK.search(cmd))
112
+
113
+ _GENERATOR = _PLUGIN_DIR / "skills" / "stryker-xunit-v2-shim" / "scripts" / "generate_shim.py"
114
+ _PY_SH = _HOOK_DIR / "py.sh"
115
+ _OPERATOR_GATE_MODULE = _LIB_DIR / "xunit_v3_operator_gate.py"
116
+
117
+ # The detector lives with the mutation-testing skill; the guard reuses it rather
118
+ # than keeping a second, drifting classification of the same constructs.
119
+ _DETECTOR_DIR = _PLUGIN_DIR / "skills" / "mutation-testing" / "scripts"
120
+ if str(_DETECTOR_DIR) not in sys.path:
121
+ sys.path.insert(0, str(_DETECTOR_DIR))
122
+
123
+ try:
124
+ import xunit_v3_feature_detector as _detector # type: ignore[import-not-found]
125
+ except ImportError: # pragma: no cover - degraded fallback, skill tree unreachable
126
+ _detector = None
127
+
128
+ try:
129
+ import xunit_v3_operator_gate as _operator_gate # type: ignore[import-not-found]
130
+ except ImportError: # pragma: no cover - degraded fallback, hooks/lib unreachable
131
+ _operator_gate = None
132
+
133
+ # Directories never worth walking when scanning for test projects/sources.
134
+ _SKIP_DIRS = {"bin", "obj", ".git", "node_modules", ".vs", "StrykerOutput"}
135
+
136
+ # v3-only constructs that must be ported to v2-compatible forms before a shim
137
+ # can compile the linked sources (see the skill's Step 1 scope probe).
138
+ _V3_ONLY = (
139
+ "AutoFixture.Xunit3", "[AutoData", "InlineAutoData", "AutoMoqData",
140
+ "MemberAutoData", "TestContext", "Assert.Skip", "Assert.Multiple",
141
+ "IAsyncLifetime", "Assert.Equivalent",
142
+ )
143
+
144
+
145
+ def _read(path: Path) -> str:
146
+ try:
147
+ return path.read_text(encoding="utf-8", errors="ignore")
148
+ except OSError:
149
+ return ""
150
+
151
+
152
+ def _is_v2_shim(csproj: Path) -> bool:
153
+ if not csproj.name.endswith(".Mutation.csproj"):
154
+ return False
155
+ return bool(re.search(r'Include="xunit"\s+Version="2', _read(csproj)))
156
+
157
+
158
+ def _is_v3(csproj: Path) -> bool:
159
+ return "xunit.v3" in _read(csproj)
160
+
161
+
162
+ _MTP_RUNNER_RE = re.compile(r"""(?:^|\s)(?:-t|--test-runner)[ =]+["']?mtp\b""")
163
+
164
+
165
+ def _uses_mtp_runner(command: str) -> bool:
166
+ """True when the command explicitly selects Stryker's Microsoft Testing
167
+ Platform runner (`-t mtp` / `--test-runner mtp`) — the sanctioned no-shim
168
+ floor (#1156/#1159): it drives the real xunit.v3 suite and yields a real
169
+ (if slow, whole-suite-per-mutant) score, so the false-~0% premise this gate
170
+ guards against does not apply."""
171
+ return bool(_MTP_RUNNER_RE.search(command))
172
+
173
+
174
+ def _resolve_run_dir(command: str, cwd: str) -> Path:
175
+ """Honour a leading `cd <dir> && ...` so the gate reasons about where Stryker
176
+ actually runs, not where the shell started."""
177
+ match = re.search(r"\bcd\s+([^\s&;|]+)", command)
178
+ if match:
179
+ target = match.group(1).strip("'\"")
180
+ return (Path(cwd) / target).resolve()
181
+ return Path(cwd).resolve()
182
+
183
+
184
+ def _find_v3_test_projects(root: Path, limit: int = 400) -> list[Path]:
185
+ """Bounded walk for xunit.v3 test .csproj under a solution root."""
186
+ found: list[Path] = []
187
+ seen = 0
188
+ for dirpath, dirnames, filenames in os.walk(root):
189
+ dirnames[:] = [d for d in dirnames if d not in _SKIP_DIRS]
190
+ for name in filenames:
191
+ if name.endswith(".csproj"):
192
+ seen += 1
193
+ if seen > limit:
194
+ return found
195
+ path = Path(dirpath) / name
196
+ if not path.name.endswith(".Mutation.csproj") and _is_v3(path):
197
+ found.append(path)
198
+ return found
199
+
200
+
201
+ def _classify(project_dir: Path) -> tuple[list[str], list[dict]]:
202
+ """Scan the project's test sources for shim-breaking v3-only usage.
203
+
204
+ Returns ``(flagged_files, classified_findings)``, both keyed on paths
205
+ relative to ``project_dir`` so the operator-facing list and the
206
+ ``--compile-exclude`` globs derived from it are stable regardless of where
207
+ the run was launched.
208
+
209
+ Two scans, deliberately: the detector supplies the *classification* the
210
+ operator gate needs (which construct, translatable or not, coverage-bearing
211
+ or neutral), while the older token list is broader — it catches v3-only
212
+ usage the detector has no construct for. Dropping a token-flagged file for
213
+ lacking a classification would silently narrow what the guard blocks on, so
214
+ those files stay in ``flagged_files`` and reach the operator labelled as
215
+ needing manual triage.
216
+ """
217
+ flagged: list[str] = []
218
+ findings: list[dict] = []
219
+ for dirpath, dirnames, filenames in os.walk(project_dir):
220
+ dirnames[:] = [d for d in dirnames if d not in _SKIP_DIRS]
221
+ for name in sorted(filenames):
222
+ if not name.endswith(".cs"):
223
+ continue
224
+ path = Path(dirpath) / name
225
+ rel = str(path.relative_to(project_dir))
226
+ text = _read(path)
227
+ classified = []
228
+ if _detector is not None:
229
+ classified = [
230
+ {
231
+ "file": rel,
232
+ "line": f.line,
233
+ "construct": f.construct,
234
+ "compile_ability": f.compile_ability,
235
+ "coverage_impact": f.coverage_impact,
236
+ "snippet": f.snippet,
237
+ }
238
+ for f in _detector.scan_text(rel, text)
239
+ ]
240
+ findings.extend(classified)
241
+ if classified or any(tok in text for tok in _V3_ONLY):
242
+ flagged.append(rel)
243
+ return flagged, findings
244
+
245
+
246
+ def _shim_dir_for(real_csproj: Path) -> Path:
247
+ real_dir = real_csproj.parent
248
+ return real_dir.parent / (real_csproj.stem + ".Mutation")
249
+
250
+
251
+ def _run_generator(
252
+ real_csproj: Path, cwd: Path, extra_args: list[str] | None = None
253
+ ) -> tuple[int, str]:
254
+ if not _GENERATOR.is_file():
255
+ return 127, f"generator not found at {_GENERATOR}"
256
+ try:
257
+ proc = subprocess.run(
258
+ [sys.executable, str(_GENERATOR), str(real_csproj), *(extra_args or [])],
259
+ cwd=str(cwd), capture_output=True, text=True, check=False, timeout=30,
260
+ )
261
+ except (OSError, subprocess.SubprocessError) as exc: # pragma: no cover
262
+ return 1, str(exc)
263
+ return proc.returncode, (proc.stdout or "") + (proc.stderr or "")
264
+
265
+
266
+ def _compile_exclude_globs(name: str, flagged: list[str]) -> list[str]:
267
+ """`--compile-exclude` values for the flagged files.
268
+
269
+ Shaped to match what the generator emits, which is the only thing verifiable
270
+ from here: `generate_shim.py` writes `<Compile Include="..\\<Name>\\**\\*.cs"
271
+ Exclude="<;-joined values>">`, and its own default exclusions are spelled
272
+ `..\\<Name>\\obj\\**\\*.cs`. So an exclusion is expressed shim-relative and
273
+ backslashed, and the separator conversion below produces that on both POSIX
274
+ and Windows hosts. (Whether MSBuild would additionally normalise a
275
+ forward-slash value is not asserted here — the shape the generator already
276
+ uses is the one to match, and the emitted value is pinned by test.)
277
+ """
278
+ return [f"..\\{name}\\" + rel.replace("/", "\\").replace(os.sep, "\\")
279
+ for rel in flagged]
280
+
281
+
282
+ def _record_command(name: str, fingerprint: str) -> str:
283
+ """The command that satisfies the gate once the operator has answered.
284
+
285
+ Routed through `hooks/py.sh` rather than a bare `python3` so it works where
286
+ `python3` is absent (Windows, #1078), and with absolute paths so it does not
287
+ depend on the cwd the agent happens to be in.
288
+ """
289
+ return (
290
+ f'sh "{_PY_SH}" "{_OPERATOR_GATE_MODULE}" record '
291
+ f'--project {name} --choice <port|exclude|skip|degrade> '
292
+ f"--fingerprint {fingerprint}"
293
+ )
294
+
295
+
296
+ def _floor_command(real_csproj: Path, cwd: Path) -> list[str]:
297
+ """The sanctioned no-shim floor, spelled out.
298
+
299
+ `coverage-analysis` is config-file-only in Stryker.NET (no CLI flag), so the
300
+ instruction says to set it in the config — handing over a `--coverage-analysis`
301
+ flag would just produce a failed command and a retry (#1777).
302
+ """
303
+ rel_project = os.path.relpath(real_csproj.parent, cwd)
304
+ # A `cd .` is noise the operator has to read past to find the real command.
305
+ lines = [] if rel_project == "." else [f" cd {rel_project}"]
306
+ return lines + [
307
+ (
308
+ ' # set "coverage-analysis": "off" in stryker-config.json '
309
+ "(config-file-only — there is no CLI flag)"
310
+ ),
311
+ " dotnet-stryker -t mtp",
312
+ ]
313
+
314
+
315
+ def _operator_gate_block(
316
+ header: str, real_csproj: Path, cwd: Path, flagged: list[str], findings: list[dict]
317
+ ) -> list[str]:
318
+ """The #1791 decision gate for one blocked project.
319
+
320
+ Returns the block body: the operator question when no decision covers the
321
+ current blocker set, otherwise the consequence of the recorded choice.
322
+ """
323
+ name = real_csproj.stem
324
+ shim_dir = _shim_dir_for(real_csproj)
325
+ rel_shim = os.path.relpath(shim_dir, cwd)
326
+ unclassified = [f for f in flagged if all(d["file"] != f for d in findings)]
327
+
328
+ question = _operator_gate.build_question(name, findings, unclassified)
329
+ decision = _operator_gate.decision_for(question, cwd=cwd)
330
+
331
+ if decision is None:
332
+ return [
333
+ header + ", and the operator has to choose how to handle it:",
334
+ "",
335
+ ] + _operator_gate.render_question(
336
+ question, record_command=_record_command(name, question.fingerprint)
337
+ )
338
+
339
+ choice = decision.get("choice")
340
+ if choice == "exclude":
341
+ code, out = _run_generator(
342
+ real_csproj,
343
+ cwd,
344
+ [arg for glob in _compile_exclude_globs(name, flagged)
345
+ for arg in ("--compile-exclude", glob)],
346
+ )
347
+ if code != 0:
348
+ return [
349
+ header + ", and scaffolding with the operator's exclusions failed:",
350
+ f" {out.strip()[:400]}",
351
+ ]
352
+ return [
353
+ header + " — scaffolded a xunit.v2 shim with the operator's exclusions",
354
+ (
355
+ f"({len(flagged)} file(s) dropped from the shim's compile set, so "
356
+ "they stay UNMEASURED by mutation):"
357
+ ),
358
+ ] + [" " + ln for ln in out.strip().splitlines()] + [
359
+ "Run mutation FROM the shim dir:",
360
+ f" cd {rel_shim} && dotnet-stryker",
361
+ ]
362
+
363
+ if choice == "degrade":
364
+ return [
365
+ (
366
+ header + " — the operator chose 'degrade': skip the shim and run "
367
+ "the no-shim floor instead."
368
+ ),
369
+ (
370
+ "It drives the real xunit.v3 suite, so the score is real but "
371
+ "whole-suite-per-mutant (slow, single advisory pass, no kill loop):"
372
+ ),
373
+ ] + _floor_command(real_csproj, cwd)
374
+
375
+ # port / skip: the sources have to change before a shim can compile.
376
+ verb = (
377
+ "Port these to v2-compatible forms"
378
+ if choice == "port"
379
+ else "Deactivate/skip these tests for the duration of the measurement"
380
+ )
381
+ tail = [
382
+ "See the stryker-xunit-v2-shim skill, Step 3 for the v3->v2 replacements.",
383
+ ]
384
+ if choice == "skip":
385
+ # Deactivating a test does not delete the construct from the file the shim
386
+ # links, so `skip` only clears this gate where the deactivation itself
387
+ # removes the offending syntax. Saying so here beats the operator
388
+ # re-running into the same block and concluding the gate is broken.
389
+ tail.append(
390
+ "NOTE: deactivating a test removes it from the RUN, not from the "
391
+ "SOURCE the shim compiles. It clears this gate only where the "
392
+ 'deactivation removes the construct itself (e.g. [Fact(Explicit = '
393
+ 'true)] -> [Fact(Skip = "...")]). For a construct in the test body '
394
+ "or on a data attribute, re-record as 'port' or 'exclude'."
395
+ )
396
+ return [
397
+ header + f" — the operator chose '{choice}', which is not done yet.",
398
+ (
399
+ f"{verb} in the REAL test project (the shim links the same sources, so "
400
+ "one edit serves both), then re-run — the guard scaffolds automatically "
401
+ "once the sources are clean:"
402
+ ),
403
+ ] + [
404
+ f" - {d['file']}:{d['line']} {d['construct']} {d['snippet']}"
405
+ for d in findings[:20]
406
+ ] + [f" - {f} (unclassified — manual triage)" for f in unclassified[:20]] + tail
407
+
408
+
409
+ def _handle_v3_project(real_csproj: Path, cwd: Path) -> list[str]:
410
+ """Auto-scaffold the shim for one xunit.v3 test project (or explain why not),
411
+ and return the block body reporting exactly what happened."""
412
+ name = real_csproj.stem
413
+ shim_dir = _shim_dir_for(real_csproj)
414
+ rel_shim = os.path.relpath(shim_dir, cwd)
415
+ header = f"[BLOCK] Stryker on the xunit.v3 project '{name}' reports a FALSE ~0% score"
416
+
417
+ # Never regenerate over an existing shim.
418
+ if (shim_dir / (name + ".Mutation.csproj")).exists():
419
+ return [
420
+ header + " — a v2 shim already exists.",
421
+ f"Run mutation FROM the shim dir: cd {rel_shim} && dotnet-stryker",
422
+ ]
423
+
424
+ # Shim-breaking sources: this is the operator's decision, not the agent's
425
+ # (#1791). Never scaffold, decline, or degrade on their behalf.
426
+ flagged, findings = _classify(real_csproj.parent)
427
+ if flagged and _operator_gate is not None:
428
+ return _operator_gate_block(header, real_csproj, cwd, flagged, findings)
429
+ if flagged: # pragma: no cover - degraded fallback, hooks/lib unreachable
430
+ return [
431
+ header + ", and the shim can't be auto-built:",
432
+ "these sources use v3-only constructs that must be ported to v2-compatible",
433
+ "forms first (see the stryker-xunit-v2-shim skill, Step 3):",
434
+ ] + [f" - {f}" for f in sorted(set(flagged))[:20]]
435
+
436
+ code, out = _run_generator(real_csproj, cwd)
437
+ if code != 0:
438
+ return [
439
+ header + ", and auto-scaffolding failed:",
440
+ f" {out.strip()[:400]}",
441
+ f"Build the shim by hand: python3 {os.path.relpath(_GENERATOR, cwd)} {os.path.relpath(real_csproj, cwd)}",
442
+ ]
443
+ lines = [
444
+ header + " — auto-scaffolded a xunit.v2 shim (perTest, 30s timeout):",
445
+ ]
446
+ lines += [" " + ln for ln in out.strip().splitlines()]
447
+ lines += [
448
+ "Review the generated shim, then run mutation FROM it:",
449
+ f" cd {rel_shim} && dotnet-stryker",
450
+ f'If the product uses InternalsVisibleTo, add [assembly: InternalsVisibleTo("{name}.Mutation")].',
451
+ (
452
+ "Nothing in these sources blocked the shim, so no operator decision "
453
+ "was needed. If you would rather not shim at all, the no-shim floor is:"
454
+ ),
455
+ ] + _floor_command(real_csproj, cwd)
456
+ return lines
457
+
458
+
459
+ _VERSION_UNKNOWN_NOTE = (
460
+ "Note: Stryker.NET's version could not be determined (`dotnet`/`dotnet "
461
+ "stryker --version` unavailable or unparseable) — failing closed to the "
462
+ "pre-5.0.0, shim-required assumption below. Set "
463
+ "DEV_TEAM_STRYKER_NET_VERSION=<X.Y.Z> to override if the installed "
464
+ "version is actually >= 5.0.0 (#2184)."
465
+ )
466
+
467
+
468
+ def _version_exempt() -> tuple[bool, bool]:
469
+ """`(exempt, version_unknown)` for the installed Stryker.NET CLI.
470
+
471
+ `exempt=True` means the version is known to be >= 5.0.0, which restored
472
+ real MTP per-test coverage (stryker-net#3752) — the gap the xunit.v2
473
+ shim exists to work around is closed, so this gate should silent-pass
474
+ regardless of which runner flag the command uses (#2184).
475
+
476
+ `version_unknown=True` means the version could not be determined at
477
+ all (no `dotnet` on PATH, the probe failed, or its output didn't parse)
478
+ — the caller fails closed to the pre-5.0.0 shim-required behavior, but
479
+ should surface `_VERSION_UNKNOWN_NOTE` in the block body so the
480
+ operator can tell a real <5.0.0 detection apart from this fallback.
481
+
482
+ Deliberately called only where the guard is about to block (project or
483
+ solution mode, immediately before building the block body) — not
484
+ unconditionally at the top of `main()` — so the `dotnet stryker
485
+ --version` subprocess call never runs for the common case (no `.sln`
486
+ match, a v2 shim run, a non-Stryker command, or a project with no
487
+ xunit.v3 test project at all).
488
+ """
489
+ if stryker_net_version is None: # pragma: no cover - degraded fallback, adapter unreachable
490
+ return False, True
491
+ version = stryker_net_version()
492
+ if version is None:
493
+ return False, True
494
+ return version >= _MTP_PER_TEST_COVERAGE_FLOOR, False
495
+
496
+
497
+ def _block(lines: list[str]) -> int:
498
+ print("\n".join(lines))
499
+ return 2
500
+
501
+
502
+ def main() -> int:
503
+ if os.environ.get("DEV_TEAM_STRYKER_XUNIT3_GATE_SKIP") == "1":
504
+ return 0
505
+
506
+ event = read_stdin_json() or {}
507
+ if event.get("tool_name") != "Bash":
508
+ return 0
509
+ command = (event.get("tool_input") or {}).get("command", "") or ""
510
+ if not _is_stryker_invocation(command):
511
+ return 0
512
+
513
+ # Sanctioned no-shim floor (#1156/#1159): an explicit MTP-runner run drives
514
+ # the real xunit.v3 suite and produces a real score, so it must not be
515
+ # blocked or shimmed. Let it through before any v3-project detection.
516
+ if _uses_mtp_runner(command):
517
+ return 0
518
+
519
+ cwd = event.get("cwd") or os.environ.get("CLAUDE_PROJECT_DIR") or os.getcwd()
520
+ run_dir = _resolve_run_dir(command, cwd)
521
+ if not run_dir.is_dir():
522
+ return 0
523
+ # Resolve: every path in the block body is computed relative to this, and
524
+ # `run_dir` (and so the shim dir derived from it) is already resolved. Mixing
525
+ # a raw cwd with resolved targets turns a sibling directory into a
526
+ # ../../../.. crawl back through the symlink's parent chain the moment the
527
+ # cwd traverses a link — macOS /var -> /private/var is the everyday case.
528
+ base = Path(cwd).resolve()
529
+
530
+ local = list(run_dir.glob("*.csproj"))
531
+
532
+ # Correct invocation: already inside a xunit.v2 shim dir. Let it run.
533
+ if any(_is_v2_shim(p) for p in local):
534
+ return 0
535
+
536
+ # Project mode bound directly to a xunit.v3 test project.
537
+ v3_local = [p for p in local if _is_v3(p)]
538
+ if v3_local:
539
+ exempt, version_unknown = _version_exempt()
540
+ if exempt:
541
+ return 0
542
+ lines = _handle_v3_project(v3_local[0], base)
543
+ if version_unknown:
544
+ lines = [_VERSION_UNKNOWN_NOTE, ""] + lines
545
+ return _block(lines)
546
+
547
+ # Solution mode: a bare run at a solution root binds to the v3 test project(s).
548
+ if list(run_dir.glob("*.sln")):
549
+ v3 = _find_v3_test_projects(run_dir)
550
+ if v3:
551
+ exempt, version_unknown = _version_exempt()
552
+ if exempt:
553
+ return 0
554
+ lines = [
555
+ "[BLOCK] `dotnet stryker` at this solution root enters solution mode and binds to",
556
+ "xunit.v3 test project(s), reporting a FALSE ~0% score (Stryker.NET can't observe",
557
+ "kills through xunit.v3 — MTP; stryker-net #3237/#3629/#3094). Handling each:",
558
+ "",
559
+ ]
560
+ if version_unknown:
561
+ lines = [_VERSION_UNKNOWN_NOTE, ""] + lines
562
+ for proj in v3[:5]:
563
+ lines += _handle_v3_project(proj, base) + [""]
564
+ lines.append("Run each shim from its own directory (no .sln in scope forces project mode).")
565
+ return _block(lines)
566
+
567
+ return 0
568
+
569
+
570
+ if __name__ == "__main__":
571
+ sys.exit(main())