Skip to content

Commit 8a7906c

Browse files
committed
fix(qa): reject fractional live token usage
1 parent c85113e commit 8a7906c

2 files changed

Lines changed: 48 additions & 2 deletions

File tree

extensions/qa-lab/src/token-efficiency-report.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,24 @@ describe("token efficiency report", () => {
134134
]);
135135
});
136136

137+
it("fails live reports with non-integer token usage evidence", () => {
138+
const report = buildTokenEfficiencyReport({
139+
summary: makeLiveSummary([
140+
makeRuntimeParity(
141+
"fractional-live-usage",
142+
makeCell("openclaw", { inputTokens: 100.5, outputTokens: 0, totalTokens: 100.5 }),
143+
makeCell("codex", { inputTokens: 101, outputTokens: 0, totalTokens: 101 }),
144+
),
145+
]),
146+
});
147+
148+
expect(report.pass).toBe(false);
149+
expect(report.failures).toEqual([
150+
"fractional-live-usage openclaw live usage inputTokens must be a non-negative integer",
151+
"fractional-live-usage openclaw live usage totalTokens must be a non-negative integer",
152+
]);
153+
});
154+
137155
it("fails empty live runtime summaries instead of treating them as skipped proof", () => {
138156
const report = buildTokenEfficiencyReport({
139157
generatedAt: "2026-05-10T00:00:00.000Z",

extensions/qa-lab/src/token-efficiency-report.ts

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,26 @@ function liveEvidenceFailures(row: TokenEfficiencyRow): string[] {
181181
return failures;
182182
}
183183

184+
function liveUsageShapeFailures(
185+
scenarioId: string,
186+
runtime: RuntimeId,
187+
usage: RuntimeParityCell["usage"],
188+
): string[] {
189+
const failures: string[] = [];
190+
for (const key of ["inputTokens", "outputTokens", "totalTokens"] as const) {
191+
const value: unknown = usage[key];
192+
if (
193+
typeof value !== "number" ||
194+
!Number.isFinite(value) ||
195+
!Number.isInteger(value) ||
196+
value < 0
197+
) {
198+
failures.push(`${scenarioId} ${runtime} live usage ${key} must be a non-negative integer`);
199+
}
200+
}
201+
return failures;
202+
}
203+
184204
export function buildTokenEfficiencyReport(
185205
params: BuildTokenEfficiencyReportParams,
186206
): TokenEfficiencyReport {
@@ -218,8 +238,16 @@ export function buildTokenEfficiencyReport(
218238
}),
219239
);
220240
const aggregate = buildAggregate(rows);
221-
const failures = rows.flatMap((row) => {
222-
const rowFailures = liveUsage ? liveEvidenceFailures(row) : [];
241+
const failures = rows.flatMap((row, index) => {
242+
const result = parityResults[index];
243+
const rowFailures =
244+
liveUsage && result
245+
? [
246+
...liveUsageShapeFailures(row.scenarioId, "openclaw", result.cells.openclaw.usage),
247+
...liveUsageShapeFailures(row.scenarioId, "codex", result.cells.codex.usage),
248+
...liveEvidenceFailures(row),
249+
]
250+
: [];
223251
if (row.flagged) {
224252
rowFailures.push(
225253
`${row.scenarioId} token delta=${formatPercent(row.deltaPercent)} exceeds ${thresholdPercent.toFixed(1)}% Codex increase threshold`,

0 commit comments

Comments
 (0)