@tangle-network/agent-eval 0.20.12 → 0.21.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.
Files changed (48) hide show
  1. package/CHANGELOG.md +76 -0
  2. package/README.md +39 -1
  3. package/dist/{chunk-75MCTH7P.js → chunk-3GN6U53I.js} +198 -3
  4. package/dist/chunk-3GN6U53I.js.map +1 -0
  5. package/dist/chunk-3IX6QTB7.js +1349 -0
  6. package/dist/chunk-3IX6QTB7.js.map +1 -0
  7. package/dist/{chunk-PKCVBYTQ.js → chunk-5IIQKMD5.js} +38 -2
  8. package/dist/chunk-5IIQKMD5.js.map +1 -0
  9. package/dist/{chunk-MCMV7DUL.js → chunk-ARZ6BEV6.js} +2 -2
  10. package/dist/{chunk-HKYRWNHV.js → chunk-HRZELXCR.js} +2 -2
  11. package/dist/{chunk-ODFINDLQ.js → chunk-KRR4VMH7.js} +11 -1
  12. package/dist/chunk-KRR4VMH7.js.map +1 -0
  13. package/dist/chunk-SNUHRBDL.js +154 -0
  14. package/dist/chunk-SNUHRBDL.js.map +1 -0
  15. package/dist/{chunk-KWUAAIHR.js → chunk-WOK2RTWG.js} +157 -1
  16. package/dist/chunk-WOK2RTWG.js.map +1 -0
  17. package/dist/{chunk-HNJLMAJ2.js → chunk-WOPGKVN4.js} +2 -2
  18. package/dist/cli.js +3 -2
  19. package/dist/cli.js.map +1 -1
  20. package/dist/{control-C8NKbF3w.d.ts → control-cxwMOAsy.d.ts} +3 -2
  21. package/dist/control.d.ts +4 -3
  22. package/dist/control.js +2 -2
  23. package/dist/emitter-B2XqDKFU.d.ts +121 -0
  24. package/dist/{feedback-trajectory-BGQ_ANCN.d.ts → feedback-trajectory-CB0A32o3.d.ts} +2 -1
  25. package/dist/index.d.ts +71 -83
  26. package/dist/index.js +48 -60
  27. package/dist/index.js.map +1 -1
  28. package/dist/openapi.json +1 -1
  29. package/dist/optimization.d.ts +3 -2
  30. package/dist/optimization.js +2 -2
  31. package/dist/reporting-Da2ihlcM.d.ts +672 -0
  32. package/dist/reporting.d.ts +5 -426
  33. package/dist/reporting.js +6 -2
  34. package/dist/{emitter-BYO2nSDA.d.ts → store-u47QaJ9G.d.ts} +1 -91
  35. package/dist/traces.d.ts +259 -3
  36. package/dist/traces.js +24 -4
  37. package/dist/wire/index.js +3 -2
  38. package/docs/research-report-methodology.md +155 -0
  39. package/package.json +10 -12
  40. package/dist/chunk-75MCTH7P.js.map +0 -1
  41. package/dist/chunk-IKFVX537.js +0 -717
  42. package/dist/chunk-IKFVX537.js.map +0 -1
  43. package/dist/chunk-KWUAAIHR.js.map +0 -1
  44. package/dist/chunk-ODFINDLQ.js.map +0 -1
  45. package/dist/chunk-PKCVBYTQ.js.map +0 -1
  46. /package/dist/{chunk-MCMV7DUL.js.map → chunk-ARZ6BEV6.js.map} +0 -0
  47. /package/dist/{chunk-HKYRWNHV.js.map → chunk-HRZELXCR.js.map} +0 -0
  48. /package/dist/{chunk-HNJLMAJ2.js.map → chunk-WOPGKVN4.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/release-confidence.ts","../src/pre-registration.ts","../src/summary-report.ts","../src/release-report.ts","../src/promotion-gate.ts"],"sourcesContent":["/**\n * Release confidence gate.\n *\n * This is the production-facing composition layer over the lower-level\n * primitives:\n * - Dataset manifests prove corpus/version coverage.\n * - RunRecord rows prove reproducible search/holdout outcomes.\n * - Multi-shot trace evidence carries turn counts and ASI diagnostics.\n * - HeldOutGate decisions remain the paired promotion authority.\n *\n * The gate is intentionally pure and conservative. Missing declared evidence\n * fails closed instead of being treated as a neutral zero.\n */\n\nimport type { DatasetManifest, DatasetScenario, DatasetSplit } from './dataset'\nimport type { GateDecision } from './held-out-gate'\nimport type { ActionableSideInfo, MultiShotTrialResult } from './multi-shot-optimization'\nimport type { RunRecord, RunSplitTag } from './run-record'\n\nexport type ReleaseConfidenceStatus = 'pass' | 'warn' | 'fail'\nexport type ReleaseConfidenceAxisName =\n | 'corpus'\n | 'quality'\n | 'generalization'\n | 'diagnostics'\n | 'efficiency'\n\nexport interface ReleaseTraceEvidence {\n scenarioId: string\n candidateId?: string\n split?: RunSplitTag\n score?: number\n ok?: boolean\n turnCount?: number\n costUsd?: number\n durationMs?: number\n failureMode?: string\n asi?: ActionableSideInfo[]\n metadata?: Record<string, unknown>\n}\n\nexport interface ReleaseConfidenceThresholds {\n /** Require a Dataset manifest or explicit scenarios. Default true. */\n requireCorpus?: boolean\n minScenarioCount?: number\n minSearchRuns?: number\n minHoldoutRuns?: number\n /** Require at least one holdout scenario/run. Default true. */\n requireHoldout?: boolean\n minPassRate?: number\n minMeanScore?: number\n /** Search mean may exceed holdout mean by at most this much. */\n maxOverfitGap?: number\n maxMeanCostUsd?: number\n maxP95WallMs?: number\n /** Low-score/failed rows must carry ASI. Default true. */\n requireAsiForFailures?: boolean\n /** Score below this is considered a failure for ASI coverage. Default 0.5. */\n failureScoreThreshold?: number\n}\n\nexport interface ReleaseConfidenceInput {\n target: string\n candidateId?: string\n baselineId?: string\n dataset?: DatasetManifest\n scenarios?: readonly DatasetScenario[]\n runs?: readonly RunRecord[]\n traces?: readonly ReleaseTraceEvidence[]\n gateDecision?: GateDecision | null\n thresholds?: ReleaseConfidenceThresholds\n}\n\nexport interface ReleaseConfidenceAxis {\n name: ReleaseConfidenceAxisName\n status: ReleaseConfidenceStatus\n score: number\n detail: string\n}\n\nexport interface ReleaseConfidenceIssue {\n axis: ReleaseConfidenceAxisName\n severity: 'critical' | 'warning'\n code: string\n detail: string\n}\n\nexport interface ReleaseConfidenceMetrics {\n scenarioCount: number\n searchRuns: number\n holdoutRuns: number\n passRate: number\n meanScore: number\n searchMeanScore: number\n holdoutMeanScore: number\n overfitGap: number\n meanCostUsd: number\n p95WallMs: number\n failedRows: number\n failuresWithAsi: number\n singleShotTraces: number\n multiShotTraces: number\n splitCounts: Record<DatasetSplit, number>\n domainCounts: Record<string, number>\n failureModeCounts: Record<string, number>\n responsibleSurfaceCounts: Record<string, number>\n}\n\nexport interface ReleaseConfidenceScorecard {\n target: string\n candidateId: string | null\n baselineId: string | null\n status: ReleaseConfidenceStatus\n promote: boolean\n axes: ReleaseConfidenceAxis[]\n issues: ReleaseConfidenceIssue[]\n metrics: ReleaseConfidenceMetrics\n dataset: DatasetManifest | null\n gateDecision: GateDecision | null\n summary: string\n}\n\nconst DEFAULT_THRESHOLDS: Required<ReleaseConfidenceThresholds> = {\n requireCorpus: true,\n minScenarioCount: 1,\n minSearchRuns: 1,\n minHoldoutRuns: 1,\n requireHoldout: true,\n minPassRate: 0.8,\n minMeanScore: 0.7,\n maxOverfitGap: 0.15,\n maxMeanCostUsd: Number.POSITIVE_INFINITY,\n maxP95WallMs: Number.POSITIVE_INFINITY,\n requireAsiForFailures: true,\n failureScoreThreshold: 0.5,\n}\n\nexport function releaseTraceEvidenceFromMultiShotTrials(\n trials: readonly MultiShotTrialResult[],\n): ReleaseTraceEvidence[] {\n return trials.map((trial) => ({\n scenarioId: trial.scenarioId,\n candidateId: trial.variantId,\n split: trial.split === 'holdout' ? 'holdout' : trial.split === 'dev' ? 'dev' : 'search',\n score: trial.score,\n ok: trial.ok,\n turnCount: Array.isArray(trial.trace?.turns) ? trial.trace.turns.length : undefined,\n costUsd: trial.cost,\n durationMs: trial.durationMs,\n failureMode: trial.error ? 'runtime_error' : undefined,\n asi: trial.asi,\n metadata: trial.metadata,\n }))\n}\n\nexport function evaluateReleaseConfidence(input: ReleaseConfidenceInput): ReleaseConfidenceScorecard {\n const thresholds = { ...DEFAULT_THRESHOLDS, ...input.thresholds }\n const candidateId = input.candidateId ?? null\n const runs = filterCandidate(input.runs ?? [], candidateId, input.baselineId)\n const traces = filterTraceCandidate(input.traces ?? [], candidateId, input.baselineId)\n const scenarios = input.scenarios ?? []\n const scenarioCount = input.dataset?.scenarioCount ?? scenarios.length\n const splitCounts = input.dataset?.splitCounts ?? countScenarioSplits(scenarios)\n const searchScores = scoresFor(runs, 'search')\n const holdoutScores = scoresFor(runs, 'holdout')\n const allScores = [...searchScores, ...holdoutScores]\n const traceScores = traces.map((t) => t.score).filter(isFiniteNumber)\n const scoreUniverse = allScores.length > 0 ? allScores : traceScores\n const searchRuns = runs.filter((r) => r.splitTag === 'search').length\n const holdoutRuns = runs.filter((r) => r.splitTag === 'holdout').length\n const searchMeanScore = mean(searchScores)\n const holdoutMeanScore = mean(holdoutScores)\n const metrics: ReleaseConfidenceMetrics = {\n scenarioCount,\n searchRuns,\n holdoutRuns,\n passRate: passRate(runs, traces, thresholds.failureScoreThreshold),\n meanScore: mean(scoreUniverse),\n searchMeanScore,\n holdoutMeanScore,\n overfitGap: safeDiff(searchMeanScore, holdoutMeanScore),\n meanCostUsd: mean([...runs.map((r) => r.costUsd), ...traces.map((t) => t.costUsd).filter(isFiniteNumber)]),\n p95WallMs: percentile([...runs.map((r) => r.wallMs), ...traces.map((t) => t.durationMs).filter(isFiniteNumber)], 0.95),\n failedRows: failedRows(runs, traces, thresholds.failureScoreThreshold).length,\n failuresWithAsi: failedRows(runs, traces, thresholds.failureScoreThreshold).filter((row) => row.hasAsi).length,\n singleShotTraces: traces.filter((t) => t.turnCount === 1).length,\n multiShotTraces: traces.filter((t) => (t.turnCount ?? 0) > 1).length,\n splitCounts,\n domainCounts: countDomains(scenarios),\n failureModeCounts: countFailureModes(runs, traces, thresholds.failureScoreThreshold),\n responsibleSurfaceCounts: countResponsibleSurfaces(traces),\n }\n\n const issues: ReleaseConfidenceIssue[] = []\n checkCorpus(input, thresholds, metrics, issues)\n checkQuality(thresholds, metrics, issues)\n checkGeneralization(input.gateDecision ?? null, thresholds, metrics, issues)\n checkDiagnostics(thresholds, metrics, issues)\n checkEfficiency(thresholds, metrics, issues)\n\n const axes = buildAxes(metrics, thresholds, input.gateDecision ?? null, issues)\n const status = issues.some((i) => i.severity === 'critical') ? 'fail'\n : issues.length > 0 ? 'warn'\n : 'pass'\n\n return {\n target: input.target,\n candidateId,\n baselineId: input.baselineId ?? null,\n status,\n promote: status === 'pass' && (input.gateDecision ? input.gateDecision.promote : true),\n axes,\n issues,\n metrics,\n dataset: input.dataset ?? null,\n gateDecision: input.gateDecision ?? null,\n summary: renderSummary(input.target, status, metrics, issues),\n }\n}\n\nexport function assertReleaseConfidence(input: ReleaseConfidenceInput): ReleaseConfidenceScorecard {\n const scorecard = evaluateReleaseConfidence(input)\n if (scorecard.status === 'fail') {\n throw new Error(scorecard.summary)\n }\n return scorecard\n}\n\nfunction filterCandidate(\n runs: readonly RunRecord[],\n candidateId: string | null,\n baselineId?: string,\n): RunRecord[] {\n if (candidateId) return runs.filter((r) => r.candidateId === candidateId)\n if (baselineId) return runs.filter((r) => r.candidateId !== baselineId)\n return [...runs]\n}\n\nfunction filterTraceCandidate(\n traces: readonly ReleaseTraceEvidence[],\n candidateId: string | null,\n baselineId?: string,\n): ReleaseTraceEvidence[] {\n if (candidateId) return traces.filter((t) => t.candidateId === undefined || t.candidateId === candidateId)\n if (baselineId) return traces.filter((t) => t.candidateId === undefined || t.candidateId !== baselineId)\n return [...traces]\n}\n\nfunction checkCorpus(\n input: ReleaseConfidenceInput,\n thresholds: Required<ReleaseConfidenceThresholds>,\n metrics: ReleaseConfidenceMetrics,\n issues: ReleaseConfidenceIssue[],\n): void {\n if (thresholds.requireCorpus && !input.dataset && (input.scenarios?.length ?? 0) === 0) {\n issues.push({ axis: 'corpus', severity: 'critical', code: 'missing_corpus', detail: 'No Dataset manifest or scenarios supplied.' })\n }\n if (metrics.scenarioCount < thresholds.minScenarioCount) {\n issues.push({ axis: 'corpus', severity: 'critical', code: 'few_scenarios', detail: `${metrics.scenarioCount} scenario(s) < min ${thresholds.minScenarioCount}.` })\n }\n if (thresholds.requireHoldout && metrics.splitCounts.holdout === 0) {\n issues.push({ axis: 'corpus', severity: 'critical', code: 'missing_holdout_split', detail: 'Corpus has no holdout scenarios.' })\n }\n}\n\nfunction checkQuality(\n thresholds: Required<ReleaseConfidenceThresholds>,\n metrics: ReleaseConfidenceMetrics,\n issues: ReleaseConfidenceIssue[],\n): void {\n if (metrics.searchRuns < thresholds.minSearchRuns) {\n issues.push({ axis: 'quality', severity: 'critical', code: 'few_search_runs', detail: `${metrics.searchRuns} search run(s) < min ${thresholds.minSearchRuns}.` })\n }\n if (metrics.passRate < thresholds.minPassRate) {\n issues.push({ axis: 'quality', severity: 'critical', code: 'low_pass_rate', detail: `passRate ${fmt(metrics.passRate)} < ${fmt(thresholds.minPassRate)}.` })\n }\n if (metrics.meanScore < thresholds.minMeanScore) {\n issues.push({ axis: 'quality', severity: 'critical', code: 'low_mean_score', detail: `meanScore ${fmt(metrics.meanScore)} < ${fmt(thresholds.minMeanScore)}.` })\n }\n}\n\nfunction checkGeneralization(\n gateDecision: GateDecision | null,\n thresholds: Required<ReleaseConfidenceThresholds>,\n metrics: ReleaseConfidenceMetrics,\n issues: ReleaseConfidenceIssue[],\n): void {\n if (thresholds.requireHoldout && metrics.holdoutRuns < thresholds.minHoldoutRuns) {\n issues.push({ axis: 'generalization', severity: 'critical', code: 'few_holdout_runs', detail: `${metrics.holdoutRuns} holdout run(s) < min ${thresholds.minHoldoutRuns}.` })\n }\n if (Number.isFinite(metrics.overfitGap) && metrics.overfitGap > thresholds.maxOverfitGap) {\n issues.push({ axis: 'generalization', severity: 'critical', code: 'overfit_gap', detail: `search-holdout gap ${fmt(metrics.overfitGap)} > ${fmt(thresholds.maxOverfitGap)}.` })\n }\n if (gateDecision && !gateDecision.promote) {\n issues.push({ axis: 'generalization', severity: 'critical', code: `gate_${gateDecision.rejectionCode ?? 'reject'}`, detail: gateDecision.reason })\n }\n}\n\nfunction checkDiagnostics(\n thresholds: Required<ReleaseConfidenceThresholds>,\n metrics: ReleaseConfidenceMetrics,\n issues: ReleaseConfidenceIssue[],\n): void {\n if (!thresholds.requireAsiForFailures) return\n if (metrics.failedRows > metrics.failuresWithAsi) {\n issues.push({\n axis: 'diagnostics',\n severity: 'critical',\n code: 'missing_failure_asi',\n detail: `${metrics.failedRows - metrics.failuresWithAsi} failed row(s) have no actionable side information.`,\n })\n }\n}\n\nfunction checkEfficiency(\n thresholds: Required<ReleaseConfidenceThresholds>,\n metrics: ReleaseConfidenceMetrics,\n issues: ReleaseConfidenceIssue[],\n): void {\n if (metrics.meanCostUsd > thresholds.maxMeanCostUsd) {\n issues.push({ axis: 'efficiency', severity: 'critical', code: 'cost_budget', detail: `meanCostUsd ${fmt(metrics.meanCostUsd)} > ${fmt(thresholds.maxMeanCostUsd)}.` })\n }\n if (metrics.p95WallMs > thresholds.maxP95WallMs) {\n issues.push({ axis: 'efficiency', severity: 'critical', code: 'latency_budget', detail: `p95WallMs ${fmt(metrics.p95WallMs)} > ${fmt(thresholds.maxP95WallMs)}.` })\n }\n}\n\nfunction buildAxes(\n metrics: ReleaseConfidenceMetrics,\n thresholds: Required<ReleaseConfidenceThresholds>,\n gateDecision: GateDecision | null,\n issues: ReleaseConfidenceIssue[],\n): ReleaseConfidenceAxis[] {\n return [\n axis('corpus', issues, bounded(metrics.scenarioCount / Math.max(1, thresholds.minScenarioCount)), `${metrics.scenarioCount} scenarios; holdout=${metrics.splitCounts.holdout}`),\n axis('quality', issues, Math.min(metrics.passRate, metrics.meanScore), `passRate=${fmt(metrics.passRate)} meanScore=${fmt(metrics.meanScore)}`),\n axis('generalization', issues, gateDecision && !gateDecision.promote ? 0 : gapScore(metrics.overfitGap, thresholds.maxOverfitGap), `holdoutRuns=${metrics.holdoutRuns} overfitGap=${fmt(metrics.overfitGap)}`),\n axis('diagnostics', issues, metrics.failedRows === 0 ? 1 : metrics.failuresWithAsi / metrics.failedRows, `failuresWithAsi=${metrics.failuresWithAsi}/${metrics.failedRows}`),\n axis('efficiency', issues, efficiencyScore(metrics, thresholds), `meanCostUsd=${fmt(metrics.meanCostUsd)} p95WallMs=${fmt(metrics.p95WallMs)}`),\n ]\n}\n\nfunction axis(\n name: ReleaseConfidenceAxisName,\n issues: ReleaseConfidenceIssue[],\n score: number,\n detail: string,\n): ReleaseConfidenceAxis {\n const own = issues.filter((i) => i.axis === name)\n const status = own.some((i) => i.severity === 'critical') ? 'fail'\n : own.length > 0 ? 'warn'\n : 'pass'\n return { name, status, score: bounded(score), detail }\n}\n\nfunction countScenarioSplits(scenarios: readonly DatasetScenario[]): Record<DatasetSplit, number> {\n const counts: Record<DatasetSplit, number> = { train: 0, dev: 0, test: 0, holdout: 0 }\n for (const scenario of scenarios) counts[scenario.split ?? 'train']++\n return counts\n}\n\nfunction countDomains(scenarios: readonly DatasetScenario[]): Record<string, number> {\n const out: Record<string, number> = {}\n for (const scenario of scenarios) {\n const domain = scenario.tags?.domain ?? scenario.tags?.category ?? 'uncategorized'\n out[domain] = (out[domain] ?? 0) + 1\n }\n return out\n}\n\nfunction countFailureModes(\n runs: readonly RunRecord[],\n traces: readonly ReleaseTraceEvidence[],\n threshold: number,\n): Record<string, number> {\n const out: Record<string, number> = {}\n for (const run of runs) {\n const score = run.outcome.holdoutScore ?? run.outcome.searchScore\n if (run.failureMode || (score !== undefined && score < threshold)) {\n const mode = run.failureMode ?? 'low_score'\n out[mode] = (out[mode] ?? 0) + 1\n }\n }\n for (const trace of traces) {\n if (trace.failureMode || trace.ok === false || (trace.score !== undefined && trace.score < threshold)) {\n const mode = trace.failureMode ?? (trace.ok === false ? 'not_ok' : 'low_score')\n out[mode] = (out[mode] ?? 0) + 1\n }\n }\n return out\n}\n\nfunction countResponsibleSurfaces(traces: readonly ReleaseTraceEvidence[]): Record<string, number> {\n const out: Record<string, number> = {}\n for (const trace of traces) {\n for (const asi of trace.asi ?? []) {\n const surface = asi.responsibleSurface ?? 'unknown'\n out[surface] = (out[surface] ?? 0) + 1\n }\n }\n return out\n}\n\nfunction failedRows(\n runs: readonly RunRecord[],\n traces: readonly ReleaseTraceEvidence[],\n threshold: number,\n): Array<{ hasAsi: boolean }> {\n const out: Array<{ hasAsi: boolean }> = []\n for (const run of runs) {\n const score = run.outcome.holdoutScore ?? run.outcome.searchScore\n if (run.failureMode || (score !== undefined && score < threshold)) {\n const asiMetric = run.outcome.raw.asi\n out.push({ hasAsi: typeof asiMetric === 'number' && asiMetric > 0 })\n }\n }\n for (const trace of traces) {\n if (trace.failureMode || trace.ok === false || (trace.score !== undefined && trace.score < threshold)) {\n out.push({ hasAsi: (trace.asi?.length ?? 0) > 0 })\n }\n }\n return out\n}\n\nfunction passRate(\n runs: readonly RunRecord[],\n traces: readonly ReleaseTraceEvidence[],\n threshold: number,\n): number {\n const outcomes = [\n ...runs.map((run) => {\n const score = run.outcome.holdoutScore ?? run.outcome.searchScore\n return !run.failureMode && score !== undefined && score >= threshold\n }),\n ...traces.map((trace) => trace.ok !== false && (trace.score === undefined || trace.score >= threshold)),\n ]\n if (outcomes.length === 0) return 0\n return outcomes.filter(Boolean).length / outcomes.length\n}\n\nfunction scoresFor(runs: readonly RunRecord[], split: RunSplitTag): number[] {\n return runs\n .filter((run) => run.splitTag === split)\n .map((run) => split === 'holdout' ? run.outcome.holdoutScore : run.outcome.searchScore)\n .filter(isFiniteNumber)\n}\n\nfunction mean(xs: readonly number[]): number {\n if (xs.length === 0) return Number.NaN\n return xs.reduce((sum, x) => sum + x, 0) / xs.length\n}\n\nfunction percentile(xs: readonly number[], p: number): number {\n if (xs.length === 0) return Number.NaN\n const sorted = [...xs].sort((a, b) => a - b)\n return sorted[Math.min(sorted.length - 1, Math.max(0, Math.ceil(p * sorted.length) - 1))]!\n}\n\nfunction isFiniteNumber(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value)\n}\n\nfunction safeDiff(a: number, b: number): number {\n if (!Number.isFinite(a) || !Number.isFinite(b)) return Number.NaN\n return a - b\n}\n\nfunction gapScore(gap: number, maxGap: number): number {\n if (!Number.isFinite(gap)) return 0\n if (maxGap <= 0) return gap <= 0 ? 1 : 0\n return bounded(1 - Math.max(0, gap) / maxGap)\n}\n\nfunction efficiencyScore(\n metrics: ReleaseConfidenceMetrics,\n thresholds: Required<ReleaseConfidenceThresholds>,\n): number {\n const cost = Number.isFinite(thresholds.maxMeanCostUsd) && Number.isFinite(metrics.meanCostUsd)\n ? bounded(thresholds.maxMeanCostUsd / Math.max(metrics.meanCostUsd, 1e-12))\n : 1\n const latency = Number.isFinite(thresholds.maxP95WallMs) && Number.isFinite(metrics.p95WallMs)\n ? bounded(thresholds.maxP95WallMs / Math.max(metrics.p95WallMs, 1e-12))\n : 1\n return Math.min(cost, latency)\n}\n\nfunction bounded(x: number): number {\n if (!Number.isFinite(x)) return 0\n return Math.max(0, Math.min(1, x))\n}\n\nfunction renderSummary(\n target: string,\n status: ReleaseConfidenceStatus,\n metrics: ReleaseConfidenceMetrics,\n issues: ReleaseConfidenceIssue[],\n): string {\n const prefix = `release confidence ${status}: ${target}`\n const metricText = `scenarios=${metrics.scenarioCount} searchRuns=${metrics.searchRuns} holdoutRuns=${metrics.holdoutRuns} passRate=${fmt(metrics.passRate)} meanScore=${fmt(metrics.meanScore)}`\n if (issues.length === 0) return `${prefix}; ${metricText}`\n return `${prefix}; ${metricText}; issues=${issues.map((i) => i.code).join(',')}`\n}\n\nfunction fmt(x: number): string {\n if (!Number.isFinite(x)) return String(x)\n return x.toFixed(4)\n}\n","/**\n * Pre-registered hypotheses — declare what you're testing BEFORE the\n * run, check it AFTER. Prevents p-hacking, optional stopping, and the\n * \"we ran until it looked good\" failure mode.\n *\n * Manifest is a plain JSON-friendly object. Sign it with a content hash\n * + timestamp; the registered record becomes immutable. Post-run,\n * evaluate the manifest against observed results — the library refuses\n * to let you re-interpret a different metric as the declared one.\n */\n\nexport interface HypothesisManifest {\n id: string\n /** Human prose — goes into the audit trail. */\n hypothesis: string\n /** Metric the hypothesis claims to move. */\n metric: string\n /** 'increase' = candidate should score higher than baseline; 'decrease' = lower. */\n direction: 'increase' | 'decrease'\n /** Minimum effect size to count (same units as the metric). */\n minEffect: number\n /** Alpha threshold. */\n alpha: number\n /** Target statistical power at which sample size was pre-computed. */\n power: number\n /** Declared N per arm before running. */\n preRegisteredN: number\n /** ISO8601 timestamp the manifest was registered. */\n registeredAt: string\n /** Optional identifiers to tie into the trace corpus. */\n baselineLabel?: string\n candidateLabel?: string\n}\n\n/**\n * Identifier for the hashing scheme used to produce `contentHash`.\n *\n * `'sha256-content'` — sha256 hex over the canonicalized manifest with\n * the `contentHash` and `algo` fields stripped. This is what\n * `signManifest` produces today.\n *\n * Held as a string union so future schemes can be added without\n * breaking parsers; legacy SignedManifest values written before this\n * field existed will deserialize cleanly because the field is optional.\n */\nexport type SignedManifestAlgo = 'sha256-content'\n\nexport interface SignedManifest extends HypothesisManifest {\n /** sha256 hex of canonicalized manifest (everything except contentHash and algo). */\n contentHash: string\n /**\n * Algorithm string describing how `contentHash` was produced.\n *\n * Optional on the type so legacy serialized manifests (pre-`algo`)\n * still parse, but ALWAYS populated by {@link signManifest}.\n * Consumers that want to enforce a known algorithm should reject\n * manifests where this field is missing or unrecognized.\n */\n algo?: SignedManifestAlgo\n}\n\nexport interface HypothesisResult {\n manifest: SignedManifest\n observedN: number\n observedEffect: number\n observedPValue: number\n /** True iff the observed effect hits the pre-declared direction with\n * magnitude ≥ minEffect AND p < alpha. */\n confirmed: boolean\n /** Enumerated reasons the hypothesis was rejected (each a machine-tag). */\n rejectionReasons: Array<'wrong_direction' | 'effect_too_small' | 'not_significant' | 'undersampled'>\n notes?: string\n}\n\n/**\n * Deterministic JSON canonicalization — sort object keys recursively.\n *\n * Two semantically-equal objects produce byte-identical canonicalized output;\n * this is what makes a content-hash stable across encoders, key insertion\n * orders, and runtime versions. Exported for any consumer that needs the same\n * canonicalization guarantee outside the manifest-signing path (e.g., signing\n * an artifact bundle, hashing a dataset version, etc.).\n */\nexport function canonicalize(v: unknown): unknown {\n if (v === null || typeof v !== 'object') return v\n if (Array.isArray(v)) return v.map(canonicalize)\n const keys = Object.keys(v as Record<string, unknown>).sort()\n const out: Record<string, unknown> = {}\n for (const k of keys) out[k] = canonicalize((v as Record<string, unknown>)[k])\n return out\n}\n\n/**\n * SHA-256 hex (full 64 chars) over the canonicalized JSON encoding of `obj`.\n *\n * The same primitive `signManifest` and `verifyManifest` are built on, exposed\n * directly so consumers signing arbitrary structured content (artifact bundles,\n * production packets, dataset manifests, etc.) don't have to re-derive\n * canonicalize+sha256 from scratch.\n *\n * Stable across:\n * - object key insertion order (canonicalization sorts keys recursively)\n * - encoder choice (UTF-8 via TextEncoder, fixed)\n * - runtime (uses the Web Crypto subtle digest, present in Node ≥18 and browsers)\n *\n * Naming note: `hashJson` rather than `hashContent` because `hashContent` is\n * already taken in `prompt-registry.ts` for the truncated 12-char prompt-id\n * helper, which has different semantics (string input, short return). Both\n * coexist; `hashJson` is the right name when you mean \"canonicalize then hash.\"\n *\n * @example\n * const hash = await hashJson({ id: '1', kind: 'spec' })\n * // 'a3f1...' (64 hex chars)\n */\nexport async function hashJson<T>(obj: T): Promise<string> {\n const canonical = canonicalize(obj)\n const bytes = new TextEncoder().encode(JSON.stringify(canonical))\n const digest = await globalThis.crypto.subtle.digest('SHA-256', bytes)\n return Array.from(new Uint8Array(digest))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n}\n\n/**\n * Sign a manifest with a SHA-256 content hash.\n *\n * The hash covers the canonicalized manifest with the `contentHash`\n * and `algo` fields stripped; this lets verifiers re-sign the rest and\n * compare. Returned manifest always carries `algo: 'sha256-content'`\n * so downstream consumers can identify the scheme; legacy serialized\n * manifests without `algo` still verify because it is stripped before\n * hashing on both sides.\n */\nexport async function signManifest(m: HypothesisManifest): Promise<SignedManifest> {\n const hash = await hashJson(m)\n return { ...m, contentHash: hash, algo: 'sha256-content' }\n}\n\n/**\n * Verify that a signed manifest has not been tampered with.\n *\n * Strips `contentHash` and `algo` before re-signing so legacy manifests\n * (written before `algo` was emitted) verify identically to current\n * ones.\n */\nexport async function verifyManifest(m: SignedManifest): Promise<boolean> {\n const { contentHash, algo: _algo, ...rest } = m\n void _algo\n const resigned = await signManifest(rest)\n return resigned.contentHash === contentHash\n}\n\n/**\n * Evaluate a pre-registered hypothesis against observed results.\n * Mechanical — no re-interpretation permitted.\n */\nexport async function evaluateHypothesis(\n manifest: SignedManifest,\n observed: { n: number; effect: number; pValue: number },\n): Promise<HypothesisResult> {\n if (!(await verifyManifest(manifest))) {\n throw new Error('evaluateHypothesis: manifest content hash mismatch (tampered)')\n }\n const reasons: HypothesisResult['rejectionReasons'] = []\n const directionOk =\n manifest.direction === 'increase' ? observed.effect > 0 : observed.effect < 0\n if (!directionOk) reasons.push('wrong_direction')\n if (Math.abs(observed.effect) < manifest.minEffect) reasons.push('effect_too_small')\n if (observed.pValue >= manifest.alpha) reasons.push('not_significant')\n if (observed.n < manifest.preRegisteredN) reasons.push('undersampled')\n return {\n manifest,\n observedN: observed.n,\n observedEffect: observed.effect,\n observedPValue: observed.pValue,\n confirmed: reasons.length === 0,\n rejectionReasons: reasons,\n }\n}\n","/**\n * Reporting helpers — production summaries and paper-quality figures — sit alongside `reporter.ts` rather\n * than replacing it.\n *\n * Three artefacts:\n *\n * - `summaryTable` Markdown table of per-candidate means,\n * 95% bootstrap CIs, BH-adjusted Wilcoxon\n * p-values, and Cohen's d versus a\n * comparator candidate.\n * - `paretoChart` Abstract spec for a cost vs quality\n * scatter, with gate decisions overlaid.\n * Returns numbers + labels — caller\n * chooses the plotting library.\n * - `gainHistogram`\n * Per-item paired holdout deltas as a\n * histogram spec (bins + counts + median +\n * CI). Same \"data, not images\" contract.\n *\n * The figure types are PlotSpecs — JSON-friendly, library-agnostic.\n * They aren't React components and they aren't PNGs; they are\n * what you'd hand to vega-lite, plotly, matplotlib, or your own\n * Canvas renderer to draw the actual figure.\n */\n\nimport { confidenceInterval, cohensD, wilcoxonSignedRank } from './statistics'\nimport { benjaminiHochberg, pairedMde } from './power-analysis'\nimport { pairedBootstrap } from './paired-stats'\nimport { canonicalize, hashJson } from './pre-registration'\nimport type { GateDecision } from './held-out-gate'\nimport type { FailureClusterReport } from './pipelines/failure-cluster'\nimport type { RunRecord } from './run-record'\n\n// ── summaryTable ───────────────────────────────────────────────────────\n\nexport interface SummaryTableOptions {\n /** Comparator candidate id. Wilcoxon + Cohen's d are computed\n * versus this candidate. Required for paired stats columns. */\n comparator?: string\n /** Which split to read scores from. Default 'holdout'. */\n split?: 'search' | 'holdout'\n /** Confidence level for the bootstrap CI on the mean. Default 0.95. */\n confidence?: number\n /** FDR for BH adjustment of the comparison p-values. Default 0.05. */\n fdr?: number\n}\n\nexport interface SummaryTableRow {\n candidateId: string\n n: number\n mean: number\n ciLow: number\n ciHigh: number\n /** BH-adjusted q-value vs comparator. NaN if no comparator. */\n qValue: number\n /** Cohen's d vs comparator. NaN if no comparator. */\n cohensD: number\n}\n\nexport interface SummaryTable {\n rows: SummaryTableRow[]\n comparator: string | null\n split: 'search' | 'holdout'\n /** Pre-rendered markdown — drop into a paper or PR. */\n markdown: string\n}\n\n/**\n * Table 1 helper. Buckets runs by `candidateId`, computes mean +\n * bootstrap CI on the chosen split, and (when a comparator is given)\n * BH-adjusted Wilcoxon p + Cohen's d versus that comparator.\n */\nexport function summaryTable(runs: RunRecord[], opts: SummaryTableOptions = {}): SummaryTable {\n const split = opts.split ?? 'holdout'\n const confidence = opts.confidence ?? 0.95\n const fdr = opts.fdr ?? 0.05\n const comparator = opts.comparator ?? null\n const scoreField = split === 'holdout' ? 'holdoutScore' : 'searchScore'\n\n const byCandidate = new Map<string, { runs: RunRecord[]; scores: number[] }>()\n for (const r of runs) {\n if (r.splitTag !== split) continue\n const v = r.outcome[scoreField]\n if (typeof v !== 'number' || !Number.isFinite(v)) continue\n const bucket = byCandidate.get(r.candidateId) ?? { runs: [], scores: [] }\n bucket.runs.push(r)\n bucket.scores.push(v)\n byCandidate.set(r.candidateId, bucket)\n }\n\n const candidateIds = [...byCandidate.keys()].sort()\n const compRuns = comparator ? byCandidate.get(comparator) : undefined\n\n // First pass: per-candidate means + CIs + raw p-values.\n const tentative: Array<SummaryTableRow & { rawP: number }> = []\n for (const id of candidateIds) {\n const bucket = byCandidate.get(id)!\n const ci = confidenceInterval(bucket.scores, confidence)\n let rawP = Number.NaN\n let d = Number.NaN\n if (comparator && compRuns && id !== comparator) {\n const paired = pairScoresByKey(bucket.runs, compRuns.runs, scoreField)\n if (paired.before.length >= 6) {\n rawP = wilcoxonSignedRank(paired.before, paired.after).p\n }\n d = cohensD(compRuns.scores, bucket.scores)\n }\n tentative.push({\n candidateId: id,\n n: bucket.scores.length,\n mean: ci.mean,\n ciLow: ci.lower,\n ciHigh: ci.upper,\n qValue: rawP,\n cohensD: d,\n rawP,\n })\n }\n\n // BH-adjust across the comparison set (skip NaN rows / the\n // comparator itself). Adjustment is a no-op when there are 0 or 1\n // comparators.\n if (comparator) {\n const idxs: number[] = []\n const ps: number[] = []\n for (let i = 0; i < tentative.length; i++) {\n const r = tentative[i]!\n if (r.candidateId === comparator) continue\n if (!Number.isFinite(r.rawP)) continue\n idxs.push(i)\n ps.push(r.rawP)\n }\n if (ps.length > 0) {\n const { qValues } = benjaminiHochberg(ps, fdr)\n for (let k = 0; k < idxs.length; k++) {\n tentative[idxs[k]!]!.qValue = qValues[k]!\n }\n }\n }\n\n const rows = tentative.map(({ rawP: _rawP, ...rest }) => rest)\n const markdown = renderSummaryTableMarkdown(rows, comparator, split)\n return { rows, comparator, split, markdown }\n}\n\nfunction pairScoresByKey(\n candidate: RunRecord[],\n baseline: RunRecord[],\n scoreField: 'searchScore' | 'holdoutScore',\n): { before: number[]; after: number[] } {\n const baseIdx = new Map<string, number>()\n for (const r of baseline) {\n const v = r.outcome[scoreField]\n if (typeof v === 'number' && Number.isFinite(v)) {\n baseIdx.set(`${r.experimentId}::${r.seed}`, v)\n }\n }\n const before: number[] = []\n const after: number[] = []\n for (const r of candidate) {\n const v = r.outcome[scoreField]\n if (typeof v !== 'number' || !Number.isFinite(v)) continue\n const key = `${r.experimentId}::${r.seed}`\n const b = baseIdx.get(key)\n if (b === undefined) continue\n before.push(b)\n after.push(v)\n }\n return { before, after }\n}\n\nfunction renderSummaryTableMarkdown(\n rows: SummaryTableRow[],\n comparator: string | null,\n split: 'search' | 'holdout',\n): string {\n const lines: string[] = []\n const cmpLabel = comparator ? ` (vs ${comparator})` : ''\n lines.push(`Summary Table — ${split} split${cmpLabel}`)\n lines.push('')\n lines.push('| Candidate | N | Mean | 95% CI | q (BH) | Cohen\\'s d |')\n lines.push('|---|---:|---:|---|---:|---:|')\n for (const r of rows) {\n const ci = `[${fmt(r.ciLow)}, ${fmt(r.ciHigh)}]`\n const q = Number.isFinite(r.qValue) ? r.qValue.toFixed(4) : '—'\n const d = Number.isFinite(r.cohensD) ? r.cohensD.toFixed(3) : '—'\n lines.push(`| ${r.candidateId} | ${r.n} | ${fmt(r.mean)} | ${ci} | ${q} | ${d} |`)\n }\n return lines.join('\\n')\n}\n\n// ── paretoChart ─────────────────────────────────────────────────────\n\nexport interface ParetoPoint {\n candidateId: string\n /** Mean USD cost per run on the chosen split. */\n cost: number\n /** Mean score on the chosen split. */\n quality: number\n /** Number of runs that informed this point. */\n n: number\n /** Whether this candidate is on the Pareto frontier — high\n * quality, low cost, no dominator. */\n onFrontier: boolean\n /** Optional gate verdict for this candidate, if a `GateDecision`\n * for it was passed in. */\n gate?: 'promote' | 'reject_few_runs' | 'reject_negative_delta' | 'reject_overfit_gap' | null\n}\n\nexport interface ParetoFigureSpec {\n kind: 'pareto-cost-quality'\n split: 'search' | 'holdout'\n points: ParetoPoint[]\n axes: { x: 'costUsd'; y: 'score' }\n}\n\n/**\n * Cost vs quality scatter spec. `gateDecisions` is keyed by\n * candidate id; if present, every point picks up the gate verdict\n * for overlay.\n */\nexport function paretoChart(\n runs: RunRecord[],\n opts: {\n split?: 'search' | 'holdout'\n gateDecisions?: Record<string, GateDecision>\n } = {},\n): ParetoFigureSpec {\n const split = opts.split ?? 'holdout'\n const scoreField = split === 'holdout' ? 'holdoutScore' : 'searchScore'\n\n const buckets = new Map<string, { cost: number[]; quality: number[] }>()\n for (const r of runs) {\n if (r.splitTag !== split) continue\n const v = r.outcome[scoreField]\n if (typeof v !== 'number' || !Number.isFinite(v)) continue\n const bucket = buckets.get(r.candidateId) ?? { cost: [], quality: [] }\n bucket.cost.push(r.costUsd)\n bucket.quality.push(v)\n buckets.set(r.candidateId, bucket)\n }\n\n const points: ParetoPoint[] = []\n for (const [candidateId, bucket] of buckets.entries()) {\n points.push({\n candidateId,\n cost: avg(bucket.cost),\n quality: avg(bucket.quality),\n n: bucket.cost.length,\n onFrontier: false,\n gate: opts.gateDecisions?.[candidateId]\n ? gateLabel(opts.gateDecisions[candidateId]!)\n : undefined,\n })\n }\n\n // Pareto: minimize cost, maximize quality. A point is dominated if\n // some other point has lower-or-equal cost AND higher-or-equal\n // quality with strict inequality somewhere.\n for (const p of points) {\n p.onFrontier = !points.some((q) => q !== p && dominates(q, p))\n }\n\n return {\n kind: 'pareto-cost-quality',\n split,\n axes: { x: 'costUsd', y: 'score' },\n points,\n }\n}\n\nfunction dominates(a: ParetoPoint, b: ParetoPoint): boolean {\n return a.cost <= b.cost && a.quality >= b.quality && (a.cost < b.cost || a.quality > b.quality)\n}\n\nfunction gateLabel(d: GateDecision): ParetoPoint['gate'] {\n if (d.promote) return 'promote'\n if (d.rejectionCode === 'few_runs') return 'reject_few_runs'\n if (d.rejectionCode === 'negative_delta') return 'reject_negative_delta'\n if (d.rejectionCode === 'overfit_gap') return 'reject_overfit_gap'\n return null\n}\n\n// ── gainHistogram ───────────────────────────────────────────\n\nexport interface GainDistributionBin {\n /** Inclusive lower edge. */\n lo: number\n /** Exclusive upper edge (or inclusive if it's the last bin). */\n hi: number\n /** Number of pairs whose delta lands in this bin. */\n count: number\n}\n\nexport interface GainDistributionFigureSpec {\n kind: 'gain-distribution'\n candidateId: string\n comparator: string\n split: 'search' | 'holdout'\n /** Number of pairs used. */\n n: number\n bins: GainDistributionBin[]\n median: number\n ci: { low: number; high: number }\n}\n\nexport interface GainDistributionOptions {\n /** Number of histogram bins. Default 11 (so the centre is exact at 0). */\n bins?: number\n /** Which split to use. Default 'holdout'. */\n split?: 'search' | 'holdout'\n /** Confidence level for the CI. Default 0.95. */\n confidence?: number\n /** Bootstrap resamples. Default 2000. */\n resamples?: number\n /** Deterministic seed. */\n seed?: number\n}\n\n/**\n * Held-out improvement distribution: per-pair delta (candidate −\n * comparator), histogrammed. Includes the bootstrap CI on the median\n * delta — same primitive the promotion gate uses.\n */\nexport function gainHistogram(\n runs: RunRecord[],\n candidateId: string,\n comparator: string,\n opts: GainDistributionOptions = {},\n): GainDistributionFigureSpec {\n const split = opts.split ?? 'holdout'\n const scoreField = split === 'holdout' ? 'holdoutScore' : 'searchScore'\n const binCount = opts.bins ?? 11\n if (binCount < 1) throw new Error('gainHistogram: bins must be ≥ 1')\n\n const candidate = runs.filter((r) => r.candidateId === candidateId && r.splitTag === split)\n const baseline = runs.filter((r) => r.candidateId === comparator && r.splitTag === split)\n // pairScoresByKey returns before=baseline-score, after=candidate-score\n // for each (experimentId, seed) pair where both sides recorded a\n // valid score on this split. delta = after - before = candidate - baseline.\n const { before, after } = pairScoresByKey(candidate, baseline, scoreField)\n const n = before.length\n\n if (n === 0) {\n return {\n kind: 'gain-distribution',\n candidateId,\n comparator,\n split,\n n: 0,\n bins: [],\n median: 0,\n ci: { low: 0, high: 0 },\n }\n }\n\n const deltas = before.map((b, i) => after[i]! - b)\n const sortedDeltas = [...deltas].sort((a, b) => a - b)\n const median = medianOfSorted(sortedDeltas)\n const min = sortedDeltas[0]!\n const max = sortedDeltas[sortedDeltas.length - 1]!\n\n // Symmetric bins around the wider of (|min|, |max|) so the chart\n // visually centres on zero without dropping outliers.\n const bound = Math.max(Math.abs(min), Math.abs(max), 1e-6)\n const lo = -bound\n const hi = bound\n const width = (hi - lo) / binCount\n const bins: GainDistributionBin[] = []\n for (let i = 0; i < binCount; i++) {\n bins.push({ lo: lo + i * width, hi: lo + (i + 1) * width, count: 0 })\n }\n for (const d of deltas) {\n let idx = Math.floor((d - lo) / width)\n if (idx < 0) idx = 0\n if (idx >= binCount) idx = binCount - 1\n bins[idx]!.count += 1\n }\n\n const ci = pairedBootstrap(before, after, {\n confidence: opts.confidence ?? 0.95,\n resamples: opts.resamples ?? 2000,\n statistic: 'median',\n seed: opts.seed,\n })\n\n return {\n kind: 'gain-distribution',\n candidateId,\n comparator,\n split,\n n,\n bins,\n median,\n ci: { low: ci.low, high: ci.high },\n }\n}\n\n// ── researchReport ───────────────────────────────────────────────────\n\nexport type ResearchReportDecision =\n | 'promote'\n | 'hold'\n | 'reject'\n | 'equivalent'\n | 'needs_more_data'\n\n/**\n * Hard floor below which a paired comparison is treated as uninformative\n * regardless of `minPairs`. Mirrors the lower limit on Wilcoxon signed-rank\n * exact tables; below this the test has no power to separate effect sizes.\n */\nexport const RESEARCH_REPORT_HARD_PAIR_FLOOR = 6\n\nexport interface ResearchReportOptions {\n /** Human-readable report title. */\n title?: string\n /** Comparator candidate id. Required for statistical decision guidance. */\n comparator?: string\n /** Which split to use for the primary decision. Default 'holdout'. */\n split?: 'search' | 'holdout'\n /** Confidence level used by lower-level report helpers. Default 0.95. */\n confidence?: number\n /** FDR threshold for q-values. Default 0.05. */\n fdr?: number\n /**\n * Soft floor on paired observations before issuing a directional\n * promote / reject. Below this we report `needs_more_data` and surface the\n * minimum detectable effect at the current N. Default 20 — chosen so the\n * Wilcoxon signed-rank approximation is reasonable and so the paired\n * bootstrap CI has non-degenerate coverage. Hard floor is enforced at\n * `RESEARCH_REPORT_HARD_PAIR_FLOOR` (6) regardless of this value.\n */\n minPairs?: number\n /**\n * Region of Practical Equivalence on the paired delta. When a candidate's\n * paired-delta CI is fully contained in `[low, high]`, the decision is\n * `equivalent` rather than `hold`. Sourced from the domain owner — there is\n * no statistically-defensible default.\n */\n rope?: { low: number; high: number }\n /**\n * Power for the minimum detectable effect (MDE) reported on each candidate.\n * Default 0.8.\n */\n mdePower?: number\n /**\n * Two-sided alpha for the MDE. Default matches `fdr` so the reported MDE\n * lines up with the test the report actually runs.\n */\n mdeAlpha?: number\n /** Optional held-out gate decisions keyed by candidate id. */\n gateDecisions?: Record<string, GateDecision>\n /** Optional failure clusters from failureClusterView. */\n failureClusters?: FailureClusterReport\n /** Build gain histograms for these candidates. Defaults to all non-comparator candidates. */\n candidateIds?: string[]\n /** Deterministic bootstrap seed passed to gainHistogram and the posterior helper. */\n seed?: number\n /** Report timestamp. Defaults to current time. */\n generatedAt?: string\n /**\n * Hash of a preregistered protocol (e.g. `signManifest({...}).contentHash`).\n * Embedded verbatim in the report so the analysis can be cited as the\n * preregistered one rather than a post-hoc fishing expedition.\n */\n preregistrationHash?: string\n}\n\nexport interface ResearchReportRecommendation {\n decision: ResearchReportDecision\n candidateId: string | null\n rationale: string[]\n risks: string[]\n nextActions: string[]\n}\n\nexport interface ResearchReportCandidate {\n candidateId: string\n n: number\n mean: number\n ciLow: number\n ciHigh: number\n qValue: number\n cohensD: number\n meanDeltaVsComparator: number | null\n pairedN: number\n medianGain: number | null\n meanGain: number | null\n gainCi: { low: number; high: number } | null\n /**\n * Bayesian-bootstrap-style posterior summaries on the paired delta. Computed\n * from the same resamples that produce the gain CI; interpretable as\n * \"fraction of resamples in which the candidate beats the comparator on\n * matched pairs.\"\n */\n prGreaterThanZero: number | null\n prInRope: number | null\n /**\n * Minimum detectable effect (in score units) at the candidate's paired N,\n * the configured power, and the configured alpha. Standardised by the\n * observed paired-delta SD and inverted via `requiredSampleSize`. Reported\n * for every candidate so a `needs_more_data` verdict is actionable.\n */\n mde: number | null\n onParetoFrontier: boolean\n gate?: ParetoPoint['gate']\n decision: ResearchReportDecision\n decisionReason: string\n}\n\nexport interface ResearchReportMethodology {\n /**\n * Plain-language assumptions the report depends on. Read these first when\n * deciding whether the verdict is load-bearing for a launch decision.\n */\n assumptions: string[]\n /** Tests and estimators the verdict was computed from. */\n methods: string[]\n /** Alternatives the author considered and why this report didn't take them. */\n alternatives: string[]\n /** Failure modes — when this report should NOT drive a decision. */\n whenNotToApply: string[]\n /** Citations for the methodological choices above. */\n citations: string[]\n}\n\nexport interface ResearchReport {\n kind: 'agent-eval-research-report'\n title: string\n generatedAt: string\n split: 'search' | 'holdout'\n comparator: string | null\n /**\n * SHA-256 over the canonicalised set of `(runId, candidateId, split)` triples\n * the report was computed from, plus the comparator and split. Stable across\n * key insertion order; recomputable by the reader to verify provenance.\n */\n runFingerprint: string\n preregistrationHash: string | null\n rope: { low: number; high: number } | null\n executiveSummary: string[]\n recommendation: ResearchReportRecommendation\n candidates: ResearchReportCandidate[]\n summary: SummaryTable\n charts: {\n pareto: ParetoFigureSpec\n gains: GainDistributionFigureSpec[]\n }\n methodology: ResearchReportMethodology\n failureClusters?: FailureClusterReport\n markdown: string\n html: string\n}\n\n/**\n * Internal: paired posterior summary on (candidate − comparator) deltas.\n *\n * Returns the bootstrap CI on the median (matching `gainHistogram`) plus\n * Bayesian-flavoured posterior summaries Pr(Δ>0) and Pr(Δ∈ROPE) computed\n * from a Bayesian-bootstrap-flavoured resample distribution on the mean\n * (Rubin 1981 — non-informative bootstrap-prior duality), and the\n * minimum detectable paired effect at the configured power and α.\n *\n * `null` is returned when no paired observations exist; callers must\n * gate on `n` before consuming the bootstrap statistics.\n */\nfunction pairedPosterior(\n runs: RunRecord[],\n candidateId: string,\n comparator: string,\n opts: {\n split: 'search' | 'holdout'\n confidence: number\n seed?: number\n rope: { low: number; high: number } | null\n mdePower: number\n mdeAlpha: number\n },\n): {\n n: number\n meanDelta: number\n medianDelta: number\n sdDelta: number\n ci: { low: number; high: number }\n prGreaterThanZero: number\n prInRope: number | null\n mde: number\n} | null {\n const scoreField = opts.split === 'holdout' ? 'holdoutScore' : 'searchScore'\n const candidate = runs.filter((r) => r.candidateId === candidateId && r.splitTag === opts.split)\n const baseline = runs.filter((r) => r.candidateId === comparator && r.splitTag === opts.split)\n const { before, after } = pairScoresByKey(candidate, baseline, scoreField)\n const n = before.length\n if (n === 0) return null\n\n const deltas = before.map((b, i) => after[i]! - b)\n const meanDelta = deltas.reduce((s, x) => s + x, 0) / n\n const sortedDeltas = [...deltas].sort((a, b) => a - b)\n const medianDelta = medianOfSorted(sortedDeltas)\n const sdDelta = stdev(deltas, meanDelta)\n\n const ci = pairedBootstrap(before, after, {\n confidence: opts.confidence,\n resamples: 2000,\n statistic: 'median',\n seed: opts.seed,\n })\n\n // Enumerate bootstrap-mean samples to derive posterior summaries on the\n // mean delta. Same RNG family as `pairedBootstrap` but kept local so we can\n // examine the full sample distribution rather than just quantiles.\n const meanSamples = bootstrapMeanSamples(deltas, 2000, opts.seed)\n const prGreaterThanZero = meanSamples.length === 0\n ? 0\n : meanSamples.filter((s) => s > 0).length / meanSamples.length\n const prInRope = opts.rope === null || meanSamples.length === 0\n ? null\n : meanSamples.filter((s) => s >= opts.rope!.low && s <= opts.rope!.high).length / meanSamples.length\n\n const dStandardised = pairedMde({ nPaired: n, alpha: opts.mdeAlpha, power: opts.mdePower })\n const mde = sdDelta === 0 ? 0 : dStandardised * sdDelta\n\n return {\n n,\n meanDelta,\n medianDelta,\n sdDelta,\n ci: { low: ci.low, high: ci.high },\n prGreaterThanZero,\n prInRope,\n mde,\n }\n}\n\nfunction bootstrapMeanSamples(deltas: number[], resamples: number, seed?: number): number[] {\n const n = deltas.length\n if (n === 0) return []\n if (n === 1) return new Array<number>(resamples).fill(deltas[0]!)\n const rng = seedRng(seed)\n const samples = new Array<number>(resamples)\n for (let b = 0; b < resamples; b++) {\n let sum = 0\n for (let k = 0; k < n; k++) sum += deltas[Math.floor(rng() * n)]!\n samples[b] = sum / n\n }\n return samples\n}\n\nfunction seedRng(seed?: number): () => number {\n if (seed === undefined) return Math.random\n let s = seed >>> 0\n return () => {\n s = (s + 0x6D2B79F5) >>> 0\n let t = s\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n}\n\nfunction stdev(xs: number[], mean: number): number {\n if (xs.length < 2) return 0\n let sse = 0\n for (const x of xs) sse += (x - mean) ** 2\n return Math.sqrt(sse / (xs.length - 1))\n}\n\n/**\n * Executive research report for CPO / AI-lead / launch-review consumption.\n *\n * Composes:\n * - `summaryTable` marginal stats with BH-FDR-adjusted q-values\n * - `paretoChart` cost-vs-quality frontier with gate overlay\n * - `gainHistogram` per-candidate paired-delta distribution\n * - paired posterior (this file): bootstrap CI on median, Pr(Δ>0),\n * Pr(Δ∈ROPE), MDE at the configured power\n *\n * Decisions are made on paired evidence — never on marginal means alone —\n * and respect any held-out gate decision the caller passes through. The\n * report embeds a SHA-256 fingerprint of the input run set and, optionally,\n * the hash of a preregistered protocol so a downstream reader can verify\n * provenance and that the analysis was the preregistered one.\n *\n * Async because the fingerprint uses Web Crypto via `hashJson`; deterministic\n * for any fixed `runs`, `seed`, and ROPE.\n */\nexport async function researchReport(runs: RunRecord[], opts: ResearchReportOptions = {}): Promise<ResearchReport> {\n const split = opts.split ?? 'holdout'\n const comparator = opts.comparator ?? null\n const confidence = opts.confidence ?? 0.95\n const fdr = opts.fdr ?? 0.05\n const minPairs = Math.max(opts.minPairs ?? 20, RESEARCH_REPORT_HARD_PAIR_FLOOR)\n const rope = opts.rope ?? null\n const mdePower = opts.mdePower ?? 0.8\n const mdeAlpha = opts.mdeAlpha ?? fdr\n const title = opts.title ?? 'Agent Evaluation Research Report'\n const generatedAt = opts.generatedAt ?? new Date().toISOString()\n const preregistrationHash = opts.preregistrationHash ?? null\n\n if (rope && !(Number.isFinite(rope.low) && Number.isFinite(rope.high) && rope.low <= rope.high)) {\n throw new Error(`researchReport: rope must satisfy low ≤ high with finite bounds, got ${JSON.stringify(rope)}`)\n }\n\n const summary = summaryTable(runs, {\n comparator: comparator ?? undefined,\n split,\n confidence,\n fdr,\n })\n const pareto = paretoChart(runs, { split, gateDecisions: opts.gateDecisions })\n const candidateIds = opts.candidateIds\n ?? summary.rows.map((r) => r.candidateId).filter((id) => id !== comparator)\n const gains = comparator\n ? candidateIds.map((id) => gainHistogram(runs, id, comparator, {\n split,\n confidence,\n seed: opts.seed,\n }))\n : []\n\n const gainByCandidate = new Map(gains.map((g) => [g.candidateId, g]))\n const paretoByCandidate = new Map(pareto.points.map((p) => [p.candidateId, p]))\n const posteriorByCandidate = new Map<string, ReturnType<typeof pairedPosterior>>()\n if (comparator) {\n for (const id of candidateIds) {\n posteriorByCandidate.set(id, pairedPosterior(runs, id, comparator, {\n split,\n confidence,\n seed: opts.seed,\n rope,\n mdePower,\n mdeAlpha,\n }))\n }\n }\n\n const candidates = summary.rows\n .map((row) => {\n const gain = gainByCandidate.get(row.candidateId)\n const point = paretoByCandidate.get(row.candidateId)\n const posterior = posteriorByCandidate.get(row.candidateId) ?? null\n const classified = classifyCandidate(row, {\n comparator,\n posterior,\n point,\n fdr,\n minPairs,\n rope,\n })\n return {\n candidateId: row.candidateId,\n n: row.n,\n mean: row.mean,\n ciLow: row.ciLow,\n ciHigh: row.ciHigh,\n qValue: row.qValue,\n cohensD: row.cohensD,\n meanDeltaVsComparator: posterior ? posterior.meanDelta : null,\n pairedN: posterior?.n ?? gain?.n ?? 0,\n medianGain: posterior ? posterior.medianDelta : (gain ? gain.median : null),\n meanGain: posterior ? posterior.meanDelta : null,\n gainCi: posterior ? posterior.ci : (gain ? gain.ci : null),\n prGreaterThanZero: posterior ? posterior.prGreaterThanZero : null,\n prInRope: posterior ? posterior.prInRope : null,\n mde: posterior ? posterior.mde : null,\n onParetoFrontier: point?.onFrontier ?? false,\n gate: point?.gate,\n decision: classified.decision,\n decisionReason: classified.reason,\n } satisfies ResearchReportCandidate\n })\n .sort((a, b) => {\n const decisionRank = decisionWeight(b.decision) - decisionWeight(a.decision)\n if (decisionRank !== 0) return decisionRank\n return b.mean - a.mean\n })\n\n const recommendation = buildRecommendation(candidates, {\n comparator,\n failureClusters: opts.failureClusters,\n rope,\n minPairs,\n preregistrationHash,\n })\n const executiveSummary = buildExecutiveSummary(candidates, recommendation, {\n comparator,\n split,\n failureClusters: opts.failureClusters,\n preregistrationHash,\n })\n const methodology = buildMethodology({ split, comparator, fdr, minPairs, rope, confidence, mdePower, mdeAlpha })\n\n const runFingerprint = await hashJson(canonicalize({\n triples: runs\n .filter((r) => r.splitTag === split)\n .map((r) => ({ runId: r.runId, candidateId: r.candidateId, splitTag: r.splitTag }))\n .sort((a, b) => a.runId.localeCompare(b.runId)),\n comparator,\n split,\n }))\n\n const markdown = renderResearchMarkdown({\n title,\n generatedAt,\n split,\n comparator,\n rope,\n runFingerprint,\n preregistrationHash,\n executiveSummary,\n recommendation,\n candidates,\n summary,\n pareto,\n gains,\n methodology,\n failureClusters: opts.failureClusters,\n })\n const html = renderResearchHtml(markdown, title)\n\n return {\n kind: 'agent-eval-research-report',\n title,\n generatedAt,\n split,\n comparator,\n runFingerprint,\n preregistrationHash,\n rope,\n executiveSummary,\n recommendation,\n candidates,\n summary,\n charts: { pareto, gains },\n methodology,\n failureClusters: opts.failureClusters,\n markdown,\n html,\n }\n}\n\nfunction buildMethodology(ctx: {\n split: 'search' | 'holdout'\n comparator: string | null\n fdr: number\n minPairs: number\n rope: { low: number; high: number } | null\n confidence: number\n mdePower: number\n mdeAlpha: number\n}): ResearchReportMethodology {\n const assumptions: string[] = [\n 'Pairs are matched by (experimentId, seed); the candidate and comparator see the same scenarios in the same order.',\n 'Paired deltas are exchangeable conditional on the matched scenario — no mid-run distribution shift.',\n `Decisions are pre-specified at fdr=${ctx.fdr}, minPairs=${ctx.minPairs}, confidence=${ctx.confidence}; deviating from these post-hoc invalidates the false-discovery control.`,\n ]\n if (ctx.rope) {\n assumptions.push(`The Region of Practical Equivalence ${formatRope(ctx.rope)} is supplied by the domain owner; equivalent verdicts are only meaningful if that range is treated as the standing definition of \"no material difference.\"`)\n }\n if (ctx.comparator === null) {\n assumptions.push('No comparator was configured; this run is descriptive, not causal.')\n }\n const methods: string[] = [\n 'Marginal scores summarised with BH-FDR-adjusted Wilcoxon signed-rank q-values and Cohen\\'s d via summaryTable.',\n 'Paired evidence summarised with bootstrap CI on the median delta and Bayesian-bootstrap-style Pr(Δ>0) and Pr(Δ∈ROPE) on the mean delta.',\n `Minimum detectable effect reported per candidate at α=${ctx.mdeAlpha} (two-sided), power=${ctx.mdePower}, standardised by the observed paired-delta SD.`,\n 'Pareto frontier flagged as a separate axis (cost vs quality); a candidate can be on-frontier without winning the paired test.',\n 'Held-out gate decisions, when supplied, override the statistical verdict in the reject direction.',\n ]\n const alternatives: string[] = [\n 'Paired t-test rejected: not robust to the heavy-tailed score distributions common in agent benchmarks.',\n 'Unpaired Mann–Whitney rejected: matched scenarios make pairing free; unpaired throws away that variance reduction.',\n 'Sequential / always-valid inference (e-values, mSPRT) is the right tool for iterative sweeps and is out of scope for this single-look report — preregister and run once, or wrap this report in an alpha-spending schedule.',\n 'Hierarchical Bayesian shrinkage across many candidates is future work; the current ranking uses raw paired statistics.',\n ]\n const whenNotToApply: string[] = [\n `Paired N below ${RESEARCH_REPORT_HARD_PAIR_FLOOR} on any candidate — the bootstrap CI is degenerate.`,\n 'Comparator chosen post-hoc by inspecting the same data; q-values are no longer false-discovery-controlled.',\n 'Scenarios not drawn under a stable preregistered protocol; the report can describe the data but cannot anchor a launch decision.',\n 'Score distributions with mid-run shift (judge model swap, rubric change, infra outage) — pair exchangeability is violated.',\n ]\n const citations: string[] = [\n 'Benjamini, Y. & Hochberg, Y. (1995). Controlling the false discovery rate: a practical and powerful approach to multiple testing. JRSS B, 57(1), 289–300.',\n 'Wilcoxon, F. (1945). Individual comparisons by ranking methods. Biometrics Bulletin, 1(6), 80–83.',\n 'Efron, B. (1979). Bootstrap methods: another look at the jackknife. Annals of Statistics, 7(1), 1–26.',\n 'Rubin, D. B. (1981). The Bayesian bootstrap. Annals of Statistics, 9(1), 130–134.',\n 'Kruschke, J. K. (2018). Rejecting or accepting parameter values in Bayesian estimation. Advances in Methods and Practices in Psychological Science, 1(2), 270–280. (ROPE.)',\n ]\n return { assumptions, methods, alternatives, whenNotToApply, citations }\n}\n\nfunction formatRope(rope: { low: number; high: number }): string {\n return `[${fmt(rope.low)}, ${fmt(rope.high)}]`\n}\n\nfunction classifyCandidate(\n row: SummaryTableRow,\n ctx: {\n comparator: string | null\n posterior: ReturnType<typeof pairedPosterior> | null\n point?: ParetoPoint\n fdr: number\n minPairs: number\n rope: { low: number; high: number } | null\n },\n): { decision: ResearchReportDecision; reason: string } {\n if (ctx.comparator && row.candidateId === ctx.comparator) {\n return { decision: 'hold', reason: 'Comparator baseline.' }\n }\n if (!ctx.comparator) {\n return {\n decision: ctx.point?.onFrontier ? 'hold' : 'needs_more_data',\n reason: 'No comparator configured; report ranks candidates but cannot anchor a promotion call.',\n }\n }\n // Held-out gate is authoritative against — promote requires statistical\n // evidence even if the gate said `promote` (gate is necessary, not sufficient).\n if (ctx.point?.gate && ctx.point.gate !== 'promote') {\n return { decision: 'reject', reason: `Held-out gate returned ${ctx.point.gate}.` }\n }\n if (!ctx.posterior || ctx.posterior.n < RESEARCH_REPORT_HARD_PAIR_FLOOR) {\n return {\n decision: 'needs_more_data',\n reason: `Only ${ctx.posterior?.n ?? 0} paired observations; below hard floor of ${RESEARCH_REPORT_HARD_PAIR_FLOOR} for any paired inference.`,\n }\n }\n const ci = ctx.posterior.ci\n if (ctx.rope && ci.low >= ctx.rope.low && ci.high <= ctx.rope.high) {\n return {\n decision: 'equivalent',\n reason: `Paired-delta CI [${fmt(ci.low)}, ${fmt(ci.high)}] is fully inside ROPE ${formatRope(ctx.rope)}; candidate is practically equivalent to comparator.`,\n }\n }\n const significant = Number.isFinite(row.qValue) && row.qValue <= ctx.fdr\n const gainPositive = ci.low > 0\n const gainNegative = ci.high < 0\n if (gainNegative) {\n return { decision: 'reject', reason: `Paired-delta CI [${fmt(ci.low)}, ${fmt(ci.high)}] lies entirely below zero.` }\n }\n if (ctx.posterior.n < ctx.minPairs) {\n return {\n decision: 'needs_more_data',\n reason: `Only ${ctx.posterior.n} paired observations; minimum detectable effect at this N is ${fmt(ctx.posterior.mde)} score units (need ≥ ${ctx.minPairs} pairs to issue a directional verdict).`,\n }\n }\n if (significant && gainPositive) {\n return {\n decision: 'promote',\n reason: `BH-adjusted q=${fmt(row.qValue)} ≤ ${ctx.fdr} and paired-delta CI [${fmt(ci.low)}, ${fmt(ci.high)}] excludes zero; Pr(Δ>0)=${fmt(ctx.posterior.prGreaterThanZero)}.`,\n }\n }\n return {\n decision: 'hold',\n reason: `Pr(Δ>0)=${fmt(ctx.posterior.prGreaterThanZero)} but CI [${fmt(ci.low)}, ${fmt(ci.high)}] crosses zero; effect not decisive at fdr=${ctx.fdr}.`,\n }\n}\n\nfunction buildRecommendation(\n candidates: ResearchReportCandidate[],\n ctx: {\n comparator: string | null\n failureClusters?: FailureClusterReport\n rope: { low: number; high: number } | null\n minPairs: number\n preregistrationHash: string | null\n },\n): ResearchReportRecommendation {\n const nonComparator = candidates.filter((c) => c.candidateId !== ctx.comparator)\n const bestPromote = nonComparator.find((c) => c.decision === 'promote')\n const bestEquivalent = nonComparator.find((c) => c.decision === 'equivalent')\n const chosen = bestPromote ?? bestEquivalent ?? nonComparator[0] ?? null\n const decision: ResearchReportDecision = bestPromote\n ? 'promote'\n : nonComparator.some((c) => c.decision === 'needs_more_data')\n ? 'needs_more_data'\n : bestEquivalent\n ? 'equivalent'\n : nonComparator.some((c) => c.decision === 'hold')\n ? 'hold'\n : 'reject'\n\n const rationale: string[] = []\n const risks: string[] = []\n const nextActions: string[] = []\n\n if (chosen) {\n rationale.push(`${chosen.candidateId}: ${chosen.decisionReason}`)\n if (chosen.gainCi) {\n const probSummary = chosen.prGreaterThanZero !== null\n ? `, Pr(Δ>0)=${fmt(chosen.prGreaterThanZero)}`\n : ''\n rationale.push(`Median paired gain CI: [${fmt(chosen.gainCi.low)}, ${fmt(chosen.gainCi.high)}]${probSummary}.`)\n }\n if (chosen.mde !== null && Number.isFinite(chosen.mde)) {\n rationale.push(`MDE at current paired N=${chosen.pairedN}: ${fmt(chosen.mde)} score units.`)\n }\n }\n if (!ctx.comparator) {\n risks.push('No comparator was configured; verdict is descriptive, not causal.')\n nextActions.push('Re-run with a stable comparator candidate for paired inference.')\n }\n if (!ctx.preregistrationHash) {\n risks.push('No preregistration hash supplied; readers cannot verify the analysis was specified before data inspection.')\n nextActions.push('Sign a HypothesisManifest before the next sweep and pass `preregistrationHash` so the report cites it.')\n }\n if (ctx.rope === null && nonComparator.length > 0) {\n risks.push('No ROPE configured; the report cannot distinguish \"equivalent\" from \"inconclusive\".')\n nextActions.push('Define a domain-specific Region of Practical Equivalence and pass it to lock in the equivalence threshold.')\n }\n const inconclusive = nonComparator.filter((c) => c.decision === 'needs_more_data')\n if (inconclusive.length > 0) {\n const worst = inconclusive.reduce((a, b) => (b.pairedN < a.pairedN ? b : a))\n risks.push(`${inconclusive.length} candidate(s) below soft floor (${ctx.minPairs} pairs); thinnest is ${worst.candidateId} with ${worst.pairedN}.`)\n nextActions.push(`Collect at least ${ctx.minPairs - worst.pairedN} more matched holdout runs for ${worst.candidateId}.`)\n }\n const rejected = nonComparator.filter((c) => c.decision === 'reject')\n if (rejected.length > 0) {\n risks.push(`${rejected.length} candidate(s) failed the paired test or held-out gate; do not ship those variants.`)\n }\n if (ctx.failureClusters && ctx.failureClusters.clusters.length > 0) {\n const top = ctx.failureClusters.clusters[0]!\n risks.push(`Top failure cluster: ${top.failureClass} across ${top.runCount} run(s).`)\n nextActions.push('Prioritize the largest failure cluster before broad rollout.')\n }\n if (decision === 'promote') {\n nextActions.push('Ship behind the existing promotion gate and monitor canaries.')\n } else if (decision === 'hold') {\n nextActions.push('Keep current production candidate while expanding holdout evidence.')\n } else if (decision === 'equivalent') {\n nextActions.push('Either keep the comparator (no quality regression) or promote on cost/latency grounds — equivalence does not justify either; the choice is a product decision, not a stats one.')\n } else if (decision === 'reject') {\n nextActions.push('Do not promote this sweep; inspect failures and generate a revised candidate.')\n }\n\n return {\n decision,\n candidateId: chosen?.candidateId ?? null,\n rationale,\n risks,\n nextActions,\n }\n}\n\nfunction buildExecutiveSummary(\n candidates: ResearchReportCandidate[],\n recommendation: ResearchReportRecommendation,\n ctx: {\n comparator: string | null\n split: 'search' | 'holdout'\n failureClusters?: FailureClusterReport\n preregistrationHash: string | null\n },\n): string[] {\n const lines: string[] = []\n const nonComparator = candidates.filter((c) => c.candidateId !== ctx.comparator)\n lines.push(`Evaluated ${nonComparator.length} candidate(s) on the ${ctx.split} split${ctx.comparator ? ` against ${ctx.comparator}` : ''}.`)\n lines.push(`Recommendation: ${recommendation.decision}${recommendation.candidateId ? ` ${recommendation.candidateId}` : ''}.`)\n const promoted = nonComparator.filter((c) => c.decision === 'promote').length\n const held = nonComparator.filter((c) => c.decision === 'hold').length\n const equivalent = nonComparator.filter((c) => c.decision === 'equivalent').length\n const rejected = nonComparator.filter((c) => c.decision === 'reject').length\n const more = nonComparator.filter((c) => c.decision === 'needs_more_data').length\n lines.push(`Decision mix: ${promoted} promote, ${equivalent} equivalent, ${held} hold, ${rejected} reject, ${more} need more data.`)\n const frontier = nonComparator.filter((c) => c.onParetoFrontier).map((c) => c.candidateId)\n if (frontier.length > 0) lines.push(`Pareto-frontier candidates: ${frontier.join(', ')}.`)\n if (ctx.failureClusters) {\n lines.push(`Failure clustering found ${ctx.failureClusters.totalFailures}/${ctx.failureClusters.totalRuns} failed runs across ${ctx.failureClusters.clusters.length} reportable cluster(s).`)\n }\n lines.push(ctx.preregistrationHash\n ? `Preregistered analysis: ${ctx.preregistrationHash.slice(0, 12)}…`\n : 'Analysis is post-hoc — no preregistration hash supplied.')\n return lines\n}\n\nfunction renderResearchMarkdown(report: {\n title: string\n generatedAt: string\n split: 'search' | 'holdout'\n comparator: string | null\n executiveSummary: string[]\n recommendation: ResearchReportRecommendation\n candidates: ResearchReportCandidate[]\n summary: SummaryTable\n pareto: ParetoFigureSpec\n gains: GainDistributionFigureSpec[]\n rope: { low: number; high: number } | null\n runFingerprint: string\n preregistrationHash: string | null\n methodology: ResearchReportMethodology\n failureClusters?: FailureClusterReport\n}): string {\n const lines: string[] = []\n lines.push(`# ${report.title}`)\n lines.push('')\n lines.push(`**Generated:** ${report.generatedAt}`)\n lines.push(`**Primary split:** ${report.split}`)\n lines.push(`**Comparator:** ${report.comparator ?? 'not configured'}`)\n lines.push(`**ROPE:** ${report.rope ? formatRope(report.rope) : 'not configured'}`)\n lines.push(`**Run fingerprint:** \\`${report.runFingerprint}\\``)\n lines.push(`**Preregistration:** ${report.preregistrationHash ? `\\`${report.preregistrationHash}\\`` : 'none'}`)\n lines.push('')\n lines.push('## Executive Summary')\n lines.push('')\n for (const item of report.executiveSummary) lines.push(`- ${item}`)\n lines.push('')\n lines.push('## Recommendation')\n lines.push('')\n lines.push(`**Decision:** ${report.recommendation.decision}`)\n lines.push(`**Candidate:** ${report.recommendation.candidateId ?? 'N/A'}`)\n lines.push('')\n lines.push('### Rationale')\n lines.push('')\n for (const item of report.recommendation.rationale) lines.push(`- ${item}`)\n lines.push('')\n lines.push('### Risks')\n lines.push('')\n for (const item of report.recommendation.risks.length ? report.recommendation.risks : ['No material report-level risks detected.']) {\n lines.push(`- ${item}`)\n }\n lines.push('')\n lines.push('### Next Actions')\n lines.push('')\n for (const item of report.recommendation.nextActions) lines.push(`- ${item}`)\n lines.push('')\n lines.push('## Candidate Decision Table')\n lines.push('')\n lines.push('| Candidate | Decision | Mean | Δ̄ | Pr(Δ>0) | q | d | Paired N | Median Gain CI | MDE | Pareto | Gate |')\n lines.push('|---|---|---:|---:|---:|---:|---:|---:|---|---:|---|---|')\n for (const c of report.candidates) {\n const delta = c.meanDeltaVsComparator === null ? '-' : signed(c.meanDeltaVsComparator)\n const prGt = c.prGreaterThanZero === null ? '-' : c.prGreaterThanZero.toFixed(3)\n const q = Number.isFinite(c.qValue) ? c.qValue.toFixed(4) : '-'\n const d = Number.isFinite(c.cohensD) ? c.cohensD.toFixed(3) : '-'\n const gain = c.gainCi ? `[${fmt(c.gainCi.low)}, ${fmt(c.gainCi.high)}]` : '-'\n const mde = c.mde === null || !Number.isFinite(c.mde) ? '-' : fmt(c.mde)\n lines.push(`| ${c.candidateId} | ${c.decision} | ${fmt(c.mean)} | ${delta} | ${prGt} | ${q} | ${d} | ${c.pairedN} | ${gain} | ${mde} | ${c.onParetoFrontier ? 'yes' : 'no'} | ${c.gate ?? '-'} |`)\n }\n lines.push('')\n lines.push('## Statistical Summary')\n lines.push('')\n lines.push(report.summary.markdown)\n lines.push('')\n lines.push('## Methodology')\n lines.push('')\n lines.push('### Assumptions')\n lines.push('')\n for (const item of report.methodology.assumptions) lines.push(`- ${item}`)\n lines.push('')\n lines.push('### Methods')\n lines.push('')\n for (const item of report.methodology.methods) lines.push(`- ${item}`)\n lines.push('')\n lines.push('### Alternatives Considered')\n lines.push('')\n for (const item of report.methodology.alternatives) lines.push(`- ${item}`)\n lines.push('')\n lines.push('### When NOT To Apply')\n lines.push('')\n for (const item of report.methodology.whenNotToApply) lines.push(`- ${item}`)\n lines.push('')\n lines.push('### Citations')\n lines.push('')\n for (const item of report.methodology.citations) lines.push(`- ${item}`)\n lines.push('')\n lines.push('## Chart Specs')\n lines.push('')\n lines.push('The report carries JSON chart specs for Pareto cost/quality and paired gain histograms.')\n lines.push('')\n lines.push('```json')\n lines.push(JSON.stringify({ pareto: report.pareto, gains: report.gains }, null, 2))\n lines.push('```')\n if (report.failureClusters) {\n lines.push('')\n lines.push('## Failure Clusters')\n lines.push('')\n lines.push('| Failure Class | Runs | Scenarios | Tool | Example |')\n lines.push('|---|---:|---:|---|---|')\n for (const c of report.failureClusters.clusters.slice(0, 10)) {\n lines.push(`| ${c.failureClass} | ${c.runCount} | ${c.scenarioIds.length} | ${c.toolName ?? '-'} | ${escapePipes(c.exampleError ?? c.exampleRunId)} |`)\n }\n }\n return lines.join('\\n')\n}\n\nfunction renderResearchHtml(markdown: string, title: string): string {\n const body = markdownToHtml(markdown)\n return [\n '<!doctype html>',\n '<html lang=\"en\">',\n '<head>',\n '<meta charset=\"utf-8\">',\n '<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">',\n `<title>${escapeHtml(title)}</title>`,\n '<style>',\n 'body{font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,\"Segoe UI\",sans-serif;margin:0;color:#172026;background:#f7f8f8;}',\n 'main{max-width:1080px;margin:0 auto;padding:40px 24px 64px;background:#fff;min-height:100vh;}',\n 'h1{font-size:34px;line-height:1.15;margin:0 0 20px;}h2{margin-top:34px;border-top:1px solid #d9dfdf;padding-top:22px;}h3{margin-top:22px;}',\n 'p,li{line-height:1.55;}table{border-collapse:collapse;width:100%;margin:16px 0;font-size:14px;}th,td{border:1px solid #d9dfdf;padding:8px;text-align:left;}th{background:#eef2f2;}',\n 'code,pre{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;}pre{overflow:auto;background:#111827;color:#f9fafb;padding:16px;border-radius:6px;}',\n '</style>',\n '</head>',\n '<body><main>',\n body,\n '</main></body></html>',\n ].join('\\n')\n}\n\nfunction markdownToHtml(markdown: string): string {\n const lines = markdown.split('\\n')\n const html: string[] = []\n let inList = false\n let inCode = false\n let code: string[] = []\n let table: string[] = []\n\n const flushList = () => {\n if (inList) {\n html.push('</ul>')\n inList = false\n }\n }\n const flushTable = () => {\n if (table.length === 0) return\n html.push(renderMarkdownTable(table))\n table = []\n }\n\n for (const line of lines) {\n if (line.startsWith('```')) {\n if (inCode) {\n html.push(`<pre><code>${escapeHtml(code.join('\\n'))}</code></pre>`)\n code = []\n inCode = false\n } else {\n flushList()\n flushTable()\n inCode = true\n }\n continue\n }\n if (inCode) {\n code.push(line)\n continue\n }\n if (line.startsWith('|')) {\n flushList()\n table.push(line)\n continue\n }\n flushTable()\n if (line.startsWith('- ')) {\n if (!inList) {\n html.push('<ul>')\n inList = true\n }\n html.push(`<li>${inlineMarkdown(line.slice(2))}</li>`)\n continue\n }\n flushList()\n if (line.startsWith('# ')) html.push(`<h1>${inlineMarkdown(line.slice(2))}</h1>`)\n else if (line.startsWith('## ')) html.push(`<h2>${inlineMarkdown(line.slice(3))}</h2>`)\n else if (line.startsWith('### ')) html.push(`<h3>${inlineMarkdown(line.slice(4))}</h3>`)\n else if (line.trim() === '') html.push('')\n else html.push(`<p>${inlineMarkdown(line)}</p>`)\n }\n flushList()\n flushTable()\n return html.join('\\n')\n}\n\nfunction renderMarkdownTable(lines: string[]): string {\n const rows = lines\n .filter((line) => !/^\\|[-:\\s|]+\\|$/.test(line))\n .map((line) => line.slice(1, -1).split('|').map((cell) => inlineMarkdown(cell.trim())))\n if (rows.length === 0) return ''\n const [head, ...body] = rows\n const th = head!.map((cell) => `<th>${cell}</th>`).join('')\n const trs = body.map((row) => `<tr>${row.map((cell) => `<td>${cell}</td>`).join('')}</tr>`).join('\\n')\n return `<table><thead><tr>${th}</tr></thead><tbody>${trs}</tbody></table>`\n}\n\nfunction inlineMarkdown(s: string): string {\n return escapeHtml(s).replace(/\\*\\*([^*]+)\\*\\*/g, '<strong>$1</strong>')\n}\n\nfunction escapeHtml(s: string): string {\n return s\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n}\n\nfunction escapePipes(s: string): string {\n return s.replace(/\\|/g, '\\\\|')\n}\n\nfunction decisionWeight(decision: ResearchReportDecision): number {\n if (decision === 'promote') return 5\n if (decision === 'equivalent') return 4\n if (decision === 'hold') return 3\n if (decision === 'needs_more_data') return 2\n return 1\n}\n\nfunction signed(x: number): string {\n return `${x >= 0 ? '+' : ''}${fmt(x)}`\n}\n\n// ── tiny helpers ─────────────────────────────────────────────────────\n\nfunction avg(xs: number[]): number {\n if (xs.length === 0) return Number.NaN\n return xs.reduce((s, x) => s + x, 0) / xs.length\n}\n\nfunction medianOfSorted(sorted: number[]): number {\n if (sorted.length === 0) return 0\n const mid = Math.floor(sorted.length / 2)\n return sorted.length % 2 === 0 ? (sorted[mid - 1]! + sorted[mid]!) / 2 : sorted[mid]!\n}\n\nfunction fmt(x: number): string {\n if (!Number.isFinite(x)) return String(x)\n return x.toFixed(4)\n}\n","import type { ReleaseConfidenceScorecard } from './release-confidence'\nimport { summaryTable } from './summary-report'\nimport type { RunRecord } from './run-record'\n\nexport interface RenderReleaseReportOptions {\n title?: string\n runs?: readonly RunRecord[]\n comparator?: string\n traceAnalystFindings?: readonly string[]\n nextActions?: readonly string[]\n}\n\nexport function renderReleaseReport(\n scorecard: ReleaseConfidenceScorecard,\n options: RenderReleaseReportOptions = {},\n): string {\n const title = options.title ?? `Release Report: ${scorecard.target}`\n const lines: string[] = []\n lines.push(`# ${title}`)\n lines.push('')\n lines.push(`Status: **${scorecard.status.toUpperCase()}**`)\n lines.push(`Promote: **${scorecard.promote ? 'yes' : 'no'}**`)\n if (scorecard.candidateId) lines.push(`Candidate: \\`${scorecard.candidateId}\\``)\n if (scorecard.baselineId) lines.push(`Baseline: \\`${scorecard.baselineId}\\``)\n lines.push('')\n lines.push(scorecard.summary)\n lines.push('')\n\n lines.push('## Metrics')\n lines.push('')\n lines.push('| Metric | Value |')\n lines.push('|---|---:|')\n lines.push(`| Scenarios | ${scorecard.metrics.scenarioCount} |`)\n lines.push(`| Search runs | ${scorecard.metrics.searchRuns} |`)\n lines.push(`| Holdout runs | ${scorecard.metrics.holdoutRuns} |`)\n lines.push(`| Pass rate | ${pct(scorecard.metrics.passRate)} |`)\n lines.push(`| Mean score | ${num(scorecard.metrics.meanScore)} |`)\n lines.push(`| Search mean | ${num(scorecard.metrics.searchMeanScore)} |`)\n lines.push(`| Holdout mean | ${num(scorecard.metrics.holdoutMeanScore)} |`)\n lines.push(`| Overfit gap | ${num(scorecard.metrics.overfitGap)} |`)\n lines.push(`| Mean cost | $${num(scorecard.metrics.meanCostUsd)} |`)\n lines.push(`| p95 wall time | ${Math.round(scorecard.metrics.p95WallMs)} ms |`)\n lines.push('')\n\n if (scorecard.issues.length > 0) {\n lines.push('## Issues')\n lines.push('')\n for (const issue of scorecard.issues) {\n lines.push(`- **${issue.severity}** \\`${issue.code}\\` (${issue.axis}): ${issue.detail}`)\n }\n lines.push('')\n }\n\n const surfaces = entries(scorecard.metrics.responsibleSurfaceCounts)\n if (surfaces.length > 0) {\n lines.push('## Responsible Surfaces')\n lines.push('')\n for (const [surface, count] of surfaces) lines.push(`- ${surface}: ${count}`)\n lines.push('')\n }\n\n const failures = entries(scorecard.metrics.failureModeCounts)\n if (failures.length > 0) {\n lines.push('## Failure Modes')\n lines.push('')\n for (const [mode, count] of failures) lines.push(`- ${mode}: ${count}`)\n lines.push('')\n }\n\n if (options.runs && options.runs.length > 0) {\n lines.push('## Run Summary')\n lines.push('')\n lines.push(summaryTable([...options.runs], {\n comparator: options.comparator ?? scorecard.baselineId ?? undefined,\n split: 'holdout',\n }).markdown)\n lines.push('')\n }\n\n if (options.traceAnalystFindings && options.traceAnalystFindings.length > 0) {\n lines.push('## TraceAnalyst Findings')\n lines.push('')\n for (const finding of options.traceAnalystFindings) lines.push(`- ${finding}`)\n lines.push('')\n }\n\n const nextActions = options.nextActions ?? defaultNextActions(scorecard)\n if (nextActions.length > 0) {\n lines.push('## Next Actions')\n lines.push('')\n for (const action of nextActions) lines.push(`- ${action}`)\n lines.push('')\n }\n\n return lines.join('\\n').trimEnd() + '\\n'\n}\n\nfunction defaultNextActions(scorecard: ReleaseConfidenceScorecard): string[] {\n if (scorecard.promote) return ['Promote the candidate and keep canaries enabled.']\n return scorecard.issues\n .filter((issue) => issue.severity === 'critical')\n .map((issue) => `Resolve ${issue.code}: ${issue.detail}`)\n}\n\nfunction entries(values: Record<string, number>): Array<[string, number]> {\n return Object.entries(values)\n .filter(([, count]) => count > 0)\n .sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))\n}\n\nfunction pct(value: number): string {\n return Number.isFinite(value) ? `${(value * 100).toFixed(1)}%` : 'n/a'\n}\n\nfunction num(value: number): string {\n return Number.isFinite(value) ? value.toFixed(3) : 'n/a'\n}\n","/**\n * Bootstrap-CI promotion gate.\n *\n * In any iterative-improvement loop (GEPA, prompt evolution, dataset\n * curation), the question is \"did this generation actually improve, or are\n * we celebrating noise?\". With small N and noisy outcomes, point-estimate\n * deltas lie. Bootstrap confidence intervals tell the operator whether the\n * delta is real before code or prompts get promoted.\n *\n * This module is pure functions — no I/O, no model calls. Easy to unit-test\n * and to compose into any verdict gate.\n *\n * Default gate:\n * - Bootstrap mean baseline vs candidate (1k resamples).\n * - Compute the delta distribution; pass if the lower CI bound > 0.\n * - Tunable confidence (default 95%) and resample count.\n *\n * Verdict semantics intentionally match the existing `experiments.jsonl`\n * vocabulary:\n * - ADVANCE: candidate's CI lower bound > baseline mean (real win)\n * - KEEP: overlap, but candidate point estimate >= baseline (neutral)\n * - REVERT: candidate's CI upper bound < baseline mean (real regression)\n * - INCONCLUSIVE: not enough samples or CI straddles zero with no signal\n */\n\nexport type Verdict = 'ADVANCE' | 'KEEP' | 'REVERT' | 'INCONCLUSIVE'\n\nexport interface BootstrapResult {\n baselineMean: number\n candidateMean: number\n /** candidateMean - baselineMean, point estimate. */\n delta: number\n /** Lower bound of the (1 - alpha) CI on the delta. */\n ciLower: number\n /** Upper bound of the (1 - alpha) CI on the delta. */\n ciUpper: number\n /** Number of bootstrap resamples used. */\n iterations: number\n alpha: number\n verdict: Verdict\n}\n\nexport interface BootstrapOptions {\n /** Confidence level alpha (default 0.05 → 95% CI). */\n alpha?: number\n /** Number of resamples (default 1000). */\n iterations?: number\n /**\n * Minimum total samples (baseline + candidate) below which we always\n * return INCONCLUSIVE — bootstrap with too few samples is meaningless.\n * Default 6 (combined).\n */\n minTotalSamples?: number\n /** RNG seed for reproducibility. Default: Math.random. */\n seed?: number\n}\n\n/**\n * Compute the bootstrap CI on (candidateMean - baselineMean) and a verdict.\n *\n * Uses simple percentile bootstrap on the difference of resampled means.\n * That's the standard non-parametric primitive — no distributional\n * assumptions, robust to skew, easy to reason about.\n */\nexport function bootstrapCi(\n baseline: number[],\n candidate: number[],\n options: BootstrapOptions = {},\n): BootstrapResult {\n const alpha = options.alpha ?? 0.05\n const iterations = options.iterations ?? 1000\n const minTotal = options.minTotalSamples ?? 6\n const rng = mulberry32(options.seed ?? hashSeed(baseline, candidate))\n\n const baselineMean = mean(baseline)\n const candidateMean = mean(candidate)\n const delta = candidateMean - baselineMean\n\n if (baseline.length + candidate.length < minTotal || baseline.length === 0 || candidate.length === 0) {\n return {\n baselineMean,\n candidateMean,\n delta,\n ciLower: -Infinity,\n ciUpper: Infinity,\n iterations: 0,\n alpha,\n verdict: 'INCONCLUSIVE',\n }\n }\n\n const deltas: number[] = new Array(iterations)\n for (let i = 0; i < iterations; i++) {\n const bResample = resample(baseline, rng)\n const cResample = resample(candidate, rng)\n deltas[i] = mean(cResample) - mean(bResample)\n }\n deltas.sort((a, b) => a - b)\n const lowerIdx = Math.floor((alpha / 2) * iterations)\n const upperIdx = Math.floor((1 - alpha / 2) * iterations) - 1\n const ciLower = deltas[Math.max(0, lowerIdx)]!\n const ciUpper = deltas[Math.min(iterations - 1, upperIdx)]!\n\n let verdict: Verdict\n if (ciLower > 0) verdict = 'ADVANCE'\n else if (ciUpper < 0) verdict = 'REVERT'\n else if (delta >= 0) verdict = 'KEEP'\n else verdict = 'INCONCLUSIVE'\n\n return {\n baselineMean,\n candidateMean,\n delta,\n ciLower,\n ciUpper,\n iterations,\n alpha,\n verdict,\n }\n}\n\nfunction mean(xs: number[]): number {\n if (xs.length === 0) return 0\n let s = 0\n for (const x of xs) s += x\n return s / xs.length\n}\n\nfunction resample(xs: number[], rng: () => number): number[] {\n const out = new Array(xs.length)\n for (let i = 0; i < xs.length; i++) out[i] = xs[Math.floor(rng() * xs.length)]\n return out\n}\n\n/** Mulberry32 — fast deterministic PRNG. Stable across runs given the same seed. */\nfunction mulberry32(seed: number): () => number {\n let t = seed >>> 0\n return () => {\n t += 0x6d2b79f5\n let r = t\n r = Math.imul(r ^ (r >>> 15), r | 1)\n r ^= r + Math.imul(r ^ (r >>> 7), r | 61)\n return ((r ^ (r >>> 14)) >>> 0) / 4294967296\n }\n}\n\n/** Stable seed derived from the inputs — same data → same CI bounds. */\nfunction hashSeed(a: number[], b: number[]): number {\n let h = 2166136261\n for (const x of [...a, ...b]) {\n const view = new Float64Array([x])\n const bytes = new Uint8Array(view.buffer)\n for (const byte of bytes) {\n h ^= byte\n h = Math.imul(h, 16777619)\n }\n }\n return h >>> 0\n}\n\n/**\n * Judge-replay promotion gate.\n *\n * The cheap inner-loop judge that drives an evolution run is by definition\n * fast and noisy. When you're about to promote a winning variant to the\n * canonical default, you want a STRONGER judge (a more expensive model, a\n * human grader, a separately-trained reward model) to confirm the win\n * generalises beyond the inner loop.\n *\n * This helper takes raw winner + baseline outputs, scores both through the\n * stronger judge, and applies `bootstrapCi`. ADVANCE means the stronger\n * judge agrees the winner is real with the configured confidence. Doesn't\n * matter what shape your \"output\" is — pass a string, an object, anything\n * the judge can read.\n */\nexport interface JudgeReplayGateArgs<TOutput> {\n baselineOutputs: TOutput[]\n candidateOutputs: TOutput[]\n /** Stronger judge — async to allow LLM calls. Return a 0..N scalar score. */\n judge: (output: TOutput) => Promise<number> | number\n alpha?: number\n iterations?: number\n /** RNG seed for reproducibility. */\n seed?: number\n /** Maximum concurrent judge calls. Default 4. */\n judgeConcurrency?: number\n}\n\nexport async function judgeReplayGate<TOutput>(\n args: JudgeReplayGateArgs<TOutput>,\n): Promise<BootstrapResult & { baselineSamples: number; candidateSamples: number }> {\n const concurrency = args.judgeConcurrency ?? 4\n const baselineScores = await scoreAll(args.baselineOutputs, args.judge, concurrency)\n const candidateScores = await scoreAll(args.candidateOutputs, args.judge, concurrency)\n const ci = bootstrapCi(baselineScores, candidateScores, {\n ...(args.alpha !== undefined ? { alpha: args.alpha } : {}),\n ...(args.iterations !== undefined ? { iterations: args.iterations } : {}),\n ...(args.seed !== undefined ? { seed: args.seed } : {}),\n })\n return {\n ...ci,\n baselineSamples: baselineScores.length,\n candidateSamples: candidateScores.length,\n }\n}\n\nasync function scoreAll<TOutput>(\n outputs: TOutput[],\n judge: (output: TOutput) => Promise<number> | number,\n concurrency: number,\n): Promise<number[]> {\n const results: number[] = new Array(outputs.length)\n let next = 0\n async function worker(): Promise<void> {\n while (true) {\n const i = next++\n if (i >= outputs.length) return\n const v = await judge(outputs[i]!)\n results[i] = Number.isFinite(v) ? v : 0\n }\n }\n await Promise.all(Array.from({ length: Math.max(1, concurrency) }, () => worker()))\n return results\n}\n"],"mappings":"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","names":["fmt","mean","mean"]}
