@tangle-network/agent-eval 0.126.7 → 0.127.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 (129) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/README.md +2 -2
  3. package/dist/analyst/index.d.ts +51 -39
  4. package/dist/analyst/index.js +4 -4
  5. package/dist/belief-state/index.d.ts +34 -36
  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 -10
  9. package/dist/builder-eval/index.js +1 -1
  10. package/dist/campaign/index.d.ts +432 -146
  11. package/dist/campaign/index.js +11 -9
  12. package/dist/{chunk-ARU2PZFM.js → chunk-424XHVKV.js} +43 -23
  13. package/dist/chunk-424XHVKV.js.map +1 -0
  14. package/dist/{chunk-NUKSVU3W.js → chunk-5DTSBUL2.js} +2 -2
  15. package/dist/{chunk-BTACVO2W.js → chunk-65QETEKG.js} +542 -258
  16. package/dist/chunk-65QETEKG.js.map +1 -0
  17. package/dist/{chunk-CGG5SLH3.js → chunk-ARCFIY7U.js} +2 -2
  18. package/dist/{chunk-P22LJ3Y2.js → chunk-CLELFRQG.js} +6 -4
  19. package/dist/chunk-CLELFRQG.js.map +1 -0
  20. package/dist/{chunk-LUNF2SEL.js → chunk-DJKY2TSY.js} +3 -3
  21. package/dist/chunk-DPUHNQLN.js +232 -0
  22. package/dist/chunk-DPUHNQLN.js.map +1 -0
  23. package/dist/{chunk-IPYXE555.js → chunk-EJGRPCO3.js} +36 -13
  24. package/dist/chunk-EJGRPCO3.js.map +1 -0
  25. package/dist/{chunk-K6IAZZ6L.js → chunk-FA3MFYNA.js} +132 -110
  26. package/dist/chunk-FA3MFYNA.js.map +1 -0
  27. package/dist/chunk-IG35YDN3.js +614 -0
  28. package/dist/chunk-IG35YDN3.js.map +1 -0
  29. package/dist/{chunk-DPZAEKA6.js → chunk-IMGJZBFG.js} +84 -56
  30. package/dist/chunk-IMGJZBFG.js.map +1 -0
  31. package/dist/{chunk-H5UD2323.js → chunk-IN455XKS.js} +53 -1
  32. package/dist/chunk-IN455XKS.js.map +1 -0
  33. package/dist/{chunk-PJQFMIOX.js → chunk-MHELPNRP.js} +31 -1
  34. package/dist/chunk-MHELPNRP.js.map +1 -0
  35. package/dist/{chunk-IILEIWGW.js → chunk-NL33OXEP.js} +41 -36
  36. package/dist/chunk-NL33OXEP.js.map +1 -0
  37. package/dist/{chunk-474LBSOX.js → chunk-OD5NQ2CS.js} +41 -16
  38. package/dist/chunk-OD5NQ2CS.js.map +1 -0
  39. package/dist/{chunk-QOTFXW5L.js → chunk-P5W7RQKK.js} +2 -2
  40. package/dist/{chunk-IR3KBHOY.js → chunk-P6FYH6K4.js} +39 -3
  41. package/dist/chunk-P6FYH6K4.js.map +1 -0
  42. package/dist/{chunk-J5SQWP6Y.js → chunk-PBE2LOSS.js} +18 -2
  43. package/dist/chunk-PBE2LOSS.js.map +1 -0
  44. package/dist/{chunk-E3IADPLG.js → chunk-PRB53E3J.js} +50 -224
  45. package/dist/chunk-PRB53E3J.js.map +1 -0
  46. package/dist/{chunk-X4UCIOTZ.js → chunk-S5YLIBFX.js} +2 -2
  47. package/dist/{chunk-7VYEGHWF.js → chunk-SZLVEKMJ.js} +41 -20
  48. package/dist/chunk-SZLVEKMJ.js.map +1 -0
  49. package/dist/{chunk-LKKT3IVV.js → chunk-TSN7JT6D.js} +6 -4
  50. package/dist/{chunk-LKKT3IVV.js.map → chunk-TSN7JT6D.js.map} +1 -1
  51. package/dist/{chunk-M7AH34KV.js → chunk-UTA2TGC4.js} +32 -16
  52. package/dist/chunk-UTA2TGC4.js.map +1 -0
  53. package/dist/{chunk-MAX3TN3C.js → chunk-UWZZKKU7.js} +7 -19
  54. package/dist/chunk-UWZZKKU7.js.map +1 -0
  55. package/dist/{chunk-ZVCHKKOP.js → chunk-WED5KLZQ.js} +39 -15
  56. package/dist/chunk-WED5KLZQ.js.map +1 -0
  57. package/dist/{chunk-OCFJACJU.js → chunk-X6VOPMLD.js} +74 -14
  58. package/dist/chunk-X6VOPMLD.js.map +1 -0
  59. package/dist/{chunk-MOXWMGPC.js → chunk-Y5CYOL42.js} +159 -70
  60. package/dist/chunk-Y5CYOL42.js.map +1 -0
  61. package/dist/{chunk-FO7HEH76.js → chunk-YJBNWCAA.js} +2 -2
  62. package/dist/chunk-ZPUEEM5U.js +179 -0
  63. package/dist/chunk-ZPUEEM5U.js.map +1 -0
  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 +421 -124
  67. package/dist/contract/index.js +242 -115
  68. package/dist/contract/index.js.map +1 -1
  69. package/dist/control.d.ts +34 -32
  70. package/dist/control.js +2 -2
  71. package/dist/hosted/index.d.ts +142 -41
  72. package/dist/hosted/index.js +23 -1
  73. package/dist/index.d.ts +364 -255
  74. package/dist/index.js +315 -226
  75. package/dist/index.js.map +1 -1
  76. package/dist/meta-eval/index.d.ts +32 -32
  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 +97 -74
  82. package/dist/reporting.js +5 -4
  83. package/dist/rl.d.ts +177 -131
  84. package/dist/rl.js +232 -126
  85. package/dist/rl.js.map +1 -1
  86. package/dist/rollout/index.d.ts +53 -63
  87. package/dist/rollout/index.js +7 -5
  88. package/dist/{run-campaign-FFRM3RH5.js → run-campaign-3A2EBYBE.js} +4 -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 +66 -41
  92. package/dist/traces.js +9 -5
  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/hosted-ingest-spec.md +37 -40
  97. package/docs/insight-report.md +57 -7
  98. package/docs/research-report-methodology.md +20 -21
  99. package/docs/rollout.md +13 -8
  100. package/package.json +4 -3
  101. package/dist/chunk-474LBSOX.js.map +0 -1
  102. package/dist/chunk-7VYEGHWF.js.map +0 -1
  103. package/dist/chunk-ARU2PZFM.js.map +0 -1
  104. package/dist/chunk-BTACVO2W.js.map +0 -1
  105. package/dist/chunk-DPZAEKA6.js.map +0 -1
  106. package/dist/chunk-E3IADPLG.js.map +0 -1
  107. package/dist/chunk-H5UD2323.js.map +0 -1
  108. package/dist/chunk-IILEIWGW.js.map +0 -1
  109. package/dist/chunk-IPYXE555.js.map +0 -1
  110. package/dist/chunk-IR3KBHOY.js.map +0 -1
  111. package/dist/chunk-J5SQWP6Y.js.map +0 -1
  112. package/dist/chunk-K6IAZZ6L.js.map +0 -1
  113. package/dist/chunk-M7AH34KV.js.map +0 -1
  114. package/dist/chunk-MAX3TN3C.js.map +0 -1
  115. package/dist/chunk-MOXWMGPC.js.map +0 -1
  116. package/dist/chunk-OCFJACJU.js.map +0 -1
  117. package/dist/chunk-P22LJ3Y2.js.map +0 -1
  118. package/dist/chunk-PJQFMIOX.js.map +0 -1
  119. package/dist/chunk-ZVCHKKOP.js.map +0 -1
  120. package/dist/chunk-ZZUXHH3R.js +0 -99
  121. package/dist/chunk-ZZUXHH3R.js.map +0 -1
  122. /package/dist/{chunk-NUKSVU3W.js.map → chunk-5DTSBUL2.js.map} +0 -0
  123. /package/dist/{chunk-CGG5SLH3.js.map → chunk-ARCFIY7U.js.map} +0 -0
  124. /package/dist/{chunk-LUNF2SEL.js.map → chunk-DJKY2TSY.js.map} +0 -0
  125. /package/dist/{chunk-QOTFXW5L.js.map → chunk-P5W7RQKK.js.map} +0 -0
  126. /package/dist/{chunk-X4UCIOTZ.js.map → chunk-S5YLIBFX.js.map} +0 -0
  127. /package/dist/{chunk-FO7HEH76.js.map → chunk-YJBNWCAA.js.map} +0 -0
  128. /package/dist/{chunk-KE2VWPZX.js.map → chunk-ZUUWPZCV.js.map} +0 -0
  129. /package/dist/{run-campaign-FFRM3RH5.js.map → run-campaign-3A2EBYBE.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-65QETEKG.js";
11
11
  import {
12
12
  SearchLedgerConflictError,
13
13
  SearchLedgerError,
@@ -19,29 +19,33 @@ import {
19
19
  runCampaign,
20
20
  summarizeBackendIntegrity,
21
21
  withSearchLedgerFileLock
22
- } from "./chunk-ZVCHKKOP.js";
22
+ } from "./chunk-WED5KLZQ.js";
23
23
  import {
24
24
  Mutex
25
25
  } from "./chunk-WGXIEX7P.js";
26
+ import {
27
+ campaignCellToRunRecord
28
+ } from "./chunk-ZPUEEM5U.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,
42
45
  modelHasSnapshot,
46
+ runTaskScore,
43
47
  validateRunRecord
44
- } from "./chunk-IILEIWGW.js";
48
+ } from "./chunk-NL33OXEP.js";
45
49
  import {
46
50
  canonicalize
47
51
  } from "./chunk-VSMTAMNK.js";
