@mutagent/helix 0.1.0-alpha.14

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 (357) hide show
  1. package/.claude/skills/mutagent-helix/SKILL.md +113 -0
  2. package/.claude/skills/mutagent-helix/scripts/cli/codex-transcode.ts +143 -0
  3. package/.claude/skills/mutagent-helix/scripts/cli/doctor.ts +111 -0
  4. package/.claude/skills/mutagent-helix/scripts/cli/init.ts +382 -0
  5. package/.claude/skills/mutagent-helix/scripts/cli/run.sh +61 -0
  6. package/CLAUDE.md +193 -0
  7. package/LICENSE +201 -0
  8. package/NOTICE +22 -0
  9. package/README.md +209 -0
  10. package/assets/adl-loop.svg +162 -0
  11. package/assets/system-status.svg +422 -0
  12. package/bin/mutagent-cli.mjs +9950 -0
  13. package/bin/mutagent-helix.mjs +78 -0
  14. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/CLAUDE.md +28 -0
  15. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/SKILL.md +138 -0
  16. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/assets/templates/agentspec.yaml.tpl +247 -0
  17. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/references/frameworks/doc-pins.md +53 -0
  18. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/references/principles.md +91 -0
  19. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/references/requirements.yaml +295 -0
  20. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/references/workflows/orchestrator-protocol.md +302 -0
  21. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/scripts/cli/doctor.ts +116 -0
  22. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/scripts/cli/init.ts +230 -0
  23. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/scripts/cli/run.sh +60 -0
  24. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/scripts/config/resolve-spec-dir.ts +199 -0
  25. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/scripts/contract/agentspec.schema.ts +455 -0
  26. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/scripts/setup/detect.ts +67 -0
  27. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/scripts/validate/validate-spec.ts +93 -0
  28. package/mutagent-agentspec/LICENSE +201 -0
  29. package/mutagent-agentspec/NOTICE +19 -0
  30. package/mutagent-agentspec/README.md +44 -0
  31. package/mutagent-builder/.claude/skills/mutagent-builder/SKILL.md +100 -0
  32. package/mutagent-builder/.claude/skills/mutagent-builder/assets/agents/ai-architect.md +312 -0
  33. package/mutagent-builder/.claude/skills/mutagent-builder/assets/agents/ai-engineer.md +357 -0
  34. package/mutagent-builder/.claude/skills/mutagent-builder/assets/templates/build-report.md.tpl +39 -0
  35. package/mutagent-builder/.claude/skills/mutagent-builder/references/principles.md +31 -0
  36. package/mutagent-builder/.claude/skills/mutagent-builder/references/workflows/build-protocol.md +61 -0
  37. package/mutagent-builder/.claude/skills/mutagent-builder/references/workflows/improve-handoff.md +23 -0
  38. package/mutagent-builder/.claude/skills/mutagent-builder/scripts/cli/run.sh +60 -0
  39. package/mutagent-builder/.claude/skills/mutagent-builder/scripts/handoff/validate-build-input.ts +72 -0
  40. package/mutagent-builder/.claude/skills/mutagent-builder/scripts/sync-spec/check-sync-spec.ts +499 -0
  41. package/mutagent-builder/.claude/skills/mutagent-builder/scripts/verify/spec-impl-coverage.ts +182 -0
  42. package/mutagent-builder/CLAUDE.md +25 -0
  43. package/mutagent-builder/README.md +26 -0
  44. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/README.md +192 -0
  45. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/SKILL.md +352 -0
  46. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/agents/ai-architect.md +256 -0
  47. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/agents/ai-engineer.md +344 -0
  48. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/agents/diagnostics-analyzer.md +576 -0
  49. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/agents/discovery.md +425 -0
  50. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/audit.json.tpl +24 -0
  51. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/audit.md.tpl +49 -0
  52. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/config.yaml.tpl +100 -0
  53. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/pr-body.md.tpl +56 -0
  54. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/report.html.tpl +327 -0
  55. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/shared/README.md +27 -0
  56. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/shared/iter-N-handover.md.tpl +125 -0
  57. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/shared/self-diagnosis-contract.v0.1.0.yaml.tpl +234 -0
  58. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/shared/spec.yaml.tpl +152 -0
  59. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/shared/team.yaml.tpl +127 -0
  60. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/shared/wave-N-dashboard.html.tpl +1712 -0
  61. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.1-nl-query.md +59 -0
  62. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.2-tier0-progress.md +58 -0
  63. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.3-analysis-progress.md +44 -0
  64. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.4-html-report.md +61 -0
  65. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.5-rca-detail.md +69 -0
  66. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.6-stale-warning.md +53 -0
  67. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.1-welcome.md +60 -0
  68. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.2-source-platform-picker.md +41 -0
  69. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.3-source-auth.md +75 -0
  70. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.4-target-picker.md +48 -0
  71. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.5-ask-tool.md +43 -0
  72. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.6-config-review.md +57 -0
  73. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.7-filter-defaults.md +52 -0
  74. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.8-first-run.md +59 -0
  75. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/examples/sample-findings.json +92 -0
  76. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/examples/sample-meta.json +47 -0
  77. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/adapter-strategy.md +75 -0
  78. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/config-migration.md +84 -0
  79. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/config.md +159 -0
  80. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/filter-search-matrix.md +66 -0
  81. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/harness-knowledge.md +22 -0
  82. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/memory-format.md +78 -0
  83. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/onboarding-decisions.yaml +187 -0
  84. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/operation-inventory.md +59 -0
  85. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/overview.md +167 -0
  86. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/reference.md +119 -0
  87. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/script-index.md +101 -0
  88. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-adapter-contract.md +93 -0
  89. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-platforms/claude-code-transcripts.md +66 -0
  90. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-platforms/codex-transcripts.md +78 -0
  91. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-platforms/codex.md +145 -0
  92. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-platforms/install-paths.md +57 -0
  93. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-platforms/langfuse.md +178 -0
  94. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-platforms/local-jsonl.md +55 -0
  95. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-platforms/openobserve.md +102 -0
  96. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-platforms/otel.md +63 -0
  97. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/target-platforms/cloud-rest.md +84 -0
  98. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/target-platforms/local-claude.md +65 -0
  99. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/target-platforms/local-cloud-agent-sdk.md +92 -0
  100. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/target-platforms/local-codex.md +72 -0
  101. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/target-platforms/local-cursor.md +108 -0
  102. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/target-platforms/local-mastra.md +77 -0
  103. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/target-platforms/local-opencode.md +70 -0
  104. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/apply-pr-comment-format.md +82 -0
  105. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/diagnostics.md +35 -0
  106. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/handover-contract.md +247 -0
  107. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/onboarding.md +300 -0
  108. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/orchestrator-protocol.md +1861 -0
  109. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/rca.md +331 -0
  110. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/rendering-anatomy.md +314 -0
  111. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/schedule-prep.md +100 -0
  112. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/scope-model.md +128 -0
  113. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/verification-methodology.md +174 -0
  114. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/aggregate/sort-findings.ts +0 -0
  115. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/awareness/blind-spots.ts +167 -0
  116. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/awareness/llm-sample.ts +681 -0
  117. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/cli/doctor.ts +215 -0
  118. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/cli/init.ts +1013 -0
  119. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/cli/install-agents.ts +350 -0
  120. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/cli/run.sh +61 -0
  121. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/cli/shared-templates.ts +79 -0
  122. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/config/load.ts +392 -0
  123. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/config/resolve-credential.ts +120 -0
  124. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/config/schema.ts +641 -0
  125. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/config/validate.ts +134 -0
  126. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/context/build-diagnosis-context.ts +417 -0
  127. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/context/load-context.ts +105 -0
  128. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/contract/types.ts +166 -0
  129. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/enrich/build-render-input.ts +1964 -0
  130. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/enrich/corpus-severity.ts +172 -0
  131. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/enrich/dismissal-match.ts +270 -0
  132. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/enrich/rank-remedies.ts +75 -0
  133. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/hooks/install-hooks.sh +46 -0
  134. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/hooks/pre-push.sh +78 -0
  135. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/invocation/parse-brief.ts +188 -0
  136. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/library/match.ts +114 -0
  137. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/library/paths.ts +95 -0
  138. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/library/store.ts +535 -0
  139. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/library/types.ts +181 -0
  140. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/lint/template-inline-js.ts +267 -0
  141. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/memory/append.ts +188 -0
  142. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/memory/read.ts +218 -0
  143. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/normalize/platforms/entity-context.ts +686 -0
  144. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/normalize/read-unitf.ts +267 -0
  145. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/normalize/trace.ts +1078 -0
  146. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/normalize/unitf-adapter.ts +0 -0
  147. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/normalize/unitf-types.ts +213 -0
  148. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/report/persist-selections.ts +174 -0
  149. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/report/render.ts +3254 -0
  150. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/run/diagnose.ts +64 -0
  151. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/run/session.ts +167 -0
  152. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/sample/caps.ts +345 -0
  153. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/sample/deep-read-gate.ts +424 -0
  154. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/sample/representative.ts +584 -0
  155. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/scan/objection.ts +224 -0
  156. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/scan/trajectory.ts +489 -0
  157. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/self-diagnostics/dispatch.ts +135 -0
  158. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/self-diagnostics/probe.ts +170 -0
  159. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/setup/detect.ts +307 -0
  160. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/setup/ensure-cli.ts +315 -0
  161. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/setup/reconfigure.ts +77 -0
  162. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/setup/verify-agents.ts +207 -0
  163. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/slicer.ts +166 -0
  164. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/source/adapters/claude-code.ts +17 -0
  165. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/source/adapters/codex.ts +11 -0
  166. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/source/adapters/langfuse.ts +17 -0
  167. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/source/adapters/local-jsonl.ts +12 -0
  168. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/source/adapters/otel.ts +12 -0
  169. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/source/index.ts +54 -0
  170. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/source/registry.ts +45 -0
  171. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/source/types.ts +86 -0
  172. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/stale-detector.ts +74 -0
  173. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/test/render-playwright.cli.ts +477 -0
  174. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/tier0/claude-code.ts +133 -0
  175. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/tier0/langfuse.ts +143 -0
  176. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/tier0-scan.ts +423 -0
  177. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/validate/completeness-check.ts +436 -0
  178. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/validate/doc-refs.ts +190 -0
  179. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/validate/finalize-gate.ts +417 -0
  180. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/validate/findings-contract.ts +628 -0
  181. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/validate/render-js-syntax.ts +188 -0
  182. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/validate/report-checklist.yaml +217 -0
  183. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/validate/trace-shape.ts +262 -0
  184. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/validate/wave6-checklist.ts +326 -0
  185. package/mutagent-diagnostics/CLAUDE.md +41 -0
  186. package/mutagent-diagnostics/LICENSE +201 -0
  187. package/mutagent-diagnostics/NOTICE +18 -0
  188. package/mutagent-diagnostics/README.md +343 -0
  189. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/SKILL.md +548 -0
  190. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/assets/agents/audit-executor.md +169 -0
  191. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/assets/agents/dataset-builder.md +160 -0
  192. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/assets/agents/discovery.md +425 -0
  193. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/assets/agents/evaluator.md +1108 -0
  194. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/assets/brand/theme.css +213 -0
  195. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/assets/brand/wordmark.html +9 -0
  196. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/lenses/context-flow-lens.md +85 -0
  197. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/lenses/data-lens.md +47 -0
  198. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/lenses/decision-lens.md +48 -0
  199. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/lenses/methodology-critic-lens.md +53 -0
  200. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/lenses/trajectory-lens.md +44 -0
  201. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/build-review-interface.md +83 -0
  202. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/edd-loop.md +134 -0
  203. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/error-analysis.md +113 -0
  204. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/eval-audit.md +154 -0
  205. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/eval-stage.md +168 -0
  206. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/generate-synthetic-data.md +81 -0
  207. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/grounded-adjudication.md +221 -0
  208. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/memory-format.md +65 -0
  209. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/methodology.md +201 -0
  210. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/operation-inventory.md +197 -0
  211. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/validate-evaluator.md +125 -0
  212. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/workflows/orchestrator-protocol.md +300 -0
  213. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/write-judge-prompt.md +123 -0
  214. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/schemas/behavior-tree.schema.yaml +73 -0
  215. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/schemas/dataset.schema.yaml +66 -0
  216. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/schemas/edd-change-request.schema.yaml +114 -0
  217. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/schemas/eval-matrix.schema.yaml +74 -0
  218. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/schemas/flow-graph.schema.yaml +69 -0
  219. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/schemas/flow-profile.schema.yaml +49 -0
  220. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/schemas/methodology-review.schema.yaml +40 -0
  221. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/schemas/scorecard.schema.yaml +85 -0
  222. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/agent-dispatch.ts +0 -0
  223. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/aggregate-discover.ts +543 -0
  224. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/artifact-paths.ts +115 -0
  225. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/assemble-scorecard.ts +172 -0
  226. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/build-dataset.ts +186 -0
  227. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/build-evals.ts +93 -0
  228. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/build-review-ui.ts +393 -0
  229. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/check-method-router.ts +170 -0
  230. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/aggregate.ts +112 -0
  231. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/audit-run.ts +182 -0
  232. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/doctor.ts +211 -0
  233. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/dogfood.ts +133 -0
  234. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/init.ts +601 -0
  235. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/methodology-review.ts +122 -0
  236. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/prep.ts +295 -0
  237. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/profile-subject.ts +165 -0
  238. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/run.sh +56 -0
  239. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/variance-check.ts +105 -0
  240. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/code-eval.ts +248 -0
  241. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/code-quality-verdict.ts +285 -0
  242. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/codegen-evals.ts +173 -0
  243. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cold-start-project.ts +151 -0
  244. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cold-start-sampler.ts +267 -0
  245. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/config/load.ts +343 -0
  246. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/config/schema.ts +380 -0
  247. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/contracts/agentspec-evals.ts +85 -0
  248. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/contracts/dataset.ts +149 -0
  249. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/contracts/eval-engine.ts +118 -0
  250. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/contracts/eval-matrix.ts +577 -0
  251. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/contracts/eval-types.ts +1074 -0
  252. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/contracts/flow-graph.ts +194 -0
  253. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/contracts/types.ts +303 -0
  254. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/contracts/validation.ts +193 -0
  255. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/derive-dataset.ts +152 -0
  256. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/determine-outcome.ts +219 -0
  257. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/diff-discriminate.ts +160 -0
  258. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/discover-criteria.ts +348 -0
  259. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/edd/change-request.ts +232 -0
  260. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/edd/edd-types.ts +210 -0
  261. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/edd/variance-gate.ts +186 -0
  262. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/emit-completeness.ts +111 -0
  263. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/eval-engine.ts +160 -0
  264. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/evaluate.ts +333 -0
  265. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/flow-graph.ts +230 -0
  266. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/judge-prompt-template.ts +253 -0
  267. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/judge-provider.ts +135 -0
  268. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/lint-grounding.ts +229 -0
  269. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/lint-uniformity.ts +168 -0
  270. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/living-suite.ts +109 -0
  271. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/load-bundle.ts +203 -0
  272. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/load-profile-vocab.ts +64 -0
  273. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/load-profile.ts +106 -0
  274. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/mask.ts +138 -0
  275. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/materialize-dataset.ts +113 -0
  276. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/matrix-judge.ts +750 -0
  277. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/memory/append.ts +215 -0
  278. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/memory/read.ts +168 -0
  279. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/persist-eval-criteria.ts +232 -0
  280. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/prep-tasks.ts +125 -0
  281. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/profile-subject.ts +310 -0
  282. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/publish-report.ts +131 -0
  283. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/read-unitf-traces.ts +81 -0
  284. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/render-build-cards.ts +195 -0
  285. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/render-discover-report.ts +1640 -0
  286. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/render-eval-report.ts +3838 -0
  287. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/render-report.ts +212 -0
  288. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/resolve-credential.ts +110 -0
  289. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/resolve-ref.ts +98 -0
  290. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/result-verify.ts +129 -0
  291. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/route-failures.ts +330 -0
  292. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/run-deterministic.ts +367 -0
  293. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/run-evaluate.ts +719 -0
  294. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/run-judge.ts +155 -0
  295. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/run-pipeline.ts +175 -0
  296. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/sample-traces.ts +210 -0
  297. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/self-audit.ts +387 -0
  298. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/source-map.ts +106 -0
  299. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/subject-profile.ts +134 -0
  300. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/substrate.ts +162 -0
  301. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/sync-eval-criteria.ts +244 -0
  302. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/ui-slots.ts +119 -0
  303. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/unitf-to-evaltrace.ts +284 -0
  304. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/validate-judge.ts +358 -0
  305. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/variance-compare.ts +177 -0
  306. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/subjects/mutagent-diagnostics/behavior-tree.yaml +140 -0
  307. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/subjects/mutagent-diagnostics/eval-matrix.yaml +1270 -0
  308. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/subjects/mutagent-diagnostics/methodology-review.yaml +105 -0
  309. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/workflows/audit.workflow.js +82 -0
  310. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/workflows/data-leak.workflow.js +236 -0
  311. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/workflows/variance.workflow.js +163 -0
  312. package/mutagent-evaluator/CLAUDE.md +45 -0
  313. package/mutagent-evaluator/LICENSE +201 -0
  314. package/mutagent-evaluator/NOTICE +23 -0
  315. package/mutagent-evaluator/README.md +88 -0
  316. package/mutagent-optimize/.claude/skills/mutagent-optimize/SKILL.md +287 -0
  317. package/mutagent-optimize/.claude/skills/mutagent-optimize/scripts/contracts/amend-request.ts +503 -0
  318. package/mutagent-optimize/.claude/skills/mutagent-optimize/scripts/improve-loop-run.ts +304 -0
  319. package/mutagent-optimize/.claude/skills/mutagent-optimize/scripts/loop-state-cli.ts +300 -0
  320. package/mutagent-optimize/.claude/skills/mutagent-optimize/scripts/loop-state.ts +440 -0
  321. package/mutagent-optimize/CLAUDE.md +49 -0
  322. package/mutagent-optimize/README.md +26 -0
  323. package/mutagent-orchestrator/CLAUDE.md +102 -0
  324. package/mutagent-orchestrator/README.md +20 -0
  325. package/mutagent-orchestrator/assets/agents/discovery.md +425 -0
  326. package/mutagent-orchestrator/assets/agents/dogfood-monitor.md +266 -0
  327. package/mutagent-orchestrator/assets/agents/monitor.md +258 -0
  328. package/mutagent-orchestrator/orchestrator.md +782 -0
  329. package/mutagent-orchestrator/references/MONITORING.md +209 -0
  330. package/mutagent-orchestrator/references/config-fields.md +132 -0
  331. package/mutagent-orchestrator/references/config-migration.md +132 -0
  332. package/mutagent-orchestrator/references/index-registry.md +92 -0
  333. package/mutagent-orchestrator/routing.yaml +391 -0
  334. package/mutagent-orchestrator/scripts/config-schema.ts +1010 -0
  335. package/mutagent-orchestrator/scripts/dispatch.ts +439 -0
  336. package/mutagent-orchestrator/scripts/dogfood/extract-feedback.ts +203 -0
  337. package/mutagent-orchestrator/scripts/dogfood/reconstruct-trajectory.ts +327 -0
  338. package/mutagent-orchestrator/scripts/dogfood/render-dogfood-report.ts +347 -0
  339. package/mutagent-orchestrator/scripts/dogfood/resolve-subagents.ts +160 -0
  340. package/mutagent-orchestrator/scripts/dogfood/run-report.ts +264 -0
  341. package/mutagent-orchestrator/scripts/dogfood/slack-thread.ts +106 -0
  342. package/mutagent-orchestrator/scripts/dogfood/types.ts +257 -0
  343. package/mutagent-orchestrator/scripts/eval-routing.ts +753 -0
  344. package/mutagent-orchestrator/scripts/gate.ts +219 -0
  345. package/mutagent-orchestrator/scripts/handover-contract.ts +362 -0
  346. package/mutagent-orchestrator/scripts/index/build-index.ts +351 -0
  347. package/mutagent-orchestrator/scripts/index/render-index.ts +110 -0
  348. package/mutagent-orchestrator/scripts/monitor/slack-notify.ts +111 -0
  349. package/mutagent-orchestrator/scripts/monitor/triggers.ts +162 -0
  350. package/mutagent-orchestrator/scripts/onboarding-check.ts +369 -0
  351. package/mutagent-orchestrator/scripts/render-roster.ts +308 -0
  352. package/mutagent-orchestrator/scripts/resolve-credential.ts +185 -0
  353. package/mutagent-orchestrator/scripts/resolve-paths.ts +114 -0
  354. package/mutagent-orchestrator/scripts/slack/format.ts +63 -0
  355. package/mutagent-orchestrator/scripts/slack/post.ts +115 -0
  356. package/mutagent-orchestrator/scripts/sync-index.ts +311 -0
  357. package/package.json +64 -0
