@tangle-network/agent-eval 0.117.1 → 0.118.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 (143) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/analyst/index.d.ts +2772 -21
  3. package/dist/analyst/index.js +7 -6
  4. package/dist/analyst/index.js.map +1 -1
  5. package/dist/belief-state/index.d.ts +706 -10
  6. package/dist/belief-state/index.js +2 -1
  7. package/dist/belief-state/index.js.map +1 -1
  8. package/dist/benchmarks/index.d.ts +958 -14
  9. package/dist/benchmarks/index.js +12 -10
  10. package/dist/builder-eval/index.d.ts +449 -4
  11. package/dist/builder-eval/index.js +4 -3
  12. package/dist/builder-eval/index.js.map +1 -1
  13. package/dist/campaign/index.d.ts +4275 -73
  14. package/dist/campaign/index.js +12 -10
  15. package/dist/{chunk-VF3XSYTI.js → chunk-33JA4TFA.js} +6 -6
  16. package/dist/{chunk-4JLWXDYA.js → chunk-3EHHMC6E.js} +2 -2
  17. package/dist/{chunk-CCZIVI3F.js → chunk-BFW56GTT.js} +2 -2
  18. package/dist/{chunk-YZPO4UHR.js → chunk-DP3BBMYJ.js} +100 -143
  19. package/dist/chunk-DP3BBMYJ.js.map +1 -0
  20. package/dist/{chunk-E4BUPP7Z.js → chunk-HKUCJ437.js} +38 -66
  21. package/dist/chunk-HKUCJ437.js.map +1 -0
  22. package/dist/{chunk-HZHNRYHK.js → chunk-K6N6XJJX.js} +2 -2
  23. package/dist/chunk-KSDQVPLR.js +286 -0
  24. package/dist/chunk-KSDQVPLR.js.map +1 -0
  25. package/dist/chunk-MA6HLL3S.js +65 -0
  26. package/dist/chunk-MA6HLL3S.js.map +1 -0
  27. package/dist/{chunk-MGEHEHSN.js → chunk-OIIMMLRB.js} +11 -11
  28. package/dist/{chunk-DXZRATT5.js → chunk-OYZAPX5G.js} +3 -3
  29. package/dist/chunk-PXE2VKMX.js +140 -0
  30. package/dist/chunk-PXE2VKMX.js.map +1 -0
  31. package/dist/{chunk-JSJZ4PJ6.js → chunk-Q442S5AS.js} +17 -17
  32. package/dist/{chunk-ODVOOEWQ.js → chunk-QBRSJK47.js} +2 -2
  33. package/dist/{chunk-S2F4J57L.js → chunk-QKEGNI5B.js} +77 -32
  34. package/dist/chunk-QKEGNI5B.js.map +1 -0
  35. package/dist/{chunk-5UF54T55.js → chunk-S3UZOQ5Y.js} +34 -7
  36. package/dist/chunk-S3UZOQ5Y.js.map +1 -0
  37. package/dist/{chunk-FQNLDL4D.js → chunk-SVH2ANFD.js} +136 -4
  38. package/dist/chunk-SVH2ANFD.js.map +1 -0
  39. package/dist/{chunk-GQCZRZ7L.js → chunk-U5CHZ5M3.js} +9 -9
  40. package/dist/{chunk-TVVP3ZZQ.js → chunk-VQMK5FMP.js} +2 -1
  41. package/dist/{chunk-TVVP3ZZQ.js.map → chunk-VQMK5FMP.js.map} +1 -1
  42. package/dist/chunk-WDHBCA3M.js +31 -0
  43. package/dist/chunk-WDHBCA3M.js.map +1 -0
  44. package/dist/{chunk-HQPHZGL6.js → chunk-YLMUS4MM.js} +9 -9
  45. package/dist/{chunk-LQUTGLOZ.js → chunk-ZET2UAYW.js} +15 -65
  46. package/dist/chunk-ZET2UAYW.js.map +1 -0
  47. package/dist/contract/index.d.ts +4012 -38
  48. package/dist/contract/index.js +56 -29
  49. package/dist/contract/index.js.map +1 -1
  50. package/dist/control.d.ts +1013 -9
  51. package/dist/control.js +4 -3
  52. package/dist/fuzz.d.ts +194 -4
  53. package/dist/fuzz.js +3 -3
  54. package/dist/hosted/index.d.ts +498 -17
  55. package/dist/index.d.ts +10982 -1286
  56. package/dist/index.js +97 -80
  57. package/dist/index.js.map +1 -1
  58. package/dist/matrix/index.d.ts +139 -4
  59. package/dist/meta-eval/index.d.ts +862 -15
  60. package/dist/meta-eval/index.js +2 -1
  61. package/dist/meta-eval/index.js.map +1 -1
  62. package/dist/multishot/index.d.ts +214 -14
  63. package/dist/openapi.json +1 -1
  64. package/dist/pipelines/index.d.ts +392 -7
  65. package/dist/pipelines/index.js +5 -3
  66. package/dist/pipelines/index.js.map +1 -1
  67. package/dist/reporting.d.ts +1277 -17
  68. package/dist/rl.d.ts +2359 -28
  69. package/dist/rl.js +6 -5
  70. package/dist/rl.js.map +1 -1
  71. package/dist/storyboard/index.d.ts +86 -1
  72. package/dist/trace-attributes.d.ts +16 -0
  73. package/dist/trace-attributes.js +32 -0
  74. package/dist/trace-attributes.js.map +1 -0
  75. package/dist/traces.d.ts +1970 -697
  76. package/dist/traces.js +49 -32
  77. package/dist/wire/index.d.ts +655 -9
  78. package/docs/insight-report.md +44 -0
  79. package/package.json +9 -3
  80. package/dist/adversarial-B7loGVVX.d.ts +0 -19
  81. package/dist/analyst-C8HHvfJp.d.ts +0 -88
  82. package/dist/analyze-runs--2x39HZ7.d.ts +0 -81
  83. package/dist/baseline-DKq3gJpP.d.ts +0 -141
  84. package/dist/calibration-C8MTS7cw.d.ts +0 -101
  85. package/dist/chunk-5UF54T55.js.map +0 -1
  86. package/dist/chunk-E4BUPP7Z.js.map +0 -1
  87. package/dist/chunk-FQNLDL4D.js.map +0 -1
  88. package/dist/chunk-LQUTGLOZ.js.map +0 -1
  89. package/dist/chunk-S2F4J57L.js.map +0 -1
  90. package/dist/chunk-YZPO4UHR.js.map +0 -1
  91. package/dist/code-agent-session-CjZsVd19.d.ts +0 -87
  92. package/dist/control-6vuGfmDH.d.ts +0 -258
  93. package/dist/cost-ledger-DWy3XdJc.d.ts +0 -183
  94. package/dist/dataset-NENEzRgk.d.ts +0 -115
  95. package/dist/default-registry-DaK8b3fv.d.ts +0 -155
  96. package/dist/emitter-CjD7vUwv.d.ts +0 -122
  97. package/dist/errors-oeQrLqXC.d.ts +0 -74
  98. package/dist/failure-cluster-DOAcSJ87.d.ts +0 -76
  99. package/dist/feedback-trajectory-BUnM58xL.d.ts +0 -348
  100. package/dist/gepa-eESocoDi.d.ts +0 -642
  101. package/dist/index-PdX4VnPA.d.ts +0 -423
  102. package/dist/insight-report-DY4nDW9Q.d.ts +0 -310
  103. package/dist/integrity-DqlBiLyK.d.ts +0 -81
  104. package/dist/judge-calibration-7C-IDmKr.d.ts +0 -145
  105. package/dist/kind-factory-ClZmO25A.d.ts +0 -171
  106. package/dist/llm-client-qoDd18Qz.d.ts +0 -289
  107. package/dist/multi-layer-verifier-BsqKuLyN.d.ts +0 -150
  108. package/dist/off-policy-DiwuKKg7.d.ts +0 -132
  109. package/dist/outcome-store-rnXLEqSn.d.ts +0 -63
  110. package/dist/policy-edit-wG9uFEFm.d.ts +0 -455
  111. package/dist/pre-registration-BWQhJ3vz.d.ts +0 -761
  112. package/dist/provenance-DpjwyseI.d.ts +0 -541
  113. package/dist/query-CF7PG61p.d.ts +0 -35
  114. package/dist/raw-provider-sink-C46HDghv.d.ts +0 -132
  115. package/dist/release-report-C8G2i5Xi.d.ts +0 -236
  116. package/dist/researcher-C8XyxQsu.d.ts +0 -387
  117. package/dist/rubric-predictive-validity-p49lLVrE.d.ts +0 -105
  118. package/dist/run-record-BDH49H2E.d.ts +0 -360
  119. package/dist/runtime-trajectory-DGBIUt4B.d.ts +0 -49
  120. package/dist/schema-B3Q3l9Z_.d.ts +0 -201
  121. package/dist/semantic-concept-judge-CXnPEJbf.d.ts +0 -723
  122. package/dist/sequential-5iSVfzl2.d.ts +0 -139
  123. package/dist/series-convergence-D5OWMBg6.d.ts +0 -33
  124. package/dist/statistics-KUnG73jH.d.ts +0 -494
  125. package/dist/storage-DrX3v_5B.d.ts +0 -50
  126. package/dist/store-C1YxJDEK.d.ts +0 -248
  127. package/dist/store-DGqD0Pyo.d.ts +0 -116
  128. package/dist/summary-report-C5bKFfm-.d.ts +0 -445
  129. package/dist/test-graded-scenario-B0ybnPY7.d.ts +0 -166
  130. package/dist/types-BSw1rOUB.d.ts +0 -634
  131. package/dist/types-BUxNaJ8c.d.ts +0 -108
  132. package/dist/types-BkfcQnxV.d.ts +0 -313
  133. package/dist/verdict-C9MlYujm.d.ts +0 -35
  134. /package/dist/{chunk-VF3XSYTI.js.map → chunk-33JA4TFA.js.map} +0 -0
  135. /package/dist/{chunk-4JLWXDYA.js.map → chunk-3EHHMC6E.js.map} +0 -0
  136. /package/dist/{chunk-CCZIVI3F.js.map → chunk-BFW56GTT.js.map} +0 -0
  137. /package/dist/{chunk-HZHNRYHK.js.map → chunk-K6N6XJJX.js.map} +0 -0
  138. /package/dist/{chunk-MGEHEHSN.js.map → chunk-OIIMMLRB.js.map} +0 -0
  139. /package/dist/{chunk-DXZRATT5.js.map → chunk-OYZAPX5G.js.map} +0 -0
  140. /package/dist/{chunk-JSJZ4PJ6.js.map → chunk-Q442S5AS.js.map} +0 -0
  141. /package/dist/{chunk-ODVOOEWQ.js.map → chunk-QBRSJK47.js.map} +0 -0
  142. /package/dist/{chunk-GQCZRZ7L.js.map → chunk-U5CHZ5M3.js.map} +0 -0
  143. /package/dist/{chunk-HQPHZGL6.js.map → chunk-YLMUS4MM.js.map} +0 -0
