mirror of
https://github.com/morluto/rea.git
synced 2026-11-14 18:52:48 +00:00
* refactor(analysis): centralize resource budgets and recovery facts * feat(analysis): expose ASAR and Ghidra runtime admission controls * feat(artifacts): expose reader admission and preserve limited recognition * feat(javascript): expose recoverable semantic precision budgets * feat(web): add recoverable source-map budgets and compact retained views * feat(web): make historical capture decoding budgets recoverable * fix(desktop): enforce selected view policies across capture and export * feat(runtime): make Frida and LLDB retention budgets selectable * feat(native): expose diagnostic budgets and preserve exhaustion causes * feat(managed): expose recoverable snapshot and representation budgets * feat(metadata): make Go and Rust inspection budgets recoverable * feat(wasm): expose representation and producer admissions * feat(evm): expose per-call worker resource budgets * feat(android): make resource and string-pool omissions recoverable * feat(producers): expose command and recorded-capture budgets * docs(analysis): record recovery contracts and integrated validation * fix(docs): link calibration oracle from published verification pages * fix(docs): restore desktop task anchors and receipt links * test(analysis): align fixtures with selectable budget contracts * fix(analysis): remove source-location projector dependency cycle * test(analysis): refresh budget recovery and verifier regressions * test(analysis): preserve format and publication recovery expectations * test(windows): align conformance with owned runtime admission * fix(desktop): preserve selected alias kinds in exported state * test(analysis): align provider fixtures with recoverable budgets * test(desktop): validate emitted alias metadata structurally * fix(ghidra): classify bounded Windows endpoint refusals * test(cli): assert selectable artifact admission recovery * fix(cli): preserve capture provenance in environment builds
257 lines
9.5 KiB
TypeScript
257 lines
9.5 KiB
TypeScript
import { appendFile, writeFile } from "node:fs/promises";
|
|
import { join } from "node:path";
|
|
|
|
import { expect, it, vi } from "vitest";
|
|
|
|
import { createTestTempDirectory } from "../../tests/fixtures/temporaryDirectory.js";
|
|
import { withOwnedRegularFile } from "../filesystem/OwnedRegularFile.js";
|
|
import { ArtifactEmbeddedFormatProbes } from "./ArtifactEmbeddedFormatProbes.js";
|
|
import * as dotnetLayout from "./dotnet/DotnetBundle.js";
|
|
import { dotnetBundleFixture } from "./dotnet/DotnetBundle.fixture.js";
|
|
import { denoMachO } from "./deno/DenoStandalone.fixture.js";
|
|
import * as denoLocation from "./deno/DenoStandaloneLocation.js";
|
|
import * as pckLocation from "./GodotPckLocation.js";
|
|
import { resolveArtifactReaderLimits } from "../domain/artifactReaderLimits.js";
|
|
import { nodeSeaElf } from "./nodeSea/NodeSea.fixture.js";
|
|
|
|
it("readmits cached SEA recognition when the accepted policy changes", async () => {
|
|
const path = join(
|
|
await createTestTempDirectory("rea-probe-policy-"),
|
|
"carrier",
|
|
);
|
|
await writeFile(path, nodeSeaElf({ fuse: "set", ownership: "section" }));
|
|
await withOwnedRegularFile(path, {}, async (source) => {
|
|
const original = new ArtifactEmbeddedFormatProbes(path, source);
|
|
const location = await original.nodeSea();
|
|
expect(location).toBeDefined();
|
|
const lower = new ArtifactEmbeddedFormatProbes(
|
|
path,
|
|
source,
|
|
undefined,
|
|
original.completedFacts(),
|
|
resolveArtifactReaderLimits({ node_sea: { blob_bytes: 1 } }),
|
|
);
|
|
await expect(lower.nodeSea()).rejects.toMatchObject({
|
|
reason: "limit",
|
|
readerLimit: {
|
|
parameter: "artifact_limits.node_sea.blob_bytes",
|
|
effective_value: 1,
|
|
},
|
|
});
|
|
expect(Object.hasOwn(lower.completedFacts(), "nodeSea")).toBe(false);
|
|
const restored = new ArtifactEmbeddedFormatProbes(
|
|
path,
|
|
source,
|
|
undefined,
|
|
lower.completedFacts(),
|
|
resolveArtifactReaderLimits(),
|
|
);
|
|
expect(await restored.nodeSea()).toEqual(location);
|
|
const recognitionLimited = new ArtifactEmbeddedFormatProbes(
|
|
path,
|
|
source,
|
|
undefined,
|
|
restored.completedFacts(),
|
|
resolveArtifactReaderLimits({
|
|
node_sea: { recognition_header_count: 1 },
|
|
}),
|
|
);
|
|
await expect(recognitionLimited.nodeSea()).resolves.toBeUndefined();
|
|
expect(Object.hasOwn(recognitionLimited.completedFacts(), "nodeSea")).toBe(
|
|
false,
|
|
);
|
|
expect(
|
|
recognitionLimited.completedFacts().nodeSeaRecognitionFailure,
|
|
).toMatchObject({
|
|
readerLimit: {
|
|
parameter: "artifact_limits.node_sea.recognition_header_count",
|
|
effective_value: 1,
|
|
required_value: 3,
|
|
},
|
|
});
|
|
const recognitionRestored = new ArtifactEmbeddedFormatProbes(
|
|
path,
|
|
source,
|
|
undefined,
|
|
recognitionLimited.completedFacts(),
|
|
resolveArtifactReaderLimits({
|
|
node_sea: { recognition_header_count: 3 },
|
|
}),
|
|
);
|
|
expect(await recognitionRestored.nodeSea()).toEqual(location);
|
|
expect(
|
|
recognitionRestored.completedFacts().nodeSeaRecognitionFailure,
|
|
).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
it("distinguishes examined absence from unexamined formats and honors cancellation on a cached result", async () => {
|
|
const root = await createTestTempDirectory("rea-embedded-probe-facts-");
|
|
const path = join(root, "plain");
|
|
await writeFile(path, "plain bytes without an embedded archive");
|
|
const locate = vi.spyOn(pckLocation, "locateGodotPck");
|
|
try {
|
|
await withOwnedRegularFile(path, {}, async (source) => {
|
|
const controller = new AbortController();
|
|
const probes = new ArtifactEmbeddedFormatProbes(
|
|
path,
|
|
source,
|
|
controller.signal,
|
|
);
|
|
await expect(probes.godotPck()).resolves.toBeUndefined();
|
|
const facts = probes.completedFacts();
|
|
expect(facts.godotPck).toBeNull();
|
|
expect(Object.hasOwn(facts, "nodeSea")).toBe(false);
|
|
expect(Object.hasOwn(facts, "denoStandalone")).toBe(false);
|
|
expect(Object.hasOwn(facts, "pyInstaller")).toBe(false);
|
|
const resumed = new ArtifactEmbeddedFormatProbes(
|
|
path,
|
|
source,
|
|
controller.signal,
|
|
facts,
|
|
);
|
|
await expect(resumed.godotPck()).resolves.toBeUndefined();
|
|
expect(locate).toHaveBeenCalledTimes(1);
|
|
const reason = new Error("cancel cached observation");
|
|
controller.abort(reason);
|
|
await expect(resumed.godotPck()).rejects.toMatchObject({
|
|
reason: "cancelled",
|
|
cause: reason,
|
|
});
|
|
expect(locate).toHaveBeenCalledTimes(1);
|
|
});
|
|
} finally {
|
|
locate.mockRestore();
|
|
}
|
|
});
|
|
|
|
it("leaves a failed probe unexamined so a subsequent successful observation can be retained", async () => {
|
|
const root = await createTestTempDirectory("rea-embedded-probe-failure-");
|
|
const path = join(root, "plain");
|
|
await writeFile(path, "plain bytes without an embedded archive");
|
|
const failure = Object.assign(new Error("injected read failure"), {
|
|
code: "EIO",
|
|
});
|
|
const locate = vi
|
|
.spyOn(pckLocation, "locateGodotPck")
|
|
.mockRejectedValueOnce(failure);
|
|
try {
|
|
await withOwnedRegularFile(path, {}, async (source) => {
|
|
const probes = new ArtifactEmbeddedFormatProbes(path, source);
|
|
await expect(probes.godotPck()).rejects.toBe(failure);
|
|
expect(Object.hasOwn(probes.completedFacts(), "godotPck")).toBe(false);
|
|
await expect(probes.godotPck()).resolves.toBeUndefined();
|
|
expect(probes.completedFacts().godotPck).toBeNull();
|
|
expect(locate).toHaveBeenCalledTimes(2);
|
|
});
|
|
} finally {
|
|
locate.mockRestore();
|
|
}
|
|
});
|
|
|
|
it("reuses a located .NET header only for the same source and honors cached cancellation", async () => {
|
|
const root = await createTestTempDirectory("rea-dotnet-probe-facts-");
|
|
const path = join(root, "host");
|
|
const fixture = dotnetBundleFixture();
|
|
await writeFile(path, fixture.bytes);
|
|
const locate = vi.spyOn(dotnetLayout, "findDotnetBundleHeader");
|
|
try {
|
|
const facts = await withOwnedRegularFile(path, {}, async (source) => {
|
|
const controller = new AbortController();
|
|
const first = new ArtifactEmbeddedFormatProbes(
|
|
path,
|
|
source,
|
|
controller.signal,
|
|
);
|
|
expect(
|
|
Object.hasOwn(first.completedFacts(), "dotnetBundleHeaderOffset"),
|
|
).toBe(false);
|
|
await expect(first.dotnetBundle()).resolves.toBe(fixture.headerOffset);
|
|
const completed = first.completedFacts();
|
|
const resumed = new ArtifactEmbeddedFormatProbes(
|
|
path,
|
|
source,
|
|
controller.signal,
|
|
completed,
|
|
);
|
|
await expect(resumed.dotnetBundle()).resolves.toBe(fixture.headerOffset);
|
|
expect(locate).toHaveBeenCalledTimes(1);
|
|
const reason = new Error("cancel cached .NET observation");
|
|
controller.abort(reason);
|
|
await expect(resumed.dotnetBundle()).rejects.toMatchObject({
|
|
reason: "cancelled",
|
|
cause: reason,
|
|
});
|
|
return completed;
|
|
});
|
|
await appendFile(path, "changed");
|
|
await withOwnedRegularFile(path, {}, async (source) => {
|
|
expect(
|
|
() => new ArtifactEmbeddedFormatProbes(path, source, undefined, facts),
|
|
).toThrow("Root artifact changed before inventory");
|
|
});
|
|
expect(locate).toHaveBeenCalledTimes(1);
|
|
} finally {
|
|
locate.mockRestore();
|
|
}
|
|
});
|
|
|
|
it("keeps a failed .NET probe unexamined before a successful absence observation", async () => {
|
|
const root = await createTestTempDirectory("rea-dotnet-probe-retry-");
|
|
const path = join(root, "plain");
|
|
await writeFile(path, "plain bytes");
|
|
const failure = new Error("injected marker read failure");
|
|
const locate = vi
|
|
.spyOn(dotnetLayout, "findDotnetBundleHeader")
|
|
.mockRejectedValueOnce(failure);
|
|
try {
|
|
await withOwnedRegularFile(path, {}, async (source) => {
|
|
const probes = new ArtifactEmbeddedFormatProbes(path, source);
|
|
await expect(probes.dotnetBundle()).rejects.toBe(failure);
|
|
expect(
|
|
Object.hasOwn(probes.completedFacts(), "dotnetBundleHeaderOffset"),
|
|
).toBe(false);
|
|
await expect(probes.dotnetBundle()).resolves.toBeUndefined();
|
|
expect(probes.completedFacts().dotnetBundleHeaderOffset).toBeNull();
|
|
expect(locate).toHaveBeenCalledTimes(2);
|
|
});
|
|
} finally {
|
|
locate.mockRestore();
|
|
}
|
|
});
|
|
|
|
it("caches a present Deno section and records examined absence", async () => {
|
|
const root = await createTestTempDirectory("rea-deno-probe-facts-");
|
|
const presentPath = join(root, "deno");
|
|
const absentPath = join(root, "plain");
|
|
await writeFile(presentPath, denoMachO());
|
|
await writeFile(absentPath, "plain bytes without a Deno section");
|
|
const locate = vi.spyOn(denoLocation, "locateDenoStandalone");
|
|
try {
|
|
await withOwnedRegularFile(presentPath, {}, async (source) => {
|
|
const probes = new ArtifactEmbeddedFormatProbes(presentPath, source);
|
|
expect(Object.hasOwn(probes.completedFacts(), "denoStandalone")).toBe(
|
|
false,
|
|
);
|
|
const found = await probes.denoStandalone();
|
|
expect(found.status).toBe("present");
|
|
await expect(probes.denoStandalone()).resolves.toBe(found);
|
|
expect(locate).toHaveBeenCalledTimes(1);
|
|
});
|
|
await withOwnedRegularFile(absentPath, {}, async (source) => {
|
|
const probes = new ArtifactEmbeddedFormatProbes(absentPath, source);
|
|
expect(Object.hasOwn(probes.completedFacts(), "denoStandalone")).toBe(
|
|
false,
|
|
);
|
|
await expect(probes.denoStandalone()).resolves.toEqual({
|
|
status: "absent",
|
|
});
|
|
expect(probes.completedFacts().denoStandalone).toEqual({
|
|
status: "absent",
|
|
});
|
|
});
|
|
} finally {
|
|
locate.mockRestore();
|
|
}
|
|
});
|