@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.
- package/.claude/skills/mutagent-helix/SKILL.md +113 -0
- package/.claude/skills/mutagent-helix/scripts/cli/codex-transcode.ts +143 -0
- package/.claude/skills/mutagent-helix/scripts/cli/doctor.ts +111 -0
- package/.claude/skills/mutagent-helix/scripts/cli/init.ts +382 -0
- package/.claude/skills/mutagent-helix/scripts/cli/run.sh +61 -0
- package/CLAUDE.md +193 -0
- package/LICENSE +201 -0
- package/NOTICE +22 -0
- package/README.md +209 -0
- package/assets/adl-loop.svg +162 -0
- package/assets/system-status.svg +422 -0
- package/bin/mutagent-cli.mjs +9950 -0
- package/bin/mutagent-helix.mjs +78 -0
- package/mutagent-agentspec/.claude/skills/mutagent-agentspec/CLAUDE.md +28 -0
- package/mutagent-agentspec/.claude/skills/mutagent-agentspec/SKILL.md +138 -0
- package/mutagent-agentspec/.claude/skills/mutagent-agentspec/assets/templates/agentspec.yaml.tpl +247 -0
- package/mutagent-agentspec/.claude/skills/mutagent-agentspec/references/frameworks/doc-pins.md +53 -0
- package/mutagent-agentspec/.claude/skills/mutagent-agentspec/references/principles.md +91 -0
- package/mutagent-agentspec/.claude/skills/mutagent-agentspec/references/requirements.yaml +295 -0
- package/mutagent-agentspec/.claude/skills/mutagent-agentspec/references/workflows/orchestrator-protocol.md +302 -0
- package/mutagent-agentspec/.claude/skills/mutagent-agentspec/scripts/cli/doctor.ts +116 -0
- package/mutagent-agentspec/.claude/skills/mutagent-agentspec/scripts/cli/init.ts +230 -0
- package/mutagent-agentspec/.claude/skills/mutagent-agentspec/scripts/cli/run.sh +60 -0
- package/mutagent-agentspec/.claude/skills/mutagent-agentspec/scripts/config/resolve-spec-dir.ts +199 -0
- package/mutagent-agentspec/.claude/skills/mutagent-agentspec/scripts/contract/agentspec.schema.ts +455 -0
- package/mutagent-agentspec/.claude/skills/mutagent-agentspec/scripts/setup/detect.ts +67 -0
- package/mutagent-agentspec/.claude/skills/mutagent-agentspec/scripts/validate/validate-spec.ts +93 -0
- package/mutagent-agentspec/LICENSE +201 -0
- package/mutagent-agentspec/NOTICE +19 -0
- package/mutagent-agentspec/README.md +44 -0
- package/mutagent-builder/.claude/skills/mutagent-builder/SKILL.md +100 -0
- package/mutagent-builder/.claude/skills/mutagent-builder/assets/agents/ai-architect.md +312 -0
- package/mutagent-builder/.claude/skills/mutagent-builder/assets/agents/ai-engineer.md +357 -0
- package/mutagent-builder/.claude/skills/mutagent-builder/assets/templates/build-report.md.tpl +39 -0
- package/mutagent-builder/.claude/skills/mutagent-builder/references/principles.md +31 -0
- package/mutagent-builder/.claude/skills/mutagent-builder/references/workflows/build-protocol.md +61 -0
- package/mutagent-builder/.claude/skills/mutagent-builder/references/workflows/improve-handoff.md +23 -0
- package/mutagent-builder/.claude/skills/mutagent-builder/scripts/cli/run.sh +60 -0
- package/mutagent-builder/.claude/skills/mutagent-builder/scripts/handoff/validate-build-input.ts +72 -0
- package/mutagent-builder/.claude/skills/mutagent-builder/scripts/sync-spec/check-sync-spec.ts +499 -0
- package/mutagent-builder/.claude/skills/mutagent-builder/scripts/verify/spec-impl-coverage.ts +182 -0
- package/mutagent-builder/CLAUDE.md +25 -0
- package/mutagent-builder/README.md +26 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/README.md +192 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/SKILL.md +352 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/agents/ai-architect.md +256 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/agents/ai-engineer.md +344 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/agents/diagnostics-analyzer.md +576 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/agents/discovery.md +425 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/audit.json.tpl +24 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/audit.md.tpl +49 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/config.yaml.tpl +100 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/pr-body.md.tpl +56 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/report.html.tpl +327 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/shared/README.md +27 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/shared/iter-N-handover.md.tpl +125 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/shared/self-diagnosis-contract.v0.1.0.yaml.tpl +234 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/shared/spec.yaml.tpl +152 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/shared/team.yaml.tpl +127 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/shared/wave-N-dashboard.html.tpl +1712 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.1-nl-query.md +59 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.2-tier0-progress.md +58 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.3-analysis-progress.md +44 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.4-html-report.md +61 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.5-rca-detail.md +69 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.6-stale-warning.md +53 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.1-welcome.md +60 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.2-source-platform-picker.md +41 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.3-source-auth.md +75 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.4-target-picker.md +48 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.5-ask-tool.md +43 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.6-config-review.md +57 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.7-filter-defaults.md +52 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.8-first-run.md +59 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/examples/sample-findings.json +92 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/examples/sample-meta.json +47 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/adapter-strategy.md +75 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/config-migration.md +84 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/config.md +159 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/filter-search-matrix.md +66 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/harness-knowledge.md +22 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/memory-format.md +78 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/onboarding-decisions.yaml +187 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/operation-inventory.md +59 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/overview.md +167 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/reference.md +119 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/script-index.md +101 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-adapter-contract.md +93 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-platforms/claude-code-transcripts.md +66 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-platforms/codex-transcripts.md +78 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-platforms/codex.md +145 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-platforms/install-paths.md +57 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-platforms/langfuse.md +178 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-platforms/local-jsonl.md +55 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-platforms/openobserve.md +102 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-platforms/otel.md +63 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/target-platforms/cloud-rest.md +84 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/target-platforms/local-claude.md +65 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/target-platforms/local-cloud-agent-sdk.md +92 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/target-platforms/local-codex.md +72 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/target-platforms/local-cursor.md +108 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/target-platforms/local-mastra.md +77 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/target-platforms/local-opencode.md +70 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/apply-pr-comment-format.md +82 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/diagnostics.md +35 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/handover-contract.md +247 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/onboarding.md +300 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/orchestrator-protocol.md +1861 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/rca.md +331 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/rendering-anatomy.md +314 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/schedule-prep.md +100 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/scope-model.md +128 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/verification-methodology.md +174 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/aggregate/sort-findings.ts +0 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/awareness/blind-spots.ts +167 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/awareness/llm-sample.ts +681 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/cli/doctor.ts +215 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/cli/init.ts +1013 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/cli/install-agents.ts +350 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/cli/run.sh +61 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/cli/shared-templates.ts +79 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/config/load.ts +392 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/config/resolve-credential.ts +120 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/config/schema.ts +641 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/config/validate.ts +134 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/context/build-diagnosis-context.ts +417 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/context/load-context.ts +105 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/contract/types.ts +166 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/enrich/build-render-input.ts +1964 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/enrich/corpus-severity.ts +172 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/enrich/dismissal-match.ts +270 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/enrich/rank-remedies.ts +75 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/hooks/install-hooks.sh +46 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/hooks/pre-push.sh +78 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/invocation/parse-brief.ts +188 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/library/match.ts +114 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/library/paths.ts +95 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/library/store.ts +535 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/library/types.ts +181 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/lint/template-inline-js.ts +267 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/memory/append.ts +188 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/memory/read.ts +218 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/normalize/platforms/entity-context.ts +686 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/normalize/read-unitf.ts +267 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/normalize/trace.ts +1078 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/normalize/unitf-adapter.ts +0 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/normalize/unitf-types.ts +213 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/report/persist-selections.ts +174 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/report/render.ts +3254 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/run/diagnose.ts +64 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/run/session.ts +167 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/sample/caps.ts +345 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/sample/deep-read-gate.ts +424 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/sample/representative.ts +584 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/scan/objection.ts +224 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/scan/trajectory.ts +489 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/self-diagnostics/dispatch.ts +135 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/self-diagnostics/probe.ts +170 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/setup/detect.ts +307 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/setup/ensure-cli.ts +315 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/setup/reconfigure.ts +77 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/setup/verify-agents.ts +207 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/slicer.ts +166 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/source/adapters/claude-code.ts +17 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/source/adapters/codex.ts +11 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/source/adapters/langfuse.ts +17 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/source/adapters/local-jsonl.ts +12 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/source/adapters/otel.ts +12 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/source/index.ts +54 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/source/registry.ts +45 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/source/types.ts +86 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/stale-detector.ts +74 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/test/render-playwright.cli.ts +477 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/tier0/claude-code.ts +133 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/tier0/langfuse.ts +143 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/tier0-scan.ts +423 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/validate/completeness-check.ts +436 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/validate/doc-refs.ts +190 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/validate/finalize-gate.ts +417 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/validate/findings-contract.ts +628 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/validate/render-js-syntax.ts +188 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/validate/report-checklist.yaml +217 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/validate/trace-shape.ts +262 -0
- package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/validate/wave6-checklist.ts +326 -0
- package/mutagent-diagnostics/CLAUDE.md +41 -0
- package/mutagent-diagnostics/LICENSE +201 -0
- package/mutagent-diagnostics/NOTICE +18 -0
- package/mutagent-diagnostics/README.md +343 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/SKILL.md +548 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/assets/agents/audit-executor.md +169 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/assets/agents/dataset-builder.md +160 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/assets/agents/discovery.md +425 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/assets/agents/evaluator.md +1108 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/assets/brand/theme.css +213 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/assets/brand/wordmark.html +9 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/lenses/context-flow-lens.md +85 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/lenses/data-lens.md +47 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/lenses/decision-lens.md +48 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/lenses/methodology-critic-lens.md +53 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/lenses/trajectory-lens.md +44 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/build-review-interface.md +83 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/edd-loop.md +134 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/error-analysis.md +113 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/eval-audit.md +154 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/eval-stage.md +168 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/generate-synthetic-data.md +81 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/grounded-adjudication.md +221 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/memory-format.md +65 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/methodology.md +201 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/operation-inventory.md +197 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/validate-evaluator.md +125 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/workflows/orchestrator-protocol.md +300 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/write-judge-prompt.md +123 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/schemas/behavior-tree.schema.yaml +73 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/schemas/dataset.schema.yaml +66 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/schemas/edd-change-request.schema.yaml +114 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/schemas/eval-matrix.schema.yaml +74 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/schemas/flow-graph.schema.yaml +69 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/schemas/flow-profile.schema.yaml +49 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/schemas/methodology-review.schema.yaml +40 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/schemas/scorecard.schema.yaml +85 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/agent-dispatch.ts +0 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/aggregate-discover.ts +543 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/artifact-paths.ts +115 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/assemble-scorecard.ts +172 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/build-dataset.ts +186 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/build-evals.ts +93 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/build-review-ui.ts +393 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/check-method-router.ts +170 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/aggregate.ts +112 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/audit-run.ts +182 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/doctor.ts +211 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/dogfood.ts +133 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/init.ts +601 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/methodology-review.ts +122 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/prep.ts +295 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/profile-subject.ts +165 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/run.sh +56 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/variance-check.ts +105 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/code-eval.ts +248 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/code-quality-verdict.ts +285 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/codegen-evals.ts +173 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cold-start-project.ts +151 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cold-start-sampler.ts +267 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/config/load.ts +343 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/config/schema.ts +380 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/contracts/agentspec-evals.ts +85 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/contracts/dataset.ts +149 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/contracts/eval-engine.ts +118 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/contracts/eval-matrix.ts +577 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/contracts/eval-types.ts +1074 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/contracts/flow-graph.ts +194 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/contracts/types.ts +303 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/contracts/validation.ts +193 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/derive-dataset.ts +152 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/determine-outcome.ts +219 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/diff-discriminate.ts +160 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/discover-criteria.ts +348 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/edd/change-request.ts +232 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/edd/edd-types.ts +210 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/edd/variance-gate.ts +186 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/emit-completeness.ts +111 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/eval-engine.ts +160 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/evaluate.ts +333 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/flow-graph.ts +230 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/judge-prompt-template.ts +253 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/judge-provider.ts +135 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/lint-grounding.ts +229 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/lint-uniformity.ts +168 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/living-suite.ts +109 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/load-bundle.ts +203 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/load-profile-vocab.ts +64 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/load-profile.ts +106 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/mask.ts +138 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/materialize-dataset.ts +113 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/matrix-judge.ts +750 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/memory/append.ts +215 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/memory/read.ts +168 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/persist-eval-criteria.ts +232 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/prep-tasks.ts +125 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/profile-subject.ts +310 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/publish-report.ts +131 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/read-unitf-traces.ts +81 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/render-build-cards.ts +195 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/render-discover-report.ts +1640 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/render-eval-report.ts +3838 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/render-report.ts +212 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/resolve-credential.ts +110 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/resolve-ref.ts +98 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/result-verify.ts +129 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/route-failures.ts +330 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/run-deterministic.ts +367 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/run-evaluate.ts +719 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/run-judge.ts +155 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/run-pipeline.ts +175 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/sample-traces.ts +210 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/self-audit.ts +387 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/source-map.ts +106 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/subject-profile.ts +134 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/substrate.ts +162 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/sync-eval-criteria.ts +244 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/ui-slots.ts +119 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/unitf-to-evaltrace.ts +284 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/validate-judge.ts +358 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/variance-compare.ts +177 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/subjects/mutagent-diagnostics/behavior-tree.yaml +140 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/subjects/mutagent-diagnostics/eval-matrix.yaml +1270 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/subjects/mutagent-diagnostics/methodology-review.yaml +105 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/workflows/audit.workflow.js +82 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/workflows/data-leak.workflow.js +236 -0
- package/mutagent-evaluator/.claude/skills/mutagent-evaluator/workflows/variance.workflow.js +163 -0
- package/mutagent-evaluator/CLAUDE.md +45 -0
- package/mutagent-evaluator/LICENSE +201 -0
- package/mutagent-evaluator/NOTICE +23 -0
- package/mutagent-evaluator/README.md +88 -0
- package/mutagent-optimize/.claude/skills/mutagent-optimize/SKILL.md +287 -0
- package/mutagent-optimize/.claude/skills/mutagent-optimize/scripts/contracts/amend-request.ts +503 -0
- package/mutagent-optimize/.claude/skills/mutagent-optimize/scripts/improve-loop-run.ts +304 -0
- package/mutagent-optimize/.claude/skills/mutagent-optimize/scripts/loop-state-cli.ts +300 -0
- package/mutagent-optimize/.claude/skills/mutagent-optimize/scripts/loop-state.ts +440 -0
- package/mutagent-optimize/CLAUDE.md +49 -0
- package/mutagent-optimize/README.md +26 -0
- package/mutagent-orchestrator/CLAUDE.md +102 -0
- package/mutagent-orchestrator/README.md +20 -0
- package/mutagent-orchestrator/assets/agents/discovery.md +425 -0
- package/mutagent-orchestrator/assets/agents/dogfood-monitor.md +266 -0
- package/mutagent-orchestrator/assets/agents/monitor.md +258 -0
- package/mutagent-orchestrator/orchestrator.md +782 -0
- package/mutagent-orchestrator/references/MONITORING.md +209 -0
- package/mutagent-orchestrator/references/config-fields.md +132 -0
- package/mutagent-orchestrator/references/config-migration.md +132 -0
- package/mutagent-orchestrator/references/index-registry.md +92 -0
- package/mutagent-orchestrator/routing.yaml +391 -0
- package/mutagent-orchestrator/scripts/config-schema.ts +1010 -0
- package/mutagent-orchestrator/scripts/dispatch.ts +439 -0
- package/mutagent-orchestrator/scripts/dogfood/extract-feedback.ts +203 -0
- package/mutagent-orchestrator/scripts/dogfood/reconstruct-trajectory.ts +327 -0
- package/mutagent-orchestrator/scripts/dogfood/render-dogfood-report.ts +347 -0
- package/mutagent-orchestrator/scripts/dogfood/resolve-subagents.ts +160 -0
- package/mutagent-orchestrator/scripts/dogfood/run-report.ts +264 -0
- package/mutagent-orchestrator/scripts/dogfood/slack-thread.ts +106 -0
- package/mutagent-orchestrator/scripts/dogfood/types.ts +257 -0
- package/mutagent-orchestrator/scripts/eval-routing.ts +753 -0
- package/mutagent-orchestrator/scripts/gate.ts +219 -0
- package/mutagent-orchestrator/scripts/handover-contract.ts +362 -0
- package/mutagent-orchestrator/scripts/index/build-index.ts +351 -0
- package/mutagent-orchestrator/scripts/index/render-index.ts +110 -0
- package/mutagent-orchestrator/scripts/monitor/slack-notify.ts +111 -0
- package/mutagent-orchestrator/scripts/monitor/triggers.ts +162 -0
- package/mutagent-orchestrator/scripts/onboarding-check.ts +369 -0
- package/mutagent-orchestrator/scripts/render-roster.ts +308 -0
- package/mutagent-orchestrator/scripts/resolve-credential.ts +185 -0
- package/mutagent-orchestrator/scripts/resolve-paths.ts +114 -0
- package/mutagent-orchestrator/scripts/slack/format.ts +63 -0
- package/mutagent-orchestrator/scripts/slack/post.ts +115 -0
- package/mutagent-orchestrator/scripts/sync-index.ts +311 -0
- 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
|
+
}
|