@@ -0,0 +1,173 @@
1
+ /**
2
+ * scripts/codegen-evals.ts — Path B (F14): emit CODE-WRITTEN evals in the target's
3
+ * own language (Type A — PURE string codegen).
4
+ * ---------------------------------------------------------------------------
5
+ * Path B of the EVAL-stage engine fork (eval-engine.ts). For a code-FRAMEWORK
6
+ * target (Mastra/TS, runtime=bun) this emits a SELF-CONTAINED eval-suite source
7
+ * file the user runs DIRECTLY — no Claude-Code sub-agents anywhere (F14):
8
+ *
9
+ * - deterministic CODE-CHECKS (the `codeCheck` helper — objective, no LLM)
10
+ * - an LLM-JUDGE call VIA SDK (the `judgeViaSdk` seam — provider SDK, NOT a
11
+ * CC sub-agent; the user wires their own key)
12
+ * - eval-criteria checks → a per-criterion pass/fail + a gate (runVerdict)
13
+ * - the scorecard JSON written to a DISCOVERABLE output sink.
14
+ *
15
+ * The emitted code reaches back into NOTHING in `.claude/skills/` (it ships INTO
16
+ * the target's repo). This module is PURE string assembly — same input →
17
+ * byte-identical source (no clock / random / network), so the generated suite is
18
+ * itself reproducible. Subject-agnostic: criteria are DATA.
19
+ *
20
+ * Austerity note: this is the Path-B analog of the EV-050 in-house/export seam —
21
+ * it EMITS a provider-calling artifact for the user to run; the DEFAULT
22
+ * agent-dispatch (Path A) path never imports it.
23
+ */
24
+
25
+ /** A criterion to codegen — the minimal Path-B slice (maps from agentspec success_criteria). */
26
+ export interface CodegenCriterion {
27
+ id: string;
28
+ statement: string;
29
+ /** `code-check` → a deterministic check; `llm-judge` → an SDK judge call. */
30
+ type: "code-check" | "llm-judge";
31
+ goal: string;
32
+ }
33
+
34
+ export interface CodegenInput {
35
+ subject: string;
36
+ /** the target runtime ("bun" | "node" | "deno" …) — drives the emitted module style. */
37
+ runtime: string;
38
+ targetFramework: string;
39
+ criteria: CodegenCriterion[];
40
+ /** the discoverable sink the suite writes its scorecard to. */
41
+ outputSink: string;
42
+ }
43
+
44
+ /** JSON-encode a value for safe embedding as a source literal. PURE. */
45
+ function lit(value: unknown): string {
46
+ return JSON.stringify(value);
47
+ }
48
+
49
+ /**
50
+ * Emit a portable, self-contained eval-suite SOURCE file (TS) for the target.
51
+ * Deterministic. THROWS on an empty criteria set or an unknown criterion type
52
+ * (fail-loud — never silently emit a no-op suite or skip a criterion). PURE.
53
+ */
54
+ export function codegenEvalSuite(input: CodegenInput): string {
55
+ if (input.criteria.length === 0) {
56
+ throw new Error(
57
+ "codegenEvalSuite: no criteria — there is nothing to write evals for. " +
58
+ "Materialize criteria from the agentspec.evals.success_criteria first.",
59
+ );
60
+ }
61
+ for (const c of input.criteria) {
62
+ if (c.type !== "code-check" && c.type !== "llm-judge") {
63
+ throw new Error(
64
+ `codegenEvalSuite: unknown criterion type '${String((c as { type: unknown }).type)}' ` +
65
+ `on criterion '${c.id}'. Expected 'code-check' | 'llm-judge'.`,
66
+ );
67
+ }
68
+ }
69
+
70
+ // The criteria are embedded as data; the runner dispatches by `type` at runtime.
71
+ const criteriaLiteral = lit(
72
+ input.criteria.map((c) => ({ id: c.id, statement: c.statement, type: c.type, goal: c.goal })),
73
+ );
74
+
75
+ // NOTE: keep this a single template literal so the codegen is PURE + deterministic.
76
+ // It deliberately contains NO Claude-Code dispatch — the only LLM path is the
77
+ // user-supplied `judgeViaSdk` SDK seam (Path B portability, F14).
78
+ return `/**
79
+ * code-evals.ts — PORTABLE code-written eval suite for ${input.subject}
80
+ * Target: ${input.targetFramework} (runtime: ${input.runtime})
81
+ * GENERATED by mutagent-evaluator (Path B — code-written). Runs WITHOUT Claude Code.
82
+ *
83
+ * Wire two seams to your target:
84
+ * - runAgent(query): call YOUR built ${input.targetFramework} agent → its output.
85
+ * - judgeViaSdk(prompt): call YOUR provider SDK (the LLM judge). NOT a Claude-Code
86
+ * sub-agent — your own key, your own SDK. Returns {result:"pass"|"fail", critique}.
87
+ *
88
+ * Then: \`${input.runtime} run code-evals.ts <dataset.json>\` → writes the scorecard to
89
+ * ${input.outputSink}scorecard.json (the discoverable sink).
90
+ */
91
+
92
+ export interface DatasetCase { id: string; query: string; tuple?: Record<string, string>; }
93
+ export interface CriterionVerdict { criterionId: string; result: "pass" | "fail"; critique: string; }
94
+ export interface Scorecard {
95
+ subject: string;
96
+ perCriterion: Record<string, { pass: number; fail: number }>;
97
+ runVerdict: "pass" | "fail";
98
+ rows: { caseId: string; verdicts: CriterionVerdict[] }[];
99
+ }
100
+
101
+ /** The agentspec-derived criteria (embedded as DATA — subject-agnostic). */
102
+ const CRITERIA: { id: string; statement: string; type: "code-check" | "llm-judge"; goal: string }[] =
103
+ ${criteriaLiteral};
104
+
105
+ // ── seam 1: run YOUR built agent (wire this to your ${input.targetFramework} entrypoint) ──
106
+ export type RunAgent = (query: string) => Promise<{ output: string; trace?: unknown }>;
107
+
108
+ // ── seam 2: your provider-SDK LLM judge (NOT a Claude-Code sub-agent — portable) ──
109
+ export type JudgeViaSdk = (prompt: string) => Promise<{ result: "pass" | "fail"; critique: string }>;
110
+
111
+ /** Deterministic CODE check for an objective criterion (no LLM). Extend per criterion id. */
112
+ export function codeCheck(criterionId: string, output: string): CriterionVerdict {
113
+ // Default code-check: non-empty, well-formed output. Specialize by criterionId as needed.
114
+ const ok = typeof output === "string" && output.trim().length > 0;
115
+ return { criterionId, result: ok ? "pass" : "fail", critique: ok ? "output present" : "empty output" };
116
+ }
117
+
118
+ /** LLM-judge a subjective criterion VIA the user's SDK seam (critique-before-verdict, binary). */
119
+ export async function judgeCriterion(
120
+ judgeViaSdk: JudgeViaSdk,
121
+ criterion: { id: string; statement: string },
122
+ query: string,
123
+ output: string,
124
+ ): Promise<CriterionVerdict> {
125
+ const prompt =
126
+ "Critique FIRST, then a BINARY verdict. Criterion: " + criterion.statement +
127
+ "\\nUser query: " + query + "\\nAgent output: " + output +
128
+ "\\nRespond {critique, result: 'pass'|'fail'}.";
129
+ const { result, critique } = await judgeViaSdk(prompt);
130
+ return { criterionId: criterion.id, result, critique };
131
+ }
132
+
133
+ /** Run the full suite over a dataset → a gate-bearing scorecard. Portable. */
134
+ export async function runEvalSuite(
135
+ dataset: DatasetCase[],
136
+ runAgent: RunAgent,
137
+ judgeViaSdk: JudgeViaSdk,
138
+ ): Promise<Scorecard> {
139
+ const perCriterion: Record<string, { pass: number; fail: number }> = {};
140
+ for (const c of CRITERIA) perCriterion[c.id] = { pass: 0, fail: 0 };
141
+ const rows: { caseId: string; verdicts: CriterionVerdict[] }[] = [];
142
+ for (const dc of dataset) {
143
+ const { output } = await runAgent(dc.query);
144
+ const verdicts: CriterionVerdict[] = [];
145
+ for (const c of CRITERIA) {
146
+ const v =
147
+ c.type === "code-check"
148
+ ? codeCheck(c.id, output)
149
+ : await judgeCriterion(judgeViaSdk, c, dc.query, output);
150
+ perCriterion[c.id][v.result] += 1;
151
+ verdicts.push(v);
152
+ }
153
+ rows.push({ caseId: dc.id, verdicts });
154
+ }
155
+ const anyFail = Object.values(perCriterion).some((p) => p.fail > 0);
156
+ return { subject: ${lit(input.subject)}, perCriterion, runVerdict: anyFail ? "fail" : "pass", rows };
157
+ }
158
+
159
+ /** CLI: \`${input.runtime} run code-evals.ts <dataset.json>\` → write the scorecard to the sink. */
160
+ export async function main(
161
+ datasetPath: string,
162
+ runAgent: RunAgent,
163
+ judgeViaSdk: JudgeViaSdk,
164
+ writeFile: (path: string, body: string) => Promise<void>,
165
+ readFile: (path: string) => Promise<string>,
166
+ ): Promise<Scorecard> {
167
+ const dataset = JSON.parse(await readFile(datasetPath)) as DatasetCase[];
168
+ const scorecard = await runEvalSuite(dataset, runAgent, judgeViaSdk);
169
+ await writeFile(${lit(input.outputSink)} + "scorecard.json", JSON.stringify(scorecard, null, 2));
170
+ return scorecard;
171
+ }
172
+ `;
173
+ }
@@ -0,0 +1,151 @@
1
+ /**
2
+ * scripts/cold-start-project.ts — EV-5.3 the EvalTrace → ColdTrace projection.
3
+ * ---------------------------------------------------------------------------
4
+ * The COLD front-door (`cold-start-sampler.ts`) balances a bootstrap ✓/✗ suite
5
+ * from MECHANICAL labels alone (no LLM judge yet). Its input is a `ColdTrace`
6
+ * (id + `MechanicalSignals` + dedup keys). The determiner PREP stage, however,
7
+ * works over `EvalTrace[]` (the projection of the handed-over UniTF export). This
8
+ * module is the thin, PURE adapter between the two — and the SINGLE place the
9
+ * cold sampler is wired into the determiner/discover path.
10
+ *
11
+ * ── HONEST-NULL projection (why the mapping looks the way it does) ────────────
12
+ * The `EvalTrace` contract does NOT carry a generic `ext.signals` /
13
+ * `ext.classification` block — the UniTF→EvalTrace projection (`unitf-to-
14
+ * evaltrace.ts`) FLATTENS only the fields it can ground onto the top level
15
+ * (`errored` · `status` · `incomplete` · `scores`) and the UniTF source `ext`
16
+ * itself carries just `ext.eval` (the §9.4.2 fidelity marker). So the mechanical
17
+ * signals are read from what ACTUALLY survives to `EvalTrace`, and every signal
18
+ * with no grounded source stays UNKNOWN (absent), never a fabricated `false`:
19
+ *
20
+ * MechanicalSignals.hasError ← EvalTrace.errored (ERROR family)
21
+ * MechanicalSignals.hasApiErrors ← EvalTrace.status === "error" (ERROR family)
22
+ * MechanicalSignals.incomplete ← EvalTrace.incomplete (TERMINAL family)
23
+ * MechanicalSignals.hasScore/minScore ← numeric EvalTrace.scores (SCORE family)
24
+ * MechanicalSignals.hasChatFeedback/negativeReaction ← UNKNOWN — the FEEDBACK
25
+ * family is not carried on EvalTrace today; omitted (never coerced false).
26
+ * ColdTrace.scenario ← UNKNOWN — no classification field on EvalTrace, so a
27
+ * trace has no dedup key and is kept (never a false collapse).
28
+ * ColdTrace.worthiness ← UNKNOWN — no worthiness field on EvalTrace (dedup is a
29
+ * no-op without a scenario key anyway).
30
+ *
31
+ * PURE + deterministic: no clock, no random, no network. A given `EvalTrace[]`
32
+ * always yields the identical selection (reproducible cold suites — C-PIN-adjacent).
33
+ */
34
+ import {
35
+ coldStartSample,
36
+ type ColdStartSuite,
37
+ type ColdTrace,
38
+ type MechanicalSignals,
39
+ } from "./cold-start-sampler.ts";
40
+ import type { EvalTrace } from "./contracts/eval-types.ts";
41
+
42
+ /**
43
+ * Read the SCORE family off `EvalTrace.scores`. Scores are carried verbatim
44
+ * (`unknown[]`, Langfuse-style `{ name, value }`). Only FINITE NUMERIC `value`s
45
+ * count toward the cold SCORE signal; a non-numeric or absent value contributes
46
+ * nothing. Returns `{}` (both UNKNOWN) when there is no numeric score — honest-
47
+ * null, never a fabricated `hasScore:false`.
48
+ */
49
+ function scoreSignals(scores: unknown[] | undefined): Pick<MechanicalSignals, "hasScore" | "minScore"> {
50
+ if (scores === undefined || scores.length === 0) return {};
51
+ let min = Number.POSITIVE_INFINITY;
52
+ let seen = false;
53
+ for (const s of scores) {
54
+ if (s === null || typeof s !== "object") continue;
55
+ const value = (s as { value?: unknown }).value;
56
+ if (typeof value === "number" && Number.isFinite(value)) {
57
+ seen = true;
58
+ if (value < min) min = value;
59
+ }
60
+ }
61
+ return seen ? { hasScore: true, minScore: min } : {};
62
+ }
63
+
64
+ /**
65
+ * Project one `EvalTrace` → the cold sampler's `ColdTrace`. Honest-null: only
66
+ * grounded signals are set; everything else is left absent (UNKNOWN). Explicit
67
+ * about the ERROR/TERMINAL/SCORE families it can ground and the FEEDBACK family
68
+ * it cannot (see the module header).
69
+ */
70
+ export function projectEvalTraceToCold(trace: EvalTrace): ColdTrace {
71
+ const signals: MechanicalSignals = {};
72
+ // ERROR family — `errored` is the always-set structured flag (false = a grounded
73
+ // not-errored). `status === "error"` is the raw carried tri-state; surface it as
74
+ // the API-error signal when the source supplied it.
75
+ if (trace.errored !== undefined) signals.hasError = trace.errored;
76
+ if (trace.status === "error") signals.hasApiErrors = true;
77
+ // TERMINAL family — the §9.4.2 truncation marker (absent ⇒ UNKNOWN, never false).
78
+ if (trace.incomplete !== undefined) signals.incomplete = trace.incomplete;
79
+ // SCORE family — derived from any numeric platform score.
80
+ Object.assign(signals, scoreSignals(trace.scores));
81
+ // FEEDBACK family (hasChatFeedback/negativeReaction), scenario, worthiness: NOT
82
+ // carried on EvalTrace — deliberately omitted so they read UNKNOWN downstream.
83
+ return { id: trace.id, signals };
84
+ }
85
+
86
+ /** Project a batch of `EvalTrace` → `ColdTrace[]`, order-preserving + PURE. */
87
+ export function projectColdTraces(traces: EvalTrace[]): ColdTrace[] {
88
+ return traces.map(projectEvalTraceToCold);
89
+ }
90
+
91
+ /**
92
+ * The cold-start selection metadata surfaced into the discover/determiner report
93
+ * (the determiner-stage `manifest.json`). `lowConfidence` is the load-bearing
94
+ * flag: a thin-negative cold suite MUST have its first judge pass treated as
95
+ * LOW-CONFIDENCE and re-balanced once real verdicts exist.
96
+ */
97
+ export interface ColdStartMeta {
98
+ /** the sampler's target suite size (default = incoming trace count → pass-through). */
99
+ targetSize: number;
100
+ /** how many traces the batch handed to the sampler. */
101
+ input: number;
102
+ /** how many traces the cold suite selected (≤ input; = input on pass-through). */
103
+ selected: number;
104
+ passCount: number;
105
+ failCount: number;
106
+ /** the ✗-pool was too thin — treat the first cold judge pass as LOW-CONFIDENCE. */
107
+ lowConfidence: boolean;
108
+ /** the ✗-pool was rarer than its balanced half → every available fail was taken. */
109
+ oversampledFailPool: boolean;
110
+ /** BOTH non-empty pools are represented (never a success-only bootstrap suite). */
111
+ minBothHeld: boolean;
112
+ }
113
+
114
+ /**
115
+ * Wire the cold-start sampler over an `EvalTrace[]` batch and map the balanced
116
+ * suite BACK to the concrete `EvalTrace[]` the determiner PREP consumes. This is
117
+ * the SAFE call-site helper: it subsamples FIRST, so the untouched
118
+ * `prepDeterminerTasks` still emits exactly one determiner task per SELECTED
119
+ * trace. `size` defaults to the incoming count — a pass-through that only
120
+ * subsamples when an explicit smaller `size` is given (or the batch's own
121
+ * ✓/✗ imbalance triggers oversample flagging). PURE + deterministic.
122
+ */
123
+ export function selectColdStartSuite(
124
+ traces: EvalTrace[],
125
+ opts: { size?: number; minBoth?: number; prevalenceFloor?: number; scoreThreshold?: number } = {},
126
+ ): { selected: EvalTrace[]; meta: ColdStartMeta; suite: ColdStartSuite } {
127
+ const size = opts.size ?? traces.length;
128
+ const suite = coldStartSample(projectColdTraces(traces), {
129
+ size,
130
+ minBoth: opts.minBoth,
131
+ prevalenceFloor: opts.prevalenceFloor,
132
+ scoreThreshold: opts.scoreThreshold,
133
+ });
134
+ // Map the selected cold reps back to their source EvalTrace, preserving the
135
+ // suite's (✓-then-✗) order. `filter` guards the impossible missing-id case.
136
+ const byId = new Map(traces.map((t) => [t.id, t] as const));
137
+ const selected = suite.selected
138
+ .map((c) => byId.get(c.id))
139
+ .filter((t): t is EvalTrace => t !== undefined);
140
+ const meta: ColdStartMeta = {
141
+ targetSize: size,
142
+ input: traces.length,
143
+ selected: selected.length,
144
+ passCount: suite.passCount,
145
+ failCount: suite.failCount,
146
+ lowConfidence: suite.lowConfidence,
147
+ oversampledFailPool: suite.oversampledFailPool,
148
+ minBothHeld: suite.minBothHeld,
149
+ };
150
+ return { selected, meta, suite };
151
+ }
@@ -0,0 +1,267 @@
1
+ /**
2
+ * scripts/cold-start-sampler.ts — EV-5.3 the balanced COLD-START sampler.
3
+ * ---------------------------------------------------------------------------
4
+ * PRE-SUITE, there is NO LLM judge yet: the EV-042 determiner (`determine-
5
+ * outcome.ts`) needs a criteria suite to run, and the suite doesn't exist yet.
6
+ * So the ONLY ✓/✗ labels available at cold start are:
7
+ * (a) the agent/skill DEFINITION's success ORACLE, and
8
+ * (b) deterministic MECHANICAL signals — the four cold-label families
9
+ * ERROR · FEEDBACK · SCORE · TERMINAL (a subset of `ext.signals` plus the
10
+ * §9.4.2 terminal/`incomplete` marker). No provider, no judge tokens.
11
+ *
12
+ * This is DISTINCT from `sample-traces.ts` `balancedSample`, which balances over
13
+ * the LLM-determiner's `OutcomeVerdict` labels (a WARM, post-judge input). This
14
+ * module is the COLD front-door: it manufactures a balanced ✓/✗ bootstrap suite
15
+ * from mechanical labels alone so the first judge pass is trained on BOTH classes.
16
+ *
17
+ * The pipeline (in order):
18
+ * stratify → SL-5 prevalence floor → worthiness/scenario dedup →
19
+ * MIN-BOTH (a guaranteed minimum from BOTH pools — never a success-only suite) →
20
+ * oversample the ✗-pool when rare (and flag the suite LOW-CONFIDENCE).
21
+ *
22
+ * PURE + deterministic: no `Math.random`, no clock, no network. A given
23
+ * (traces, opts) always yields the identical suite (reproducible cold suites —
24
+ * C-PIN-adjacent). Never fabricates a trace: a scarcer class contributes all it
25
+ * has and no more.
26
+ */
27
+
28
+ // ── Mechanical cold labels (NO LLM judge) ───────────────────────────────────
29
+
30
+ /** The cold outcome — the ONLY two pools a balanced suite is built from. */
31
+ export const ColdOutcome = { Pass: "pass", Fail: "fail" } as const;
32
+ export type ColdOutcomeValue = (typeof ColdOutcome)[keyof typeof ColdOutcome];
33
+
34
+ /**
35
+ * The four MECHANICAL cold-label signal families available pre-suite. Mirrors the
36
+ * subset of UniTF `ext.signals` (`hasError`/`hasApiErrors`/`hasChatFeedback`/
37
+ * `negativeReaction`/`hasScore`/`minScore`) plus the §9.4.2 terminal marker
38
+ * (`incomplete`). All optional/additive: an absent field is UNKNOWN, never a
39
+ * false — the oracle reads only what is present.
40
+ */
41
+ export interface MechanicalSignals {
42
+ /** ERROR family — a run/tool error was recorded. */
43
+ hasError?: boolean;
44
+ /** ERROR family — provider/API errors were recorded. */
45
+ hasApiErrors?: boolean;
46
+ /** FEEDBACK family — a user chat reaction exists on the trace. */
47
+ hasChatFeedback?: boolean;
48
+ /** FEEDBACK family — that reaction was negative (frustration/swear hit). */
49
+ negativeReaction?: boolean;
50
+ /** SCORE family — a numeric score exists. */
51
+ hasScore?: boolean;
52
+ /** SCORE family — the lowest score seen (compared to `scoreThreshold`). */
53
+ minScore?: number;
54
+ /** TERMINAL family — the session was cut off / reached no terminal event. */
55
+ incomplete?: boolean;
56
+ }
57
+
58
+ /** One candidate trace at cold start: its id + mechanical signals + dedup keys. */
59
+ export interface ColdTrace {
60
+ id: string;
61
+ signals: MechanicalSignals;
62
+ /** `ext.classification.scenario` — the dedup key (one rep per scenario). */
63
+ scenario?: string;
64
+ /** `ext.signals.worthinessScore` [0,1] — dedup keeps the worthiest rep. */
65
+ worthiness?: number;
66
+ }
67
+
68
+ /**
69
+ * The DEFINITION success oracle: maps a cold trace → ✓/✗, or `null` when the
70
+ * mechanical signals are insufficient to decide. A `null` (UNKNOWN) trace is kept
71
+ * for coverage but NEVER forced into a pool — it can't help balance and must not
72
+ * fabricate a label. The default is {@link defaultMechanicalOracle}; a subject
73
+ * whose DEFINITION encodes a richer success rule injects its own here.
74
+ */
75
+ export type SuccessOracle = (t: ColdTrace) => ColdOutcomeValue | null;
76
+
77
+ /** Default SCORE-family pass/fail cut. */
78
+ export const DEFAULT_SCORE_THRESHOLD = 0.5;
79
+
80
+ /**
81
+ * The default MECHANICAL oracle over the four cold-label families. A trace is ✗
82
+ * when ANY negative mechanical signal fired — an error, a NEGATIVE user reaction,
83
+ * a below-threshold score, or a non-terminal/truncated session — and ✓ otherwise.
84
+ * PURE + total (never returns `null`): a subject that needs an UNKNOWN verdict
85
+ * injects its own oracle. No LLM, no provider.
86
+ */
87
+ export function defaultMechanicalOracle(
88
+ scoreThreshold: number = DEFAULT_SCORE_THRESHOLD,
89
+ ): SuccessOracle {
90
+ return (t) => {
91
+ const s = t.signals;
92
+ const errored = s.hasError === true || s.hasApiErrors === true;
93
+ const negFeedback = s.hasChatFeedback === true && s.negativeReaction === true;
94
+ const lowScore =
95
+ s.hasScore === true && typeof s.minScore === "number" && s.minScore < scoreThreshold;
96
+ const truncated = s.incomplete === true;
97
+ return errored || negFeedback || lowScore || truncated ? ColdOutcome.Fail : ColdOutcome.Pass;
98
+ };
99
+ }
100
+
101
+ // ── stratify ────────────────────────────────────────────────────────────────
102
+
103
+ /** The ✓/✗ pools plus the UNKNOWN remainder (oracle abstained). Order-preserving. */
104
+ export interface Stratified {
105
+ pass: ColdTrace[];
106
+ fail: ColdTrace[];
107
+ unknown: ColdTrace[];
108
+ }
109
+
110
+ /**
111
+ * Partition traces into the ✓/✗ pools via the oracle (UNKNOWN → `unknown`).
112
+ * PURE + deterministic; preserves input order within each pool.
113
+ */
114
+ export function stratify(traces: ColdTrace[], oracle: SuccessOracle): Stratified {
115
+ const pass: ColdTrace[] = [];
116
+ const fail: ColdTrace[] = [];
117
+ const unknown: ColdTrace[] = [];
118
+ for (const t of traces) {
119
+ const v = oracle(t);
120
+ if (v === ColdOutcome.Pass) pass.push(t);
121
+ else if (v === ColdOutcome.Fail) fail.push(t);
122
+ else unknown.push(t);
123
+ }
124
+ return { pass, fail, unknown };
125
+ }
126
+
127
+ // ── worthiness / scenario dedup ─────────────────────────────────────────────
128
+
129
+ /**
130
+ * Keep ONE representative per `scenario` — the highest `worthiness` (ties → the
131
+ * first seen). Traces with NO scenario have no dedup key, so they are all kept
132
+ * (they can't be proven duplicates). Deterministic + order-preserving over the
133
+ * surviving representatives. Never reorders by worthiness — only DROPS lower-
134
+ * worthiness same-scenario duplicates.
135
+ */
136
+ export function dedupByScenario(pool: ColdTrace[]): ColdTrace[] {
137
+ // First pass: pick the winning id per scenario (highest worthiness, first-seen tie).
138
+ const winner = new Map<string, ColdTrace>();
139
+ for (const t of pool) {
140
+ if (t.scenario === undefined) continue;
141
+ const cur = winner.get(t.scenario);
142
+ if (cur === undefined || (t.worthiness ?? 0) > (cur.worthiness ?? 0)) {
143
+ winner.set(t.scenario, t);
144
+ }
145
+ }
146
+ // Second pass: emit in original order, keeping non-scenario traces + each
147
+ // scenario's winner exactly once.
148
+ const emittedScenario = new Set<string>();
149
+ const out: ColdTrace[] = [];
150
+ for (const t of pool) {
151
+ if (t.scenario === undefined) {
152
+ out.push(t);
153
+ continue;
154
+ }
155
+ if (winner.get(t.scenario) === t && !emittedScenario.has(t.scenario)) {
156
+ emittedScenario.add(t.scenario);
157
+ out.push(t);
158
+ }
159
+ }
160
+ return out;
161
+ }
162
+
163
+ // ── coldStartSample — the balanced cold suite ───────────────────────────────
164
+
165
+ export interface ColdStartOptions {
166
+ /** Target suite size (the sampler stays at or under this, MIN-BOTH excepted). */
167
+ size: number;
168
+ /**
169
+ * MIN-BOTH — the guaranteed minimum drawn from EACH non-empty pool (default 1).
170
+ * When honoring both minimums would exceed `size`, MIN-BOTH WINS: a balanced
171
+ * bootstrap suite is worth more than a hard size cap, and a success-only suite
172
+ * is never acceptable.
173
+ */
174
+ minBoth?: number;
175
+ /**
176
+ * SL-5 PREVALENCE FLOOR — the minimum number of ✗-pool traces retained even when
177
+ * the ✗ class is scarce (default = `minBoth`). The fail budget never drops below
178
+ * `min(prevalenceFloor, availableFails)`, so a rare-but-present failure signal is
179
+ * never balanced away.
180
+ */
181
+ prevalenceFloor?: number;
182
+ /** SCORE-family pass/fail cut for the default oracle (default 0.5). */
183
+ scoreThreshold?: number;
184
+ /** The DEFINITION success oracle (default `defaultMechanicalOracle(scoreThreshold)`). */
185
+ oracle?: SuccessOracle;
186
+ /** Worthiness/scenario dedup (default true). */
187
+ dedup?: boolean;
188
+ }
189
+
190
+ export interface ColdStartSuite {
191
+ /** The selected cold suite (deduped, balanced): ✓ representatives then ✗. */
192
+ selected: ColdTrace[];
193
+ passCount: number;
194
+ failCount: number;
195
+ /** true when the ✗-pool was too rare to fill its balanced half → all fails taken. */
196
+ oversampledFailPool: boolean;
197
+ /**
198
+ * true when the suite rests on TOO-FEW negatives — the ✗-pool was oversampled or
199
+ * couldn't fill its balanced half (or is empty). Downstream MUST treat the first
200
+ * cold judge pass as LOW-CONFIDENCE and re-balance once real verdicts exist.
201
+ */
202
+ lowConfidence: boolean;
203
+ /**
204
+ * The MIN-BOTH invariant: BOTH non-empty pools are represented in `selected`.
205
+ * A success-only suite (or a fail-only suite) ⇒ false. When both pools have
206
+ * members this is ALWAYS true.
207
+ */
208
+ minBothHeld: boolean;
209
+ }
210
+
211
+ /**
212
+ * Build a balanced cold-start suite from mechanical labels. Runs the full EV-5.3
213
+ * pipeline: stratify → SL-5 prevalence floor → scenario/worthiness dedup →
214
+ * MIN-BOTH → oversample-when-rare. PURE + deterministic; never fabricates.
215
+ */
216
+ export function coldStartSample(traces: ColdTrace[], opts: ColdStartOptions): ColdStartSuite {
217
+ const size = Math.max(0, Math.floor(opts.size));
218
+ const minBoth = Math.max(0, Math.floor(opts.minBoth ?? 1));
219
+ const oracle = opts.oracle ?? defaultMechanicalOracle(opts.scoreThreshold);
220
+
221
+ const strat = stratify(traces, oracle);
222
+ const pass = opts.dedup === false ? strat.pass : dedupByScenario(strat.pass);
223
+ const fail = opts.dedup === false ? strat.fail : dedupByScenario(strat.fail);
224
+
225
+ const perSide = Math.floor(size / 2);
226
+ // SL-5 prevalence floor: fails we must keep even when scarce (capped at availability).
227
+ const prevalenceFloor = Math.max(0, Math.floor(opts.prevalenceFloor ?? minBoth));
228
+ const failFloor = Math.min(Math.max(prevalenceFloor, minBoth), fail.length);
229
+
230
+ let takeFail: number;
231
+ let takePass: number;
232
+ let oversampledFailPool = false;
233
+
234
+ if (fail.length > 0 && fail.length < perSide) {
235
+ // ✗-pool RARE — oversample: take EVERY available fail, fill the rest with ✓.
236
+ oversampledFailPool = true;
237
+ takeFail = fail.length;
238
+ takePass = Math.min(pass.length, Math.max(0, size - takeFail));
239
+ } else {
240
+ // Balanced take, but never below the SL-5 floor for fails.
241
+ takeFail = Math.min(fail.length, Math.max(perSide, failFloor));
242
+ takePass = Math.min(pass.length, Math.max(0, size - takeFail));
243
+ // If ✓ is scarce and budget remains, let ✗ backfill up to `size`.
244
+ if (takePass + takeFail < size) {
245
+ takeFail = Math.min(fail.length, size - takePass);
246
+ }
247
+ }
248
+
249
+ // MIN-BOTH enforcement — never drop a NON-EMPTY pool below min(minBoth, available).
250
+ // This is the "never a success-only suite" guarantee; it can push the total over
251
+ // `size` only in the degenerate small-`size` case, which is intentional.
252
+ if (fail.length > 0) takeFail = Math.max(takeFail, Math.min(minBoth, fail.length));
253
+ if (pass.length > 0) takePass = Math.max(takePass, Math.min(minBoth, pass.length));
254
+
255
+ const selectedPass = pass.slice(0, takePass);
256
+ const selectedFail = fail.slice(0, takeFail);
257
+ const selected = [...selectedPass, ...selectedFail];
258
+
259
+ const passCount = selectedPass.length;
260
+ const failCount = selectedFail.length;
261
+ const minBothHeld = passCount > 0 && failCount > 0;
262
+ // Low-confidence when negatives are thin: oversampled, or the ✗-pool couldn't
263
+ // fill its balanced half, or there are no negatives at all.
264
+ const lowConfidence = oversampledFailPool || fail.length === 0 || failCount < perSide;
265
+
266
+ return { selected, passCount, failCount, oversampledFailPool, lowConfidence, minBothHeld };
267
+ }