@tangle-network/agent-eval 0.126.7 → 0.128.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 (132) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/README.md +6 -2
  3. package/dist/analyst/index.d.ts +52 -43
  4. package/dist/analyst/index.js +4 -4
  5. package/dist/belief-state/index.d.ts +35 -40
  6. package/dist/belief-state/index.js +2 -2
  7. package/dist/benchmarks/index.d.ts +30 -12
  8. package/dist/benchmarks/index.js +12 -11
  9. package/dist/builder-eval/index.js +1 -1
  10. package/dist/campaign/index.d.ts +441 -160
  11. package/dist/campaign/index.js +11 -10
  12. package/dist/{chunk-IILEIWGW.js → chunk-2JX3CFMB.js} +100 -40
  13. package/dist/chunk-2JX3CFMB.js.map +1 -0
  14. package/dist/chunk-2MKQIFS4.js +183 -0
  15. package/dist/chunk-2MKQIFS4.js.map +1 -0
  16. package/dist/{chunk-NUKSVU3W.js → chunk-5DTSBUL2.js} +2 -2
  17. package/dist/{chunk-H5UD2323.js → chunk-7ZZMD7UK.js} +102 -2
  18. package/dist/chunk-7ZZMD7UK.js.map +1 -0
  19. package/dist/{chunk-474LBSOX.js → chunk-BYT7ELPS.js} +45 -18
  20. package/dist/chunk-BYT7ELPS.js.map +1 -0
  21. package/dist/{chunk-LUNF2SEL.js → chunk-DJKY2TSY.js} +3 -3
  22. package/dist/chunk-DPUHNQLN.js +232 -0
  23. package/dist/chunk-DPUHNQLN.js.map +1 -0
  24. package/dist/chunk-DRYIUNWY.js +622 -0
  25. package/dist/chunk-DRYIUNWY.js.map +1 -0
  26. package/dist/{chunk-IPYXE555.js → chunk-EJGRPCO3.js} +36 -13
  27. package/dist/chunk-EJGRPCO3.js.map +1 -0
  28. package/dist/{chunk-OCFJACJU.js → chunk-EOSZT7PL.js} +82 -18
  29. package/dist/chunk-EOSZT7PL.js.map +1 -0
  30. package/dist/{chunk-ZVCHKKOP.js → chunk-EZJEIH2R.js} +39 -15
  31. package/dist/chunk-EZJEIH2R.js.map +1 -0
  32. package/dist/{chunk-M7AH34KV.js → chunk-IHQDPH7D.js} +32 -16
  33. package/dist/chunk-IHQDPH7D.js.map +1 -0
  34. package/dist/{chunk-PJQFMIOX.js → chunk-MHELPNRP.js} +31 -1
  35. package/dist/chunk-MHELPNRP.js.map +1 -0
  36. package/dist/{chunk-K6IAZZ6L.js → chunk-NACAGYSY.js} +153 -122
  37. package/dist/chunk-NACAGYSY.js.map +1 -0
  38. package/dist/{chunk-BTACVO2W.js → chunk-NKAGIDE2.js} +542 -258
  39. package/dist/chunk-NKAGIDE2.js.map +1 -0
  40. package/dist/{chunk-ARU2PZFM.js → chunk-NYLOYM6N.js} +43 -23
  41. package/dist/chunk-NYLOYM6N.js.map +1 -0
  42. package/dist/{chunk-QOTFXW5L.js → chunk-P5W7RQKK.js} +2 -2
  43. package/dist/{chunk-IR3KBHOY.js → chunk-P6FYH6K4.js} +39 -3
  44. package/dist/chunk-P6FYH6K4.js.map +1 -0
  45. package/dist/{chunk-J5SQWP6Y.js → chunk-PBE2LOSS.js} +18 -2
  46. package/dist/chunk-PBE2LOSS.js.map +1 -0
  47. package/dist/{chunk-X4UCIOTZ.js → chunk-S5YLIBFX.js} +2 -2
  48. package/dist/{chunk-7VYEGHWF.js → chunk-SZLVEKMJ.js} +41 -20
  49. package/dist/chunk-SZLVEKMJ.js.map +1 -0
  50. package/dist/{chunk-P22LJ3Y2.js → chunk-TBL77AUT.js} +8 -8
  51. package/dist/chunk-TBL77AUT.js.map +1 -0
  52. package/dist/{chunk-LKKT3IVV.js → chunk-TSN7JT6D.js} +6 -4
  53. package/dist/{chunk-LKKT3IVV.js.map → chunk-TSN7JT6D.js.map} +1 -1
  54. package/dist/{chunk-E3IADPLG.js → chunk-UB2LOJ6Q.js} +51 -227
  55. package/dist/chunk-UB2LOJ6Q.js.map +1 -0
  56. package/dist/{chunk-MAX3TN3C.js → chunk-UWZZKKU7.js} +7 -19
  57. package/dist/chunk-UWZZKKU7.js.map +1 -0
  58. package/dist/{chunk-DPZAEKA6.js → chunk-VLOATJQ2.js} +85 -57
  59. package/dist/chunk-VLOATJQ2.js.map +1 -0
  60. package/dist/{chunk-MOXWMGPC.js → chunk-XDWDC2MP.js} +197 -79
  61. package/dist/chunk-XDWDC2MP.js.map +1 -0
  62. package/dist/{chunk-CGG5SLH3.js → chunk-XPRT64IE.js} +2 -2
  63. package/dist/{chunk-FO7HEH76.js → chunk-YJBNWCAA.js} +2 -2
  64. package/dist/{chunk-KE2VWPZX.js → chunk-ZUUWPZCV.js} +3 -3
  65. package/dist/cli.js +4 -4
  66. package/dist/contract/index.d.ts +438 -138
  67. package/dist/contract/index.js +259 -113
  68. package/dist/contract/index.js.map +1 -1
  69. package/dist/control.d.ts +56 -39
  70. package/dist/control.js +2 -3
  71. package/dist/hosted/index.d.ts +152 -51
  72. package/dist/hosted/index.js +24 -1
  73. package/dist/index.d.ts +399 -277
  74. package/dist/index.js +363 -244
  75. package/dist/index.js.map +1 -1
  76. package/dist/meta-eval/index.d.ts +33 -36
  77. package/dist/meta-eval/index.js +2 -2
  78. package/dist/multishot/index.d.ts +1 -0
  79. package/dist/openapi.json +1 -1
  80. package/dist/pipelines/index.js +2 -2
  81. package/dist/reporting.d.ts +101 -80
  82. package/dist/reporting.js +7 -5
  83. package/dist/rl.d.ts +198 -142
  84. package/dist/rl.js +235 -127
  85. package/dist/rl.js.map +1 -1
  86. package/dist/rollout/index.d.ts +54 -67
  87. package/dist/rollout/index.js +6 -5
  88. package/dist/{run-campaign-FFRM3RH5.js → run-campaign-ISHFZ7FJ.js} +6 -3
  89. package/dist/supervisor-run/index.d.ts +7 -15
  90. package/dist/supervisor-run/index.js +2 -2
  91. package/dist/traces.d.ts +72 -50
  92. package/dist/traces.js +9 -6
  93. package/dist/wire/index.d.ts +1 -0
  94. package/dist/wire/index.js +2 -2
  95. package/docs/concepts.md +18 -1
  96. package/docs/customer-journeys.md +7 -6
  97. package/docs/hosted-ingest-spec.md +37 -40
  98. package/docs/insight-report.md +78 -7
  99. package/docs/research-report-methodology.md +20 -21
  100. package/docs/rollout.md +13 -8
  101. package/package.json +4 -3
  102. package/dist/chunk-474LBSOX.js.map +0 -1
  103. package/dist/chunk-7VYEGHWF.js.map +0 -1
  104. package/dist/chunk-ARU2PZFM.js.map +0 -1
  105. package/dist/chunk-BTACVO2W.js.map +0 -1
  106. package/dist/chunk-DPZAEKA6.js.map +0 -1
  107. package/dist/chunk-E3IADPLG.js.map +0 -1
  108. package/dist/chunk-H5UD2323.js.map +0 -1
  109. package/dist/chunk-IILEIWGW.js.map +0 -1
  110. package/dist/chunk-IPYXE555.js.map +0 -1
  111. package/dist/chunk-IR3KBHOY.js.map +0 -1
  112. package/dist/chunk-J5SQWP6Y.js.map +0 -1
  113. package/dist/chunk-K6IAZZ6L.js.map +0 -1
  114. package/dist/chunk-M7AH34KV.js.map +0 -1
  115. package/dist/chunk-MAX3TN3C.js.map +0 -1
  116. package/dist/chunk-MOXWMGPC.js.map +0 -1
  117. package/dist/chunk-OCFJACJU.js.map +0 -1
  118. package/dist/chunk-P22LJ3Y2.js.map +0 -1
  119. package/dist/chunk-PJQFMIOX.js.map +0 -1
  120. package/dist/chunk-VSMTAMNK.js +0 -53
  121. package/dist/chunk-VSMTAMNK.js.map +0 -1
  122. package/dist/chunk-ZVCHKKOP.js.map +0 -1
  123. package/dist/chunk-ZZUXHH3R.js +0 -99
  124. package/dist/chunk-ZZUXHH3R.js.map +0 -1
  125. /package/dist/{chunk-NUKSVU3W.js.map → chunk-5DTSBUL2.js.map} +0 -0
  126. /package/dist/{chunk-LUNF2SEL.js.map → chunk-DJKY2TSY.js.map} +0 -0
  127. /package/dist/{chunk-QOTFXW5L.js.map → chunk-P5W7RQKK.js.map} +0 -0
  128. /package/dist/{chunk-X4UCIOTZ.js.map → chunk-S5YLIBFX.js.map} +0 -0
  129. /package/dist/{chunk-CGG5SLH3.js.map → chunk-XPRT64IE.js.map} +0 -0
  130. /package/dist/{chunk-FO7HEH76.js.map → chunk-YJBNWCAA.js.map} +0 -0
  131. /package/dist/{chunk-KE2VWPZX.js.map → chunk-ZUUWPZCV.js.map} +0 -0
  132. /package/dist/{run-campaign-FFRM3RH5.js.map → run-campaign-ISHFZ7FJ.js.map} +0 -0
