@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,750 @@
1
+ /**
2
+ * scripts/matrix-judge.ts — PREP + AGGREGATE for the EVAL-MATRIX × TRAJECTORY judging cell.
3
+ * ---------------------------------------------------------------------------
4
+ * The DEFAULT `*evaluate` judging path. The reasoning lives in the Judge Agent
5
+ * (`assets/agents/eval-matrix-judge.md`); this file is **Type A — deterministic
6
+ * only** (no judge prompt, no LLM call). It:
7
+ * PREP — `buildMatrixPacket` / `writeMatrixPacket`: assemble one DATA packet
8
+ * per trajectory (the WHOLE matrix + that trajectory + transcript) for
9
+ * the parent to dispatch to a Judge Agent.
10
+ * AGGREGATE — `aggregateMatrixScorecard`: read the per-trajectory verdict files
11
+ * the Judge Agents wrote, fold each criterion's verdicts across
12
+ * trajectories into one GATE-gradable verdict + a per-trajectory
13
+ * variance view, and roll up via `evaluate.ts` (severity-gated GATE).
14
+ *
15
+ * Per-TRAJECTORY fan-out: one Judge Agent scores the whole matrix for one
16
+ * session → high throughput across many sessions. Folding policy (binary GATE):
17
+ * a criterion is PASS only if it passes on EVERY judged trajectory; any fail →
18
+ * fail; else (no fail, ≥1 uncertain) → uncertain. The per-trajectory scores feed
19
+ * the variance view. PURE — same inputs ⇒ identical scorecard.
20
+ */
21
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
22
+ import { join } from "node:path";
23
+ import {
24
+ assertMatrixPacket,
25
+ localizeText,
26
+ parseMatrixVerdictFile,
27
+ type MatrixCriterion,
28
+ type MatrixPacket,
29
+ type MatrixVerdict,
30
+ type MatrixVerdictFile,
31
+ type SubjectProfile,
32
+ type TrajectoryStep,
33
+ type TranscriptTurn,
34
+ } from "./contracts/eval-matrix.ts";
35
+ import {
36
+ CheckMethod,
37
+ OutcomeVerdict,
38
+ type CriterionVerdict,
39
+ type EvalTrace,
40
+ type GroundingReadiness,
41
+ type IndependentVerifyRecord,
42
+ type OutcomeVerdictValue,
43
+ } from "./contracts/eval-types.ts";
44
+ import { runCodeEval, type CodeEvalSpec } from "./code-eval.ts";
45
+ import { promptHash, writeJudgeTask, type JudgeTaskSpec, type PinnedEnvelope } from "./agent-dispatch.ts";
46
+ import { verifyVerdict, type VerifierSignal } from "./result-verify.ts";
47
+ import { Severity, type SeverityValue } from "./contracts/types.ts";
48
+ import {
49
+ rollupScorecard,
50
+ type CriterionReruns,
51
+ type GradedCriterion,
52
+ type Scorecard,
53
+ } from "./evaluate.ts";
54
+
55
+ /** A stable, filename-safe key for a trajectory id (content hash; no clock/random). */
56
+ export function trajectoryKey(trajectoryId: string): string {
57
+ return promptHash(trajectoryId, "trajectory");
58
+ }
59
+
60
+ export function packetFileName(trajectoryId: string): string {
61
+ return `${trajectoryKey(trajectoryId)}.packet.json`;
62
+ }
63
+ export function matrixVerdictFileName(trajectoryId: string): string {
64
+ return `${trajectoryKey(trajectoryId)}.verdict.json`;
65
+ }
66
+
67
+ /** Extract the ordered tool trajectory (DATA) from a trace. */
68
+ function trajectoryOf(trace: EvalTrace): TrajectoryStep[] {
69
+ return trace.observations
70
+ .filter((o) => o.type === "TOOL")
71
+ .map((o) => ({
72
+ name: o.name ?? "?",
73
+ ...(o.input !== undefined ? { input: o.input } : {}),
74
+ ...(o.output !== undefined ? { output: o.output } : {}),
75
+ }));
76
+ }
77
+
78
+ /** Build the minimal transcript (DATA) from a trace's input/output. */
79
+ function transcriptOf(trace: EvalTrace): TranscriptTurn[] {
80
+ const turns: TranscriptTurn[] = [];
81
+ const prompt = typeof trace.input?.prompt === "string" ? trace.input.prompt : "";
82
+ if (prompt.length > 0) turns.push({ role: "user", content: prompt });
83
+ const resp = typeof trace.output?.response === "string" ? trace.output.response : "";
84
+ if (resp.length > 0) turns.push({ role: "assistant", content: resp });
85
+ return turns;
86
+ }
87
+
88
+ // ── T1 (B-U3) tier-0 deterministic pre-pass ──────────────────────────────────
89
+ //
90
+ // THE real cost lever (§9.4.1): run the code-method rows FIRST (deterministic,
91
+ // zero judge tokens, byte-identical), then dispatch ONLY the residual judge rows.
92
+ // A criterion routes by its OPTIONAL `checkMethod` (absent ⇒ `llm-judge`, so an
93
+ // all-judge matrix is byte-stable — every row stays in the packet):
94
+ // - `deterministic` → CODE-EXEC in the pre-pass; NOT dispatched.
95
+ // - `hybrid` → CODE pre-filter in the pre-pass; if code FAILS the judge is
96
+ // GATED OFF (the code-fail IS the verdict); if code PASSES the
97
+ // row stays residual for the judge to confirm the subjective half.
98
+ // - `llm-judge`/absent → residual (dispatched to the judge).
99
+ // FAIL-LOUD: a code-routed row with no `codeEval` spec THROWS (never silently judged).
100
+
101
+ /** One trajectory's tier-0 result: the deterministic code verdicts + the residual
102
+ * judge criteria that still need dispatching for THIS trajectory. PURE. */
103
+ export interface Tier0Result {
104
+ codeVerdicts: MatrixVerdict[];
105
+ residualCriteria: MatrixCriterion[];
106
+ }
107
+
108
+ function codeMethodOf(c: MatrixCriterion): "deterministic" | "llm-judge" | "hybrid" {
109
+ return c.checkMethod ?? CheckMethod.LlmJudge;
110
+ }
111
+
112
+ /** Run one matrix row's extracted code-eval into a MatrixVerdict (confidence 1). */
113
+ function matrixCodeVerdict(c: MatrixCriterion, trace: EvalTrace): MatrixVerdict {
114
+ if (c.codeEval === undefined) {
115
+ throw new Error(
116
+ `tier0PrePass: criterion '${c.criterionId}' is checkMethod=${codeMethodOf(c)} but carries ` +
117
+ "no `codeEval` spec. Code-routed matrix rows REQUIRE an extracted code-eval; refusing to " +
118
+ "silently LLM-judge a row typed as code (T1 / M1).",
119
+ );
120
+ }
121
+ const code = runCodeEval(c.codeEval as CodeEvalSpec, trace);
122
+ return {
123
+ criterionId: c.criterionId,
124
+ critique: code.detail,
125
+ result: code.result === "pass" ? OutcomeVerdict.Pass : OutcomeVerdict.Fail,
126
+ confidence: 1,
127
+ };
128
+ }
129
+
130
+ /**
131
+ * Tier-0 pre-pass for ONE trajectory: route every criterion by `checkMethod`,
132
+ * run the code rows now, and return the residual judge rows. DETERMINISTIC +
133
+ * PURE (the code-eval is a pure function of (spec, trace)); criteria order is
134
+ * preserved so the residual packet + merged scorecard are byte-stable.
135
+ */
136
+ export function tier0PrePass(criteria: MatrixCriterion[], trace: EvalTrace): Tier0Result {
137
+ const codeVerdicts: MatrixVerdict[] = [];
138
+ const residualCriteria: MatrixCriterion[] = [];
139
+ for (const c of criteria) {
140
+ const method = codeMethodOf(c);
141
+ if (method === CheckMethod.LlmJudge) {
142
+ residualCriteria.push(c);
143
+ continue;
144
+ }
145
+ if (method === CheckMethod.Deterministic) {
146
+ codeVerdicts.push(matrixCodeVerdict(c, trace));
147
+ continue;
148
+ }
149
+ // hybrid — code pre-filter; fail short-circuits, pass falls through to the judge.
150
+ const v = matrixCodeVerdict(c, trace);
151
+ if (v.result === OutcomeVerdict.Fail) codeVerdicts.push(v);
152
+ else residualCriteria.push(c);
153
+ }
154
+ return { codeVerdicts, residualCriteria };
155
+ }
156
+
157
+ // ── #3 (§9.4.2 node 1) EXAMINE fidelity gate — the DETERMINISTIC short-circuit ─
158
+ //
159
+ // The judge's node-1 fidelity gate says "a truncated trace EXITS early as
160
+ // INCOMPLETE — never fabricate a pass/fail from a partial trace." That gate must
161
+ // ACTUALLY short-circuit: a truncated trajectory is NEVER walked per-criterion.
162
+ // Where truncation is detectable BEFORE dispatch (an explicit ingestion marker, or
163
+ // a structurally-empty trace), the PIPELINE gates it deterministically — it emits a
164
+ // synthesized INCOMPLETE verdict and never dispatches the full criteria walk (no
165
+ // judge tokens spent reading a partial trace). PURE — no clock/random/network.
166
+
167
+ /** The deterministic EXAMINE fidelity verdict for one trace. */
168
+ export interface TraceFidelity {
169
+ complete: boolean;
170
+ reason?: string;
171
+ }
172
+
173
+ /**
174
+ * Deterministic pre-judge fidelity gate (§9.4.2 node 1). A trace is INCOMPLETE iff
175
+ * (a) the ingestion layer explicitly marked it `incomplete:true` (a truncated /
176
+ * unterminated session), OR (b) it is STRUCTURALLY EMPTY — no observations AND no
177
+ * `output.response` (literally nothing to judge). Conservative by design: anything
178
+ * with a tool step OR a response is `complete` and judged normally (the judge's own
179
+ * node-1 gate still catches subtler truncation at reason-time). PURE.
180
+ */
181
+ export function assessTraceFidelity(trace: EvalTrace): TraceFidelity {
182
+ if (trace.incomplete === true) {
183
+ return {
184
+ complete: false,
185
+ reason:
186
+ trace.incompleteReason ??
187
+ "trace marked incomplete by the ingestion layer (truncated / unterminated session).",
188
+ };
189
+ }
190
+ const hasObservations = trace.observations.length > 0;
191
+ const hasResponse = typeof trace.output?.response === "string" && trace.output.response.length > 0;
192
+ if (!hasObservations && !hasResponse) {
193
+ return {
194
+ complete: false,
195
+ reason:
196
+ "trace is structurally empty: no observations and no output.response — nothing to judge (truncated capture).",
197
+ };
198
+ }
199
+ return { complete: true };
200
+ }
201
+
202
+ /**
203
+ * Synthesize the INCOMPLETE `MatrixVerdictFile` for a truncated trajectory — the
204
+ * deterministic node-1 short-circuit. Emits `fidelity.complete:false`, an EMPTY
205
+ * `verdicts[]` (the per-criterion loop is SKIPPED — never a fabricated verdict from
206
+ * a partial trace), a dense na/uncertain map (every criterion abstains), and a
207
+ * capture-defect `localize`. This file is COLLECTED like a dispatched verdict so the
208
+ * report shows the trajectory as INCOMPLETE — but it contributes NO criterion verdict
209
+ * to the gate fold (empty `verdicts[]`). PURE.
210
+ */
211
+ export function synthesizeIncompleteVerdictFile(
212
+ trace: EvalTrace,
213
+ criteria: MatrixCriterion[],
214
+ pin: { model: string; temperature: 0 },
215
+ fidelity?: TraceFidelity,
216
+ ): MatrixVerdictFile {
217
+ const fid = fidelity ?? assessTraceFidelity(trace);
218
+ const reason = fid.reason ?? "trace truncated / unterminated — emitted INCOMPLETE.";
219
+ const denseMap: Record<string, OutcomeVerdictValue | "na"> = {};
220
+ for (const c of criteria) denseMap[c.criterionId] = OutcomeVerdict.Uncertain;
221
+ return {
222
+ trajectoryId: trace.id,
223
+ judgeModel: pin.model,
224
+ temperature: 0,
225
+ fidelity: { complete: false, reason },
226
+ judgeSteps: [
227
+ {
228
+ kind: "examine",
229
+ text: `EXAMINE — fidelity gate (node 1): ${reason} STOP early: emitted INCOMPLETE, the per-criterion loop is SKIPPED (no fabricated verdict from a partial trace).`,
230
+ anchor: 0,
231
+ },
232
+ ],
233
+ verdicts: [],
234
+ denseMap,
235
+ localize: `Capture/fidelity defect (ROOT): ${reason} Not a subject behavioural defect — verdict is INCOMPLETE.`,
236
+ health: { contextGathered: true, grounded: 0, assumed: 0, stoppedAtSymptom: false },
237
+ };
238
+ }
239
+
240
+ /** PREP — write one synthesized/dispatched verdict file per trajectory into `dir`. */
241
+ export function writeMatrixVerdictFile(dir: string, file: MatrixVerdictFile): string {
242
+ mkdirSync(dir, { recursive: true });
243
+ writeFileSync(join(dir, matrixVerdictFileName(file.trajectoryId)), JSON.stringify(file, null, 2));
244
+ return file.trajectoryId;
245
+ }
246
+
247
+ // ── T5 (B-U4) adaptive-K + overload guard ────────────────────────────────────
248
+ //
249
+ // `prepMatrixPackets` is hardwired 1:1 (one packet per trajectory). T5 adds the
250
+ // CONTEXT-BUDGET ESTIMATOR + a K-BATCHER that groups trajectories into 1:K packets
251
+ // ONLY when they FIT a token budget AND stay ISOLATED (same cohort). DEFAULT K=1 →
252
+ // every trajectory is its own group → byte-identical to today. The OVERLOAD GUARD:
253
+ // a trajectory whose own estimate already exceeds the budget is NEVER batched
254
+ // (flagged `overBudget`); a batch is closed the moment the next trajectory would
255
+ // blow the budget. PURE — a rough chars/4 heuristic, no clock/random/network.
256
+
257
+ /** Rough context-token estimate of a one-trajectory matrix packet (chars/4). */
258
+ export function estimateMatrixPacketTokens(criteria: MatrixCriterion[], trace: EvalTrace): number {
259
+ const criteriaChars = JSON.stringify(criteria).length;
260
+ const trajChars = JSON.stringify(trajectoryOf(trace)).length;
261
+ const transcriptChars = JSON.stringify(transcriptOf(trace)).length;
262
+ return Math.ceil((criteriaChars + trajChars + transcriptChars) / 4);
263
+ }
264
+
265
+ /** One adaptive-K group: the trajectory ids batched into a single judging packet. */
266
+ export interface PacketGroup {
267
+ trajectoryIds: string[];
268
+ estTokens: number;
269
+ /** true iff a SINGLE trajectory already exceeded the budget (never batched). */
270
+ overBudget: boolean;
271
+ }
272
+
273
+ export interface AdaptiveKItem {
274
+ trajectoryId: string;
275
+ estTokens: number;
276
+ /** the ISOLATION key — only same-key trajectories may share a group (default: the id → fully isolated). */
277
+ isolationKey?: string;
278
+ }
279
+
280
+ export interface AdaptiveKOptions {
281
+ /** max trajectories per packet. DEFAULT 1 (1:1 — the headline default). */
282
+ maxK?: number;
283
+ /** per-packet context-token budget. DEFAULT Infinity (no budget pressure). */
284
+ tokenBudget?: number;
285
+ }
286
+
287
+ /**
288
+ * Plan adaptive 1:K packet groups. Greedy, ORDER-PRESERVING: items accumulate into
289
+ * a group while `group.length < maxK` AND the running estimate stays ≤ budget AND
290
+ * the isolation key matches; otherwise a new group opens. An item that ALONE exceeds
291
+ * the budget is its own `overBudget` singleton (the overload guard — never batched).
292
+ * Default (maxK=1) ⇒ one singleton per item (byte-identical to the 1:1 path). PURE.
293
+ */
294
+ export function planAdaptivePackets(items: AdaptiveKItem[], opts: AdaptiveKOptions = {}): PacketGroup[] {
295
+ const maxK = Math.max(1, opts.maxK ?? 1);
296
+ const budget = opts.tokenBudget ?? Number.POSITIVE_INFINITY;
297
+ const groups: PacketGroup[] = [];
298
+ let cur: { ids: string[]; est: number; key: string } | null = null;
299
+ const flush = (): void => {
300
+ if (cur !== null) {
301
+ groups.push({ trajectoryIds: cur.ids, estTokens: cur.est, overBudget: false });
302
+ cur = null;
303
+ }
304
+ };
305
+ for (const it of items) {
306
+ const key = it.isolationKey ?? it.trajectoryId;
307
+ // overload guard: a single item over budget is an un-batchable singleton.
308
+ if (it.estTokens > budget) {
309
+ flush();
310
+ groups.push({ trajectoryIds: [it.trajectoryId], estTokens: it.estTokens, overBudget: true });
311
+ continue;
312
+ }
313
+ const fits =
314
+ cur !== null && cur.key === key && cur.ids.length < maxK && cur.est + it.estTokens <= budget;
315
+ if (!fits) {
316
+ flush();
317
+ cur = { ids: [], est: 0, key };
318
+ }
319
+ cur!.ids.push(it.trajectoryId);
320
+ cur!.est += it.estTokens;
321
+ }
322
+ flush();
323
+ return groups;
324
+ }
325
+
326
+ /**
327
+ * PREP — assemble one MatrixPacket (DATA) for a trajectory: the WHOLE matrix +
328
+ * that trajectory's tool path + transcript. Validates the packet shape. PURE.
329
+ *
330
+ * T1: when `residualCriteria` is supplied (the tier-0 residual judge rows), the
331
+ * packet carries ONLY those — the judge never re-scores a code-decided row. An
332
+ * empty residual set means the trajectory is fully code-decided (no dispatch);
333
+ * the caller skips PREP for it. ABSENT ⇒ the whole matrix (legacy, byte-stable).
334
+ */
335
+ export function buildMatrixPacket(
336
+ subject: string,
337
+ trace: EvalTrace,
338
+ criteria: MatrixCriterion[],
339
+ pin: { model: string; temperature: 0 },
340
+ subjectProfile?: SubjectProfile,
341
+ ): MatrixPacket {
342
+ const packet: MatrixPacket = {
343
+ subject,
344
+ trajectoryId: trace.id,
345
+ criteria,
346
+ trajectory: trajectoryOf(trace),
347
+ transcript: transcriptOf(trace),
348
+ // §9.4.4 M1 — the judge reads WHO the agent is before it judges. ABSENT ⇒
349
+ // byte-stable legacy packet (the judge reconstructs the profile at reason-time).
350
+ ...(subjectProfile !== undefined ? { subjectProfile } : {}),
351
+ pin,
352
+ };
353
+ assertMatrixPacket(packet);
354
+ return packet;
355
+ }
356
+
357
+ /** PREP — write one packet file per trajectory into `dir`. Returns the trajectory ids. */
358
+ export function writeMatrixPacket(dir: string, packet: MatrixPacket): string {
359
+ mkdirSync(dir, { recursive: true });
360
+ writeFileSync(join(dir, packetFileName(packet.trajectoryId)), JSON.stringify(packet, null, 2));
361
+ return packet.trajectoryId;
362
+ }
363
+
364
+ /** verdict → numeric score (pass=1, fail=0, uncertain=0.5) for the variance view. */
365
+ function scoreOf(v: OutcomeVerdictValue): number {
366
+ if (v === OutcomeVerdict.Pass) return 1;
367
+ if (v === OutcomeVerdict.Fail) return 0;
368
+ return 0.5;
369
+ }
370
+
371
+ /**
372
+ * Fold one criterion's verdicts across trajectories into a single GATE-gradable
373
+ * verdict (binary policy: PASS iff all pass; any fail → fail; else uncertain).
374
+ * PURE.
375
+ */
376
+ export function foldCriterionVerdicts(
377
+ criterionId: string,
378
+ perTrajectory: { trajectoryId: string; verdict: MatrixVerdict }[],
379
+ ): { verdict: CriterionVerdict; scores: OutcomeVerdictValue[] } {
380
+ const results = perTrajectory.map((p) => p.verdict.result);
381
+ let folded: OutcomeVerdictValue;
382
+ if (results.some((r) => r === OutcomeVerdict.Fail)) folded = OutcomeVerdict.Fail;
383
+ else if (results.some((r) => r === OutcomeVerdict.Uncertain)) folded = OutcomeVerdict.Uncertain;
384
+ else folded = OutcomeVerdict.Pass;
385
+
386
+ // representative critique: the first failing (else first uncertain, else first) trajectory.
387
+ const lead =
388
+ perTrajectory.find((p) => p.verdict.result === OutcomeVerdict.Fail) ??
389
+ perTrajectory.find((p) => p.verdict.result === OutcomeVerdict.Uncertain) ??
390
+ perTrajectory[0];
391
+ const minConfidence = perTrajectory.reduce((m, p) => Math.min(m, p.verdict.confidence), 1);
392
+
393
+ // GA — NO silent field drop: carry the lead trajectory's refs / assumptions /
394
+ // blockedBy onto the folded verdict. `blockedBy` only meaningful on an
395
+ // indeterminate fold (the lead is the first uncertain when folded=uncertain).
396
+ const verdict: CriterionVerdict = {
397
+ criterionId,
398
+ traceId: lead?.trajectoryId ?? "(suite)",
399
+ result: folded,
400
+ confidence: minConfidence,
401
+ critique: lead?.verdict.critique ?? "(no verdict)",
402
+ };
403
+ if (lead?.verdict.refs !== undefined) verdict.refs = lead.verdict.refs;
404
+ if (lead?.verdict.assumptions !== undefined) verdict.assumptions = lead.verdict.assumptions;
405
+ if (folded === OutcomeVerdict.Uncertain && lead?.verdict.blockedBy !== undefined) {
406
+ verdict.blockedBy = lead.verdict.blockedBy;
407
+ }
408
+
409
+ return { verdict, scores: results };
410
+ }
411
+
412
+ // ── T3 independent verifier (§9.4.2 node 7) ──────────────────────────────────
413
+ //
414
+ // Self-verify (#mode-verify, GA-5) is the FIRST pass. For GATING (CRIT/HIGH) FAILS
415
+ // a SECOND, INDEPENDENT judge is dispatched to REFUTE the verdict — reviewer ≠ the
416
+ // judge that decided. It is DOWNGRADE-ONLY (`result-verify.ts`): it may weaken a
417
+ // fail to `uncertain(blockedBy)` (rolling the run up to INCOMPLETE), never
418
+ // strengthen, never flip. A confirmed fail STANDS. Default OFF (no signals → no
419
+ // change → byte-stable).
420
+
421
+ const DEFAULT_GATING: readonly SeverityValue[] = [Severity.Crit, Severity.High];
422
+
423
+ /** The folded per-criterion verdicts that are GATING FAILS (FAIL ∧ severity ∈ gating). */
424
+ export function gatingFailVerdicts(
425
+ verdicts: CriterionVerdict[],
426
+ severityById: Map<string, string>,
427
+ gatingSeverities?: string[],
428
+ ): CriterionVerdict[] {
429
+ const gating = new Set<string>(gatingSeverities ?? DEFAULT_GATING);
430
+ return verdicts.filter(
431
+ (v) => v.result === OutcomeVerdict.Fail && gating.has(severityById.get(v.criterionId) ?? ""),
432
+ );
433
+ }
434
+
435
+ /**
436
+ * PREP the SECOND-judge REFUTE tasks (T3): one independent-verify task per gating
437
+ * fail, keyed by content hash, with `unit.kind: "verify"`. The dispatched reviewer
438
+ * (a DISTINCT identity) reasons over the SAME situation and tries to REFUTE — it
439
+ * emits a `VerifierSignal {entails, leap?, leapKind?}`. Deterministic file writes.
440
+ */
441
+ export function prepIndependentVerifyTasks(
442
+ dir: string,
443
+ gatingFails: CriterionVerdict[],
444
+ criteriaById: Map<string, MatrixCriterion>,
445
+ pin: PinnedEnvelope,
446
+ ): JudgeTaskSpec[] {
447
+ const specs: JudgeTaskSpec[] = [];
448
+ for (const v of gatingFails) {
449
+ const crit = criteriaById.get(v.criterionId);
450
+ const system = [
451
+ "You are an INDEPENDENT verifier — NOT the judge that produced this verdict.",
452
+ "Your one job: decide whether the JUDGE'S CLAIM actually ENTAILS the FAIL verdict,",
453
+ "or whether there is an inferential leap (a hidden, ungrounded premise). Try to",
454
+ "REFUTE the fail. You are DOWNGRADE-ONLY: you may weaken fail→uncertain, NEVER flip",
455
+ "to pass, NEVER strengthen. Output STRICT JSON:",
456
+ '{ "entails": true|false, "leap": "<residual ungrounded premise if !entails>",',
457
+ ' "leapKind": "factual-intent"|"normative"|"scope" }',
458
+ ].join("\n");
459
+ const user = [
460
+ `Criterion: ${crit?.statement ?? v.criterionId}`,
461
+ `Pass condition: ${crit?.passCondition ?? "(n/a)"}`,
462
+ `Judge verdict: FAIL (confidence ${v.confidence})`,
463
+ `Judge critique:\n${v.critique}`,
464
+ v.refs !== undefined ? `Cited refs: ${JSON.stringify(v.refs)}` : "Cited refs: (none)",
465
+ ].join("\n");
466
+ specs.push(writeJudgeTask(dir, { unit: { kind: "verify", criterionId: v.criterionId, traceId: v.traceId }, system, user, pin }));
467
+ }
468
+ return specs;
469
+ }
470
+
471
+ export interface MatrixAggregateInput {
472
+ criteria: MatrixCriterion[];
473
+ /** the per-trajectory verdict files the Judge Agents wrote (raw JSON text). */
474
+ verdictFilesRaw: string[];
475
+ /** failing criteria at these severities fail the gate (default CRIT+HIGH). */
476
+ gatingSeverities?: string[];
477
+ /**
478
+ * T1 — the tier-0 deterministic code verdicts, per trajectory. Merged into the
479
+ * same per-criterion fold as the judge verdicts so a code-decided row gates
480
+ * exactly like a judged one. ABSENT ⇒ pure-judge aggregate (byte-stable). PURE.
481
+ */
482
+ codeVerdictsByTrajectory?: { trajectoryId: string; verdicts: MatrixVerdict[] }[];
483
+ /**
484
+ * T3 — the independent-verifier signals (criterionId → VerifierSignal) the
485
+ * dispatched 2nd judge produced, + the situation to re-resolve refs over. Applied
486
+ * DOWNGRADE-ONLY to GATING FAILS before the gate rollup (a refuted fail →
487
+ * uncertain → INCOMPLETE). ABSENT ⇒ no second pass (byte-stable). PURE.
488
+ */
489
+ independentVerify?: { situation: EvalTrace[]; signals: Record<string, VerifierSignal> };
490
+ }
491
+
492
+ export interface MatrixAggregateResult {
493
+ scorecard: Scorecard;
494
+ /** the folded per-criterion verdict (for the report's ✓/✗ table). */
495
+ verdicts: CriterionVerdict[];
496
+ /**
497
+ * T3 (§9.4.2 node 7) — the AUDITABLE independent-verify ledger: one record per
498
+ * GATING fail that went through the 2nd-judge refutation pass (upheld or
499
+ * downgraded). EMPTY when no `independentVerify` input was supplied. Mirrors the
500
+ * `independentVerify` field now stamped onto each affected `CriterionVerdict`.
501
+ */
502
+ independentVerify: IndependentVerifyRecord[];
503
+ /**
504
+ * UI-12-A — the GA-1 grounding-capture readiness over the FINAL folded verdicts
505
+ * (computed AFTER any independent-verify downgrade). Threaded so the report's
506
+ * judgeHealth + the run's loud readiness log read the same machine-checkable
507
+ * number. ADVISORY — never gates the run (see `assessGroundingReadiness`).
508
+ */
509
+ groundingReadiness: GroundingReadiness;
510
+ }
511
+
512
+ /**
513
+ * UI-12-A — assess the GA-1 grounding-capture readiness of the folded verdicts.
514
+ *
515
+ * PURE. NEVER throws (judge-only + advisory): a loud `warning` is SET when the
516
+ * silent-capture regression is present (decided verdicts emitted, but ZERO carry a
517
+ * structured `refs[]`). The DENOMINATOR is the DECIDED verdicts (pass|fail) — an
518
+ * `uncertain` abstain legitimately carries `blockedBy` instead of refs and is `na`
519
+ * for grounding, never "ungrounded". Folding abstains/bare-absences into the
520
+ * denominator is exactly what made `groundedPct` read a false 0% (UI-12 audit).
521
+ */
522
+ export function assessGroundingReadiness(verdicts: CriterionVerdict[]): GroundingReadiness {
523
+ const isDecided = (v: CriterionVerdict): boolean =>
524
+ v.result === OutcomeVerdict.Pass || v.result === OutcomeVerdict.Fail;
525
+ const hasRef = (v: CriterionVerdict): boolean => (v.refs?.length ?? 0) > 0;
526
+
527
+ const decided = verdicts.filter(isDecided);
528
+ const grounded = decided.filter(hasRef);
529
+ const abstained = verdicts.filter((v) => v.result === OutcomeVerdict.Uncertain);
530
+ const ungroundedDecided = decided.filter((v) => !hasRef(v)).map((v) => v.criterionId);
531
+
532
+ const readiness: GroundingReadiness = {
533
+ decidedCount: decided.length,
534
+ groundedCount: grounded.length,
535
+ abstainedCount: abstained.length,
536
+ groundedPctOfDecided: decided.length > 0 ? Math.round((100 * grounded.length) / decided.length) : 100,
537
+ ungroundedDecided,
538
+ };
539
+ if (decided.length > 0 && grounded.length === 0) {
540
+ readiness.warning =
541
+ `GA-1 GROUNDING-CAPTURE REGRESSION: ${decided.length} decided verdict(s) emitted, ` +
542
+ "but 0 carry a structured refs[] — groundedPct reads a FALSE 0%. The judge " +
543
+ "(#mode-judge-trajectory) MUST emit refs[]{obs,path,value} grounding EACH decided " +
544
+ "verdict (assets/agents/evaluator.md node 4 GROUND). Abstains (uncertain) are exempt (na).";
545
+ }
546
+ return readiness;
547
+ }
548
+
549
+ /**
550
+ * AGGREGATE — read the per-trajectory Judge Agent verdict files, fold each
551
+ * criterion across trajectories, and roll up the severity-gated GATE + variance
552
+ * view (`evaluate.ts`). Validates every verdict file (critique-before-verdict +
553
+ * closed result set). PURE — same verdict files ⇒ identical scorecard.
554
+ */
555
+ export function aggregateMatrixScorecard(input: MatrixAggregateInput): MatrixAggregateResult {
556
+ const files = input.verdictFilesRaw.map(parseMatrixVerdictFile);
557
+ const severityById = new Map(input.criteria.map((c) => [c.criterionId, c.severity]));
558
+
559
+ // criterionId → per-trajectory verdicts
560
+ const byCriterion = new Map<string, { trajectoryId: string; verdict: MatrixVerdict }[]>();
561
+ for (const file of files) {
562
+ for (const v of file.verdicts) {
563
+ const list = byCriterion.get(v.criterionId) ?? [];
564
+ list.push({ trajectoryId: file.trajectoryId, verdict: v });
565
+ byCriterion.set(v.criterionId, list);
566
+ }
567
+ }
568
+ // T1 — fold the tier-0 code verdicts into the SAME per-criterion map (a code row
569
+ // gates identically to a judged one). Deterministic order: trajectory order as
570
+ // supplied, code verdicts appended after the judge verdicts for that trajectory.
571
+ for (const entry of input.codeVerdictsByTrajectory ?? []) {
572
+ for (const v of entry.verdicts) {
573
+ const list = byCriterion.get(v.criterionId) ?? [];
574
+ list.push({ trajectoryId: entry.trajectoryId, verdict: v });
575
+ byCriterion.set(v.criterionId, list);
576
+ }
577
+ }
578
+
579
+ const graded: GradedCriterion[] = [];
580
+ const reruns: Record<string, CriterionReruns> = {};
581
+ const verdicts: CriterionVerdict[] = [];
582
+
583
+ // iterate criteria in matrix order (deterministic), skipping unjudged ones.
584
+ for (const criterion of input.criteria) {
585
+ const perTraj = byCriterion.get(criterion.criterionId);
586
+ if (perTraj === undefined || perTraj.length === 0) continue;
587
+ const folded = foldCriterionVerdicts(criterion.criterionId, perTraj);
588
+ verdicts.push(folded.verdict);
589
+ graded.push({
590
+ criterionId: criterion.criterionId,
591
+ severity: severityById.get(criterion.criterionId) ?? criterion.severity,
592
+ verdict: folded.verdict,
593
+ });
594
+ reruns[criterion.criterionId] = { scores: folded.scores, trajectories: [] };
595
+ }
596
+ // sort verdict scores are already deterministic; void scoreOf keeps it referenced for clarity.
597
+ void scoreOf;
598
+
599
+ // T3 — independent-verifier pass over GATING FAILS (downgrade-only). A refuted
600
+ // fail weakens to `uncertain(blockedBy)` → the gate rolls up to INCOMPLETE. The
601
+ // verdicts + graded rows are updated in place so the rollup sees the downgrade.
602
+ // EVERY gating fail that went through the 2nd judge gets an AUDITABLE
603
+ // `independentVerify` record stamped on it (upheld OR downgraded) — persisted
604
+ // proof that a DIFFERENT judge ran, not just "eligible for".
605
+ const independentVerify: IndependentVerifyRecord[] = [];
606
+ if (input.independentVerify !== undefined) {
607
+ const { situation, signals } = input.independentVerify;
608
+ const gatingFails = gatingFailVerdicts(verdicts, severityById, input.gatingSeverities);
609
+ const gatingFailIds = new Set(gatingFails.map((v) => v.criterionId));
610
+ for (const v of verdicts) {
611
+ if (!gatingFailIds.has(v.criterionId)) continue;
612
+ const signal = signals[v.criterionId] ?? { entails: true };
613
+ const res = verifyVerdict(v, situation, signal);
614
+ const record: IndependentVerifyRecord = {
615
+ byDifferentJudge: true,
616
+ upheld: !res.downgraded,
617
+ reason: res.reason,
618
+ ...(signal.reviewerId !== undefined ? { reviewerId: signal.reviewerId } : {}),
619
+ ...(res.downgraded && signal.leapKind !== undefined ? { leapKind: signal.leapKind } : {}),
620
+ };
621
+ independentVerify.push({ criterionId: v.criterionId, ...record });
622
+ if (res.downgraded) {
623
+ // mutate the verdict + its graded row to the downgraded (uncertain) verdict.
624
+ Object.assign(v, res.verdict);
625
+ const g = graded.find((gc) => gc.criterionId === v.criterionId);
626
+ if (g !== undefined) g.verdict = res.verdict;
627
+ }
628
+ // stamp the auditable record onto the (possibly-downgraded) folded verdict.
629
+ v.independentVerify = record;
630
+ }
631
+ }
632
+
633
+ const scorecard = rollupScorecard({
634
+ criteria: graded,
635
+ reruns,
636
+ ...(input.gatingSeverities !== undefined ? { gatingSeverities: input.gatingSeverities } : {}),
637
+ });
638
+ // UI-12-A — assess GA-1 grounding readiness over the FINAL folded verdicts (post
639
+ // independent-verify downgrade). The `warning` is the machine-checkable catch for
640
+ // the silent-capture regression; the run logs it loudly (run-evaluate AGGREGATE).
641
+ const groundingReadiness = assessGroundingReadiness(verdicts);
642
+ return { scorecard, verdicts, independentVerify, groundingReadiness };
643
+ }
644
+
645
+ // ── T4 (§9.4.2 nodes 8.5 + 9) consolidate-by-locus + DERIVED health ──────────
646
+ //
647
+ // CONSOLIDATE-BY-LOCUS: failing criteria that share a ROOT (the `localize` band of
648
+ // the trajectory that led each fail) collapse to ONE finding with N symptoms — the
649
+ // cascade is reported once, not N times. DERIVED HEALTH: the per-trajectory judge
650
+ // health is COMPUTED from the walk (judgeSteps with a ref = grounded; assumptions /
651
+ // blockedBy = assumed; a present `localize` = reached-root) — NOT read from the
652
+ // judge's self-reported `health` field (which can be wrong). Both PURE.
653
+
654
+ /** One root-locus cluster: a shared root + the criteria that are its symptoms. */
655
+ export interface LocusCluster {
656
+ root: string;
657
+ criterionIds: string[];
658
+ exampleTraceId?: string;
659
+ }
660
+
661
+ /** The health DERIVED from the judge walk (NOT the self-reported `health` field). */
662
+ export interface DerivedHealth {
663
+ contextGathered: boolean;
664
+ /** judge steps (or verdicts) that cite a structured ref. */
665
+ grounded: number;
666
+ /** surfaced assumptions + assumption-blocked abstains. */
667
+ assumed: number;
668
+ /** localize present + non-empty ⇒ the judge reached a root (depth ≥ 1). */
669
+ rootDepth: number;
670
+ /** true iff the judge did NOT localize a root (stopped at the symptom). */
671
+ stoppedAtSymptom: boolean;
672
+ }
673
+
674
+ /**
675
+ * Derive the judge health from the WALK — refs-present = grounded, assumptions /
676
+ * blockedBy = assumed, a non-empty `localize` = reached-root. Ignores the judge's
677
+ * self-reported `health` (T4: don't trust self-graded health). PURE.
678
+ */
679
+ export function deriveWalkHealth(file: MatrixVerdictFile): DerivedHealth {
680
+ const steps = file.judgeSteps ?? [];
681
+ const verdicts = file.verdicts ?? [];
682
+ // a ref counts as grounded whether emitted as a string OR a structured {obs,…} object.
683
+ const groundedSteps = steps.filter((s) => {
684
+ const r = s.ref as unknown;
685
+ return (typeof r === "string" && r.length > 0) || (typeof r === "object" && r !== null);
686
+ }).length;
687
+ const groundedVerdicts = verdicts.filter((v) => (v.refs?.length ?? 0) > 0).length;
688
+ const grounded = groundedSteps + groundedVerdicts;
689
+ const assumed =
690
+ verdicts.reduce((n, v) => n + (v.assumptions?.length ?? 0), 0) +
691
+ verdicts.filter((v) => v.blockedBy !== undefined).length;
692
+ const hasLocalize = localizeText(file.localize).length > 0;
693
+ const contextGathered = file.context !== undefined || steps.some((s) => s.kind === "context" || s.kind === "gather");
694
+ return {
695
+ contextGathered,
696
+ grounded,
697
+ assumed,
698
+ rootDepth: hasLocalize ? 1 : 0,
699
+ stoppedAtSymptom: !hasLocalize,
700
+ };
701
+ }
702
+
703
+ /**
704
+ * Consolidate failing criteria by their shared ROOT locus. The root for a failing
705
+ * criterion is the `localize` band of the trajectory that led the fold (the
706
+ * verdict's `traceId`); criteria with no localizable root fall under a per-criterion
707
+ * `unlocalized:<id>` bucket (never merged with a real root). Deterministic order:
708
+ * roots in first-seen order, criteria in input order. PURE.
709
+ */
710
+ export function consolidateByLocus(
711
+ failingVerdicts: CriterionVerdict[],
712
+ files: MatrixVerdictFile[],
713
+ ): LocusCluster[] {
714
+ const localizeByTrace = new Map<string, string>();
715
+ for (const f of files) {
716
+ const loc = localizeText(f.localize);
717
+ if (loc.length > 0) localizeByTrace.set(f.trajectoryId, loc);
718
+ }
719
+ const order: string[] = [];
720
+ const byRoot = new Map<string, LocusCluster>();
721
+ for (const v of failingVerdicts) {
722
+ const root = localizeByTrace.get(v.traceId) ?? `unlocalized:${v.criterionId}`;
723
+ let cluster = byRoot.get(root);
724
+ if (cluster === undefined) {
725
+ cluster = { root, criterionIds: [], ...(v.traceId ? { exampleTraceId: v.traceId } : {}) };
726
+ byRoot.set(root, cluster);
727
+ order.push(root);
728
+ }
729
+ cluster.criterionIds.push(v.criterionId);
730
+ }
731
+ return order.map((r) => byRoot.get(r)!);
732
+ }
733
+
734
+ /** AGGREGATE helper — read raw verdict files for the given trajectory ids from a dir. */
735
+ export function readMatrixVerdictFiles(verdictDir: string, trajectoryIds: string[]): string[] {
736
+ const raws: string[] = [];
737
+ for (const id of trajectoryIds) {
738
+ const path = join(verdictDir, matrixVerdictFileName(id));
739
+ if (!existsSync(path)) {
740
+ throw new Error(
741
+ `matrix-judge: no verdict file for trajectory '${id}' at '${path}'. The DEFAULT ` +
742
+ "*evaluate path produces verdicts from dispatched eval-matrix-judge subagents on the " +
743
+ "HOST runtime — PREP packets → dispatch one judge per trajectory → collect verdict " +
744
+ "files → AGGREGATE (references/workflows/orchestrator-protocol.md).",
745
+ );
746
+ }
747
+ raws.push(readFileSync(path, "utf8"));
748
+ }
749
+ return raws;
750
+ }