Files
reverse-engineering-anything/tests/boundary/browser/historicalCaptureDecoder.test.ts
T
gensokyo-devandgensokyo-dev 07e4b700ac test: let the deadline policy own test waits
Vitest's expect.poll and vi.waitFor stop after one second by default, a
host-speed guess that the project's deadline policy does not see. Under
hosted-CI load, kunaProjectConcurrency failed that way twice on unrelated
PRs. Another 256 waits relied on the default, and 97 passed literals
picked to fit some host.

Waits now take as long as their test may run, less the reporting reserve
that children already keep. Each Vitest project sets expect.poll's
default, and the new waitFor in tests/support/testWait.ts replaces
vi.waitFor. Fixture readiness waits (awaitAcknowledgement and the provider
process waits) default to the same deadline, and their host-speed literal
arguments are removed. One remainingTestDeadline owns the arithmetic for
both children and waits.

Ten waits whose short timeout was the real check now assert it directly
(Kuna version probe, Cutter discovery, doctor and Inspector cancellation,
apktool fixture teardown, JADX disconnect): settlement before the
production deadline that would otherwise also satisfy the wait, or a
deadline pinned beyond every test deadline.

The rea/project-wait-deadline lint rule rejects vi.waitFor and explicit
expect.poll timeouts. The testing guide and the CI tests audit skill now
document the policy.

Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-11-14 19:28:38 +08:00

1412 lines
49 KiB
TypeScript