@@ -7,7 +7,7 @@ import {
7
7
  pairHoldout,
8
8
  recoverTruncatedJson,
9
9
  surfaceContentHash
10
- } from "./chunk-BTACVO2W.js";
10
+ } from "./chunk-NKAGIDE2.js";
11
11
  import {
12
12
  SearchLedgerConflictError,
13
13
  SearchLedgerError,
@@ -19,32 +19,34 @@ import {
19
19
  runCampaign,
20
20
  summarizeBackendIntegrity,
21
21
  withSearchLedgerFileLock
22
- } from "./chunk-ZVCHKKOP.js";
22
+ } from "./chunk-EZJEIH2R.js";
23
23
  import {
24
24
  Mutex
25
25
  } from "./chunk-WGXIEX7P.js";
26
+ import {
27
+ campaignCellToRunRecord
28
+ } from "./chunk-2MKQIFS4.js";
29
+ import {
30
+ comparePairedArms
31
+ } from "./chunk-DPUHNQLN.js";
26
32
  import {
27
33
  eProcess,
28
- mcnemar,
29
34
  mulberry32,
30
- pairedBootstrap,
31
- pairedRiskDifference,
32
- wilcoxonSignedRank
33
- } from "./chunk-PJQFMIOX.js";
35
+ pairedBootstrap
36
+ } from "./chunk-MHELPNRP.js";
34
37
  import {
35
38
  CostLedger
36
39
  } from "./chunk-WS3NZZQQ.js";
