mirror of
https://github.com/morluto/rea
synced 2026-10-28 06:46:47 -04:00
63bf91405c
Deliver complete Evidence directly through MCP with required nullable analysis profiles and immutable per-server delivery settings. Bind selected environments at construction and require typed cleanup outcomes with retained retry ownership. Remove test-only routing, duplicate session and snapshot metadata, producer-field repairs, and ambiguous provider arguments. Separate artifact byte identity from occurrence classification and retain typed source-map and partial native facts across CLI, MCP, and verifier consumers. BREAKING CHANGE: obsolete Evidence envelopes, session aliases, incomplete snapshots, and missing normalized producer facts are no longer accepted.
97 lines
3.4 KiB
TypeScript
97 lines
3.4 KiB
TypeScript
import { readFile, stat, writeFile } from "node:fs/promises";
|
|
import { join } from "node:path";
|
|
|
|
import { describe, expect, it } from "vitest";
|
|
|
|
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
|
|
|
import { createAnalysisExecution } from "../../../src/application/AnalysisProvider.js";
|
|
import {
|
|
readAnalysisSnapshot,
|
|
writeAnalysisSnapshot,
|
|
} from "../../../src/application/binary/AnalysisSnapshotFiles.js";
|
|
import {
|
|
createAnalysisSnapshotEntry,
|
|
parseAnalysisSnapshot,
|
|
snapshotBinding,
|
|
snapshotTarget,
|
|
type AnalysisSnapshot,
|
|
} from "../../../src/domain/analysisSnapshot.js";
|
|
import {
|
|
ANALYSIS_SNAPSHOT_PROFILE as PROFILE,
|
|
ANALYSIS_SNAPSHOT_PROVIDER as PROVIDER,
|
|
ANALYSIS_SNAPSHOT_TARGET as TARGET,
|
|
} from "../../../src/domain/analysisSnapshot.fixture.js";
|
|
import { createEvidence } from "../../../src/domain/evidence.js";
|
|
import { createEvidenceBundle } from "../../../src/domain/evidenceBundle.js";
|
|
|
|
describe("analysis snapshots: persistence", () => {
|
|
it("writes canonical private v2 JSON and rejects changed query identity", async () => {
|
|
const directory = await createTestTempDirectory("rea-snapshot-");
|
|
const path = join(directory, "analysis.json");
|
|
const target = snapshotTarget(TARGET);
|
|
const binding = snapshotBinding(PROFILE);
|
|
const entry = createAnalysisSnapshotEntry({
|
|
target,
|
|
binding,
|
|
operation: "address_name",
|
|
parameters: { address: "0x1000" },
|
|
execution: createAnalysisExecution("main", PROVIDER, {
|
|
analysisProfile: PROFILE,
|
|
rawResult: "main",
|
|
subject: {
|
|
path: TARGET.path,
|
|
sha256: TARGET.sha256,
|
|
format: TARGET.format,
|
|
...(TARGET.architecture === undefined
|
|
? {}
|
|
: { architecture: TARGET.architecture }),
|
|
},
|
|
}),
|
|
});
|
|
const evidence = createEvidence(TARGET, PROVIDER, {
|
|
operation: "address_name",
|
|
parameters: { address: "0x1000" },
|
|
result: "main",
|
|
rawResult: "main",
|
|
analysisProfile: PROFILE,
|
|
});
|
|
const snapshot: AnalysisSnapshot = {
|
|
target,
|
|
binding,
|
|
entries: [entry],
|
|
workflow_entries: [],
|
|
evidence_bundle: createEvidenceBundle([evidence]),
|
|
};
|
|
const written = await writeAnalysisSnapshot(snapshot, path, false);
|
|
expect(written.ok).toBe(true);
|
|
expect((await readFile(path, "utf8")).endsWith("\n")).toBe(true);
|
|
expect((await stat(path)).mode & 0o777).toBe(0o600);
|
|
expect((await readAnalysisSnapshot(path)).ok).toBe(true);
|
|
|
|
const altered: unknown = JSON.parse(await readFile(path, "utf8"));
|
|
if (
|
|
typeof altered !== "object" ||
|
|
altered === null ||
|
|
!("entries" in altered) ||
|
|
!Array.isArray(altered.entries)
|
|
)
|
|
throw new TypeError("fixture snapshot is malformed");
|
|
const first: unknown = altered.entries[0];
|
|
if (
|
|
typeof first !== "object" ||
|
|
first === null ||
|
|
!("parameters" in first) ||
|
|
typeof first.parameters !== "object" ||
|
|
first.parameters === null
|
|
)
|
|
throw new TypeError("fixture entry is malformed");
|
|
Reflect.set(first.parameters, "address", "0x2000");
|
|
await writeFile(path, JSON.stringify(altered));
|
|
const loaded = await readAnalysisSnapshot(path);
|
|
expect(loaded.ok).toBe(false);
|
|
if (!loaded.ok) expect(loaded.error._tag).toBe("EvidenceIntegrityError");
|
|
expect(() => parseAnalysisSnapshot(altered)).toThrow(/identifier/u);
|
|
});
|
|
});
|