import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import type { AnalysisError } from "../../../src/domain/analysisErrorBase.js";
import { ProviderProcessSupervisor } from "../../../src/process/ProviderProcess.js";
import { createDeferred } from "../../fixtures/binarySession.js";
import { PrivateRuntimeRoot } from "../../../src/process/PrivateRuntimeRoot.js";
import {
access,
chmod,
mkdir,
mkdtemp,
readFile,
rm,
stat,
symlink,
truncate,
writeFile,
} from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { expect, it, onTestFinished, vi } from "vitest";
import { HistoricalCaptureDecoder } from "../../../src/browser/history/HistoricalCaptureDecoder.js";
import { MitmproxyCaptureAdapter } from "../../../src/browser/history/MitmproxyCaptureAdapter.js";
import {
MITMPROXY_CAPTURE_PROVIDER_IDENTITY,
HAR_CAPTURE_PROVIDER_IDENTITY,
} from "../../../src/browser/history/CaptureProviderIdentities.js";
import {
inspectWebNetworkCaptureInputSchema,
WEB_NETWORK_CAPTURE_LIMITS,
} from "../../../src/domain/webNetworkCapture.js";
import { historicalHar } from "../../fixtures/historicalHar.js";
import { decodeHarCapture } from "../../../src/browser/history/HarCapture.js";
import { projectAnalysisError } from "../../../src/domain/analysisErrorProjection.js";
import { primaryAnalysisError } from "../../../src/domain/analysisErrorBase.js";
import { OwnedFileHandle } from "../../../src/filesystem/OwnedFileHandle.js";
import { waitFor } from "../../support/testWait.js";
const linux = it.skipIf(process.platform !== "linux");
linux("refuses a directory configured as the mitmdump executable", async () => {
const root = await mkdtemp(join(tmpdir(), "rea-mitmdump-command-"));
onTestFinished(() => rm(root, { recursive: true, force: true }));
const command = join(root, "mitmdump");
await mkdir(command);
await expect(
new MitmproxyCaptureAdapter({ REA_MITMDUMP_COMMAND: command }).command(
join(root, "request.json"),
join(root, "runtime"),
),
).rejects.toMatchObject({
_tag: "AnalysisCapabilityUnavailableError",
reason: expect.stringContaining(command),
});
});
linux("allows a symlink to a regular mitmdump executable", async () => {
const root = await mkdtemp(join(tmpdir(), "rea-mitmdump-command-symlink-"));
onTestFinished(() => rm(root, { recursive: true, force: true }));
const command = join(root, "mitmdump");
const target = join(root, "mitmdump-bin");
await writeFile(target, "#!/bin/sh\n", { mode: 0o700 });
await symlink(target, command);
await expect(
new MitmproxyCaptureAdapter({ REA_MITMDUMP_COMMAND: command }).command(
join(root, "request.json"),
join(root, "runtime"),
),
).resolves.toMatchObject({ command });
});
it("keeps the admitted decoder environment across adapter preparation and refreshes it for the next call", async () => {
const root = await mkdtemp(join(tmpdir(), "rea-capture-environment-"));
onTestFinished(() => rm(root, { recursive: true, force: true }));
const path = join(root, "capture.har");
const observedPath = join(root, "observed.json");
const text = JSON.stringify(historicalHar());
await writeFile(path, text);
const environment = { ...process.env, REA_CAPTURE_TEST_VALUE: "first" };
let runtimePath: string | undefined;
const decoder = new HistoricalCaptureDecoder(
[
{
format: "har",
identity: HAR_CAPTURE_PROVIDER_IDENTITY,
command: async (_, selectedRuntime) => {
// Adapter preparation can yield while callers reconfigure the next operation.
await Promise.resolve();
environment.REA_CAPTURE_TEST_VALUE = "changed-during-preparation";
return {
command: process.execPath,
arguments: [
"-e",
`
const fs = require("node:fs");
fs.writeFileSync(process.argv[1], JSON.stringify(process.env.REA_CAPTURE_TEST_VALUE));
fs.writeFileSync(process.argv[2], process.argv[3]);
`,
observedPath,
join(selectedRuntime, "reply.json"),
JSON.stringify({ ok: true, value: decodeHarCapture(text, []) }),
],
};
},
},
],
environment,
async () => {
const runtime = await PrivateRuntimeRoot.create({
prefix: "rea-capture-environment-",
});
runtimePath = runtime.path;
return runtime;
},
);
onTestFinished(() => decoder.close());
for (const selected of ["first", "second"]) {
environment.REA_CAPTURE_TEST_VALUE = selected;
const result = await decoder.inspect(
inspectWebNetworkCaptureInputSchema.parse({
capture_path: path,
format: "har",
}),
);
expect(result.ok).toBe(true);
expect(JSON.parse(await readFile(observedPath, "utf8"))).toBe(selected);
if (runtimePath === undefined) throw new Error("runtime was not acquired");
await expect(access(runtimePath)).rejects.toMatchObject({ code: "ENOENT" });
}
});
it.skipIf(process.platform === "win32")(
"binds independently selected mitmproxy configuration before runtime preparation",
async () => {
const root = await mkdtemp(join(tmpdir(), "rea-mitmproxy-environment-"));
onTestFinished(() => rm(root, { recursive: true, force: true }));
const capturePath = join(root, "capture.mitm");
const observedPath = join(root, "observed.json");
await writeFile(capturePath, "inert selected capture");
const first = join(root, "first");
const second = join(root, "second");
const value = {
...decodeHarCapture(JSON.stringify(historicalHar()), []),
decoder: MITMPROXY_CAPTURE_PROVIDER_IDENTITY,
};
for (const command of [first, second]) {
await writeFile(
command,
`#!${process.execPath}
const fs = require("node:fs");
const request = JSON.parse(fs.readFileSync(process.argv.find(a => a.startsWith("rea_request_path=")).slice("rea_request_path=".length), "utf8"));
fs.writeFileSync(${JSON.stringify(observedPath)}, JSON.stringify({ command: ${JSON.stringify(command)}, host: process.env.REA_CAPTURE_TEST_VALUE }));
fs.writeFileSync(request.reply_path, ${JSON.stringify(JSON.stringify({ ok: true, value }))});
`,
{ mode: 0o700 },
);
}
// Exercise the Linux adapter gate while the actual owned inert child uses this host.
const command = MitmproxyCaptureAdapter.prototype.command;
vi.spyOn(MitmproxyCaptureAdapter.prototype, "command").mockImplementation(
function (this: MitmproxyCaptureAdapter, request, runtime) {
const platform = Object.getOwnPropertyDescriptor(process, "platform")!;
Object.defineProperty(process, "platform", {
...platform,
value: "linux",
});
try {
return command.call(this, request, runtime);
} finally {
Object.defineProperty(process, "platform", platform);
}
},
);
onTestFinished(() => {
vi.restoreAllMocks();
});
const adapterEnvironment = { REA_MITMDUMP_COMMAND: first };
const hostEnvironment = {
...process.env,
REA_MITMDUMP_COMMAND: "independent-host-setting",
REA_CAPTURE_TEST_VALUE: "first-host",
};
let runtimePath: string | undefined;
const decoder = new HistoricalCaptureDecoder(
[new MitmproxyCaptureAdapter(adapterEnvironment)],
hostEnvironment,
async () => {
adapterEnvironment.REA_MITMDUMP_COMMAND = second;
hostEnvironment.REA_CAPTURE_TEST_VALUE = "changed-during-preparation";
const runtime = await PrivateRuntimeRoot.create({
prefix: "rea-mitmproxy-environment-",
});
runtimePath = runtime.path;
return runtime;
},
);
onTestFinished(() => decoder.close());
for (const [selectedCommand, selectedHost] of [
[first, "first-host"],
[second, "second-host"],
] as const) {
adapterEnvironment.REA_MITMDUMP_COMMAND = selectedCommand;
hostEnvironment.REA_CAPTURE_TEST_VALUE = selectedHost;
const result = await decoder.inspect(
inspectWebNetworkCaptureInputSchema.parse({
capture_path: capturePath,
format: "mitmproxy",
}),
);
expect(
result.ok,
result.ok ? "" : JSON.stringify(projectAnalysisError(result.error)),
).toBe(true);
expect(JSON.parse(await readFile(observedPath, "utf8"))).toEqual({
command: selectedCommand,
host: selectedHost,
});
if (runtimePath === undefined)
throw new Error("runtime was not acquired");
await expect(access(runtimePath)).rejects.toMatchObject({
code: "ENOENT",
});
}
},
);
const expectOwnedDecoderPrimary = (
error: AnalysisError,
outcome: "cancelled" | "process",
reason: unknown,
) => {
const primary = primaryAnalysisError(error);
if (outcome === "cancelled") {
expect(primary._tag).toBe("AnalysisCancelledError");
expect(primary.cause).toBe(reason);
} else {
expect(primary.diagnostics).toMatchObject({
exit_code: 7,
stderr: "authored workload failure",
});
}
};
it.each(["cancelled", "process"] as const)(
"retains an unresolved decoder and its root across concurrent inspection and shutdown (%s)",
async (outcome) => {
const root = await mkdtemp(join(tmpdir(), "rea-capture-owned-cleanup-"));
onTestFinished(() => rm(root, { recursive: true, force: true }));
const capturePath = join(root, "capture.har");
const markerPath = join(root, "started.json");
const finishPath = join(root, "finish");
const text = JSON.stringify(historicalHar());
await writeFile(capturePath, text);
const peerEntered = createDeferred<void>();
const peerContinue = createDeferred<void>();
const controller = new AbortController();
const reason = { request: "cancel owned inert decoder" };
let targetPid: number | undefined;
let targetOwner: ProviderProcessSupervisor | undefined;
let denied = true;
let targetStops = 0;
const stop = ProviderProcessSupervisor.prototype.stop;
vi.spyOn(ProviderProcessSupervisor.prototype, "stop").mockImplementation(
function (this: ProviderProcessSupervisor, options) {
if (this.launch.process.pid === targetPid) {
targetOwner = this;
targetStops++;
if (denied)
return Promise.resolve({
status: "incomplete",
reason: "controlled stop refusal",
});
}
return stop.call(this, options);
},
);
let calls = 0;
let roots = 0;
let targetRuntime: string | undefined;
let targetRootCloses = 0;
let denyRoot = false;
const decoder = new HistoricalCaptureDecoder(
[
{
format: "har",
identity: HAR_CAPTURE_PROVIDER_IDENTITY,
command: async (_, runtimePath) => {
if (calls++ === 0)
return {
command: process.execPath,
arguments: [
"-e",
`const fs = require("node:fs"); fs.writeFileSync(process.argv[1], JSON.stringify(process.pid)); setInterval(() => { if (fs.existsSync(process.argv[2])) { process.stderr.write("authored workload failure"); process.exit(7); } }, 10)`,
markerPath,
finishPath,
],
};
peerEntered.resolve(undefined);
await peerContinue.promise;
await writeFile(
join(runtimePath, "reply.json"),
JSON.stringify({ ok: true, value: decodeHarCapture(text, []) }),
);
return { command: process.execPath, arguments: ["-e", ""] };
},
},
],
process.env,
async () => {
const runtime = await PrivateRuntimeRoot.create({
prefix: "capture-private-runtime-",
});
if (roots++ !== 0) return runtime;
targetRuntime = runtime.path;
return {
path: runtime.path,
close: async () => {
targetRootCloses++;
if (denyRoot) throw new Error("controlled root close refusal");
await runtime.close();
},
};
},
);
onTestFinished(async () => {
denied = false;
denyRoot = false;
peerContinue.resolve(undefined);
await targetOwner?.stop();
await decoder.close();
vi.restoreAllMocks();
});
const input = inspectWebNetworkCaptureInputSchema.parse({
capture_path: capturePath,
format: "har",
sensitive_values: ["capture-private-runtime"],
});
const target = decoder.inspect(input, { signal: controller.signal });
await waitFor(async () => {
targetPid = JSON.parse(await readFile(markerPath, "utf8"));
});
const peer = decoder.inspect(input);
await peerEntered.promise;
if (outcome === "cancelled") controller.abort(reason);
else await writeFile(finishPath, "finish workload");
const failed = await target;
if (failed.ok) throw new Error("cancelled decoder must fail");
expect(targetRootCloses).toBe(0);
expectOwnedDecoderPrimary(failed.error, outcome, reason);
expect(failed.error.partialObservation).toMatchObject({
kind: "file-snapshot-hash",
path: capturePath,
bytes: Buffer.byteLength(text),
sha256: expect.stringMatching(/^[a-f0-9]{64}$/),
});
expect(projectAnalysisError(failed.error).code).toBe("cleanup_incomplete");
expect(JSON.stringify(projectAnalysisError(failed.error))).not.toContain(
"capture-private-runtime",
);
if (targetRuntime === undefined) throw new Error("runtime missing");
await expect(access(targetRuntime)).resolves.toBeUndefined();
expect(targetOwner?.launch.process.exitCode).toBe(
outcome === "cancelled" ? null : 7,
);
const closing = decoder.close().then(
() => undefined,
(cause) => cause,
);
peerContinue.resolve(undefined);
expect((await peer).ok).toBe(true);
expect(await closing).toBeInstanceOf(Error);
expect(targetRootCloses).toBe(0);
denied = false;
denyRoot = true;
await expect(decoder.close()).rejects.toBeInstanceOf(Error);
expect(targetRootCloses).toBe(1);
const releasedStops = targetStops;
denyRoot = false;
await decoder.close();
expect(targetStops).toBe(releasedStops);
await expect(access(targetRuntime)).rejects.toMatchObject({
code: "ENOENT",
});
expect(projectAnalysisError(failed.error).code).not.toBe(
"cleanup_incomplete",
);
expectOwnedDecoderPrimary(failed.error, outcome, reason);
expect(projectAnalysisError(failed.error).code).toBe(
outcome === "cancelled" ? "cancelled" : "execution_failure",
);
},
);
it("applies a non-default capture deadline and releases its runtime", async () => {
const root = await mkdtemp(join(tmpdir(), "rea-capture-deadline-"));
onTestFinished(() => rm(root, { recursive: true, force: true }));
const path = join(root, "capture.har");
await writeFile(path, JSON.stringify(historicalHar()));
let runtimePath: string | undefined;
const decoder = new HistoricalCaptureDecoder(
[
{
format: "har",
identity: HAR_CAPTURE_PROVIDER_IDENTITY,
command: () =>
Promise.resolve({
command: process.execPath,
arguments: ["-e", "setInterval(() => {}, 1_000_000)"],
}),
},
],
process.env,
async () => {
const runtime = await PrivateRuntimeRoot.create({
prefix: "rea-capture-deadline-",
});
runtimePath = runtime.path;
return runtime;
},
);
const result = await decoder.inspect(
inspectWebNetworkCaptureInputSchema.parse({
capture_path: path,
format: "har",
capture_timeout_ms: 250,
}),
);
if (result.ok) throw new Error("expected capture timeout");
expect(result.error._tag).toBe("AnalysisTimeoutError");
expect(result.error.userMessage).toContain("250");
expect(result.error.userMessage).toContain("capture_timeout_ms");
if (runtimePath === undefined) throw new Error("runtime was not acquired");
await expect(access(runtimePath)).rejects.toMatchObject({ code: "ENOENT" });
});
it.each([true, false])(
"binds decoder replies to the complete selected provider identity (matching name: %s)",
async (matching) => {
const root = await mkdtemp(join(tmpdir(), "rea-capture-identity-"));
onTestFinished(() => rm(root, { recursive: true, force: true }));
const path = join(root, "capture.har");
const text = JSON.stringify(historicalHar());
await writeFile(path, text);
const decoder = new HistoricalCaptureDecoder(
[
{
format: "har",
identity: HAR_CAPTURE_PROVIDER_IDENTITY,
command: async (_, runtimePath) => {
const value = decodeHarCapture(text, []);
if (!matching) value.decoder.name = "different adapter";
await writeFile(
join(runtimePath, "reply.json"),
JSON.stringify({ ok: true, value }),
);
return { command: process.execPath, arguments: ["-e", ""] };
},
},
],
process.env,
);
const result = await decoder.inspect(
inspectWebNetworkCaptureInputSchema.parse({
capture_path: path,
format: "har",
}),
);
expect(result.ok).toBe(matching);
if (!result.ok) expect(result.error._tag).toBe("AnalysisOutputError");
else expect(result.value.decoder).toEqual(HAR_CAPTURE_PROVIDER_IDENTITY);
},
);
it("classifies an oversized selected capture before creating an owned decoder", async () => {
const root = await mkdtemp(join(tmpdir(), "rea-historical-limit-"));
onTestFinished(() => rm(root, { recursive: true, force: true }));
const path = join(root, "input.har");
await writeFile(path, "");
await truncate(path, WEB_NETWORK_CAPTURE_LIMITS.inputBytes + 1);
const decoder = new HistoricalCaptureDecoder(
[
{
format: "har",
identity: HAR_CAPTURE_PROVIDER_IDENTITY,
command: async () => {
throw new Error("Oversized input must not launch decoding");
},
},
],
process.env,
);
const result = await decoder.inspect(
inspectWebNetworkCaptureInputSchema.parse({
capture_path: path,
format: "har",
}),
);
if (result.ok) throw new Error("Oversized input must fail");
expect(result.error._tag).toBe("AnalysisInputError");
expect(projectAnalysisError(result.error)).toMatchObject({
category: "invalid_input",
details: {
issues: [
{
path: ["capture_path"],
reason: "out_of_range",
expected: {
maximum_capture_bytes: WEB_NETWORK_CAPTURE_LIMITS.inputBytes,
},
},
],
},
});
});
it("retains a failed capture reader and retries it before a fresh load", async () => {
const root = await mkdtemp(join(tmpdir(), "rea-capture-reader-close-"));
onTestFinished(() => rm(root, { recursive: true, force: true }));
const path = join(root, "input.har");
await writeFile(path, JSON.stringify(historicalHar()));
const originalClose = OwnedFileHandle.prototype.close;
const close = vi.spyOn(OwnedFileHandle.prototype, "close");
let allowClose = false;
let closeAttempts = 0;
close.mockImplementation(async function (this: OwnedFileHandle) {
closeAttempts += 1;
if (!allowClose) throw new Error("injected capture reader close failure");
await originalClose.call(this);
});
let decoderCalls = 0;
const decoder = new HistoricalCaptureDecoder(
[
{
format: "har",
identity: HAR_CAPTURE_PROVIDER_IDENTITY,
command: async () => {
decoderCalls += 1;
return {
command: process.execPath,
arguments: ["-e", "process.exit(0)"],
};
},
},
],
process.env,
);
const input = inspectWebNetworkCaptureInputSchema.parse({
capture_path: path,
format: "har",
});
try {
const first = await decoder.inspect(input);
if (first.ok) throw new Error("Reader close failure must fail inspection");
expect(first.error.cleanupIncomplete).toBe(true);
expect(first.error.cleanupResources).toContain(path);
expect(decoderCalls).toBe(0);
const refused = await decoder.inspect(input);
if (refused.ok) throw new Error("Fresh read must wait for owner cleanup");
expect(refused.error.cleanupIncomplete).toBe(true);
expect(refused.error.cleanupResources).toContain(path);
expect(decoderCalls).toBe(0);
expect(closeAttempts).toBe(2);
allowClose = true;
await decoder.close();
expect(closeAttempts).toBe(3);
expect(first.error.cleanupIncomplete).toBe(false);
expect(first.error.cleanupResources).toEqual([]);
} finally {
allowClose = true;
await decoder.close().catch(() => undefined);
close.mockRestore();
}
});
it("does not misclassify decoder filesystem failures as missing selected input", async () => {
const root = await mkdtemp(join(tmpdir(), "rea-historical-command-"));
onTestFinished(() => rm(root, { recursive: true, force: true }));
const path = join(root, "input.har");
await writeFile(path, JSON.stringify(historicalHar()));
const decoder = new HistoricalCaptureDecoder(
[
{
format: "har",
identity: HAR_CAPTURE_PROVIDER_IDENTITY,
command: async () => {
throw Object.assign(
new Error("Configured decoder command file missing"),
{ code: "ENOENT" },
);
},
},
],
process.env,
);
const result = await decoder.inspect(
inspectWebNetworkCaptureInputSchema.parse({
capture_path: path,
format: "har",
}),
);
if (result.ok) throw new Error("Failed decoder command must fail");
expect(result.error._tag).toBe("ProviderAdapterError");
expect(projectAnalysisError(result.error)).toMatchObject({
details: {
diagnostics: {
phase: "decoder",
reason: "Configured decoder command file missing",
},
},
});
});
it.each(["missing-capture", "missing-reply", "failed-command"])(
"redacts declared paths and diagnostics while preserving the %s failure",
async (mode) => {
const root = await mkdtemp(join(tmpdir(), "rea-historical-sensitive-"));
onTestFinished(() => rm(root, { recursive: true, force: true }));
const path = join(root, "explicit-private-value.har");
if (mode !== "missing-capture")
await writeFile(path, JSON.stringify(historicalHar()));
const decoder = new HistoricalCaptureDecoder(
[
{
format: "har",
identity: HAR_CAPTURE_PROVIDER_IDENTITY,
command: async () => ({
command: process.execPath,
arguments: [
"-e",
mode === "failed-command"
? 'process.stderr.write("explicit-private-value ordinary diagnostic"); process.exit(2)'
: "process.exit(0)",
],
}),
},
],
process.env,
);
const result = await decoder.inspect(
inspectWebNetworkCaptureInputSchema.parse({
capture_path: path,
format: "har",
sensitive_values: ["explicit-private-value", "REDACTED"],
}),
);
if (result.ok) throw new Error("Failure required");
const projected = projectAnalysisError(result.error);
const serialized = JSON.stringify(projected);
expect(serialized).not.toContain("explicit-private-value");
expect(serialized).not.toContain("REDACTED");
expect(result.error._tag).toBe(
mode === "missing-capture"
? "AnalysisInputError"
: mode === "missing-reply"
? "AnalysisOutputError"
: "ProviderAdapterError",
);
if (mode === "missing-capture") expect(serialized).toContain("ENOENT");
if (mode === "failed-command")
expect(serialized).toContain('"exit_code":2');
},
);
it("reports an absent owned reply as output failure and removes its private snapshot root", async () => {
const root = await mkdtemp(join(tmpdir(), "rea-historical-decoder-"));
onTestFinished(() => rm(root, { recursive: true, force: true }));
const path = join(root, "input.har");
await writeFile(path, JSON.stringify(historicalHar()));
let privatePath: string | undefined;
const decoder = new HistoricalCaptureDecoder(
[
{
format: "har",
identity: HAR_CAPTURE_PROVIDER_IDENTITY,
command: async (_, runtimePath) => {
privatePath = runtimePath;
return {
command: process.execPath,
arguments: ["-e", "process.exit(0)"],
};
},
},
],
process.env,
);
const result = await decoder.inspect(
inspectWebNetworkCaptureInputSchema.parse({
capture_path: path,
format: "har",
}),
);
if (result.ok) throw new Error("Owned reply is required");
expect(result.error._tag).toBe("AnalysisOutputError");
expect(result.error.message).toContain("ENOENT");
if (privatePath === undefined)
throw new Error("Private root was not acquired");
await expect(access(privatePath)).rejects.toMatchObject({ code: "ENOENT" });
});
it("cancels after snapshot acquisition before launch and removes private input declarations", async () => {
const root = await mkdtemp(join(tmpdir(), "rea-historical-cancel-"));
onTestFinished(() => rm(root, { recursive: true, force: true }));
const path = join(root, "input.har");
await writeFile(path, JSON.stringify(historicalHar()));
let privatePath: string | undefined;
const controller = new AbortController();
const decoder = new HistoricalCaptureDecoder(
[
{
format: "har",
identity: HAR_CAPTURE_PROVIDER_IDENTITY,
command: async (_, runtimePath) => {
privatePath = runtimePath;
controller.abort();
return {
command: process.execPath,
arguments: ["-e", "process.exit(3)"],
};
},
},
],
process.env,
);
const result = await decoder.inspect(
inspectWebNetworkCaptureInputSchema.parse({
capture_path: path,
format: "har",
sensitive_values: ["explicit-private-declaration"],
}),
{ signal: controller.signal },
);
if (result.ok) throw new Error("Cancelled acquisition must fail");
expect(result.error._tag).toBe("AnalysisCancelledError");
if (privatePath === undefined)
throw new Error("Private root was not acquired");
await expect(access(privatePath)).rejects.toMatchObject({ code: "ENOENT" });
});
it("preserves the exact cancellation reason observed during final runtime close", async () => {
const root = await mkdtemp(join(tmpdir(), "rea-historical-final-cancel-"));
onTestFinished(() => rm(root, { recursive: true, force: true }));
const path = join(root, "input.har");
const text = JSON.stringify(historicalHar());
await writeFile(path, text);
const controller = new AbortController();
const reason = { request: "cancel during runtime close" };
const decoder = new HistoricalCaptureDecoder(
[
{
format: "har",
identity: HAR_CAPTURE_PROVIDER_IDENTITY,
command: async (_, runtimePath) => {
await writeFile(
join(runtimePath, "reply.json"),
JSON.stringify({ ok: true, value: decodeHarCapture(text, []) }),
);
return {
command: process.execPath,
arguments: ["-e", "process.exit(0)"],
};
},
},
],
process.env,
async () => {
const runtime = await PrivateRuntimeRoot.create({
prefix: "rea-final-cancel-proof-",
});
return {
path: runtime.path,
close: async () => {
controller.abort(reason);
await runtime.close();
},
};
},
);
const result = await decoder.inspect(
inspectWebNetworkCaptureInputSchema.parse({
capture_path: path,
format: "har",
}),
{ signal: controller.signal },
);
if (result.ok) throw new Error("Finalization cancellation must fail");
expect(result.error._tag).toBe("AnalysisCancelledError");
expect(result.error.cause).toBe(reason);
expect(result.error.partialObservation).toMatchObject({
artifact: { path, sha256: expect.any(String) },
records: [{ ordinal: 0 }],
});
});
it("retains completed capture facts and binds final root cleanup to its retry lease", async () => {
const root = await mkdtemp(join(tmpdir(), "rea-historical-report-cleanup-"));
onTestFinished(() => rm(root, { recursive: true, force: true }));
const path = join(root, "input.har");
const text = JSON.stringify(historicalHar());
await writeFile(path, text);
let runtimePath: string | undefined;
let allowClose = false;
let runtime: PrivateRuntimeRoot | undefined;
const decoder = new HistoricalCaptureDecoder(
[
{
format: "har",
identity: HAR_CAPTURE_PROVIDER_IDENTITY,
command: async (_, path) => {
await writeFile(
join(path, "reply.json"),
JSON.stringify({ ok: true, value: decodeHarCapture(text, []) }),
);
return {
command: process.execPath,
arguments: ["-e", "process.exit(0)"],
};
},
},
],
process.env,
async () => {
runtime = await PrivateRuntimeRoot.create({
prefix: "rea-report-cleanup-proof-",
});
runtimePath = runtime.path;
onTestFinished(() => runtime?.close());
return {
path: runtime.path,
close: async () => {
if (!allowClose)
throw new Error("injected private root close failure");
await runtime?.close();
},
};
},
);
const result = await decoder.inspect(
inspectWebNetworkCaptureInputSchema.parse({
capture_path: path,
format: "har",
}),
);
if (result.ok) throw new Error("Root close failure must be reported");
expect(result.error.cleanupIncomplete).toBe(true);
expect(runtimePath).toBeDefined();
expect(result.error.cleanupResources).toContain(runtimePath);
expect(result.error.partialObservation).toMatchObject({
artifact: { path, sha256: expect.any(String) },
records: [{ ordinal: 0 }],
});
allowClose = true;
await decoder.close();
expect(result.error.cleanupIncomplete).toBe(false);
expect(result.error.cleanupResources).toEqual([]);
});
it("keeps late cancellation primary when runtime close also fails, then clears on retry", async () => {
const root = await mkdtemp(join(tmpdir(), "rea-historical-cancel-cleanup-"));
onTestFinished(() => rm(root, { recursive: true, force: true }));
const path = join(root, "input.har");
const text = JSON.stringify(historicalHar());
await writeFile(path, text);
const controller = new AbortController();
const reason = { request: "cancel during failed root close" };
let runtime: PrivateRuntimeRoot | undefined;
let closeAttempts = 0;
const decoder = new HistoricalCaptureDecoder(
[
{
format: "har",
identity: HAR_CAPTURE_PROVIDER_IDENTITY,
command: async (_, runtimePath) => {
await writeFile(
join(runtimePath, "reply.json"),
JSON.stringify({ ok: true, value: decodeHarCapture(text, []) }),
);
return {
command: process.execPath,
arguments: ["-e", "process.exit(0)"],
};
},
},
],
process.env,
async () => {
runtime = await PrivateRuntimeRoot.create({
prefix: "rea-cancel-cleanup-proof-",
});
onTestFinished(() => runtime?.close());
return {
path: runtime.path,
close: async () => {
closeAttempts += 1;
if (closeAttempts === 1) {
controller.abort(reason);
throw new Error("injected close failure after cancellation");
}
await runtime?.close();
},
};
},
);
const result = await decoder.inspect(
inspectWebNetworkCaptureInputSchema.parse({
capture_path: path,
format: "har",
}),
{ signal: controller.signal },
);
if (result.ok) throw new Error("Cancellation and failed close must fail");
expect(result.error._tag).toBe("ProviderAdapterError");
expect(result.error.cleanupPrimary?._tag).toBe("AnalysisCancelledError");
expect(result.error.cleanupPrimary?.cause).toBe(reason);
expect(JSON.stringify(result.error.diagnostics)).not.toContain(
"partial_observation",
);
expect(result.error.partialObservation).toMatchObject({
artifact: { path, sha256: expect.any(String) },
records: [{ ordinal: 0 }],
});
expect(result.error.cleanupIncomplete).toBe(true);
expect(result.error.cleanupResources).toContain(runtime?.path);
await decoder.close();
expect(closeAttempts).toBe(2);
expect(result.error.cleanupIncomplete).toBe(false);
expect(result.error.cleanupResources).toEqual([]);
});
it.each([
{ reason: "input-limit", tag: "AnalysisInputError" },
{ reason: "expanded-limit", tag: "AnalysisInputError" },
{ reason: "resource-limit", tag: "AnalysisResourceConstraintError" },
{ reason: "decoder", tag: "ProviderAdapterError" },
{ reason: "limit", tag: "AnalysisOutputError" },
])(
"preserves $reason decoder failures through the public error boundary",
async ({ reason, tag }) => {
const root = await mkdtemp(join(tmpdir(), "rea-historical-reply-"));
onTestFinished(() => rm(root, { recursive: true, force: true }));
const path = join(root, "input.har");
await writeFile(path, JSON.stringify(historicalHar()));
let privatePath: string | undefined;
const decoder = new HistoricalCaptureDecoder(
[
{
format: "har",
identity: HAR_CAPTURE_PROVIDER_IDENTITY,
command: async (_, runtimePath) => {
privatePath = runtimePath;
await writeFile(
join(runtimePath, "reply.json"),
JSON.stringify({
ok: false,
reason,
message: "Specific decoder constraint",
pointer: "/extension/child",
}),
);
return {
command: process.execPath,
arguments: ["-e", "process.exit(0)"],
};
},
},
],
process.env,
);
const result = await decoder.inspect(
inspectWebNetworkCaptureInputSchema.parse({
capture_path: path,
format: "har",
}),
);
if (result.ok) throw new Error("Failure required");
expect(result.error._tag).toBe(tag);
const projected = projectAnalysisError(result.error);
if (reason === "input-limit") {
expect(projected).toMatchObject({
category: "invalid_input",
details: {
issues: [
{
path: ["capture_path", "/extension/child"],
reason: "out_of_range",
expected: {
maximum_capture_nesting: WEB_NETWORK_CAPTURE_LIMITS.depth,
},
},
],
},
});
} else if (reason === "expanded-limit") {
expect(projected).toMatchObject({
category: "invalid_input",
details: {
issues: [
{
path: ["capture_path", "/extension/child"],
reason: "out_of_range",
expected: {
maximum_expanded_capture_bytes:
WEB_NETWORK_CAPTURE_LIMITS.inputBytes,
},
},
],
},
});
} else if (reason === "limit") {
expect(projected).toMatchObject({
code: "unreadable_output",
retryable: false,
message: expect.stringContaining(
String(WEB_NETWORK_CAPTURE_LIMITS.outputBytes),
),
details: {
diagnostics: {
maximum_reply_bytes: WEB_NETWORK_CAPTURE_LIMITS.outputBytes,
},
},
});
expect(projected.remediation.action).toContain(
`Increase max_reply_bytes above ${String(WEB_NETWORK_CAPTURE_LIMITS.outputBytes)}`,
);
expect(projected.remediation.action).toContain(
"next inspect_web_network_capture call",
);
expect(projected.remediation.action).toContain(
"do not recreate a completed report from a refused decode",
);
expect(projected.remediation.action).not.toContain("rea doctor");
expect(result.error.partialObservation).toMatchObject({
kind: "file-snapshot-hash",
path,
sha256: expect.stringMatching(/^[a-f0-9]{64}$/),
});
} else if (tag === "ProviderAdapterError") {
expect(projected).toMatchObject({
details: {
diagnostics: {
phase: "decoder",
reason: "Specific decoder constraint",
failure_kind: reason,
pointer: "/extension/child",
},
},
});
}
if (privatePath === undefined)
throw new Error("Private root was not acquired");
await expect(access(privatePath)).rejects.toMatchObject({ code: "ENOENT" });
},
);
it.skipIf(process.platform === "win32" || process.getuid?.() === 0)(
"reports a real filesystem permission denial separately from missing capture input",
async () => {
const root = await mkdtemp(join(tmpdir(), "rea-historical-denied-"));
onTestFinished(() => rm(root, { recursive: true, force: true }));
const path = join(root, "unreadable.har");
await writeFile(path, JSON.stringify(historicalHar()), { mode: 0o000 });
const decoder = new HistoricalCaptureDecoder(
[
{
format: "har",
identity: HAR_CAPTURE_PROVIDER_IDENTITY,
command: async () => {
throw new Error("Permission-denied input must not launch decoding");
},
},
],
process.env,
);
const result = await decoder.inspect(
inspectWebNetworkCaptureInputSchema.parse({
capture_path: path,
format: "har",
}),
);
await chmod(path, 0o600);
if (result.ok) throw new Error("Permission denial required");
expect(projectAnalysisError(result.error)).toMatchObject({
code: "access_denied",
category: "unavailable",
retryable: false,
details: {
operation: "inspect_web_network_capture",
path,
system_code: "EACCES",
},
});
expect(projectAnalysisError(result.error).remediation.action).toContain(
"read access",
);
},
);
it.each(["format", "process"])(
"preserves the structured %s failure when runtime cleanup fails",
async (kind) => {
const root = await mkdtemp(join(tmpdir(), "rea-historical-cleanup-"));
onTestFinished(() => rm(root, { recursive: true, force: true }));
const path = join(root, "capture-private.har");
await writeFile(path, JSON.stringify(historicalHar()));
const decoder = new HistoricalCaptureDecoder(
[
{
format: "har",
identity: HAR_CAPTURE_PROVIDER_IDENTITY,
command: async (_, runtimePath) => {
if (kind === "format")
await writeFile(
join(runtimePath, "reply.json"),
JSON.stringify({
ok: false,
reason: "format",
message: "Malformed retained record",
pointer: "/metadata/capture-private",
}),
);
return {
command: process.execPath,
arguments: [
"-e",
kind === "format"
? "process.exit(0)"
: 'process.stderr.write("Specific provider fault"); process.exit(3)',
],
};
},
},
],
process.env,
async () => {
const runtime = await PrivateRuntimeRoot.create({
prefix: "rea-cleanup-proof-",
});
onTestFinished(() => runtime.close());
return {
path: runtime.path,
close: async () => {
throw new Error("Deliberate cleanup denial");
},
};
},
);
const result = await decoder.inspect(
inspectWebNetworkCaptureInputSchema.parse({
capture_path: path,
format: "har",
sensitive_values: ["capture-private"],
}),
);
if (result.ok) throw new Error("Cleanup failure required");
expect(result.error.cleanupPrimary?._tag).toBe(
kind === "format" ? "AnalysisInputError" : "ProviderAdapterError",
);
const projected = projectAnalysisError(result.error);
expect(projected).toMatchObject({
code: "cleanup_incomplete",
details: {
diagnostics: {
primary_error:
kind === "format"
? {
category: "invalid_input",
details: {
issues: [
{
path: ["capture_path", "/metadata"],
reason: "invalid_format",
message: "Malformed retained record",
},
],
},
}
: {
code: "execution_failure",
details: {
diagnostics: {
phase: "decoder",
exit_code: 3,
stderr: "Specific provider fault",
},
},
},
},
},
});
expect(JSON.stringify(projected)).not.toContain("capture-private");
},
);
it.each([
{ closeFails: false, reply: "capture" },
{ closeFails: true, reply: "capture" },
{ closeFails: false, reply: "malformed" },
{ closeFails: true, reply: "malformed" },
{ closeFails: false, reply: "malformed UTF-8" },
{ closeFails: true, reply: "malformed UTF-8" },
{ closeFails: false, reply: "malformed schema" },
{ closeFails: true, reply: "malformed schema" },
{ closeFails: false, reply: "refusal" },
{ closeFails: true, reply: "refusal" },
])(
"retains validated reply completion through descriptor cancellation %j",
async ({ closeFails, reply }) => {
const root = await mkdtemp(join(tmpdir(), "rea-reply-finalization-"));
onTestFinished(() => rm(root, { recursive: true, force: true }));
const path = join(root, "input.har");
const text = JSON.stringify(historicalHar());
await writeFile(path, text);
const controller = new AbortController();
const reason = { caller: "reply descriptor close" };
const originalClose = OwnedFileHandle.prototype.close;
let replyPath: string | undefined;
let replyCloses = 0;
const close = vi
.spyOn(OwnedFileHandle.prototype, "close")
.mockImplementation(async function (this: OwnedFileHandle) {
let isReply = false;
if (replyPath !== undefined) {
try {
const named = await stat(replyPath);
const opened = await this.handle.stat();
isReply = named.dev === opened.dev && named.ino === opened.ino;
} catch (cause) {
if ((cause as NodeJS.ErrnoException).code !== "ENOENT") throw cause;
}
}
if (isReply) replyCloses += 1;
if (isReply && replyCloses === 1 && closeFails) {
controller.abort(reason);
throw new Error("controlled reply close denial");
}
await originalClose.call(this);
if (isReply && replyCloses === 1) controller.abort(reason);
});
const decoder = new HistoricalCaptureDecoder(
[
{
format: "har",
identity: HAR_CAPTURE_PROVIDER_IDENTITY,
command: async (_, runtimePath) => {
replyPath = join(runtimePath, "reply.json");
const bytes =
reply === "malformed UTF-8"
? Buffer.concat([
Buffer.from('{"ok":false,"reason":"format","message":"'),
Buffer.from([0xff]),
Buffer.from('","pointer":""}'),
])
: Buffer.from(
reply === "malformed"
? "{"
: JSON.stringify(
reply === "malformed schema"
? { ok: true, value: {} }
: reply === "refusal"
? {
ok: false,
reason: "limit",
message: "Complete reply allowance exceeded",
pointer: "",
}
: { ok: true, value: decodeHarCapture(text, []) },
),
);
return {
command: process.execPath,
arguments: [
"-e",
`require('node:fs').writeFileSync(process.argv[1],Buffer.from(${JSON.stringify(bytes.toString("base64"))},'base64'))`,
replyPath,
],
};
},
},
],
process.env,
);
try {
const result = await decoder.inspect(
inspectWebNetworkCaptureInputSchema.parse({
capture_path: path,
format: "har",
}),
{ signal: controller.signal },
);
if (result.ok)
throw new Error("Expected reply finalization cancellation");
expect(projectAnalysisError(result.error).code).toBe(
closeFails
? "cleanup_incomplete"
: reply === "capture"
? "cancelled"
: "unreadable_output",
);
if (reply !== "capture")
expect(result.error.partialObservation).toMatchObject({
kind: "file-snapshot-hash",
path,
bytes: Buffer.byteLength(text),
sha256: expect.stringMatching(/^[a-f0-9]{64}$/),
});
else
expect(result.error.partialObservation).toMatchObject({
artifact: { path },
records: [{ ordinal: 0 }],
});
await decoder.close();
expect(result.error.cleanupIncomplete).toBe(false);
expect(projectAnalysisError(result.error).code).toBe(
reply === "capture" ? "cancelled" : "unreadable_output",
);
const primary = primaryAnalysisError(result.error);
if (reply !== "capture") {
expect(primary.diagnostics).toMatchObject({
reply_finalization_error: { code: "cancelled" },
});
expect(
primary.secondaryFailures.some(
(failure) =>
failure._tag === "AnalysisCancelledError" &&
failure.cause === reason,
),
).toBe(true);
if (reply === "malformed")
expect(primary.message).toContain("Reply is malformed JSON.");
if (reply === "malformed UTF-8")
expect(primary.message).toContain("Reply is not valid UTF-8.");
if (reply === "malformed schema")
expect(primary.message).toContain("Reply violates its schema");
} else expect(primary.cause).toBe(reason);
expect(replyCloses).toBe(closeFails ? 2 : 1);
} finally {
close.mockRestore();
await decoder.close();
}
},
);
it("excludes normalized native numbers before retaining a completed decoder reply", async () => {
const root = await createTestTempDirectory("rea-native-number-redaction-");
const capturePath = join(root, "capture.mitm");
const original = "controlled native decoder input";
await writeFile(capturePath, original);
const payload = decodeHarCapture(JSON.stringify(historicalHar()), []);
payload.decoder = MITMPROXY_CAPTURE_PROVIDER_IDENTITY;
const record = payload.records[0]!;
record.reported = { metadata: { small: 1e-7, large: 1e20, ordinary: 42 } };
record.binary_fields = [];
record.redactions = [];
record.numeric_literals = [
{ pointer: "/metadata/small", producer_type: "float", literal: "1e-07" },
{ pointer: "/metadata/large", producer_type: "float", literal: "1e+20" },
];
const decoder = new HistoricalCaptureDecoder(
[
{
format: "mitmproxy",
identity: MITMPROXY_CAPTURE_PROVIDER_IDENTITY,
command: async (_, runtime) => ({
command: process.execPath,
arguments: [
"-e",
"require('node:fs').writeFileSync(process.argv[1], process.argv[2])",
join(runtime, "reply.json"),
JSON.stringify({ ok: true, value: payload }),
],
}),
},
],
process.env,
);
onTestFinished(() => decoder.close());
for (const marked of [false, true]) {
const result = await decoder.inspect(
inspectWebNetworkCaptureInputSchema.parse({
capture_path: capturePath,
format: "mitmproxy",
sensitive_values: marked ? ["1e-7", "000000"] : [],
}),
);
if (!result.ok) throw result.error;
const retained = result.value.records[0]!;
expect(retained.reported).toEqual({
metadata: {
small: marked ? null : 1e-7,
large: marked ? null : 1e20,
ordinary: 42,
},
});
expect(retained.numeric_literals).toEqual(
marked ? [] : record.numeric_literals,
);
expect(retained.redactions).toEqual(
marked
? [
{ pointer: "/metadata/small", reason: "explicit-sensitive-value" },
{ pointer: "/metadata/large", reason: "explicit-sensitive-value" },
]
: [],
);
expect(await readFile(capturePath, "utf8")).toBe(original);
}
});