@@ -1,20 +1,501 @@
1
- import { M as MutableSurface, d as GateDecision } from '../types-BSw1rOUB.js';
2
- import { I as InsightReport } from '../insight-report-DY4nDW9Q.js';
3
- import '../policy-edit-wG9uFEFm.js';
4
- import '../run-record-BDH49H2E.js';
5
- import '@tangle-network/agent-interface';
6
- import '../errors-oeQrLqXC.js';
7
- import '../schema-B3Q3l9Z_.js';
8
- import '../store-C1YxJDEK.js';
9
- import '../types-BkfcQnxV.js';
10
- import '../cost-ledger-DWy3XdJc.js';
11
- import '@tangle-network/tcloud';
12
- import '../llm-client-qoDd18Qz.js';
13
- import '../raw-provider-sink-C46HDghv.js';
14
- import '../summary-report-C5bKFfm-.js';
15
- import '../failure-cluster-DOAcSJ87.js';
16
- import '../store-DGqD0Pyo.js';
17
- import '../judge-calibration-7C-IDmKr.js';
1
+ /**
2
+ * Pass A substrate types `runCampaign` is the one primitive every
3
+ * eval flow composes from. Three contracts in this file:
4
+ *
5
+ * - `Scenario` input set
6
+ * - `DispatchFn` how to run one scenario → artifact
7
+ * - `CampaignResult` defined output schema (the contract downstream tools depend on)
8
+ *
9
+ * Three more lifted from earlier substrate work (re-exported):
10
+ *
11
+ * - `JudgeConfig` pluggable dimensional scorer (0.38)
12
+ * - `Mutator` optimization-loop surface mutator
13
+ * - `Gate` promotion gate (`HeldOutGate` and friends adapt to this)
14
+ *
15
+ * No new architecture vs 0.38 — Pass A formalizes the shapes so consumers
16
+ * can build dashboards / CI gates / regression diffs against a stable schema.
17
+ */
18
+
19
+ /** A tier-4 code surface — a finalized candidate change to the agent's
20
+ * IMPLEMENTATION, not its prompt. Produced by autoresearch (reads codebase +
21
+ * trace findings → opens a worktree). `worktreeRef` locates the candidate;
22
+ * the exact commits, tree, and binary-patch digest identify it. See the
23
+ * improvement-tier table in `docs/design/loop-taxonomy.md`. */
24
+ interface CodeSurface {
25
+ readonly kind: 'code';
26
+ /** Worktree path or git ref holding the candidate code change. This is a
27
+ * mutable locator and is deliberately excluded from content hashes. */
28
+ readonly worktreeRef: string;
29
+ /** Human-readable ref the worktree was forked from. Not identity-bearing. */
30
+ readonly baseRef: string;
31
+ /** Exact commit the candidate was forked from. */
32
+ readonly baseCommit: string;
33
+ /** Exact tree object for `baseCommit`. */
34
+ readonly baseTree: string;
35
+ /** Exact finalized candidate commit. */
36
+ readonly candidateCommit: string;
37
+ /** Exact tree object for `candidateCommit`. */
38
+ readonly candidateTree: string;
39
+ /** Identity of the exact patch artifact. The deployable candidate bundle
40
+ * carries the same descriptor plus its base64-encoded content. */
41
+ readonly patch: {
42
+ readonly format: 'git-diff-binary';
43
+ readonly sha256: `sha256:${string}`;
44
+ readonly byteLength: number;
45
+ };
46
+ /** Human summary of what changed — rendered into the auto-PR body. */
47
+ readonly summary?: string;
48
+ }
49
+ /** The mutable surface a proposer changes. Tiers (see
50
+ * `docs/design/loop-taxonomy.md`):
51
+ * - `string` — tiers 1-2: system-prompt addendum / serialized tool
52
+ * config. Cheap, reversible, text-diffable.
53
+ * - `CodeSurface` — tier 4: an implementation change behind a worktree ref.
54
+ * Tier 3 (knowledge) is owned by agent-knowledge and rides its own adapter,
55
+ * not this type. */
56
+ type MutableSurface = string | CodeSurface;
57
+ /** Five-valued verdict taxonomy (MOSS-paper alignment). */
58
+ type GateDecision = 'ship' | 'hold' | 'need_more_work' | 'model_ceiling' | 'arch_ceiling';
59
+
60
+ /**
61
+ * Reporting helpers — production summaries and paper-quality figures — sit alongside `reporter.ts` rather
62
+ * than replacing it.
63
+ *
64
+ * Three artefacts:
65
+ *
66
+ * - `summaryTable` Markdown table of per-candidate means,
67
+ * 95% bootstrap CIs, BH-adjusted Wilcoxon
68
+ * p-values, and Cohen's d versus a
69
+ * comparator candidate.
70
+ * - `paretoChart` Abstract spec for a cost vs quality
71
+ * scatter, with gate decisions overlaid.
72
+ * Returns numbers + labels — caller
73
+ * chooses the plotting library.
74
+ * - `gainHistogram`
75
+ * Per-item paired holdout deltas as a
76
+ * histogram spec (bins + counts + median +
77
+ * CI). Same "data, not images" contract.
78
+ *
79
+ * The figure types are PlotSpecs — JSON-friendly, library-agnostic.
80
+ * They aren't React components and they aren't PNGs; they are
81
+ * what you'd hand to vega-lite, plotly, matplotlib, or your own
82
+ * Canvas renderer to draw the actual figure.
83
+ */
84
+
85
+ interface ParetoPoint {
86
+ candidateId: string;
87
+ /** Mean USD cost per run on the chosen split. */
88
+ cost: number;
89
+ /** Mean score on the chosen split. */
90
+ quality: number;
91
+ /** Number of runs that informed this point. */
92
+ n: number;
93
+ /** Whether this candidate is on the Pareto frontier — high
94
+ * quality, low cost, no dominator. */
95
+ onFrontier: boolean;
96
+ /** Optional gate verdict for this candidate, if a `GateDecision`
97
+ * for it was passed in. */
98
+ gate?: 'promote' | 'reject_few_runs' | 'reject_negative_delta' | 'reject_overfit_gap' | null;
99
+ }
100
+ interface ParetoFigureSpec {
101
+ kind: 'pareto-cost-quality';
102
+ split: 'search' | 'holdout';
103
+ points: ParetoPoint[];
104
+ axes: {
105
+ x: 'costUsd';
106
+ y: 'score';
107
+ };
108
+ }
109
+ interface GainDistributionBin {
110
+ /** Inclusive lower edge. */
111
+ lo: number;
112
+ /** Exclusive upper edge (or inclusive if it's the last bin). */
113
+ hi: number;
114
+ /** Number of pairs whose delta lands in this bin. */
115
+ count: number;
116
+ }
117
+
118
+ interface ContinuousAgreement {
119
+ /** Cohen's κ_w with quadratic weights, computed on raw [0,1] scores. */
120
+ weightedKappa: number;
121
+ /** ICC(2,1): two-way random effects, absolute agreement, single rater. */
122
+ icc: number;
123
+ /** Pearson product-moment correlation (averaged over rater pairs if N>2). */
124
+ pearson: number;
125
+ /** Spearman rank correlation (averaged over rater pairs if N>2). */
126
+ spearman: number;
127
+ /** 95% bootstrap percentile CIs over items. */
128
+ ci: {
129
+ icc: [number, number];
130
+ weightedKappa: [number, number];
131
+ };
132
+ /** Number of complete items (no NaN across raters). */
133
+ n: number;
134
+ /** Number of raters. */
135
+ raters: number;
136
+ }
137
+
138
+ /**
139
+ * # InsightReport — the rigorous decision packet for any set of agent runs.
140
+ *
141
+ * Returned by `analyzeRuns()` and embedded in `SelfImproveResult.insight` +
142
+ * the hosted-tier `EvalRunEvent.insightReport`. One shape across two surfaces:
143
+ *
144
+ * - **Customer who has a closed loop** (`selfImprove`): the report ships
145
+ * with the loop output. Their dashboard renders ship/hold + lift CI +
146
+ * calibration + cluster + Pareto in one packet.
147
+ * - **Customer who has observed runs but no loop** (`analyzeRuns` directly):
148
+ * same packet from a `RunRecord[]` they already have — production traces,
149
+ * approve/reject corpus, CSV gold set.
150
+ *
151
+ * Every field is optional except the distributional summary — fields are
152
+ * populated when the input data supports them:
153
+ *
154
+ * - `lift` requires both baseline and candidate splits to be present.
155
+ * - `interRater` requires multi-rater feedback (≥2 raters per run).
156
+ * - `judges` populates per-judge stats only when the run records carry
157
+ * `outcome.judgeScores`.
158
+ * - `failureClusters` requires the optional `analystRegistry` to be wired.
159
+ * - `contamination` requires canary scenarios to be passed in.
160
+ * - `outcomeCorrelation` requires a downstream outcome signal.
161
+ * - `sequential` requires the run set to be ordered (treats them as a
162
+ * stream and emits an anytime-valid interim decision).
163
+ *
164
+ * Consumers read the `recommendations` array first — that's the
165
+ * actionable layer, ranked by priority. The numeric sections back it up.
166
+ */
167
+
168
+ interface InsightReport {
169
+ /** Number of runs analyzed. */
170
+ n: number;
171
+ /** Runtime facts carried by the run records. These describe execution,
172
+ * not task quality: duration, queueing, token categories, models, and
173
+ * explicitly recorded failures. */
174
+ execution: ExecutionInsight;
175
+ /** Composite-score distribution across all runs. Always present. */
176
+ composite: ScalarDistribution;
177
+ /** Per-dimension distributions for every dimension that appeared in any
178
+ * run's judge scores. Empty when no judge scores were recorded. */
179
+ perDimension: Record<string, ScalarDistribution>;
180
+ /** Cost/quality distribution and Pareto frontier. */
181
+ costQuality: {
182
+ cost: ScalarDistribution;
183
+ pareto: ParetoFigureSpec;
184
+ /** Cost source coverage. `uncaptured` rows are excluded from the USD
185
+ * distribution and Pareto chart; observed and estimated totals remain
186
+ * separate so reports never present estimates as billed spend. */
187
+ provenance?: CostProvenanceSummary;
188
+ /** Set when the cost/quality view is degraded because the input data
189
+ * doesn't fully support it — e.g. all `costUsd` were zero, or only a
190
+ * single candidate appears (so the Pareto is a single point). The
191
+ * named fields name the degraded sub-view, free-text the reason. */
192
+ degraded?: {
193
+ cost?: string;
194
+ pareto?: string;
195
+ };
196
+ };
197
+ /** Per-judge calibration + bias detection. Populated for every judge name
198
+ * that appears in `outcome.judgeScores`. Bias fields require either a
199
+ * gold reference or multi-rater data. */
200
+ judges: Record<string, JudgeInsight>;
201
+ /** Inter-rater agreement when multiple judges scored the same runs.
202
+ * Includes pairwise kappa and the specific run ids where raters
203
+ * disagree — the cases worth a human meeting. */
204
+ interRater?: InterRaterInsight;
205
+ /** Pairwise lift (baseline → candidate) with bootstrap CI. Present when
206
+ * `RunRecord.splitTag` includes both `holdout` and search/dev splits,
207
+ * or when caller passes an explicit baseline/candidate split. */
208
+ lift?: LiftInsight;
209
+ /** Failure clusters with exemplars. Populated when an AnalystRegistry
210
+ * is wired in `analyzeRuns({ analyst })`. */
211
+ failureClusters?: FailureClusterInsight;
212
+ /** Canary leak count + holdout audit status. Populated when canary
213
+ * scenarios are passed in. */
214
+ contamination?: ContaminationInsight;
215
+ /** Correlation between judge composite and a downstream outcome the
216
+ * caller supplies (engagement, revenue, downstream pass rate, etc.).
217
+ * When present, the optional reward model is the model that maps
218
+ * judge scores → predicted outcome. */
219
+ outcomeCorrelation?: OutcomeCorrelationInsight;
220
+ /** Aggregate release-readiness summary. A consumer needing the full
221
+ * substrate `ReleaseConfidenceScorecard` (SLO-axis evaluation,
222
+ * ActionableSideInfo bag) calls `evaluateReleaseConfidence()` directly;
223
+ * this summary captures the analyzeRuns-derived axes. */
224
+ release: ReleaseSummary;
225
+ /** Delta vs a prior period when `baselineRuns` is passed. Per-metric
226
+ * current vs baseline with Welch CI + Cohen's d + significance flag.
227
+ * Answers "did my last change help?" — the customer-conversion question.
228
+ * Surfaced metrics: composite, cost, duration, tokenUsage, plus any
229
+ * per-dimension judge metric present in both windows. */
230
+ priorPeriodComparison?: PriorPeriodComparison;
231
+ /** Model-free failure-mode breakdown from `RunRecord.failureMode`, ranked
232
+ * by count descending. Present when any run carries a `failureMode`.
233
+ * Complements `failureClusters` (LLM-semantic) with the structured tags
234
+ * the harness already recorded — actionable with no analyst wired. */
235
+ failureModes?: FailureModeTally[];
236
+ /** Top-N actionable recommendations, ranked by priority. The packet's
237
+ * human-readable layer; the numeric sections are the evidence. */
238
+ recommendations: Recommendation[];
239
+ }
240
+ interface CostProvenanceSummary {
241
+ observed: {
242
+ n: number;
243
+ totalUsd: number;
244
+ };
245
+ estimated: {
246
+ n: number;
247
+ totalUsd: number;
248
+ };
249
+ uncaptured: {
250
+ n: number;
251
+ };
252
+ knownFraction: number;
253
+ }
254
+ interface ExecutionInsight {
255
+ /** End-to-end wall time for every run. */
256
+ durationMs: ScalarDistribution;
257
+ /** Queue time for the subset of runs that recorded it. */
258
+ queueMs: ScalarDistribution;
259
+ /** Token distributions plus corpus totals. Optional token categories use
260
+ * distribution `n` to disclose how many runs recorded that category. */
261
+ tokenUsage: TokenUsageInsight;
262
+ /** Usage reported only by orchestration or agent aggregate spans.
263
+ * Kept separate because it may duplicate model-call telemetry in other traces. */
264
+ aggregateUsage: {
265
+ runs: number;
266
+ tokenUsage: TokenUsageInsight;
267
+ costUsd: ScalarDistribution;
268
+ totalCostUsd: number;
269
+ };
270
+ /** Stable model counts, largest cohort first. */
271
+ models: Array<{
272
+ model: string;
273
+ runs: number;
274
+ }>;
275
+ /** Model-call coverage. `events` is available only from producers that
276
+ * record `outcome.raw.llm_span_count`; `runs` also recognizes non-zero
277
+ * token usage from other producers. */
278
+ modelCalls: {
279
+ runs: number;
280
+ events: number;
281
+ reportingRuns: number;
282
+ };
283
+ /** Failure counts remain separate from outcome scores. `reportedErrorEvents`
284
+ * sums `outcome.raw.error_span_count` only where a producer supplied it. */
285
+ failures: {
286
+ runs: number;
287
+ fraction: number;
288
+ reportedErrorEvents: number;
289
+ reportingRuns: number;
290
+ };
291
+ }
292
+ interface TokenUsageInsight {
293
+ input: ScalarDistribution;
294
+ output: ScalarDistribution;
295
+ reasoning: ScalarDistribution;
296
+ cached: ScalarDistribution;
297
+ cacheWrite: ScalarDistribution;
298
+ totals: {
299
+ input: number;
300
+ output: number;
301
+ reasoning: number;
302
+ cached: number;
303
+ cacheWrite: number;
304
+ };
305
+ }
306
+ /** Distributional summary of a scalar-valued metric. */
307
+ interface ScalarDistribution {
308
+ /** Sample count after dropping non-finite values. */
309
+ n: number;
310
+ mean: number;
311
+ p50: number;
312
+ p95: number;
313
+ stddev: number;
314
+ min: number;
315
+ max: number;
316
+ /** Histogram bins using `agent-eval`'s `gainHistogram` primitive. */
317
+ histogram: GainDistributionBin[];
318
+ /** Worst-N runs by score, ascending. Populated for the composite
319
+ * distribution so the report names the runs a customer should
320
+ * inspect first. Undefined when the distribution was computed from a
321
+ * raw value list with no run identity (e.g. cost). */
322
+ tailRuns?: Array<{
323
+ runId: string;
324
+ score: number;
325
+ }>;
326
+ }
327
+ interface JudgeInsight {
328
+ /** Number of times this judge scored a run. */
329
+ n: number;
330
+ /** Mean composite over this judge's runs. */
331
+ meanScore: number;
332
+ /** Calibration against a gold reference, when provided. Cohen's κ for
333
+ * binary thresholding + continuous agreement metrics. */
334
+ calibration?: ContinuousAgreement;
335
+ /** Positional bias — when the judge sees options in different orders,
336
+ * do its preferences track the content or the position? */
337
+ positionalBias?: number;
338
+ /** Self-preference — when the judge sees its own model's output vs a
339
+ * competitor, does it over-pick its own? */
340
+ selfPreference?: number;
341
+ /** Verbosity bias — does the judge reward longer outputs regardless of
342
+ * quality? */
343
+ verbosityBias?: number;
344
+ }
345
+ interface InterRaterInsight {
346
+ /** Number of raters whose scores were aggregated. */
347
+ raters: number;
348
+ /** Number of runs every rater scored. */
349
+ jointlyRated: number;
350
+ /** Cohen's κ averaged across rater pairs. */
351
+ kappa: number;
352
+ /** Pairwise κ per rater pair (key = `"raterA::raterB"`). */
353
+ perPair: Record<string, number>;
354
+ /** Run ids where raters disagree the most — the high-value triage list. */
355
+ disagreementCases: Array<{
356
+ runId: string;
357
+ ratings: Array<{
358
+ rater: string;
359
+ score: number;
360
+ }>;
361
+ range: number;
362
+ }>;
363
+ }
364
+ interface LiftInsight {
365
+ baselineMean: number;
366
+ candidateMean: number;
367
+ /** Candidate − baseline. */
368
+ delta: number;
369
+ /** Lower / upper bound of bootstrap CI on the delta. */
370
+ ci95: [number, number];
371
+ /** Paired-t-test p-value. */
372
+ pValue: number;
373
+ /** Number of paired observations. */
374
+ n: number;
375
+ /** Cohen's d for the delta. */
376
+ cohensD: number;
377
+ /** Minimum detectable effect at current n, 80% power. */
378
+ mde: number;
379
+ /** Sample size needed to detect the observed delta at 80% power. */
380
+ requiredN: number;
381
+ }
382
+ interface FailureClusterInsight {
383
+ /** All clusters identified by the registry, ranked by share descending. */
384
+ clusters: Array<{
385
+ id: string;
386
+ name: string;
387
+ /** Fraction of failed runs in this cluster, 0..1. */
388
+ share: number;
389
+ /** Exemplar `runId`s (≤ 5) the consumer can drill into. */
390
+ exemplars: string[];
391
+ /** Short LLM-generated suggested fix when the registry supports it. */
392
+ suggestedFix?: string;
393
+ }>;
394
+ totalFailures: number;
395
+ }
396
+ /** Model-free failure breakdown over the structured `RunRecord.failureMode`
397
+ * enum. Unlike `failureClusters` (semantic, requires an LLM analyst), this
398
+ * is computed directly from the tags the harness already recorded — so a
399
+ * customer ingesting one batch with no judge/analyst still learns which
400
+ * named failure dominates. */
401
+ interface FailureModeTally {
402
+ /** The `failureMode` tag. */
403
+ mode: string;
404
+ /** Number of runs carrying this tag. */
405
+ count: number;
406
+ /** Share of the whole corpus, 0..1. */
407
+ share: number;
408
+ }
409
+ interface ContaminationInsight {
410
+ /** Canary phrases that leaked into outputs. */
411
+ leaks: number;
412
+ /** Holdout audit verdict — did any holdout-tagged run end up in the
413
+ * search/dev pool, or vice versa? */
414
+ holdoutAuditPassed: boolean;
415
+ details?: Array<{
416
+ runId: string;
417
+ canary: string;
418
+ matched: string;
419
+ }>;
420
+ }
421
+ interface OutcomeCorrelationInsight {
422
+ /** What outcome the consumer is correlating against (e.g.
423
+ * `'engagement_rate'`, `'approval_rate'`, `'downstream_pass'`). */
424
+ metric: string;
425
+ /** Number of (run, outcome) pairs used. */
426
+ n: number;
427
+ /** Pearson correlation between composite score and outcome. */
428
+ pearson: number;
429
+ /** Spearman rank correlation — robust to monotonic non-linearity. */
430
+ spearman: number;
431
+ /** When present, the simple linear reward model fit to the data. */
432
+ rewardModel?: {
433
+ intercept: number;
434
+ slope: number;
435
+ r2: number;
436
+ };
437
+ }
438
+ interface ReleaseSummary {
439
+ /** Overall verdict across axes — fail if any axis fails, else warn if any
440
+ * warns, else pass. */
441
+ status: 'pass' | 'warn' | 'fail';
442
+ axes: Array<{
443
+ name: 'quality-lift' | 'contamination' | 'composite-distribution';
444
+ status: 'pass' | 'warn' | 'fail';
445
+ detail: string;
446
+ }>;
447
+ /** Free-form issues surfaced beyond the standard axes. Empty by default;
448
+ * consumers can post-process to populate. */
449
+ issues: string[];
450
+ }
451
+ interface MetricDelta {
452
+ /** Current-period mean. */
453
+ current: number;
454
+ /** Baseline-period mean. */
455
+ baseline: number;
456
+ /** current - baseline. Positive means improved (or, for cost/duration,
457
+ * the consumer-side interpretation: "higher current" — semantic
458
+ * direction depends on the metric). */
459
+ delta: number;
460
+ /** Welch 95% confidence interval on the delta. Two-sample, unpaired —
461
+ * the baseline and current run sets may have different scenarios. */
462
+ ci95: [number, number];
463
+ /** Welch t-test p-value (two-sided). */
464
+ pValue: number;
465
+ /** Cohen's d (pooled stddev). Effect size, signed. */
466
+ cohensD: number;
467
+ /** Sample sizes. */
468
+ baselineN: number;
469
+ currentN: number;
470
+ /** True when p < 0.05 AND |d| >= 0.2 (small-effect threshold). The
471
+ * conjunction prevents large-effect-but-noisy and significant-but-
472
+ * tiny from triggering recommendations. */
473
+ significant: boolean;
474
+ }
475
+ interface PriorPeriodComparison {
476
+ /** Sample counts. */
477
+ baselineN: number;
478
+ currentN: number;
479
+ /** Optional human-readable label — "vs prior 7 days", "vs v3 release". */
480
+ windowLabel?: string;
481
+ /** Every metric we could compare. Keys: 'composite', 'cost', 'duration',
482
+ * 'tokenUsage' for always-present ones; per-dimension keys when both
483
+ * windows have judge scores on the same dimension. */
484
+ metrics: Record<string, MetricDelta>;
485
+ /** Metric names where current is significantly WORSE than baseline.
486
+ * Direction-aware: for cost/duration, higher current = worse. */
487
+ regressedMetrics: string[];
488
+ /** Metric names where current is significantly BETTER than baseline. */
489
+ improvedMetrics: string[];
490
+ }
491
+ interface Recommendation {
492
+ priority: 'critical' | 'high' | 'medium' | 'low';
493
+ kind: 'ship' | 'hold' | 'investigate' | 'fix' | 'recalibrate' | 'expand-corpus';
494
+ title: string;
495
+ detail: string;
496
+ /** Optional pointer back into the report for the evidence. */
497
+ evidencePath?: string;
498
+ }
18
499
 
19
500
  /**
20
501
  * # Hosted-tier wire format — the schema that EVERY orchestrator (ours,