@tangle-network/agent-eval 0.179.0 → 0.181.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +66 -0
- package/README.md +119 -146
- package/dist/adapters/http.d.ts +2 -2
- package/dist/{agent-profile-B7yErX0q.d.ts → agent-profile-CivaSsSy.d.ts} +4 -4
- package/dist/{agent-profile-B7yErX0q.d.ts.map → agent-profile-CivaSsSy.d.ts.map} +1 -1
- package/dist/{agent-profile-cell-0gSi5ffD.js → agent-profile-cell-Cv6UA-W_.js} +20 -57
- package/dist/agent-profile-cell-Cv6UA-W_.js.map +1 -0
- package/dist/{agent-profile-cell-CTOZJUuE.d.ts → agent-profile-cell-s__adRnK.d.ts} +3 -3
- package/dist/agent-profile-cell-s__adRnK.d.ts.map +1 -0
- package/dist/analyst/index.d.ts +10 -10
- package/dist/analyst/index.js +4 -4
- package/dist/ast-CP9ae9B0.js +557 -0
- package/dist/ast-CP9ae9B0.js.map +1 -0
- package/dist/ast-hI-vjW6J.d.ts +457 -0
- package/dist/ast-hI-vjW6J.d.ts.map +1 -0
- package/dist/{benchmark-command-CY6Dg5t5.js → benchmark-command-B57n9vjz.js} +7 -6
- package/dist/{benchmark-command-CY6Dg5t5.js.map → benchmark-command-B57n9vjz.js.map} +1 -1
- package/dist/benchmarks/index.d.ts +4 -4
- package/dist/benchmarks/index.js +3 -3
- package/dist/campaign/index.d.ts +6 -6
- package/dist/campaign/index.js +8 -8
- package/dist/{campaign-BGEurASO.js → campaign-4_ppJW5X.js} +12 -12
- package/dist/{campaign-BGEurASO.js.map → campaign-4_ppJW5X.js.map} +1 -1
- package/dist/{campaign-evidence-D8DBLqLI.js → campaign-evidence-B8oF9xQ6.js} +515 -471
- package/dist/campaign-evidence-B8oF9xQ6.js.map +1 -0
- package/dist/cli.js +5 -8
- package/dist/cli.js.map +1 -1
- package/dist/{client-BlLY6o2w.js → client-CXE-U1SA.js} +3 -1
- package/dist/client-CXE-U1SA.js.map +1 -0
- package/dist/{client-CuQgX33c.d.ts → client-kh2jOjTK.d.ts} +4 -4
- package/dist/{client-CuQgX33c.d.ts.map → client-kh2jOjTK.d.ts.map} +1 -1
- package/dist/contract/index.d.ts +13 -13
- package/dist/contract/index.js +11 -10
- package/dist/contract/index.js.map +1 -1
- package/dist/{default-registry-IGDE9XIC.d.ts → default-registry-BwDSWVzg.d.ts} +6 -6
- package/dist/{default-registry-IGDE9XIC.d.ts.map → default-registry-BwDSWVzg.d.ts.map} +1 -1
- package/dist/{default-registry-BryMEmr8.js → default-registry-aL7xUrUz.js} +2 -2
- package/dist/{default-registry-BryMEmr8.js.map → default-registry-aL7xUrUz.js.map} +1 -1
- package/dist/{define-agent-eval-Cx4Ls9ta.d.ts → define-agent-eval-CwOWWQt_.d.ts} +33 -12
- package/dist/define-agent-eval-CwOWWQt_.d.ts.map +1 -0
- package/dist/{define-agent-eval-Dzidv34q.js → define-agent-eval-Ddu33JH9.js} +134 -67
- package/dist/define-agent-eval-Ddu33JH9.js.map +1 -0
- package/dist/{dspy-rlm-engine-xKiWmj_G.js → dspy-rlm-engine-S53V0HhE.js} +2 -2
- package/dist/{dspy-rlm-engine-xKiWmj_G.js.map → dspy-rlm-engine-S53V0HhE.js.map} +1 -1
- package/dist/{engine-CX8ReXkn.d.ts → engine-DS1cysJy.d.ts} +10 -7
- package/dist/engine-DS1cysJy.d.ts.map +1 -0
- package/dist/{eval-campaign-Cs-7MiCs.js → eval-campaign-aYdtjtJR.js} +4 -4
- package/dist/{eval-campaign-Cs-7MiCs.js.map → eval-campaign-aYdtjtJR.js.map} +1 -1
- package/dist/{exact-types-B7LC1EyX.d.ts → exact-types-BZDe0W2D.d.ts} +2 -2
- package/dist/{exact-types-B7LC1EyX.d.ts.map → exact-types-BZDe0W2D.d.ts.map} +1 -1
- package/dist/experiment/index.d.ts +27 -477
- package/dist/experiment/index.d.ts.map +1 -1
- package/dist/experiment/index.js +95 -559
- package/dist/experiment/index.js.map +1 -1
- package/dist/{experiment-tracker-B3TiF5-u.d.ts → experiment-tracker-C7PfnF4b.d.ts} +2 -2
- package/dist/{experiment-tracker-B3TiF5-u.d.ts.map → experiment-tracker-C7PfnF4b.d.ts.map} +1 -1
- package/dist/{external-optimizer-process-Dlz8YxrT.js → external-optimizer-process-QDRURJAM.js} +3 -3
- package/dist/{external-optimizer-process-Dlz8YxrT.js.map → external-optimizer-process-QDRURJAM.js.map} +1 -1
- package/dist/{external-optimizer-subprocess-q3VzlGAO.js → external-optimizer-subprocess-D4dzUBZI.js} +3 -2
- package/dist/{external-optimizer-subprocess-q3VzlGAO.js.map → external-optimizer-subprocess-D4dzUBZI.js.map} +1 -1
- package/dist/{feedback-trajectory-eHWNv5Aj.d.ts → feedback-trajectory-CXmtITBo.d.ts} +3 -3
- package/dist/{feedback-trajectory-eHWNv5Aj.d.ts.map → feedback-trajectory-CXmtITBo.d.ts.map} +1 -1
- package/dist/hosted/index.d.ts +2 -2
- package/dist/hosted/index.d.ts.map +1 -1
- package/dist/hosted/index.js +1 -1
- package/dist/{index-BxWvILU8.d.ts → index-Bp_6sj3x.d.ts} +109 -56
- package/dist/index-Bp_6sj3x.d.ts.map +1 -0
- package/dist/{index-e7LXeRVa.d.ts → index-CJ3LhKIX.d.ts} +2 -2
- package/dist/{index-e7LXeRVa.d.ts.map → index-CJ3LhKIX.d.ts.map} +1 -1
- package/dist/{index-CbLmrWCa.d.ts → index-DNntP4ch.d.ts} +8 -8
- package/dist/{index-CbLmrWCa.d.ts.map → index-DNntP4ch.d.ts.map} +1 -1
- package/dist/{index-DxNYmx4a.d.ts → index-DoykkxW0.d.ts} +11 -11
- package/dist/{index-DxNYmx4a.d.ts.map → index-DoykkxW0.d.ts.map} +1 -1
- package/dist/index.d.ts +28 -28
- package/dist/index.js +25 -16
- package/dist/index.js.map +1 -1
- package/dist/{insight-report-DETqPc_A.d.ts → insight-report-D1qa0HWs.d.ts} +9 -5
- package/dist/{insight-report-DETqPc_A.d.ts.map → insight-report-D1qa0HWs.d.ts.map} +1 -1
- package/dist/{integrity-DsHWCebQ.js → integrity-DH5ng72x.js} +2 -2
- package/dist/{integrity-DsHWCebQ.js.map → integrity-DH5ng72x.js.map} +1 -1
- package/dist/{integrity-BKTcA-HP.d.ts → integrity-rGOfSUle.d.ts} +2 -2
- package/dist/{integrity-BKTcA-HP.d.ts.map → integrity-rGOfSUle.d.ts.map} +1 -1
- package/dist/{ledger-core-Cs9f7385.js → journal-Cs9f7385.js} +1 -1
- package/dist/journal-Cs9f7385.js.map +1 -0
- package/dist/{judge-calibration-C5CbMYce.d.ts → judge-calibration-DFtEMlde.d.ts} +31 -2
- package/dist/judge-calibration-DFtEMlde.d.ts.map +1 -0
- package/dist/{judge-calibration-BnpVKtnb.js → judge-calibration-DYmaBtJr.js} +48 -2
- package/dist/{judge-calibration-BnpVKtnb.js.map → judge-calibration-DYmaBtJr.js.map} +1 -1
- package/dist/ledger-core/index.d.ts +1 -1
- package/dist/ledger-core/index.js +1 -1
- package/dist/{llm-judge-v80Kmu9g.js → llm-judge-DEFZeSiu.js} +645 -456
- package/dist/llm-judge-DEFZeSiu.js.map +1 -0
- package/dist/{matrix-DeMmnWrP.d.ts → matrix-CyhW-vgJ.d.ts} +2 -2
- package/dist/{matrix-DeMmnWrP.d.ts.map → matrix-CyhW-vgJ.d.ts.map} +1 -1
- package/dist/meta-eval/index.d.ts +138 -7
- package/dist/meta-eval/index.d.ts.map +1 -1
- package/dist/meta-eval/index.js +245 -97
- package/dist/meta-eval/index.js.map +1 -1
- package/dist/{mint-Cc1_zwRQ.js → mint-ySIIkKlV.js} +2 -2
- package/dist/{mint-Cc1_zwRQ.js.map → mint-ySIIkKlV.js.map} +1 -1
- package/dist/multishot/golden/index.d.ts +1 -1
- package/dist/multishot/index.d.ts +2 -2
- package/dist/openapi.json +1 -1
- package/dist/outcome-store-BXlkwMPR.js +131 -0
- package/dist/outcome-store-BXlkwMPR.js.map +1 -0
- package/dist/{outcome-store-BYHIuO0e.d.ts → outcome-store-CNt4iZ67.d.ts} +18 -25
- package/dist/outcome-store-CNt4iZ67.d.ts.map +1 -0
- package/dist/{paired-promotion-decision-CGzg0cI_.d.ts → paired-promotion-decision-DPsMQm-0.d.ts} +13 -7
- package/dist/{paired-promotion-decision-CGzg0cI_.d.ts.map → paired-promotion-decision-DPsMQm-0.d.ts.map} +1 -1
- package/dist/pipelines/index.js +1 -1
- package/dist/{produced-state-Cv0kJJuP.js → produced-state-BHboMaab.js} +3 -3
- package/dist/{produced-state-Cv0kJJuP.js.map → produced-state-BHboMaab.js.map} +1 -1
- package/dist/profile-cell.d.ts +1 -1
- package/dist/profile-cell.js +1 -1
- package/dist/{promotion-policy-DWOm70gx.js → promotion-policy-CDMMxzb6.js} +28 -40
- package/dist/promotion-policy-CDMMxzb6.js.map +1 -0
- package/dist/{registry-ByVld1-5.d.ts → registry-BRbB6Y0v.d.ts} +4 -4
- package/dist/{registry-ByVld1-5.d.ts.map → registry-BRbB6Y0v.d.ts.map} +1 -1
- package/dist/{release-confidence-BAcNYOf1.d.ts → release-confidence-BcqeQTHW.d.ts} +3 -3
- package/dist/{release-confidence-BAcNYOf1.d.ts.map → release-confidence-BcqeQTHW.d.ts.map} +1 -1
- package/dist/{release-confidence-BcGCclTB.js → release-confidence-DMg8n18l.js} +2 -2
- package/dist/{release-confidence-BcGCclTB.js.map → release-confidence-DMg8n18l.js.map} +1 -1
- package/dist/{report-command-DKlXfU5r.js → report-command-V1ecVgAv.js} +27 -3
- package/dist/report-command-V1ecVgAv.js.map +1 -0
- package/dist/reporting.d.ts +4 -4
- package/dist/reporting.js +3 -3
- package/dist/{researcher-jsW1X94L.d.ts → researcher-64T49THL.d.ts} +6 -6
- package/dist/{researcher-jsW1X94L.d.ts.map → researcher-64T49THL.d.ts.map} +1 -1
- package/dist/{reward-hacking-ZXEi9VCq.d.ts → reward-hacking-uzO_ihep.d.ts} +2 -2
- package/dist/{reward-hacking-ZXEi9VCq.d.ts.map → reward-hacking-uzO_ihep.d.ts.map} +1 -1
- package/dist/rl.d.ts +53 -99
- package/dist/rl.d.ts.map +1 -1
- package/dist/rl.js +182 -169
- package/dist/rl.js.map +1 -1
- package/dist/rollout/index.d.ts +1 -1
- package/dist/rollout/index.js +2 -2
- package/dist/{rollout-DmoJVqrF.js → rollout-B-UF5R6w.js} +2 -2
- package/dist/{rollout-DmoJVqrF.js.map → rollout-B-UF5R6w.js.map} +1 -1
- package/dist/rubric-predictive-validity-Bmj2_cll.d.ts +79 -0
- package/dist/rubric-predictive-validity-Bmj2_cll.d.ts.map +1 -0
- package/dist/rubric-predictive-validity-CCK-1B7w.js +178 -0
- package/dist/rubric-predictive-validity-CCK-1B7w.js.map +1 -0
- package/dist/{run-record-DTv1MdjK.d.ts → run-record-BiTWauyO.d.ts} +2 -2
- package/dist/{run-record-DTv1MdjK.d.ts.map → run-record-BiTWauyO.d.ts.map} +1 -1
- package/dist/run-record-Br-Yzt_k.js +464 -0
- package/dist/run-record-Br-Yzt_k.js.map +1 -0
- package/dist/{run-record-DQpSf7t-.js → run-record-DualPTn2.js} +2 -2
- package/dist/{run-record-DQpSf7t-.js.map → run-record-DualPTn2.js.map} +1 -1
- package/dist/{semantic-concept-judge-Bi6_iGqg.js → semantic-concept-judge-Bm5JDEKO.js} +3 -3
- package/dist/{semantic-concept-judge-Bi6_iGqg.js.map → semantic-concept-judge-Bm5JDEKO.js.map} +1 -1
- package/dist/{sequential-B5gXgcyp.js → sequential-DAsyV2T9.js} +42 -25
- package/dist/sequential-DAsyV2T9.js.map +1 -0
- package/dist/{series-convergence-DeG33RpC.d.ts → series-convergence-BnMs_uAr.d.ts} +3 -3
- package/dist/{series-convergence-DeG33RpC.d.ts.map → series-convergence-BnMs_uAr.d.ts.map} +1 -1
- package/dist/{skillopt-optimization-method-C3oYul8v.js → skillopt-optimization-method-CL_0aArC.js} +5 -5
- package/dist/{skillopt-optimization-method-C3oYul8v.js.map → skillopt-optimization-method-CL_0aArC.js.map} +1 -1
- package/dist/{statistical-heldout-0La5ZTlv.d.ts → statistical-heldout-CpVd6FmY.d.ts} +207 -144
- package/dist/statistical-heldout-CpVd6FmY.d.ts.map +1 -0
- package/dist/{store-tool-spans-4J1EDElP.d.ts → store-tool-spans-Dt-YdAuE.d.ts} +6 -6
- package/dist/{store-tool-spans-4J1EDElP.d.ts.map → store-tool-spans-Dt-YdAuE.d.ts.map} +1 -1
- package/dist/{summary-report-gMrbYawB.d.ts → summary-report-D1h4dlrK.d.ts} +3 -3
- package/dist/{summary-report-gMrbYawB.d.ts.map → summary-report-D1h4dlrK.d.ts.map} +1 -1
- package/dist/{summary-report-B16xy9Kd.js → summary-report-e-MaOAHV.js} +2 -2
- package/dist/{summary-report-B16xy9Kd.js.map → summary-report-e-MaOAHV.js.map} +1 -1
- package/dist/supervisor-run/index.d.ts +4 -2
- package/dist/supervisor-run/index.d.ts.map +1 -1
- package/dist/supervisor-run/index.js +3 -3
- package/dist/{terminal-record-Ce9_UjRz.js → terminal-record-BtPwKTSr.js} +58 -26
- package/dist/terminal-record-BtPwKTSr.js.map +1 -0
- package/dist/{tool-groups-2QA0S7dK.d.ts → tool-groups-B2bSNaJB.d.ts} +3 -3
- package/dist/tool-groups-B2bSNaJB.d.ts.map +1 -0
- package/dist/{tool-waste-B9tdWV6g.js → tool-waste-C7MU9u1e.js} +2 -2
- package/dist/{tool-waste-B9tdWV6g.js.map → tool-waste-C7MU9u1e.js.map} +1 -1
- package/dist/trace-repair/index.d.ts +2 -2
- package/dist/traces.d.ts +6 -6
- package/dist/traces.js +1 -1
- package/dist/{types-BmlkCrg0.d.ts → types-BvZoPTGa.d.ts} +3 -3
- package/dist/{types-BmlkCrg0.d.ts.map → types-BvZoPTGa.d.ts.map} +1 -1
- package/dist/{types-gvRsyJLh.d.ts → types-CBbLtr2J.d.ts} +38 -3
- package/dist/{types-gvRsyJLh.d.ts.map → types-CBbLtr2J.d.ts.map} +1 -1
- package/dist/{types-C34V4Vto.d.ts → types-CS0qk_Yp.d.ts} +4 -4
- package/dist/{types-C34V4Vto.d.ts.map → types-CS0qk_Yp.d.ts.map} +1 -1
- package/dist/{types-DzuaM493.d.ts → types-D7gEdPoQ.d.ts} +3 -3
- package/dist/{types-DzuaM493.d.ts.map → types-D7gEdPoQ.d.ts.map} +1 -1
- package/dist/{types-vUdAx2Cj.d.ts → types-lPkDQNqJ.d.ts} +20 -2
- package/dist/{types-vUdAx2Cj.d.ts.map → types-lPkDQNqJ.d.ts.map} +1 -1
- package/dist/wire/index.d.ts +2 -2
- package/docs/adapters-observability.md +14 -0
- package/docs/campaign-proposers.md +86 -128
- package/docs/charter.md +108 -112
- package/docs/concepts.md +157 -69
- package/docs/design/mlbenchmarks-book-review.md +440 -0
- package/docs/design/mlbenchmarks-review/observations.json +713 -0
- package/docs/design/mlbenchmarks-review/probes.mts +476 -0
- package/docs/design/mlbenchmarks-review/sources.json +200 -0
- package/docs/design/self-improvement-evidence-audit.md +263 -0
- package/docs/design.md +2 -1
- package/docs/eval-surface-map.md +95 -42
- package/docs/evaluation-integrity.md +220 -0
- package/docs/experiment.md +111 -55
- package/docs/feature-guide.md +5 -6
- package/docs/hosted-ingest-spec.md +4 -11
- package/docs/insight-report.md +187 -455
- package/docs/outcome-validity.md +182 -0
- package/docs/product-eval-adoption.md +1 -2
- package/docs/research-report-methodology.md +7 -7
- package/docs/search-history-receipts.md +8 -0
- package/docs/statistical-evidence.md +129 -0
- package/docs/verdicts.md +76 -49
- package/package.json +1 -1
- package/dist/agent-profile-cell-0gSi5ffD.js.map +0 -1
- package/dist/agent-profile-cell-CTOZJUuE.d.ts.map +0 -1
- package/dist/campaign-evidence-D8DBLqLI.js.map +0 -1
- package/dist/client-BlLY6o2w.js.map +0 -1
- package/dist/define-agent-eval-Cx4Ls9ta.d.ts.map +0 -1
- package/dist/define-agent-eval-Dzidv34q.js.map +0 -1
- package/dist/engine-CX8ReXkn.d.ts.map +0 -1
- package/dist/index-BxWvILU8.d.ts.map +0 -1
- package/dist/judge-calibration-C5CbMYce.d.ts.map +0 -1
- package/dist/ledger-core-Cs9f7385.js.map +0 -1
- package/dist/llm-judge-v80Kmu9g.js.map +0 -1
- package/dist/outcome-store-BYHIuO0e.d.ts.map +0 -1
- package/dist/outcome-store-ChBKlTd_.js +0 -75
- package/dist/outcome-store-ChBKlTd_.js.map +0 -1
- package/dist/promotion-policy-DWOm70gx.js.map +0 -1
- package/dist/report-command-DKlXfU5r.js.map +0 -1
- package/dist/rubric-predictive-validity-2D5Gw9z9.js +0 -131
- package/dist/rubric-predictive-validity-2D5Gw9z9.js.map +0 -1
- package/dist/rubric-predictive-validity-Dl1dvKCv.d.ts +0 -75
- package/dist/rubric-predictive-validity-Dl1dvKCv.d.ts.map +0 -1
- package/dist/run-record-CR63CpHK.js +0 -216
- package/dist/run-record-CR63CpHK.js.map +0 -1
- package/dist/sequential-B5gXgcyp.js.map +0 -1
- package/dist/statistical-heldout-0La5ZTlv.d.ts.map +0 -1
- package/dist/terminal-record-Ce9_UjRz.js.map +0 -1
- package/dist/tool-groups-2QA0S7dK.d.ts.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"campaign-evidence-D8DBLqLI.js","names":[],"sources":["../src/campaign/coverage.ts","../src/integrity/backend-integrity.ts","../src/campaign/surface-identity.ts","../src/paired-delta-test.ts","../src/paired-promotion-decision.ts","../src/campaign/gates/statistical-heldout.ts","../src/campaign/gates/power-preflight.ts","../src/json-recovery.ts","../src/reflective-mutation.ts","../src/campaign/score-utils.ts","../src/campaign/provenance.ts","../src/attestation.ts","../src/experiment/evidence-receipt.ts","../src/experiment/campaign-evidence.ts"],"sourcesContent":["import { contentHash } from '../verdict-cache'\nimport type {\n CampaignCellResult,\n CampaignResult,\n CampaignScenarioIdentity,\n Scenario,\n} from './types'\n\nexport interface CampaignCoverage {\n complete: boolean\n expectedCellIds: string[]\n scorableCellIds: string[]\n unscorableCells: Array<{ cellId: string; reason: string }>\n}\n\n/** Reject campaign designs whose denominator cannot be identified exactly. */\nexport function assertCampaignDesign<TScenario extends Scenario>(\n scenarios: readonly TScenario[],\n reps: number,\n): void {\n if (!Number.isSafeInteger(reps) || reps < 1) {\n throw new Error('campaign design requires reps to be a positive safe integer')\n }\n const scenarioIds = new Set<string>()\n for (const scenario of scenarios) {\n if (typeof scenario.id !== 'string' || scenario.id.trim().length === 0) {\n throw new Error('campaign design requires every scenario to have a non-empty id')\n }\n if (scenarioIds.has(scenario.id)) {\n throw new Error(`campaign design contains duplicate scenario id '${scenario.id}'`)\n }\n if (typeof scenario.kind !== 'string' || scenario.kind.trim().length === 0) {\n throw new Error('campaign design requires every scenario to have a non-empty kind')\n }\n if (\n scenario.seedGroup !== undefined &&\n (typeof scenario.seedGroup !== 'string' || scenario.seedGroup.trim().length === 0)\n ) {\n throw new Error('campaign design requires seedGroup to be a non-empty string when set')\n }\n scenarioIds.add(scenario.id)\n }\n}\n\n/** Redacted but independently verifiable identity of one complete scenario. */\nexport function campaignScenarioIdentity<TScenario extends Scenario>(\n scenario: TScenario,\n): CampaignScenarioIdentity & Pick<TScenario, 'id' | 'kind'> {\n assertCampaignDesign([scenario], 1)\n return {\n id: scenario.id,\n kind: scenario.kind,\n scenarioDigest: `sha256:${contentHash(scenario)}`,\n }\n}\n\n/** Canonical split identity reconstructed from redacted scenario identities. */\nexport function campaignSplitDigestFromIdentities(\n scenarios: readonly CampaignScenarioIdentity[],\n reps: number,\n): `sha256:${string}` {\n assertCampaignDesign(scenarios, reps)\n for (const scenario of scenarios) {\n if (!/^sha256:[a-f0-9]{64}$/.test(scenario.scenarioDigest)) {\n throw new Error(`campaign scenario '${scenario.id}' has an invalid digest`)\n }\n }\n return `sha256:${contentHash({\n schema: 'tangle.campaign-split',\n scenarios: scenarios.map(({ id, kind, scenarioDigest }) => ({ id, kind, scenarioDigest })),\n reps,\n })}`\n}\n\n/** Canonical identity of the exact scenario payloads and replicate count. */\nexport function campaignSplitDigest<TScenario extends Scenario>(\n scenarios: readonly TScenario[],\n reps: number,\n): `sha256:${string}` {\n assertCampaignDesign(scenarios, reps)\n return campaignSplitDigestFromIdentities(scenarios.map(campaignScenarioIdentity), reps)\n}\n\n/** Refuse a campaign whose retained task identities contradict its split digest. */\nexport function assertCampaignSplitIdentity(\n scenarios: readonly CampaignScenarioIdentity[],\n reps: number,\n splitDigest: string,\n): void {\n if (campaignSplitDigestFromIdentities(scenarios, reps) !== splitDigest) {\n throw new Error('campaign split digest does not match its retained scenario identities')\n }\n}\n\n/** Exact designed-denominator receipt for one campaign. */\nexport function campaignCoverage<TArtifact, TScenario extends Scenario>(\n cells: readonly CampaignCellResult<TArtifact>[],\n scenarios: readonly TScenario[],\n reps: number,\n requireJudgeScore: boolean,\n): CampaignCoverage {\n assertCampaignDesign(scenarios, reps)\n const expectedCellIds = designedCellIds(scenarios, reps)\n const cellsById = new Map<string, CampaignCellResult<TArtifact>[]>()\n for (const cell of cells) {\n const matches = cellsById.get(cell.cellId) ?? []\n matches.push(cell)\n cellsById.set(cell.cellId, matches)\n }\n\n const scorableCellIds: string[] = []\n const unscorableCells: Array<{ cellId: string; reason: string }> = []\n for (const cellId of expectedCellIds) {\n const matches = cellsById.get(cellId) ?? []\n if (matches.length === 0) {\n unscorableCells.push({ cellId, reason: 'missing campaign cell' })\n continue\n }\n if (matches.length > 1) {\n unscorableCells.push({ cellId, reason: `duplicate campaign cell (${matches.length})` })\n continue\n }\n\n const cell = matches[0]!\n const scoreEntries = Object.entries(cell.judgeScores)\n const successfulScores = scoreEntries\n .map(([, score]) => score)\n .filter((score) => score.failed !== true && Number.isFinite(score.composite))\n const nonFiniteScores = scoreEntries.filter(\n ([, score]) =>\n score.failed !== true &&\n (!Number.isFinite(score.composite) ||\n Object.values(score.dimensions).some((value) => !Number.isFinite(value))),\n )\n const reasons: string[] = []\n if (cell.error) reasons.push(cell.error)\n if (cell.artifact === null || cell.artifact === undefined) reasons.push('missing artifact')\n if (!cell.error && requireJudgeScore && successfulScores.length === 0) {\n reasons.push('no successful finite judge score')\n }\n if (scoreEntries.some(([, score]) => score.failed === true)) {\n reasons.push('judge score marked failed')\n }\n const failedPanelJudges = [\n ...new Set(scoreEntries.flatMap(([, score]) => score.failedJudges ?? [])),\n ].sort()\n if (failedPanelJudges.length > 0) {\n reasons.push(`judge panel incomplete: ${failedPanelJudges.join(', ')}`)\n }\n if (nonFiniteScores.length > 0) {\n reasons.push(\n `non-finite judge score: ${nonFiniteScores\n .map(([name]) => name)\n .sort()\n .join(', ')}`,\n )\n }\n\n if (reasons.length > 0) {\n unscorableCells.push({ cellId, reason: reasons.join('; ') })\n } else {\n scorableCellIds.push(cellId)\n }\n }\n\n const expected = new Set(expectedCellIds)\n for (const cell of cells) {\n if (cell.cellId !== `${cell.scenarioId}:${cell.rep}`) {\n unscorableCells.push({\n cellId: cell.cellId,\n reason: 'campaign cell id does not match scenario id and rep',\n })\n continue\n }\n if (!expected.has(cell.cellId)) {\n unscorableCells.push({ cellId: cell.cellId, reason: 'unexpected campaign cell' })\n }\n }\n\n return {\n complete: unscorableCells.length === 0 && scorableCellIds.length === expectedCellIds.length,\n expectedCellIds,\n scorableCellIds,\n unscorableCells,\n }\n}\n\nexport function formatCoverageFailures(coverage: CampaignCoverage): string {\n const shown = coverage.unscorableCells\n .slice(0, 3)\n .map((cell) => `${cell.cellId}: ${cell.reason}`)\n .join('; ')\n const remainder = coverage.unscorableCells.length - Math.min(3, coverage.unscorableCells.length)\n return remainder > 0 ? `${shown}; +${remainder} more` : shown || 'unknown coverage failure'\n}\n\nfunction designedCellIds<TScenario extends Scenario>(\n scenarios: readonly TScenario[],\n reps: number,\n): string[] {\n const ids: string[] = []\n for (const scenario of scenarios) {\n for (let rep = 0; rep < reps; rep++) ids.push(`${scenario.id}:${rep}`)\n }\n return ids\n}\n\n/** Require the complete designed denominator before a final comparison. */\nexport function assertCompleteCampaign<TArtifact, TScenario extends Scenario>(\n campaign: CampaignResult<TArtifact, TScenario>,\n scenarios: readonly TScenario[],\n reps: number,\n requireJudgeScore: boolean,\n label: string,\n): void {\n const coverage = campaignCoverage(campaign.cells, scenarios, reps, requireJudgeScore)\n if (!coverage.complete) {\n throw new Error(\n `${label} is incomplete (${coverage.scorableCellIds.length}/${coverage.expectedCellIds.length} designed cells scorable) — ${formatCoverageFailures(coverage)}. Refusing to compare unequal results.`,\n )\n }\n}\n","/**\n * Backend-integrity guard: distinguish \"agent failed\" from \"eval ran against\n * a stub / unconfigured backend.\" Without this guard a canonical eval can\n * silently report `0/N passed` and look like an agent-quality problem when\n * the LLM was never actually called — the failure mode we just hit running\n * the 4-vertical parallel eval (legal-sandbox-stub returned hard-coded 33-104\n * char strings; gtm/creative defaulted to a cli-bridge that wasn't running).\n *\n * The shape:\n *\n * const report = summarizeBackendIntegrity(records)\n * assertRealBackend(records) // throws BackendIntegrityError if 100% stub\n *\n * A record is \"stub-mode\" if its `tokenUsage.input === 0 && tokenUsage.output === 0`.\n * (`costUsd` alone is unreliable — some backends successfully call LLMs but\n * don't propagate pricing, producing real tokens with $0 cost.)\n *\n * Verdicts:\n * - `real` — at least one record has nonzero token usage\n * - `stub` — every record is stub-mode (eval ran blind)\n * - `mixed` — some records real, some stub (partial backend failure;\n * often the 429-cascade or auth-half-failed case)\n */\n\nimport type { CostReceipt } from '../cost-ledger'\nimport { AgentEvalError } from '../errors'\nimport type { RunRecord } from '../run-record'\n\nexport interface BackendIntegrityReport {\n /** Total records inspected. */\n totalRecords: number\n /** Records with input=0 AND output=0 (a stub fingerprint). */\n stubRecords: number\n /** Records with nonzero token usage (real LLM activity). */\n realRecords: number\n /** Records where output>0 but costUsd=0 (real LLM, broken cost ledger). */\n uncostedRecords: number\n /** Sum of input tokens across all records. */\n totalInputTokens: number\n /** Sum of output tokens across all records. */\n totalOutputTokens: number\n /** Sum of costUsd across all records. */\n totalCostUsd: number\n /** Worst-case integrity verdict. */\n verdict: 'real' | 'mixed' | 'stub'\n /** Human-readable diagnosis suitable for terminal output. */\n diagnosis: string\n}\n\n/**\n * Error thrown when an integrity assertion fails. Caller can pattern-match\n * by `code === 'AGENT_EVAL_BACKEND_STUB'` to differentiate from other\n * errors.\n */\nexport class BackendIntegrityError extends AgentEvalError {\n constructor(\n message: string,\n public readonly report: BackendIntegrityReport,\n ) {\n super('backend_integrity', message)\n }\n}\n\n/**\n * Inspect a batch of RunRecords and return an integrity report. Pure\n * function — no I/O, no logging. The caller decides what to do with the\n * verdict (print warning, throw, gate CI, etc.).\n */\nexport function summarizeBackendIntegrity(\n records: ReadonlyArray<RunRecord>,\n): BackendIntegrityReport {\n return summarizeBackendUsage(\n records.map((record) => ({\n inputTokens: record.tokenUsage.input,\n outputTokens: record.tokenUsage.output,\n costUsd: record.costUsd,\n })),\n )\n}\n\n/** Inspect settled agent calls from the canonical cost ledger. */\nexport function summarizeAgentReceiptIntegrity(\n receipts: ReadonlyArray<CostReceipt>,\n): BackendIntegrityReport {\n return summarizeBackendUsage(\n receipts\n .filter((receipt) => receipt.channel === 'agent')\n .map((receipt) => ({\n inputTokens: receipt.inputTokens,\n outputTokens: receipt.outputTokens,\n costUsd: receipt.costUsd,\n })),\n )\n}\n\ninterface BackendUsage {\n inputTokens: number\n outputTokens: number\n costUsd: number | null\n}\n\nfunction summarizeBackendUsage(records: readonly BackendUsage[]): BackendIntegrityReport {\n const totalRecords = records.length\n let stubRecords = 0\n let realRecords = 0\n let uncostedRecords = 0\n let totalInputTokens = 0\n let totalOutputTokens = 0\n let totalCostUsd = 0\n for (const rec of records) {\n totalInputTokens += rec.inputTokens\n totalOutputTokens += rec.outputTokens\n totalCostUsd += rec.costUsd ?? 0\n if (rec.inputTokens === 0 && rec.outputTokens === 0) stubRecords++\n else realRecords++\n if (rec.outputTokens > 0 && (rec.costUsd === null || rec.costUsd === 0)) uncostedRecords++\n }\n const verdict: BackendIntegrityReport['verdict'] =\n totalRecords === 0\n ? 'stub'\n : stubRecords === totalRecords\n ? 'stub'\n : stubRecords === 0\n ? 'real'\n : 'mixed'\n const diagnosis = buildDiagnosis({\n totalRecords,\n stubRecords,\n realRecords,\n uncostedRecords,\n totalInputTokens,\n totalOutputTokens,\n totalCostUsd,\n verdict,\n })\n return {\n totalRecords,\n stubRecords,\n realRecords,\n uncostedRecords,\n totalInputTokens,\n totalOutputTokens,\n totalCostUsd,\n verdict,\n diagnosis,\n }\n}\n\nfunction buildDiagnosis(r: Omit<BackendIntegrityReport, 'diagnosis'>): string {\n if (r.totalRecords === 0) {\n return 'no records — eval produced zero runs; backend likely failed before first turn'\n }\n if (r.verdict === 'stub') {\n return [\n `all ${r.totalRecords} records have zero token usage — the LLM backend was never called.`,\n 'common causes: --backend sandbox without a sandbox bridge running; stub model returning hard-coded strings;',\n 'auth misconfigured so requests were silently dropped before the LLM. Re-run with --backend tcloud and TANGLE_API_KEY set,',\n 'or boot the cli-bridge / sandbox before invoking the eval.',\n ].join(' ')\n }\n if (r.verdict === 'mixed') {\n const pct = ((r.stubRecords / r.totalRecords) * 100).toFixed(0)\n return [\n `${r.stubRecords}/${r.totalRecords} records (${pct}%) have zero token usage — the backend partially failed.`,\n 'common causes: rate-limit cascade (429s after the first N personas);',\n 'transient auth expiry mid-run; provider outage. Treat the affected records as missing data, not agent failures.',\n ].join(' ')\n }\n // verdict === 'real'\n if (r.uncostedRecords > 0) {\n const pct = ((r.uncostedRecords / r.totalRecords) * 100).toFixed(0)\n return [\n `${r.totalRecords} records with real LLM activity (in=${r.totalInputTokens}, out=${r.totalOutputTokens} tokens).`,\n `${r.uncostedRecords} (${pct}%) have output tokens but costUsd=0. Two distinct roots:`,\n '(a) cost ledger mis-wired — no usage propagation from the runtime stream into RunRecord; or',\n '(b) the model is unpriced at the source (sandbox/router returned $0 despite real tokens).',\n 'For (b), price the measured tokens against the substrate table (estimateCost) instead of leaving $0.',\n ].join(' ')\n }\n return `${r.totalRecords} records with real LLM activity (in=${r.totalInputTokens}, out=${r.totalOutputTokens} tokens, $${r.totalCostUsd.toFixed(4)}).`\n}\n\n/**\n * Throw BackendIntegrityError if the verdict is 'stub' — i.e. every record\n * shows zero LLM activity. Non-strict callers can pass `{ allowMixed: false }`\n * to also reject mixed verdicts (recommended for CI gates).\n *\n * Real backends pass through silently.\n */\nexport function assertRealBackend(\n records: ReadonlyArray<RunRecord>,\n opts: { allowMixed?: boolean } = {},\n): BackendIntegrityReport {\n const report = summarizeBackendIntegrity(records)\n return assertBackendReport(report, opts)\n}\n\n/** Reject a cost ledger with no real agent call or a partial stub run. */\nexport function assertRealAgentReceipts(\n receipts: ReadonlyArray<CostReceipt>,\n opts: { allowMixed?: boolean } = {},\n): BackendIntegrityReport {\n const report = summarizeAgentReceiptIntegrity(receipts)\n return assertBackendReport(report, opts)\n}\n\nfunction assertBackendReport(\n report: BackendIntegrityReport,\n opts: { allowMixed?: boolean },\n): BackendIntegrityReport {\n const allowMixed = opts.allowMixed ?? true\n if (report.verdict === 'stub') {\n throw new BackendIntegrityError(\n `backend-integrity: ran against a stub or unconfigured backend — ${report.diagnosis}`,\n report,\n )\n }\n if (!allowMixed && report.verdict === 'mixed') {\n throw new BackendIntegrityError(\n `backend-integrity: partial backend failure rejected — ${report.diagnosis}`,\n report,\n )\n }\n return report\n}\n","import { createHash } from 'node:crypto'\nimport { canonicalString } from '../ledger-core/canonical'\nimport type { CodeSurface, ComponentSurface, MutableSurface } from './types'\n\nconst GIT_OBJECT_ID = /^(?:[a-f0-9]{40}|[a-f0-9]{64})$/\nconst SHA256 = /^sha256:[a-f0-9]{64}$/\n\n/** Validate the immutable identity shape; the owning executor verifies the Git objects and patch. */\nexport function assertCodeSurfaceIdentity(surface: unknown): asserts surface is CodeSurface {\n if (!surface || typeof surface !== 'object') {\n throw new TypeError('CodeSurface must be an object')\n }\n const candidate = surface as Partial<CodeSurface>\n if (candidate.kind !== 'code') throw new TypeError('CodeSurface.kind must be \"code\"')\n if (typeof candidate.worktreeRef !== 'string' || candidate.worktreeRef.trim().length === 0) {\n throw new TypeError('CodeSurface.worktreeRef must be a non-empty locator')\n }\n if (typeof candidate.baseRef !== 'string' || candidate.baseRef.trim().length === 0) {\n throw new TypeError('CodeSurface.baseRef must be a non-empty ref label')\n }\n for (const [field, value] of [\n ['baseCommit', candidate.baseCommit],\n ['baseTree', candidate.baseTree],\n ['candidateCommit', candidate.candidateCommit],\n ['candidateTree', candidate.candidateTree],\n ] as const) {\n if (typeof value !== 'string' || !GIT_OBJECT_ID.test(value)) {\n throw new TypeError(`CodeSurface.${field} must be a full Git object id`)\n }\n }\n const patch = candidate.patch\n if (!patch || typeof patch !== 'object' || patch.format !== 'git-diff-binary') {\n throw new TypeError('CodeSurface.patch.format must be \"git-diff-binary\"')\n }\n if (typeof patch.sha256 !== 'string' || !SHA256.test(patch.sha256)) {\n throw new TypeError('CodeSurface.patch.sha256 must be a sha256 digest')\n }\n if (!Number.isSafeInteger(patch.byteLength) || patch.byteLength < 0) {\n throw new TypeError('CodeSurface.patch.byteLength must be a non-negative safe integer')\n }\n}\n\n/** Assert that a value is a valid non-empty component surface. */\nfunction assertComponentSurface(surface: unknown): asserts surface is ComponentSurface {\n if (!surface || typeof surface !== 'object') {\n throw new TypeError('ComponentSurface must be an object')\n }\n const candidate = surface as Partial<ComponentSurface>\n if (candidate.kind !== 'components') {\n throw new TypeError('ComponentSurface.kind must be \"components\"')\n }\n if (\n !candidate.components ||\n typeof candidate.components !== 'object' ||\n Array.isArray(candidate.components)\n ) {\n throw new TypeError('ComponentSurface.components must be an object')\n }\n const entries = Object.entries(candidate.components)\n if (entries.length === 0) {\n throw new TypeError('ComponentSurface.components must not be empty')\n }\n for (const [name, content] of entries) {\n if (!name.trim() || name.trim() !== name) {\n throw new TypeError('ComponentSurface component names must be trimmed and non-empty')\n }\n if (typeof content !== 'string') {\n throw new TypeError(`ComponentSurface component '${name}' must be a string`)\n }\n }\n}\n\n/**\n * Deterministic identity material for a component surface.\n *\n * `canonicalString` orders keys by UTF-16 code unit (RFC 8785), which is a\n * property of the value alone. The previous material ordered them with\n * `localeCompare`, which reads the host's collation — so the same surface\n * could produce two different identities on two machines, and the stored\n * identity would stop matching a recomputation of the identical surface.\n */\nexport function componentSurfaceIdentityMaterial(surface: ComponentSurface): string {\n assertComponentSurface(surface)\n return canonicalString({\n schema: 'tangle.component-surface',\n components: surface.components,\n })\n}\n\n/**\n * The retired material builder, kept PRIVATE and reachable only from\n * {@link surfaceHashMatches}.\n *\n * A surface identity recorded before this release was minted from these bytes.\n * The verify path tries the current material first and falls back to this one,\n * so a stored identity still matches its own surface; nothing mints from it.\n *\n * Every component surface's identity moves, not only one whose names sort\n * differently under the host's collation: RFC 8785 also orders the two\n * top-level keys, so `components` precedes `schema` where this builder emitted\n * them in literal order. The retention window therefore covers every stored\n * component-surface identity, which is why this builder is kept rather than\n * scoped to the mixed-case case.\n */\nfunction retiredComponentSurfaceIdentityMaterial(surface: ComponentSurface): string {\n assertComponentSurface(surface)\n return JSON.stringify({\n schema: 'tangle.component-surface',\n components: Object.fromEntries(\n Object.entries(surface.components).sort(([left], [right]) => left.localeCompare(right)),\n ),\n })\n}\n\n/** Canonical, location-independent identity of a finalized code candidate.\n * Commit metadata is excluded: two commits with the same base, final tree,\n * and patch bytes are the same executable candidate. */\nexport function codeSurfaceIdentityMaterial(surface: CodeSurface): string {\n assertCodeSurfaceIdentity(surface)\n return JSON.stringify({\n schema: 'tangle.code-surface',\n baseCommit: surface.baseCommit,\n baseTree: surface.baseTree,\n candidateTree: surface.candidateTree,\n patch: {\n format: surface.patch.format,\n sha256: surface.patch.sha256,\n byteLength: surface.patch.byteLength,\n },\n })\n}\n\n/** Full SHA-256 content identity for a prompt or finalized code surface. */\nexport function surfaceContentHash(surface: MutableSurface): `sha256:${string}` {\n const material =\n typeof surface === 'string'\n ? surface\n : surface.kind === 'components'\n ? componentSurfaceIdentityMaterial(surface)\n : codeSurfaceIdentityMaterial(surface)\n return `sha256:${createHash('sha256').update(material).digest('hex')}`\n}\n\n/** Short loop key derived from the same content identity as provenance. */\nexport function surfaceHash(surface: MutableSurface): string {\n return surfaceContentHash(surface).slice('sha256:'.length, 'sha256:'.length + 16)\n}\n\n/**\n * Whether `storedHash` is the loop key of `surface`, under the current identity\n * material or the retired one.\n *\n * A stored key is 16 hex characters with no room for a scheme tag, so the\n * scheme cannot be read off the value the way an `agent-profile-cell` id names\n * its own. The verify path therefore tries both, which gives the same property:\n * a key minted by an earlier release still matches its own surface, and a\n * surface that was actually edited matches neither.\n *\n * Only a component surface can differ between the two; a prompt or code surface\n * produces identical material under both, so the second comparison is a no-op\n * for them.\n */\nexport function surfaceHashMatches(surface: MutableSurface, storedHash: string): boolean {\n if (surfaceHash(surface) === storedHash) return true\n if (typeof surface === 'string' || surface.kind !== 'components') return false\n const retired = createHash('sha256')\n .update(retiredComponentSurfaceIdentityMaterial(surface))\n .digest('hex')\n return retired.slice(0, 16) === storedHash\n}\n\n/** Canonical customer-visible description of the exact before/after surfaces. */\nexport function renderSurfaceDiff(\n winnerSurface: MutableSurface,\n baselineSurface: MutableSurface,\n): string {\n if (typeof winnerSurface === 'string' && typeof baselineSurface === 'string') {\n return [\n '--- baseline',\n '+++ winner',\n ...baselineSurface.split('\\n').map((line) => `- ${line}`),\n ...winnerSurface.split('\\n').map((line) => `+ ${line}`),\n ].join('\\n')\n }\n\n const describe = (surface: MutableSurface): string => {\n if (typeof surface === 'string') return '(prompt surface)'\n if (surface.kind === 'components') {\n assertComponentSurface(surface)\n return Object.entries(surface.components)\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([name, content]) => `[${name}]\\n${content}`)\n .join('\\n\\n')\n }\n assertCodeSurfaceIdentity(surface)\n return [\n `baseCommit=${surface.baseCommit}`,\n `baseTree=${surface.baseTree}`,\n `candidateCommit=${surface.candidateCommit}`,\n `candidateTree=${surface.candidateTree}`,\n `patch=${surface.patch.sha256}`,\n `patchBytes=${surface.patch.byteLength}`,\n ...(surface.summary ? [surface.summary] : []),\n ].join('\\n')\n }\n\n return `--- baseline\\n${describe(baselineSurface)}\\n+++ winner\\n${describe(winnerSurface)}`\n}\n\n/** Bind a campaign cache entry to the exact surface and caller-owned execution revision. */\nexport function surfaceDispatchRef(surface: MutableSurface, executionRef = 'anonymous'): string {\n if (!executionRef.trim() || executionRef.trim() !== executionRef) {\n throw new Error('surfaceDispatchRef: executionRef must be trimmed and non-empty')\n }\n return `surface:${executionRef}:${surfaceContentHash(surface)}`\n}\n","import {\n type PairedBootstrapOptions,\n type PairedBootstrapResult,\n pairedBootstrap,\n pairedSignTest,\n} from './statistics'\n\nexport interface PairedDeltaTestOptions extends PairedBootstrapOptions {\n /** Smallest candidate-minus-baseline delta that counts as improvement. Default 0. */\n threshold?: number\n /** Caller-required paired observations. The exact test may impose a higher minimum. */\n minPairs?: number\n}\n\nexport interface PairedDeltaTestResult {\n bootstrap: PairedBootstrapResult\n method: 'bootstrap-ci' | 'exact-sign'\n /** Exact one-sided p-value below the bootstrap minimum; otherwise null. */\n pValue: number | null\n /** Effective observation minimum after accounting for confidence. */\n minimumPairs: number\n sufficient: boolean\n /**\n * The bootstrap interval has zero width (or is non-finite), so it carries no\n * information about how far the estimate could be wrong and cannot support a\n * decision in either direction. See {@link pairedDeltaTest}.\n */\n indeterminate: boolean\n significant: boolean\n}\n\n/** Smallest all-positive sample that can clear a one-sided exact sign test. */\nexport function minimumPairsForPairedDeltaTest(confidence = 0.95): number {\n if (!Number.isFinite(confidence) || confidence <= 0 || confidence >= 1) {\n throw new Error(\n `minimumPairsForPairedDeltaTest: confidence must be in (0,1), got ${confidence}`,\n )\n }\n const oneSidedAlpha = (1 - confidence) / 2\n return Math.ceil(Math.log2(1 / oneSidedAlpha))\n}\n\n/**\n * Tests whether a paired candidate-minus-baseline delta clears a threshold.\n *\n * At 20 or more pairs, the percentile bootstrap lower bound carries the\n * decision. Below that point the interval is descriptive only, so the function\n * switches to a pre-registered one-sided exact sign test. The exact path is\n * deliberately conservative: it requires both a point estimate above the\n * threshold and enough consistently positive paired differences.\n *\n * ## A zero-width interval is never significant\n *\n * When every paired delta is identical the resample distribution is a point\n * mass and the interval collapses: `[0, 0]` when all pairs tie, `[g, g]` on n\n * identical deltas of g. Neither says the effect is certain — both say the\n * sample carries no information about how far the estimate could be wrong, and\n * `low > threshold` then answers on the point estimate alone. It fails in both\n * directions: `[0, 0]` clears every NEGATIVE threshold, which is how a\n * tie-dominated pass/fail comparison laundered a regression into a\n * noninferiority pass, and `[g, g]` clears every threshold below g with no\n * spread behind it. Under a bounded asymmetric null whose true mean paired\n * delta is exactly 0 — 2 % of pairs dropping by 1.0, the rest gaining 0.0204 —\n * every sample that misses the drop is exactly that shape, and deciding on\n * `low > 0` promoted 65.65 % of samples at n = 20 against a nominal 5 %.\n *\n * So `indeterminate` is reported and `significant` is false whenever the\n * interval has zero width, on BOTH paths: at small n the exact sign test is a\n * test of the MEDIAN and a zero-spread sample is precisely where it stops\n * saying anything about the mean the caller is thresholding.\n *\n * `threshold` may be negative — that is a noninferiority margin, and it is the\n * regime the zero-width hole is worst in. For a two-point (pass/fail) outcome\n * the percentile bootstrap is not a valid interval at a nonzero margin at all;\n * use {@link decidePairedPromotion}, which routes those to Tango's score\n * interval, rather than thresholding this function's bootstrap directly.\n */\nexport function pairedDeltaTest(\n before: number[],\n after: number[],\n options: PairedDeltaTestOptions = {},\n): PairedDeltaTestResult {\n const threshold = options.threshold ?? 0\n if (!Number.isFinite(threshold)) {\n throw new Error(`pairedDeltaTest: threshold must be finite, got ${threshold}`)\n }\n const confidence = options.confidence ?? 0.95\n const exactMinimum = minimumPairsForPairedDeltaTest(confidence)\n const requestedMinimum = options.minPairs ?? exactMinimum\n if (!Number.isInteger(requestedMinimum) || requestedMinimum < 1) {\n throw new Error(`pairedDeltaTest: minPairs must be a positive integer, got ${requestedMinimum}`)\n }\n const minimumPairs = Math.max(requestedMinimum, exactMinimum)\n const bootstrap = pairedBootstrap(before, after, options)\n const sufficient = bootstrap.n >= minimumPairs\n // A point-mass resample distribution is an absence of evidence, not a\n // certainty, and it is the shape that clears every negative threshold. Both\n // paths refuse it: see the \"zero-width\" section of this function's docs.\n const indeterminate =\n bootstrap.n > 0 &&\n (!Number.isFinite(bootstrap.low) ||\n !Number.isFinite(bootstrap.high) ||\n bootstrap.low === bootstrap.high)\n\n if (bootstrap.gateEligible) {\n return {\n bootstrap,\n method: 'bootstrap-ci',\n pValue: null,\n minimumPairs,\n sufficient,\n indeterminate,\n significant: sufficient && !indeterminate && bootstrap.low > threshold,\n }\n }\n\n const differences = before.map((value, index) => after[index]! - value - threshold)\n const exact = pairedSignTest(differences, 'greater')\n const estimate = options.statistic === 'mean' ? bootstrap.mean : bootstrap.median\n return {\n bootstrap,\n method: 'exact-sign',\n pValue: exact.pValue,\n minimumPairs,\n sufficient,\n indeterminate,\n significant:\n sufficient &&\n !indeterminate &&\n estimate > threshold &&\n exact.pValue <= (1 - bootstrap.confidence) / 2,\n }\n}\n","/**\n * @module\n * ONE rule for \"does this paired interval clear a promotion threshold\".\n *\n * The rule below was derived on `HeldOutGate` (#479) after the same estimator\n * bug shipped twice. It then turned out that a SECOND gate — the composable\n * `heldOutGate`, plus everything else routed through `heldoutSignificance` —\n * still carried the original defect, because the rule had been written into one\n * gate's method body rather than into a shared function. Two copies of a\n * statistical rule is how a defect survives in one of them, so there is now\n * exactly one copy and both gates call it.\n *\n * Three things the rule does that a bare `pairedBootstrap(...).low > threshold`\n * does not:\n *\n * 1. **Two-point (pass/fail) outcomes decide on Tango's SCORE interval.** On a\n * pass/fail eval the paired delta vector is dominated by ties, so the\n * bootstrap of the mean is a resample of a lattice with three atoms and its\n * percentile interval is not valid at a nonzero margin. The score interval\n * (`pairedRiskDifferenceScore`) re-estimates the nuisance loss rate under\n * each hypothesised margin instead of fixing it at the observed value, which\n * is the only construction that stays a confidence interval as the margin\n * moves off zero — the regime every noninferiority threshold lives in.\n * Measured on the composable gate before this change, at a true risk\n * difference sitting exactly on the production caller's -0.05 margin and a\n * nominal 5 %: 14.60 % false promotion at n = 40 and 10.10 % at n = 76.\n * 2. **McNemar's exact test holds a VETO at every non-negative threshold.**\n * Redundant with the interval by construction and kept anyway, so that\n * swapping the estimator for one without that duality cannot silently\n * reintroduce \"promotes what the exact test refuses\". Witness: n = 6, b = 5,\n * c = 0 — no exact argument reaches alpha = 0.05 with 5 discordant pairs\n * (two-sided floor 2/2^5 = 0.0625), whatever an interval says. A NEGATIVE\n * threshold is a noninferiority question, which McNemar's test of \"no\n * difference\" is not the right test for, so the veto does not apply there.\n * 3. **A ZERO-WIDTH interval is refused, wherever it sits.** At [0, 0] it\n * cannot tell a gain from a regression and clears every negative threshold.\n * Away from zero it fails the opposite way: n identical positive deltas give\n * [g, g], which clears threshold 0 on no spread at all. Both are an absence\n * of evidence. Measured on the composable gate before this change, under a\n * bounded asymmetric null whose true mean paired delta is exactly 0: 88.50 %\n * false promotion at n = 6 and 65.65 % at n = 20 against a nominal 5 %.\n *\n * Orthogonal to the small-sample switch inside {@link pairedDeltaTest}: that\n * picks the TEST from the sample size (bootstrap CI at n >= 20, pre-registered\n * exact sign test below it), this picks the ESTIMATOR from the outcome's shape.\n * Both are needed — an exact sign test applied to a tie-pinned median is still\n * blind, and a mean bootstrap CI at n = 6 is still not a valid test.\n */\n\nimport { minimumPairsForPairedDeltaTest, pairedDeltaTest } from './paired-delta-test'\nimport {\n type PairedBootstrapResult,\n pairedBinaryScale,\n pairedDeltaTieFraction,\n pairedRiskDifferenceExact,\n pairedRiskDifferenceScore,\n} from './statistics'\n\n/** Which paired estimator produced the deciding interval. */\nexport type PairedDecisionStatistic =\n | 'paired_risk_difference'\n | 'mean_bootstrap'\n | 'median_bootstrap'\n\n/** Which test carried the decision, given the estimator and the sample size. */\nexport type PairedDecisionMethod = 'score-interval' | 'bootstrap-ci' | 'exact-sign'\n\n/** McNemar's exact paired-binary evidence, on the two-point path only. */\nexport interface PairedMcNemarEvidence {\n /** Discordant pairs the treatment won. */\n b: number\n /** Discordant pairs the control won. */\n c: number\n /** b + c — the only pairs carrying information. */\n nDiscordant: number\n /** Two-sided exact p-value. */\n pValue: number\n}\n\nexport interface PairedPromotionDecisionOptions {\n /** Smallest candidate-minus-baseline delta that counts as improvement, in the\n * caller's native units. May be negative (a noninferiority margin). Default 0. */\n threshold?: number\n /** Confidence level. Default 0.95. */\n confidence?: number\n /** Bootstrap resamples, on the paths where a bootstrap decides. Default 2000. */\n resamples?: number\n /** Deterministic bootstrap seed. Omitted ⇒ derived from the deltas. */\n seed?: number\n /** Caller-required paired observations. The exact test may impose a higher\n * minimum; the effective one is reported as `minimumPairs`. */\n minPairs?: number\n /**\n * `'mean'` (default) routes by SHAPE: a two-point (pass/fail) outcome on any\n * encoding decides on the score interval, everything else on the mean\n * bootstrap. `'median'` forces the median bootstrap on every input, including\n * shapes where it is structurally blind — kept for callers who want outlier\n * robustness on genuinely continuous outcomes and accept that cost.\n */\n statistic?: 'mean' | 'median'\n}\n\nexport interface PairedPromotionDecision {\n /** Paired observations supplied. */\n n: number\n /** Threshold the interval was judged against, native units. */\n threshold: number\n confidence: number\n statistic: PairedDecisionStatistic\n method: PairedDecisionMethod\n /** Common positive level of a two-point outcome ({0,1} ⇒ 1, {0,100} ⇒ 100),\n * or null when the outcome is not two-point. Non-null is exactly the\n * condition for the `paired_risk_difference` path, and it is the factor\n * `delta` / `low` / `high` were rescaled by. */\n binaryScale: number | null\n /** Exact-tie fraction over the paired deltas; null when there are no pairs. */\n tieFraction: number | null\n /** Point estimate of the DECIDING statistic, in the caller's native units. */\n delta: number\n /** Lower bound of the DECIDING interval, native units. */\n low: number\n /** Upper bound of the DECIDING interval, native units. */\n high: number\n /** The bootstrap that decided, or null when the score interval did. Callers\n * that need a bootstrap as a diagnostic on the two-point path compute their\n * own — it is not computed here, so the binary path costs no resamples. */\n bootstrap: PairedBootstrapResult | null\n /** McNemar's exact evidence, or null off the two-point path. */\n mcnemar: PairedMcNemarEvidence | null\n /** Exact one-sided sign-test p-value on the small-sample bootstrap path;\n * null otherwise. */\n pValue: number | null\n /** Effective observation minimum after accounting for confidence. */\n minimumPairs: number\n /** n >= minimumPairs. */\n sufficient: boolean\n /** The deciding interval is zero-width or non-finite — no evidence in either\n * direction, so it cannot clear any threshold on evidence. */\n indeterminate: boolean\n /** McNemar's exact test refuses at a non-negative threshold. */\n exactTestVetoes: boolean\n /** The deciding interval clears the threshold, ignoring the other two guards. */\n clearsThreshold: boolean\n /** `sufficient && !indeterminate && clearsThreshold && !exactTestVetoes` —\n * the whole rule. */\n promote: boolean\n /** What `delta` measures, for a reason string. */\n label: 'success-rate' | 'mean' | 'median'\n /** Why a zero-width interval is zero-width; empty when it is not. */\n indeterminateCause: string\n /** Sentence naming the test when the exact sign test decided; else empty. */\n methodDetail: string\n}\n\n/** The shape facts that pick the estimator, without computing an interval. */\nexport interface PairedDecisionShape {\n statistic: PairedDecisionStatistic\n /** Common positive level of a two-point outcome; null when not two-point. */\n binaryScale: number | null\n /** Exact-tie fraction over the paired deltas; null when there are no pairs. */\n tieFraction: number | null\n}\n\n/**\n * Which estimator {@link decidePairedPromotion} would use on this data, and the\n * shape facts behind it — for callers that must report the shape on a path\n * where no interval is computed at all (an early rejection, or zero pairs).\n * Cheap: no bootstrap, no interval.\n */\nexport function pairedDecisionShape(\n before: number[],\n after: number[],\n statistic: 'mean' | 'median' = 'mean',\n): PairedDecisionShape {\n const tieFraction = before.length === 0 ? null : pairedDeltaTieFraction(before, after)\n if (statistic === 'median') {\n return { statistic: 'median_bootstrap', binaryScale: null, tieFraction }\n }\n const binaryScale = pairedBinaryScale(before, after)\n if (binaryScale !== null) {\n return { statistic: 'paired_risk_difference', binaryScale, tieFraction }\n }\n return { statistic: 'mean_bootstrap', binaryScale: null, tieFraction }\n}\n\n/**\n * Decide whether a paired candidate-minus-baseline delta clears a promotion\n * threshold. `before` is the baseline arm, `after` the candidate arm, paired by\n * position. Throws on unequal lengths.\n */\nexport function decidePairedPromotion(\n before: number[],\n after: number[],\n options: PairedPromotionDecisionOptions = {},\n): PairedPromotionDecision {\n if (before.length !== after.length) {\n throw new Error(\n `decidePairedPromotion: unequal sample sizes (${before.length} vs ${after.length})`,\n )\n }\n const threshold = options.threshold ?? 0\n if (!Number.isFinite(threshold)) {\n throw new Error(`decidePairedPromotion: threshold must be finite, got ${threshold}`)\n }\n const confidence = options.confidence ?? 0.95\n const exactMinimum = minimumPairsForPairedDeltaTest(confidence)\n const requestedMinimum = options.minPairs ?? exactMinimum\n if (!Number.isInteger(requestedMinimum) || requestedMinimum < 1) {\n throw new Error(\n `decidePairedPromotion: minPairs must be a positive integer, got ${requestedMinimum}`,\n )\n }\n const minimumPairs = Math.max(requestedMinimum, exactMinimum)\n const n = before.length\n const sufficient = n >= minimumPairs\n const { binaryScale, tieFraction } = pairedDecisionShape(before, after, options.statistic)\n\n let core: {\n statistic: PairedDecisionStatistic\n method: PairedDecisionMethod\n delta: number\n low: number\n high: number\n bootstrap: PairedBootstrapResult | null\n mcnemar: PairedMcNemarEvidence | null\n pValue: number | null\n clearsThreshold: boolean\n label: PairedPromotionDecision['label']\n methodDetail: string\n }\n\n if (binaryScale !== null) {\n // Normalise the two-point encoding to {0,1} so the estimators see the\n // pass/fail structure, then rescale the answer back into the caller's\n // native units — the threshold is read in the units of the scores, so a\n // 0-100 pass/fail dimension must be gated in points, not in a rate.\n const unitControl = before.map((v) => v / binaryScale)\n const unitTreatment = after.map((v) => v / binaryScale)\n // TWO estimators with different jobs, because no single one does both.\n // `exact` is the authority on RD = 0 and supplies the veto; its\n // Clopper-Pearson interval conditions on the discordant count and is\n // therefore NOT a confidence interval at a nonzero margin. `score` is\n // Tango's, which is.\n const exact = pairedRiskDifferenceExact(unitControl, unitTreatment, confidence)\n const score = pairedRiskDifferenceScore(unitControl, unitTreatment, confidence)\n const low = score.lower * binaryScale\n core = {\n statistic: 'paired_risk_difference',\n method: 'score-interval',\n delta: score.riskDifference * binaryScale,\n low,\n high: score.upper * binaryScale,\n bootstrap: null,\n mcnemar: {\n b: exact.b,\n c: exact.c,\n nDiscordant: exact.nDiscordant,\n pValue: exact.pValue,\n },\n pValue: null,\n clearsThreshold: low > threshold,\n label: 'success-rate',\n methodDetail: '',\n }\n } else {\n const bootstrapStatistic = options.statistic === 'median' ? 'median' : 'mean'\n const test = pairedDeltaTest(before, after, {\n confidence,\n resamples: options.resamples,\n statistic: bootstrapStatistic,\n seed: options.seed,\n threshold,\n minPairs: options.minPairs,\n })\n const ci = test.bootstrap\n core = {\n statistic: bootstrapStatistic === 'mean' ? 'mean_bootstrap' : 'median_bootstrap',\n method: test.method,\n delta: bootstrapStatistic === 'mean' ? ci.mean : ci.median,\n low: ci.low,\n high: ci.high,\n bootstrap: ci,\n mcnemar: null,\n pValue: test.pValue,\n clearsThreshold: test.significant,\n label: bootstrapStatistic,\n methodDetail:\n test.method === 'exact-sign'\n ? ` Below ${test.minimumPairs} pairs the interval is descriptive only;` +\n ` the decision is the exact one-sided sign test, p=${fmt(test.pValue ?? 1)}.`\n : '',\n }\n }\n\n const indeterminate =\n !Number.isFinite(core.low) || !Number.isFinite(core.high) || core.low === core.high\n const indeterminateCause = !indeterminate\n ? ''\n : tieFraction === 1\n ? 'every paired delta is an exact tie'\n : core.mcnemar !== null && core.mcnemar.nDiscordant === 0\n ? 'every pair is concordant (0 discordant pairs)'\n : `the ${core.label} CI collapsed to a point at ${fmt(core.low)}`\n // Only at a non-negative threshold: a negative threshold asks a\n // noninferiority question, which McNemar's test of \"no difference\" does not\n // answer.\n const exactTestVetoes =\n core.mcnemar !== null && threshold >= 0 && !(core.mcnemar.pValue < 1 - confidence)\n\n return {\n n,\n threshold,\n confidence,\n binaryScale,\n tieFraction,\n minimumPairs,\n sufficient,\n indeterminate,\n indeterminateCause,\n exactTestVetoes,\n promote: sufficient && !indeterminate && core.clearsThreshold && !exactTestVetoes,\n ...core,\n }\n}\n\nfunction fmt(x: number): string {\n return x.toFixed(4)\n}\n","/**\n * Statistical held-out promotion machinery — the trustworthy core the\n * point-estimate `heldout-delta` gate lacked.\n *\n * The shipped false positive it prevents: a winner re-scored against the\n * baseline on the holdout read run-to-run model NOISE (e.g. 91 vs 95) as a\n * \"+4 lift\" and shipped, because the gate compared point estimates with no\n * confidence interval. Here we pair candidate vs baseline holdout observations\n * and bootstrap a CI on the paired delta — a candidate ships only when the CI\n * lower bound clears the effect-size threshold (the gain is real at the\n * confidence level, not noise), and is blocked when a critical dimension\n * (e.g. `hallucination_free` for a legal agent) significantly regresses even if\n * the net composite rose (anti-Goodhart).\n *\n * Two traps this module is built around (both produce a NEW false positive if\n * gotten wrong):\n * 1. PAIRING GRANULARITY — pairs by FULL `cellId` (`scenario:rep`), never by\n * `scenarioId` (which averages reps away and destroys the within-pair\n * variance reduction that makes a paired bootstrap tighter than unpaired).\n * One paired observation per cell ⇒ reps multiply n.\n * 2. SCALE — a judge may emit composites/dimensions on [0,1] or 0-100. The\n * threshold + tolerance are interpreted in the judge's NATIVE scale; the\n * per-dimension tolerance auto-scales off the observed baseline magnitudes\n * so `-0.10` on [0,1] doesn't silently become a no-op on a 0-100 dimension.\n */\n\nimport {\n decidePairedPromotion,\n type PairedDecisionMethod,\n type PairedDecisionStatistic,\n type PairedMcNemarEvidence,\n type PairedPromotionDecision,\n} from '../../paired-promotion-decision'\nimport {\n DECISION_PAIRED_DELTA_STATISTIC,\n type PairedBootstrapResult,\n pairedBootstrap,\n} from '../../statistics'\nimport type { JudgeScore } from '../types'\n\n/** Tie fraction at/above which a gate annotates its verdict with the tie share.\n * Tie-domination of the median bites structurally at >= 0.5 (the median is then\n * 0 by construction); 0.4 is a softer warn threshold that flags a run APPROACHING\n * that regime, so an operator sees it before the median goes fully blind. */\nexport const TIE_WARN_FRACTION = 0.4\n\nexport interface PairedHoldout {\n /** Baseline scalar per paired cell (same order as `after`/`cellIds`). */\n before: number[]\n /** Candidate scalar per paired cell. */\n after: number[]\n /** The full cellIds (`scenario:rep`) that paired, in order. */\n cellIds: string[]\n}\n\n/**\n * Pair candidate vs baseline holdout observations by FULL cellId. `select`\n * pulls the scalar from a cell's judge reports (composite, or a named\n * dimension); a cell contributes the mean of `select` across its judges. Cells\n * whose scenario is not in `scenarioIds`, or where `select` is undefined for\n * every judge on either side, are skipped on BOTH sides so the arrays stay\n * paired. Throws when the two maps disagree on which holdout cells exist — a\n * load-bearing invariant: the baseline + winner holdout campaigns run the same\n * scenarios with the same seed base, so their cellIds MUST align; a mismatch\n * means a silent pairing bug, not a soft fallback.\n */\nexport function pairHoldout(\n candidate: Map<string, Record<string, JudgeScore>>,\n baseline: Map<string, Record<string, JudgeScore>>,\n scenarioIds: Set<string>,\n select: (s: JudgeScore) => number | undefined,\n): PairedHoldout {\n const cellValue = (\n byCell: Map<string, Record<string, JudgeScore>>,\n cellId: string,\n ): number | undefined => {\n const scores = byCell.get(cellId)\n if (!scores) return undefined\n const vals: number[] = []\n for (const s of Object.values(scores)) {\n if (s.failed === true) {\n throw new Error(`pairHoldout: cell '${cellId}' contains a failed judge score`)\n }\n const v = select(s)\n if (typeof v === 'number' && !Number.isFinite(v)) {\n throw new Error(`pairHoldout: cell '${cellId}' contains a non-finite selected score`)\n }\n if (typeof v === 'number') vals.push(v)\n }\n if (vals.length === 0) return undefined\n return vals.reduce((a, b) => a + b, 0) / vals.length\n }\n\n const inScope = (cellId: string) => scenarioIds.has(cellId.split(':')[0] ?? '')\n const candCells = [...candidate.keys()].filter(inScope).sort()\n const baseCells = [...baseline.keys()].filter(inScope).sort()\n // Alignment invariant — the holdout campaigns share scenarios + seed, so the\n // cell sets must be identical. Differ ⇒ a real pairing bug; fail loud.\n if (candCells.length !== baseCells.length || candCells.some((c, i) => c !== baseCells[i])) {\n throw new Error(\n `pairHoldout: candidate/baseline holdout cells do not align — ` +\n `candidate=[${candCells.join(',')}] baseline=[${baseCells.join(',')}]. ` +\n `Both holdout campaigns must run the same scenarios with the same seed base.`,\n )\n }\n\n const before: number[] = []\n const after: number[] = []\n const cellIds: string[] = []\n for (const cellId of candCells) {\n const b = cellValue(baseline, cellId)\n const a = cellValue(candidate, cellId)\n // A scalar absent on both sides means that dimension was not scored. A\n // one-sided absence is asymmetric evidence loss, never a row to discard.\n if (b === undefined && a === undefined) continue\n if (b === undefined || a === undefined) {\n throw new Error(`pairHoldout: cell '${cellId}' has a selected score on only one arm`)\n }\n before.push(b)\n after.push(a)\n cellIds.push(cellId)\n }\n return { before, after, cellIds }\n}\n\nexport interface HeldoutSignificance {\n paired: PairedHoldout\n /**\n * The paired bootstrap on the requested statistic (MEAN by default — see the\n * tie note on `heldoutSignificance`).\n *\n * DIAGNOSTIC, not necessarily the interval the verdict keyed on. On a\n * two-point (pass/fail) outcome the decision routes to Tango's score interval\n * instead, because a percentile bootstrap of the mean over a three-atom\n * lattice is not a valid interval at a nonzero margin. Read\n * `decision.low`/`decision.high` for the interval that actually decided, and\n * `decisionStatistic` for which one it is.\n */\n bootstrap: PairedBootstrapResult\n /** The MEDIAN paired-delta bootstrap, reported as a diagnostic. When many\n * scenarios are tied (both sides solve them), the median is pinned near 0\n * regardless of the mean lift — comparing the two exposes tie-domination. */\n medianBootstrap: PairedBootstrapResult\n /**\n * The full promotion decision: which estimator the outcome's shape admits,\n * the interval it produced, McNemar's exact veto on the two-point path, and\n * whether the interval was zero-width (no evidence in either direction). The\n * single source of `significant`.\n */\n decision: PairedPromotionDecision\n /** Which paired estimator the verdict was decided on. */\n decisionStatistic: PairedDecisionStatistic\n /** McNemar's exact evidence on the two-point path; null otherwise. */\n mcnemar: PairedMcNemarEvidence | null\n /** Fraction of paired observations that are exact ties (|delta| < 1e-9). A\n * high tie fraction is WHY a median-based gate would have missed a real lift;\n * it is the observability the tie fix adds. */\n tieFraction: number\n /** n paired observations. */\n n: number\n /** Effective minimum after applying the bootstrap's hard statistical floor. */\n minimumRequired: number\n /** Statistical method that carried the decision. */\n decisionMethod: PairedDecisionMethod\n /** Exact one-sided p-value on the small-sample path; otherwise null. */\n pValue: number | null\n /** True iff n >= minimumRequired, the DECIDING interval has nonzero width,\n * its lower bound clears the threshold, and McNemar's exact test does not\n * veto at a non-negative threshold. */\n significant: boolean\n /** Set when n < minimumRequired — too little evidence to claim significance. */\n fewRuns: boolean\n}\n\nexport interface HeldoutSignificanceOptions {\n deltaThreshold?: number\n minProductiveRuns?: number\n confidence?: number\n resamples?: number\n /** Fixed by default for a deterministic, reproducible gate verdict. */\n seed?: number\n statistic?: 'mean' | 'median'\n}\n\n/**\n * Significance of the held-out composite lift: ship only when the lower bound\n * of the interval the outcome's shape ADMITS exceeds `deltaThreshold` (default\n * 0 ⇒ \"confidently positive\"). Interpret `deltaThreshold` in the judge's native\n * scale.\n *\n * The decision is delegated whole to {@link decidePairedPromotion}, the one\n * copy of the rule (`src/paired-promotion-decision.ts`), which `HeldOutGate`\n * also calls. That module's header carries the measurements; the short version\n * is three guards a bare `bootstrap.low > threshold` does not have:\n *\n * - a two-point (pass/fail) outcome decides on Tango's SCORE interval, the\n * only paired-binary construction that stays valid at a nonzero margin;\n * - McNemar's exact test VETOES at any non-negative threshold;\n * - a ZERO-WIDTH interval is refused rather than promoted, in either\n * direction — [0,0] clears every negative threshold and [g,g] clears every\n * threshold below g, and both are an absence of evidence, not a result.\n *\n * Measured on this function before those guards landed, at a nominal 5 %:\n * 14.60 % false promotion at n = 40 on a paired-binary noninferiority boundary,\n * and 88.50 % at n = 6 under a bounded asymmetric null whose true mean paired\n * delta is exactly 0.\n *\n * At small n, where the percentile bootstrap is descriptive only, a\n * pre-registered exact sign test still carries the bootstrap path.\n */\nexport function heldoutSignificance(\n paired: PairedHoldout,\n opts: HeldoutSignificanceOptions = {},\n): HeldoutSignificance {\n const deltaThreshold = opts.deltaThreshold ?? 0\n const confidence = opts.confidence ?? 0.95\n const resamples = opts.resamples ?? 2000\n const seed = opts.seed ?? 1337\n // DEFAULT to the MEAN paired delta, not the median. The median is destroyed by\n // TIES: whenever both baseline and candidate solve a holdout scenario (a common\n // case once the agent is decent — and INCREASINGLY common as you add holdout\n // scenarios for statistical power), that scenario contributes delta 0. When\n // >=50% of paired cells are ties the median is pinned at 0 regardless of a large,\n // consistent lift on the rest, and the gate holds a genuinely better candidate.\n // (Measured live, supervisor-lab run 6: 40 cells, 20 ties, MEAN +0.177, MEDIAN 0\n // → false hold. Doubling the holdout for \"power\" made it WORSE by adding ties.)\n // The mean equals the reported aggregate lift, ties correctly contribute 0\n // without dominating, and it is the textbook paired-comparison estimator; the\n // median is kept as a reported diagnostic. Callers wanting outlier-robustness at\n // the cost of tie-blindness can still pass `statistic: 'median'`.\n const statistic = opts.statistic ?? 'mean'\n const decision = decidePairedPromotion(paired.before, paired.after, {\n confidence,\n resamples,\n statistic,\n seed,\n threshold: deltaThreshold,\n minPairs: opts.minProductiveRuns,\n })\n // `decision.bootstrap` is null exactly when the score interval decided, so\n // the requested-statistic bootstrap is computed here for the diagnostic\n // field. Same two bootstraps as before on every path.\n const bootstrap =\n decision.bootstrap ??\n pairedBootstrap(paired.before, paired.after, { confidence, resamples, statistic, seed })\n const medianBootstrap =\n statistic === 'median'\n ? bootstrap\n : pairedBootstrap(paired.before, paired.after, {\n confidence,\n resamples,\n statistic: 'median',\n seed,\n })\n const n = paired.before.length\n let ties = 0\n for (let i = 0; i < n; i += 1) {\n const after = paired.after[i] ?? 0\n const before = paired.before[i] ?? 0\n if (Math.abs(after - before) < 1e-9) ties += 1\n }\n const tieFraction = n === 0 ? 0 : ties / n\n return {\n paired,\n bootstrap,\n medianBootstrap,\n decision,\n decisionStatistic: decision.statistic,\n mcnemar: decision.mcnemar,\n tieFraction,\n n,\n minimumRequired: decision.minimumPairs,\n decisionMethod: decision.method,\n pValue: decision.pValue,\n significant: decision.promote,\n fewRuns: !decision.sufficient,\n }\n}\n\nexport interface DimensionRegression {\n dimension: string\n /** Paired bootstrap on (candidate − baseline). DIAGNOSTIC on a pass/fail\n * dimension, where `ci` carries the interval that decided instead. */\n bootstrap: PairedBootstrapResult\n /** Which paired statistic `bootstrap.low` is the lower bound of. `'mean'`\n * unless the caller asked for the median. `bootstrap.median` still carries\n * the median point estimate either way. */\n bootstrapStatistic: 'median' | 'mean'\n /** The interval `regressed` was decided on, in the dimension's native units. */\n ci: { low: number; high: number }\n /** Which estimator produced `ci`. */\n decisionStatistic: PairedDecisionStatistic\n /** McNemar's exact evidence on a pass/fail dimension; null otherwise. */\n mcnemar: PairedMcNemarEvidence | null\n /** `ci` has zero width — no evidence in either direction. */\n indeterminate: boolean\n /** True iff the candidate may have regressed this dimension by more than\n * tolerance: the lower bound of the DECIDING interval on (candidate −\n * baseline) is below −tolerance, OR the exact small-sample test proves a drop\n * past tolerance. */\n regressed: boolean\n tolerance: number\n n: number\n}\n\n/** Detect the native scale of a set of scores: 0-100 when any magnitude clears\n * 1.5, else [0,1]. Used to auto-scale the regression tolerance so a default\n * expressed for [0,1] is not silently a no-op on a 0-100 dimension. */\nexport function detectScale(values: number[]): 1 | 100 {\n return values.some((v) => Math.abs(v) > 1.5) ? 100 : 1\n}\n\n/** Per-critical-dimension regression guard. For each dimension, pair the\n * candidate vs baseline values by full cellId and bootstrap the paired delta;\n * a dimension is \"regressed\" when the CI lower bound < −tolerance (conservative\n * — blocks if the credible worst case exceeds tolerance, which is the right\n * posture for safety dimensions like `hallucination_free`). When `tolerance`\n * is omitted it auto-scales: 0.05 on [0,1], 5 on 0-100.\n *\n * The interval comes from {@link decidePairedPromotion}, so a pass/fail\n * dimension is judged on Tango's score interval rather than a percentile\n * bootstrap of the mean — `tolerance` is a NONZERO margin, and the bootstrap\n * is not a valid interval at one. That matters most here because this guard\n * fails OPEN by construction: `tolerance` is positive, so an interval pinned at\n * [0,0] never satisfies `low < −tolerance` and a real regression on a safety\n * dimension would be reported as `regressed: false`. On the median it fails the\n * same way for the same reason — when most pairs tie, which is automatic for a\n * pass/fail dimension on {0,1} and on the 0-100 encoding `detectScale` exists\n * to support, the median CI collapses to [0,0]. Pass `statistic: 'median'` to\n * restore the pre-0.134 behaviour. */\nexport function dimensionRegressions(\n candidate: Map<string, Record<string, JudgeScore>>,\n baseline: Map<string, Record<string, JudgeScore>>,\n scenarioIds: Set<string>,\n criticalDimensions: string[],\n opts: {\n tolerance?: number\n confidence?: number\n resamples?: number\n seed?: number\n /** Paired statistic the CI is computed on. Default `'mean'` — see\n * {@link DECISION_PAIRED_DELTA_STATISTIC} for why the median is not. */\n statistic?: 'mean' | 'median'\n } = {},\n): DimensionRegression[] {\n const out: DimensionRegression[] = []\n for (const dim of criticalDimensions) {\n const paired = pairHoldout(candidate, baseline, scenarioIds, (s) => s.dimensions[dim])\n if (paired.before.length === 0) continue // dimension not scored on this judge\n const tolerance = opts.tolerance ?? 0.05 * detectScale([...paired.before, ...paired.after])\n const bootstrapStatistic = opts.statistic ?? DECISION_PAIRED_DELTA_STATISTIC\n const shared = {\n confidence: opts.confidence ?? 0.95,\n resamples: opts.resamples ?? 2000,\n statistic: bootstrapStatistic,\n seed: opts.seed ?? 1337,\n }\n const guard = decidePairedPromotion(paired.before, paired.after, shared)\n const regression = decidePairedPromotion(paired.after, paired.before, {\n ...shared,\n threshold: tolerance,\n })\n const bootstrap = guard.bootstrap ?? pairedBootstrap(paired.before, paired.after, shared)\n out.push({\n dimension: dim,\n bootstrap,\n bootstrapStatistic,\n ci: { low: guard.low, high: guard.high },\n decisionStatistic: guard.statistic,\n mcnemar: guard.mcnemar,\n indeterminate: guard.indeterminate,\n // Fires on EITHER burden of proof — see `floorBreached` in\n // `promotion-policy.ts` for the same rule and the reasoning. The CI arm\n // is the contract this interface and `default-production-gate`'s reason\n // string both state (\"CI.low < -tolerance\"), read off the DECIDING\n // interval; the exact-test arm adds the small-sample path where the\n // bootstrap interval is descriptive only.\n // The credible-worst-case arm stays on the BOOTSTRAP — see the same\n // decision in `floorBreached` (`promotion-policy.ts`). On a pass/fail\n // dimension the score interval is ±z²/(n+z²) even when every pair is\n // concordant, so reading the floor off it would flag an unchanged safety\n // dimension as regressed at any realistic n. The PROVEN-drop arm does use\n // the shared rule, which is what closes the fail-open hole that mattered:\n // a genuine pass/fail regression is now judged on an interval valid at\n // the nonzero `tolerance`, instead of a bootstrap that is pinned wherever\n // ties dominate.\n regressed: bootstrap.low < -tolerance || regression.promote,\n tolerance,\n n: paired.before.length,\n })\n }\n return out\n}\n","/**\n * Power preflight — \"can this budget detect the effect you are hunting?\"\n *\n * The failure it prevents (measured, twice): a live prompt-improvement campaign ran\n * 333 sandbox cells over 5.6 hours and produced a +0.08 holdout lift the ship gate\n * (paired bootstrap, CI.low > 0.05) could not distinguish from zero — because at\n * that holdout size and worker variance the MINIMUM DETECTABLE lift was larger than\n * any effect a prompt change plausibly produces. The budget was spent learning what\n * a 30-second calculation on the baseline cells already knew. No eval framework we\n * know of surfaces this; every underpowered improvement run everywhere ends in an\n * uninformative \"hold\".\n *\n * Model: the ship rule is `CI.low(paired Δ) > deltaThreshold`. Approximating the\n * bootstrap CI as normal, `CI.low ≈ effect − z·sd_Δ/√n`, so the smallest shippable\n * true effect is `MDE = deltaThreshold + z·sd_Δ/√n`. The paired-delta SD is unknown\n * before the candidate exists; we bound it by the zero-correlation case\n * `sd_Δ ≤ √2·sd_baseline` — a CONSERVATIVE (upper) MDE, which is the correct\n * direction for a warning. Pairing is per cell (`scenario:rep`), so reps multiply n.\n *\n * Standalone by design: feed it any baseline composites (a `gate:'none'` run, a\n * live-proof table) BEFORE budgeting the real search; `selfImprove` also attaches\n * it to every result and warns when the run was structurally unable to ship.\n */\n\nexport interface PowerPreflightOptions {\n /** Per-cell baseline composites on the HOLDOUT scenarios (one per scenario:rep cell). */\n baselineComposites: number[]\n /** Paired observations the budgeted comparison will produce\n * (holdout scenarios × reps). Defaults to `baselineComposites.length`. */\n pairedN?: number\n /** The ship gate's effect-size threshold. Default 0.05 (defaultProductionGate). */\n deltaThreshold?: number\n /** CI confidence the gate uses. Default 0.95. */\n confidence?: number\n /** True when the holdout is scored by the SAME judge/scorer family as the gate\n * (selfImprove's default composition — one judge scores everything). Under a\n * shared channel, raising paired n reduces only the IDIOSYNCRATIC noise share;\n * systematic judge bias is untouched, so the MDE here is a lower bound and the\n * only full debiaser is an independent second scoring channel\n * (recursive-self-improvement S1c, closed form in EXP-023 P0). Default false. */\n sharedScorerChannel?: boolean\n}\n\nexport interface PowerPreflight {\n /** Paired observations the comparison will have. */\n n: number\n /** Baseline per-cell composite standard deviation (the variance the effect must beat). */\n sd: number\n /** Minimum detectable lift: the smallest TRUE effect the gate could ship at this budget. */\n mde: number\n /** Baseline holdout composite mean. */\n baselineMean: number\n /** Headroom to a perfect 1.0 composite (the largest achievable lift on a [0,1] judge). */\n headroom: number\n /** True when even the largest achievable effect (headroom) is below the MDE —\n * the run is structurally unable to ship regardless of proposal quality.\n * Only asserted for [0,1]-scaled judges (see `scaleAssumed`). */\n underpowered: boolean\n /** True when composites look [0,1]-scaled; headroom/underpowered are only\n * meaningful under that convention (0-100 judges get mde/sd/n but no verdict). */\n scaleAssumed: boolean\n deltaThreshold: number\n confidence: number\n /** Set when the holdout shares the gate's scoring channel: more cells cannot\n * buy back systematic judge bias — treat the MDE as a lower bound. */\n sharedChannelCaveat?: string\n /** One actionable sentence for humans and logs. */\n recommendation: string\n}\n\n/** Two-sided z for the common confidence levels; interpolation is overkill here. */\nfunction zFor(confidence: number): number {\n if (confidence >= 0.99) return 2.576\n if (confidence >= 0.95) return 1.96\n if (confidence >= 0.9) return 1.645\n return 1.282\n}\n\n/** Estimate the minimum detectable lift a paired-holdout improvement run can\n * ship at a given budget, from the baseline holdout composites — call it BEFORE\n * spending a search to learn whether the effect you are hunting is even\n * observable at this holdout size and worker variance. */\nexport function powerPreflight(opts: PowerPreflightOptions): PowerPreflight {\n const composites = opts.baselineComposites.filter((v) => Number.isFinite(v))\n if (composites.length < 3) {\n throw new Error(\n `powerPreflight: need >= 3 finite baseline composites to estimate variance, got ${composites.length}`,\n )\n }\n const deltaThreshold = opts.deltaThreshold ?? 0.05\n const confidence = opts.confidence ?? 0.95\n const n = opts.pairedN ?? composites.length\n if (n < 2) throw new Error(`powerPreflight: pairedN must be >= 2, got ${n}`)\n\n const mean = composites.reduce((a, b) => a + b, 0) / composites.length\n const variance =\n composites.reduce((a, b) => a + (b - mean) * (b - mean), 0) / (composites.length - 1)\n const sd = Math.sqrt(variance)\n const z = zFor(confidence)\n const mde = deltaThreshold + (z * Math.SQRT2 * sd) / Math.sqrt(n)\n\n const scaleAssumed = composites.every((v) => v >= -0.001 && v <= 1.5)\n const headroom = Math.max(0, 1 - mean)\n const underpowered = scaleAssumed && mde > headroom\n\n const sharedChannelCaveat = opts.sharedScorerChannel\n ? 'Holdout and gate share one scoring channel: raising n/reps reduces only idiosyncratic noise — systematic judge bias remains and this MDE is a lower bound. Full debiasing needs an independent second scoring channel (different judge/benchmark family).'\n : undefined\n\n const recommendation = underpowered\n ? `UNDERPOWERED: minimum detectable lift ${mde.toFixed(3)} exceeds the ${headroom.toFixed(3)} headroom above the baseline (${mean.toFixed(3)}) — no achievable effect can ship at this budget. Raise paired n (scenarios x reps) to ~${Math.ceil(((z * Math.SQRT2 * sd) / Math.max(headroom - deltaThreshold, 0.01)) ** 2)} or reduce worker variance before searching.`\n : `Minimum detectable lift at n=${n}: ${mde.toFixed(3)} (baseline sd ${sd.toFixed(3)}). Effects smaller than this cannot clear the gate; budget the search for effects you believe exceed it.`\n\n return {\n n,\n sd,\n mde,\n baselineMean: mean,\n headroom,\n underpowered,\n scaleAssumed,\n deltaThreshold,\n confidence,\n ...(sharedChannelCaveat ? { sharedChannelCaveat } : {}),\n recommendation: sharedChannelCaveat\n ? `${recommendation} ${sharedChannelCaveat}`\n : recommendation,\n }\n}\n","/**\n * Truncation-tolerant JSON recovery — shared by every parser that reads JSON\n * out of a model response (reflective-mutation proposals, judge scores, the\n * completion-correctness checker).\n *\n * LLMs routinely hit a max_tokens cap mid-emission, leaving a JSON prefix\n * with an unclosed string / object / array and often a dangling key or\n * trailing comma. Throwing on that prefix — and letting the throw fold into\n * a fabricated zero score downstream — is the bug class this module exists\n * to prevent (see `JudgeParseError`'s contract: a synthetic zero is\n * indistinguishable from a real low score). Recovering the complete prefix\n * turns a would-be fabricated zero into a real measurement.\n */\n\n/**\n * Walk the input as JSON-aware (string vs not, escape-aware) and close\n * unclosed `{` / `[` in LIFO order at the tail. If the input was already\n * balanced returns it unchanged. If a string was open at end-of-input we\n * also close it with `\"` first, since a truncated string-mid-value is the\n * most common LLM cap-hit failure mode and JSON.parse cannot proceed\n * without one.\n *\n * Returns null when the structure is unrecoverable (e.g. depth would go\n * negative — that's an *over*-closed prefix, not a truncation).\n */\nexport function autoCloseTruncatedJson(raw: string): string | null {\n const stack: Array<'{' | '['> = []\n let inString = false\n let escaped = false\n for (const c of raw) {\n if (escaped) {\n escaped = false\n continue\n }\n if (inString) {\n if (c === '\\\\') {\n escaped = true\n continue\n }\n if (c === '\"') {\n inString = false\n continue\n }\n continue\n }\n if (c === '\"') {\n inString = true\n continue\n }\n if (c === '{' || c === '[') stack.push(c)\n else if (c === '}') {\n if (stack.pop() !== '{') return null\n } else if (c === ']') {\n if (stack.pop() !== '[') return null\n }\n }\n if (stack.length === 0 && !inString) return raw\n let suffix = ''\n // A truncation right after a backslash leaves an incomplete escape: the\n // closing `\"` we append would be consumed as the escape target and the\n // string would stay open. Complete the escape to a literal backslash first.\n if (escaped) suffix += '\\\\'\n if (inString) suffix += '\"'\n while (stack.length > 0) {\n const opener = stack.pop()!\n suffix += opener === '{' ? '}' : ']'\n }\n return raw + suffix\n}\n\nconst UNPARSEABLE = Symbol('unparseable')\n\nfunction tryParse(candidate: string): unknown {\n try {\n return JSON.parse(candidate)\n } catch {\n return UNPARSEABLE\n }\n}\n\n/** Index of the last `,` that sits outside any string literal, or -1. Cutting\n * there discards a dangling key / half-emitted value at the tail while\n * keeping every complete member before it. */\nfunction lastCommaOutsideString(s: string): number {\n let inString = false\n let escaped = false\n let last = -1\n for (let i = 0; i < s.length; i++) {\n const c = s[i]!\n if (escaped) {\n escaped = false\n continue\n }\n if (inString) {\n if (c === '\\\\') escaped = true\n else if (c === '\"') inString = false\n continue\n }\n if (c === '\"') inString = true\n else if (c === ',') last = i\n }\n return last\n}\n\n/**\n * Best-effort parse of a possibly-truncated JSON payload embedded in model\n * output (prose and markdown fences tolerated). Tries each opener position\n * (earliest `{`/`[` first, then the other when the first yields nothing —\n * prose like `[note] {\"score\":3}` must not poison the slice), and from each\n * start, in order:\n *\n * 1. plain `JSON.parse` of the opener → last-closer slice,\n * 2. auto-closing unclosed structures at the tail\n * (`autoCloseTruncatedJson`),\n * 3. trimming the tail back to the previous complete member boundary (the\n * last comma outside a string) and auto-closing again, repeatedly.\n *\n * Recovers e.g. `{\"correct\": false, \"` → `{ correct: false }` — the exact\n * cap-hit shape that has zeroed real eval rows. Returns the parsed value\n * (always an object or array, given the slice starts at an opener), or\n * `null` when nothing parseable can be recovered. Never throws.\n */\nexport function recoverTruncatedJson(text: string): unknown {\n const objStart = text.indexOf('{')\n const arrStart = text.indexOf('[')\n const starts = [objStart, arrStart].filter((i) => i >= 0).sort((a, b) => a - b)\n for (const start of starts) {\n const recovered = recoverFrom(text.slice(start))\n if (recovered !== UNPARSEABLE) return recovered\n }\n return null\n}\n\nfunction recoverFrom(slice: string): unknown {\n let candidate = slice\n\n const lastClose = Math.max(candidate.lastIndexOf('}'), candidate.lastIndexOf(']'))\n if (lastClose > 0) {\n const balanced = tryParse(candidate.slice(0, lastClose + 1))\n if (balanced !== UNPARSEABLE) return balanced\n }\n\n // Bounded: each iteration strictly shortens the candidate at a comma, so 64\n // covers any realistic member count without risking a pathological spin.\n for (let i = 0; i < 64; i++) {\n const closed = autoCloseTruncatedJson(candidate)\n if (closed !== null) {\n const parsed = tryParse(closed)\n if (parsed !== UNPARSEABLE) return parsed\n }\n const cut = lastCommaOutsideString(candidate)\n if (cut <= 0) return UNPARSEABLE\n candidate = candidate.slice(0, cut)\n }\n return UNPARSEABLE\n}\n","/**\n * Reflective mutation — primitives for trace-conditioned prompt rewriting.\n *\n * Used by `prompt-evolution.ts` (and any consumer running iterative\n * improvement). Given a parent prompt + concrete trace evidence (top trials,\n * bottom trials, missed expectations), produce an LLM-ready prompt that\n * proposes targeted mutations — not blind rephrasings.\n *\n * Why this lives outside `prompt-evolution.ts`: any consumer that wants to\n * run reflective rewriting WITHOUT the population/Pareto machinery can\n * import these primitives directly.\n *\n * Quality bar (vs. naive \"mutate this prompt\"):\n * - Show parent ↔ children diff, not just one variant\n * - Quote specific missed goldens with their match phrases\n * - Surface the model's actual emitted output side-by-side with what was expected\n * - Quote concrete mutation primitives so the model has a vocabulary\n */\n\nimport { autoCloseTruncatedJson } from './json-recovery'\n\n/** Bound on rendered/carried `emitted` evidence. ONE constant shared by the\n * producer (campaignBreakdown's per-scenario excerpt) and this renderer — if\n * the two drifted, the tighter side would silently re-clip carried evidence. */\nexport const EMITTED_EVIDENCE_MAX_CHARS = 2000\n\nexport interface TrialTrace {\n /** Stable id for the trial — surfaces in the prompt for grounding. */\n id: string\n /** Score the trial received on its primary metric. */\n score: number\n /** Candidate inputs the agent was given (e.g., the fixture or scenario). */\n inputName?: string\n /**\n * Goldens / expectations this trial was tested against, with whether each\n * was matched. The reflection prompt quotes the missed ones specifically.\n */\n expectations?: Array<{ id: string; phrase: string; matched: boolean }>\n /** Free-form text — what the agent actually emitted (e.g., findings, plan). */\n emitted?: string\n /** The judge's free-form note on WHY this trial scored low — the failure\n * evidence the reflection targets. Should be a generalizable pattern (which\n * checks/lines/dimensions failed, and how), never case-specific ground\n * truth (that would teach memorization, not capability). */\n failureNote?: string\n /** Optional structured metrics (recall, precision, cost, latency). */\n metrics?: Record<string, number>\n}\n\nexport interface ReflectionContext {\n /** What is being mutated — appears in the system prompt for orientation. */\n target: string\n /** Current variant's payload — JSON-serialised for the prompt. */\n parentPayload: unknown\n /** Best-performing trials this generation. */\n topTrials: TrialTrace[]\n /** Worst-performing trials this generation — the missed-golden source. */\n bottomTrials: TrialTrace[]\n /** How many children the mutator should propose. */\n childCount: number\n /** Optional: domain-specific mutation primitives the model can pick from. */\n mutationPrimitives?: string[]\n}\n\nexport const DEFAULT_MUTATION_PRIMITIVES: string[] = [\n 'Strengthen an imperative (\"should\" → \"must\")',\n 'Add a concrete example pulled from a missed-golden phrase',\n 'Remove a redundant rule that did not improve recall',\n 'Add a counterfactual (\"if X is missing, the score is capped at Y\")',\n 'Reorder sections so the highest-impact rule is first',\n 'Replace abstract language with a domain-specific noun the trial misses',\n]\n\n/**\n * Build the LLM-ready reflection prompt. Output is plain text — pass it as\n * the user message. The system message should be small and stable (e.g.\n * \"Output ONLY a JSON object matching the schema below.\").\n */\nexport function buildReflectionPrompt(ctx: ReflectionContext): string {\n const primitives = ctx.mutationPrimitives ?? DEFAULT_MUTATION_PRIMITIVES\n const sections: string[] = []\n\n sections.push(`# Mutation target: ${ctx.target}`)\n sections.push('')\n sections.push(\n `You are tuning the prompt component named \\`${ctx.target}\\`. The current variant is shown below; you have ${ctx.topTrials.length} top trials and ${ctx.bottomTrials.length} bottom trials as evidence. Propose ${ctx.childCount} mutation${ctx.childCount === 1 ? '' : 's'} that fix specific weaknesses visible in the bottom trials. Avoid blank rephrasings.`,\n )\n sections.push('')\n\n sections.push('## Current variant')\n sections.push('```json')\n sections.push(JSON.stringify(ctx.parentPayload, null, 2))\n sections.push('```')\n sections.push('')\n\n if (ctx.bottomTrials.length > 0) {\n sections.push('## Failures (bottom trials) — what went wrong')\n sections.push('')\n for (const trial of ctx.bottomTrials) {\n sections.push(\n `### Trial \\`${trial.id}\\` — score ${trial.score.toFixed(2)}${trial.inputName ? ` (${trial.inputName})` : ''}`,\n )\n if (trial.failureNote) {\n sections.push('')\n // 1500 chars fits a real traceback / failing-assertion note; clipping\n // mid-traceback would hide the executable-judge evidence the\n // reflection targets.\n sections.push(`**Why it scored low:** ${truncate(trial.failureNote, 1500)}`)\n }\n const missed = (trial.expectations ?? []).filter((e) => !e.matched)\n if (missed.length > 0) {\n sections.push('')\n sections.push('**Missed expectations:**')\n for (const m of missed) {\n sections.push(`- \\`${m.id}\\`: should match phrase \\`${quote(m.phrase)}\\``)\n }\n }\n if (trial.emitted) {\n sections.push('')\n sections.push('**What the agent emitted:**')\n sections.push('```')\n sections.push(truncate(trial.emitted, EMITTED_EVIDENCE_MAX_CHARS))\n sections.push('```')\n }\n sections.push('')\n }\n }\n\n if (ctx.topTrials.length > 0) {\n sections.push('## Successes (top trials) — what to preserve')\n sections.push('')\n for (const trial of ctx.topTrials) {\n sections.push(\n `- \\`${trial.id}\\`: score ${trial.score.toFixed(2)}${trial.inputName ? ` (${trial.inputName})` : ''}`,\n )\n }\n sections.push('')\n }\n\n sections.push('## Allowed mutation primitives')\n sections.push('')\n for (const p of primitives) sections.push(`- ${p}`)\n sections.push('')\n\n sections.push('## Output schema')\n sections.push('')\n sections.push('Respond with a JSON object — no prose, no markdown fences:')\n sections.push('```json')\n sections.push(\n JSON.stringify(\n {\n proposals: [\n {\n label: '<short label, ≤ 40 chars>',\n rationale: '<which failure this targets and which primitive you used>',\n payload: '<full payload of the new variant — same shape as the current variant>',\n },\n ],\n },\n null,\n 2,\n ),\n )\n sections.push('```')\n\n return sections.join('\\n')\n}\n\nfunction truncate(s: string, max: number): string {\n if (s.length <= max) return s\n return `${s.slice(0, max)}… [truncated]`\n}\n\nfunction quote(s: string): string {\n return s.replace(/`/g, '\\\\`')\n}\n\nexport interface ReflectionProposal {\n label: string\n rationale: string\n payload: unknown\n}\n\n/**\n * Parse the model's JSON response back into proposals. Tolerates markdown\n * fences and surrounding prose. Returns at most `maxProposals`.\n */\nexport function parseReflectionResponse(raw: string, maxProposals?: number): ReflectionProposal[] {\n let text = raw.trim()\n if (text.startsWith('```')) text = text.replace(/^```(?:json)?\\n?/, '').replace(/\\n?```$/, '')\n\n // Try to parse as either a JSON object `{proposals: [...]}` or a bare\n // array `[...]`. LLMs frequently emit one or the other depending on how\n // they read the schema example; accept both.\n let parsed: unknown = null\n const objectStart = text.indexOf('{')\n const objectEnd = text.lastIndexOf('}')\n const arrayStart = text.indexOf('[')\n const arrayEnd = text.lastIndexOf(']')\n // Prefer whichever delimiter comes first (the model committed to that shape).\n const tryObjectFirst = objectStart >= 0 && (arrayStart < 0 || objectStart < arrayStart)\n const candidates: string[] = []\n if (tryObjectFirst) {\n if (objectStart >= 0 && objectEnd > objectStart)\n candidates.push(text.slice(objectStart, objectEnd + 1))\n if (arrayStart >= 0 && arrayEnd > arrayStart)\n candidates.push(text.slice(arrayStart, arrayEnd + 1))\n } else {\n if (arrayStart >= 0 && arrayEnd > arrayStart)\n candidates.push(text.slice(arrayStart, arrayEnd + 1))\n if (objectStart >= 0 && objectEnd > objectStart)\n candidates.push(text.slice(objectStart, objectEnd + 1))\n }\n for (const slice of candidates) {\n try {\n parsed = JSON.parse(slice)\n break\n } catch {\n // try next\n }\n }\n\n // Truncation-tolerant fallback: LLMs frequently hit a max_tokens cap\n // mid-emission, leaving N unclosed `}` / `]` at the tail. Close them in\n // order from the deepest unclosed structure outward, by walking the\n // candidate slice and tracking depth, then retrying JSON.parse. This\n // recovers any complete proposals before the cutoff and drops the rest.\n if (parsed == null) {\n for (const slice of candidates) {\n const closed = autoCloseTruncatedJson(slice)\n if (closed != null && closed !== slice) {\n try {\n parsed = JSON.parse(closed)\n break\n } catch {\n // give up on this candidate\n }\n }\n }\n }\n\n if (parsed == null) return []\n\n // Normalize: accept `{proposals: [...]}` or a bare array.\n let proposalsRaw: unknown\n if (Array.isArray(parsed)) {\n proposalsRaw = parsed\n } else if (parsed && typeof parsed === 'object') {\n proposalsRaw = (parsed as { proposals?: unknown }).proposals\n }\n if (!Array.isArray(proposalsRaw)) return []\n\n const out: ReflectionProposal[] = []\n for (const p of proposalsRaw) {\n if (!p || typeof p !== 'object') continue\n const obj = p as { label?: unknown; rationale?: unknown; payload?: unknown }\n if (!('payload' in obj)) continue\n out.push({\n label: typeof obj.label === 'string' ? obj.label : 'mutation',\n rationale: typeof obj.rationale === 'string' ? obj.rationale : '',\n payload: obj.payload,\n })\n if (maxProposals !== undefined && out.length >= maxProposals) break\n }\n return out\n}\n","/**\n * Shared campaign-score reductions used by every optimizer preset\n * (`runOptimization`, external optimization methods, `compareOptimizationMethods`).\n * \"composite of a campaign\" and \"per-scenario / per-dimension breakdown\" so\n * the optimizers cannot drift on how a surface's score is computed.\n */\n\nimport { EMITTED_EVIDENCE_MAX_CHARS } from '../reflective-mutation'\nimport { projectCampaignCellQuality } from './run-record'\nimport type { CampaignResult, Scenario } from './types'\n\n/** Mean composite across cells with complete task-quality evidence.\n * Partial judge results remain on their cells but never enter this value.\n * A campaign with no complete score has no numeric mean and fails loudly. */\nexport function campaignMeanComposite<TArtifact, TScenario extends Scenario>(\n campaign: CampaignResult<TArtifact, TScenario>,\n): number {\n const mean = campaignMeanCompositeOrNull(campaign)\n if (mean === null) {\n throw new Error('campaignMeanComposite: campaign has no complete cell-quality scores')\n }\n return mean\n}\n\n/** Nullable campaign mean for wire and report fields that represent missing quality. */\nexport function campaignMeanCompositeOrNull<TArtifact, TScenario extends Scenario>(\n campaign: CampaignResult<TArtifact, TScenario>,\n): number | null {\n const scores = campaign.cells.flatMap((cell) => {\n const score = projectCampaignCellQuality(cell).score\n return score === undefined ? [] : [score]\n })\n return scores.length === 0 ? null : scores.reduce((sum, score) => sum + score, 0) / scores.length\n}\n\n/** Reject rank keys that cannot produce deterministic lexicographic ordering. */\nexport function assertFiniteRankKey(\n key: readonly number[],\n label: string,\n expectedLength?: number,\n): void {\n if (!Array.isArray(key) || key.length === 0) {\n throw new Error(`${label} must return a non-empty array`)\n }\n if (expectedLength !== undefined && key.length !== expectedLength) {\n throw new Error(`${label} returned ${key.length} elements; expected ${expectedLength}`)\n }\n for (let index = 0; index < key.length; index++) {\n if (!Number.isFinite(key[index])) {\n throw new Error(`${label}[${index}] must be finite`)\n }\n }\n}\n\n/** Compare fixed-length lexicographic rank keys where each element is higher-is-better.\n * Returns a positive number when `a` ranks above `b`, negative when below, and\n * zero when equal. */\nexport function compareRankKeys(a: readonly number[], b: readonly number[]): number {\n assertFiniteRankKey(a, 'rank key a')\n assertFiniteRankKey(b, 'rank key b', a.length)\n for (let i = 0; i < a.length; i++) {\n const av = a[i]!\n const bv = b[i]!\n if (av !== bv) return av - bv\n }\n return 0\n}\n\nexport interface CampaignBreakdown {\n /** Mean score per judge dimension across all cells. */\n dimensions: Record<string, number>\n /** Per-scenario composite (mean over reps + judges) + the judge's free-form\n * `notes` for that scenario (the \"why\" a reflective proposer grounds on) +\n * an optional `emitted` excerpt of the candidate's raw output (the \"what it\n * actually did\" a reflective proposer grounds on). */\n scenarios: Array<{ scenarioId: string; composite: number; notes?: string; emitted?: string }>\n}\n\n/** Per-candidate evidence a reflective/patch proposer grounds its next proposal\n * on: mean score per judge dimension + per-scenario composite. */\nexport function campaignBreakdown<TArtifact, TScenario extends Scenario>(\n campaign: CampaignResult<TArtifact, TScenario>,\n): CampaignBreakdown {\n const dimSums: Record<string, number> = {}\n const dimCounts: Record<string, number> = {}\n const byScenario = new Map<string, number[]>()\n const notesByScenario = new Map<string, Set<string>>()\n const emittedByScenario = new Map<string, { composite: number; text: string }>()\n for (const cell of campaign.cells) {\n const quality = projectCampaignCellQuality(cell)\n if (quality.score === undefined) continue\n const judgeScores = Object.values(quality.successfulJudgeScores)\n const cellComposite = quality.score\n const arr = byScenario.get(cell.scenarioId) ?? []\n arr.push(cellComposite)\n byScenario.set(cell.scenarioId, arr)\n // Carry the candidate's raw output as trajectory evidence when the artifact\n // is a string (the common prompt-tier shape). Across reps, keep the\n // LOWEST-composite cell's output — reflection grounds on the failure, and\n // the bottom-trial excerpt is the one buildReflectionPrompt renders.\n if (typeof cell.artifact === 'string' && cell.artifact.trim().length > 0) {\n const prev = emittedByScenario.get(cell.scenarioId)\n if (!prev || cellComposite < prev.composite) {\n emittedByScenario.set(cell.scenarioId, {\n composite: cellComposite,\n text: cell.artifact.slice(0, EMITTED_EVIDENCE_MAX_CHARS),\n })\n }\n }\n // Collect the judges' free-form notes per scenario (deduped) — the failure\n // evidence the reflective proposer grounds on. Generalizable by contract;\n // the judge must not put case-specific ground truth here.\n for (const s of judgeScores) {\n if (s.notes?.trim()) {\n const set = notesByScenario.get(cell.scenarioId) ?? new Set<string>()\n set.add(s.notes.trim())\n notesByScenario.set(cell.scenarioId, set)\n }\n }\n for (const score of judgeScores) {\n for (const [key, value] of Object.entries(score.dimensions)) {\n if (!Number.isFinite(value)) continue\n dimSums[key] = (dimSums[key] ?? 0) + value\n dimCounts[key] = (dimCounts[key] ?? 0) + 1\n }\n }\n }\n const dimensions: Record<string, number> = {}\n for (const key of Object.keys(dimSums)) {\n const count = dimCounts[key] ?? 0\n dimensions[key] = count > 0 ? (dimSums[key] ?? 0) / count : 0\n }\n const scenarios = [...byScenario.entries()].map(([scenarioId, comps]) => {\n const notesSet = notesByScenario.get(scenarioId)\n const notes = notesSet && notesSet.size > 0 ? [...notesSet].join(' | ') : undefined\n const emitted = emittedByScenario.get(scenarioId)?.text\n return {\n scenarioId,\n composite: comps.reduce((a, b) => a + b, 0) / comps.length,\n ...(notes ? { notes } : {}),\n ...(emitted ? { emitted } : {}),\n }\n })\n return { dimensions, scenarios }\n}\n","/**\n * Loop provenance — the durable, queryable record of WHAT a self-improvement\n * loop did and WHY, plus the OTel spans that let an OTLP collector pivot from\n * an eval-run to the underlying candidate→cell→gate→promote chain.\n *\n * Two artifacts, one source of truth:\n *\n * 1. `LoopProvenanceRecord` — a structured JSON record capturing every\n * candidate (surfaceHash + label + rationale + structured cause), its measured composite,\n * the gate decision + reasons + delta, the held-out lift, the explicit\n * baseline→candidate diff, and BACKEND PROVENANCE (the\n * `assertRealBackend` verdict + worker call count + model). This is the\n * ingestable audit artifact: the +lift recomputes from it, the \"because\n * Z\" rationale survives in it, and a stub backend is detectable from it.\n *\n * 2. `loopProvenanceSpans()` — the same chain emitted as OTLP-ingestable\n * `TraceSpanEvent`s, pivoted on the substrate's standard\n * `tangle.runId` / `tangle.scenarioId` / `tangle.cellId` /\n * `tangle.generation` attributes (the same pivots `/adapters/otel`\n * reads). The hosted `/v1/ingest/traces` endpoint receives the FULL loop,\n * not just the `cost.*` spans `runCampaign` already emits per cell.\n *\n * The record is built from the loop result and its settled cost receipts — no\n * second usage collector can contradict what the measured cells recorded.\n */\n\nimport { createHash } from 'node:crypto'\nimport { join } from 'node:path'\nimport type { CostReceipt } from '../cost-ledger'\nimport type { HostedClient } from '../hosted/client'\nimport type {\n EvalRunCellScore,\n EvalRunEvent,\n EvalRunGenerationSnapshot,\n TraceSpanEvent,\n} from '../hosted/types'\nimport { summarizeAgentReceiptIntegrity } from '../integrity/backend-integrity'\nimport { canonicalString, compareCodeUnits, hashCanonical } from '../ledger-core/canonical'\nimport { assertCampaignSplitIdentity } from './coverage'\nimport type {\n ComparisonCost,\n OptimizationMethodProvenance,\n} from './presets/compare-optimization-methods'\nimport type { RunImprovementLoopResult } from './presets/run-improvement-loop'\nimport { campaignCellExecutionEvidence, projectCampaignCellQuality } from './run-record'\nimport { campaignMeanComposite, campaignMeanCompositeOrNull } from './score-utils'\nimport type { CampaignStorage } from './storage'\nimport {\n renderSurfaceDiff,\n surfaceContentHash,\n surfaceHash,\n surfaceHashMatches,\n} from './surface-identity'\nimport type {\n CampaignResult,\n GateContribution,\n GateDecision,\n GateResult,\n GenerationCandidate,\n MutableSurface,\n Scenario,\n} from './types'\n\nexport interface LoopProvenanceCandidate {\n /** Generation index this candidate was proposed in. */\n generation: number\n /** 16-char loop-identity fingerprint (matches `GenerationCandidate.surfaceHash`). */\n surfaceHash: string\n /** Full sha256 content hash — byte-identical-verifiable. */\n contentHash: string\n /** Exact scored rows that produced this candidate's search result. */\n campaignDigest: `sha256:${string}`\n /** Proposer label, when the proposer returned a `ProposedCandidate`. */\n label?: string\n /** Proposer rationale — the \"because Z\". When the proposer returned a bare\n * surface (blind mutator) this is absent. */\n rationale?: string\n /** Proposer-supplied typed attribution, carried unchanged from\n * `GenerationCandidate.attribution`. Opaque here; the producer's schema tag\n * governs interpretation. */\n attribution?: Readonly<Record<string, unknown>>\n /** Exact complete incumbent this candidate mutated. */\n parentSurfaceHash: string\n /** Search-split composite of the exact parent. */\n parentComposite: number\n /** Search-split composite change relative to the exact parent. */\n observedDeltaFromParent?: number\n /** Whether the candidate completed every designed cell and could be selected. */\n eligibleForPromotion: boolean\n /** Designed-denominator receipt retained even for incomplete candidates. */\n coverage: NonNullable<GenerationCandidate['coverage']>\n /** Mean composite this candidate scored on the search split, or null when unscorable. */\n composite: number | null\n /** Whether this candidate was promoted out of its generation. */\n promoted: boolean\n}\n\nexport interface LoopProvenanceBackend {\n /** `assertRealBackend`-grade verdict over the worker call records. */\n verdict: 'real' | 'mixed' | 'stub'\n /** Number of worker LLM calls captured (the audit's \"worker call count\"). */\n workerCallCount: number\n /** Distinct model ids observed across worker calls. */\n models: string[]\n totalInputTokens: number\n totalOutputTokens: number\n totalCostUsd: number\n}\n\nexport interface LoopProvenanceEvidence {\n search: {\n splitDigest: `sha256:${string}`\n baselineCampaignDigest: `sha256:${string}`\n }\n holdout: {\n splitDigest: `sha256:${string}`\n baselineCampaignDigest: `sha256:${string}`\n winnerCampaignDigest: `sha256:${string}`\n neutralized?: {\n contentHash: `sha256:${string}`\n campaignDigest: `sha256:${string}`\n composite: number\n lift: number\n }\n }\n costReceiptsDigest: `sha256:${string}`\n}\n\nexport interface LoopProvenanceOptimizationMethod {\n name: string\n cost: ComparisonCost\n durationMs?: number\n provenance?: OptimizationMethodProvenance\n}\n\n/**\n * The durable provenance record. Aligns to the hosted `EvalRunEvent` path but\n * ADDS the rationale + the explicit baseline→candidate diff (both omitted from\n * the bare hosted event) + backend provenance.\n */\nexport interface LoopProvenanceRecord {\n schema: 'tangle.loop-provenance'\n /** SHA-256 over the canonical record with this field omitted. */\n recordDigest: `sha256:${string}`\n runId: string\n runDir: string\n timestamp: string\n /** Baseline + winner surface content hashes — distinguishable, byte-verifiable. */\n baselineContentHash: string\n winnerContentHash: string\n /** Proposer label/rationale for the promoted change. Absent ⇒ winner == baseline. */\n winnerLabel?: string\n winnerRationale?: string\n /** The explicit baseline→winner unified diff the gate decided on. */\n diff: string\n /** Every candidate across every generation, with its rationale and structured cause. */\n candidates: LoopProvenanceCandidate[]\n /** Complete external method identity and spend, when one authored the candidate. */\n optimizationMethod?: LoopProvenanceOptimizationMethod\n /** Exact campaign, split, surface, and receipt identities behind every summary. */\n evidence: LoopProvenanceEvidence\n /** Baseline composite on the search split that generated the candidates. */\n baselineSearchComposite: number\n /** The gate verdict — decision + reasons + contributing gates + delta. */\n gate: {\n decision: GateDecision\n reasons: string[]\n delta?: number\n contributingGates: GateContribution[]\n }\n /** Present iff the loop ran with `holdout: 'deferred'` — the held-out\n * comparison was intentionally not measured in this run, so the holdout\n * composites and `heldOutLift` are ABSENT rather than recorded as a\n * meaningless 0. */\n holdout?: 'deferred'\n /** baseline-on-holdout composite mean. Absent when `holdout === 'deferred'`. */\n baselineHoldoutComposite?: number\n /** winner-on-holdout composite mean. Absent when `holdout === 'deferred'`. */\n winnerHoldoutComposite?: number\n /** winnerHoldout - baselineHoldout — RECOMPUTABLE from this record. Absent\n * when `holdout === 'deferred'` (no held-out measurement ran). */\n heldOutLift?: number\n /** Backend provenance: stub-vs-real verdict + worker call count + models. */\n backend: LoopProvenanceBackend\n totalCostUsd: number\n totalDurationMs: number\n}\n\nexport interface BuildLoopProvenanceArgs<TArtifact, TScenario extends Scenario> {\n runId: string\n runDir: string\n timestamp: string\n baselineSurface: MutableSurface\n winnerSurface: MutableSurface\n winnerLabel?: string\n winnerRationale?: string\n /** Exact baseline campaign on the search split. */\n baselineSearchCampaign: CampaignResult<TArtifact, TScenario>\n /** Per-generation candidate records straight off the loop result. */\n generations: Array<{\n generationIndex: number\n candidates: GenerationCandidate[]\n promoted: string[]\n /** Surfaces measured this generation, keyed by surface hash so the content\n * hash can be computed and the loop identity rechecked from real bytes. */\n surfaces: Array<{\n surfaceHash: string\n surface: MutableSurface\n campaign: CampaignResult<TArtifact, TScenario>\n }>\n }>\n gate: GateResult\n /** Holdout policy the loop ran with. `'deferred'` ⇒ the holdout campaigns\n * below are the shared empty campaign and the record omits the holdout\n * composites + `heldOutLift`. Default `'measured'`. */\n holdout?: 'measured' | 'deferred'\n baselineOnHoldout: CampaignResult<TArtifact, TScenario>\n winnerOnHoldout: CampaignResult<TArtifact, TScenario>\n neutralizedSurface?: MutableSurface\n neutralizedOnHoldout?: CampaignResult<TArtifact, TScenario>\n /** Settled run-wide receipts — agent calls are the source for backend provenance. */\n costReceipts: ReadonlyArray<CostReceipt>\n totalCostUsd: number\n totalDurationMs: number\n optimizationMethod?: LoopProvenanceOptimizationMethod\n}\n\nexport interface LoopProvenanceArgsFromResult<TArtifact, TScenario extends Scenario> {\n runId: string\n runDir: string\n timestamp: string\n baselineSurface: MutableSurface\n result: RunImprovementLoopResult<TArtifact, TScenario>\n costReceipts: ReadonlyArray<CostReceipt>\n totalCostUsd: number\n totalDurationMs: number\n}\n\n/** One translation from a completed improvement loop into durable evidence. */\nexport function loopProvenanceArgsFromResult<TArtifact, TScenario extends Scenario>(\n input: LoopProvenanceArgsFromResult<TArtifact, TScenario>,\n): BuildLoopProvenanceArgs<TArtifact, TScenario> {\n const { result } = input\n return {\n runId: input.runId,\n runDir: input.runDir,\n timestamp: input.timestamp,\n baselineSurface: input.baselineSurface,\n winnerSurface: result.winnerSurface,\n ...(result.winnerLabel ? { winnerLabel: result.winnerLabel } : {}),\n ...(result.winnerRationale ? { winnerRationale: result.winnerRationale } : {}),\n baselineSearchCampaign: result.baselineCampaign,\n generations: result.generations.map(({ record, surfaces }) => ({\n generationIndex: record.generationIndex,\n candidates: record.candidates,\n promoted: record.promoted,\n surfaces: surfaces.map(({ surfaceHash, surface, campaign }) => ({\n surfaceHash,\n surface,\n campaign,\n })),\n })),\n gate: result.gateResult,\n ...(result.holdout === 'deferred' ? { holdout: 'deferred' as const } : {}),\n baselineOnHoldout: result.baselineOnHoldout,\n winnerOnHoldout: result.winnerOnHoldout,\n ...(result.neutralizedSurface && result.neutralizedOnHoldout\n ? {\n neutralizedSurface: result.neutralizedSurface,\n neutralizedOnHoldout: result.neutralizedOnHoldout,\n }\n : {}),\n costReceipts: input.costReceipts,\n totalCostUsd: input.totalCostUsd,\n totalDurationMs: input.totalDurationMs,\n }\n}\n\nfunction meanHoldoutComposite<TArtifact, TScenario extends Scenario>(\n campaign: CampaignResult<TArtifact, TScenario>,\n): number {\n return campaignMeanComposite(campaign)\n}\n\n/** Build the durable provenance record from a completed loop result. */\nexport function buildLoopProvenanceRecord<TArtifact, TScenario extends Scenario>(\n args: BuildLoopProvenanceArgs<TArtifact, TScenario>,\n): LoopProvenanceRecord {\n if (!args.runId.trim() || !args.runDir.trim()) {\n throw new Error('buildLoopProvenanceRecord: runId and runDir must be non-empty')\n }\n const timestampMs = Date.parse(args.timestamp)\n if (!Number.isFinite(timestampMs) || new Date(timestampMs).toISOString() !== args.timestamp) {\n throw new Error('buildLoopProvenanceRecord: timestamp must be a canonical ISO instant')\n }\n assertGateContributions(args.gate.contributingGates, 'buildLoopProvenanceRecord')\n const agentReceipts = args.costReceipts.filter((receipt) => receipt.channel === 'agent')\n const integrity = summarizeAgentReceiptIntegrity(agentReceipts)\n const models = [...new Set(agentReceipts.map((receipt) => receipt.model))].sort()\n const baselineSearchComposite = campaignMeanComposite(args.baselineSearchCampaign)\n if (!Number.isFinite(baselineSearchComposite)) {\n throw new Error('buildLoopProvenanceRecord: baselineSearchComposite must be finite')\n }\n\n const candidates: LoopProvenanceCandidate[] = []\n let incumbentSurfaceHash = surfaceHash(args.baselineSurface)\n let incumbentComposite = baselineSearchComposite\n let previousGeneration = -1\n for (const gen of args.generations) {\n if (\n !Number.isSafeInteger(gen.generationIndex) ||\n gen.generationIndex !== previousGeneration + 1\n ) {\n throw new Error(\n 'buildLoopProvenanceRecord: generation indices must be contiguous integers starting at zero',\n )\n }\n previousGeneration = gen.generationIndex\n if (gen.candidates.length === 0) {\n throw new Error('buildLoopProvenanceRecord: a recorded generation must contain a candidate')\n }\n if (new Set(gen.promoted).size !== gen.promoted.length || gen.promoted.length > 1) {\n throw new Error(\n 'buildLoopProvenanceRecord: each generation may promote at most one candidate',\n )\n }\n const promotedSet = new Set(gen.promoted)\n const surfaceByHash = new Map(gen.surfaces.map((measured) => [measured.surfaceHash, measured]))\n const candidateByHash = new Map(\n gen.candidates.map((candidate) => [candidate.surfaceHash, candidate]),\n )\n if (candidateByHash.size !== gen.candidates.length) {\n throw new Error('buildLoopProvenanceRecord: duplicate candidate surface hash')\n }\n if (surfaceByHash.size !== gen.surfaces.length) {\n throw new Error('buildLoopProvenanceRecord: duplicate candidate surface entry')\n }\n if (surfaceByHash.size !== candidateByHash.size) {\n throw new Error(\n 'buildLoopProvenanceRecord: every measured candidate requires exactly one surface',\n )\n }\n for (const promotedHash of promotedSet) {\n if (!candidateByHash.has(promotedHash)) {\n throw new Error('buildLoopProvenanceRecord: promoted hash has no measured candidate')\n }\n }\n for (const c of gen.candidates) {\n validateCandidateMeasurement(\n c,\n incumbentSurfaceHash,\n incumbentComposite,\n promotedSet.has(c.surfaceHash),\n )\n const measured = surfaceByHash.get(c.surfaceHash)\n if (measured === undefined) {\n throw new Error('buildLoopProvenanceRecord: measured candidate is missing its surface')\n }\n const { surface, campaign } = measured\n if (!surfaceHashMatches(surface, c.surfaceHash)) {\n throw new Error(\n 'buildLoopProvenanceRecord: candidate surface hash does not match its surface bytes',\n )\n }\n if (campaign.splitDigest !== args.baselineSearchCampaign.splitDigest) {\n throw new Error(\n 'buildLoopProvenanceRecord: candidate campaign does not match the search split',\n )\n }\n const entry: LoopProvenanceCandidate = {\n generation: gen.generationIndex,\n surfaceHash: c.surfaceHash,\n contentHash: surfaceContentHash(surface),\n campaignDigest: campaignMeasurementDigest(campaign),\n parentSurfaceHash: c.parentSurfaceHash!,\n parentComposite: c.parentComposite!,\n eligibleForPromotion: c.eligibleForPromotion,\n coverage: {\n expectedCells: c.coverage.expectedCells,\n scorableCells: c.coverage.scorableCells,\n unscorableCells: c.coverage.unscorableCells.map((cell) => ({ ...cell })),\n },\n composite: c.composite,\n promoted: promotedSet.has(c.surfaceHash),\n }\n if (c.label) entry.label = c.label\n if (c.rationale) entry.rationale = c.rationale\n if (c.attribution) entry.attribution = c.attribution\n if (c.observedDeltaFromParent !== undefined) {\n entry.observedDeltaFromParent = c.observedDeltaFromParent\n }\n candidates.push(entry)\n }\n const promotedHash = gen.promoted[0]\n if (promotedHash) {\n const promoted = candidateByHash.get(promotedHash)!\n incumbentSurfaceHash = promoted.surfaceHash\n if (promoted.composite === null) {\n throw new Error('buildLoopProvenanceRecord: promoted candidate is missing a composite')\n }\n incumbentComposite = promoted.composite\n }\n }\n if (surfaceHash(args.winnerSurface) !== incumbentSurfaceHash) {\n throw new Error(\n 'buildLoopProvenanceRecord: winner surface does not match the final promoted incumbent',\n )\n }\n\n const holdoutDeferred = args.holdout === 'deferred'\n if (args.baselineOnHoldout.splitDigest !== args.winnerOnHoldout.splitDigest) {\n throw new Error('buildLoopProvenanceRecord: baseline and winner use different holdout splits')\n }\n if ((args.neutralizedSurface === undefined) !== (args.neutralizedOnHoldout === undefined)) {\n throw new Error(\n 'buildLoopProvenanceRecord: neutralized surface and campaign must be supplied together',\n )\n }\n if (\n args.neutralizedOnHoldout &&\n args.neutralizedOnHoldout.splitDigest !== args.baselineOnHoldout.splitDigest\n ) {\n throw new Error(\n 'buildLoopProvenanceRecord: neutralized campaign uses a different holdout split',\n )\n }\n if (holdoutDeferred && args.neutralizedOnHoldout) {\n throw new Error(\n 'buildLoopProvenanceRecord: a deferred holdout cannot include a neutralized measurement',\n )\n }\n const holdoutMeasurement = holdoutDeferred\n ? { kind: 'deferred' as const }\n : {\n kind: 'measured' as const,\n baseline: meanHoldoutComposite(args.baselineOnHoldout),\n winner: meanHoldoutComposite(args.winnerOnHoldout),\n ...(args.neutralizedOnHoldout\n ? { neutralized: meanHoldoutComposite(args.neutralizedOnHoldout) }\n : {}),\n }\n\n const diff =\n surfaceContentHash(args.baselineSurface) === surfaceContentHash(args.winnerSurface)\n ? ''\n : renderSurfaceDiff(args.winnerSurface, args.baselineSurface)\n\n const recordWithoutDigest: Omit<LoopProvenanceRecord, 'recordDigest'> = {\n schema: 'tangle.loop-provenance',\n runId: args.runId,\n runDir: args.runDir,\n timestamp: args.timestamp,\n baselineContentHash: surfaceContentHash(args.baselineSurface),\n winnerContentHash: surfaceContentHash(args.winnerSurface),\n diff,\n candidates,\n evidence: {\n search: {\n splitDigest: args.baselineSearchCampaign.splitDigest,\n baselineCampaignDigest: campaignMeasurementDigest(args.baselineSearchCampaign),\n },\n holdout: {\n splitDigest: args.baselineOnHoldout.splitDigest,\n baselineCampaignDigest: campaignMeasurementDigest(args.baselineOnHoldout),\n winnerCampaignDigest: campaignMeasurementDigest(args.winnerOnHoldout),\n ...(args.neutralizedSurface &&\n args.neutralizedOnHoldout &&\n holdoutMeasurement.kind === 'measured' &&\n holdoutMeasurement.neutralized !== undefined\n ? {\n neutralized: {\n contentHash: surfaceContentHash(args.neutralizedSurface),\n campaignDigest: campaignMeasurementDigest(args.neutralizedOnHoldout),\n composite: holdoutMeasurement.neutralized,\n lift: holdoutMeasurement.neutralized - holdoutMeasurement.baseline,\n },\n }\n : {}),\n },\n costReceiptsDigest: canonicalDigest(\n [...args.costReceipts].sort((left, right) => compareCodeUnits(left.callId, right.callId)),\n ),\n },\n baselineSearchComposite,\n gate: {\n decision: args.gate.decision,\n reasons: args.gate.reasons,\n ...(args.gate.delta === undefined ? {} : { delta: args.gate.delta }),\n contributingGates: args.gate.contributingGates.map((g) => ({\n name: g.name,\n status: g.status,\n detail: durableGateDetail(g.detail),\n })),\n },\n // Deferred holdout records the MODE, never a fabricated 0-lift: the\n // held-out comparison intentionally did not run in this loop.\n ...(holdoutMeasurement.kind === 'deferred'\n ? { holdout: 'deferred' as const }\n : {\n baselineHoldoutComposite: holdoutMeasurement.baseline,\n winnerHoldoutComposite: holdoutMeasurement.winner,\n heldOutLift: holdoutMeasurement.winner - holdoutMeasurement.baseline,\n }),\n backend: {\n verdict: integrity.verdict,\n workerCallCount: integrity.totalRecords,\n models,\n totalInputTokens: integrity.totalInputTokens,\n totalOutputTokens: integrity.totalOutputTokens,\n totalCostUsd: integrity.totalCostUsd,\n },\n totalCostUsd: args.totalCostUsd,\n totalDurationMs: args.totalDurationMs,\n }\n if (args.optimizationMethod) {\n recordWithoutDigest.optimizationMethod = durableOptimizationMethod(args.optimizationMethod)\n }\n if (args.winnerLabel) recordWithoutDigest.winnerLabel = args.winnerLabel\n if (args.winnerRationale) recordWithoutDigest.winnerRationale = args.winnerRationale\n return {\n ...recordWithoutDigest,\n recordDigest: canonicalDigest(recordWithoutDigest),\n }\n}\n\nfunction durableOptimizationMethod(\n value: LoopProvenanceOptimizationMethod,\n): LoopProvenanceOptimizationMethod {\n if (\n !value ||\n typeof value !== 'object' ||\n typeof value.name !== 'string' ||\n !value.name.trim() ||\n value.name.trim() !== value.name\n ) {\n throw new Error('buildLoopProvenanceRecord: optimization method name is invalid')\n }\n if (\n !value.cost ||\n !Number.isFinite(value.cost.totalCostUsd) ||\n value.cost.totalCostUsd < 0 ||\n typeof value.cost.accountingComplete !== 'boolean' ||\n !Array.isArray(value.cost.incompleteReasons) ||\n value.cost.incompleteReasons.some((reason) => typeof reason !== 'string' || !reason.trim()) ||\n value.cost.accountingComplete !== (value.cost.incompleteReasons.length === 0)\n ) {\n throw new Error('buildLoopProvenanceRecord: optimization method cost is invalid')\n }\n if (\n value.durationMs !== undefined &&\n (!Number.isFinite(value.durationMs) || value.durationMs < 0)\n ) {\n throw new Error('buildLoopProvenanceRecord: optimization method duration is invalid')\n }\n try {\n return JSON.parse(canonicalString(value)) as LoopProvenanceOptimizationMethod\n } catch (cause) {\n throw new Error('buildLoopProvenanceRecord: optimization method data must be canonical JSON', {\n cause,\n })\n }\n}\n\n/** Digest the exact campaign fields that can affect a measured comparison. */\nexport function campaignMeasurementDigest<TArtifact, TScenario extends Scenario>(\n campaign: CampaignResult<TArtifact, TScenario>,\n): `sha256:${string}` {\n assertCampaignSplitIdentity(campaign.scenarios, campaign.reps, campaign.splitDigest)\n return canonicalDigest({\n schema: 'tangle.campaign-measurement',\n manifestHash: campaign.manifestHash,\n splitDigest: campaign.splitDigest,\n seed: campaign.seed,\n reps: campaign.reps,\n runDir: campaign.runDir,\n scenarios: campaign.scenarios,\n cells: [...campaign.cells]\n .sort((left, right) => compareCodeUnits(left.cellId, right.cellId))\n .map((cell) => ({\n manifestHash: cell.manifestHash ?? null,\n cellId: cell.cellId,\n scenarioId: cell.scenarioId,\n rep: cell.rep,\n generation: cell.generation ?? null,\n judgeScores: cell.judgeScores,\n costUsd: cell.costUsd,\n costProvenance: cell.costProvenance,\n costCallIds: [...(cell.costCallIds ?? [])].sort(),\n tokenUsage: cell.tokenUsage,\n resolvedModels: [...(cell.resolvedModels ?? [])].sort(),\n resolvedModel: cell.resolvedModel ?? null,\n durationMs: cell.durationMs,\n seed: cell.seed,\n cached: cell.cached,\n errorStage: cell.errorStage ?? null,\n errorJudge: cell.errorJudge ?? null,\n error: cell.error ?? null,\n })),\n })\n}\n\n/** Recompute and validate the self-addressed durable record. */\nexport function verifyLoopProvenanceRecord(record: LoopProvenanceRecord): LoopProvenanceRecord {\n if (record.schema !== 'tangle.loop-provenance') {\n throw new Error('loop provenance has an unsupported schema')\n }\n const { recordDigest, ...recordWithoutDigest } = record\n if (recordDigest !== canonicalDigest(recordWithoutDigest)) {\n throw new Error('loop provenance record digest does not match its contents')\n }\n assertGateContributions(record.gate?.contributingGates, 'loop provenance')\n return record\n}\n\n/** SHA-256 over the RFC 8785 canonical JSON of `value`. Throws\n * `LedgerCanonicalizationError` for a value with no canonical form. */\nexport function canonicalDigest(value: unknown): `sha256:${string}` {\n return hashCanonical(value)\n}\n\nfunction durableGateDetail(detail: unknown): unknown {\n if (detail === undefined) return null\n try {\n return JSON.parse(canonicalString(detail)) as unknown\n } catch (cause) {\n throw new Error('buildLoopProvenanceRecord: gate detail must be canonical JSON', {\n cause,\n })\n }\n}\n\nfunction assertGateContributions(\n value: unknown,\n source: string,\n): asserts value is GateContribution[] {\n if (!Array.isArray(value)) {\n throw new Error(`${source}: gate contributingGates must be an array`)\n }\n const statuses = new Set(['pass', 'fail', 'not_evaluated'])\n for (const [index, contribution] of value.entries()) {\n if (!contribution || typeof contribution !== 'object') {\n throw new Error(`${source}: gate contribution ${index} must be an object`)\n }\n const item = contribution as Record<string, unknown>\n if (typeof item.name !== 'string' || item.name.length === 0) {\n throw new Error(`${source}: gate contribution ${index} must have a non-empty name`)\n }\n if (!statuses.has(String(item.status))) {\n throw new Error(\n `${source}: gate contribution '${item.name}' must have status pass, fail, or not_evaluated`,\n )\n }\n if ('passed' in item) {\n throw new Error(\n `${source}: gate contribution '${item.name}' uses obsolete passed; use status instead`,\n )\n }\n }\n}\n\nfunction validateCandidateMeasurement(\n candidate: GenerationCandidate,\n expectedParentHash: string,\n expectedParentComposite: number,\n promoted: boolean,\n): void {\n if (!candidate.parentSurfaceHash || !/^[a-f0-9]{16}$/.test(candidate.parentSurfaceHash)) {\n throw new Error(\n 'buildLoopProvenanceRecord: parentSurfaceHash must be 16 lowercase hex characters',\n )\n }\n if (candidate.parentSurfaceHash !== expectedParentHash) {\n throw new Error('buildLoopProvenanceRecord: candidate parent does not match the incumbent')\n }\n if (\n candidate.parentComposite === undefined ||\n !Number.isFinite(candidate.parentComposite) ||\n Math.abs(candidate.parentComposite - expectedParentComposite) > 1e-12\n ) {\n throw new Error(\n 'buildLoopProvenanceRecord: candidate parentComposite does not match the incumbent',\n )\n }\n if (candidate.observedDeltaFromParent !== undefined) {\n if (!Number.isFinite(candidate.observedDeltaFromParent)) {\n throw new Error('buildLoopProvenanceRecord: observedDeltaFromParent must be finite')\n }\n if (candidate.eligibleForPromotion !== true) {\n throw new Error(\n 'buildLoopProvenanceRecord: observedDeltaFromParent requires a complete eligible candidate and parentSurfaceHash',\n )\n }\n }\n const coverage = candidate.coverage\n if (\n !Number.isSafeInteger(coverage.expectedCells) ||\n coverage.expectedCells <= 0 ||\n !Number.isSafeInteger(coverage.scorableCells) ||\n coverage.scorableCells < 0 ||\n coverage.scorableCells > coverage.expectedCells\n ) {\n throw new Error('buildLoopProvenanceRecord: invalid candidate coverage denominator')\n }\n const unscorableIds = new Set<string>()\n for (const failure of coverage.unscorableCells) {\n if (\n typeof failure.cellId !== 'string' ||\n failure.cellId.length === 0 ||\n typeof failure.reason !== 'string' ||\n failure.reason.length === 0 ||\n unscorableIds.has(failure.cellId)\n ) {\n throw new Error('buildLoopProvenanceRecord: invalid candidate coverage failures')\n }\n unscorableIds.add(failure.cellId)\n }\n if (coverage.expectedCells - coverage.scorableCells !== coverage.unscorableCells.length) {\n throw new Error(\n 'buildLoopProvenanceRecord: candidate coverage counts do not match its failures',\n )\n }\n const complete =\n coverage.scorableCells === coverage.expectedCells && coverage.unscorableCells.length === 0\n if (candidate.eligibleForPromotion !== complete) {\n throw new Error(\n 'buildLoopProvenanceRecord: candidate eligibility contradicts its coverage receipt',\n )\n }\n if (complete) {\n if (candidate.composite === null || !Number.isFinite(candidate.composite)) {\n throw new Error('buildLoopProvenanceRecord: complete candidate composite must be finite')\n }\n if (candidate.observedDeltaFromParent === undefined) {\n throw new Error(\n 'buildLoopProvenanceRecord: complete candidate is missing observedDeltaFromParent',\n )\n }\n const recomputed = candidate.composite - candidate.parentComposite\n if (Math.abs(candidate.observedDeltaFromParent - recomputed) > 1e-12) {\n throw new Error('buildLoopProvenanceRecord: observed delta does not match measured scores')\n }\n } else {\n if (candidate.composite !== null && !Number.isFinite(candidate.composite)) {\n throw new Error('buildLoopProvenanceRecord: candidate composite must be finite or null')\n }\n if (candidate.observedDeltaFromParent !== undefined) {\n throw new Error('buildLoopProvenanceRecord: incomplete candidate cannot carry observed delta')\n }\n }\n if (promoted && (!complete || (candidate.observedDeltaFromParent ?? 0) <= 0)) {\n throw new Error('buildLoopProvenanceRecord: promoted candidate must improve the incumbent')\n }\n}\n\n// ── OTel span emission ──────────────────────────────────────────────────\n\nfunction hashId(parts: string[]): string {\n return createHash('sha256').update(parts.join(':')).digest('hex')\n}\n\n/**\n * Build the loop's OTLP-ingestable spans from a provenance record. One root\n * span per loop (`tangle.runId`), one span per generation, one span per\n * candidate (carrying its surfaceHash + label), and one span for the gate\n * decision (carrying reasons + delta + lift). Candidate + gate spans pivot on\n * the same `tangle.runId` / `tangle.generation` attributes `/adapters/otel`\n * reads, so the hosted collector reconstructs the full tree.\n *\n * Times are synthesized monotonically off a single base so the span tree is\n * orderable; the substrate does not retain per-candidate wall-clock starts.\n */\nexport function loopProvenanceSpans(\n record: LoopProvenanceRecord,\n opts: { baseTimeMs?: number } = {},\n): TraceSpanEvent[] {\n const traceId = hashId(['trace', record.runId]).slice(0, 32)\n const baseTimeMs = opts.baseTimeMs ?? (Date.parse(record.timestamp) || Date.now())\n const durationMs = Math.max(1, record.totalDurationMs)\n if (!Number.isSafeInteger(baseTimeMs) || baseTimeMs < 0) {\n throw new RangeError('loop provenance baseTimeMs must be a non-negative safe integer')\n }\n if (!Number.isSafeInteger(durationMs)) {\n throw new RangeError('loop provenance duration must be a safe integer number of milliseconds')\n }\n const baseTime = BigInt(baseTimeMs)\n const baseNano = (baseTime * 1_000_000n).toString()\n const endNano = ((baseTime + BigInt(durationMs)) * 1_000_000n).toString()\n const spans: TraceSpanEvent[] = []\n\n const rootSpanId = hashId(['root', record.runId]).slice(0, 16)\n const rootAttributes: TraceSpanEvent['attributes'] = {\n 'tangle.runId': record.runId,\n 'tangle.runDir': record.runDir,\n 'tangle.baselineContentHash': record.baselineContentHash,\n 'tangle.winnerContentHash': record.winnerContentHash,\n 'tangle.baselineSearchComposite': record.baselineSearchComposite,\n 'tangle.gateDecision': record.gate.decision,\n 'tangle.backendVerdict': record.backend.verdict,\n 'tangle.workerCallCount': record.backend.workerCallCount,\n 'tangle.totalCostUsd': record.totalCostUsd,\n }\n if (record.heldOutLift !== undefined) rootAttributes['tangle.heldOutLift'] = record.heldOutLift\n if (record.holdout) rootAttributes['tangle.holdout'] = record.holdout\n spans.push({\n traceId,\n spanId: rootSpanId,\n name: 'improvement-loop',\n startTimeUnixNano: baseNano,\n endTimeUnixNano: endNano,\n attributes: rootAttributes,\n status: { code: 'OK' },\n 'tangle.runId': record.runId,\n })\n\n // Group candidates by generation for the per-generation parent span.\n const byGen = new Map<number, LoopProvenanceCandidate[]>()\n for (const c of record.candidates) {\n const arr = byGen.get(c.generation) ?? []\n arr.push(c)\n byGen.set(c.generation, arr)\n }\n for (const [generation, cands] of [...byGen.entries()].sort((a, b) => a[0] - b[0])) {\n const genSpanId = hashId(['gen', record.runId, String(generation)]).slice(0, 16)\n const measuredComposites = cands.flatMap((candidate) =>\n candidate.composite === null ? [] : [candidate.composite],\n )\n spans.push({\n traceId,\n spanId: genSpanId,\n parentSpanId: rootSpanId,\n name: `generation-${generation}`,\n startTimeUnixNano: baseNano,\n endTimeUnixNano: endNano,\n attributes: {\n 'tangle.runId': record.runId,\n 'tangle.generation': generation,\n 'tangle.populationSize': cands.length,\n ...(measuredComposites.length > 0\n ? { 'tangle.bestComposite': Math.max(...measuredComposites) }\n : {}),\n },\n 'tangle.runId': record.runId,\n 'tangle.generation': generation,\n })\n for (let i = 0; i < cands.length; i++) {\n const c = cands[i]!\n const candSpanId = hashId(['cand', record.runId, String(generation), c.surfaceHash]).slice(\n 0,\n 16,\n )\n const attributes: TraceSpanEvent['attributes'] = {\n 'tangle.runId': record.runId,\n 'tangle.generation': generation,\n 'tangle.surfaceHash': c.surfaceHash,\n 'tangle.contentHash': c.contentHash,\n 'tangle.parentSurfaceHash': c.parentSurfaceHash,\n 'tangle.parentComposite': c.parentComposite,\n 'tangle.eligibleForPromotion': c.eligibleForPromotion,\n 'tangle.expectedCells': c.coverage.expectedCells,\n 'tangle.scorableCells': c.coverage.scorableCells,\n 'tangle.unscorableCells': c.coverage.unscorableCells.length,\n 'tangle.promoted': c.promoted,\n }\n if (c.composite !== null) attributes['tangle.composite'] = c.composite\n if (c.observedDeltaFromParent !== undefined) {\n attributes['tangle.observedDeltaFromParent'] = c.observedDeltaFromParent\n }\n if (c.label) attributes['tangle.candidateLabel'] = c.label\n if (c.rationale) attributes['tangle.candidateRationale'] = c.rationale\n spans.push({\n traceId,\n spanId: candSpanId,\n parentSpanId: genSpanId,\n name: `candidate-${c.surfaceHash}`,\n startTimeUnixNano: baseNano,\n endTimeUnixNano: endNano,\n attributes,\n 'tangle.runId': record.runId,\n 'tangle.generation': generation,\n })\n }\n }\n\n // Gate span — child of root, carries the decision/reasons/delta the audit\n // needs and pivots back to the run.\n const gateSpanId = hashId(['gate', record.runId]).slice(0, 16)\n const gateAttributes: TraceSpanEvent['attributes'] = {\n 'tangle.runId': record.runId,\n 'tangle.gateDecision': record.gate.decision,\n 'tangle.gateReasons': JSON.stringify(record.gate.reasons),\n }\n const gateDelta = record.gate.delta ?? record.heldOutLift\n if (gateDelta !== undefined) gateAttributes['tangle.gateDelta'] = gateDelta\n if (record.heldOutLift !== undefined) gateAttributes['tangle.heldOutLift'] = record.heldOutLift\n if (record.baselineHoldoutComposite !== undefined) {\n gateAttributes['tangle.baselineHoldoutComposite'] = record.baselineHoldoutComposite\n }\n if (record.winnerHoldoutComposite !== undefined) {\n gateAttributes['tangle.winnerHoldoutComposite'] = record.winnerHoldoutComposite\n }\n if (record.holdout) gateAttributes['tangle.holdout'] = record.holdout\n spans.push({\n traceId,\n spanId: gateSpanId,\n parentSpanId: rootSpanId,\n name: 'gate-decision',\n startTimeUnixNano: endNano,\n endTimeUnixNano: endNano,\n attributes: gateAttributes,\n status: { code: 'OK' },\n 'tangle.runId': record.runId,\n })\n\n return spans\n}\n\n// ── Durable emission ─────────────────────────────────────────────────────\n\n/** Canonical durable paths under the run dir. */\nexport function provenanceRecordPath(runDir: string): string {\n return join(runDir, 'loop-provenance.json')\n}\n/**\n * Canonical path for the durable OTLP spans JSONL file under a loop run directory.\n */\nexport function provenanceSpansPath(runDir: string): string {\n return join(runDir, 'loop-provenance-spans.jsonl')\n}\n\nexport interface EmitLoopProvenanceResult {\n record: LoopProvenanceRecord\n spans: TraceSpanEvent[]\n /** Absolute paths the record + spans were written to, when storage persists. */\n recordPath: string\n spansPath: string\n}\n\nexport interface EmitLoopProvenanceArgs<TArtifact, TScenario extends Scenario>\n extends BuildLoopProvenanceArgs<TArtifact, TScenario> {\n /** Storage the record + spans are written through. */\n storage: CampaignStorage\n /** When set, the spans are also shipped to the hosted `/v1/ingest/traces`\n * endpoint so the collector receives the full loop, not just `cost.*`. */\n hostedClient?: HostedClient\n}\n\n/** Snapshot a held-out campaign into the hosted `EvalRunGenerationSnapshot`\n * shape — per-cell composite + per-judge dimensions, aggregate mean, cost,\n * duration. The dashboard renders these as the baseline → winner comparison. */\nfunction snapshotFromHoldout<TArtifact, TScenario extends Scenario>(\n index: number,\n surfaceHash: string,\n surface: MutableSurface,\n campaign: CampaignResult<TArtifact, TScenario>,\n): EvalRunGenerationSnapshot {\n const cells: EvalRunCellScore[] = campaign.cells.map((cell) => {\n const execution = campaignCellExecutionEvidence(cell)\n const quality = projectCampaignCellQuality(cell)\n const score: EvalRunCellScore = {\n scenarioId: cell.scenarioId,\n rep: cell.rep,\n compositeMean: quality.score ?? null,\n dimensions: quality.judgeScores?.perJudge ?? {},\n terminalOutcome: execution.terminalOutcome,\n executionErrorCount: execution.executionErrorCount ?? null,\n }\n if (cell.error) score.errorMessage = cell.error\n return score\n })\n return {\n index,\n surfaceHash,\n surface,\n cells,\n compositeMean: campaignMeanCompositeOrNull(campaign),\n costUsd: campaign.aggregates.cost.totalCostUsd,\n durationMs: campaign.durationMs,\n }\n}\n\n/** Build the hosted `EvalRunEvent` from the loop args + record — baseline +\n * winner snapshots, gate decision, held-out lift, cost, duration. Shipped to\n * `/v1/ingest/eval-runs` so the run appears in the dashboard's run list (the\n * trace spans, shipped separately, back the per-candidate drill-down). */\nfunction buildEvalRunEvent<TArtifact, TScenario extends Scenario>(\n args: EmitLoopProvenanceArgs<TArtifact, TScenario>,\n record: LoopProvenanceRecord,\n): EvalRunEvent {\n return {\n runId: args.runId,\n runDir: args.runDir,\n timestamp: args.timestamp,\n status: 'finished',\n labels: {},\n baseline: snapshotFromHoldout(\n 0,\n record.baselineContentHash,\n args.baselineSurface,\n args.baselineOnHoldout,\n ),\n generations: [\n snapshotFromHoldout(1, record.winnerContentHash, args.winnerSurface, args.winnerOnHoldout),\n ],\n gateDecision: args.gate.decision,\n // Deferred holdout ships NO lift — the wire field is optional and a 0\n // would read downstream as a measured no-improvement.\n ...(record.heldOutLift !== undefined ? { holdoutLift: record.heldOutLift } : {}),\n totalCostUsd: args.totalCostUsd,\n totalDurationMs: args.totalDurationMs,\n }\n}\n\n/**\n * Build the provenance record + OTel spans and persist them durably under the\n * run dir (and ship spans to a hosted collector when one is wired). Returns\n * both artifacts so the caller can assert on / re-derive from them.\n *\n * Fail-loud: the durable write throws on storage failure (a swallowed write is\n * exactly the \"emitted but lost\" failure this closes). The hosted span ship is\n * the one best-effort leg — its failure is logged, not thrown, so an offline\n * collector never fails the loop (the durable artifact is the source of truth).\n */\nexport async function emitLoopProvenance<TArtifact, TScenario extends Scenario>(\n args: EmitLoopProvenanceArgs<TArtifact, TScenario>,\n): Promise<EmitLoopProvenanceResult> {\n const record = buildLoopProvenanceRecord(args)\n const spans = loopProvenanceSpans(record)\n\n args.storage.ensureDir(args.runDir)\n const recordPath = provenanceRecordPath(args.runDir)\n const spansPath = provenanceSpansPath(args.runDir)\n args.storage.write(recordPath, JSON.stringify(record, null, 2))\n args.storage.write(spansPath, spans.map((s) => JSON.stringify(s)).join('\\n'))\n\n if (args.hostedClient) {\n // Ship BOTH streams so the run is fully visible in the dashboard: the\n // eval-run event (→ run list + baseline/winner/gate/lift) AND the trace\n // spans (→ per-candidate drill-down). Best-effort: an offline collector is\n // logged, never thrown — the durable artifact above is the source of truth.\n try {\n await args.hostedClient.ingestEvalRun(buildEvalRunEvent(args, record))\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n // eslint-disable-next-line no-console -- intentional: hosted ingest is best-effort\n console.warn(`[agent-eval] hosted eval-run ingest failed (continuing): ${msg}`)\n }\n try {\n await args.hostedClient.ingestTraces(spans)\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n // eslint-disable-next-line no-console -- intentional: hosted span ship is best-effort\n console.warn(`[agent-eval] provenance span ingest failed (continuing): ${msg}`)\n }\n }\n\n return { record, spans, recordPath, spansPath }\n}\n","/**\n * Reproducibility attestation for any serializable report object.\n *\n * `attest()` binds a report to its content address (sha-256 over canonical\n * JSON) AND binds that address to the provenance needed to reproduce it:\n * model versions, seeds, price-table hash, code SHA, inputs hash. The outer\n * `envelopeHash` prevents provenance from being rewritten while leaving the\n * report hash valid.\n *\n * Layering: content-addressing is the substrate's job; cryptographic SIGNING\n * (who vouches for the attestation, key management, transparency logs) is the\n * consumer's layer on top. An `AttestedReport` is a stable byte-identical\n * payload a consumer can sign — the substrate never holds keys.\n *\n * Generic by design: the report parameter is ANY value `canonicalJson`\n * accepts (campaign results, fuzz capsules, scorecards, cost ledgers). Do not\n * couple this module to a specific report schema.\n */\n\nimport { contentHash } from './verdict-cache'\n\n/** Hash scheme identifier carried by every attestation. A verifier rejects\n * unknown algorithms instead of guessing. */\nexport const ATTESTATION_ALGORITHM = 'sha256/canonical-json' as const\n\nexport interface AttestationProvenance {\n /** Every model involved in producing the report, name → version/id. */\n modelVersions: Record<string, string>\n /** RNG seeds the run was driven by, when seeded. */\n seeds?: number[]\n /** Content hash of the price table used for cost figures — cost numbers\n * are only reproducible against the same prices. */\n priceTableHash?: string\n /** Git SHA of the code that produced the report. */\n codeSha: string\n /** Content hash of the input set (scenarios, dataset manifest, ...). */\n inputsHash?: string\n /** ISO-8601 timestamp, caller-supplied — the substrate stays clock-free\n * so attestation is deterministic and testable. */\n createdAt: string\n}\n\nexport interface AttestedReport {\n /** Hex sha-256 over the canonical JSON of the report. */\n reportHash: string\n provenance: AttestationProvenance\n algorithm: typeof ATTESTATION_ALGORITHM\n /**\n * Hex sha-256 over `{ reportHash, provenance, algorithm }`. New attestations\n * always carry it. Optional only so persisted pre-envelope attestations can\n * still be read and explicitly recognized as legacy by callers.\n */\n envelopeHash?: string\n}\n\nexport interface AttestationVerification {\n valid: boolean\n /** Populated iff `valid` is false — names the exact mismatch. */\n reason?: string\n /** True only for a valid pre-envelope attestation whose provenance is not cryptographically bound. */\n legacyUnboundProvenance?: true\n}\n\nfunction envelopeMaterial(\n reportHash: string,\n provenance: AttestationProvenance,\n algorithm: typeof ATTESTATION_ALGORITHM,\n): object {\n return { reportHash, provenance, algorithm }\n}\n\n/**\n * Content-address a report and bind it to its provenance. Throws (via\n * `canonicalJson`) if the report or provenance contains undefined / function /\n * symbol / non-finite numbers — an attestation that cannot be unambiguously\n * serialized cannot be trusted.\n */\nexport function attest(report: unknown, provenance: AttestationProvenance): AttestedReport {\n const reportHash = contentHash(report)\n const algorithm = ATTESTATION_ALGORITHM\n return {\n reportHash,\n provenance,\n algorithm,\n envelopeHash: contentHash(envelopeMaterial(reportHash, provenance, algorithm)),\n }\n}\n\n/**\n * Verify a report against its attestation. Returns a typed outcome rather\n * than throwing: an unverifiable report (e.g. one that no longer\n * canonicalizes) is a verification failure with the cause in `reason`, not a\n * crash — verifiers run in pipelines that must record WHY, not die.\n *\n * Legacy attestations without `envelopeHash` remain readable, but verification\n * explicitly marks their provenance as unbound so a promotion path can refuse\n * them instead of accidentally treating old metadata as cryptographic proof.\n */\nexport function verifyAttestation(\n report: unknown,\n attested: AttestedReport,\n): AttestationVerification {\n if (attested.algorithm !== ATTESTATION_ALGORITHM) {\n return {\n valid: false,\n reason: `unknown algorithm '${attested.algorithm}' — this verifier only checks '${ATTESTATION_ALGORITHM}'`,\n }\n }\n let recomputed: string\n try {\n recomputed = contentHash(report)\n } catch (err) {\n return {\n valid: false,\n reason: `report is not canonicalizable: ${err instanceof Error ? err.message : String(err)}`,\n }\n }\n if (recomputed !== attested.reportHash) {\n return {\n valid: false,\n reason: `report hash mismatch: attested ${attested.reportHash}, recomputed ${recomputed}`,\n }\n }\n\n if (attested.envelopeHash === undefined) {\n return { valid: true, legacyUnboundProvenance: true }\n }\n\n let envelopeHash: string\n try {\n envelopeHash = contentHash(\n envelopeMaterial(attested.reportHash, attested.provenance, attested.algorithm),\n )\n } catch (err) {\n return {\n valid: false,\n reason: `attestation provenance is not canonicalizable: ${err instanceof Error ? err.message : String(err)}`,\n }\n }\n if (envelopeHash !== attested.envelopeHash) {\n return {\n valid: false,\n reason: `attestation envelope hash mismatch: attested ${attested.envelopeHash}, recomputed ${envelopeHash}`,\n }\n }\n\n return { valid: true }\n}\n","/**\n * Evidence receipts are the join between Runtime execution and Eval promotion.\n *\n * Runtime says what actually ran. Eval says what independently measured it.\n * This receipt binds those worlds without making either package import the other:\n * stable pursuit/run identity, exact candidate/evaluator/environment/input/output\n * content identities, and the authority class that produced the observation.\n *\n * The payload is attested with agent-eval's existing canonical report attestation.\n * Signing/key management deliberately remains outside this substrate; consumers may\n * sign the byte-stable receipt or anchor its attestation in a transparency log.\n */\n\nimport {\n type AttestationProvenance,\n type AttestedReport,\n attest,\n verifyAttestation,\n} from '../attestation'\n\nexport const EVIDENCE_RECEIPT_VERSION = '1.0.0' as const\n\n/** Closed promotion vocabulary. A typo or unknown future kind is never independent by default. */\nexport const EVIDENCE_AUTHORITY_KINDS = [\n 'candidate-self-report',\n 'independent-evaluator',\n 'independent-replication',\n 'human-review',\n 'production-canary',\n] as const\n\nexport type EvidenceAuthorityKind = (typeof EVIDENCE_AUTHORITY_KINDS)[number]\n\nexport const INDEPENDENT_EVIDENCE_AUTHORITY_KINDS = [\n 'independent-evaluator',\n 'independent-replication',\n 'human-review',\n 'production-canary',\n] as const satisfies readonly EvidenceAuthorityKind[]\n\nexport interface EvidenceAuthority {\n readonly kind: EvidenceAuthorityKind\n /** Stable authority/service/person identifier; never inferred from model prose. */\n readonly id: string\n}\n\nexport interface EvidenceBinding {\n readonly schemaVersion: typeof EVIDENCE_RECEIPT_VERSION\n /** Stable objective identity spanning retries, forks, resumes, and multiple runs. */\n readonly pursuitId: string\n /** Concrete execution/evaluation run this evidence was produced from. */\n readonly runId: string\n /** Exact candidate/program/profile bundle under evaluation. */\n readonly candidateDigest: string\n /** Exact evaluator/checker program or registered experiment definition. */\n readonly evaluatorDigest: string\n /** Exact sandbox/container/dependency/environment identity. */\n readonly environmentDigest: string\n /** Commitment to the input set. The hidden inputs themselves need not be exposed. */\n readonly inputSetCommitment: string\n /** Content identity of the raw evaluated output/artifact set. */\n readonly outputDigest: string\n /** Content identity of the evaluation result/report/verdict body. */\n readonly resultDigest: string\n readonly authority: EvidenceAuthority\n /** Optional experiment seal that governed the evaluation. */\n readonly experimentDigest?: string\n /** Optional observer-journal chain tip covering the execution being evaluated. */\n readonly observerDigest?: string\n}\n\nexport interface EvidenceReceipt {\n readonly binding: EvidenceBinding\n readonly attestation: AttestedReport\n}\n\nexport interface EvidenceReceiptVerification {\n readonly valid: boolean\n readonly reason?: string\n}\n\nexport interface CreateEvidenceReceiptInput extends Omit<EvidenceBinding, 'schemaVersion'> {}\n\n/**\n * Mint a content-attested evidence receipt. Required identity fields are deliberately\n * non-optional: unknown evidence stays unknown and cannot accidentally look certified.\n * The attestation's input provenance must equal the receipt commitment so two competing\n * descriptions of the evaluated population cannot coexist inside one valid receipt.\n */\nexport function createEvidenceReceipt(\n input: CreateEvidenceReceiptInput,\n provenance: AttestationProvenance,\n): EvidenceReceipt {\n const inputSetCommitment = requiredIdentity(input.inputSetCommitment, 'inputSetCommitment')\n assertInputCommitment(provenance, inputSetCommitment)\n const binding: EvidenceBinding = Object.freeze({\n schemaVersion: EVIDENCE_RECEIPT_VERSION,\n pursuitId: requiredIdentity(input.pursuitId, 'pursuitId'),\n runId: requiredIdentity(input.runId, 'runId'),\n candidateDigest: requiredIdentity(input.candidateDigest, 'candidateDigest'),\n evaluatorDigest: requiredIdentity(input.evaluatorDigest, 'evaluatorDigest'),\n environmentDigest: requiredIdentity(input.environmentDigest, 'environmentDigest'),\n inputSetCommitment,\n outputDigest: requiredIdentity(input.outputDigest, 'outputDigest'),\n resultDigest: requiredIdentity(input.resultDigest, 'resultDigest'),\n authority: requiredAuthority(input.authority),\n ...(input.experimentDigest === undefined\n ? {}\n : { experimentDigest: requiredIdentity(input.experimentDigest, 'experimentDigest') }),\n ...(input.observerDigest === undefined\n ? {}\n : { observerDigest: requiredIdentity(input.observerDigest, 'observerDigest') }),\n })\n return Object.freeze({ binding, attestation: attest(binding, provenance) })\n}\n\n/**\n * Verify promotion-grade evidence. Generic report attestation keeps a legacy read path,\n * but an EvidenceReceipt never accepts unbound provenance: changing the evaluator code,\n * model versions, input commitment provenance, or creation record must invalidate the\n * evidence rather than merely annotating it as legacy.\n */\nexport function verifyEvidenceReceipt(receipt: EvidenceReceipt): EvidenceReceiptVerification {\n if (receipt.binding.schemaVersion !== EVIDENCE_RECEIPT_VERSION) {\n return {\n valid: false,\n reason: `unsupported evidence receipt version '${receipt.binding.schemaVersion}'`,\n }\n }\n try {\n for (const [field, value] of Object.entries({\n pursuitId: receipt.binding.pursuitId,\n runId: receipt.binding.runId,\n candidateDigest: receipt.binding.candidateDigest,\n evaluatorDigest: receipt.binding.evaluatorDigest,\n environmentDigest: receipt.binding.environmentDigest,\n inputSetCommitment: receipt.binding.inputSetCommitment,\n outputDigest: receipt.binding.outputDigest,\n resultDigest: receipt.binding.resultDigest,\n })) {\n requiredIdentity(value, field)\n }\n requiredAuthority(receipt.binding.authority)\n assertInputCommitment(receipt.attestation.provenance, receipt.binding.inputSetCommitment)\n } catch (error) {\n return { valid: false, reason: error instanceof Error ? error.message : String(error) }\n }\n\n const verification = verifyAttestation(receipt.binding, receipt.attestation)\n if (!verification.valid) return verification\n if (\n verification.legacyUnboundProvenance === true ||\n receipt.attestation.envelopeHash === undefined\n ) {\n return {\n valid: false,\n reason: 'evidence receipt provenance is not bound by an attestation envelope',\n }\n }\n return { valid: true }\n}\n\n/**\n * Promotion may choose a stricter policy, but this primitive makes the basic separation\n * explicit: only a recognized independent authority is independent. Unknown/forged kinds\n * and candidate self-reports both return false.\n */\nexport function isIndependentEvidence(receipt: EvidenceReceipt): boolean {\n return (INDEPENDENT_EVIDENCE_AUTHORITY_KINDS as readonly string[]).includes(\n receipt.binding.authority?.kind,\n )\n}\n\nfunction requiredAuthority(value: unknown): EvidenceAuthority {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new TypeError('evidence receipt: authority must be an object')\n }\n const authority = value as { kind?: unknown; id?: unknown }\n if (\n typeof authority.kind !== 'string' ||\n !(EVIDENCE_AUTHORITY_KINDS as readonly string[]).includes(authority.kind)\n ) {\n throw new TypeError(`evidence receipt: unknown authority kind '${String(authority.kind)}'`)\n }\n if (typeof authority.id !== 'string') {\n throw new TypeError('evidence receipt: authority.id must be a string')\n }\n return Object.freeze({\n kind: authority.kind as EvidenceAuthorityKind,\n id: requiredIdentity(authority.id, 'authority.id'),\n })\n}\n\nfunction assertInputCommitment(\n provenance: AttestationProvenance,\n inputSetCommitment: string,\n): void {\n if (typeof provenance?.inputsHash !== 'string' || provenance.inputsHash.trim().length === 0) {\n throw new TypeError('evidence receipt: provenance.inputsHash is required')\n }\n if (provenance.inputsHash.trim() !== inputSetCommitment) {\n throw new TypeError(\n 'evidence receipt: provenance.inputsHash must equal binding.inputSetCommitment',\n )\n }\n}\n\nfunction requiredIdentity(value: string, field: string): string {\n const normalized = value.trim()\n if (normalized.length === 0) throw new TypeError(`evidence receipt: ${field} must be non-empty`)\n return normalized\n}\n","import type { AttestationProvenance } from '../attestation'\nimport { assertCampaignSplitIdentity, campaignCoverage } from '../campaign/coverage'\nimport { campaignMeasurementDigest } from '../campaign/provenance'\nimport { surfaceContentHash } from '../campaign/surface-identity'\nimport type { CampaignResult, MutableSurface, Scenario } from '../campaign/types'\nimport { hashCanonical } from '../ledger-core/canonical'\nimport { type CreateEvidenceReceiptInput, createEvidenceReceipt } from './evidence-receipt'\n\n/** Caller-owned execution context. Eval never infers evaluator authority or environment identity. */\nexport type CampaignEvidenceContext = Pick<\n CreateEvidenceReceiptInput,\n | 'pursuitId'\n | 'evaluatorDigest'\n | 'environmentDigest'\n | 'authority'\n | 'experimentDigest'\n | 'observerDigest'\n> & { provenance: Omit<AttestationProvenance, 'inputsHash'> }\n\n/** Bind a complete measured campaign to its executed surface and actual outputs. */\nexport function createCampaignEvidenceReceipt<S extends Scenario, A>(input: {\n campaign: CampaignResult<A, S>\n surface: MutableSurface\n context: CampaignEvidenceContext\n}) {\n const { campaign, surface, context } = input\n assertCampaignSplitIdentity(campaign.scenarios, campaign.reps, campaign.splitDigest)\n const coverage = campaignCoverage(campaign.cells, campaign.scenarios, campaign.reps, true)\n if (campaign.scenarios.length === 0 || !coverage.complete) {\n throw new Error('campaign evidence requires a complete, nonempty measurement')\n }\n const { provenance, ...binding } = context\n return createEvidenceReceipt(\n {\n ...binding,\n runId: campaign.runDir,\n candidateDigest: surfaceContentHash(surface),\n inputSetCommitment: campaign.splitDigest,\n outputDigest: hashCanonical(\n [...campaign.cells]\n .sort((a, b) => (a.cellId < b.cellId ? -1 : a.cellId > b.cellId ? 1 : 0))\n .map((cell) => ({ cellId: cell.cellId, artifact: cell.artifact })),\n ),\n resultDigest: campaignMeasurementDigest(campaign),\n },\n { ...provenance, inputsHash: campaign.splitDigest },\n )\n}\n"],"mappings":"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"}
|