@@ -112,155 +116,6 @@ function failureModeRecallJudge(opts = {}) {
112
116
  };
113
117
  }
114
118
 
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
119
  // src/campaign/cross-surface-context.ts
265
120
  function validateCrossSurfaceInput(input) {
266
121
  assertNonEmptyUnique(input.taskOrder, "taskOrder");
@@ -1528,7 +1383,7 @@ function neutralizationGate(options) {
1528
1383
  contributingGates: [
1529
1384
  {
1530
1385
  name: "neutralizationGate",
1531
- passed: false,
1386
+ status: "fail",
1532
1387
  detail: { candidateLift: cand.lift, neutralizedLift: neut.lift, n: cand.n }
1533
1388
  }
1534
1389
  ],
@@ -1548,7 +1403,7 @@ function neutralizationGate(options) {
1548
1403
  contributingGates: [
1549
1404
  {
1550
1405
  name: "neutralizationGate",
1551
- passed,
1406
+ status: passed ? "pass" : "fail",
1552
1407
  detail: {
1553
1408
  candidateLift: cand.lift,
1554
1409
  neutralizedLift: neut.lift,
@@ -1754,14 +1609,20 @@ function sequentialPairedGate(options) {
1754
1609
  return {
1755
1610
  decision: "need_more_work",
1756
1611
  reasons: [`${name}: no paired holdout observations \u2014 nothing to test`],
1757
- contributingGates: [{ name, passed: false, detail }]
1612
+ contributingGates: [{ name, status: "not_evaluated", detail }]
1758
1613
  };
1759
1614
  }
1760
1615
  const decision = last.decision === "promote" ? "ship" : last.decision === "continue" ? "need_more_work" : "hold";
1761
1616
  return {
1762
1617
  decision,
1763
1618
  reasons: [`${name}: ${last.reason}`],
1764
- contributingGates: [{ name, passed: decision === "ship", detail }],
1619
+ contributingGates: [
1620
+ {
1621
+ name,
1622
+ status: decision === "ship" ? "pass" : decision === "need_more_work" ? "not_evaluated" : "fail",
1623
+ detail
1624
+ }
1625
+ ],
1765
1626
  delta: meanDelta
1766
1627
  };
1767
1628
  }
@@ -1785,7 +1646,11 @@ function sequentialDecide(options = {}) {
1785
1646
  `sequentialDecide: generation ${record.generationIndex} has no candidates \u2014 cannot extract a top candidate`
1786
1647
  );
1787
1648
  }
1788
- return record.candidates.reduce((best, c) => c.composite > best.composite ? c : best);
1649
+ return record.candidates.reduce((best, candidate) => {
1650
+ if (best.composite === null) return candidate;
1651
+ if (candidate.composite === null) return best;
1652
+ return candidate.composite > best.composite ? candidate : best;
1653
+ });
1789
1654
  };
1790
1655
  const decide = ({ history }) => {
1791
1656
  if (stopped) return stopped;
@@ -2726,10 +2591,6 @@ function sha(input) {
2726
2591
  function mean2(xs) {
2727
2592
  return xs.length === 0 ? 0 : xs.reduce((a, b) => a + b, 0) / xs.length;
2728
2593
  }
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
2594
  function requireResolvedModel(cell, profileId) {
2734
2595
  const resolved = cell.resolvedModel?.trim();
2735
2596
  if (!resolved) {
@@ -2749,60 +2610,17 @@ function buildRunRecord(args) {
2749
2610
  const profileId = agentProfileId(profile);
2750
2611
  const declaredModel = agentProfileModelId(profile);
2751
2612
  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 = {
2613
+ const record = campaignCellToRunRecord(cell, {
2789
2614
  runId: `${matrixId}:${profileId}:${cell.cellId}`,
2790
2615
  experimentId,
2791
2616
  candidateId: profileId,
2792
- seed: cell.seed,
2793
2617
  model,
2794
2618
  promptHash: profileHash,
2795
2619
  configHash,
2796
2620
  commitSha,
2797
- wallMs: cell.durationMs,
2798
- costUsd,
2799
- tokenUsage: cell.tokenUsage,
2800
- outcome,
2801
2621
  splitTag,
2802
- scenarioId: cell.scenarioId,
2803
- ...args.agentProfileCell ? { agentProfile: args.agentProfileCell } : {},
2804
- ...cell.error ? { failureMode: cell.error } : {}
2805
- };
2622
+ agentProfile: args.agentProfileCell
2623
+ });
2806
2624
  if (args.corpusText && args.scenario) {
2807
2625
  try {
2808
2626
  const text = args.corpusText(cell.artifact, args.scenario);
@@ -2842,10 +2660,13 @@ async function runProfileMatrix(opts) {
2842
2660
  configHash: profileHash,
2843
2661
  commitSha: opts.commitSha,
2844
2662
  wallMs: 0,
2845
- costUsd: 0,
2663
+ costUsd: null,
2664
+ costProvenance: { kind: "uncaptured", usd: null },
2846
2665
  tokenUsage: { input: 0, output: 0 },
2847
- outcome: splitTag === "holdout" ? { holdoutScore: 0, raw: {} } : { searchScore: 0, raw: {} },
2848
- splitTag
2666
+ terminalOutcome: "succeeded",
2667
+ outcome: { raw: { execution_error_count: 0 } },
2668
+ splitTag,
2669
+ scenarioId: "recordability-probe"
2849
2670
  });
2850
2671
  } catch (err) {
2851
2672
  throw new ProfileMatrixError(
@@ -2920,7 +2741,9 @@ async function runProfileMatrix(opts) {
2920
2741
  // one harness, so the first record's model is representative).
2921
2742
  model: declaredModel === HARNESS_NATIVE_MODEL ? profileRecords[0]?.model ?? declaredModel : declaredModel,
2922
2743
  records: profileRecords.length,
2923
- meanComposite: mean2(profileRecords.map(compositeOf)),
2744
+ meanComposite: meanOrNull2(
2745
+ profileRecords.map(scoreOf).filter((score) => score !== void 0)
2746
+ ),
2924
2747
  totalCostUsd,
2925
2748
  integrity: summarizeBackendIntegrity(profileRecords)
2926
2749
  };
@@ -2937,16 +2760,21 @@ async function runProfileMatrix(opts) {
2937
2760
  const byPersona = opts.personaOf ? rollupByPersona(records, opts.scenarios, opts.personaOf) : void 0;
2938
2761
  return { matrixId, experimentId, records, byProfile, byScenario, byPersona, integrity, campaigns };
2939
2762
  }
2940
- function compositeOf(r) {
2941
- return r.outcome.holdoutScore ?? r.outcome.searchScore ?? 0;
2763
+ function scoreOf(r) {
2764
+ return runTaskScore(r);
2765
+ }
2766
+ function meanOrNull2(values) {
2767
+ return values.length === 0 ? null : mean2(values);
2942
2768
  }
2943
2769
  function rollup(records, keyOf) {
2944
2770
  const groups = /* @__PURE__ */ new Map();
2945
2771
  for (const r of records) {
2946
2772
  const key = keyOf(r);
2947
2773
  if (key === void 0) continue;
2774
+ const score = scoreOf(r);
2775
+ if (score === void 0) continue;
2948
2776
  const arr = groups.get(key) ?? [];
2949
- arr.push(compositeOf(r));
2777
+ arr.push(score);
2950
2778
  groups.set(key, arr);
2951
2779
  }
2952
2780
  const out = {};
@@ -3508,7 +3336,7 @@ function replayEntries(entries, campaignId) {
3508
3336
  const generationOperation = event.plan.operations.find(
3509
3337
  (operation) => operation.operationId === slot.generationOperationId
3510
3338
  );
3511
- if (!generationOperation || generationOperation.kind !== "candidate-generation") {
3339
+ if (generationOperation?.kind !== "candidate-generation") {
3512
3340
  throw new SearchLedgerIntegrityError(
3513
3341
  `candidate slot ${slot.slotId} references unplanned candidate-generation operation ${slot.generationOperationId}`
3514
3342
  );
@@ -4585,8 +4413,6 @@ function resolveWorktreePath(surface, worktreeDir) {
4585
4413
  }
4586
4414
 
4587
4415
  export {
4588
- pairArms,
4589
- comparePairedArms,
4590
4416
  completionVerdict,
4591
4417
  verifyCompletion,
4592
4418
  parseCorrectnessResponse,
@@ -4634,4 +4460,4 @@ export {
4634
4460
  verifyCodeSurface,
4635
4461
  resolveWorktreePath
4636
4462
  };
4637
- //# sourceMappingURL=chunk-E3IADPLG.js.map
4463
+ //# sourceMappingURL=chunk-PRB53E3J.js.map