@@ -5,15 +5,26 @@ var TraceEmitter = class {
5
5
  _runId;
6
6
  now;
7
7
  id;
8
+ hooks;
9
+ hookErrors;
8
10
  constructor(store, options = {}) {
9
11
  this.store = store;
10
12
  this.now = options.now ?? (() => Date.now());
11
13
  this.id = options.id ?? (() => cryptoRandomId());
12
14
  this._runId = options.runId ?? this.id();
15
+ this.hooks = options.onRunComplete ?? [];
16
+ this.hookErrors = options.hookErrors ?? "swallow";
13
17
  }
14
18
  get runId() {
15
19
  return this._runId;
16
20
  }
21
+ get traceStore() {
22
+ return this.store;
23
+ }
24
+ /** Append a hook after construction (e.g. attach the trace analyst). */
25
+ addRunCompleteHook(hook) {
26
+ this.hooks.push(hook);
27
+ }
17
28
  // ── Run lifecycle ──────────────────────────────────────────────────
18
29
  /**
19
30
  * Begin a Run.
@@ -40,13 +51,38 @@ var TraceEmitter = class {
40
51
  async endRun(outcome) {
41
52
  const status = outcome?.pass === false ? "failed" : "completed";
42
53
  await this.store.updateRun(this._runId, { endedAt: this.now(), status, outcome });
54
+ await this.runHooks({ runId: this._runId, emitter: this, store: this.store, outcome, status });
43
55
  }
44
56
  async abortRun(reason) {
57
+ const outcome = { pass: false, notes: reason };
45
58
  await this.store.updateRun(this._runId, {
46
59
  endedAt: this.now(),
47
60
  status: "aborted",
48
- outcome: { pass: false, notes: reason }
61
+ outcome
49
62
  });
63
+ await this.runHooks({ runId: this._runId, emitter: this, store: this.store, outcome, status: "aborted" });
64
+ }
65
+ async runHooks(ctx) {
66
+ for (const hook of this.hooks) {
67
+ try {
68
+ await hook(ctx);
69
+ } catch (err) {
70
+ if (this.hookErrors === "throw") throw err;
71
+ try {
72
+ await this.store.appendEvent({
73
+ eventId: this.id(),
74
+ runId: this._runId,
75
+ kind: "log",
76
+ timestamp: this.now(),
77
+ payload: {
78
+ source: "run_complete_hook",
79
+ error: err instanceof Error ? err.message : String(err)
80
+ }
81
+ });
82
+ } catch {
83
+ }
84
+ }
85
+ }
50
86
  }
51
87
  // ── Generic span ───────────────────────────────────────────────────
52
88
  async span(init) {
@@ -197,4 +233,4 @@ export {
197
233
  TraceEmitter,
198
234
  llmSpanFromProvider
199
235
  };
200
- //# sourceMappingURL=chunk-PKCVBYTQ.js.map
236
+ //# sourceMappingURL=chunk-5IIQKMD5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/trace/emitter.ts"],"sourcesContent":["/**\n * TraceEmitter — hierarchical span builder that auto-parents using an\n * internal stack. One emitter per Run; emitters do NOT share state.\n *\n * Convenience methods (`llm`, `tool`, `retrieval`, `judge`, `sandbox`)\n * return a `SpanHandle` with `.end()` / `.fail()` so callers don't\n * have to thread spanIds manually. For async workflows that can't use\n * the stack (e.g. fan-out parallel calls), pass `parentSpanId`\n * explicitly.\n */\n\nimport type {\n Artifact,\n BudgetLedgerEntry,\n EventKind,\n JudgeSpan,\n LlmSpan,\n Message,\n RetrievalSpan,\n Run,\n RunOutcome,\n SandboxSpan,\n Span,\n SpanKind,\n ToolSpan,\n TraceEvent,\n} from './schema'\nimport type { TraceStore } from './store'\n\nexport interface SpanHandle<S extends Span = Span> {\n span: S\n end(patch?: Partial<S>): Promise<void>\n fail(error: string | Error, patch?: Partial<S>): Promise<void>\n}\n\nexport interface RunCompleteHookContext {\n runId: string\n emitter: TraceEmitter\n store: TraceStore\n /** Outcome the caller passed to `endRun` (undefined for `abortRun`). */\n outcome?: RunOutcome\n /** Final run status. */\n status: 'completed' | 'failed' | 'aborted'\n}\n\nexport type RunCompleteHook = (ctx: RunCompleteHookContext) => Promise<void> | void\n\nexport interface TraceEmitterOptions {\n runId?: string\n /** Inject a clock for deterministic tests. */\n now?: () => number\n /** Inject an id generator for deterministic tests. */\n id?: () => string\n /**\n * Hooks fired after `endRun` / `abortRun` writes the final run state.\n * Designed for trace-analyst auto-execution, integrity assertions, and\n * outbound notifications. Hooks run sequentially in the order supplied.\n *\n * By default a hook that throws is swallowed and logged as a `note` event\n * on the run — auto-orchestration must not crash the underlying flow.\n * Set `hookErrors: 'throw'` to propagate.\n */\n onRunComplete?: RunCompleteHook[]\n /** `'swallow'` (default) | `'throw'`. */\n hookErrors?: 'swallow' | 'throw'\n}\n\nexport class TraceEmitter {\n private store: TraceStore\n private stack: string[] = []\n private _runId: string\n private now: () => number\n private id: () => string\n private hooks: RunCompleteHook[]\n private hookErrors: 'swallow' | 'throw'\n\n constructor(store: TraceStore, options: TraceEmitterOptions = {}) {\n this.store = store\n this.now = options.now ?? (() => Date.now())\n this.id = options.id ?? (() => cryptoRandomId())\n this._runId = options.runId ?? this.id()\n this.hooks = options.onRunComplete ?? []\n this.hookErrors = options.hookErrors ?? 'swallow'\n }\n\n get runId(): string { return this._runId }\n\n get traceStore(): TraceStore { return this.store }\n\n /** Append a hook after construction (e.g. attach the trace analyst). */\n addRunCompleteHook(hook: RunCompleteHook): void {\n this.hooks.push(hook)\n }\n\n // ── Run lifecycle ──────────────────────────────────────────────────\n\n /**\n * Begin a Run.\n *\n * `scenarioId` is required on the persisted Run shape — every Run downstream\n * gets a non-empty scenarioId so filters and aggregations stay simple — but\n * the INPUT here accepts it as optional. When omitted, startRun substitutes\n * a sensible default (`run.layer ?? run.tags?.['kind'] ?? 'runtime'`) so\n * runtime / operator / meta-eval runs that have no curated-scenario corpus\n * to anchor to don't have to invent placeholder strings at the call site.\n */\n async startRun(\n run: Omit<Run, 'runId' | 'scenarioId' | 'startedAt' | 'status'> & { scenarioId?: string },\n ): Promise<Run> {\n const scenarioId =\n run.scenarioId ??\n run.layer ??\n run.tags?.['kind'] ??\n 'runtime'\n const full: Run = {\n ...run,\n scenarioId,\n runId: this._runId,\n startedAt: this.now(),\n status: 'running',\n }\n await this.store.appendRun(full)\n return full\n }\n\n async endRun(outcome?: RunOutcome): Promise<void> {\n const status: 'completed' | 'failed' = outcome?.pass === false ? 'failed' : 'completed'\n await this.store.updateRun(this._runId, { endedAt: this.now(), status, outcome })\n await this.runHooks({ runId: this._runId, emitter: this, store: this.store, outcome, status })\n }\n\n async abortRun(reason: string): Promise<void> {\n const outcome = { pass: false, notes: reason }\n await this.store.updateRun(this._runId, {\n endedAt: this.now(),\n status: 'aborted',\n outcome,\n })\n await this.runHooks({ runId: this._runId, emitter: this, store: this.store, outcome, status: 'aborted' })\n }\n\n private async runHooks(ctx: RunCompleteHookContext): Promise<void> {\n for (const hook of this.hooks) {\n try {\n await hook(ctx)\n } catch (err) {\n if (this.hookErrors === 'throw') throw err\n try {\n await this.store.appendEvent({\n eventId: this.id(),\n runId: this._runId,\n kind: 'log',\n timestamp: this.now(),\n payload: {\n source: 'run_complete_hook',\n error: err instanceof Error ? err.message : String(err),\n },\n })\n } catch {\n // best-effort\n }\n }\n }\n }\n\n // ── Generic span ───────────────────────────────────────────────────\n\n async span<S extends Span = Span>(init: {\n kind: SpanKind\n name: string\n parentSpanId?: string\n attributes?: Record<string, unknown>\n } & Partial<Omit<S, 'spanId' | 'runId' | 'startedAt' | 'kind' | 'name'>>): Promise<SpanHandle<S>> {\n const spanId = this.id()\n const parent = init.parentSpanId ?? this.stack[this.stack.length - 1]\n const span = {\n spanId,\n parentSpanId: parent,\n runId: this._runId,\n startedAt: this.now(),\n ...init,\n } as unknown as S\n await this.store.appendSpan(span)\n this.stack.push(spanId)\n return this.handle<S>(span)\n }\n\n private handle<S extends Span>(span: S): SpanHandle<S> {\n return {\n span,\n end: async (patch?: Partial<S>) => {\n const endedAt = this.now()\n await this.store.updateSpan(span.spanId, { endedAt, status: 'ok', ...patch } as Partial<Span>)\n this.pop(span.spanId)\n },\n fail: async (error: string | Error, patch?: Partial<S>) => {\n const endedAt = this.now()\n const errStr = error instanceof Error ? error.message : error\n await this.store.updateSpan(span.spanId, {\n endedAt,\n status: 'error',\n error: errStr,\n ...patch,\n } as Partial<Span>)\n this.pop(span.spanId)\n },\n }\n }\n\n private pop(spanId: string): void {\n const idx = this.stack.lastIndexOf(spanId)\n if (idx >= 0) this.stack.splice(idx, 1)\n }\n\n // ── Typed span conveniences ────────────────────────────────────────\n\n llm(init: Omit<LlmSpan, 'spanId' | 'runId' | 'kind' | 'startedAt'>): Promise<SpanHandle<LlmSpan>> {\n return this.span<LlmSpan>({ kind: 'llm', ...init })\n }\n\n tool(init: Omit<ToolSpan, 'spanId' | 'runId' | 'kind' | 'startedAt'>): Promise<SpanHandle<ToolSpan>> {\n return this.span<ToolSpan>({ kind: 'tool', ...init })\n }\n\n retrieval(init: Omit<RetrievalSpan, 'spanId' | 'runId' | 'kind' | 'startedAt'>): Promise<SpanHandle<RetrievalSpan>> {\n return this.span<RetrievalSpan>({ kind: 'retrieval', ...init })\n }\n\n async recordJudge(verdict: Omit<JudgeSpan, 'spanId' | 'runId' | 'kind' | 'startedAt' | 'endedAt'>): Promise<JudgeSpan> {\n const spanId = this.id()\n const now = this.now()\n const full: JudgeSpan = {\n spanId,\n runId: this._runId,\n kind: 'judge',\n startedAt: now,\n endedAt: now,\n status: 'ok',\n ...verdict,\n }\n await this.store.appendSpan(full)\n return full\n }\n\n sandbox(init: Omit<SandboxSpan, 'spanId' | 'runId' | 'kind' | 'startedAt'>): Promise<SpanHandle<SandboxSpan>> {\n return this.span<SandboxSpan>({ kind: 'sandbox', ...init })\n }\n\n // ── Events ─────────────────────────────────────────────────────────\n\n async emit(event: { kind: EventKind; spanId?: string; payload?: Record<string, unknown> }): Promise<TraceEvent> {\n const full: TraceEvent = {\n eventId: this.id(),\n runId: this._runId,\n spanId: event.spanId ?? this.stack[this.stack.length - 1],\n kind: event.kind,\n timestamp: this.now(),\n payload: event.payload ?? {},\n }\n await this.store.appendEvent(full)\n return full\n }\n\n // ── Budget ledger ──────────────────────────────────────────────────\n\n async recordBudget(entry: Omit<BudgetLedgerEntry, 'runId' | 'timestamp'> & { timestamp?: number }): Promise<BudgetLedgerEntry> {\n const full: BudgetLedgerEntry = {\n runId: this._runId,\n timestamp: entry.timestamp ?? this.now(),\n dimension: entry.dimension,\n limit: entry.limit,\n consumed: entry.consumed,\n remaining: entry.remaining,\n breached: entry.breached,\n spanId: entry.spanId ?? this.stack[this.stack.length - 1],\n }\n await this.store.appendBudgetEntry(full)\n if (full.breached) {\n await this.emit({\n kind: 'budget_breach',\n spanId: full.spanId,\n payload: { dimension: full.dimension, limit: full.limit, consumed: full.consumed },\n })\n }\n return full\n }\n\n // ── Artifacts ──────────────────────────────────────────────────────\n\n async recordArtifact(artifact: Omit<Artifact, 'artifactId' | 'runId'>): Promise<Artifact> {\n const full: Artifact = { artifactId: this.id(), runId: this._runId, ...artifact }\n await this.store.appendArtifact(full)\n return full\n }\n\n // ── Nested composition ─────────────────────────────────────────────\n\n /**\n * Runs `fn` inside a span; auto-ends on success, auto-fails on throw.\n * Returns the fn's return value. Use this for the 95% case.\n */\n async within<T>(\n init: Parameters<TraceEmitter['span']>[0],\n fn: (handle: SpanHandle) => Promise<T>,\n ): Promise<T> {\n const handle = await this.span(init)\n try {\n const result = await fn(handle)\n await handle.end()\n return result\n } catch (err) {\n await handle.fail(err instanceof Error ? err : String(err))\n throw err\n }\n }\n}\n\n// Helpers -------------------------------------------------------------\n\nfunction cryptoRandomId(): string {\n if (typeof globalThis.crypto?.randomUUID === 'function') return globalThis.crypto.randomUUID()\n return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`\n}\n\n/** Helper to build an LLM span handle args object from a provider-shaped response. */\nexport function llmSpanFromProvider(args: {\n name?: string\n model: string\n messages: Message[]\n output: string\n usage?: { inputTokens?: number; outputTokens?: number; cachedTokens?: number; reasoningTokens?: number }\n costUsd?: number\n finishReason?: string\n}): Omit<LlmSpan, 'spanId' | 'runId' | 'kind' | 'startedAt'> {\n return {\n name: args.name ?? args.model,\n model: args.model,\n messages: args.messages,\n output: args.output,\n inputTokens: args.usage?.inputTokens,\n outputTokens: args.usage?.outputTokens,\n cachedTokens: args.usage?.cachedTokens,\n reasoningTokens: args.usage?.reasoningTokens,\n costUsd: args.costUsd,\n finishReason: args.finishReason,\n }\n}\n"],"mappings":"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","names":[]}
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-YUFXO3TU.js";
4
4
  import {
5
5
  TraceEmitter
6
- } from "./chunk-PKCVBYTQ.js";
6
+ } from "./chunk-5IIQKMD5.js";
7
7
 
8
8
  // src/control-runtime.ts
9
9
  var DEFAULT_BUDGET = {
@@ -1307,4 +1307,4 @@ export {
1307
1307
  runProposeReviewAsControlLoop,
1308
1308
  controlFailureClassFromVerification
1309
1309
  };
1310
- //# sourceMappingURL=chunk-MCMV7DUL.js.map
1310
+ //# sourceMappingURL=chunk-ARZ6BEV6.js.map
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  pairedBootstrap,
6
6
  pairedWilcoxon
7
- } from "./chunk-ODFINDLQ.js";
7
+ } from "./chunk-KRR4VMH7.js";
8
8
 
