mirror of
https://github.com/morluto/rea.git
synced 2026-10-27 18:05:45 +00:00
analyze_javascript_application ran several long phases with no event-loop turn, so MCP ping and cancellation waited: each file's parse, analysis and semantic projection; building every application node and relationship before the application graph's first sealing step; and whole-graph schema parses inside both immutable graph factories. - Each file runs as steps (parse, static analysis, semantic analysis, then each projection pass), driven by the existing time-sliced checkpoint. - Application graph input construction yields between phases, per module link and per file of findings. - The pipeline transfers its privately built graph inputs to new sealing steps that validate the graph's own fields synchronously and elements, content checks and the digest in steps. The public copying factories keep their synchronous capture. Results are unchanged: graph IDs and the complete result digest match main on five inputs including Obsidian's 23 MB obsidian.asar. On the issue's 1,200-function fixture the longest event-loop block falls from about 290 ms to 90 ms, and ping after abort from up to 286 ms to at most 56 ms. On obsidian.asar it falls from 10.9 s to 5.4 s; the rest is one analyzer stage of a single very large file. Refs #1462 Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: N0zoM1z0 <161784452+N0zoM1z0@users.noreply.github.com>
327 lines
12 KiB
TypeScript
327 lines
12 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { z } from "zod";
|
|
|
|
import { JAVASCRIPT_APPLICATION_EVIDENCE_EXAMPLE } from "../../contracts/javascript/javascriptRuntimeReconciliationExample.js";
|
|
import { freezeJsonSnapshot } from "../immutableJson.js";
|
|
import {
|
|
javascriptApplicationAnalysisResultSchema,
|
|
parseOwnedJavaScriptApplicationAnalysisSteps,
|
|
} from "./javascriptApplicationAnalysis.js";
|
|
import {
|
|
createJavaScriptApplicationGraph,
|
|
createImmutableJavaScriptApplicationGraphSteps,
|
|
isValidatedImmutableJavaScriptApplicationGraph,
|
|
sealTransferredJavaScriptApplicationGraphSteps,
|
|
} from "./javascriptApplicationGraph.js";
|
|
import {
|
|
createJavaScriptSemanticGraph,
|
|
createImmutableJavaScriptSemanticGraphSteps,
|
|
isValidatedImmutableJavaScriptSemanticGraph,
|
|
sealTransferredJavaScriptSemanticGraphSteps,
|
|
} from "./javascriptSemanticGraph.js";
|
|
|
|
const complete = <Value>(steps: Iterator<void, Value>): Value => {
|
|
let next = steps.next();
|
|
while (!next.done) next = steps.next();
|
|
return next.value;
|
|
};
|
|
|
|
const example = () =>
|
|
javascriptApplicationAnalysisResultSchema.parse(
|
|
JAVASCRIPT_APPLICATION_EVIDENCE_EXAMPLE.normalized_result,
|
|
);
|
|
|
|
const ownedExample = () => {
|
|
const result = example();
|
|
const { graph_id: _applicationId, ...application } = result.graph;
|
|
const { graph_id: _semanticId, ...semantic } = result.semantic_graph;
|
|
return {
|
|
...result,
|
|
graph: complete(
|
|
createImmutableJavaScriptApplicationGraphSteps(application),
|
|
),
|
|
semantic_graph: complete(
|
|
createImmutableJavaScriptSemanticGraphSteps(semantic),
|
|
),
|
|
};
|
|
};
|
|
|
|
const issuesFrom = (action: () => unknown) => {
|
|
try {
|
|
action();
|
|
} catch (error: unknown) {
|
|
if (error instanceof z.ZodError) return error.issues;
|
|
throw error;
|
|
}
|
|
throw new Error("Expected complete result validation to reject the input");
|
|
};
|
|
|
|
describe("owned JavaScript graph validation", () => {
|
|
it("reuses exact sealed graphs and preserves all public result fields", () => {
|
|
const input = ownedExample();
|
|
const result = complete(
|
|
parseOwnedJavaScriptApplicationAnalysisSteps(input),
|
|
);
|
|
expect(result).toEqual(
|
|
javascriptApplicationAnalysisResultSchema.parse(input),
|
|
);
|
|
expect(result.graph).toBe(input.graph);
|
|
expect(result.semantic_graph).toBe(input.semantic_graph);
|
|
expect(result.summary).not.toBe(input.summary);
|
|
expect(result.statistics).not.toBe(input.statistics);
|
|
expect(Object.isFrozen(result.graph.nodes[0]?.observations)).toBe(true);
|
|
expect(Object.isFrozen(result.semantic_graph.nodes[0]?.properties)).toBe(
|
|
true,
|
|
);
|
|
expect(isValidatedImmutableJavaScriptApplicationGraph(result.graph)).toBe(
|
|
true,
|
|
);
|
|
expect(
|
|
isValidatedImmutableJavaScriptSemanticGraph(result.semantic_graph),
|
|
).toBe(true);
|
|
expect(
|
|
isValidatedImmutableJavaScriptApplicationGraph(result.graph.nodes),
|
|
).toBe(false);
|
|
});
|
|
|
|
it("keeps ordinary constructors mutable and clones inputs before sealing", () => {
|
|
const input = example();
|
|
const { graph_id: _applicationId, ...application } = input.graph;
|
|
const { graph_id: _semanticId, ...semantic } = input.semantic_graph;
|
|
const ordinaryApplication = createJavaScriptApplicationGraph(application);
|
|
const ordinarySemantic = createJavaScriptSemanticGraph(semantic);
|
|
expect(Object.isFrozen(ordinaryApplication)).toBe(false);
|
|
expect(Object.isFrozen(ordinarySemantic)).toBe(false);
|
|
const applicationSteps =
|
|
createImmutableJavaScriptApplicationGraphSteps(application);
|
|
const semanticSteps = createImmutableJavaScriptSemanticGraphSteps(semantic);
|
|
application.limitations.push("Changed after factory input was cloned.");
|
|
semantic.limitations.push("Changed after factory input was cloned.");
|
|
expect(complete(applicationSteps)).toEqual(ordinaryApplication);
|
|
expect(complete(semanticSteps)).toEqual(ordinarySemantic);
|
|
expect(
|
|
isValidatedImmutableJavaScriptApplicationGraph(ordinaryApplication),
|
|
).toBe(false);
|
|
expect(isValidatedImmutableJavaScriptSemanticGraph(ordinarySemantic)).toBe(
|
|
false,
|
|
);
|
|
});
|
|
|
|
it.each(["mutable", "shallow-frozen", "json-sealed"])(
|
|
"fully validates %s imported graphs instead of trusting their IDs",
|
|
(representation) => {
|
|
const input = example();
|
|
input.graph.graph_id = `jag_${"f".repeat(64)}`;
|
|
if (representation === "shallow-frozen") Object.freeze(input.graph);
|
|
if (representation === "json-sealed") freezeJsonSnapshot(input.graph);
|
|
expect(isValidatedImmutableJavaScriptApplicationGraph(input.graph)).toBe(
|
|
false,
|
|
);
|
|
const issues = issuesFrom(() =>
|
|
complete(parseOwnedJavaScriptApplicationAnalysisSteps(input)),
|
|
);
|
|
expect(issues).toEqual(
|
|
issuesFrom(() =>
|
|
javascriptApplicationAnalysisResultSchema.parse(input),
|
|
),
|
|
);
|
|
expect(
|
|
issues.some(({ path }) => path.join("/") === "graph/graph_id"),
|
|
).toBe(true);
|
|
},
|
|
);
|
|
|
|
it("fully parses valid imported graphs without conferring an owned proof", () => {
|
|
const input = example();
|
|
const parsed = complete(
|
|
parseOwnedJavaScriptApplicationAnalysisSteps(input),
|
|
);
|
|
expect(parsed).toEqual(input);
|
|
expect(parsed.graph).not.toBe(input.graph);
|
|
expect(parsed.semantic_graph).not.toBe(input.semantic_graph);
|
|
expect(
|
|
isValidatedImmutableJavaScriptSemanticGraph(parsed.semantic_graph),
|
|
).toBe(false);
|
|
});
|
|
|
|
it("rejects a forged semantic graph paired with an authenticated application graph", () => {
|
|
const input = ownedExample();
|
|
input.semantic_graph = freezeJsonSnapshot({
|
|
...input.semantic_graph,
|
|
graph_id: `jsrg_${"f".repeat(64)}`,
|
|
});
|
|
expect(
|
|
isValidatedImmutableJavaScriptSemanticGraph(input.semantic_graph),
|
|
).toBe(false);
|
|
expect(
|
|
issuesFrom(() =>
|
|
complete(parseOwnedJavaScriptApplicationAnalysisSteps(input)),
|
|
),
|
|
).toEqual(
|
|
issuesFrom(() => javascriptApplicationAnalysisResultSchema.parse(input)),
|
|
);
|
|
});
|
|
|
|
it("does not authenticate an abandoned sealing operation", () => {
|
|
const input = example();
|
|
const { graph_id: _semanticId, ...semantic } = input.semantic_graph;
|
|
const originalNode = semantic.nodes[0];
|
|
if (originalNode === undefined) throw new Error("Expected a semantic node");
|
|
semantic.nodes[0] = {
|
|
...originalNode,
|
|
properties: {
|
|
rows: Array.from({ length: 10_000 }, (_, value) => ({ value })),
|
|
},
|
|
};
|
|
const mutable = createJavaScriptSemanticGraph(semantic);
|
|
const { graph_id: _mutableId, ...mutableInput } = mutable;
|
|
const steps = createImmutableJavaScriptSemanticGraphSteps(mutableInput);
|
|
expect(steps.next().done).toBe(false);
|
|
steps.return(mutable);
|
|
expect(isValidatedImmutableJavaScriptSemanticGraph(mutable)).toBe(false);
|
|
const sealed = complete(
|
|
createImmutableJavaScriptSemanticGraphSteps(mutableInput),
|
|
);
|
|
expect(sealed).toEqual(mutable);
|
|
expect(isValidatedImmutableJavaScriptSemanticGraph(sealed)).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe("owned JavaScript result bindings", () => {
|
|
it.each(["application", "root", "node"])(
|
|
"retains the %s binding check for individually authenticated graphs",
|
|
(binding) => {
|
|
const input = ownedExample();
|
|
if (binding === "root") input.root_artifact_sha256 = "e".repeat(64);
|
|
else {
|
|
const { graph_id: _semanticId, ...semantic } = input.semantic_graph;
|
|
if (binding === "application")
|
|
semantic.application_graph_id = `jag_${"e".repeat(64)}`;
|
|
else {
|
|
const node = semantic.nodes[0];
|
|
if (node === undefined) throw new Error("Expected a semantic node");
|
|
semantic.nodes = [
|
|
{ ...node, application_node_ids: [`jag_node_${"e".repeat(64)}`] },
|
|
...semantic.nodes.slice(1),
|
|
];
|
|
}
|
|
input.semantic_graph = complete(
|
|
createImmutableJavaScriptSemanticGraphSteps(semantic),
|
|
);
|
|
}
|
|
expect(
|
|
issuesFrom(() =>
|
|
complete(parseOwnedJavaScriptApplicationAnalysisSteps(input)),
|
|
),
|
|
).toEqual(
|
|
issuesFrom(() =>
|
|
javascriptApplicationAnalysisResultSchema.parse(input),
|
|
),
|
|
);
|
|
},
|
|
);
|
|
|
|
it("yields while checking a wide binding set and closes an abandoned iteration", () => {
|
|
const input = ownedExample();
|
|
const { graph_id: _semanticId, ...semantic } = input.semantic_graph;
|
|
const node = semantic.nodes[0];
|
|
if (node === undefined) throw new Error("Expected a semantic node");
|
|
semantic.nodes = [
|
|
{
|
|
...node,
|
|
application_node_ids: Array.from(
|
|
{ length: 10_000 },
|
|
(_, index) => `jag_node_${index.toString(16).padStart(64, "0")}`,
|
|
),
|
|
},
|
|
...semantic.nodes.slice(1),
|
|
];
|
|
input.semantic_graph = complete(
|
|
createImmutableJavaScriptSemanticGraphSteps(semantic),
|
|
);
|
|
const steps = parseOwnedJavaScriptApplicationAnalysisSteps(input);
|
|
expect(steps.next().done).toBe(false);
|
|
steps.return(input);
|
|
expect(steps.next().done).toBe(true);
|
|
expect(
|
|
issuesFrom(() =>
|
|
complete(parseOwnedJavaScriptApplicationAnalysisSteps(input)),
|
|
),
|
|
).toEqual(
|
|
issuesFrom(() => javascriptApplicationAnalysisResultSchema.parse(input)),
|
|
);
|
|
});
|
|
|
|
it("retains strict metadata validation alongside authenticated graphs", () => {
|
|
const input = {
|
|
...ownedExample(),
|
|
statistics: { ...example().statistics, findings: -1 },
|
|
extra: true,
|
|
};
|
|
expect(
|
|
issuesFrom(() =>
|
|
complete(parseOwnedJavaScriptApplicationAnalysisSteps(input)),
|
|
),
|
|
).toEqual(
|
|
issuesFrom(() => javascriptApplicationAnalysisResultSchema.parse(input)),
|
|
);
|
|
});
|
|
});
|
|
|
|
describe("graphs transferred to their sealing steps", () => {
|
|
it("seal the same validated graphs as the copying factories", () => {
|
|
const input = example();
|
|
const { graph_id: _applicationId, ...application } = input.graph;
|
|
const { graph_id: _semanticId, ...semantic } = input.semantic_graph;
|
|
const expectedApplication = createJavaScriptApplicationGraph(application);
|
|
const expectedSemantic = createJavaScriptSemanticGraph(semantic);
|
|
const sealedApplication = complete(
|
|
sealTransferredJavaScriptApplicationGraphSteps(
|
|
structuredClone(application),
|
|
),
|
|
);
|
|
const sealedSemantic = complete(
|
|
sealTransferredJavaScriptSemanticGraphSteps(structuredClone(semantic)),
|
|
);
|
|
expect(sealedApplication).toEqual(expectedApplication);
|
|
expect(sealedSemantic).toEqual(expectedSemantic);
|
|
expect(
|
|
isValidatedImmutableJavaScriptApplicationGraph(sealedApplication),
|
|
).toBe(true);
|
|
expect(isValidatedImmutableJavaScriptSemanticGraph(sealedSemantic)).toBe(
|
|
true,
|
|
);
|
|
});
|
|
|
|
it("report the issues a whole-graph parse reports", () => {
|
|
const input = example();
|
|
const { graph_id: _applicationId, ...application } = input.graph;
|
|
const { graph_id: _semanticId, ...semantic } = input.semantic_graph;
|
|
const node = semantic.nodes[0];
|
|
const applicationNode = application.nodes[0];
|
|
if (node === undefined || applicationNode === undefined)
|
|
throw new Error("Expected semantic and application nodes");
|
|
const malformed = {
|
|
...semantic,
|
|
nodes: [{ ...node, label: 7 }, ...semantic.nodes.slice(1)],
|
|
};
|
|
expect(
|
|
issuesFrom(() =>
|
|
complete(sealTransferredJavaScriptSemanticGraphSteps(malformed)),
|
|
),
|
|
).toEqual(issuesFrom(() => createJavaScriptSemanticGraph(malformed)));
|
|
const stale = {
|
|
...application,
|
|
nodes: [
|
|
{ ...applicationNode, node_id: `jag_node_${"f".repeat(64)}` },
|
|
...application.nodes.slice(1),
|
|
],
|
|
};
|
|
expect(
|
|
issuesFrom(() =>
|
|
complete(sealTransferredJavaScriptApplicationGraphSteps(stale)),
|
|
),
|
|
).toEqual(issuesFrom(() => createJavaScriptApplicationGraph(stale)));
|
|
});
|
|
});
|