Files
reverse-engineering-anything/tests/boundary/process/processCaptureComparison.test.ts
T

251 lines
6.7 KiB
TypeScript

import { expect, it } from "vitest";
import {
compareProcessCaptures,
digestProcessCommitment,
type ProcessCapture,
} from "../../../src/domain/processCapture.js";
const emptyCapture = (): ProcessCapture => {
const normalization = {
paths: true,
pids: true,
ports: true,
time_bucket_ms: 10,
patterns: [],
};
const scenario = { executable_sha256: "0".repeat(64) };
const comparisonContract = {};
const shimPlan: readonly unknown[] = [];
const replayPlan = {};
return {
schema_version: 4,
manifest: {
rea_version: "test",
provider_version: "3",
platform: process.platform,
architecture: process.arch,
pty_backend: "node-pty",
started_at: "2026-01-01T00:00:00.000Z",
completed_at: "2026-01-01T00:00:00.001Z",
scenario,
comparison_contract: comparisonContract,
shim_plan: shimPlan,
replay_plan: replayPlan,
full_scenario_sha256: digestProcessCommitment(scenario),
comparison_contract_sha256: digestProcessCommitment(comparisonContract),
executable_sha256: "0".repeat(64),
normalization_sha256: digestProcessCommitment(normalization),
shim_plan_sha256: digestProcessCommitment(shimPlan),
replay_plan_sha256: digestProcessCommitment(replayPlan),
},
normalization,
frames: [],
rendered_frames: [],
interaction_events: [],
exit: { code: 0, signal: null, reason: "exited" },
settlement: {
state: "quiesced",
elapsed_ms: 50,
cleanup_outcome: "not_required",
},
process_samples: [],
filesystem_checkpoints: [
{ name: "before", at_ms: 0, files: [], effects: [], truncated: false },
{
name: "after_settlement",
at_ms: 50,
files: [],
effects: [],
truncated: false,
},
],
shim_events: [],
protocol_events: [],
replay_transitions: [],
reactive_run: null,
event_journal: [],
files_before: [],
files_after: [],
filesystem_effects: [],
truncated: false,
limitations: [],
residual_unknowns: [],
cleanup: {
owned_process_group: "verified",
temporary_root: "removed",
},
};
};
it("classifies missing observations as unknown and one-sided evidence as added", () => {
const base = {
schema_version: 4 as const,
manifest: emptyCapture().manifest,
settlement: emptyCapture().settlement,
normalization: {
paths: true,
pids: true,
ports: true,
time_bucket_ms: 10,
patterns: [],
},
frames: [],
rendered_frames: [],
interaction_events: [],
exit: { code: 0, signal: null, reason: "exited" as const },
process_samples: [],
filesystem_checkpoints: emptyCapture().filesystem_checkpoints,
shim_events: [],
protocol_events: [],
replay_transitions: [],
reactive_run: null,
files_before: [],
files_after: [],
filesystem_effects: [],
truncated: false,
limitations: [],
residual_unknowns: [],
cleanup: {
owned_process_group: "verified" as const,
temporary_root: "removed" as const,
},
};
const added = compareProcessCaptures(base, {
...base,
frames: [{ sequence: 0, at_ms: 0, data: "new" }],
rendered_frames: [
{
sequence: 0,
at_ms: 0,
columns: 3,
rows: 1,
cursor_x: 3,
cursor_y: 0,
active_buffer: "normal",
lines: ["new"],
serialized_state: "new",
},
],
});
expect(added.terminal).toBe("added");
expect(added.status).toBe("changed");
const unknown = compareProcessCaptures(
{ ...base, residual_unknowns: [{ scope: "process", reason: "sampled" }] },
base,
);
expect(unknown.process).toBe("unknown");
expect(unknown.shim).toBe("unchanged");
expect(unknown.status).toBe("unknown");
});
it("compares raw terminal chunks even when rendered states agree", () => {
const capture = {
schema_version: 4 as const,
manifest: emptyCapture().manifest,
settlement: emptyCapture().settlement,
normalization: {
paths: true,
pids: true,
ports: true,
time_bucket_ms: 10,
patterns: [],
},
frames: [{ sequence: 0, at_ms: 0, data: "bar" }],
rendered_frames: [],
interaction_events: [],
exit: { code: 0, signal: null, reason: "exited" as const },
process_samples: [],
filesystem_checkpoints: emptyCapture().filesystem_checkpoints,
shim_events: [],
protocol_events: [],
replay_transitions: [],
reactive_run: null,
files_before: [],
files_after: [],
filesystem_effects: [],
truncated: false,
limitations: [],
residual_unknowns: [],
cleanup: {
owned_process_group: "verified" as const,
temporary_root: "removed" as const,
},
};
const comparison = compareProcessCaptures(capture, {
...capture,
frames: [{ sequence: 0, at_ms: 0, data: "foo\rbar" }],
});
expect(comparison.terminal).toBe("changed");
expect(comparison.first_divergence).toMatchObject({
status: "found",
dimension: "terminal",
});
});
it("keeps filesystem evidence unknown when stable snapshots match", () => {
const capture = {
schema_version: 4 as const,
manifest: emptyCapture().manifest,
settlement: emptyCapture().settlement,
normalization: {
paths: true,
pids: true,
ports: true,
time_bucket_ms: 10,
patterns: [],
},
frames: [],
rendered_frames: [],
interaction_events: [],
exit: { code: 0, signal: null, reason: "exited" as const },
process_samples: [],
filesystem_checkpoints: emptyCapture().filesystem_checkpoints,
shim_events: [],
protocol_events: [],
replay_transitions: [],
reactive_run: null,
files_before: [],
files_after: [],
filesystem_effects: [],
truncated: false,
limitations: [],
residual_unknowns: [
{ scope: "filesystem" as const, reason: "watcher unavailable" },
],
cleanup: {
owned_process_group: "verified" as const,
temporary_root: "removed" as const,
},
};
const comparison = compareProcessCaptures(capture, capture);
expect(comparison.filesystem).toBe("unknown");
expect(comparison.status).toBe("unknown");
const complete = { ...capture, residual_unknowns: [] };
const transient = compareProcessCaptures(complete, {
...complete,
filesystem_checkpoints: [
{ name: "before", at_ms: 0, files: [], effects: [], truncated: false },
{
name: "during_run",
at_ms: 10,
files: [],
effects: [],
truncated: false,
},
{
name: "after_settlement",
at_ms: 50,
files: [],
effects: [],
truncated: false,
},
],
});
expect(transient.filesystem).toBe("changed");
expect(transient.status).toBe("changed");
});