@tangle-network/agent-eval 0.120.1 → 0.120.2

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 (171) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/package.json +1 -1
  3. package/dist/analyst/index.d.ts +0 -3111
  4. package/dist/analyst/index.js +0 -403
  5. package/dist/analyst/index.js.map +0 -1
  6. package/dist/authenticity/index.d.ts +0 -161
  7. package/dist/authenticity/index.js +0 -215
  8. package/dist/authenticity/index.js.map +0 -1
  9. package/dist/belief-state/index.d.ts +0 -1301
  10. package/dist/belief-state/index.js +0 -2152
  11. package/dist/belief-state/index.js.map +0 -1
  12. package/dist/benchmarks/index.d.ts +0 -974
  13. package/dist/benchmarks/index.js +0 -60
  14. package/dist/benchmarks/index.js.map +0 -1
  15. package/dist/builder-eval/index.d.ts +0 -695
  16. package/dist/builder-eval/index.js +0 -366
  17. package/dist/builder-eval/index.js.map +0 -1
  18. package/dist/campaign/index.d.ts +0 -7454
  19. package/dist/campaign/index.js +0 -272
  20. package/dist/campaign/index.js.map +0 -1
  21. package/dist/chunk-32BZXMSO.js +0 -3878
  22. package/dist/chunk-32BZXMSO.js.map +0 -1
  23. package/dist/chunk-3A246TSA.js +0 -998
  24. package/dist/chunk-3A246TSA.js.map +0 -1
  25. package/dist/chunk-3RF76KTD.js +0 -84
  26. package/dist/chunk-3RF76KTD.js.map +0 -1
  27. package/dist/chunk-3YYRZDON.js +0 -45
  28. package/dist/chunk-3YYRZDON.js.map +0 -1
  29. package/dist/chunk-4I2E3LLO.js +0 -1030
  30. package/dist/chunk-4I2E3LLO.js.map +0 -1
  31. package/dist/chunk-ARU2PZFM.js +0 -312
  32. package/dist/chunk-ARU2PZFM.js.map +0 -1
  33. package/dist/chunk-BOD4O7OF.js +0 -40
  34. package/dist/chunk-BOD4O7OF.js.map +0 -1
  35. package/dist/chunk-DPZAEKA6.js +0 -880
  36. package/dist/chunk-DPZAEKA6.js.map +0 -1
  37. package/dist/chunk-DTJ6QUQB.js +0 -131
  38. package/dist/chunk-DTJ6QUQB.js.map +0 -1
  39. package/dist/chunk-GGE4NNQT.js +0 -65
  40. package/dist/chunk-GGE4NNQT.js.map +0 -1
  41. package/dist/chunk-H5UD2323.js +0 -286
  42. package/dist/chunk-H5UD2323.js.map +0 -1
  43. package/dist/chunk-HHWE3POT.js +0 -94
  44. package/dist/chunk-HHWE3POT.js.map +0 -1
  45. package/dist/chunk-HKUCJ437.js +0 -787
  46. package/dist/chunk-HKUCJ437.js.map +0 -1
  47. package/dist/chunk-JHCHEVET.js +0 -274
  48. package/dist/chunk-JHCHEVET.js.map +0 -1
  49. package/dist/chunk-JHOJHHU7.js +0 -867
  50. package/dist/chunk-JHOJHHU7.js.map +0 -1
  51. package/dist/chunk-JM2SKQMS.js +0 -750
  52. package/dist/chunk-JM2SKQMS.js.map +0 -1
  53. package/dist/chunk-JN2FCO5W.js +0 -7958
  54. package/dist/chunk-JN2FCO5W.js.map +0 -1
  55. package/dist/chunk-K4DBDHLK.js +0 -158
  56. package/dist/chunk-K4DBDHLK.js.map +0 -1
  57. package/dist/chunk-K6N6XJJX.js +0 -306
  58. package/dist/chunk-K6N6XJJX.js.map +0 -1
  59. package/dist/chunk-MA6HLL3S.js +0 -65
  60. package/dist/chunk-MA6HLL3S.js.map +0 -1
  61. package/dist/chunk-MAZ26DC7.js +0 -99
  62. package/dist/chunk-MAZ26DC7.js.map +0 -1
  63. package/dist/chunk-MOXWMGPC.js +0 -577
  64. package/dist/chunk-MOXWMGPC.js.map +0 -1
  65. package/dist/chunk-NJC7U437.js +0 -626
  66. package/dist/chunk-NJC7U437.js.map +0 -1
  67. package/dist/chunk-NPCTHQIO.js +0 -91
  68. package/dist/chunk-NPCTHQIO.js.map +0 -1
  69. package/dist/chunk-ONWEPEDO.js +0 -57
  70. package/dist/chunk-ONWEPEDO.js.map +0 -1
  71. package/dist/chunk-OYZAPX5G.js +0 -1526
  72. package/dist/chunk-OYZAPX5G.js.map +0 -1
  73. package/dist/chunk-PC4UYEBM.js +0 -166
  74. package/dist/chunk-PC4UYEBM.js.map +0 -1
  75. package/dist/chunk-PICTDURQ.js +0 -766
  76. package/dist/chunk-PICTDURQ.js.map +0 -1
  77. package/dist/chunk-PJQFMIOX.js +0 -1182
  78. package/dist/chunk-PJQFMIOX.js.map +0 -1
  79. package/dist/chunk-PXD6ZFNY.js +0 -1107
  80. package/dist/chunk-PXD6ZFNY.js.map +0 -1
  81. package/dist/chunk-PXE2VKMX.js +0 -140
  82. package/dist/chunk-PXE2VKMX.js.map +0 -1
  83. package/dist/chunk-PZ5AY32C.js +0 -10
  84. package/dist/chunk-PZ5AY32C.js.map +0 -1
  85. package/dist/chunk-QBRSJK47.js +0 -622
  86. package/dist/chunk-QBRSJK47.js.map +0 -1
  87. package/dist/chunk-QWMPPZ3X.js +0 -550
  88. package/dist/chunk-QWMPPZ3X.js.map +0 -1
  89. package/dist/chunk-S3UZOQ5Y.js +0 -328
  90. package/dist/chunk-S3UZOQ5Y.js.map +0 -1
  91. package/dist/chunk-S5TT5R3L.js +0 -2668
  92. package/dist/chunk-S5TT5R3L.js.map +0 -1
  93. package/dist/chunk-T4SQEITX.js +0 -95
  94. package/dist/chunk-T4SQEITX.js.map +0 -1
  95. package/dist/chunk-TT4KNT67.js +0 -124
  96. package/dist/chunk-TT4KNT67.js.map +0 -1
  97. package/dist/chunk-U5CHZ5M3.js +0 -357
  98. package/dist/chunk-U5CHZ5M3.js.map +0 -1
  99. package/dist/chunk-ULOKLHIQ.js +0 -1937
  100. package/dist/chunk-ULOKLHIQ.js.map +0 -1
  101. package/dist/chunk-VI2UW6B6.js +0 -162
  102. package/dist/chunk-VI2UW6B6.js.map +0 -1
  103. package/dist/chunk-VQMK5FMP.js +0 -247
  104. package/dist/chunk-VQMK5FMP.js.map +0 -1
  105. package/dist/chunk-VSMTAMNK.js +0 -53
  106. package/dist/chunk-VSMTAMNK.js.map +0 -1
  107. package/dist/chunk-VZSRQ272.js +0 -149
  108. package/dist/chunk-VZSRQ272.js.map +0 -1
  109. package/dist/chunk-WW2A73HW.js +0 -159
  110. package/dist/chunk-WW2A73HW.js.map +0 -1
  111. package/dist/chunk-X4UCIOTZ.js +0 -136
  112. package/dist/chunk-X4UCIOTZ.js.map +0 -1
  113. package/dist/chunk-XDIRG3TO.js +0 -1266
  114. package/dist/chunk-XDIRG3TO.js.map +0 -1
  115. package/dist/chunk-XJYR7XFV.js +0 -317
  116. package/dist/chunk-XJYR7XFV.js.map +0 -1
  117. package/dist/chunk-ZET2UAYW.js +0 -89
  118. package/dist/chunk-ZET2UAYW.js.map +0 -1
  119. package/dist/chunk-ZZUXHH3R.js +0 -99
  120. package/dist/chunk-ZZUXHH3R.js.map +0 -1
  121. package/dist/cli.d.ts +0 -1
  122. package/dist/cli.js +0 -112
  123. package/dist/cli.js.map +0 -1
  124. package/dist/contract/index.d.ts +0 -4972
  125. package/dist/contract/index.js +0 -1654
  126. package/dist/contract/index.js.map +0 -1
  127. package/dist/control.d.ts +0 -1013
  128. package/dist/control.js +0 -34
  129. package/dist/control.js.map +0 -1
  130. package/dist/fuzz.d.ts +0 -759
  131. package/dist/fuzz.js +0 -714
  132. package/dist/fuzz.js.map +0 -1
  133. package/dist/hosted/index.d.ts +0 -730
  134. package/dist/hosted/index.js +0 -14
  135. package/dist/hosted/index.js.map +0 -1
  136. package/dist/index.d.ts +0 -16780
  137. package/dist/index.js +0 -12168
  138. package/dist/index.js.map +0 -1
  139. package/dist/matrix/index.d.ts +0 -155
  140. package/dist/matrix/index.js +0 -8
  141. package/dist/matrix/index.js.map +0 -1
  142. package/dist/meta-eval/index.d.ts +0 -1030
  143. package/dist/meta-eval/index.js +0 -417
  144. package/dist/meta-eval/index.js.map +0 -1
  145. package/dist/multishot/index.d.ts +0 -579
  146. package/dist/multishot/index.js +0 -589
  147. package/dist/multishot/index.js.map +0 -1
  148. package/dist/openapi.json +0 -992
  149. package/dist/pipelines/index.d.ts +0 -567
  150. package/dist/pipelines/index.js +0 -515
  151. package/dist/pipelines/index.js.map +0 -1
  152. package/dist/reporting.d.ts +0 -1277
  153. package/dist/reporting.js +0 -48
  154. package/dist/reporting.js.map +0 -1
  155. package/dist/rl.d.ts +0 -4092
  156. package/dist/rl.js +0 -1724
  157. package/dist/rl.js.map +0 -1
  158. package/dist/run-campaign-HNFPJET4.js +0 -14
  159. package/dist/run-campaign-HNFPJET4.js.map +0 -1
  160. package/dist/storyboard/index.d.ts +0 -279
  161. package/dist/storyboard/index.js +0 -767
  162. package/dist/storyboard/index.js.map +0 -1
  163. package/dist/trace-attributes.d.ts +0 -52
  164. package/dist/trace-attributes.js +0 -62
  165. package/dist/trace-attributes.js.map +0 -1
  166. package/dist/traces.d.ts +0 -2343
  167. package/dist/traces.js +0 -249
  168. package/dist/traces.js.map +0 -1
  169. package/dist/wire/index.d.ts +0 -1252
  170. package/dist/wire/index.js +0 -81
  171. package/dist/wire/index.js.map +0 -1