9
9
  // src/feedback-trajectory.ts
10
10
  var DEFAULT_SPLIT_POLICY = {
@@ -1351,4 +1351,4 @@ export {
1351
1351
  buildReflectionPrompt,
1352
1352
  parseReflectionResponse
1353
1353
  };
1354
- //# sourceMappingURL=chunk-HKYRWNHV.js.map
1354
+ //# sourceMappingURL=chunk-HRZELXCR.js.map
@@ -266,6 +266,15 @@ function requiredSampleSize(opts) {
266
266
  const n = 2 * Math.pow((zAlpha + zBeta) / effect, 2);
267
267
  return Math.ceil(n);
268
268
  }
269
+ function pairedMde(opts) {
270
+ if (!Number.isFinite(opts.nPaired) || opts.nPaired <= 0) return Infinity;
271
+ const alpha = opts.alpha ?? 0.05;
272
+ const power = opts.power ?? 0.8;
273
+ const twoSided = opts.twoSided ?? true;
274
+ const zAlpha = zQuantile(twoSided ? 1 - alpha / 2 : 1 - alpha);
275
+ const zBeta = zQuantile(power);
276
+ return (zAlpha + zBeta) / Math.sqrt(opts.nPaired);
277
+ }
269
278
  function bonferroni(pValues, alpha = 0.05) {
270
279
  const k = pValues.length;
271
280
  const adjusted = pValues.map((p) => Math.min(1, p * k));
@@ -404,10 +413,11 @@ export {
404
413
  wilcoxonSignedRank,
405
414
  cohensD,
406
415
  requiredSampleSize,
416
+ pairedMde,
407
417
  bonferroni,
408
418
  benjaminiHochberg,
409
419
  pairedBootstrap,
410
420
  pairedWilcoxon,
411
421
  bhAdjust
412
422
  };
413
- //# sourceMappingURL=chunk-ODFINDLQ.js.map
423
+ //# sourceMappingURL=chunk-KRR4VMH7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/statistics.ts","../src/power-analysis.ts","../src/paired-stats.ts"],"sourcesContent":["import type { JudgeScore } from './types'\n\n/** Dimensions where lower raw score = better outcome (inverted semantics) */\nconst INVERTED_DIMENSIONS = new Set([\n 'hallucination',\n 'false_confidence',\n 'worst_failure',\n])\n\n/**\n * Normalize scores so all dimensions follow \"higher = better\".\n * Inverted dimensions (hallucination, false_confidence, worst_failure)\n * already use inverted scoring in the prompt (10 = no hallucination),\n * but this function ensures consistency if raw scores leak through.\n */\nexport function normalizeScores(scores: JudgeScore[]): JudgeScore[] {\n return scores.map((s) => {\n if (INVERTED_DIMENSIONS.has(s.dimension)) {\n return s\n }\n return s\n })\n}\n\n/** Weighted mean — falls back to uniform weights when omitted */\nexport function weightedMean(scores: { score: number; weight?: number }[]): number {\n if (scores.length === 0) return 0\n let totalWeight = 0\n let weightedSum = 0\n for (const { score, weight } of scores) {\n const w = weight ?? 1\n weightedSum += score * w\n totalWeight += w\n }\n return totalWeight > 0 ? weightedSum / totalWeight : 0\n}\n\n/** Bootstrap confidence interval */\nexport function confidenceInterval(\n scores: number[],\n confidence = 0.95,\n): { mean: number; lower: number; upper: number } {\n if (scores.length === 0) return { mean: 0, lower: 0, upper: 0 }\n if (scores.length === 1) return { mean: scores[0], lower: scores[0], upper: scores[0] }\n\n const n = scores.length\n const mean = scores.reduce((a, b) => a + b, 0) / n\n\n const B = 1000\n const bootstrapMeans: number[] = []\n\n for (let i = 0; i < B; i++) {\n let sum = 0\n for (let j = 0; j < n; j++) {\n sum += scores[Math.floor(Math.random() * n)]\n }\n bootstrapMeans.push(sum / n)\n }\n\n bootstrapMeans.sort((a, b) => a - b)\n\n const alpha = 1 - confidence\n const lowerIdx = Math.floor((alpha / 2) * B)\n const upperIdx = Math.floor((1 - alpha / 2) * B) - 1\n\n return {\n mean,\n lower: bootstrapMeans[lowerIdx],\n upper: bootstrapMeans[Math.min(upperIdx, B - 1)],\n }\n}\n\n/**\n * Inter-rater reliability — simplified Krippendorff's alpha.\n *\n * Each inner array is one judge's scores for all items.\n * All arrays must have the same length (same items scored).\n */\nexport function interRaterReliability(judgeScores: JudgeScore[][]): number {\n if (judgeScores.length < 2) return 1\n\n // Group scores by dimension across judges\n const dimensionMap = new Map<string, number[][]>()\n for (const judgeSet of judgeScores) {\n for (const s of judgeSet) {\n if (!dimensionMap.has(s.dimension)) dimensionMap.set(s.dimension, [])\n const arr = dimensionMap.get(s.dimension)!\n if (arr.length === 0 || arr[arr.length - 1].length >= judgeScores.length) {\n arr.push([s.score])\n } else {\n arr[arr.length - 1].push(s.score)\n }\n }\n }\n\n // Collect all paired ratings\n const allValues: number[] = []\n const pairDiffs: number[] = []\n\n for (const items of dimensionMap.values()) {\n for (const ratings of items) {\n if (ratings.length < 2) continue\n for (const v of ratings) allValues.push(v)\n for (let i = 0; i < ratings.length; i++) {\n for (let j = i + 1; j < ratings.length; j++) {\n pairDiffs.push((ratings[i] - ratings[j]) ** 2)\n }\n }\n }\n }\n\n if (pairDiffs.length === 0 || allValues.length < 2) return 1\n\n const observedDisagreement = pairDiffs.reduce((a, b) => a + b, 0) / pairDiffs.length\n\n // Expected disagreement from all possible pairings of values\n let expectedDisagreement = 0\n let expectedCount = 0\n for (let i = 0; i < allValues.length; i++) {\n for (let j = i + 1; j < allValues.length; j++) {\n expectedDisagreement += (allValues[i] - allValues[j]) ** 2\n expectedCount++\n }\n }\n expectedDisagreement = expectedCount > 0 ? expectedDisagreement / expectedCount : 0\n\n if (expectedDisagreement === 0) return 1\n return 1 - observedDisagreement / expectedDisagreement\n}\n\n/**\n * Mann-Whitney U test for comparing two independent groups.\n * Returns U statistic and approximate p-value (normal approximation).\n */\nexport function mannWhitneyU(a: number[], b: number[]): { u: number; p: number } {\n if (a.length === 0 || b.length === 0) return { u: 0, p: 1 }\n\n const n1 = a.length\n const n2 = b.length\n\n // Rank all values together\n const combined = [\n ...a.map((v) => ({ v, group: 'a' as const })),\n ...b.map((v) => ({ v, group: 'b' as const })),\n ].sort((x, y) => x.v - y.v)\n\n // Assign ranks with tie handling\n const ranks: number[] = new Array(combined.length)\n let i = 0\n while (i < combined.length) {\n let j = i\n while (j < combined.length && combined[j].v === combined[i].v) j++\n const avgRank = (i + 1 + j) / 2\n for (let k = i; k < j; k++) ranks[k] = avgRank\n i = j\n }\n\n // Sum ranks for group a\n let r1 = 0\n for (let k = 0; k < combined.length; k++) {\n if (combined[k].group === 'a') r1 += ranks[k]\n }\n\n const u1 = r1 - (n1 * (n1 + 1)) / 2\n const u2 = n1 * n2 - u1\n const u = Math.min(u1, u2)\n\n // Normal approximation for p-value\n const mu = (n1 * n2) / 2\n const sigma = Math.sqrt((n1 * n2 * (n1 + n2 + 1)) / 12)\n\n if (sigma === 0) return { u, p: 1 }\n\n const z = Math.abs(u - mu) / sigma\n // Two-tailed p-value from z-score (approximation)\n const p = 2 * (1 - normalCdf(z))\n\n return { u, p }\n}\n\n/** Partial credit: returns 0-1 ratio of current toward target */\nexport function partialCredit(current: number, target: number): number {\n if (target <= 0) return 1\n return Math.min(1, Math.max(0, current / target))\n}\n\n/**\n * Paired t-test — before/after measurements on the SAME items.\n * Pairing removes inter-item variance, giving tighter significance than\n * an unpaired test when comparing prompt v1 vs prompt v2 on identical\n * scenarios.\n */\nexport function pairedTTest(before: number[], after: number[]): { t: number; df: number; p: number } {\n if (before.length !== after.length) {\n throw new Error(`pairedTTest: unequal sample sizes (${before.length} vs ${after.length})`)\n }\n const n = before.length\n if (n < 2) return { t: 0, df: 0, p: 1 }\n\n const diffs = before.map((b, i) => after[i] - b)\n const mean = diffs.reduce((a, b) => a + b, 0) / n\n const variance = diffs.reduce((acc, d) => acc + (d - mean) ** 2, 0) / (n - 1)\n const se = Math.sqrt(variance / n)\n if (se === 0) return { t: mean === 0 ? 0 : Infinity, df: n - 1, p: mean === 0 ? 1 : 0 }\n\n const t = mean / se\n const df = n - 1\n const p = 2 * (1 - studentTCdf(Math.abs(t), df))\n return { t, df, p }\n}\n\n/**\n * Wilcoxon signed-rank test — paired non-parametric alternative.\n * Use when the differences aren't normally distributed.\n */\nexport function wilcoxonSignedRank(before: number[], after: number[]): { w: number; p: number } {\n if (before.length !== after.length) {\n throw new Error(`wilcoxonSignedRank: unequal sample sizes (${before.length} vs ${after.length})`)\n }\n const diffs = before.map((b, i) => after[i] - b).filter((d) => d !== 0)\n const n = diffs.length\n if (n < 6) return { w: 0, p: 1 }\n\n const absRanks = diffs\n .map((d, i) => ({ abs: Math.abs(d), sign: Math.sign(d), i }))\n .sort((a, b) => a.abs - b.abs)\n const ranks: number[] = new Array(n)\n let i = 0\n while (i < n) {\n let j = i\n while (j < n && absRanks[j].abs === absRanks[i].abs) j++\n const avg = (i + 1 + j) / 2\n for (let k = i; k < j; k++) ranks[absRanks[k].i] = avg\n i = j\n }\n let wPlus = 0\n for (let k = 0; k < n; k++) if (diffs[k] > 0) wPlus += ranks[k]\n\n const mean = (n * (n + 1)) / 4\n const variance = (n * (n + 1) * (2 * n + 1)) / 24\n const z = (wPlus - mean) / Math.sqrt(variance)\n const p = 2 * (1 - normalCdf(Math.abs(z)))\n return { w: wPlus, p }\n}\n\n/**\n * Cohen's d — standardized effect size for two independent groups.\n * Positive d means group b has higher mean than group a.\n * Rule of thumb: |d| < 0.2 negligible, 0.2–0.5 small, 0.5–0.8 medium, > 0.8 large.\n */\nexport function cohensD(a: number[], b: number[]): number {\n if (a.length < 2 || b.length < 2) return 0\n const meanA = a.reduce((x, y) => x + y, 0) / a.length\n const meanB = b.reduce((x, y) => x + y, 0) / b.length\n const varA = a.reduce((acc, x) => acc + (x - meanA) ** 2, 0) / (a.length - 1)\n const varB = b.reduce((acc, x) => acc + (x - meanB) ** 2, 0) / (b.length - 1)\n const pooled = Math.sqrt(\n ((a.length - 1) * varA + (b.length - 1) * varB) / (a.length + b.length - 2),\n )\n if (pooled === 0) return 0\n return (meanB - meanA) / pooled\n}\n\n/** Student-t CDF approximation via Abramowitz-Stegun series. */\nfunction studentTCdf(t: number, df: number): number {\n if (df <= 0) return 0.5\n if (df > 100) return normalCdf(t)\n const x = df / (df + t * t)\n const a = df / 2\n const b = 0.5\n const ib = incompleteBeta(x, a, b)\n return t >= 0 ? 1 - 0.5 * ib : 0.5 * ib\n}\n\n/** Regularized incomplete beta function via continued fraction (Lentz). */\nfunction incompleteBeta(x: number, a: number, b: number): number {\n if (x <= 0) return 0\n if (x >= 1) return 1\n const lnBeta = lnGamma(a) + lnGamma(b) - lnGamma(a + b)\n const front = Math.exp(Math.log(x) * a + Math.log(1 - x) * b - lnBeta) / a\n const maxIter = 200\n const eps = 3e-7\n let c = 1\n let d = 1 - ((a + b) * x) / (a + 1)\n if (Math.abs(d) < 1e-30) d = 1e-30\n d = 1 / d\n let f = d\n for (let m = 1; m <= maxIter; m++) {\n const m2 = 2 * m\n let num = (m * (b - m) * x) / ((a + m2 - 1) * (a + m2))\n d = 1 + num * d\n if (Math.abs(d) < 1e-30) d = 1e-30\n c = 1 + num / c\n if (Math.abs(c) < 1e-30) c = 1e-30\n d = 1 / d\n f *= d * c\n num = -((a + m) * (a + b + m) * x) / ((a + m2) * (a + m2 + 1))\n d = 1 + num * d\n if (Math.abs(d) < 1e-30) d = 1e-30\n c = 1 + num / c\n if (Math.abs(c) < 1e-30) c = 1e-30\n d = 1 / d\n const delta = d * c\n f *= delta\n if (Math.abs(delta - 1) < eps) break\n }\n return front * f\n}\n\n/** Lanczos approximation to ln Γ(z). */\nfunction lnGamma(z: number): number {\n const g = 7\n const coefs = [\n 0.99999999999980993, 676.5203681218851, -1259.1392167224028,\n 771.32342877765313, -176.61502916214059, 12.507343278686905,\n -0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7,\n ]\n if (z < 0.5) {\n return Math.log(Math.PI / Math.sin(Math.PI * z)) - lnGamma(1 - z)\n }\n z -= 1\n let x = coefs[0]\n for (let i = 1; i < g + 2; i++) x += coefs[i] / (z + i)\n const t = z + g + 0.5\n return 0.5 * Math.log(2 * Math.PI) + (z + 0.5) * Math.log(t) - t + Math.log(x)\n}\n\n// Standard normal CDF approximation (Abramowitz and Stegun)\nfunction normalCdf(x: number): number {\n const a1 = 0.254829592\n const a2 = -0.284496736\n const a3 = 1.421413741\n const a4 = -1.453152027\n const a5 = 1.061405429\n const p = 0.3275911\n\n const sign = x < 0 ? -1 : 1\n const absX = Math.abs(x)\n const t = 1 / (1 + p * absX)\n const y = 1 - ((((a5 * t + a4) * t + a3) * t + a2) * t + a1) * t * Math.exp(-absX * absX / 2)\n\n return 0.5 * (1 + sign * y)\n}\n","/**\n * Power analysis + multiple-comparison correction.\n *\n * Two jobs:\n * 1. Before running: `requiredSampleSize({ effect, alpha, power })`\n * returns the N per arm needed to detect a given effect size.\n * 2. After running: `benjaminiHochberg(pValues, fdr)` and\n * `bonferroni(pValues, alpha)` correct for multiple pairwise tests\n * so pairwise variant comparisons stay statistically honest.\n *\n * Fixes the correctness bug in 0.2's pairwise optimizer which applied\n * alpha directly across n*(n-1)/2 pairwise tests without correction —\n * dramatically inflating false-positive rate when variants ≥ 3.\n */\n\n/**\n * Required N per arm for a two-sample comparison at target effect size,\n * alpha, and power. Uses the normal-approximation formula:\n *\n * n = 2 * ( (z_{1-α/2} + z_{1-β}) / d )^2\n *\n * where d is Cohen's d. Returns Infinity for effect ≤ 0.\n */\nexport function requiredSampleSize(opts: { effect: number; alpha?: number; power?: number; twoSided?: boolean }): number {\n const effect = opts.effect\n if (!Number.isFinite(effect) || effect <= 0) return Infinity\n const alpha = opts.alpha ?? 0.05\n const power = opts.power ?? 0.8\n const twoSided = opts.twoSided ?? true\n const zAlpha = zQuantile(twoSided ? 1 - alpha / 2 : 1 - alpha)\n const zBeta = zQuantile(power)\n const n = 2 * Math.pow((zAlpha + zBeta) / effect, 2)\n return Math.ceil(n)\n}\n\n/**\n * Minimum detectable paired effect (in standardised units) given a target\n * paired sample size. Closed-form inverse of the paired-t / sign-rank power\n * formula under the normal approximation:\n *\n * d_min = (z_{1-α/2} + z_β) / sqrt(n_paired)\n *\n * Multiply by `sd(deltas)` to convert to score units. Treat as a lower bound:\n * the Wilcoxon signed-rank test and bootstrap CIs have asymptotic relative\n * efficiency below 1 against the t-test on heavy-tailed distributions, so the\n * true achievable MDE in those regimes is somewhat larger.\n */\nexport function pairedMde(opts: { nPaired: number; alpha?: number; power?: number; twoSided?: boolean }): number {\n if (!Number.isFinite(opts.nPaired) || opts.nPaired <= 0) return Infinity\n const alpha = opts.alpha ?? 0.05\n const power = opts.power ?? 0.8\n const twoSided = opts.twoSided ?? true\n const zAlpha = zQuantile(twoSided ? 1 - alpha / 2 : 1 - alpha)\n const zBeta = zQuantile(power)\n return (zAlpha + zBeta) / Math.sqrt(opts.nPaired)\n}\n\n/** Bonferroni adjustment: multiply every p-value by the number of tests, clamp at 1. */\nexport function bonferroni(pValues: number[], alpha = 0.05): { adjusted: number[]; significant: boolean[] } {\n const k = pValues.length\n const adjusted = pValues.map((p) => Math.min(1, p * k))\n const significant = adjusted.map((p) => p < alpha)\n return { adjusted, significant }\n}\n\n/**\n * Benjamini–Hochberg false discovery rate. Returns adjusted q-values and\n * significance at the target FDR. Properly handles ties and preserves\n * monotonicity of q-values.\n */\nexport function benjaminiHochberg(pValues: number[], fdr = 0.05): { qValues: number[]; significant: boolean[] } {\n const n = pValues.length\n if (n === 0) return { qValues: [], significant: [] }\n const indexed = pValues.map((p, i) => ({ p, i })).sort((a, b) => a.p - b.p)\n const q = new Array<number>(n)\n // Ranks are 1-based; q_i = p_i * n / rank_i\n let minRight = 1\n for (let k = n - 1; k >= 0; k--) {\n const rank = k + 1\n const raw = indexed[k].p * n / rank\n const bounded = Math.min(minRight, raw)\n minRight = bounded\n q[indexed[k].i] = Math.min(1, bounded)\n }\n const significant = q.map((v) => v < fdr)\n return { qValues: q, significant }\n}\n\n/** Standard-normal inverse CDF (Acklam approximation). */\nfunction zQuantile(p: number): number {\n if (p <= 0 || p >= 1) {\n if (p === 0) return -Infinity\n if (p === 1) return Infinity\n return NaN\n }\n const a = [-3.969683028665376e1, 2.209460984245205e2, -2.759285104469687e2, 1.383577518672690e2, -3.066479806614716e1, 2.506628277459239]\n const b = [-5.447609879822406e1, 1.615858368580409e2, -1.556989798598866e2, 6.680131188771972e1, -1.328068155288572e1]\n const c = [-7.784894002430293e-3, -3.223964580411365e-1, -2.400758277161838, -2.549732539343734, 4.374664141464968, 2.938163982698783]\n const d = [7.784695709041462e-3, 3.224671290700398e-1, 2.445134137142996, 3.754408661907416]\n const pLow = 0.02425\n const pHigh = 1 - pLow\n let q: number\n let r: number\n if (p < pLow) {\n q = Math.sqrt(-2 * Math.log(p))\n return (((((c[0] * q + c[1]) * q + c[2]) * q + c[3]) * q + c[4]) * q + c[5]) /\n ((((d[0] * q + d[1]) * q + d[2]) * q + d[3]) * q + 1)\n }\n if (p <= pHigh) {\n q = p - 0.5\n r = q * q\n return (((((a[0] * r + a[1]) * r + a[2]) * r + a[3]) * r + a[4]) * r + a[5]) * q /\n (((((b[0] * r + b[1]) * r + b[2]) * r + b[3]) * r + b[4]) * r + 1)\n }\n q = Math.sqrt(-2 * Math.log(1 - p))\n return -(((((c[0] * q + c[1]) * q + c[2]) * q + c[3]) * q + c[4]) * q + c[5]) /\n ((((d[0] * q + d[1]) * q + d[2]) * q + d[3]) * q + 1)\n}\n","/**\n * Paper-grade paired statistics for held-out promotion gates.\n *\n * The promotion gate (`HeldOutGate`) needs three things:\n *\n * 1. A bootstrap confidence interval on the per-item paired delta\n * (`pairedBootstrap`). Median delta is the headline number; the\n * CI lower bound is what the gate checks against `pairedDeltaThreshold`.\n * 2. A non-parametric significance test on the paired deltas\n * (`pairedWilcoxon` — re-export of `wilcoxonSignedRank` under the\n * paper-style name).\n * 3. False-discovery-rate correction across simultaneously-tested\n * candidate variants (`bhAdjust` — re-export of `benjaminiHochberg`).\n *\n * Why a separate file: every existing primitive lives in `statistics.ts`\n * (general) or `power-analysis.ts` (correction). Paired-bootstrap is\n * paired-only, paper-grade, and load-bearing for the promotion gate.\n * Putting it next to `statistics.ts` would require editing that file;\n * the brief forbids that. New file, new exports, no surface change.\n */\n\nimport { wilcoxonSignedRank } from './statistics'\nimport { benjaminiHochberg } from './power-analysis'\n\nexport interface PairedBootstrapResult {\n /** Number of paired observations (after dropping unequal lengths is rejected). */\n n: number\n /** Median of paired deltas (after − before). */\n median: number\n /** Mean of paired deltas. */\n mean: number\n /** Lower bound of the bootstrap CI on the median delta. */\n low: number\n /** Upper bound of the bootstrap CI on the median delta. */\n high: number\n /** Confidence level used (e.g. 0.95). */\n confidence: number\n /** Number of bootstrap resamples used. */\n resamples: number\n}\n\nexport interface PairedBootstrapOptions {\n /** Confidence level. Default 0.95. */\n confidence?: number\n /** Bootstrap resample count. Default 2000. */\n resamples?: number\n /** Statistic to bootstrap. Default 'median'. */\n statistic?: 'median' | 'mean'\n /** Deterministic seed. If omitted, uses Math.random(). */\n seed?: number\n}\n\n/**\n * Paired bootstrap on (after - before) deltas. Returns a CI on the\n * chosen statistic (median by default). Pairs are resampled with\n * replacement. The lower bound is what the promotion gate checks: if\n * `low > pairedDeltaThreshold`, the gain is real at the chosen\n * confidence level.\n *\n * Throws on unequal sample sizes — caller must align pairs upstream.\n */\nexport function pairedBootstrap(\n before: number[],\n after: number[],\n opts: PairedBootstrapOptions = {},\n): PairedBootstrapResult {\n if (before.length !== after.length) {\n throw new Error(\n `pairedBootstrap: unequal sample sizes (${before.length} vs ${after.length})`,\n )\n }\n const confidence = opts.confidence ?? 0.95\n const resamples = opts.resamples ?? 2000\n const statistic = opts.statistic ?? 'median'\n if (confidence <= 0 || confidence >= 1) {\n throw new Error(`pairedBootstrap: confidence must be in (0,1), got ${confidence}`)\n }\n\n const n = before.length\n const deltas = before.map((b, i) => after[i]! - b)\n if (n === 0) {\n return { n: 0, median: 0, mean: 0, low: 0, high: 0, confidence, resamples }\n }\n if (n === 1) {\n const d = deltas[0]!\n return { n: 1, median: d, mean: d, low: d, high: d, confidence, resamples }\n }\n\n const rng = makeRng(opts.seed)\n const samples = new Array<number>(resamples)\n for (let b = 0; b < resamples; b++) {\n let acc: number[] | null = null\n if (statistic === 'mean') {\n let sum = 0\n for (let k = 0; k < n; k++) {\n sum += deltas[Math.floor(rng() * n)]!\n }\n samples[b] = sum / n\n } else {\n acc = new Array<number>(n)\n for (let k = 0; k < n; k++) {\n acc[k] = deltas[Math.floor(rng() * n)]!\n }\n samples[b] = medianInPlace(acc)\n }\n }\n samples.sort((a, b) => a - b)\n\n const alpha = 1 - confidence\n const lowIdx = Math.floor((alpha / 2) * resamples)\n const highIdx = Math.min(resamples - 1, Math.ceil((1 - alpha / 2) * resamples) - 1)\n\n return {\n n,\n median: medianInPlace([...deltas]),\n mean: deltas.reduce((s, x) => s + x, 0) / n,\n low: samples[lowIdx]!,\n high: samples[Math.max(highIdx, lowIdx)]!,\n confidence,\n resamples,\n }\n}\n\n/**\n * Paper-style alias for `wilcoxonSignedRank`. The signed-rank test on\n * paired deltas is the standard non-parametric significance test for\n * \"candidate beats baseline on matched items.\" Use alongside the\n * bootstrap CI: bootstrap gives effect size, Wilcoxon gives p.\n */\nexport function pairedWilcoxon(before: number[], after: number[]): { w: number; p: number } {\n return wilcoxonSignedRank(before, after)\n}\n\n/**\n * Paper-style alias for `benjaminiHochberg`. Use to correct p-values\n * across multiple candidate-vs-baseline comparisons run in the same\n * promotion sweep. Returns BH-adjusted q-values and significance at\n * the requested FDR (default 0.05).\n */\nexport function bhAdjust(pValues: number[], fdr = 0.05): { qValues: number[]; significant: boolean[] } {\n return benjaminiHochberg(pValues, fdr)\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────\n\nfunction medianInPlace(xs: number[]): number {\n if (xs.length === 0) return 0\n xs.sort((a, b) => a - b)\n const mid = Math.floor(xs.length / 2)\n return xs.length % 2 === 0 ? (xs[mid - 1]! + xs[mid]!) / 2 : xs[mid]!\n}\n\n/**\n * Tiny seedable PRNG (mulberry32). Deterministic given a seed; falls\n * back to Math.random when seed is omitted. Adequate for bootstrap\n * resampling — not cryptographic.\n */\nfunction makeRng(seed: number | undefined): () => number {\n if (seed === undefined) return Math.random\n let s = (seed | 0) || 0x9e3779b9\n return () => {\n s = (s + 0x6d2b79f5) | 0\n let t = s\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n}\n"],"mappings":"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","names":["i"]}