@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,1074 @@
1
+ /**
2
+ * scripts/contracts/eval-types.ts
3
+ * ---------------------------------------------------------------------------
4
+ * Canonical contracts for the W1 eval-DEVELOPMENT engine (EV-041/042/043/048 +
5
+ * 049/050/051/052). This is a SEPARATE surface from the v1 static-auditor
6
+ * contracts in `contracts/types.ts` (EV-REQ-001..027) — the auditor is a
7
+ * different product (the `*audit` surface); the W1 engine is the new
8
+ * eval-development capability. Keeping them in distinct files means the v1
9
+ * audit contracts stay frozen while the eval engine grows.
10
+ *
11
+ * Design invariants (mirror the orchestrator's pure-core style):
12
+ * - Pure data shapes + categorical constants (no magic strings).
13
+ * - No clock / random / network anywhere a core consumes these.
14
+ * - The live LLM judge is reached only via a `JudgeInvoke` DI seam; these
15
+ * types never bind a provider SDK.
16
+ */
17
+ import { type Static, Type } from "@sinclair/typebox";
18
+ import { Value } from "@sinclair/typebox/value";
19
+ import type { CodeEvalSpec } from "../code-eval.ts";
20
+
21
+ // ── Trace shapes (in-package; NOT importing a platform SDK type) ─────────────
22
+ //
23
+ // A minimal, platform-agnostic view of one Langfuse-style trace record: enough
24
+ // for the determiner / profiler / sampler to deep-read. We deliberately keep
25
+ // `input`/`output`/observation `output` loosely typed (`unknown`) — real
26
+ // exports carry arbitrary nested payloads; the cores narrow only the fields
27
+ // they actually read.
28
+
29
+ /** One observation (span) inside a trace. `type === "TOOL"` marks a tool call. */
30
+ export interface TraceObservation {
31
+ type: string;
32
+ name?: string;
33
+ output?: unknown;
34
+ input?: unknown;
35
+ }
36
+
37
+ /** A single trace record (one agent session). */
38
+ export interface EvalTrace {
39
+ id: string;
40
+ name?: string;
41
+ input?: { prompt?: string } & Record<string, unknown>;
42
+ output?: { response?: string; steps?: number } & Record<string, unknown>;
43
+ observations: TraceObservation[];
44
+ /** Langfuse scores — empty on the sample export (unlabeled → determiner owns it). */
45
+ scores?: unknown[];
46
+ /** Langfuse tags — empty on the sample export. */
47
+ tags?: string[];
48
+ latencyMs?: number;
49
+ costUsd?: number;
50
+ /**
51
+ * §9.4.2 node 1 (EXAMINE fidelity gate) — an EXPLICIT truncation marker the
52
+ * INGESTION layer sets when the source platform recorded the session as
53
+ * cut-off / unterminated (e.g. a Langfuse/OTel root span that never closed, an
54
+ * errored run with no terminal event). When `true`, the deterministic
55
+ * pre-judge fidelity gate (`assessTraceFidelity`) flags the trajectory
56
+ * INCOMPLETE and it is NEVER dispatched the full criteria walk — a synthesized
57
+ * INCOMPLETE verdict is emitted instead (never a fabricated pass/fail from a
58
+ * partial trace). OPTIONAL/additive: absent ⇒ the trace is judged normally.
59
+ */
60
+ incomplete?: boolean;
61
+ /** the human-readable reason the trace was marked incomplete (rides into the gate). */
62
+ incompleteReason?: string;
63
+ /**
64
+ * XF-FIX Finding C (structured error carriage) — the STRUCTURED error flag a
65
+ * criterion that judges error-handling reads. Derived at projection time from
66
+ * `computed.hasError ?? (status === "error" || any span.status === "error")`.
67
+ * Before XF-FIX the evaluator dropped error state entirely (it survived only as
68
+ * textual span output), so an error-KIND criterion was blind to it; Diagnostics
69
+ * carried it all along (`computed.hasError ?? status`). Always set (false = a
70
+ * grounded not-errored, never an absent-means-unknown). ADDITIVE — legacy
71
+ * consumers ignore it.
72
+ */
73
+ errored?: boolean;
74
+ /** XF-FIX Finding C — the RAW carried `UnifiedTrace.status` (`ok|error|unknown`),
75
+ * present when the source supplied it. `errored` is the derived boolean; this is
76
+ * the verbatim source value for a criterion that wants the tri-state. */
77
+ status?: "ok" | "error" | "unknown";
78
+ /**
79
+ * XF-FIX Finding D (token carriage) — the token usage split, carried through so a
80
+ * token-budget criterion has a STRUCTURED field. Before XF-FIX `costUsd`+`latencyMs`
81
+ * were carried but token counts were not, leaving token-KIND criteria unsupported
82
+ * at intake. Minimal split (the fields a budget check reads); undefined-safe — a
83
+ * source that omits a count leaves it absent (NEVER coerced to 0). ADDITIVE.
84
+ */
85
+ tokens?: { input?: number; output?: number; total?: number };
86
+ /** XF-FIX Finding D — the convenience total (`computed.totalTokens ?? tokens.total
87
+ * ?? input+output`). Mirrors the diagnostics `TraceMetadata.totalTokens` fallback
88
+ * chain so the two lanes report the SAME number. Absent when no token data exists. */
89
+ totalTokens?: number;
90
+ }
91
+
92
+ // ── Subject vocabulary (EV-002 zero-subject-logic / EV-049 behavior-in-profile)
93
+ //
94
+ // The engine holds the CONCEPTS (an event has a kind · some tools are recovery
95
+ // reactions · there is a primary send action · a guard may carry a counter) but
96
+ // NEVER the subject-specific NAMES. Those all live HERE, injected via the subject
97
+ // profile (`profile-subject.ts` populates them). The determiner reads the vocab
98
+ // off the injected profile — it has zero module-level subject constants.
99
+ //
100
+ // `UNCLASSIFIED_EVENT` is the ENGINE's generic sentinel for "matched no tag rule"
101
+ // — it is NOT subject vocabulary (it names no subject concept), so it stays in
102
+ // the engine.
103
+ export const UNCLASSIFIED_EVENT = "other";
104
+
105
+ /**
106
+ * One tag→event-kind classification rule. `tag` is the opening-tag stem to look
107
+ * for in a trace prompt (matched as `<{tag}`, case-insensitive — a prefix match,
108
+ * so the stem `opportunity` also catches `<opportunity_update`). `kind` is the
109
+ * label assigned on a match. Rules are evaluated in order; first match wins.
110
+ */
111
+ export interface EventTagRule {
112
+ kind: string;
113
+ tag: string;
114
+ }
115
+
116
+ /**
117
+ * The SUBJECT-SPECIFIC vocabulary the success/failure determiner needs. Produced
118
+ * by `profileSubject` (EV-049) and carried on the `SubjectProfile`; the engine
119
+ * reads it from the injected profile, never from a module constant.
120
+ */
121
+ export interface SubjectVocab {
122
+ /** tool names whose presence after a failed send counts as a recovery reaction. */
123
+ recoveryTools: string[];
124
+ /** ordered tag→kind rules; first match wins, else `UNCLASSIFIED_EVENT`. */
125
+ eventTags: EventTagRule[];
126
+ /** the primary outbound action tool name (e.g. the subject's "send" tool). */
127
+ sendTool: string;
128
+ /**
129
+ * attribute name carrying a guard's consecutive-action count (parsed as
130
+ * `{attr}="N"`); `null` when the subject has no such guard.
131
+ */
132
+ guardCounterAttr: string | null;
133
+ }
134
+
135
+ // ── Outcome verdict (EV-042) ────────────────────────────────────────────────
136
+ export const OutcomeVerdict = {
137
+ Pass: "pass",
138
+ Fail: "fail",
139
+ /** The determiner could not decide with confidence (drives uncertainty
140
+ * sampling downstream, EV-052). NEVER silently coerced to pass/fail.
141
+ * GA: also the canonical ADJUDICATE abstain state — an `uncertain` verdict
142
+ * carrying a `blockedBy` payload IS the grounded-adjudication INDETERMINATE
143
+ * (GA-4 reuses this enum rather than adding a 4th value, so the ~17 existing
144
+ * verdict consumers compile unchanged). */
145
+ Uncertain: "uncertain",
146
+ } as const;
147
+ export type OutcomeVerdictValue =
148
+ (typeof OutcomeVerdict)[keyof typeof OutcomeVerdict];
149
+
150
+ // ── Run-level verdict lattice (GA · the ternary gate) ────────────────────────
151
+ /**
152
+ * GA: the RUN-level verdict is a tri-state lattice `fail ▸ incomplete ▸ pass`
153
+ * (assemble-scorecard / evaluate.ts gate). A run is `incomplete` (NOT a false
154
+ * green) when a CRIT/HIGH criterion adjudicated `uncertain`/indeterminate but no
155
+ * CRIT/HIGH criterion outright failed — the latent false-green killer. This is a
156
+ * RUN-level rollup state, distinct from the per-criterion `OutcomeVerdict`.
157
+ */
158
+ export const RunVerdict = {
159
+ Pass: "pass",
160
+ /** ≥1 CRIT/HIGH criterion failed. */
161
+ Fail: "fail",
162
+ /** no CRIT/HIGH fail, but ≥1 CRIT/HIGH indeterminate — gate cannot certify. */
163
+ Incomplete: "incomplete",
164
+ } as const;
165
+ export type RunVerdictValue = (typeof RunVerdict)[keyof typeof RunVerdict];
166
+
167
+ // ── GA assumption kinds (GA-3 typed assumptions) ─────────────────────────────
168
+ /**
169
+ * GA-3: the TYPE of an assumption decides where its lifecycle routes when it
170
+ * blocks a verdict (the `blockedBy.kind`): `factual-intent` → re-ground from the
171
+ * trace (calibrate) · `normative` → operator ratification · `scope` → re-scope /
172
+ * skip the criterion for this situation.
173
+ */
174
+ export const AssumptionKind = {
175
+ /** a presumed FACT about intent/world the trace did not establish. */
176
+ FactualIntent: "factual-intent",
177
+ /** a value/standard call (what SHOULD count as good) — operator-owned. */
178
+ Normative: "normative",
179
+ /** whether the criterion even applies to this route/situation. */
180
+ Scope: "scope",
181
+ } as const;
182
+ export type AssumptionKindValue =
183
+ (typeof AssumptionKind)[keyof typeof AssumptionKind];
184
+
185
+ /**
186
+ * Deterministic signals extracted from a trace. These are FED to the judge;
187
+ * they are NOT the verdict. Critically, `toolCount` is a signal only — the
188
+ * determiner must never use "called a tool" as a success proxy (sample's
189
+ * zero-tool guard-holds are correct restraint = SUCCESS).
190
+ */
191
+ export interface OutcomeSignals {
192
+ /** the classified event kind (from `vocab.eventTags`), else `UNCLASSIFIED_EVENT`. */
193
+ eventKind: string;
194
+ toolCount: number;
195
+ /**
196
+ * true=≥1 send observed · false=a KNOWN no-send (the send tool IS identified,
197
+ * but the trace called it zero times) · null=UNKNOWN (the subject's send tool
198
+ * is unset/uninferred, EV-049 — we CANNOT know whether it sent, so we honestly
199
+ * report UNKNOWN rather than a false `false`). HINT only — decides nothing.
200
+ */
201
+ sentMessage: boolean | null;
202
+ /** true=at least one send succeeded · false=all sends failed · null=no send/unknown. */
203
+ sendSucceeded: boolean | null;
204
+ /** consecutive_outbound from an outbound_guard event, else null. */
205
+ guardConsecutive: number | null;
206
+ /** a recovery tool (retry/escalation) is present after a failed send. */
207
+ recoveryPresent: boolean;
208
+ }
209
+
210
+ /** A judge's critique-before-verdict structured answer. */
211
+ export interface CritiqueVerdict {
212
+ /** The reasoning — MUST precede the verdict (parse rejects a bare verdict). */
213
+ critique: string;
214
+ result: OutcomeVerdictValue | "pass" | "fail";
215
+ /** 0..1 self-reported confidence. */
216
+ confidence: number;
217
+ }
218
+
219
+ /** The determiner's output for one trace. */
220
+ export interface OutcomeResult {
221
+ traceId: string;
222
+ reached: OutcomeVerdictValue;
223
+ confidence: number;
224
+ rationale: string;
225
+ signals: OutcomeSignals;
226
+ }
227
+
228
+ // ── Discovered criteria (EV-041) ────────────────────────────────────────────
229
+ export const CriterionFlag = {
230
+ /** Build a judge / code-check for this — a genuine behavioral eval. */
231
+ EvalWorthy: "eval-worthy",
232
+ /** Infra / dependency failure — route to diagnostics, do NOT judge the model. */
233
+ Fixable: "fixable",
234
+ } as const;
235
+ export type CriterionFlagValue =
236
+ (typeof CriterionFlag)[keyof typeof CriterionFlag];
237
+
238
+ export const JudgeKind = {
239
+ /** Subjective behavioral judgment → LLM judge. */
240
+ Llm: "llm-judge",
241
+ /** Objective check over tool outputs → deterministic code. */
242
+ Code: "code-based",
243
+ /** Code detects, judge confirms. */
244
+ Hybrid: "hybrid",
245
+ } as const;
246
+ export type JudgeKindValue = (typeof JudgeKind)[keyof typeof JudgeKind];
247
+
248
+ /** One discovered BINARY ACTIONABLE eval criterion (the output of `*discover-evals`). */
249
+ export interface DiscoveredCriterion {
250
+ id: string;
251
+ /** Pass = … (binary statement). */
252
+ statement: string;
253
+ /** what the judge/check must be fed. */
254
+ judgeInputs: string[];
255
+ judgeKind: JudgeKindValue;
256
+ flag: CriterionFlagValue;
257
+ /** the ✓/✗ label evidence count that surfaced this category. */
258
+ supportCount: number;
259
+ }
260
+
261
+ // ── Judge spec + verdict (EV-043 / EV-048) ──────────────────────────────────
262
+ /** A built judge spec: one binary+confidence judge for one criterion. */
263
+ export interface JudgeSpec {
264
+ criterionId: string;
265
+ statement: string;
266
+ passDefinition: string;
267
+ failDefinition: string;
268
+ /** few-shot exemplars — drawn from the TRAIN split ONLY (never dev/test). */
269
+ fewShot: JudgeExemplar[];
270
+ judgeKind: JudgeKindValue;
271
+ }
272
+
273
+ export interface JudgeExemplar {
274
+ traceId: string;
275
+ label: OutcomeVerdictValue;
276
+ why: string;
277
+ }
278
+
279
+ /**
280
+ * GA-4: the assumption-blocked payload carried by an `uncertain`/indeterminate
281
+ * verdict. `kind` routes the calibration loop (factual→re-ground · normative→
282
+ * operator · scope→re-scope). PRESENT iff the verdict is indeterminate.
283
+ */
284
+ export interface VerdictBlock {
285
+ kind: AssumptionKindValue;
286
+ /** the unbound term / ungroundable premise / residual leap that blocked. */
287
+ text: string;
288
+ }
289
+
290
+ /**
291
+ * A judge verdict for one (criterion × subject-trace).
292
+ *
293
+ * GA additive fields (all OPTIONAL — legacy verdicts compile + flow unchanged;
294
+ * NO silent drop downstream, every stage must preserve them):
295
+ * - `refs` — the field-level resolvable evidence the claim cites (GA-1).
296
+ * - `assumptions`— typed assumptions the judge surfaced (GA-3).
297
+ * - `blockedBy` — set iff `result === uncertain` AND the abstain is assumption
298
+ * -driven; makes the indeterminate routable (GA-4).
299
+ */
300
+ export interface CriterionVerdict {
301
+ criterionId: string;
302
+ traceId: string;
303
+ result: OutcomeVerdictValue;
304
+ confidence: number;
305
+ critique: string;
306
+ refs?: DiscoveryRef[];
307
+ assumptions?: DiscoveryAssumption[];
308
+ blockedBy?: VerdictBlock;
309
+ /**
310
+ * §9.4.2 node 7 (T3) — the AUDITABLE record of the INDEPENDENT (2nd-judge)
311
+ * verification pass over a GATING fail. PRESENT iff a gating fail was put
312
+ * through `#mode-verify` (reviewer ≠ the deciding judge). `upheld:false` means
313
+ * the fail was REFUTED → downgraded to `uncertain` (the run rolls up to
314
+ * INCOMPLETE); `upheld:true` means the second judge confirmed the fail STANDS.
315
+ * Persisted so the report + on-disk artifact show that a second judge ran and
316
+ * what it concluded (not just "eligible for"). NO silent drop downstream.
317
+ */
318
+ independentVerify?: IndependentVerifyRecord;
319
+ }
320
+
321
+ /**
322
+ * §9.4.2 node 7 (T3) — the auditable second-judge verification record. Emitted
323
+ * for every GATING (CRIT/HIGH) fail that went through the INDEPENDENT verifier
324
+ * (`#mode-verify`, reviewer ≠ the deciding judge). It is the visible, persisted
325
+ * proof that the refutation pass actually ran — distinct from the self-verify
326
+ * step the deciding judge does inline.
327
+ */
328
+ export interface IndependentVerifyRecord {
329
+ /** the criterion this verification pass reviewed (set on the result-level ledger). */
330
+ criterionId?: string;
331
+ /** the contract guarantee: this review came from a DIFFERENT judge identity. */
332
+ byDifferentJudge: true;
333
+ /** true = the second judge CONFIRMED the fail (stands); false = REFUTED (downgraded). */
334
+ upheld: boolean;
335
+ /** the second judge's reasoning (entailment held / inferential leap / dead ref). */
336
+ reason: string;
337
+ /** the independent reviewer's identity (≠ the deciding judge). */
338
+ reviewerId?: string;
339
+ /** when refuted: the kind of the residual ungrounded premise (calibration routing). */
340
+ leapKind?: AssumptionKindValue;
341
+ }
342
+
343
+ /**
344
+ * UI-12-A (GA-1 grounding readiness) — the MACHINE-CHECKABLE grounding-capture
345
+ * health of a batch of folded verdicts.
346
+ *
347
+ * The denominator is the DECIDED verdicts (pass|fail) — the only verdicts a GA-1
348
+ * `refs[]` is REQUIRED for. An `uncertain` abstain legitimately carries NO ref
349
+ * (it carries `blockedBy`/`assumptions` instead) and is `na` for grounding, NOT
350
+ * ungrounded — counting abstains/bare-absences in the denominator is exactly what
351
+ * produced the false 0% the UI-12 audit caught (52/92 critiques cited observed
352
+ * strings, but 0/92 verdicts emitted structured `refs`, so `groundedPct` read 0%).
353
+ *
354
+ * `warning` is SET (loud) iff there ARE decided verdicts yet ZERO carry a ref —
355
+ * the silent-capture regression. ADVISORY by contract: the readiness assert never
356
+ * hard-fails the run; it surfaces the regression so it is caught, not hidden.
357
+ */
358
+ export interface GroundingReadiness {
359
+ /** pass|fail verdicts — the grounding-applicable denominator. */
360
+ decidedCount: number;
361
+ /** decided verdicts carrying ≥1 structured `refs[]`. */
362
+ groundedCount: number;
363
+ /** `uncertain` (abstain) verdicts — `na` for grounding (carry `blockedBy`, not refs). */
364
+ abstainedCount: number;
365
+ /** `groundedCount / decidedCount` as a %; 100 (na) when there are no decided verdicts. */
366
+ groundedPctOfDecided: number;
367
+ /** criterionIds of DECIDED verdicts missing a ref (the audit surface). */
368
+ ungroundedDecided: string[];
369
+ /** LOUD flag — set iff `decidedCount > 0 && groundedCount === 0`. */
370
+ warning?: string;
371
+ }
372
+
373
+ // ── Substrate (EV-050) ──────────────────────────────────────────────────────
374
+ export const Substrate = {
375
+ /**
376
+ * DEFAULT: Claude Code agent-dispatch. Verdicts are produced by parent-session-
377
+ * dispatched eval-judge / error-analyst leaf subagents reasoning on the HOST
378
+ * runtime (diagnostics-style mass-dispatch) and read back from verdict FILES —
379
+ * the default path calls NO provider SDK. See scripts/agent-dispatch.ts +
380
+ * references/workflows/orchestrator-protocol.md.
381
+ */
382
+ AgentDispatch: "agent-dispatch",
383
+ /**
384
+ * OPTIONAL: the evaluator's own in-house AI-SDK judge (google-genai shape).
385
+ * Kept (not deleted) but DEMOTED from default — for the CI / code-based export
386
+ * path where a provider call is wanted instead of host-runtime dispatch.
387
+ */
388
+ InHouse: "in-house",
389
+ /** Export to the user's eval framework (Vitest/promptfoo/Braintrust/…). */
390
+ UserFramework: "user-framework",
391
+ /** Deterministic code checks (objective criteria — no LLM). */
392
+ CodeBased: "code-based",
393
+ } as const;
394
+ export type SubstrateValue = (typeof Substrate)[keyof typeof Substrate];
395
+
396
+ // ── TypeBox guard for a discovered criterion (closed object) ────────────────
397
+ export const DiscoveredCriterionSchema = Type.Object(
398
+ {
399
+ id: Type.String({ minLength: 1 }),
400
+ statement: Type.String({ minLength: 1 }),
401
+ judgeInputs: Type.Array(Type.String({ minLength: 1 })),
402
+ judgeKind: Type.Union([
403
+ Type.Literal(JudgeKind.Llm),
404
+ Type.Literal(JudgeKind.Code),
405
+ Type.Literal(JudgeKind.Hybrid),
406
+ ]),
407
+ flag: Type.Union([
408
+ Type.Literal(CriterionFlag.EvalWorthy),
409
+ Type.Literal(CriterionFlag.Fixable),
410
+ ]),
411
+ supportCount: Type.Integer({ minimum: 0 }),
412
+ },
413
+ { additionalProperties: false },
414
+ );
415
+ export type DiscoveredCriterionStatic = Static<typeof DiscoveredCriterionSchema>;
416
+
417
+ // ── TypeBox guard for the subject vocabulary (EV-002 / EV-049) ───────────────
418
+ // Data-type enforcement is the script's legit job (handover): an AUTHORED vocab
419
+ // (or one auto-generated by the profiler) is validated against this closed shape
420
+ // before the engine trusts it. Strings only — the engine never executes the
421
+ // vocab, it matches against it.
422
+ export const EventTagRuleSchema = Type.Object(
423
+ {
424
+ kind: Type.String({ minLength: 1 }),
425
+ tag: Type.String({ minLength: 1 }),
426
+ },
427
+ { additionalProperties: false },
428
+ );
429
+
430
+ export const SubjectVocabSchema = Type.Object(
431
+ {
432
+ recoveryTools: Type.Array(Type.String({ minLength: 1 })),
433
+ eventTags: Type.Array(EventTagRuleSchema),
434
+ sendTool: Type.String(),
435
+ guardCounterAttr: Type.Union([Type.String({ minLength: 1 }), Type.Null()]),
436
+ },
437
+ { additionalProperties: false },
438
+ );
439
+ export type SubjectVocabStatic = Static<typeof SubjectVocabSchema>;
440
+
441
+ /**
442
+ * Validate + narrow an unknown value to `SubjectVocab` (guarded-parse style,
443
+ * mirroring the orchestrator's contract parsers). THROWS with the first schema
444
+ * error when the value does not match — a malformed authored/loaded vocab must
445
+ * never silently reach the determiner.
446
+ */
447
+ export function parseSubjectVocab(value: unknown): SubjectVocab {
448
+ if (!Value.Check(SubjectVocabSchema, value)) {
449
+ const first = [...Value.Errors(SubjectVocabSchema, value)][0];
450
+ const where = first?.path ?? "(root)";
451
+ const msg = first?.message ?? "does not match SubjectVocab";
452
+ throw new Error(`parseSubjectVocab: invalid subject vocab at ${where}: ${msg}`);
453
+ }
454
+ return value;
455
+ }
456
+
457
+ // ════════════════════════════════════════════════════════════════════════════
458
+ // §5b unified metric type-system + §5c discovery-rationale (P2 / P2b)
459
+ // ────────────────────────────────────────────────────────────────────────────
460
+ // ADDITIVE EXTENSION — a `MinedCriterion` is a `DiscoveredCriterion` PLUS the
461
+ // unified metric metadata (§5b) + an evidence-first discovery-rationale block
462
+ // (§5c, DR-2). It is a SUBTYPE so the base `DiscoveredCriterion` (and its six
463
+ // existing literal constructors across build-evals / run-pipeline / self-audit
464
+ // + tests) stay byte-stable — the discover output carries the full field set
465
+ // without forcing every consumer to change (P1-style zero-regression contract).
466
+ // ════════════════════════════════════════════════════════════════════════════
467
+
468
+ /** §5b `type.generality` — does the metric need the subject profile? */
469
+ export const Generality = {
470
+ /** subject-AGNOSTIC; reusable on ANY generation pipeline (well-formedness). */
471
+ GeneralStructural: "general-structural",
472
+ /** subject-profile-DERIVED; needs the subject's intent/brand/facts. */
473
+ SpecificSemantic: "specific-semantic",
474
+ } as const;
475
+ export type GeneralityValue = (typeof Generality)[keyof typeof Generality];
476
+
477
+ /** §5b `type.dimension` — the existing MECE R1/R2/R3 axis. */
478
+ export const MetricDimension = {
479
+ OperationCorrectness: "operation-correctness",
480
+ DataCorrectness: "data-correctness",
481
+ OperationalDeviation: "operational-deviation",
482
+ } as const;
483
+ export type MetricDimensionValue =
484
+ (typeof MetricDimension)[keyof typeof MetricDimension];
485
+
486
+ /** §5b `type.level` — the input-vs-output axis. */
487
+ export const MetricLevel = {
488
+ Context: "context",
489
+ Output: "output",
490
+ CrossStage: "cross-stage",
491
+ } as const;
492
+ export type MetricLevelValue = (typeof MetricLevel)[keyof typeof MetricLevel];
493
+
494
+ /**
495
+ * §5b `type.check_method` — the code-vs-judge ROUTER (SF-2 / DEC-16). The
496
+ * load-bearing field that drives P3 (code-track). The 3-value router shape:
497
+ * `deterministic` (code track) · `llm-judge` (judge track) · `hybrid` (code
498
+ * pre-filter + judge). `substrate` is DERIVED from this. NOTE: PRD §5b lists a
499
+ * finer 6-value taxonomy (deterministic-script | typebox-schema | gate |
500
+ * trace-cross-ref | trajectory-diff | llm-judge); the 3-value router is the part
501
+ * P3 needs — the finer split is a deferred refinement (this is additive only;
502
+ * the code-track itself is NOT implemented here).
503
+ */
504
+ // PRD §5b reconciliation: 3-value router load-bearing (SF-2/DEC-16); finer split deferred
505
+ export const CheckMethod = {
506
+ Deterministic: "deterministic",
507
+ LlmJudge: "llm-judge",
508
+ Hybrid: "hybrid",
509
+ } as const;
510
+ export type CheckMethodValue = (typeof CheckMethod)[keyof typeof CheckMethod];
511
+
512
+ /** §5c `evidence.grounding` — the "seen in traces?" answer; the honesty cut. */
513
+ export const Grounding = {
514
+ /** a failure was ACTUALLY seen in traces (cites refs + k/n prevalence). */
515
+ Observed: "observed",
516
+ /** a good-practice guard with no observed failure yet. */
517
+ Inferred: "inferred",
518
+ /** a hypothesis awaiting evidence (the weakest tier). */
519
+ HypothesisPending: "hypothesis-pending",
520
+ } as const;
521
+ export type GroundingValue = (typeof Grounding)[keyof typeof Grounding];
522
+
523
+ /** §5c `assumptions[].status`. GA-3 adds `eliminated` (the calibration-loop
524
+ * terminal state: the assumption was disproven / retired, not merely verified). */
525
+ export const AssumptionStatus = {
526
+ Verified: "verified",
527
+ Unverified: "unverified",
528
+ Hypothesis: "hypothesis",
529
+ /** GA-3: the assumption was eliminated by the calibration loop (disproven or
530
+ * retired). A criterion whose blocking assumption is eliminated is re-adjudicable. */
531
+ Eliminated: "eliminated",
532
+ } as const;
533
+ export type AssumptionStatusValue =
534
+ (typeof AssumptionStatus)[keyof typeof AssumptionStatus];
535
+
536
+ /** §5b `severity` — by variance impact; CRIT/HIGH gate. */
537
+ export const Severity = {
538
+ Crit: "CRIT",
539
+ High: "HIGH",
540
+ Med: "MED",
541
+ Low: "LOW",
542
+ } as const;
543
+ export type SeverityValue = (typeof Severity)[keyof typeof Severity];
544
+
545
+ /** §5c `expected_impact.confidence`. */
546
+ export const Confidence = {
547
+ High: "high",
548
+ Med: "med",
549
+ Low: "low",
550
+ } as const;
551
+ export type ConfidenceValue = (typeof Confidence)[keyof typeof Confidence];
552
+
553
+ /** The substrate a metric runs on — DERIVED from `check_method`. */
554
+ export const MetricSubstrate = {
555
+ Code: "code",
556
+ Judge: "judge",
557
+ } as const;
558
+ export type MetricSubstrateValue =
559
+ (typeof MetricSubstrate)[keyof typeof MetricSubstrate];
560
+
561
+ /** §5b — the unified metric metadata carried by every mined criterion. */
562
+ export interface MetricMetadata {
563
+ generality: GeneralityValue;
564
+ dimension: MetricDimensionValue;
565
+ level: MetricLevelValue;
566
+ /** the code-vs-judge router (SF-2). */
567
+ check_method: CheckMethodValue;
568
+ /** DERIVED from check_method (kept explicit for the reader). */
569
+ substrate: MetricSubstrateValue;
570
+ /** `[stepId,…]` — the recurrence: where this metric fires (define once, apply many). */
571
+ applies_to: string[];
572
+ severity: SeverityValue;
573
+ /** the MINIMAL slice the check needs. */
574
+ judge_inputs: string[];
575
+ /** EV-051 fix-vs-eval routing. */
576
+ flag: CriterionFlagValue;
577
+ }
578
+
579
+ /**
580
+ * GA-1: a STRUCTURED, resolvable grounding reference. A ref names WHERE a value
581
+ * lives (`obs` = trace/observation id · `path` = field path) and the EXACT
582
+ * `value` cited. `resolveRef` re-resolves it against the trace by exact
583
+ * (whitespace-normalized) value match — an `observed` claim must re-resolve.
584
+ */
585
+ export interface DiscoveryRef {
586
+ /** the trace id / observation id the value was read from (e.g. "ef30a271"). */
587
+ obs: string;
588
+ /** the field path within the trace/observation (e.g. "output.response"). */
589
+ path: string;
590
+ /** the EXACT cited value (re-resolved by whitespace-normalized exact match). */
591
+ value: string;
592
+ }
593
+
594
+ /**
595
+ * §5c — one assumption behind a discovered criterion + its evidence status.
596
+ * GA-3: `kind` types the assumption so its lifecycle/blocking routes correctly
597
+ * (OPTIONAL for grandfather — legacy assumptions without `kind` stay valid).
598
+ */
599
+ export interface DiscoveryAssumption {
600
+ text: string;
601
+ status: AssumptionStatusValue;
602
+ kind?: AssumptionKindValue;
603
+ }
604
+
605
+ /** §5c — the evidence block; the OBSERVED-vs-INFERRED honesty cut. */
606
+ export interface DiscoveryEvidence {
607
+ grounding: GroundingValue;
608
+ seen_in_traces: boolean;
609
+ /** honest `k/n sampled` — NOT corpus-extrapolated. */
610
+ prevalence: string;
611
+ /** GA-1: structured, RE-RESOLVABLE grounding refs. REQUIRED non-empty for
612
+ * OBSERVED, and ≥1 must re-resolve exact-match when traces are supplied. */
613
+ refs: DiscoveryRef[];
614
+ }
615
+
616
+ /** §5c expected impact = severity × coverage × discovery-confidence. */
617
+ export interface DiscoveryExpectedImpact {
618
+ severity: SeverityValue;
619
+ /** `stages/cases` the metric covers. */
620
+ coverage: string;
621
+ confidence: ConfidenceValue;
622
+ }
623
+
624
+ /** §5c (DR-2) — the per-criterion discovery-rationale block (evidence-first). */
625
+ export interface DiscoveryRationale {
626
+ /** the behavior / failure mode this criterion guards. */
627
+ targets: string;
628
+ /** the user/business/correctness consequence if it fails. */
629
+ why_problem: string;
630
+ evidence: DiscoveryEvidence;
631
+ /** trace observation → category → criterion (the decision path). */
632
+ reasoning: string;
633
+ assumptions: DiscoveryAssumption[];
634
+ expected_impact: DiscoveryExpectedImpact;
635
+ fix_or_eval: "eval-worthy" | "fixable->diagnostics";
636
+ }
637
+
638
+ /**
639
+ * A mined criterion = a `DiscoveredCriterion` + the §5b metadata + the §5c DR-2
640
+ * rationale. The output of the real `*discover-evals` AGGREGATE path.
641
+ */
642
+ export interface MinedCriterion extends DiscoveredCriterion {
643
+ metadata: MetricMetadata;
644
+ discovery: DiscoveryRationale;
645
+ /**
646
+ * The EXECUTABLE code-check reference (the uniform-standard companion of the
647
+ * human-readable `statement`). REQUIRED when `metadata.check_method` is
648
+ * `deterministic` or `hybrid` (enforced by `lint-uniformity.ts`, not TypeBox —
649
+ * the schema keeps it OPTIONAL so a pure `llm-judge` criterion omits it and
650
+ * legacy criteria stay valid). When present it is run by `runCodeEval` in the
651
+ * tier-0 pre-pass (zero judge tokens, byte-identical). Reuses the existing
652
+ * `CodeEvalSpec` registry — no new check vocabulary.
653
+ */
654
+ codeEval?: CodeEvalSpec;
655
+ }
656
+
657
+ // ── TypeBox schemas (closed objects) ────────────────────────────────────────
658
+
659
+ /**
660
+ * The CANONICAL TypeBox companion of `code-eval.ts` `CodeEvalSpec` — the single
661
+ * source of truth for validating a code-eval spec on ANY criterion (mined OR the
662
+ * judging-matrix row). `contracts/eval-matrix.ts` re-exports this as
663
+ * `MatrixCodeEvalSchema` so the two surfaces accept BYTE-IDENTICAL specs (no
664
+ * drift). Each member is a closed object; the union is exhaustive over the 7
665
+ * primitives the runtime `runCodeEval` handles (a `tests/` sync test asserts the
666
+ * schema set == the runtime switch set). Kept HERE (not in eval-matrix) so the
667
+ * MinedCriterion schema can reference it WITHOUT a runtime import cycle.
668
+ */
669
+ export const CodeEvalSpecSchema = Type.Union([
670
+ Type.Object(
671
+ { primitive: Type.Literal("presence"), field: Type.String({ minLength: 1 }) },
672
+ { additionalProperties: false },
673
+ ),
674
+ Type.Object(
675
+ {
676
+ primitive: Type.Literal("string-equality"),
677
+ field: Type.String({ minLength: 1 }),
678
+ expected: Type.String(),
679
+ caseInsensitive: Type.Optional(Type.Boolean()),
680
+ },
681
+ { additionalProperties: false },
682
+ ),
683
+ Type.Object(
684
+ { primitive: Type.Literal("format-validity"), field: Type.String({ minLength: 1 }), pattern: Type.String({ minLength: 1 }) },
685
+ { additionalProperties: false },
686
+ ),
687
+ Type.Object(
688
+ {
689
+ primitive: Type.Literal("schema-conformance"),
690
+ field: Type.String({ minLength: 1 }),
691
+ requiredKeys: Type.Array(Type.String({ minLength: 1 })),
692
+ },
693
+ { additionalProperties: false },
694
+ ),
695
+ Type.Object(
696
+ { primitive: Type.Literal("ref-integrity"), producer: Type.String({ minLength: 1 }), consumer: Type.String({ minLength: 1 }) },
697
+ { additionalProperties: false },
698
+ ),
699
+ Type.Object(
700
+ {
701
+ primitive: Type.Literal("recovery-after-failure"),
702
+ failField: Type.String({ minLength: 1 }),
703
+ failEquals: Type.String(),
704
+ recoveryTools: Type.Array(Type.String({ minLength: 1 })),
705
+ },
706
+ { additionalProperties: false },
707
+ ),
708
+ Type.Object(
709
+ {
710
+ primitive: Type.Literal("tool-output-failure"),
711
+ tool: Type.String({ minLength: 1 }),
712
+ successPath: Type.String({ minLength: 1 }),
713
+ },
714
+ { additionalProperties: false },
715
+ ),
716
+ ]);
717
+
718
+ export const MetricMetadataSchema = Type.Object(
719
+ {
720
+ generality: Type.Union([
721
+ Type.Literal(Generality.GeneralStructural),
722
+ Type.Literal(Generality.SpecificSemantic),
723
+ ]),
724
+ dimension: Type.Union([
725
+ Type.Literal(MetricDimension.OperationCorrectness),
726
+ Type.Literal(MetricDimension.DataCorrectness),
727
+ Type.Literal(MetricDimension.OperationalDeviation),
728
+ ]),
729
+ level: Type.Union([
730
+ Type.Literal(MetricLevel.Context),
731
+ Type.Literal(MetricLevel.Output),
732
+ Type.Literal(MetricLevel.CrossStage),
733
+ ]),
734
+ check_method: Type.Union([
735
+ Type.Literal(CheckMethod.Deterministic),
736
+ Type.Literal(CheckMethod.LlmJudge),
737
+ Type.Literal(CheckMethod.Hybrid),
738
+ ]),
739
+ substrate: Type.Union([
740
+ Type.Literal(MetricSubstrate.Code),
741
+ Type.Literal(MetricSubstrate.Judge),
742
+ ]),
743
+ applies_to: Type.Array(Type.String()),
744
+ severity: Type.Union([
745
+ Type.Literal(Severity.Crit),
746
+ Type.Literal(Severity.High),
747
+ Type.Literal(Severity.Med),
748
+ Type.Literal(Severity.Low),
749
+ ]),
750
+ judge_inputs: Type.Array(Type.String({ minLength: 1 })),
751
+ flag: Type.Union([
752
+ Type.Literal(CriterionFlag.EvalWorthy),
753
+ Type.Literal(CriterionFlag.Fixable),
754
+ ]),
755
+ },
756
+ { additionalProperties: false },
757
+ );
758
+
759
+ /** GA-1 — structured grounding ref (closed object). */
760
+ export const DiscoveryRefSchema = Type.Object(
761
+ {
762
+ obs: Type.String({ minLength: 1 }),
763
+ path: Type.String(),
764
+ value: Type.String({ minLength: 1 }),
765
+ },
766
+ { additionalProperties: false },
767
+ );
768
+
769
+ /** §5c/GA-3 — one assumption + status (+ optional typed `kind`). */
770
+ export const DiscoveryAssumptionSchema = Type.Object(
771
+ {
772
+ text: Type.String({ minLength: 1 }),
773
+ status: Type.Union([
774
+ Type.Literal(AssumptionStatus.Verified),
775
+ Type.Literal(AssumptionStatus.Unverified),
776
+ Type.Literal(AssumptionStatus.Hypothesis),
777
+ Type.Literal(AssumptionStatus.Eliminated),
778
+ ]),
779
+ kind: Type.Optional(
780
+ Type.Union([
781
+ Type.Literal(AssumptionKind.FactualIntent),
782
+ Type.Literal(AssumptionKind.Normative),
783
+ Type.Literal(AssumptionKind.Scope),
784
+ ]),
785
+ ),
786
+ },
787
+ { additionalProperties: false },
788
+ );
789
+
790
+ export const DiscoveryRationaleSchema = Type.Object(
791
+ {
792
+ targets: Type.String({ minLength: 1 }),
793
+ why_problem: Type.String({ minLength: 1 }),
794
+ evidence: Type.Object(
795
+ {
796
+ grounding: Type.Union([
797
+ Type.Literal(Grounding.Observed),
798
+ Type.Literal(Grounding.Inferred),
799
+ Type.Literal(Grounding.HypothesisPending),
800
+ ]),
801
+ seen_in_traces: Type.Boolean(),
802
+ prevalence: Type.String({ minLength: 1 }),
803
+ refs: Type.Array(DiscoveryRefSchema),
804
+ },
805
+ { additionalProperties: false },
806
+ ),
807
+ reasoning: Type.String({ minLength: 1 }),
808
+ assumptions: Type.Array(DiscoveryAssumptionSchema),
809
+ expected_impact: Type.Object(
810
+ {
811
+ severity: Type.Union([
812
+ Type.Literal(Severity.Crit),
813
+ Type.Literal(Severity.High),
814
+ Type.Literal(Severity.Med),
815
+ Type.Literal(Severity.Low),
816
+ ]),
817
+ coverage: Type.String(),
818
+ confidence: Type.Union([
819
+ Type.Literal(Confidence.High),
820
+ Type.Literal(Confidence.Med),
821
+ Type.Literal(Confidence.Low),
822
+ ]),
823
+ },
824
+ { additionalProperties: false },
825
+ ),
826
+ fix_or_eval: Type.Union([
827
+ Type.Literal("eval-worthy"),
828
+ Type.Literal("fixable->diagnostics"),
829
+ ]),
830
+ },
831
+ { additionalProperties: false },
832
+ );
833
+
834
+ export const MinedCriterionSchema = Type.Object(
835
+ {
836
+ id: Type.String({ minLength: 1 }),
837
+ statement: Type.String({ minLength: 1 }),
838
+ judgeInputs: Type.Array(Type.String({ minLength: 1 })),
839
+ judgeKind: Type.Union([
840
+ Type.Literal(JudgeKind.Llm),
841
+ Type.Literal(JudgeKind.Code),
842
+ Type.Literal(JudgeKind.Hybrid),
843
+ ]),
844
+ flag: Type.Union([
845
+ Type.Literal(CriterionFlag.EvalWorthy),
846
+ Type.Literal(CriterionFlag.Fixable),
847
+ ]),
848
+ supportCount: Type.Integer({ minimum: 0 }),
849
+ metadata: MetricMetadataSchema,
850
+ discovery: DiscoveryRationaleSchema,
851
+ /** the executable code-check reference (uniform standard); OPTIONAL at the
852
+ * schema layer — `lint-uniformity.ts` enforces presence by check_method. */
853
+ codeEval: Type.Optional(CodeEvalSpecSchema),
854
+ },
855
+ { additionalProperties: false },
856
+ );
857
+ export type MinedCriterionStatic = Static<typeof MinedCriterionSchema>;
858
+
859
+ /**
860
+ * Validate + narrow an unknown value to `MinedCriterion`. THROWS with the first
861
+ * schema error. Additionally enforces the §5c EVIDENCE-FIRST guard that TypeBox
862
+ * can't express: a criterion grounded `observed` MUST cite ≥1 ref AND a non-zero
863
+ * prevalence numerator — an INFERRED claim may never be rendered as OBSERVED.
864
+ */
865
+ export function parseMinedCriterion(value: unknown): MinedCriterion {
866
+ if (!Value.Check(MinedCriterionSchema, value)) {
867
+ const first = [...Value.Errors(MinedCriterionSchema, value)][0];
868
+ const where = first?.path ?? "(root)";
869
+ const msg = first?.message ?? "does not match MinedCriterion";
870
+ throw new Error(`parseMinedCriterion: invalid mined criterion at ${where}: ${msg}`);
871
+ }
872
+ assertGroundingHonest(value as MinedCriterion);
873
+ return value as MinedCriterion;
874
+ }
875
+
876
+ /**
877
+ * §5c/GA-1 HARD evidence-first gate. An `observed` grounding REQUIRES:
878
+ * (a) ≥1 cited ref, AND
879
+ * (b) a non-zero prevalence numerator (k>0 in "k/n"), AND
880
+ * (c) GA-1: when `traces` are supplied, ≥1 ref must RE-RESOLVE exact-match
881
+ * against the trace batch (an `observed` claim whose refs no longer resolve
882
+ * is an inferred-as-observed defect and is REJECTED).
883
+ * THROWS otherwise — never present an INFERRED criterion as a found defect. The
884
+ * `traces` arg is OPTIONAL so the structural gate (a,b) still runs for legacy
885
+ * callers (e.g. `parseMinedCriterion`) that have no trace batch at hand.
886
+ */
887
+ export function assertGroundingHonest(c: MinedCriterion, traces?: EvalTrace[]): void {
888
+ const ev = c.discovery.evidence;
889
+ if (ev.grounding !== Grounding.Observed) return;
890
+ if (ev.refs.length === 0) {
891
+ throw new Error(
892
+ `assertGroundingHonest: criterion '${c.id}' is grounded 'observed' but cites ` +
893
+ "NO refs — an observed defect must cite real trace refs (evidence-first; " +
894
+ "never render inferred-as-observed).",
895
+ );
896
+ }
897
+ const k = parsePrevalenceNumerator(ev.prevalence);
898
+ if (k <= 0) {
899
+ throw new Error(
900
+ `assertGroundingHonest: criterion '${c.id}' is grounded 'observed' but its ` +
901
+ `prevalence '${ev.prevalence}' has a zero numerator — observed requires k>0.`,
902
+ );
903
+ }
904
+ if (traces !== undefined && traces.length > 0) {
905
+ const anyResolves = ev.refs.some((r) => resolveRef(r, traces).resolved);
906
+ if (!anyResolves) {
907
+ throw new Error(
908
+ `assertGroundingHonest: criterion '${c.id}' is grounded 'observed' but NONE ` +
909
+ "of its refs RE-RESOLVE (exact, whitespace-normalized) against the trace " +
910
+ "batch — an observed claim must cite a value that is actually present (GA-1).",
911
+ );
912
+ }
913
+ }
914
+ }
915
+
916
+ /** Parse the `k` from a `k/n` prevalence string; returns 0 when unparseable. */
917
+ export function parsePrevalenceNumerator(prevalence: string): number {
918
+ const m = /^\s*(\d+)\s*\/\s*(\d+)/.exec(prevalence);
919
+ if (m === null) return 0;
920
+ const k = Number.parseInt(m[1], 10);
921
+ return Number.isNaN(k) ? 0 : k;
922
+ }
923
+
924
+ // ════════════════════════════════════════════════════════════════════════════
925
+ // GA-1/GA-2 — resolve-ref primitive (the BIND + GATHER guard core, PURE)
926
+ // ────────────────────────────────────────────────────────────────────────────
927
+ // `resolveRef` is the single deterministic primitive both guards ride:
928
+ // · GA-1 GATHER — an `observed` criterion's evidence refs must re-resolve.
929
+ // · GA-2 BIND — at judge time every criterion TERM (its referents) must
930
+ // resolve to a grounded referent in the SITUATION trace, else
931
+ // the verdict is indeterminate(factual-intent), NOT a fail.
932
+ // "Exact value match (whitespace-normalized)" = the normalized ref value occurs
933
+ // verbatim (as a substring token) in the normalized serialization of the value
934
+ // AT the cited `obs`+`path` — NOT anywhere in the batch. No fuzzy / no semantic
935
+ // match — the honest, deterministic, byte-reproducible cut.
936
+ //
937
+ // GA-D1 (obs+path-aware): the earlier resolver substring-matched the value
938
+ // ANYWHERE in the batch and ignored the cited `obs`/`path`, so a ref could
939
+ // "resolve" against the WRONG observation (a value minted in obs A also occurring
940
+ // in an unrelated obs B was scored resolved:true). That overstates grounding —
941
+ // an inferred-as-observed defect. `resolveRef` now LOCATES the cited `obs`, reads
942
+ // the value AT `path`, and asserts exact-equality THERE. obs not found / path
943
+ // absent / value mismatch ⇒ UNRESOLVED (correctly demoting observed→inferred via
944
+ // `assertGroundingHonest`).
945
+ // ════════════════════════════════════════════════════════════════════════════
946
+
947
+ /** Whitespace-normalize + lowercase for exact-match comparison. PURE. */
948
+ export function normalizeRefText(s: string): string {
949
+ return s.replace(/\s+/g, " ").trim().toLowerCase();
950
+ }
951
+
952
+ /** The result of resolving one ref against a trace batch. */
953
+ export interface RefResolution {
954
+ ref: DiscoveryRef;
955
+ resolved: boolean;
956
+ /** the id of the trace the value was found in (when resolved). */
957
+ matchedIn?: string;
958
+ }
959
+
960
+ /** Serialize an arbitrary value to a flat searchable string. PURE. */
961
+ function serializeValue(v: unknown): string {
962
+ if (v === null || v === undefined) return "";
963
+ if (typeof v === "string") return v;
964
+ try {
965
+ return JSON.stringify(v);
966
+ } catch {
967
+ return String(v);
968
+ }
969
+ }
970
+
971
+ /**
972
+ * Locate the trace the ref's `obs` names. An `obs` id may name the TRACE itself
973
+ * (top-level `id`) or one of its observations (by `name`). Returns the FIRST
974
+ * trace (in batch order) whose id equals `obs` OR that carries an observation
975
+ * named `obs` (exact, whitespace-normalized). `undefined` when `obs` names
976
+ * neither — which makes the ref UNRESOLVED (no whole-batch fall-back). PURE.
977
+ */
978
+ function locateByObs(obs: string, traces: EvalTrace[]): EvalTrace | undefined {
979
+ const key = normalizeRefText(obs);
980
+ if (key.length === 0) return undefined;
981
+ return traces.find(
982
+ (t) =>
983
+ normalizeRefText(t.id) === key ||
984
+ t.observations.some((o) => normalizeRefText(o.name ?? "") === key),
985
+ );
986
+ }
987
+
988
+ /**
989
+ * Read the value at a dotted `path` (e.g. `output.response`, `observations.0.output`)
990
+ * out of a trace. Numeric segments index arrays. Returns `undefined` when ANY
991
+ * segment is absent (no value at that path) — the caller treats that as
992
+ * UNRESOLVED. An empty path reads the whole trace object. PURE.
993
+ */
994
+ function readPath(root: unknown, path: string): unknown {
995
+ const segments = path.split(".").map((s) => s.trim()).filter((s) => s.length > 0);
996
+ let cur: unknown = root;
997
+ for (const seg of segments) {
998
+ if (cur === null || cur === undefined) return undefined;
999
+ if (Array.isArray(cur)) {
1000
+ const idx = Number.parseInt(seg, 10);
1001
+ if (Number.isNaN(idx) || idx < 0 || idx >= cur.length) return undefined;
1002
+ cur = cur[idx];
1003
+ continue;
1004
+ }
1005
+ if (typeof cur === "object") {
1006
+ const rec = cur as Record<string, unknown>;
1007
+ if (!Object.prototype.hasOwnProperty.call(rec, seg)) return undefined;
1008
+ cur = rec[seg];
1009
+ continue;
1010
+ }
1011
+ // a primitive with path remaining ⇒ the path does not exist.
1012
+ return undefined;
1013
+ }
1014
+ return cur;
1015
+ }
1016
+
1017
+ /**
1018
+ * Resolve one structured ref against a batch of traces. GA-D1 obs+path-aware:
1019
+ * 1. LOCATE the trace/observation the ref's `obs` names (no batch fall-back —
1020
+ * an `obs` that names nothing in the batch is UNRESOLVED).
1021
+ * 2. READ the value AT the cited `path` within that trace (an absent path is
1022
+ * UNRESOLVED — never a whole-trace scan).
1023
+ * 3. EXACT (whitespace-normalized) substring match of `value` against the
1024
+ * serialized value-at-path.
1025
+ * Returns the located trace id in `matchedIn` on a match. PURE — same (ref,
1026
+ * traces) ⇒ same resolution.
1027
+ */
1028
+ export function resolveRef(ref: DiscoveryRef, traces: EvalTrace[]): RefResolution {
1029
+ const needle = normalizeRefText(ref.value);
1030
+ if (needle.length === 0) return { ref, resolved: false };
1031
+ // (1) the cited obs MUST name a trace/observation in the batch.
1032
+ const located = locateByObs(ref.obs, traces);
1033
+ if (located === undefined) return { ref, resolved: false };
1034
+ // (2) read the value AT the cited path (absent path ⇒ unresolved).
1035
+ const at = readPath(located, ref.path);
1036
+ if (at === undefined) return { ref, resolved: false };
1037
+ // (3) exact (whitespace-normalized) value match AT that path.
1038
+ if (normalizeRefText(serializeValue(at)).includes(needle)) {
1039
+ return { ref, resolved: true, matchedIn: located.id };
1040
+ }
1041
+ return { ref, resolved: false };
1042
+ }
1043
+
1044
+ /** The result of binding a criterion's terms (its referents) to a situation. */
1045
+ export interface BindResult {
1046
+ bound: boolean;
1047
+ /** refs that did NOT resolve in the situation — each an unbound term. */
1048
+ unbound: DiscoveryRef[];
1049
+ }
1050
+
1051
+ /**
1052
+ * GA-2 L1 BIND — does every referent VALUE the criterion presupposes have a
1053
+ * grounded referent in the SITUATION trace(s)? A criterion's referents are its
1054
+ * discovery evidence refs (extendable via `extraTerms`). If ANY referent is
1055
+ * unbound the verdict must be `indeterminate(factual-intent)`, never a fail.
1056
+ *
1057
+ * NOTE (vs GA-1 GATHER): a ref's `obs` names the DISCOVERY-time trace it was
1058
+ * minted from — at judge time the SITUATION is a DIFFERENT trace with an
1059
+ * unrelated id. So BIND asks the value-presence question against the situation
1060
+ * itself (re-pointing each referent's `obs` to each situation trace), NOT the
1061
+ * obs-fidelity question `resolveRef` answers for GATHER. A referent binds iff its
1062
+ * value is present in some situation trace. PURE.
1063
+ */
1064
+ export function bindCriterionTerms(
1065
+ refs: DiscoveryRef[],
1066
+ situation: EvalTrace[],
1067
+ extraTerms: DiscoveryRef[] = [],
1068
+ ): BindResult {
1069
+ const all = [...refs, ...extraTerms];
1070
+ const boundInSituation = (r: DiscoveryRef): boolean =>
1071
+ situation.some((t) => resolveRef({ ...r, obs: t.id, path: "" }, [t]).resolved);
1072
+ const unbound = all.filter((r) => !boundInSituation(r));
1073
+ return { bound: unbound.length === 0, unbound };
1074
+ }