@@ -1,577 +0,0 @@
1
- import {
2
- summaryTable
3
- } from "./chunk-DPZAEKA6.js";
4
- import {
5
- VerificationError
6
- } from "./chunk-ONWEPEDO.js";
7
-
8
- // src/release-confidence.ts
9
- var DEFAULT_THRESHOLDS = {
10
- requireCorpus: true,
11
- minScenarioCount: 1,
12
- minSearchRuns: 1,
13
- minHoldoutRuns: 1,
14
- requireHoldout: true,
15
- minPassRate: 0.8,
16
- minMeanScore: 0.7,
17
- maxOverfitGap: 0.15,
18
- maxMeanCostUsd: Number.POSITIVE_INFINITY,
19
- maxP95WallMs: Number.POSITIVE_INFINITY,
20
- requireAsiForFailures: true,
21
- failureScoreThreshold: 0.5
22
- };
23
- function evaluateReleaseConfidence(input) {
24
- const thresholds = { ...DEFAULT_THRESHOLDS, ...input.thresholds };
25
- const candidateId = input.candidateId ?? null;
26
- const runs = filterCandidate(input.runs ?? [], candidateId, input.baselineId);
27
- const traces = filterTraceCandidate(input.traces ?? [], candidateId, input.baselineId);
28
- const scenarios = input.scenarios ?? [];
29
- const scenarioCount = input.dataset?.scenarioCount ?? scenarios.length;
30
- const splitCounts = input.dataset?.splitCounts ?? countScenarioSplits(scenarios);
31
- const searchScores = scoresFor(runs, "search");
32
- const holdoutScores = scoresFor(runs, "holdout");
33
- const allScores = [...searchScores, ...holdoutScores];
34
- const traceScores = traces.map((t) => t.score).filter(isFiniteNumber);
35
- const scoreUniverse = allScores.length > 0 ? allScores : traceScores;
36
- const searchRuns = runs.filter((r) => r.splitTag === "search").length;
37
- const holdoutRuns = runs.filter((r) => r.splitTag === "holdout").length;
38
- const searchMeanScore = mean(searchScores);
39
- const holdoutMeanScore = mean(holdoutScores);
40
- const metrics = {
41
- scenarioCount,
42
- searchRuns,
43
- holdoutRuns,
44
- passRate: passRate(runs, traces, thresholds.failureScoreThreshold),
45
- meanScore: mean(scoreUniverse),
46
- searchMeanScore,
47
- holdoutMeanScore,
48
- overfitGap: safeDiff(searchMeanScore, holdoutMeanScore),
49
- meanCostUsd: mean([
50
- ...runs.map((r) => r.costUsd),
51
- ...traces.map((t) => t.costUsd).filter(isFiniteNumber)
52
- ]),
53
- p95WallMs: percentile(
54
- [...runs.map((r) => r.wallMs), ...traces.map((t) => t.durationMs).filter(isFiniteNumber)],
55
- 0.95
56
- ),
57
- failedRows: failedRows(runs, traces, thresholds.failureScoreThreshold).length,
58
- failuresWithAsi: failedRows(runs, traces, thresholds.failureScoreThreshold).filter(
59
- (row) => row.hasAsi
60
- ).length,
61
- singleShotTraces: traces.filter((t) => t.turnCount === 1).length,
62
- multiShotTraces: traces.filter((t) => (t.turnCount ?? 0) > 1).length,
63
- splitCounts,
64
- domainCounts: countDomains(scenarios),
65
- failureModeCounts: countFailureModes(runs, traces, thresholds.failureScoreThreshold),
66
- responsibleSurfaceCounts: countResponsibleSurfaces(traces)
67
- };
68
- const issues = [];
69
- checkCorpus(input, thresholds, metrics, issues);
70
- checkQuality(thresholds, metrics, issues);
71
- checkGeneralization(input.gateDecision ?? null, thresholds, metrics, issues);
72
- checkDiagnostics(thresholds, metrics, issues);
73
- checkEfficiency(thresholds, metrics, issues);
74
- const axes = buildAxes(metrics, thresholds, input.gateDecision ?? null, issues);
75
- const status = issues.some((i) => i.severity === "critical") ? "fail" : issues.length > 0 ? "warn" : "pass";
76
- return {
77
- target: input.target,
78
- candidateId,
79
- baselineId: input.baselineId ?? null,
80
- status,
81
- promote: status === "pass" && (input.gateDecision ? input.gateDecision.promote : true),
82
- axes,
83
- issues,
84
- metrics,
85
- dataset: input.dataset ?? null,
86
- gateDecision: input.gateDecision ?? null,
87
- summary: renderSummary(input.target, status, metrics, issues)
88
- };
89
- }
90
- function assertReleaseConfidence(input) {
91
- const scorecard = evaluateReleaseConfidence(input);
92
- if (scorecard.status === "fail") {
93
- throw new VerificationError(scorecard.summary);
94
- }
95
- return scorecard;
96
- }
97
- function filterCandidate(runs, candidateId, baselineId) {
98
- if (candidateId) return runs.filter((r) => r.candidateId === candidateId);
99
- if (baselineId) return runs.filter((r) => r.candidateId !== baselineId);
100
- return [...runs];
101
- }
102
- function filterTraceCandidate(traces, candidateId, baselineId) {
103
- if (candidateId)
104
- return traces.filter((t) => t.candidateId === void 0 || t.candidateId === candidateId);
105
- if (baselineId)
106
- return traces.filter((t) => t.candidateId === void 0 || t.candidateId !== baselineId);
107
- return [...traces];
108
- }
109
- function checkCorpus(input, thresholds, metrics, issues) {
110
- if (thresholds.requireCorpus && !input.dataset && (input.scenarios?.length ?? 0) === 0) {
111
- issues.push({
112
- axis: "corpus",
113
- severity: "critical",
114
- code: "missing_corpus",
115
- detail: "No Dataset manifest or scenarios supplied."
116
- });
117
- }
118
- if (metrics.scenarioCount < thresholds.minScenarioCount) {
119
- issues.push({
120
- axis: "corpus",
121
- severity: "critical",
122
- code: "few_scenarios",
123
- detail: `${metrics.scenarioCount} scenario(s) < min ${thresholds.minScenarioCount}.`
124
- });
125
- }
126
- if (thresholds.requireHoldout && metrics.splitCounts.holdout === 0) {
127
- issues.push({
128
- axis: "corpus",
129
- severity: "critical",
130
- code: "missing_holdout_split",
131
- detail: "Corpus has no holdout scenarios."
132
- });
133
- }
134
- }
135
- function checkQuality(thresholds, metrics, issues) {
136
- if (metrics.searchRuns < thresholds.minSearchRuns) {
137
- issues.push({
138
- axis: "quality",
139
- severity: "critical",
140
- code: "few_search_runs",
141
- detail: `${metrics.searchRuns} search run(s) < min ${thresholds.minSearchRuns}.`
142
- });
143
- }
144
- if (metrics.passRate < thresholds.minPassRate) {
145
- issues.push({
146
- axis: "quality",
147
- severity: "critical",
148
- code: "low_pass_rate",
149
- detail: `passRate ${fmt(metrics.passRate)} < ${fmt(thresholds.minPassRate)}.`
150
- });
151
- }
152
- if (metrics.meanScore < thresholds.minMeanScore) {
153
- issues.push({
154
- axis: "quality",
155
- severity: "critical",
156
- code: "low_mean_score",
157
- detail: `meanScore ${fmt(metrics.meanScore)} < ${fmt(thresholds.minMeanScore)}.`
158
- });
159
- }
160
- }
161
- function checkGeneralization(gateDecision, thresholds, metrics, issues) {
162
- if (thresholds.requireHoldout && metrics.holdoutRuns < thresholds.minHoldoutRuns) {
163
- issues.push({
164
- axis: "generalization",
165
- severity: "critical",
166
- code: "few_holdout_runs",
167
- detail: `${metrics.holdoutRuns} holdout run(s) < min ${thresholds.minHoldoutRuns}.`
168
- });
169
- }
170
- if (Number.isFinite(metrics.overfitGap) && metrics.overfitGap > thresholds.maxOverfitGap) {
171
- issues.push({
172
- axis: "generalization",
173
- severity: "critical",
174
- code: "overfit_gap",
175
- detail: `search-holdout gap ${fmt(metrics.overfitGap)} > ${fmt(thresholds.maxOverfitGap)}.`
176
- });
177
- }
178
- if (gateDecision && !gateDecision.promote) {
179
- issues.push({
180
- axis: "generalization",
181
- severity: "critical",
182
- code: `gate_${gateDecision.rejectionCode ?? "reject"}`,
183
- detail: gateDecision.reason
184
- });
185
- }
186
- }
187
- function checkDiagnostics(thresholds, metrics, issues) {
188
- if (!thresholds.requireAsiForFailures) return;
189
- if (metrics.failedRows > metrics.failuresWithAsi) {
190
- issues.push({
191
- axis: "diagnostics",
192
- severity: "critical",
193
- code: "missing_failure_asi",
194
- detail: `${metrics.failedRows - metrics.failuresWithAsi} failed row(s) have no actionable side information.`
195
- });
196
- }
197
- }
198
- function checkEfficiency(thresholds, metrics, issues) {
199
- if (metrics.meanCostUsd > thresholds.maxMeanCostUsd) {
200
- issues.push({
201
- axis: "efficiency",
202
- severity: "critical",
203
- code: "cost_budget",
204
- detail: `meanCostUsd ${fmt(metrics.meanCostUsd)} > ${fmt(thresholds.maxMeanCostUsd)}.`
205
- });
206
- }
207
- if (metrics.p95WallMs > thresholds.maxP95WallMs) {
208
- issues.push({
209
- axis: "efficiency",
210
- severity: "critical",
211
- code: "latency_budget",
212
- detail: `p95WallMs ${fmt(metrics.p95WallMs)} > ${fmt(thresholds.maxP95WallMs)}.`
213
- });
214
- }
215
- }
216
- function buildAxes(metrics, thresholds, gateDecision, issues) {
217
- return [
218
- axis(
219
- "corpus",
220
- issues,
221
- bounded(metrics.scenarioCount / Math.max(1, thresholds.minScenarioCount)),
222
- `${metrics.scenarioCount} scenarios; holdout=${metrics.splitCounts.holdout}`
223
- ),
224
- axis(
225
- "quality",
226
- issues,
227
- Math.min(metrics.passRate, metrics.meanScore),
228
- `passRate=${fmt(metrics.passRate)} meanScore=${fmt(metrics.meanScore)}`
229
- ),
230
- axis(
231
- "generalization",
232
- issues,
233
- gateDecision && !gateDecision.promote ? 0 : gapScore(metrics.overfitGap, thresholds.maxOverfitGap),
234
- `holdoutRuns=${metrics.holdoutRuns} overfitGap=${fmt(metrics.overfitGap)}`
235
- ),
236
- axis(
237
- "diagnostics",
238
- issues,
239
- metrics.failedRows === 0 ? 1 : metrics.failuresWithAsi / metrics.failedRows,
240
- `failuresWithAsi=${metrics.failuresWithAsi}/${metrics.failedRows}`
241
- ),
242
- axis(
243
- "efficiency",
244
- issues,
245
- efficiencyScore(metrics, thresholds),
246
- `meanCostUsd=${fmt(metrics.meanCostUsd)} p95WallMs=${fmt(metrics.p95WallMs)}`
247
- )
248
- ];
249
- }
250
- function axis(name, issues, score, detail) {
251
- const own = issues.filter((i) => i.axis === name);
252
- const status = own.some((i) => i.severity === "critical") ? "fail" : own.length > 0 ? "warn" : "pass";
253
- return { name, status, score: bounded(score), detail };
254
- }
255
- function countScenarioSplits(scenarios) {
256
- const counts = { train: 0, dev: 0, test: 0, holdout: 0 };
257
- for (const scenario of scenarios) counts[scenario.split ?? "train"]++;
258
- return counts;
259
- }
260
- function countDomains(scenarios) {
261
- const out = {};
262
- for (const scenario of scenarios) {
263
- const domain = scenario.tags?.domain ?? scenario.tags?.category ?? "uncategorized";
264
- out[domain] = (out[domain] ?? 0) + 1;
265
- }
266
- return out;
267
- }
268
- function countFailureModes(runs, traces, threshold) {
269
- const out = {};
270
- for (const run of runs) {
271
- const score = run.outcome.holdoutScore ?? run.outcome.searchScore;
272
- if (run.failureMode || score !== void 0 && score < threshold) {
273
- const mode = run.failureMode ?? "low_score";
274
- out[mode] = (out[mode] ?? 0) + 1;
275
- }
276
- }
277
- for (const trace of traces) {
278
- if (trace.failureMode || trace.ok === false || trace.score !== void 0 && trace.score < threshold) {
279
- const mode = trace.failureMode ?? (trace.ok === false ? "not_ok" : "low_score");
280
- out[mode] = (out[mode] ?? 0) + 1;
281
- }
282
- }
283
- return out;
284
- }
285
- function countResponsibleSurfaces(traces) {
286
- const out = {};
287
- for (const trace of traces) {
288
- for (const asi of trace.asi ?? []) {
289
- const surface = asi.responsibleSurface ?? "unknown";
290
- out[surface] = (out[surface] ?? 0) + 1;
291
- }
292
- }
293
- return out;
294
- }
295
- function failedRows(runs, traces, threshold) {
296
- const out = [];
297
- for (const run of runs) {
298
- const score = run.outcome.holdoutScore ?? run.outcome.searchScore;
299
- if (run.failureMode || score !== void 0 && score < threshold) {
300
- const asiMetric = run.outcome.raw.asi;
301
- out.push({ hasAsi: typeof asiMetric === "number" && asiMetric > 0 });
302
- }
303
- }
304
- for (const trace of traces) {
305
- if (trace.failureMode || trace.ok === false || trace.score !== void 0 && trace.score < threshold) {
306
- out.push({ hasAsi: (trace.asi?.length ?? 0) > 0 });
307
- }
308
- }
309
- return out;
310
- }
311
- function passRate(runs, traces, threshold) {
312
- const outcomes = [
313
- ...runs.map((run) => {
314
- const score = run.outcome.holdoutScore ?? run.outcome.searchScore;
315
- return !run.failureMode && score !== void 0 && score >= threshold;
316
- }),
317
- ...traces.map(
318
- (trace) => trace.ok !== false && (trace.score === void 0 || trace.score >= threshold)
319
- )
320
- ];
321
- if (outcomes.length === 0) return 0;
322
- return outcomes.filter(Boolean).length / outcomes.length;
323
- }
324
- function scoresFor(runs, split) {
325
- return runs.filter((run) => run.splitTag === split).map((run) => split === "holdout" ? run.outcome.holdoutScore : run.outcome.searchScore).filter(isFiniteNumber);
326
- }
327
- function mean(xs) {
328
- if (xs.length === 0) return Number.NaN;
329
- return xs.reduce((sum, x) => sum + x, 0) / xs.length;
330
- }
331
- function percentile(xs, p) {
332
- if (xs.length === 0) return Number.NaN;
333
- const sorted = [...xs].sort((a, b) => a - b);
334
- return sorted[Math.min(sorted.length - 1, Math.max(0, Math.ceil(p * sorted.length) - 1))];
335
- }
336
- function isFiniteNumber(value) {
337
- return typeof value === "number" && Number.isFinite(value);
338
- }
339
- function safeDiff(a, b) {
340
- if (!Number.isFinite(a) || !Number.isFinite(b)) return Number.NaN;
341
- return a - b;
342
- }
343
- function gapScore(gap, maxGap) {
344
- if (!Number.isFinite(gap)) return 0;
345
- if (maxGap <= 0) return gap <= 0 ? 1 : 0;
346
- return bounded(1 - Math.max(0, gap) / maxGap);
347
- }
348
- function efficiencyScore(metrics, thresholds) {
349
- const cost = Number.isFinite(thresholds.maxMeanCostUsd) && Number.isFinite(metrics.meanCostUsd) ? bounded(thresholds.maxMeanCostUsd / Math.max(metrics.meanCostUsd, 1e-12)) : 1;
350
- const latency = Number.isFinite(thresholds.maxP95WallMs) && Number.isFinite(metrics.p95WallMs) ? bounded(thresholds.maxP95WallMs / Math.max(metrics.p95WallMs, 1e-12)) : 1;
351
- return Math.min(cost, latency);
352
- }
353
- function bounded(x) {
354
- if (!Number.isFinite(x)) return 0;
355
- return Math.max(0, Math.min(1, x));
356
- }
357
- function renderSummary(target, status, metrics, issues) {
358
- const prefix = `release confidence ${status}: ${target}`;
359
- const metricText = `scenarios=${metrics.scenarioCount} searchRuns=${metrics.searchRuns} holdoutRuns=${metrics.holdoutRuns} passRate=${fmt(metrics.passRate)} meanScore=${fmt(metrics.meanScore)}`;
360
- if (issues.length === 0) return `${prefix}; ${metricText}`;
361
- return `${prefix}; ${metricText}; issues=${issues.map((i) => i.code).join(",")}`;
362
- }
363
- function fmt(x) {
364
- if (!Number.isFinite(x)) return String(x);
365
- return x.toFixed(4);
366
- }
367
-
368
- // src/promotion-gate.ts
369
- function bootstrapCi(baseline, candidate, options = {}) {
370
- const alpha = options.alpha ?? 0.05;
371
- const iterations = options.iterations ?? 1e3;
372
- const minTotal = options.minTotalSamples ?? 6;
373
- const rng = mulberry32(options.seed ?? hashSeed(baseline, candidate));
374
- const baselineMean = mean2(baseline);
375
- const candidateMean = mean2(candidate);
376
- const delta = candidateMean - baselineMean;
377
- if (baseline.length + candidate.length < minTotal || baseline.length === 0 || candidate.length === 0) {
378
- return {
379
- baselineMean,
380
- candidateMean,
381
- delta,
382
- ciLower: -Infinity,
383
- ciUpper: Infinity,
384
- iterations: 0,
385
- alpha,
386
- verdict: "INCONCLUSIVE"
387
- };
388
- }
389
- const deltas = new Array(iterations);
390
- for (let i = 0; i < iterations; i++) {
391
- const bResample = resample(baseline, rng);
392
- const cResample = resample(candidate, rng);
393
- deltas[i] = mean2(cResample) - mean2(bResample);
394
- }
395
- deltas.sort((a, b) => a - b);
396
- const lowerIdx = Math.floor(alpha / 2 * iterations);
397
- const upperIdx = Math.floor((1 - alpha / 2) * iterations) - 1;
398
- const ciLower = deltas[Math.max(0, lowerIdx)];
399
- const ciUpper = deltas[Math.min(iterations - 1, upperIdx)];
400
- let verdict;
401
- if (ciLower > 0) verdict = "ADVANCE";
402
- else if (ciUpper < 0) verdict = "REVERT";
403
- else if (delta >= 0) verdict = "KEEP";
404
- else verdict = "INCONCLUSIVE";
405
- return {
406
- baselineMean,
407
- candidateMean,
408
- delta,
409
- ciLower,
410
- ciUpper,
411
- iterations,
412
- alpha,
413
- verdict
414
- };
415
- }
416
- function mean2(xs) {
417
- if (xs.length === 0) return 0;
418
- let s = 0;
419
- for (const x of xs) s += x;
420
- return s / xs.length;
421
- }
422
- function resample(xs, rng) {
423
- const out = new Array(xs.length);
424
- for (let i = 0; i < xs.length; i++) out[i] = xs[Math.floor(rng() * xs.length)];
425
- return out;
426
- }
427
- function mulberry32(seed) {
428
- let t = seed >>> 0;
429
- return () => {
430
- t += 1831565813;
431
- let r = t;
432
- r = Math.imul(r ^ r >>> 15, r | 1);
433
- r ^= r + Math.imul(r ^ r >>> 7, r | 61);
434
- return ((r ^ r >>> 14) >>> 0) / 4294967296;
435
- };
436
- }
437
- function hashSeed(a, b) {
438
- let h = 2166136261;
439
- for (const x of [...a, ...b]) {
440
- const view = new Float64Array([x]);
441
- const bytes = new Uint8Array(view.buffer);
442
- for (const byte of bytes) {
443
- h ^= byte;
444
- h = Math.imul(h, 16777619);
445
- }
446
- }
447
- return h >>> 0;
448
- }
449
- async function judgeReplayGate(args) {
450
- const concurrency = args.judgeConcurrency ?? 4;
451
- const baselineScores = await scoreAll(args.baselineOutputs, args.judge, concurrency);
452
- const candidateScores = await scoreAll(args.candidateOutputs, args.judge, concurrency);
453
- const ci = bootstrapCi(baselineScores, candidateScores, {
454
- ...args.alpha !== void 0 ? { alpha: args.alpha } : {},
455
- ...args.iterations !== void 0 ? { iterations: args.iterations } : {},
456
- ...args.seed !== void 0 ? { seed: args.seed } : {}
457
- });
458
- return {
459
- ...ci,
460
- baselineSamples: baselineScores.length,
461
- candidateSamples: candidateScores.length
462
- };
463
- }
464
- async function scoreAll(outputs, judge, concurrency) {
465
- const results = new Array(outputs.length);
466
- let next = 0;
467
- async function worker() {
468
- while (true) {
469
- const i = next++;
470
- if (i >= outputs.length) return;
471
- const v = await judge(outputs[i]);
472
- results[i] = Number.isFinite(v) ? v : 0;
473
- }
474
- }
475
- await Promise.all(Array.from({ length: Math.max(1, concurrency) }, () => worker()));
476
- return results;
477
- }
478
-
479
- // src/release-report.ts
480
- function renderReleaseReport(scorecard, options = {}) {
481
- const title = options.title ?? `Release Report: ${scorecard.target}`;
482
- const lines = [];
483
- lines.push(`# ${title}`);
484
- lines.push("");
485
- lines.push(`Status: **${scorecard.status.toUpperCase()}**`);
486
- lines.push(`Promote: **${scorecard.promote ? "yes" : "no"}**`);
487
- if (scorecard.candidateId) lines.push(`Candidate: \`${scorecard.candidateId}\``);
488
- if (scorecard.baselineId) lines.push(`Baseline: \`${scorecard.baselineId}\``);
489
- lines.push("");
490
- lines.push(scorecard.summary);
491
- lines.push("");
492
- lines.push("## Metrics");
493
- lines.push("");
494
- lines.push("| Metric | Value |");
495
- lines.push("|---|---:|");
496
- lines.push(`| Scenarios | ${scorecard.metrics.scenarioCount} |`);
497
- lines.push(`| Search runs | ${scorecard.metrics.searchRuns} |`);
498
- lines.push(`| Holdout runs | ${scorecard.metrics.holdoutRuns} |`);
499
- lines.push(`| Pass rate | ${pct(scorecard.metrics.passRate)} |`);
500
- lines.push(`| Mean score | ${num(scorecard.metrics.meanScore)} |`);
501
- lines.push(`| Search mean | ${num(scorecard.metrics.searchMeanScore)} |`);
502
- lines.push(`| Holdout mean | ${num(scorecard.metrics.holdoutMeanScore)} |`);
503
- lines.push(`| Overfit gap | ${num(scorecard.metrics.overfitGap)} |`);
504
- lines.push(`| Mean cost | $${num(scorecard.metrics.meanCostUsd)} |`);
505
- lines.push(`| p95 wall time | ${Math.round(scorecard.metrics.p95WallMs)} ms |`);
506
- lines.push("");
507
- if (scorecard.issues.length > 0) {
508
- lines.push("## Issues");
509
- lines.push("");
510
- for (const issue of scorecard.issues) {
511
- lines.push(`- **${issue.severity}** \`${issue.code}\` (${issue.axis}): ${issue.detail}`);
512
- }
513
- lines.push("");
514
- }
515
- const surfaces = entries(scorecard.metrics.responsibleSurfaceCounts);
516
- if (surfaces.length > 0) {
517
- lines.push("## Responsible Surfaces");
518
- lines.push("");
519
- for (const [surface, count] of surfaces) lines.push(`- ${surface}: ${count}`);
520
- lines.push("");
521
- }
522
- const failures = entries(scorecard.metrics.failureModeCounts);
523
- if (failures.length > 0) {
524
- lines.push("## Failure Modes");
525
- lines.push("");
526
- for (const [mode, count] of failures) lines.push(`- ${mode}: ${count}`);
527
- lines.push("");
528
- }
529
- if (options.runs && options.runs.length > 0) {
530
- lines.push("## Run Summary");
531
- lines.push("");
532
- lines.push(
533
- summaryTable([...options.runs], {
534
- comparator: options.comparator ?? scorecard.baselineId ?? void 0,
535
- split: "holdout"
536
- }).markdown
537
- );
538
- lines.push("");
539
- }
540
- if (options.traceAnalystFindings && options.traceAnalystFindings.length > 0) {
541
- lines.push("## TraceAnalyst Findings");
542
- lines.push("");
543
- for (const finding of options.traceAnalystFindings) lines.push(`- ${finding}`);
544
- lines.push("");
545
- }
546
- const nextActions = options.nextActions ?? defaultNextActions(scorecard);
547
- if (nextActions.length > 0) {
548
- lines.push("## Next Actions");
549
- lines.push("");
550
- for (const action of nextActions) lines.push(`- ${action}`);
551
- lines.push("");
552
- }
553
- return `${lines.join("\n").trimEnd()}
554
- `;
555
- }
556
- function defaultNextActions(scorecard) {
557
- if (scorecard.promote) return ["Promote the candidate and keep canaries enabled."];
558
- return scorecard.issues.filter((issue) => issue.severity === "critical").map((issue) => `Resolve ${issue.code}: ${issue.detail}`);
559
- }
560
- function entries(values) {
561
- return Object.entries(values).filter(([, count]) => count > 0).sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]));
562
- }
563
- function pct(value) {
564
- return Number.isFinite(value) ? `${(value * 100).toFixed(1)}%` : "n/a";
565
- }
566
- function num(value) {
567
- return Number.isFinite(value) ? value.toFixed(3) : "n/a";
568
- }
569
-
570
- export {
571
- evaluateReleaseConfidence,
572
- assertReleaseConfidence,
573
- bootstrapCi,
574
- judgeReplayGate,
575
- renderReleaseReport
576
- };
577
- //# sourceMappingURL=chunk-MOXWMGPC.js.map