37
40
  import {
38
41
  analyzeTraces
39
- } from "./chunk-NUKSVU3W.js";
42
+ } from "./chunk-5DTSBUL2.js";
40
43
  import {
41
44
  buildAgentProfileCell,
45
+ canonicalize,
42
46
  modelHasSnapshot,
47
+ runTaskScore,
43
48
  validateRunRecord
44
- } from "./chunk-IILEIWGW.js";
45
- import {
46
- canonicalize
47
- } from "./chunk-VSMTAMNK.js";
49
+ } from "./chunk-2JX3CFMB.js";
48
50
  import {
49
51
  AgentEvalError,
50
52
  ValidationError
@@ -112,155 +114,6 @@ function failureModeRecallJudge(opts = {}) {
112
114
  };
113
115
  }
114
116
 
115
- // src/paired-arms.ts
116
- function pairArms(rows, opts) {
117
- const { baselineArm, treatmentArm } = opts;
118
- if (baselineArm === treatmentArm) {
119
- throw new ValidationError(
120
- `pairArms: baselineArm and treatmentArm are both '${baselineArm}' \u2014 an arm cannot be compared to itself`
121
- );
122
- }
123
- const byArm = /* @__PURE__ */ new Map();
124
- const armsSeen = /* @__PURE__ */ new Set();
125
- for (const row of rows) {
126
- armsSeen.add(row.arm);
127
- if (row.arm !== baselineArm && row.arm !== treatmentArm) continue;
128
- const byKey = byArm.get(row.arm) ?? /* @__PURE__ */ new Map();
129
- const group = byKey.get(row.pairKey) ?? [];
130
- group.push(row);
131
- byKey.set(row.pairKey, group);
132
- byArm.set(row.arm, byKey);
133
- }
134
- for (const arm of [baselineArm, treatmentArm]) {
135
- if (!byArm.has(arm)) {
136
- const seen = [...armsSeen].sort().join(", ") || "<none>";
137
- throw new ValidationError(`pairArms: no rows for arm '${arm}' (arms present: ${seen})`);
138
- }
139
- }
140
- const baselineByKey = byArm.get(baselineArm);
141
- const treatmentByKey = byArm.get(treatmentArm);
142
- const allKeys = [.../* @__PURE__ */ new Set([...baselineByKey.keys(), ...treatmentByKey.keys()])].sort();
143
- const pairs = [];
144
- const unpairedBaseline = [];
145
- const unpairedTreatment = [];
146
- for (const pairKey of allKeys) {
147
- const b = baselineByKey.get(pairKey) ?? [];
148
- const t = treatmentByKey.get(pairKey) ?? [];
149
- if (b.length <= 1 && t.length <= 1) {
150
- if (b.length === 1 && t.length === 1) {
151
- pairs.push({ pairKey, repIndex: 0, baseline: b[0], treatment: t[0] });
152
- } else {
153
- unpairedBaseline.push(...b);
154
- unpairedTreatment.push(...t);
155
- }
156
- continue;
157
- }
158
- const bByRep = indexByRepKey(b, pairKey, baselineArm);
159
- const tByRep = indexByRepKey(t, pairKey, treatmentArm);
160
- const repKeys = [.../* @__PURE__ */ new Set([...bByRep.keys(), ...tByRep.keys()])].sort();
161
- let repIndex = 0;
162
- for (const repKey of repKeys) {
163
- const baseline = bByRep.get(repKey);
164
- const treatment = tByRep.get(repKey);
165
- if (baseline !== void 0 && treatment !== void 0) {
166
- pairs.push({ pairKey, repIndex: repIndex++, baseline, treatment });
167
- } else if (baseline !== void 0) {
168
- unpairedBaseline.push(baseline);
169
- } else if (treatment !== void 0) {
170
- unpairedTreatment.push(treatment);
171
- }
172
- }
173
- }
174
- return { pairs, unpairedBaseline, unpairedTreatment };
175
- }
176
- function indexByRepKey(group, pairKey, arm) {
177
- const byRep = /* @__PURE__ */ new Map();
178
- for (const row of group) {
179
- if (row.repKey === void 0) {
180
- throw new ValidationError(
181
- `pairArms: pairKey '${pairKey}' has multiple reps in an arm, but a row in arm '${arm}' is missing repKey \u2014 multi-rep items require an explicit repKey on every row so reps pair by identity (pairing reps by outcome or by index would bias the paired statistics)`
182
- );
183
- }
184
- if (byRep.has(row.repKey)) {
185
- throw new ValidationError(
186
- `pairArms: duplicate repKey '${row.repKey}' for pairKey '${pairKey}' in arm '${arm}' \u2014 (pairKey, repKey) must uniquely identify a rep within an arm`
187
- );
188
- }
189
- byRep.set(row.repKey, row);
190
- }
191
- return byRep;
192
- }
193
- function comparePairedArms(rows, opts) {
194
- const { pairs, unpairedBaseline, unpairedTreatment } = pairArms(rows, opts);
195
- let correctness = null;
196
- const baselinePass = [];
197
- const treatmentPass = [];
198
- for (const pair of pairs) {
199
- if (pair.baseline.pass === void 0 || pair.treatment.pass === void 0) continue;
200
- baselinePass.push(pair.baseline.pass ? 1 : 0);
201
- treatmentPass.push(pair.treatment.pass ? 1 : 0);
202
- }
203
- if (baselinePass.length > 0) {
204
- const mc = mcnemar(baselinePass, treatmentPass);
205
- correctness = {
206
- b10: mc.b,
207
- b01: mc.c,
208
- mcnemar: mc,
209
- riskDifference: pairedRiskDifference(baselinePass, treatmentPass)
210
- };
211
- }
212
- const metricNames = opts.metricNames ?? [
213
- ...new Set(
214
- pairs.flatMap((p) => [
215
- ...Object.keys(p.baseline.metrics ?? {}),
216
- ...Object.keys(p.treatment.metrics ?? {})
217
- ])
218
- )
219
- ].sort();
220
- const metricDeltas = metricNames.map((name) => {
221
- const before = [];
222
- const after = [];
223
- let nMissing = 0;
224
- for (const pair of pairs) {
225
- const b = metricValue(pair.baseline, name);
226
- const t = metricValue(pair.treatment, name);
227
- if (b === void 0 || t === void 0) {
228
- nMissing++;
229
- continue;
230
- }
231
- before.push(b);
232
- after.push(t);
233
- }
234
- const bootstrapCi = before.length === 0 ? null : pairedBootstrap(before, after, opts.bootstrap);
235
- return {
236
- name,
237
- n: before.length,
238
- nMissing,
239
- medianDelta: bootstrapCi === null ? Number.NaN : bootstrapCi.median,
240
- meanDelta: bootstrapCi === null ? Number.NaN : bootstrapCi.mean,
241
- bootstrapCi,
242
- wilcoxon: before.length === 0 ? null : wilcoxonSignedRank(before, after)
243
- };
244
- });
245
- return {
246
- nPairs: pairs.length,
247
- nUnpairedBaseline: unpairedBaseline.length,
248
- nUnpairedTreatment: unpairedTreatment.length,
249
- correctness,
250
- metricDeltas
251
- };
252
- }
253
- function metricValue(row, name) {
254
- const v = row.metrics?.[name];
255
- if (v === void 0) return void 0;
256
- if (!Number.isFinite(v)) {
257
- throw new ValidationError(
258
- `comparePairedArms: non-finite value for metric '${name}' on pairKey '${row.pairKey}' (arm '${row.arm}'): ${v}`
259
- );
260
- }
261
- return v;
262
- }
263
-
264
117
  // src/campaign/cross-surface-context.ts
