mirror of
https://github.com/morluto/rea.git
synced 2026-10-29 02:45:58 +00:00
* fix(hopper): report unavailable procedure body coverage * refactor!: simplify runtime tools and remove replay engines Keep direct inspection, capture, and comparison tools. Bind handlers to named contracts and let agents compose experiments with commands and local fixture servers. BREAKING CHANGE: Remove controlled replay, Node characterization, finite replay-machine, managed runtime planning, and redundant string-tracing tools. Retire process replay, shims, reactive scenarios, custom checkpoints, and active browser replay and origin-scope inputs.
199 lines
5.1 KiB
TypeScript
199 lines
5.1 KiB
TypeScript
import { expect, it } from "vitest";
|
|
|
|
import {
|
|
compareUnverifiedProcessCaptures as compareProcessCaptures,
|
|
emptyProcessCapture as emptyCapture,
|
|
} from "./processCapture.fixture.js";
|
|
|
|
it("classifies missing observations as unknown and one-sided evidence as added", () => {
|
|
const base = {
|
|
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,
|
|
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.status).toBe("unknown");
|
|
});
|
|
|
|
it("treats equivalent normalization records as equal regardless of member order", () => {
|
|
const capture = emptyCapture();
|
|
|
|
expect(
|
|
compareProcessCaptures(capture, {
|
|
...capture,
|
|
normalization: {
|
|
patterns: [],
|
|
time_bucket_ms: 10,
|
|
ports: true,
|
|
pids: true,
|
|
paths: true,
|
|
},
|
|
}),
|
|
).toMatchObject({
|
|
status: "unchanged",
|
|
first_divergence: { status: "none" },
|
|
});
|
|
});
|
|
|
|
it("compares raw terminal chunks even when rendered states agree", () => {
|
|
const capture = {
|
|
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,
|
|
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 = {
|
|
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,
|
|
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 finalFile = {
|
|
path: "root_0:created.txt",
|
|
type: "file" as const,
|
|
mode: 0o644,
|
|
size: 4,
|
|
sha256: "a".repeat(64),
|
|
symlink_target: null,
|
|
};
|
|
const changed = compareProcessCaptures(complete, {
|
|
...complete,
|
|
filesystem_checkpoints: [
|
|
{ name: "before", at_ms: 0, files: [], effects: [], truncated: false },
|
|
{
|
|
name: "after_settlement",
|
|
at_ms: 10,
|
|
files: [finalFile],
|
|
effects: [
|
|
{
|
|
path: finalFile.path,
|
|
status: "created",
|
|
before: null,
|
|
after: finalFile,
|
|
},
|
|
],
|
|
truncated: false,
|
|
},
|
|
],
|
|
files_after: [finalFile],
|
|
filesystem_effects: [
|
|
{
|
|
path: finalFile.path,
|
|
status: "created",
|
|
before: null,
|
|
after: finalFile,
|
|
},
|
|
],
|
|
});
|
|
expect(changed.filesystem).toBe("changed");
|
|
expect(changed.status).toBe("changed");
|
|
});
|