Files
rea/tests/boundary/rust/rustBinaryBudget.test.ts
T
morluto ef59174c1e fix(errors): name fixed allowances in resource-constraint recovery (#5633)
* fix(errors): name fixed allowances in resource-constraint recovery

Fixed parser, count, report, input, and capture refusals inherited
host-memory, wait-and-retry, or retained-Evidence advice. Producers now
attach allowance-specific recovery, and deterministic capacity caps are
not retryable. IL2CPP reader occupancy stays retryable capacity.

Refs #5556, #5405, #5456, #5459, #5460, #5504, #5505, #5506, #5537, #5628, #5630, #5631, #5632

* fix(il2cpp): keep a closing metadata reader non-retryable

close() stops admission before the active inspection finishes. A second
inspect in that window was projected as retryable capacity. Closing and
closed readers now report capability_unavailable. Occupied readers that
remain open stay retryable.

* fix(errors): align fixed-cap recovery with retained facts

IL2CPP report refusals keep observed source facts instead of denying Evidence. Command-output caps use the capture allowance. Ghidra seed recovery names the limit that was exceeded.

* fix(errors): call byte caps a byte allowance

WASM representation limits and the IL2CPP Ghidra seed-file cap are byte budgets. Their recovery no longer says the exceeded allowance is a fixed count.

* test(ida): keep unresolved procedure lookups non-retryable

Main now treats an unchanged invalid request as non-retryable. The IDA lookup tests follow that projection.

* fix(errors): qualify capture recovery for live output

A fixed capture allowance still rejects the same output. Live captures such as adb logcat can change between requests, so recovery no longer says every unchanged request fails again.

* fix(adb): keep a truncated live capture retryable

Device output can shrink between calls, so an adb capture that exceeds the allowance stays retryable. Deterministic capture and version-output limits stay non-retryable.

* fix(adb): keep truncated mutations non-retryable

Only live observations opt into retrying a capture that exceeded the allowance. Push, install, uninstall, and other mutations stay non-retryable.

* fix(errors): keep live capture recovery off deterministic limits

Artifact-derived capture allowances again say the unchanged request fails. Only volatile adb observations use the live-output sentence.

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-10-21 03:45:34 +08:00

52 lines
2.2 KiB
TypeScript

import { truncate, writeFile } from "node:fs/promises";
import { join } from "node:path";
import { expect, it } from "vitest";
import { projectAnalysisError } from "../../../src/domain/analysisErrorProjection.js";
import { RustBinaryProvider } from "../../../src/rust/RustBinaryProvider.js";
import { RUST_BINARY_INPUT_BYTES } from "../../../src/rust/RustAuditableReader.js";
import { createRustHashOverflowImage } from "../../fixtures/rust/image.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
it("refuses extra rustc paths without asking the caller to wait", async () => {
const root = await createTestTempDirectory("rea-rust-hash-budget-");
const path = join(root, "many-hashes.elf");
await writeFile(path, createRustHashOverflowImage());
const result = await new RustBinaryProvider().inspect({ path });
expect(result.ok).toBe(false);
if (result.ok) throw new Error("Expected a hash-capacity refusal");
const projected = projectAnalysisError(result.error);
expect(projected).toMatchObject({
retryable: false,
details: {
resource: "capacity",
reported_limits: { maximum_rustc_hashes: 64 },
},
});
expect(projected.remediation.action).toContain("rustc commit-path inventory");
expect(projected.remediation.action).not.toMatch(
/Wait for an active analysis/u,
);
});
it("refuses an oversized Rust input without evidence-reply advice", async () => {
const root = await createTestTempDirectory("rea-rust-input-budget-");
const path = join(root, "large.elf");
await writeFile(path, Buffer.from([0x7f, 0x45, 0x4c, 0x46]));
await truncate(path, RUST_BINARY_INPUT_BYTES + 1);
const result = await new RustBinaryProvider().inspect({ path });
expect(result.ok).toBe(false);
if (result.ok) throw new Error("Expected an input-size refusal");
const projected = projectAnalysisError(result.error);
expect(projected).toMatchObject({
retryable: false,
details: {
resource: "file-size",
reported_limits: { maximum_input_bytes: RUST_BINARY_INPUT_BYTES },
},
});
expect(projected.remediation.action).toContain("does not admit this input");
expect(projected.remediation.action).not.toMatch(
/file-size allowance for the evidence reply/u,
);
});