265
118
  function validateCrossSurfaceInput(input) {
266
119
  assertNonEmptyUnique(input.taskOrder, "taskOrder");
@@ -1528,7 +1381,7 @@ function neutralizationGate(options) {
1528
1381
  contributingGates: [
1529
1382
  {
1530
1383
  name: "neutralizationGate",
1531
- passed: false,
1384
+ status: "fail",
1532
1385
  detail: { candidateLift: cand.lift, neutralizedLift: neut.lift, n: cand.n }
1533
1386
  }
1534
1387
  ],
@@ -1548,7 +1401,7 @@ function neutralizationGate(options) {
1548
1401
  contributingGates: [
1549
1402
  {
1550
1403
  name: "neutralizationGate",
1551
- passed,
1404
+ status: passed ? "pass" : "fail",
1552
1405
  detail: {
1553
1406
  candidateLift: cand.lift,
1554
1407
  neutralizedLift: neut.lift,
@@ -1754,14 +1607,20 @@ function sequentialPairedGate(options) {
1754
1607
  return {
1755
1608
  decision: "need_more_work",
1756
1609
  reasons: [`${name}: no paired holdout observations \u2014 nothing to test`],
1757
- contributingGates: [{ name, passed: false, detail }]
1610
+ contributingGates: [{ name, status: "not_evaluated", detail }]
1758
1611
  };
1759
1612
  }
1760
1613
  const decision = last.decision === "promote" ? "ship" : last.decision === "continue" ? "need_more_work" : "hold";
1761
1614
  return {
1762
1615
  decision,
1763
1616
  reasons: [`${name}: ${last.reason}`],
1764
- contributingGates: [{ name, passed: decision === "ship", detail }],
1617
+ contributingGates: [
1618
+ {
1619
+ name,
1620
+ status: decision === "ship" ? "pass" : decision === "need_more_work" ? "not_evaluated" : "fail",
1621
+ detail
1622
+ }
1623
+ ],
1765
1624
  delta: meanDelta
1766
1625
  };
1767
1626
  }
@@ -1785,7 +1644,11 @@ function sequentialDecide(options = {}) {
1785
1644
  `sequentialDecide: generation ${record.generationIndex} has no candidates \u2014 cannot extract a top candidate`
1786
1645
  );
1787
1646
  }
1788
- return record.candidates.reduce((best, c) => c.composite > best.composite ? c : best);
1647
+ return record.candidates.reduce((best, candidate) => {
1648
+ if (best.composite === null) return candidate;
1649
+ if (candidate.composite === null) return best;
1650
+ return candidate.composite > best.composite ? candidate : best;
1651
+ });
1789
1652
  };
1790
1653
  const decide = ({ history }) => {
1791
1654
  if (stopped) return stopped;
@@ -2726,10 +2589,6 @@ function sha(input) {
2726
2589
  function mean2(xs) {
2727
2590
  return xs.length === 0 ? 0 : xs.reduce((a, b) => a + b, 0) / xs.length;
2728
2591
  }
2729
- function cellComposite(cell) {
2730
- const composites = Object.values(cell.judgeScores).map((s) => s.composite);
2731
- return composites.length === 0 ? 0 : mean2(composites);
2732
- }
2733
2592
  function requireResolvedModel(cell, profileId) {
2734
2593
  const resolved = cell.resolvedModel?.trim();
2735
2594
  if (!resolved) {
@@ -2749,60 +2608,17 @@ function buildRunRecord(args) {
2749
2608
  const profileId = agentProfileId(profile);
2750
2609
  const declaredModel = agentProfileModelId(profile);
2751
2610
  const model = declaredModel === HARNESS_NATIVE_MODEL ? requireResolvedModel(cell, profileId) : declaredModel;
2752
- const composite = cellComposite(cell);
2753
- const raw = { composite };
2754
- const perJudge = {};
2755
- const dimAccum = {};
2756
- const notes = [];
2757
- for (const [judgeName, js] of Object.entries(cell.judgeScores)) {
2758
- perJudge[judgeName] = { ...js.dimensions };
2759
- for (const [dim, value] of Object.entries(js.dimensions)) {
2760
- raw[`${judgeName}.${dim}`] = value;
2761
- dimAccum[dim] ??= [];
2762
- dimAccum[dim].push(value);
2763
- }
2764
- if (js.notes) notes.push(`${judgeName}: ${js.notes}`);
2765
- }
2766
- const perDimMean = {};
2767
- for (const [dim, values] of Object.entries(dimAccum)) perDimMean[dim] = mean2(values);
2768
- const costUsd = cell.costUsd;
2769
- raw.cost_usd = costUsd;
2770
- raw.cost_estimated = cell.costEstimated ? 1 : 0;
2771
- raw.tokens_input = cell.tokenUsage.input;
2772
- raw.tokens_output = cell.tokenUsage.output;
2773
- if (typeof cell.tokenUsage.cached === "number") raw.tokens_cached = cell.tokenUsage.cached;
2774
- raw.latency_ms = cell.durationMs;
2775
- if (costUsd > 0) {
2776
- raw.tokens_per_dollar = (cell.tokenUsage.input + cell.tokenUsage.output) / costUsd;
2777
- }
2778
- if (composite > 0.01) raw.cost_per_quality = costUsd / composite;
2779
- const outcome = splitTag === "holdout" ? { holdoutScore: composite, raw } : { searchScore: composite, raw };
2780
- if (Object.keys(perJudge).length > 0) {
2781
- outcome.judgeScores = {
2782
- perJudge,
2783
- perDimMean,
2784
- composite,
2785
- ...notes.length > 0 ? { notes: notes.join(" | ") } : {}
2786
- };
2787
- }
2788
- const record = {
2611
+ const record = campaignCellToRunRecord(cell, {
2789
2612
  runId: `${matrixId}:${profileId}:${cell.cellId}`,
2790
2613
  experimentId,
2791
2614
  candidateId: profileId,
2792
- seed: cell.seed,
2793
2615
  model,
2794
2616
  promptHash: profileHash,
2795
2617
  configHash,
2796
2618
  commitSha,
2797
- wallMs: cell.durationMs,
2798
- costUsd,
2799
- tokenUsage: cell.tokenUsage,
2800
- outcome,
2801
2619
  splitTag,
2802
- scenarioId: cell.scenarioId,
2803
- ...args.agentProfileCell ? { agentProfile: args.agentProfileCell } : {},
2804
- ...cell.error ? { failureMode: cell.error } : {}
2805
- };
2620
+ agentProfile: args.agentProfileCell
2621
+ });
2806
2622
  if (args.corpusText && args.scenario) {
2807
2623
  try {
2808
2624
  const text = args.corpusText(cell.artifact, args.scenario);
@@ -2842,10 +2658,13 @@ async function runProfileMatrix(opts) {
2842
2658
  configHash: profileHash,
2843
2659
  commitSha: opts.commitSha,
2844
2660
  wallMs: 0,
2845
- costUsd: 0,
2661
+ costUsd: null,
2662
+ costProvenance: { kind: "uncaptured", usd: null },
2846
2663
  tokenUsage: { input: 0, output: 0 },
2847
- outcome: splitTag === "holdout" ? { holdoutScore: 0, raw: {} } : { searchScore: 0, raw: {} },
2848
- splitTag
2664
+ terminalOutcome: "succeeded",
2665
+ outcome: { raw: { execution_error_count: 0 } },
2666
+ splitTag,
2667
+ scenarioId: "recordability-probe"
2849
2668
  });
2850
2669
  } catch (err) {
2851
2670
  throw new ProfileMatrixError(
@@ -2920,7 +2739,9 @@ async function runProfileMatrix(opts) {
2920
2739
  // one harness, so the first record's model is representative).
2921
2740
  model: declaredModel === HARNESS_NATIVE_MODEL ? profileRecords[0]?.model ?? declaredModel : declaredModel,
2922
2741
  records: profileRecords.length,
2923
- meanComposite: mean2(profileRecords.map(compositeOf)),
2742
+ meanComposite: meanOrNull2(
2743
+ profileRecords.map(scoreOf).filter((score) => score !== void 0)
2744
+ ),
2924
2745
  totalCostUsd,
2925
2746
  integrity: summarizeBackendIntegrity(profileRecords)
2926
2747
  };
@@ -2937,16 +2758,21 @@ async function runProfileMatrix(opts) {
2937
2758
  const byPersona = opts.personaOf ? rollupByPersona(records, opts.scenarios, opts.personaOf) : void 0;
2938
2759
  return { matrixId, experimentId, records, byProfile, byScenario, byPersona, integrity, campaigns };
2939
2760
  }
2940
- function compositeOf(r) {
2941
- return r.outcome.holdoutScore ?? r.outcome.searchScore ?? 0;
2761
+ function scoreOf(r) {
2762
+ return runTaskScore(r);
2763
+ }
2764
+ function meanOrNull2(values) {
2765
+ return values.length === 0 ? null : mean2(values);
2942
2766
  }
2943
2767
  function rollup(records, keyOf) {
2944
2768
  const groups = /* @__PURE__ */ new Map();
2945
2769
  for (const r of records) {
2946
2770
  const key = keyOf(r);
2947
2771
  if (key === void 0) continue;
2772
+ const score = scoreOf(r);
2773
+ if (score === void 0) continue;
2948
2774
  const arr = groups.get(key) ?? [];
2949
- arr.push(compositeOf(r));
2775
+ arr.push(score);
2950
2776
  groups.set(key, arr);
2951
2777
  }
2952
2778
  const out = {};
@@ -3508,7 +3334,7 @@ function replayEntries(entries, campaignId) {
3508
3334
  const generationOperation = event.plan.operations.find(
3509
3335
  (operation) => operation.operationId === slot.generationOperationId
3510
3336
  );
3511
- if (!generationOperation || generationOperation.kind !== "candidate-generation") {
3337
+ if (generationOperation?.kind !== "candidate-generation") {
3512
3338
  throw new SearchLedgerIntegrityError(
3513
3339
  `candidate slot ${slot.slotId} references unplanned candidate-generation operation ${slot.generationOperationId}`
3514
3340
  );
@@ -4585,8 +4411,6 @@ function resolveWorktreePath(surface, worktreeDir) {
4585
4411
  }
4586
4412
 
4587
4413
  export {
4588
- pairArms,
4589
- comparePairedArms,
4590
4414
  completionVerdict,
4591
4415
  verifyCompletion,
4592
4416
  parseCorrectnessResponse,
@@ -4634,4 +4458,4 @@ export {
4634
4458
  verifyCodeSurface,
4635
4459
  resolveWorktreePath
4636
4460
  };
4637
- //# sourceMappingURL=chunk-E3IADPLG.js.map
4461
+ //# sourceMappingURL=chunk-UB2LOJ6Q.js.map