mirror of
https://github.com/morluto/rea.git
synced 2026-10-22 22:02:27 -05:00
Select completed source-to-bundle mappings and candidates through the shared view owner, preserve reference-file provenance, and retain full Evidence. Reuse bounded JSON reading, heap admission, and cancellation before session writes. Verified public Redux Toolkit source/map facts with an independent oracle, equivalent CLI/MCP workflows, focused negative controls, and complete CI/review. Historical paired SDK context estimates fall about 64%; timing/resource tradeoffs and final verification receipts are recorded without a general speedup or actual model-token claim. Fixes #6112.
210 lines
7.4 KiB
TypeScript
210 lines
7.4 KiB
TypeScript
import { holdFirstFileRead } from "../support/holdFirstFileRead.js";
|
|
import { AnalysisCancelledError } from "../../src/domain/analysisErrorCore.js";
|
|
import { Client, InMemoryTransport } from "@modelcontextprotocol/client";
|
|
import { writeFile } from "node:fs/promises";
|
|
import { join } from "node:path";
|
|
import { setImmediate } from "node:timers";
|
|
import { afterEach, expect, it, onTestFinished, vi } from "vitest";
|
|
import { resolveSourceToBundleReference } from "../../src/application/javascript/SourceToBundleReference.js";
|
|
import { requireAuthenticationHeadroom } from "../../src/application/JsonAuthenticationHeadroom.js";
|
|
import * as workflow from "../../src/application/javascript/JavaScriptApplicationWorkflowService.js";
|
|
import { historicalSourceGraphSchema } from "../../src/domain/referenceSourceGraph.js";
|
|
import { ArtifactResourceScope } from "../../src/artifacts/ArtifactResourceScope.js";
|
|
import { SOURCE_TO_BUNDLE_COMPARISON_EXAMPLE } from "../../src/contracts/javascript/javascriptApplicationWorkflowExamples.js";
|
|
import { createServer } from "../../src/server/createServer.js";
|
|
import { ToolResultDelivery } from "../../src/server/toolResult.js";
|
|
import { createTestBinarySession } from "../fixtures/binarySession.js";
|
|
import { createTestTempDirectory } from "../fixtures/temporaryDirectory.js";
|
|
|
|
vi.mock("../../src/application/JsonAuthenticationHeadroom.js", { spy: true });
|
|
vi.mock(
|
|
"../../src/application/javascript/JavaScriptApplicationWorkflowService.js",
|
|
{ spy: true },
|
|
);
|
|
afterEach(() => vi.restoreAllMocks());
|
|
|
|
it("reserves graph validation/hash memory before the owning parser allocates", async () => {
|
|
const root = await createTestTempDirectory("rea-source-headroom-");
|
|
const path = join(root, "graph.json");
|
|
await writeFile(
|
|
path,
|
|
JSON.stringify(SOURCE_TO_BUNDLE_COMPARISON_EXAMPLE.reference),
|
|
);
|
|
const actual = await vi.importActual<
|
|
typeof import("../../src/application/JsonAuthenticationHeadroom.js")
|
|
>("../../src/application/JsonAuthenticationHeadroom.js");
|
|
vi.mocked(requireAuthenticationHeadroom).mockImplementationOnce(
|
|
(value, options) =>
|
|
actual.requireAuthenticationHeadroom(value, {
|
|
...options,
|
|
availableBytes: 0,
|
|
}),
|
|
);
|
|
const parser = vi.spyOn(historicalSourceGraphSchema, "safeParse");
|
|
const resources = new ArtifactResourceScope();
|
|
try {
|
|
expect(
|
|
await resolveSourceToBundleReference(
|
|
{ kind: "file", path },
|
|
undefined,
|
|
resources,
|
|
),
|
|
).toMatchObject({
|
|
ok: false,
|
|
error: {
|
|
_tag: "AnalysisResourceConstraintError",
|
|
operation: "compare_source_to_bundle",
|
|
resource: "memory",
|
|
},
|
|
});
|
|
expect(parser).not.toHaveBeenCalled();
|
|
} finally {
|
|
await resources.close();
|
|
}
|
|
expect(resources.hasPending).toBe(false);
|
|
});
|
|
|
|
it("attributes file-I/O cancellation to the comparison and preserves its exact cause", async () => {
|
|
const root = await createTestTempDirectory("rea-reference-io-cancel-");
|
|
const path = join(root, "graph.json");
|
|
await writeFile(
|
|
path,
|
|
JSON.stringify(SOURCE_TO_BUNDLE_COMPARISON_EXAMPLE.reference),
|
|
);
|
|
const held = await holdFirstFileRead(path);
|
|
const controller = new AbortController();
|
|
const cause = new Error("cancel historical graph read");
|
|
const resources = new ArtifactResourceScope();
|
|
try {
|
|
const pending = resolveSourceToBundleReference(
|
|
{ kind: "file", path },
|
|
controller.signal,
|
|
resources,
|
|
);
|
|
await held.firstRead;
|
|
controller.abort(cause);
|
|
held.release();
|
|
const result = await pending;
|
|
expect(result).toMatchObject({
|
|
ok: false,
|
|
error: {
|
|
_tag: "AnalysisCancelledError",
|
|
operation: "compare_source_to_bundle",
|
|
},
|
|
});
|
|
if (result.ok) throw new Error("Expected cancelled read");
|
|
expect(result.error.cause).toBe(cause);
|
|
} finally {
|
|
held.release();
|
|
await resources.close();
|
|
}
|
|
expect(resources.hasPending).toBe(false);
|
|
});
|
|
|
|
it.each(["validation", "comparison"] as const)(
|
|
"dispatches cancellation during %s before committing session facts",
|
|
async (stage) => {
|
|
const { client, session, path } = await connectedComparison();
|
|
const controller = new AbortController();
|
|
const before = session.exportEvidenceBundle();
|
|
if (stage === "validation") {
|
|
const parse = historicalSourceGraphSchema.safeParse;
|
|
vi.spyOn(historicalSourceGraphSchema, "safeParse").mockImplementationOnce(
|
|
(value) => {
|
|
const parsed = parse(value);
|
|
setImmediate(() =>
|
|
controller.abort(new Error("cancel during graph validation")),
|
|
);
|
|
return parsed;
|
|
},
|
|
);
|
|
} else {
|
|
const actual = await vi.importActual<typeof workflow>(
|
|
"../../src/application/javascript/JavaScriptApplicationWorkflowService.js",
|
|
);
|
|
vi.mocked(
|
|
workflow.compareSourceToBundleEvidenceValidated,
|
|
).mockImplementationOnce((input) => {
|
|
const compared = actual.compareSourceToBundleEvidenceValidated(input);
|
|
setImmediate(() =>
|
|
controller.abort(new Error("cancel during graph comparison")),
|
|
);
|
|
return compared;
|
|
});
|
|
}
|
|
let settle: (() => void) | undefined;
|
|
const settled = new Promise<void>((resolve) => {
|
|
settle = resolve;
|
|
});
|
|
const errorDelivery = ToolResultDelivery.prototype.toErrorToolResult;
|
|
vi.spyOn(
|
|
ToolResultDelivery.prototype,
|
|
"toErrorToolResult",
|
|
).mockImplementation(function (
|
|
this: ToolResultDelivery,
|
|
error,
|
|
targetContent,
|
|
) {
|
|
const result = errorDelivery.call(this, error, targetContent);
|
|
if (
|
|
error instanceof AnalysisCancelledError &&
|
|
error.operation === "compare_source_to_bundle"
|
|
)
|
|
settle?.();
|
|
return result;
|
|
});
|
|
const evidenceDelivery = ToolResultDelivery.prototype.toEvidenceToolResult;
|
|
vi.spyOn(
|
|
ToolResultDelivery.prototype,
|
|
"toEvidenceToolResult",
|
|
).mockImplementation(function (this: ToolResultDelivery, ...args) {
|
|
const result = evidenceDelivery.apply(this, args);
|
|
if (args[1].name === "compare_source_to_bundle") settle?.();
|
|
return result;
|
|
});
|
|
const pending = client
|
|
.callTool(
|
|
{
|
|
name: "compare_source_to_bundle",
|
|
arguments: {
|
|
...SOURCE_TO_BUNDLE_COMPARISON_EXAMPLE,
|
|
reference: { kind: "file", path },
|
|
view: { kind: "summary" },
|
|
},
|
|
},
|
|
{ signal: controller.signal },
|
|
)
|
|
.then(
|
|
() => null,
|
|
(cause: unknown) => cause,
|
|
);
|
|
expect(await pending).toBeInstanceOf(Error);
|
|
await settled;
|
|
expect(session.exportEvidenceBundle()).toEqual(before);
|
|
await expect(client.ping()).resolves.toEqual({});
|
|
},
|
|
);
|
|
|
|
const connectedComparison = async () => {
|
|
const root = await createTestTempDirectory("rea-source-commit-cancel-");
|
|
const path = join(root, "graph.json");
|
|
await writeFile(
|
|
path,
|
|
JSON.stringify(SOURCE_TO_BUNDLE_COMPARISON_EXAMPLE.reference),
|
|
);
|
|
const session = createTestBinarySession(() => {
|
|
throw new Error("Comparison must not start a native provider");
|
|
});
|
|
const server = createServer({ kind: "session", session });
|
|
const client = new Client({ name: "source-cancel", version: "1" });
|
|
onTestFinished(async () => {
|
|
await client.close();
|
|
await server.close();
|
|
await session.close();
|
|
});
|
|
const [a, b] = InMemoryTransport.createLinkedPair();
|
|
await server.connect(b);
|
|
await client.connect(a);
|
|
return { client, session, path };
|
|
};
|