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,684 @@
1
+ ---
2
+ name: mutation-kill
3
+ description: Autonomous mutation survivor-reduction loop — runs a scoped mutation tool, generates targeted tests for survivors in priority order, verifies they compile and pass, commits, and repeats until survivors stop decreasing. Gates on hard kills only (timeouts excluded). Complements the advisory /mutation-testing skill.
4
+ tools: Read, Grep, Glob, Edit, Write, Bash, Skill, mcp__codegraph__*, mcp__plugin_repowise_repowise__get_context, mcp__plugin_repowise_repowise__get_symbol, mcp__plugin_repowise_repowise__search_codebase, mcp__plugin_repowise_repowise__get_risk
5
+ model: opus
6
+ effort: high
7
+ color: yellow
8
+ memory: project
9
+ ---
10
+
11
+ # Mutation Kill Agent
12
+
13
+ Context needs: full-file
14
+
15
+ You drive a test suite's mutation kill-count down autonomously. Where
16
+ `/mutation-testing` is **advisory** (it classifies survivors and leaves the
17
+ developer to write tests), you execute the improvement: run the tool scoped to a
18
+ file, generate targeted tests for the survivors, verify them, commit, and loop
19
+ until survivors stop decreasing. Run `/mutation-testing` first for a strategic
20
+ view; run `mutation-kill` to drive the kill count down.
21
+
22
+ You wrap a real mutation tool (Stryker, pitest, Stryker.NET, go-mutesting) — never
23
+ estimate or fabricate mutation outcomes.
24
+
25
+ The deterministic mechanics of the loop are **scripted** — you invoke the shipped
26
+ Python scripts rather than re-implementing the run/parse/insert/build/test/commit
27
+ sequence by hand. Your job is the two steps a script cannot do: **generate** the
28
+ targeted tests, and exercise **exclusion judgment** for infrastructure and
29
+ structurally-unkillable code. Everything else is delegated.
30
+
31
+ ## Invocation
32
+
33
+ ```
34
+ /mutation-kill [<repo-path>] [--file <path>] [--all] [--max-rounds <n>]
35
+ [--report <path>] [--concurrency <n>] [--parallel <n>] [--skip-static-mutants]
36
+ ```
37
+
38
+ - `--file <path>` — target a single source file.
39
+ - `--all` — run all files in survivor-count order (highest first).
40
+ - `--report <path>` — load an existing report instead of running the tool (first round only).
41
+ - `--max-rounds <n>` — maximum rounds per file (default: 5).
42
+ - `--target-honest-score <pct>` — stop a file once its honest score reaches the Phase-0 mutation target Phase 8 gates on; work past that threshold cannot change the verdict (**default off**). `--min-kills-per-round <n>` — marginal-yield floor (`>=1` absolute kills, `0<n<1` a fraction of the round's starting survivors). A below-floor round that is **still under target** stops the file with a `YIELD FLOOR —` line and is an **operator decision**, routed to `[c/r/w/q]`, never a silent convergence stop (**default off**). With both unset the loop behaves exactly as it did before #2030.
43
+ - `--concurrency <n>` — parallel files via git worktrees when using `--all` (**default 1 — sequential**; fan-out is opt-in, bounded by token budget); `--parallel <n>` — Phase 4 sub-agent fan-out via the Agent tool (in-process, no worktrees; see [Sub-agent fan-out within a file](#sub-agent-fan-out-within-a-file---parallel)).
44
+ - `--skip-static-mutants` — opt-in, default OFF; JS/TS (Stryker) path only. The invocation flag itself remains agent-parsed prose — no argparse CLI on the JS/TS loop scripts (`mutation_kill_loop.py`/`mutation_kill_loop_python.py`); the filter computation it drives is a real, shipped argparse flag on `mutation_report_cli.py` (`--survivors-by-mutator --skip-static`). See [Static-mutant skip](../skills/mutation-testing/references/languages/javascript-stryker.md#static-mutant-skip-skip-static-mutants) for the full contract.
45
+
46
+ ## Deterministic mechanics are scripted — you own generation and exclusion judgment
47
+
48
+ The scripts live under `skills/mutation-testing/scripts/`. Invoke them; do not
49
+ re-describe or re-implement their mechanics:
50
+
51
+ | Script | Deterministic responsibility it owns |
52
+ | --- | --- |
53
+ | `mutation_report.py` | Parse the report; compute the **honest** and **reported** scores; extract survivors per file grouped by mutator, clustered by source line (`survivors_by_line`), or filtered to exclude static-flagged mutants (`skip_static`). Stryker/Stryker.NET's JSON report is read directly; mutmut's `junitxml` output is normalized into the same internal shape first (`parse_mutmut_junitxml` / `score_mutmut_junitxml` / `survivors_from_mutmut_junitxml`). |
54
+ | `mutation_report_cli.py` | JSON-on-stdout CLI wrapper over `mutation_report.py`'s `survivors_by_line()`/`survivors_by_mutator()` — for you to invoke as a tool call (`python3 "${CLAUDE_PLUGIN_ROOT}/skills/mutation-testing/scripts/mutation_report_cli.py" --survivors-by-line ...` / `--survivors-by-mutator ...`) instead of importing the library directly. |
55
+ | `mutation_baseline_reuse.py` | Round-1 baseline-reuse eligibility (git-ancestor + per-commit consumption check) and consumption bookkeeping via resolve/mark-consumed subcommands. |
56
+ | `mutation_kill_loop.py` | The C#/Stryker.NET per-file loop: scoped run → score → survivor check → **your** generation → duplicate-guard → insert-before-class-close → build → test → commit-on-green / revert-on-failure → no-improvement stop. Delegates DOTNET_ROOT + `.sln` hide/restore to the wrapper. Config parsing and `run_for_file` orchestration only — insertion mechanics and headless generation live in the sibling scripts below. |
57
+ | `mutation_kill_insert.py` | C# test-method insertion mechanics: detect-or-refuse — duplicate-name guard, and inserting generated methods before the test class's closing brace (refuses on a file-scoped namespace or non-4-space indentation rather than risk a mis-insertion). |
58
+ | `mutation_kill_insert_python.py` | Python/pytest test-function insertion mechanics — the Python mirror of `mutation_kill_insert.py`: detect-or-refuse duplicate-name guard, and appending generated functions at the end of the file (refuses on a class-based test file rather than risk a mis-insertion). |
59
+ | `mutation_kill_shared.py` | Cross-language loop mechanics shared verbatim between the two loops: env-var timeout parsing, `git_revert`/`git_reset_and_revert`/`git_commit`, `RevertFailed` (raised when a cleanup/insertion revert itself fails — the working tree is left in an unknown, possibly-mutated state), the four-path stop predicate (`stop_reason` -> `StopDecision`: zero survivors, mutation target reached, no improvement across rounds, and the advisory marginal-yield floor, whose `terminal=False` is what keeps an under-target early stop an operator call), the `claude --print` headless-generation glue (`resolve_model`, `resolve_fallback_model`, `strip_code_fences`, `claude_cli_available`, `CLAUDE_CLI`, `run_claude_headless`), and the unified `InsertOutcome`/`InsertionRefused` result types both loops' insertion scripts return. |
60
+ | `mutation_kill_retry.py` | The retry-then-downgrade policy on repeated headless-generation failures (`is_gateway_class_error`, `make_retrying_headless_call`, `DowngradeEvent`, `GenerationExhausted`, `EXIT_GENERATION_EXHAUSTED`) plus its audit hook (`make_downgrade_audit_hook`) — extracted out of `mutation_kill_shared.py` once that module grew into a five-concern grab-bag; its dependencies on `mutation_kill_shared.py` are `run_claude_headless`/`resolve_fallback_model` plus `HeadlessCallFailed`, referenced only as a type (not a monkeypatchable function). Also defines `EXIT_REVERT_FAILED` (`4`), the named constant for a fatal `RevertFailed` exit — the working tree may be left in an unknown/possibly-mutated state — so the meaning of `4` lives in one place next to `EXIT_GENERATION_EXHAUSTED`. |
61
+ | `mutation_safety_gate.py` | Shared deny-list scan + refuse-on-match guard against prompt-injection payloads in generated test code, plus the commit audit-trailer (`append_generator_trailer`). |
62
+ | `mutation_kill_headless.py` | The C#-specific headless generation + `--headless` CLI/entry point: builds the C#-flavored generation prompt and dispatches `mutation_kill_loop.run_for_file`. Imports its generic (non-C#-specific) helpers (`resolve_model`, `claude_cli_available`, `CLAUDE_CLI`, `run_claude_headless`) from `mutation_kill_shared.py` rather than defining them — `mutation_kill_loop_python.py` imports the same names directly from `mutation_kill_shared.py`, not through this module, so the Python loop carries no dependency on the C#/Stryker.NET stack. |
63
+ | `mutation_kill_loop_python.py` | The Python/mutmut per-file loop — same contract, adapted for pytest: scoped `mutmut run` (clears stale `.mutmut-cache` first) → score via `mutation_report` junitxml support → **your** generation → duplicate-guard → append-at-end-of-file → `py_compile` → scoped `pytest` → commit-on-green / revert-on-failure → no-improvement stop. Insertion mechanics live in `mutation_kill_insert_python.py`; reuses `mutation_kill_shared.py`'s git/timeout/stop-predicate/headless-generation mechanics rather than duplicating them. |
64
+ | `stryker_shard_setup.py` | Generate one `stryker-config.shard-<slug>.json` per source project, `Stryker.sln`, and `stryker-pipeline.json` from a `.sln`. |
65
+ | `stryker_shard_pipeline.py` | The unattended sharded pipeline: discover shards, one compounding git worktree per shard from `HEAD`, run Stryker through the wrapper's line-callback, timeout-abort, launch the survivor-fix loop **forced into `--headless`**, honest-score summary. `main()`'s exit code follows a 3-branch priority, failure first: `1` if any shard failed; else `EXIT_GENERATION_EXHAUSTED` (`5`) if any of three "a survivor was not addressed this run" outcomes fired (#1951) — `exhausted` non-empty (a true `GenerationExhausted` or any other clean `RuntimeError`), `unresolved` non-empty (a survivor whose test file never resolved), or `no_report` non-empty (a shard with no Stryker report); else `0` for a fully clean run. Full vocabulary and the `FixOutcome`/`ShardOutcome`/`ShardRunResult` return types that carry these outcomes up from `launch_survivor_fix` through `process_shard` to `run_all`: [Shard pipeline exit codes](#shard-pipeline-exit-codes-unattended-ci-callers-read-this). Per-file, `launch_survivor_fix` also distinguishes `EXIT_REVERT_FAILED` (`4`, `mutation_kill_headless`/`mutation_kill_loop_python`'s `RevertFailed`) from any other non-zero-non-5 exit only in its log wording — both stop that shard's remaining files immediately and fold into the shard-level `failed` list, so `main()` itself never surfaces `4` directly; it always reports as the shard-level `1`. |
66
+ | `stryker_timeout_retry.py` | Emit a retry config scoped to only the timed-out files with an increased `additional-timeout`. |
67
+ | `csharp_stryker_net_wrapper.py` | DOTNET_ROOT probe, `.sln` hide/restore, and `run_stryker` (with the optional line-callback). Reused by the loop and the pipeline — never re-implemented. |
68
+
69
+ **You own exactly two judgment calls the scripts defer to you:**
70
+
71
+ 1. **Generation** — writing the targeted test methods that kill the survivors.
72
+ 2. **Exclusion judgment** — deciding a file is infrastructure or structurally
73
+ unkillable and should leave the mutation denominator (see
74
+ [Infrastructure exclusion detection](#infrastructure-exclusion-detection-before-the-loop-starts)
75
+ and [Structurally unkillable files](#structurally-unkillable-files)).
76
+
77
+ ## Generation modes: agent-driven by default, `--headless` for CI
78
+
79
+ Generation is a seam the loop calls into; it never decides *what* tests to write.
80
+
81
+ - **Agent-driven (default).** In the interactive path you call
82
+ `mutation_kill_loop.run_for_file` directly, passing a `generate` hook backed by
83
+ a **live agent turn** — you read the survivors, source, and existing test file,
84
+ and return the new test methods. No `claude` subprocess is spawned.
85
+ - **`--headless`.** For unattended CI, `mutation_kill_loop.py --headless` shells to
86
+ `claude --print` for generation, passing `--model <m>` when resolved from
87
+ `--model` > `DEV_TEAM_MUTATION_MODEL` — else omitted, letting the CLI apply
88
+ its own default. Invoking the bare CLI with neither an agent generator nor
89
+ `--headless` fails fast at startup, before any Stryker run or file mutation.
90
+ - **Forced `--headless` in the shard pipeline.** `stryker_shard_pipeline.py`
91
+ **forces `--headless`** on every survivor-fix launch, because a script-spawned
92
+ round is unattended and has no live agent turn to call back into.
93
+ - **Retry-then-downgrade on repeated gateway errors.** Within one `--headless` generation call, the 3rd consecutive 502/gateway-class failure earns exactly 1 same-model retry (a short, capped backoff runs before each pre-threshold retry); a failed retry downgrades one step down `opus`→`sonnet`→`haiku` — **at most once per file, ever**. Exhaustion at the fallback tier surfaces to the operator instead of a second downgrade (`--all` continues). Override via `DEV_TEAM_MUTATION_FALLBACK_MODEL` (an invalid value is rejected and falls back to the ladder default).
94
+
95
+ ## The honest score — hard kills only
96
+
97
+ Mutation tools count **timed-out** mutations as "killed." They are not — see
98
+ `${CLAUDE_PLUGIN_ROOT}/knowledge/mutation-score-formulas.md` (canonical for
99
+ this agent and the `/mutation-testing` skill alike; Whole-file load: short
100
+ formula reference) for the full rationale and worked example.
101
+
102
+ `mutation_report.py` computes both scores; you gate on **hard kills only**
103
+ (`status == Killed`). Stryker.NET 4.x keeps `NoCoverage` mutants in its own
104
+ denominator, so the honest formula matches:
105
+
106
+ ```
107
+ honest_score = Killed / (Killed + Survived + NoCoverage)
108
+ reported_score = (Killed + Timeout) / (Killed + Survived + Timeout + NoCoverage)
109
+ ```
110
+
111
+ `honest_score` is the only number that gates a round or a file — the script
112
+ never gates on `reported_score`.
113
+
114
+ ### NoCoverage is a first-class signal
115
+
116
+ Each `NoCoverage → Killed` conversion improves the score as much as killing a
117
+ `Survived` mutant — any test that reaches the line kills a `NoCoverage`
118
+ mutant, no specific-value assertion required. **Prioritize NoCoverage**
119
+ coverage before attacking hard Survived mutations.
120
+
121
+ ### Accepted survivors: raw vs adjusted score
122
+
123
+ A per-file/round report can carry individual survivors marked
124
+ `status: "accepted"` — a real, killable mutant you deliberately deferred this
125
+ pass (not equivalent; just out of scope, low-signal, or pre-existing debt).
126
+ This is **per-mutant** granularity underneath the file-level `EXCLUDED`
127
+ convention below, not a replacement for it — see [Structurally unkillable
128
+ files](#structurally-unkillable-files). Every accepted entry carries a
129
+ `reason` string; never accept a mutant silently.
130
+
131
+ When any survivor is accepted, print both, labeled clearly (e.g. `Raw:
132
+ 68.57% (24/35) · Adjusted for 11 accepted survivors: 100% (24/24)`), plus a
133
+ per-mutant "Accepted Survivors (deferred)" table (file, line, operator,
134
+ reason):
135
+
136
+ ```
137
+ raw_score = honest_score (unchanged)
138
+ adjusted_score = Killed / (Killed + (Survived - Accepted) + NoCoverage)
139
+ ```
140
+
141
+ **JS/TS cross-reference.** On a JS/TS (Stryker) run with
142
+ `--skip-static-mutants` active, accepted survivors also include the
143
+ `--accepted-static-survivors --skip-static` output — fold those entries into this
144
+ table and computation; see [Static-mutant
145
+ skip](../skills/mutation-testing/references/languages/javascript-stryker.md#static-mutant-skip-skip-static-mutants)
146
+ in `javascript-stryker.md`.
147
+
148
+ ## Shard pipeline exit codes (unattended-CI callers read this)
149
+
150
+ `stryker_shard_pipeline.py main()`'s exit code is the CI contract for the
151
+ unattended sharded pipeline — a caller that only checks "zero or non-zero"
152
+ misses the difference between "fix it" and "re-run, nothing to fix." Full
153
+ vocabulary, in priority order:
154
+
155
+ | Exit code | Meaning | Triggered by |
156
+ | --- | --- | --- |
157
+ | `0` | Fully clean. No shard failed, and none of the three outcomes below fired. | — |
158
+ | `1` | One or more shards failed outright. Highest priority — takes precedence over every outcome below. | Stryker itself failed/timed out on a shard, or `launch_survivor_fix` returned `FixOutcome(ok=False, ...)` for a file (any non-zero, non-5 per-file exit — most commonly `EXIT_REVERT_FAILED`, `4`). |
159
+ | `5` (`EXIT_GENERATION_EXHAUSTED`) | No shard failed, but at least one "a survivor was not addressed this run" outcome fired (#1951). | Any of: `exhausted` non-empty (a true `GenerationExhausted` — a fully spent retry-then-downgrade budget — or any other clean `RuntimeError` such as a generation timeout); `unresolved` non-empty (a survivor whose test file never resolved via the naming convention); `no_report` non-empty (a shard Stryker produced no report for at all). |
160
+
161
+ `--skip-existing`/`--max-age-hours`-skipped shards are a **fourth**,
162
+ non-exit-code-affecting outcome: they always get a `SKIPPED shards (N)` line
163
+ in `print_summary`'s output, but never change the exit code — resuming past
164
+ an existing report is expected operator behavior, not a signal to act on.
165
+
166
+ Before #1951, only the `exhausted` case got run-level visibility; a shard
167
+ where zero survivors resolved a test file, or a shard with no Stryker report
168
+ at all, both returned exit `0` — identical to a fully clean run with zero
169
+ fix attempts made. `print_summary`'s output now also carries
170
+ `UNRESOLVED test file (N)` and `NO REPORT shards (N)` lines alongside the
171
+ existing `EXHAUSTED files (N)` line, each naming the affected
172
+ `shard/source` (or bare `shard`, for `no_report`/`skipped`) entries.
173
+
174
+ ## Shard vs full-run scores are not comparable
175
+
176
+ Scoped per-file ("shard") runs produce far higher timeout rates than full runs
177
+ (observed: 99.7% apparent kill rate on one shard; 261/344 were timeouts). Use
178
+ **scoped runs** for per-file survivor analysis and the development loop; use a
179
+ **full run** (coverage-analysis off) only for the authoritative gate score. Label
180
+ every score with its scope and **prohibit cross-scope comparison** — never present
181
+ a shard score as if it were the gate score.
182
+
183
+ ## Every generated test asserts a specific value
184
+
185
+ This is a **generation** rule — yours to enforce, not the loop's. Tests that only
186
+ assert `response.StatusCode == 200` (or any status-code-only check) cannot kill
187
+ String, Equality, ObjectInit, or LogicalNot mutations. **Every generated test must
188
+ include at least one specific value assertion** on a response field, return value,
189
+ or observable state change — not just a status code or a truthiness check.
190
+
191
+ ## Target mutation types in priority order
192
+
193
+ **Cluster survivors by source line before applying the priority order below.** Group survivors by calling
194
+ `survivors_by_line()` in `mutation_report.py` (or `python3 "${CLAUDE_PLUGIN_ROOT}/skills/mutation-testing/scripts/mutation_report_cli.py" --survivors-by-line`) rather than
195
+ re-deriving the grouping and sort yourself — its `clusters` key holds one entry per source line, sorted by
196
+ survivor count descending, ties broken by line number ascending; no adjacent-line merging is performed,
197
+ even for clusters on adjacent lines sharing one expression (your own judgment call, not the tool's).
198
+ Design one test per cluster where feasible, rather than defaulting to one test per mutant. Only after
199
+ clustering, apply the mutation-type priority order within and across clusters. A survivor with no
200
+ resolvable source line forms no cluster — it lands in the `unclustered` list instead, handled one-test-per-mutant. `survivors_by_line()`/its CLI wrapper reads Stryker/Stryker.NET's native JSON report shape only — for mutmut/pitest/go-mutesting reports this function is not yet wired up.
201
+
202
+ When you generate, group survivors by mutation type and write tests in this order:
203
+
204
+ | Priority | Type | How to kill |
205
+ | --- | --- | --- |
206
+ | 1 (easy) | String | Assert the exact string value from source |
207
+ | 1 (easy) | ObjectInit (`new Foo {}`) | Assert ≥ 2 specific non-default fields |
208
+ | 1 (easy) | Equality | Assert the boundary value; pair with one-off |
209
+ | 2 (medium) | LogicalNot / Negate | Paired tests — one per branch |
210
+ | 2 (medium) | Boolean | Test both the true and false paths |
211
+ | 3 (hard) | Statement | Exercise the code path with inputs that reach that line |
212
+ | 3 (hard) | Block removal | Requires meaningful code-path coverage |
213
+ | 4 (very hard) | Guard / structural | Direct invocation with invalid input at the guarding call site |
214
+
215
+ **Statement and Block survivors require a missing code path to be added — not a
216
+ stronger assertion on an existing test.** Do not ask the model to kill Statement
217
+ or Block mutations by strengthening assertions; they need a new test that
218
+ exercises the unreached path. Generate the easy types first and stop offering
219
+ assertion-only fixes once you reach Statement/Block.
220
+
221
+ ## Speed: scoped + per-test coverage analysis
222
+
223
+ The loop's scoped config sets per-test coverage (Stryker `coverageAnalysis: "perTest"`; pitest `withHistory`) so each mutant runs only its covering tests, not the full suite (observed 10–50× speedup). Scoped+per-test is the dev loop; the full run (coverage-analysis off) is the CI gate only. mutmut has **no** per-test coverage equivalent — every mutant runs the entire `--runner` command — so scoping `--runner` itself to the smallest exercising test file is the only speed lever available for Python.
224
+
225
+ ## Fresh build before a run
226
+
227
+ Every mutation run assumes fresh binaries. A stale build produces phantom
228
+ failures — Stryker either aborts on load or reports every mutant as `Survived`,
229
+ and both the failures and the kills are meaningless. Ensure a fresh build before
230
+ Round 1 (and again after every source edit outside the loop):
231
+
232
+ ```
233
+ dotnet build <SOLUTION> -c Debug --nologo # or the language equivalent
234
+ ```
235
+
236
+ If the build fails, **stop** — do not proceed to any round. **Never use
237
+ `--no-build` on the mutation run.** Stryker instruments the build; `--no-build`
238
+ runs against whatever binary happens to be on disk.
239
+
240
+ ## Infrastructure exclusion detection (before the loop starts)
241
+
242
+ After `mutation_report.py` parses the baseline report — and before the file-by-file
243
+ loop — read its counts to find files that are almost certainly infrastructure — DI
244
+ wiring, exception handlers, middleware, generated code — where mutations cannot be
245
+ killed by the available test surface. This judgment is **yours**; the script only
246
+ supplies the score and counts. Two signals, **in combination, alone** are
247
+ sufficient to flag a file — no filename match required:
248
+
249
+ - `score < 15%`
250
+ - `NoCoverage > 50%` of effective mutants (total − Ignored − CompileError)
251
+
252
+ **Failing either numeric signal alone must never trigger the question.** Both
253
+ must hold before a file is even considered for the batched confirmation below.
254
+
255
+ A filename match against one of these known DI/wiring/generated-code
256
+ conventions is a **named hint**, not a requirement — it strengthens the
257
+ confirmation wording for that file but is never itself sufficient, and its
258
+ absence never blocks the question when both numeric signals hold:
259
+
260
+ ```
261
+ Startup.cs Program.cs *Filter.cs
262
+ *Middleware.cs *Logger*.cs *HealthCheck*.cs
263
+ *.Designer.cs *Module.cs *Container.cs
264
+ *Registration.cs *Bootstrap*.cs *DependencyInjection*.cs
265
+ ```
266
+
267
+ Once both numeric signals hold for one or more files, ask **once, batched for
268
+ the whole scan**, itemizing each flagged file with its specific trigger
269
+ reason — named convention when the filename matches, signal-only otherwise:
270
+
271
+ ```
272
+ Are these mutations in DI registration, exception handlers, middleware, or
273
+ generated code that this test surface cannot reach?
274
+
275
+ <file1> — named convention: *Module.cs (score <n>%, NoCoverage <n>%)
276
+ <file2> — signal-only: score <n>%, NoCoverage <n>% (no filename match)
277
+ ```
278
+
279
+ - **Yes** → add the file to the `mutate` exclusion list with a documented reason
280
+ and log:
281
+
282
+ ```
283
+ EXCLUDED <file> — <reason>: <mutation types> are equivalent in <test surface>
284
+ ```
285
+
286
+ - **No** → keep in scope; the file's poor score is real coverage debt, not
287
+ infrastructure.
288
+
289
+ This is the same `EXCLUDED` log format used for the [structurally unkillable
290
+ files](#structurally-unkillable-files) section — a single audit trail either way.
291
+
292
+ ## Baseline reuse for Round 1 (all `--concurrency` values)
293
+
294
+ The pre-loop baseline scan that [Infrastructure exclusion
295
+ detection](#infrastructure-exclusion-detection-before-the-loop-starts) above
296
+ already reads can also seed a file's Round 1 — skipping a redundant fresh
297
+ scoped run — when the baseline is still fresh for that file.
298
+
299
+ **Scope: all `--concurrency` values.** Every `--concurrency` worktree
300
+ resolves the baseline report and the tracking file at the main checkout's
301
+ absolute path — resolved once via `git rev-parse --show-toplevel` before any
302
+ worktree is created — rather than a path relative to the worktree's own cwd.
303
+ No code change was needed for this: `resolve`/`mark-consumed` never join
304
+ `--tracking`/`--report` relative to the script's own location, only to the
305
+ caller-supplied `--cwd` or CWD, so an absolute path from any worktree behaves
306
+ identically to a same-directory invocation.
307
+
308
+ **Canonical paths** — the baseline report:
309
+ `StrykerOutput/baseline/reports/mutation-report.json` (per-tool equivalent per
310
+ the [per-language translation](#per-language-translation) table's own "Native
311
+ report" mapping, matching the already-documented `-O StrykerOutput/baseline`
312
+ named-run convention); the consumption-tracking file (sibling to
313
+ `StrykerOutput/mutation-kill-convergence.json`):
314
+ `StrykerOutput/mutation-kill-baseline-consumption.json`.
315
+
316
+ **No baseline report at the canonical path** — skip `resolve` entirely; every
317
+ file's Round 1 runs fresh, exactly as today.
318
+
319
+ **Capture commit.** Once, right when the pre-loop baseline scan completes,
320
+ record `git rev-parse HEAD` as the capture commit and hold it only for the
321
+ rest of this invocation — it is not persisted to a separate file.
322
+
323
+ **Per file, before that file's Round 1** (never batched):
324
+
325
+ ```
326
+ python3 mutation_baseline_reuse.py resolve --file <path> \
327
+ --capture-commit <capture-sha> \
328
+ --tracking <abs-tracking-path>
329
+ ```
330
+
331
+ `eligible: true` → seed Round 1 via `--report <abs-baseline-report-path>`
332
+ instead of a fresh scoped run. `eligible: false` → Round 1 runs fresh,
333
+ unchanged from today.
334
+
335
+ **Immediately after that file's round concludes** (per file, not batched at
336
+ the end of the invocation), when the file was baseline-seeded:
337
+
338
+ ```
339
+ python3 mutation_baseline_reuse.py mark-consumed --file <path> \
340
+ --capture-commit <capture-sha> \
341
+ --tracking <abs-tracking-path>
342
+ ```
343
+
344
+ **`<abs-tracking-path>` above must be the main checkout's absolute path** —
345
+ not `StrykerOutput/mutation-kill-baseline-consumption.json` relative to the
346
+ current `--concurrency` worktree's own cwd. The same applies to
347
+ `<abs-baseline-report-path>`, the `--report` value fed to Round 1's seed when
348
+ `eligible: true`: it must be the main checkout's absolute path to
349
+ `StrykerOutput/baseline/reports/mutation-report.json`, not a worktree-relative
350
+ one. `mark-consumed` calls from concurrent worktrees are now
351
+ interprocess-locked (via `atomic_state.locked_state(strict=True)`) and safe
352
+ to run without agent-side serialization — but only across *different* files:
353
+ the lock protects the tracking file's write integrity, not double-resolve of
354
+ the same file from two workers concurrently, so each file must still be
355
+ assigned to exactly one worker per run.
356
+
357
+ **Check its `success` field.** On `success: false`, print an operator-visible
358
+ warning naming the file and the `error` reason before continuing to the next
359
+ file — a `mark-consumed` failure is never silently absorbed into a
360
+ successful-looking summary.
361
+
362
+ Once the `--all` run concludes, print the run-level summary:
363
+
364
+ ```
365
+ baseline: seeded N, ran-fresh M, mark-failed K
366
+ ```
367
+
368
+ `seeded` counts baseline-seeded files, `ran-fresh` counts every file whose
369
+ Round 1 ran fresh (no baseline present, or ineligible), and `mark-failed`
370
+ tallies the `mark-consumed` warnings above.
371
+
372
+ ## Pre-loop feasibility gate (xunit.v3 shim-first)
373
+
374
+ On **xunit.v3** the loop is viable only through the v2 shim, because it re-runs mutation every round and that is affordable only with **per-test** coverage. Prove per-test capture works before entering — measured, not assumed. Plain xunit.v2 / other stacks skip this gate. Steps: (1) run [`xunit_v3_feature_detector.py --json`](../skills/mutation-testing/scripts/xunit_v3_feature_detector.py) and feed its output straight into the arbiter (`--v3-findings-json`) — the arbiter, not you, assembles the **always-ask** operator gate (#1160/#1791) from it; (2) build the shim and run **one timed one-file probe** under `coverage-analysis: perTest`, scanning its output for the #1157 capture-failure signal; (3) arbitrate with [`mutation_feasibility_gate.py`](../skills/mutation-testing/scripts/mutation_feasibility_gate.py) (`--probe-seconds --scope-files [--project] --v3-findings-json [--capture-failed] [--shim-declined]`). **`--v3-findings-json` is effectively required here** (#1870): every call into this gate is already on an xunit.v3 project by this section's own convention, so omitting it forces `ask-operator` instead of silently entering the loop — always run step (1) before step (3). **`enter-loop`** → proceed to the scripted loop.
375
+
376
+ **When the arbiter returns `ask-operator` with a `question` payload, present it — do not summarise it away.** Its `question_text` is ready to read out: what is blocking (per construct, per file, with coverage impact) plus the four options — **port**, **exclude**, **skip**, **degrade** — each with its tradeoff. The operator picks; you never pick for them, and in particular never take `degrade` on their behalf because it looks cheap. Pass `--shim-declined` only *after* the operator has actually chosen `degrade`. The same gate is enforced independently by the `stryker_xunit_shim_guard.py` PreToolUse hook, which blocks `dotnet-stryker` against that project until the choice is recorded — see the [stryker-xunit-v2-shim skill](../skills/stryker-xunit-v2-shim/SKILL.md), Step 1a.
377
+
378
+ **`degrade` is unconditional only for the two hard blockers.** A declined shim (#1160) or a failed per-test capture probe (#1157) — alone or together — make the loop infeasible regardless of timing, so neither ever asks: run a single advisory `/mutation-testing` pass with `coverage-analysis: off` and record the waiver verbatim: *"mutant-kill loop not feasible on this suite (xunit.v3); ran single-pass advisory instead."*
379
+
380
+ **`ask-operator` is a distinct, third outcome for the budget-only case — a slow estimate is not a hard blocker.** When the shim wasn't declined and capture didn't fail, but the probe-derived round estimate (`probe_seconds × scope files`) exceeds the configured wall-clock budget, do not auto-degrade — ask the operator. Present the confirmation prompt with:
381
+
382
+ - the estimated round duration and the budget, both in **human-readable** form (e.g. "≈42 min" vs. "30 min budget") — never raw seconds;
383
+ - the scope-file count and the per-file probe seconds the estimate was derived from;
384
+ - each choice's concrete consequence: **"proceed anyway"** re-enters the loop for this invocation at the slower pace; **"degrade"** produces a single advisory pass (score only — no mutants killed, no commits this run) and follows the same waiver-recording path as the hard-blocker case above.
385
+
386
+ Echo back which path you are taking — proceeding at the slower pace, or degrading to a single advisory pass — before acting on the operator's answer. A reply matching neither documented choice is **re-asked** with the same two choices restated; never default or guess at an off-script answer. In a non-interactive session (no usable TTY / no operator available), default to `degrade` — the reversible, cheap choice — and log the auto-decision the same way the repo's other non-interactive defaults are logged (state it plainly in run output, not only recorded to a file).
387
+
388
+ **Never grind for hours; never fabricate a score.**
389
+
390
+ ## The loop is scripted — invoke it, don't re-run its steps by hand
391
+
392
+ `mutation_kill_loop.run_for_file` drives the per-file loop deterministically:
393
+ scoped Stryker run (through the wrapper) → `mutation_report.py` scoring → survivor
394
+ check → **your** generation hook → guarded insertion → build → scoped test → commit
395
+ on green. You supply the `generate` callable and read its per-round log; the loop
396
+ owns everything mechanical:
397
+
398
+ - **Duplicate detection.** Before inserting, the loop extracts every test-method
399
+ name from the existing file and the generated block; if any name collides it
400
+ logs a warning and **stops the round without inserting** — it never renames or
401
+ corrupts the file. Stop cleanly.
402
+ - **Guarded insertion.** New methods go before the test class's closing brace. The
403
+ heuristic supports conventional block-namespace, 4-space-indented C#; for a
404
+ file-scoped namespace or non-standard indentation it **refuses** rather than
405
+ append into a structurally wrong location (broader C# styles are a documented
406
+ limitation).
407
+ - **Verify + revert.** The loop builds, then runs the scoped test class. If the
408
+ build or the scoped test run fails after insertion it reverts
409
+ (`git checkout -- <test-file>`), logs the failure, and stops the file — never
410
+ leaving a broken or non-compiling test file behind. A commit failure gets the
411
+ matching **unstage + restore** revert (`git reset -q HEAD -- <test-file>` then
412
+ `git checkout -- <test-file>`), because `git add` already staged the file before
413
+ the commit attempt failed — a plain checkout alone would restore from that
414
+ still-staged, still-mutated index, not HEAD. **A revert that itself fails (after
415
+ any of these three failure kinds) is fatal**, not silently absorbed: the loop
416
+ raises and aborts the file rather than continuing with the working tree in an
417
+ unknown state (#1598).
418
+ - **No-improvement exit.** A round whose `survivor_count >= prev_survivor_count` does not
419
+ reduce survivors, so the loop stops that file. This mandatory exit is what keeps
420
+ the loop from looping forever chasing the same survivors — never loop
421
+ indefinitely.
422
+
423
+ Commits carry a structured message citing round number, method count, and survivor
424
+ count. `--report` seeds round 1 from an existing report instead of a fresh
425
+ scoped run — manually via the flag, or automatically via [baseline
426
+ reuse](#baseline-reuse-for-round-1-all---concurrency-values) above.
427
+
428
+ ## Per-language translation
429
+
430
+ The loop's C# path is scripted; the table below is the generation + verification
431
+ contract per language.
432
+
433
+ | Language | Tool | Per-test flag | Test shape | Build verify | Test verify |
434
+ | --- | --- | --- | --- | --- | --- |
435
+ | JS/TS | Stryker | `coverageAnalysis: "perTest"` | `test('…', async () => { … })` (Vitest/Jest) | `npm run build` (if present) | `npm test -- --testPathPattern=<file>` |
436
+ | Java | pitest | `withHistory` | `@Test void …()` (JUnit 5) | `mvn compile -pl <mod> -q` | `mvn test -pl <mod> -Dtest=<class>` |
437
+ | C# | Stryker.NET | `coverage-analysis: perTest` | `[Fact]` (xUnit) / `[Test]` (NUnit) | `dotnet build <proj> --nologo` | `dotnet test <proj> --filter FullyQualifiedName~<class>` |
438
+ | Go | go-mutesting | (advisory; no per-test analysis) | `func Test…(t *testing.T)` | `go build ./…` | `go test -run Test… ./…` |
439
+ | Python | mutmut | (none — no per-test coverage analysis; mutmut always runs the full scoped test command per mutant) | `def test_…():` (pytest, flat top-level function) | `python3 -m py_compile <file>` | `python3 -m pytest <file> -q` |
440
+
441
+ ### Per-language prompt rules (for the generation call)
442
+
443
+ - **JS/TS** — match the existing `describe`/`it`/`test` nesting; use the project's assertion library (Jest/Vitest `expect`, Chai `.should`); add no new imports unless already present in the test file.
444
+ - **Java** — match `@Test` + the assertion library in the file (AssertJ / JUnit / Hamcrest); match the fixture lifecycle (JUnit 5 / TestNG); no new `import` for already-imported classes.
445
+ - **C#** — match `[Fact]`/`[Test]`; reuse the file's assertion library (FluentAssertions / AwesomeAssertions / NUnit `Assert`), mock library (Moq / NSubstitute), and fixture pattern (AutoFixture / builder).
446
+ - **Go** — prefer table-driven tests; use `testify/assert` if already present, else stdlib `t.Errorf`; add no new package imports without checking `go.mod`.
447
+ - **Python** — match the existing file's plain `assert` style (or `pytest.approx`/`pytest.raises`/`monkeypatch` when already used); flat top-level `def test_*():` functions only — no class wrapper (`mutation_kill_loop_python.py`'s insertion heuristic appends at end-of-file and refuses on a class-based test file); no new imports unless already present.
448
+
449
+ ## Structurally unkillable files
450
+
451
+ When a file's remaining survivors are structural guards (null-checks, precondition
452
+ throws, builder guards) killable only by passing invalid input directly to the
453
+ constructor/method — and the available test surface (e.g. HTTP-layer tests) cannot
454
+ reach them — **exclude the file from the mutation denominator** rather than
455
+ manufacturing a falsely high score. This is your judgment, not the loop's. Record
456
+ the exclusion in this format:
457
+
458
+ ```
459
+ EXCLUDED <file> — <reason>: surviving mutations are structural guards reachable
460
+ only by direct invalid-input invocation; available test surface is <surface>.
461
+ ```
462
+
463
+ ### Structurally untestable WITHOUT refactoring
464
+
465
+ Three patterns are unkillable by the test suite as it stands — do not spend
466
+ rounds attacking them. Log each as technical debt using the `EXCLUDED` format
467
+ above and move on.
468
+
469
+ 1. **`#if DEBUG` / `#if RELEASE` compilation blocks.** The code under test
470
+ doesn't exist in the test build; mutations live in Release-only code while
471
+ the test suite always hits the Debug path.
472
+
473
+ ```
474
+ EXCLUDED <file>::<method> — #if DEBUG block; mutations are Release-only
475
+ ```
476
+
477
+ 2. **Service-locator pattern (`HttpContext.RequestServices.GetService<T>()`).**
478
+ Cannot inject mocks without constructing a full `IServiceProvider` per test.
479
+ Kills require refactoring to constructor injection.
480
+
481
+ ```
482
+ EXCLUDED <file> — service-locator pattern; requires refactor to
483
+ constructor injection before mutations become testable
484
+ ```
485
+
486
+ 3. **Pure DI registration (`services.AddX()`, `builder.Services.AddX()`).**
487
+ The test host's `TestStartup` / `TestServer` overrides the real DI
488
+ container, so removing a real registration is invisible to any test using
489
+ test doubles. Exclude the whole file from the `mutate` glob.
490
+
491
+ ```
492
+ EXCLUDED <file> — pure DI registration; TestStartup overrides the
493
+ container so mutations are unobservable to the test surface
494
+ ```
495
+
496
+ Never spend rounds trying to kill these — they inflate the round count and
497
+ produce zero kills.
498
+
499
+ ## Convergence history across --all invocations
500
+
501
+ After each file's per-file loop concludes during an `--all` run, write or update
502
+ one entry for that file in `StrykerOutput/mutation-kill-convergence.json` (in the
503
+ target repo, alongside the other `StrykerOutput/` artifacts):
504
+
505
+ ```json
506
+ { "file": "<path>", "status": "converged", "reason": null, "commit": "<sha>" }
507
+ ```
508
+
509
+ Entry shape: `file` (path, matches the mutate-glob entry), `status`
510
+ (`"converged"` or `"excluded"`), `reason` (string for `"excluded"`, `null` for
511
+ `"converged"`), `commit` (the SHA of `HEAD` at the moment the entry is written).
512
+
513
+ Two write triggers, each tied to an existing point in the loop:
514
+
515
+ - **Converged** — the loop's `survivors == 0` exit writes or updates the file's entry with `status: "converged"`, `reason: null`, and the current commit SHA. On JS/TS with `--skip-static-mutants` active, this reads the unfiltered report count, never the generation-filtered list — see [Static-mutant skip](../skills/mutation-testing/references/languages/javascript-stryker.md#static-mutant-skip-skip-static-mutants).
516
+ - **Excluded** — a confirmed [infrastructure exclusion](#infrastructure-exclusion-detection-before-the-loop-starts)
517
+ or [structurally-unkillable exclusion](#structurally-unkillable-files) writes
518
+ or updates the file's entry with `status: "excluded"`, the same `reason` text
519
+ used in the `EXCLUDED <file> — <reason>` log line, and the current commit SHA.
520
+
521
+ ### Reading convergence history: staleness check and glob-shrinking
522
+
523
+ On a fresh `--all` invocation, read `StrykerOutput/mutation-kill-convergence.json`
524
+ **before the baseline scan** (before [infrastructure exclusion
525
+ detection](#infrastructure-exclusion-detection-before-the-loop-starts) runs). For
526
+ each entry, compare its recorded `commit` against the file's current
527
+ last-commit SHA (`git log -1 --format=%H -- <file>`):
528
+
529
+ - **Still valid** (recorded `commit` == current last-commit SHA) — this holds
530
+ **identically for both `"converged"` and `"excluded"` entries**, regardless of
531
+ status: append `"!<file>"` to the baseline `--mutate` glob and skip the file in
532
+ the per-file loop entirely. Log one of:
533
+
534
+ ```
535
+ SKIPPED <file> — already converged at <sha>
536
+ SKIPPED <file> — excluded: <reason>
537
+ ```
538
+
539
+ (matching the existing `EXCLUDED <file> — <reason>` file-first log convention).
540
+ Only the log-line wording differs between the two statuses — the glob-shrinking
541
+ and skip behavior are identical.
542
+ - **Stale** (recorded `commit` != current last-commit SHA) — the file changed
543
+ since it was recorded. Drop the stale entry and include the file in scope as
544
+ normal, exactly as if no entry existed.
545
+
546
+ Once the baseline scan completes, print a run-level summary:
547
+
548
+ ```
549
+ convergence: skipped N (already converged/excluded), testing M
550
+ ```
551
+
552
+ This mirrors the existing `mutation-history.json` reuse rule in
553
+ [`quality-targets-converge/SKILL.md`](../skills/quality-targets-converge/SKILL.md),
554
+ which requires the analogous summary line for
555
+ the same reason: without that line, the reuse rule is invisible and the operator
556
+ can't tell whether the convergence-history mechanism actually paid off.
557
+
558
+ **Distinct from `--since`.** This mechanism is complementary to, not a
559
+ replacement for, the existing `--since` incremental-run pattern (see
560
+ [`csharp-stryker-net.md`](../skills/mutation-testing/references/languages/csharp-stryker-net.md#incremental-runs-with-since)).
561
+ `--since` answers "did this source file change vs. a git ref," which cannot
562
+ express "this file's mutant set already converged under `mutation-kill`" — a file
563
+ can be unchanged since `main` yet never have been scoped by `mutation-kill` at
564
+ all. Both mechanisms can narrow the same shard config's `mutate` glob
565
+ simultaneously.
566
+
567
+ ## Tiered mutation-level (Stryker.NET only)
568
+
569
+ The baseline `--all` scan runs at `--mutation-level Basic`. A file whose
570
+ Basic-level rounds reach `survivors == 0` is done — no Standard-level pass, and
571
+ no change from today's convergence-history write.
572
+
573
+ A file whose Basic-level rounds stop via the no-improvement or `--max-rounds`
574
+ exit with `survivors > 0` logs:
575
+
576
+ ```
577
+ ESCALATING <file> — Standard pass: N survivors remaining after Basic
578
+ ```
579
+
580
+ and gets **one** additional pass at `--mutation-level Standard`, scoped via
581
+ `--mutate` to just that file only, to surface the pickier operators
582
+ (`LinqMutation`, `StringMutation`, etc.) that `Basic` doesn't generate.
583
+
584
+ If that Standard-level pass itself stops (no-improvement / `--max-rounds`) with
585
+ `survivors > 0`, the file is left in scope with **no convergence-history entry**
586
+ written — per the [convergence-history write triggers](#convergence-history-across---all-invocations),
587
+ only `survivors == 0` or an explicit exclusion writes an entry. The file is
588
+ simply re-attempted from Basic on the next `--all` invocation, the same as any
589
+ other never-converged file today.
590
+
591
+ ### CompileError trap during escalation
592
+
593
+ A file that hits the known Standard-level `CompileError` trap during its
594
+ escalation pass — the same "[Caching / key-building classes under
595
+ `mutation-level: Standard`](../skills/mutation-testing/references/languages/csharp-stryker-net.md#probe-file-selection--c-specific-traps)"
596
+ plume documented in `csharp-stryker-net.md` (`LinqMutation`/`StringMutation`
597
+ operators generating calls to methods that don't exist, producing 1000+
598
+ `CompileError` mutants) — drops back to Basic-only results and logs an
599
+ `EXCLUDED` line, not a retry loop:
600
+
601
+ ```
602
+ EXCLUDED <file> — Standard-level CompileError trap: LinqMutation/StringMutation
603
+ operators produced non-compiling mutants; retaining Basic-level results
604
+ ```
605
+
606
+ ### Concurrency cross-reference
607
+
608
+ The Stryker.NET wrapper's `--stryker-concurrency` flag (env:
609
+ `STRYKER_MUTANT_CONCURRENCY`) defaults Stryker's own mutant-testing-process
610
+ count to `cores − 2` (`max(1, cpu_count - 2)`) — see
611
+ [`csharp-stryker-net.md`](../skills/mutation-testing/references/languages/csharp-stryker-net.md#concurrency-default).
612
+ This is a **different dial** from mutation-kill's own `--concurrency` flag
613
+ (worktree fan-out, default 1, above), and the difference is what each one
614
+ *costs*. `--stryker-concurrency` is genuine **process** concurrency priced in
615
+ CPU — which is why `cores − 2` is the right bound for it. `--concurrency` is an
616
+ **agent-level actor count** priced in tokens, where cores do not govern.
617
+ `--stryker-concurrency` is unrelated to and unchanged by this default.
618
+
619
+ ## Parallelism
620
+
621
+ With `--all`, files run **sequentially by default** — `--concurrency` defaults
622
+ to **1**. Each worktree runs an independent mutation-kill loop, so raising it
623
+ raises the concurrent *agent* count, not just CPU load: fan-out never *saves*
624
+ tokens, it trades them for wall-clock (#1515) — the same default the build
625
+ skill already applies to the same class of decision. Opt in when
626
+ wall-clock matters more than spend, bounding `n` by the **token budget** for
627
+ the run, not by core count; physical cores − 2 is a machine-capacity ceiling on
628
+ top of that budget decision, never the thing that picks `n`. For unattended CI,
629
+ `stryker_shard_pipeline.py` provides the compounding-worktree,
630
+ forced-`--headless` alternative described above.
631
+
632
+ ### Sub-agent fan-out within a file (`--parallel`)
633
+
634
+ `--concurrency` fans **files** out across git worktrees. `--parallel <n>` fans
635
+ **sub-agents** out **within** a file's Phase-4 survivor set, using the Agent
636
+ tool directly — no worktrees, because test-file writes don't conflict with
637
+ source-file reads. The two flags are orthogonal, and this fan-out is an
638
+ agent-orchestration step (spawning generation sub-agents), not a scripted one.
639
+
640
+ With `--all --parallel <n>`:
641
+
642
+ 1. Sort files by survivor count (descending); cap at the first `4 × n`
643
+ candidates.
644
+ 2. Group into `n` batches of up to 4 files each.
645
+ 3. Spawn `n` sub-agents in parallel via the Agent tool. Each sub-agent reads
646
+ its files' survivor lists from the baseline JSON, clusters them by
647
+ source line (per [above](#target-mutation-types-in-priority-order)),
648
+ and targets mutation types in the priority order within and across
649
+ clusters (String → ObjectInit → Equality → Negate → Conditional →
650
+ Statement).
651
+ 4. Synthesize results at the barrier; if survivors still exceed the round's
652
+ threshold, repeat with the next batch.
653
+
654
+ `--parallel` has **no default** — off unless the operator asks, and turning it
655
+ on is a wall-clock-for-tokens trade, not a free speedup. Once opted in, the
656
+ *ceiling* per batch is **3–4** agents for easy mutation types (String /
657
+ Equality / ObjectInit) and **1–2** for hard types (Statement / Block removal) —
658
+ an upper bound on what the work tolerates, not a target to run at. Easy types
659
+ tolerate more concurrent test edits because each survivor is fixed by an
660
+ independent assertion; hard types require code-path additions where two
661
+ concurrent edits to the same test class collide.
662
+
663
+ ### Interaction with `--concurrency`
664
+
665
+ `--concurrency` governs the **outer** worktree fan-out (files × worktrees) and
666
+ `--parallel` the **inner** Agent-tool fan-out (sub-agents per Phase-4 batch).
667
+ Both default to sequential, so the effective actor count is **1 unless the
668
+ operator opts into both**. When both are set it is the product (`concurrency ×
669
+ parallel`), every actor an independent agent burning tokens — so the product is
670
+ a **token-budget** decision first. Physical cores − 2 remains a machine-capacity
671
+ ceiling: fail fast when the product exceeds it rather than oversubscribing.
672
+ Passing that check does not make a large product correct, only hostable.
673
+
674
+ ## Go is advisory
675
+
676
+ go-mutesting is alpha-quality and has no per-test coverage analysis. For Go,
677
+ `mutation-kill` runs in **advisory** mode: it logs survivors and the generated
678
+ tests but **does not commit** — the operator applies them manually. Pair with
679
+ `go test -fuzz` for boundary discovery (see `skills/mutation-testing/references/languages/go-go-mutesting.md`).
680
+
681
+ ## Relationship to other skills
682
+
683
+ - `/mutation-testing` — advisory: runs the tool and classifies survivors for a human. `mutation-kill` is the autonomous loop that drives the count down. Complementary.
684
+ - `/test-upgrade` — may invoke `mutation-kill` during Phase 3 (per-Story) and Phase 4 (`--all` convergence) when the operator opts into autonomous improvement.