Files
rea/tests/process-global/derivedOperationFailures.test.ts
T

860 lines
31 KiB
TypeScript

import { writeFile } from "node:fs/promises";
import { join } from "node:path";
import { InMemoryTransport, Client } from "@modelcontextprotocol/client";
import { afterEach, describe, expect, it, vi } from "vitest";
import { z } from "zod";
import { ARTIFACT_COMPARISON_EXAMPLE } from "../../src/contracts/artifactComparisonExample.js";
import { FUNCTION_COMPARISON_EXAMPLE } from "../../src/contracts/functionComparisonExample.js";
import { completeReconstructionCoverageData } from "../../src/domain/reconstructionCoverage.fixture.js";
import { reconstructionClosureResultSchema } from "../../src/domain/reconstructionCoverage.js";
import { createEvidence } from "../../src/domain/evidence.js";
import { functionComparisonResultSchema } from "../../src/domain/functionComparisonSchemas.js";
import { createServer } from "../../src/server/createServer.js";
import { createTestBinarySession } from "../fixtures/binarySession.js";
import { parseMcpToolError } from "../fixtures/mcpToolError.js";
import {
MANAGED_APPLICATION_GRAPH_EXAMPLE,
MANAGED_MEMBER_COMPARISON_EXAMPLE,
MANAGED_NATIVE_VERIFICATION_EXAMPLE,
MANAGED_RECONSTRUCTION_IMPORT_EXAMPLE,
} from "../../src/contracts/managed/managedWorkflowExamples.js";
import { managedApplicationGraphResultSchema } from "../../src/domain/managed/managedApplicationGraph.js";
import { managedMemberComparisonResultSchema } from "../../src/domain/managed/managedMemberComparison.js";
import { managedNativeVerificationResultSchema } from "../../src/domain/managed/managedNativeVerificationSchemas.js";
import { managedReconstructionImportResultSchema } from "../../src/domain/managed/managedReconstruction.js";
import { captureProcessScenarioFile } from "../../src/application/process/ProcessCli.js";
import { compareManagedMemberPaths } from "../../src/application/managed/ManagedMemberComparisonService.js";
import { buildManagedPeFixture } from "../../src/dotnet/ManagedPe.fixture.js";
import { createTestTempDirectory } from "../fixtures/temporaryDirectory.js";
import { ProcessCaptureError } from "../../src/process/capture/ProcessCaptureError.js";
import { reconstructionObligationLedgerSchema } from "../../src/domain/reconstructionObligationLedgerSchemas.js";
import {
request as ledgerRequest,
processEvidence,
} from "../../src/application/ReconstructionObligationLedger.fixture.js";
import { processCaptureSchema } from "../../src/domain/process/processCapture.js";
import { JAVASCRIPT_APPLICATION_EVIDENCE_EXAMPLE } from "../../src/contracts/javascript/javascriptRuntimeReconciliationExample.js";
import { javascriptApplicationAnalysisResultSchema } from "../../src/domain/javascript/javascriptApplicationAnalysis.js";
import { javaScriptSemanticQueryResultSchema } from "../../src/domain/javascript/javascriptSemanticQuerySchemas.js";
import {
JAVASCRIPT_FEATURE_TRACE_EXAMPLE,
JAVASCRIPT_APPLICATION_VERSION_COMPARISON_EXAMPLE,
SOURCE_TO_BUNDLE_COMPARISON_EXAMPLE,
} from "../../src/contracts/javascript/javascriptApplicationWorkflowExamples.js";
import { JAVASCRIPT_EXPORT_SHAPE_COMPARISON_EXAMPLE } from "../../src/contracts/javascript/javascriptExportShapeComparisonExample.js";
import { applicationFeatureTraceResultSchema } from "../../src/domain/javascript/javascriptFeatureTraceSchemas.js";
import { ownedApplicationVersionComparisonResultSchema } from "../../src/domain/javascript/javascriptApplicationVersionComparisonSchemas.js";
import { javaScriptExportShapeComparisonResultSchema } from "../../src/domain/javascript/javascriptExportShapeComparisonSchemas.js";
import { sourceToBundleComparisonResultSchema } from "../../src/domain/javascript/sourceToBundleComparisonSchemas.js";
import { JAVASCRIPT_RUNTIME_RECONCILIATION_EXAMPLE } from "../../src/contracts/javascript/javascriptRuntimeReconciliationExample.js";
import { javascriptRuntimeReconciliationResultSchema } from "../../src/domain/javascript/javascriptRuntimeReconciliationSchemas.js";
import { browserCompletenessSchema } from "../../src/domain/browserCompleteness.js";
import { createElectronActiveEvidence } from "../../src/application/javascript/ElectronActiveEvidence.js";
import { electronActiveObservationInputSchema } from "../../src/domain/javascript/electronActiveObservation.js";
import { createElectronActiveObservationFixtureResult } from "../../src/domain/javascript/electronActiveObservation.fixture.js";
import { nativeFunctionMatchingSchema } from "../../src/domain/native/functionMatching.js";
import { FunctionByteCoverage } from "../../src/domain/native/functionByteCoverage.js";
import {
nativeMatchingInventory,
nativeMatchingDetails,
} from "../fixtures/nativeFunctionMatching.js";
/** Unexpected implementation failures retain the SDK text surface, without a typed caller error. */
const expectUnexpectedToolFailure = (
response: Awaited<ReturnType<Client["callTool"]>>,
failure: Error,
): void => {
expect(response).toMatchObject({
isError: true,
content: [{ type: "text", text: failure.message }],
});
expect(response.structuredContent).toBeUndefined();
};
const unexpectedResultFailures = [
["TypeError", () => new TypeError("injected result parser TypeError")],
["Error", () => new Error("injected result parser Error")],
[
"ZodError",
() => {
const result = z.string().safeParse(1);
if (result.success) throw new Error("Expected an invalid string parse");
return result.error;
},
],
] as const;
describe.each([
{
name: "trace_application_feature",
input: JAVASCRIPT_FEATURE_TRACE_EXAMPLE,
result: applicationFeatureTraceResultSchema,
},
{
name: "compare_application_versions",
input: JAVASCRIPT_APPLICATION_VERSION_COMPARISON_EXAMPLE,
result: ownedApplicationVersionComparisonResultSchema,
},
{
name: "compare_javascript_export_shapes",
input: JAVASCRIPT_EXPORT_SHAPE_COMPARISON_EXAMPLE,
result: javaScriptExportShapeComparisonResultSchema,
},
{
name: "compare_source_to_bundle",
input: SOURCE_TO_BUNDLE_COMPARISON_EXAMPLE,
result: sourceToBundleComparisonResultSchema,
},
])("$name output failures through the public SDK", (workflow) => {
afterEach(() => vi.restoreAllMocks());
it.each(unexpectedResultFailures)(
"preserves an unexpected %s without recording sources or derived Evidence",
async (_kind, createFailure) => {
await withSdk(async ({ client, session }) => {
const failure = createFailure();
vi.spyOn(workflow.result, "parse").mockImplementation(() => {
throw failure;
});
const response = await client.callTool({
name: workflow.name,
arguments: workflow.input,
});
expectUnexpectedToolFailure(response, failure);
expect(session.exportEvidenceBundle().records).toEqual([]);
expect(session.exportEvidenceBundle().unknowns).toEqual([]);
});
},
);
});
const invalidFunctionOperationEvidence = () => {
const left = FUNCTION_COMPARISON_EXAMPLE.left;
if (left.subject === null) throw new Error("Expected a function subject");
return createEvidence(
{
path: "/tmp/wrong-function-operation",
sha256: left.subject.digest.sha256,
format: left.subject.format,
...(left.subject.architecture === null
? {}
: { architecture: left.subject.architecture }),
},
left.provider,
{
predicateType: left.predicate_type,
operation: "inspect_analysis_view",
parameters: left.parameters,
result: left.normalized_result,
confidence: left.confidence,
authority: left.authority,
...(left.relationship_coverage === null
? {}
: { relationshipCoverage: left.relationship_coverage }),
},
);
};
const malformedFunctionResultEvidence = () => {
const left = FUNCTION_COMPARISON_EXAMPLE.left;
if (left.subject === null) throw new Error("Expected a function subject");
return createEvidence(
{
path: "/tmp/malformed-function-result",
sha256: left.subject.digest.sha256,
format: left.subject.format,
...(left.subject.architecture === null
? {}
: { architecture: left.subject.architecture }),
},
left.provider,
{
predicateType: left.predicate_type,
operation: "analyze_function",
parameters: left.parameters,
result: { malformed: true },
confidence: left.confidence,
authority: left.authority,
...(left.relationship_coverage === null
? {}
: { relationshipCoverage: left.relationship_coverage }),
},
);
};
const withSdk = async <Value>(
run: (input: {
readonly client: Client;
readonly session: ReturnType<typeof createTestBinarySession>;
}) => Promise<Value>,
): Promise<Value> => {
const session = createTestBinarySession(() => {
throw new Error(
"These deterministic Evidence tools must not launch a provider",
);
});
const server = createServer({ kind: "session", session });
const client = new Client({
name: "derived-operation-failures",
version: "1",
});
const [clientTransport, serverTransport] =
InMemoryTransport.createLinkedPair();
try {
await server.connect(serverTransport);
await client.connect(clientTransport);
return await run({ client, session });
} finally {
await Promise.allSettled([client.close(), server.close(), session.close()]);
}
};
const activeRuntimeFixture = () => {
const root = join(process.cwd(), "active-runtime-fixture");
const applicationPath = join(root, "main.js");
const result = createElectronActiveObservationFixtureResult(applicationPath);
const evidence = createElectronActiveEvidence(
{
...electronActiveObservationInputSchema.parse({
executable_path: process.execPath,
application_path: applicationPath,
application_root: root,
}),
application_root: root,
},
result,
{
id: "rea-playwright-electron-active",
name: "REA Playwright active Electron observation provider",
version: "1",
},
);
return { evidence, result };
};
describe("runtime reconciliation failure ownership through the public SDK", () => {
afterEach(() => vi.restoreAllMocks());
it.each(unexpectedResultFailures)(
"preserves an unexpected %s from generated reconciliation output",
async (_label, createFailure) => {
await withSdk(async ({ client, session }) => {
const failure = createFailure();
vi.spyOn(
javascriptRuntimeReconciliationResultSchema,
"parse",
).mockImplementation(() => {
throw failure;
});
const response = await client.callTool({
name: "reconcile_javascript_runtime",
arguments: JAVASCRIPT_RUNTIME_RECONCILIATION_EXAMPLE,
});
expectUnexpectedToolFailure(response, failure);
expect(session.exportEvidenceBundle()).toMatchObject({
records: [],
unknowns: [],
});
});
},
);
it.each(unexpectedResultFailures)(
"preserves an unexpected %s while interpreting an authenticated active capture",
async (_label, createFailure) => {
await withSdk(async ({ client, session }) => {
const { evidence: runtime } = activeRuntimeFixture();
const failure = createFailure();
vi.spyOn(browserCompletenessSchema, "parse").mockImplementation(() => {
throw failure;
});
const response = await client.callTool({
name: "reconcile_javascript_runtime",
arguments: {
static_layers:
JAVASCRIPT_RUNTIME_RECONCILIATION_EXAMPLE.static_layers,
runtime_observations: [runtime],
},
});
expectUnexpectedToolFailure(response, failure);
expect(session.exportEvidenceBundle()).toMatchObject({
records: [],
unknowns: [],
});
});
},
);
it.each([
{
field: "payload",
path: ["normalized_result", "application", "application_path"],
reason: "invalid_type",
},
{
field: "parameters",
path: ["parameters", "application_root"],
reason: "invalid_type",
},
{
field: "scope",
path: ["normalized_result", "application", "application_path"],
reason: "invalid_value",
},
])(
"keeps an invalid active $field at its caller path",
async ({ field, path, reason }) => {
await withSdk(async ({ client, session }) => {
const { evidence, result } = activeRuntimeFixture();
const runtime = createEvidence(undefined, evidence.provider, {
operation: evidence.operation,
predicateType: evidence.predicate_type,
authority: evidence.authority,
confidence: evidence.confidence,
parameters:
field === "parameters"
? { ...evidence.parameters, application_root: 3 }
: evidence.parameters,
result:
field === "parameters"
? result
: {
...result,
application: {
...result.application,
application_path:
field === "payload"
? 3
: join(process.cwd(), "another-application", "main.js"),
},
},
});
const response = await client.callTool({
name: "reconcile_javascript_runtime",
arguments: {
static_layers:
JAVASCRIPT_RUNTIME_RECONCILIATION_EXAMPLE.static_layers,
runtime_observations: [runtime],
},
});
expect(response.isError).toBe(true);
expect(parseMcpToolError(response).error).toMatchObject({
code: "invalid_request",
details: {
operation: "reconcile_javascript_runtime",
issues: [{ path: ["runtime_observations", 0, ...path], reason }],
},
});
expect(session.exportEvidenceBundle()).toMatchObject({
records: [],
unknowns: [],
});
});
},
);
});
describe("derived operation failures through the public SDK", () => {
afterEach(() => vi.restoreAllMocks());
it("keeps a wrong function operation as a caller constraint at left", async () => {
await withSdk(async ({ client, session }) => {
const response = await client.callTool({
name: "compare_functions",
arguments: {
left: invalidFunctionOperationEvidence(),
right: FUNCTION_COMPARISON_EXAMPLE.right,
},
});
expect(parseMcpToolError(response).error).toMatchObject({
code: "invalid_request",
details: {
issues: [expect.objectContaining({ path: ["left"] })],
},
});
expect(session.exportEvidenceBundle().records).toEqual([]);
});
});
it("keeps malformed analyze_function payloads as Evidence integrity failures", async () => {
await withSdk(async ({ client, session }) => {
const response = await client.callTool({
name: "compare_functions",
arguments: {
left: malformedFunctionResultEvidence(),
right: FUNCTION_COMPARISON_EXAMPLE.right,
},
});
expect(parseMcpToolError(response).error.code).toBe(
"evidence_integrity_mismatch",
);
expect(session.exportEvidenceBundle().records).toEqual([]);
});
});
it("classifies a duplicated call-path function at its second selection", async () => {
await withSdk(async ({ client, session }) => {
const source = FUNCTION_COMPARISON_EXAMPLE.left;
expect(session.recordEvidence(source).ok).toBe(true);
const before = session.exportEvidenceBundle();
const response = await client.callTool({
name: "build_call_path",
arguments: {
functions: [source, source],
start: { address: "0x1000" },
goal: { address: "0x1001" },
},
});
expect(parseMcpToolError(response).error).toMatchObject({
code: "invalid_request",
details: {
issues: [expect.objectContaining({ path: ["functions", 1] })],
},
});
expect(session.exportEvidenceBundle()).toEqual(before);
});
});
it("classifies a non-inventory artifact carrier at left", async () => {
await withSdk(async ({ client, session }) => {
const response = await client.callTool({
name: "compare_artifacts",
arguments: {
left: FUNCTION_COMPARISON_EXAMPLE.left,
right: ARTIFACT_COMPARISON_EXAMPLE.right,
},
});
expect(parseMcpToolError(response).error).toMatchObject({
code: "invalid_request",
details: {
issues: [expect.objectContaining({ path: ["left"] })],
},
});
expect(session.exportEvidenceBundle().records).toEqual([]);
});
});
it.each(unexpectedResultFailures)(
"preserves an unexpected %s from result validation",
async (_label, createFailure) => {
await withSdk(async ({ client, session }) => {
const failure = createFailure();
vi.spyOn(functionComparisonResultSchema, "parse").mockImplementation(
() => {
throw failure;
},
);
const response = await client.callTool({
name: "compare_functions",
arguments: {
left: FUNCTION_COMPARISON_EXAMPLE.left,
right: FUNCTION_COMPARISON_EXAMPLE.right,
},
});
expectUnexpectedToolFailure(response, failure);
expect(session.exportEvidenceBundle().records).toEqual([]);
});
},
);
it.each(unexpectedResultFailures)(
"preserves an unexpected %s from coverage result validation",
async (_label, createFailure) => {
await withSdk(async ({ client, session }) => {
const coverage = completeReconstructionCoverageData();
const failure = createFailure();
vi.spyOn(reconstructionClosureResultSchema, "parse").mockImplementation(
() => {
throw failure;
},
);
const response = await client.callTool({
name: "evaluate_reconstruction_coverage",
arguments: { coverage, boundary_id: "replacement.cli" },
});
expectUnexpectedToolFailure(response, failure);
expect(session.exportEvidenceBundle().records).toEqual([]);
});
},
);
});
const managedWorkflows = [
{
name: "project_managed_application_graph",
input: MANAGED_APPLICATION_GRAPH_EXAMPLE,
result: managedApplicationGraphResultSchema,
sourceField: "managed_members",
source: MANAGED_APPLICATION_GRAPH_EXAMPLE.managed_members,
},
{
name: "compare_managed_members",
input: MANAGED_MEMBER_COMPARISON_EXAMPLE,
result: managedMemberComparisonResultSchema,
sourceField: "left",
source: MANAGED_MEMBER_COMPARISON_EXAMPLE.left,
},
{
name: "verify_managed_native_boundaries",
input: MANAGED_NATIVE_VERIFICATION_EXAMPLE,
result: managedNativeVerificationResultSchema,
sourceField: "managed_boundaries",
source: MANAGED_NATIVE_VERIFICATION_EXAMPLE.managed_boundaries,
},
{
name: "import_managed_reconstruction",
input: MANAGED_RECONSTRUCTION_IMPORT_EXAMPLE,
result: managedReconstructionImportResultSchema,
sourceField: "static_members",
source: MANAGED_RECONSTRUCTION_IMPORT_EXAMPLE.static_members,
},
] as const;
describe.each(managedWorkflows)(
"$name failure ownership through the public SDK",
(workflow) => {
afterEach(() => vi.restoreAllMocks());
it("rejects an authentic source with the wrong operation at its selection", async () => {
await withSdk(async ({ client, session }) => {
const response = await client.callTool({
name: workflow.name,
arguments: {
...workflow.input,
[workflow.sourceField]: FUNCTION_COMPARISON_EXAMPLE.left,
},
});
expect(parseMcpToolError(response).error).toMatchObject({
code: "invalid_request",
details: {
issues: [expect.objectContaining({ path: [workflow.sourceField] })],
},
});
expect(session.exportEvidenceBundle().records).toEqual([]);
});
});
it("rejects a malformed authenticated source payload as Evidence integrity", async () => {
await withSdk(async ({ client, session }) => {
const source = createEvidence(undefined, workflow.source.provider, {
operation: workflow.source.operation,
parameters: {},
result: { malformed: true },
});
const response = await client.callTool({
name: workflow.name,
arguments: { ...workflow.input, [workflow.sourceField]: source },
});
expect(parseMcpToolError(response).error.code).toBe(
"evidence_integrity_mismatch",
);
expect(session.exportEvidenceBundle().records).toEqual([]);
});
});
it("rejects a tampered source before recording any Evidence", async () => {
await withSdk(async ({ client, session }) => {
const response = await client.callTool({
name: workflow.name,
arguments: {
...workflow.input,
[workflow.sourceField]: {
...workflow.source,
normalized_result: { tampered: true },
},
},
});
expect(parseMcpToolError(response).error.code).toBe(
"evidence_integrity_mismatch",
);
expect(session.exportEvidenceBundle().records).toEqual([]);
});
});
it.each(unexpectedResultFailures)(
"preserves an unexpected %s from its generated output",
async (_label, createFailure) => {
await withSdk(async ({ client, session }) => {
const failure = createFailure();
vi.spyOn(workflow.result, "parse").mockImplementation(() => {
throw failure;
});
const response = await client.callTool({
name: workflow.name,
arguments: workflow.input,
});
expectUnexpectedToolFailure(response, failure);
expect(session.exportEvidenceBundle().records).toEqual([]);
});
},
);
},
);
describe("managed comparison output failure with completed source reads", () => {
afterEach(() => vi.restoreAllMocks());
it("retains the left source and output failure cause after reading real artifacts", async () => {
const root = await createTestTempDirectory("rea-managed-output-failure-");
const leftPath = join(root, "left.dll");
const rightPath = join(root, "right.dll");
await writeFile(leftPath, buildManagedPeFixture());
await writeFile(
rightPath,
buildManagedPeFixture({ methodName: "Changed" }),
);
const parsed = z.string().safeParse(1);
if (parsed.success) throw new Error("Expected invalid output");
const failure = parsed.error;
vi.spyOn(managedMemberComparisonResultSchema, "parse").mockImplementation(
() => {
throw failure;
},
);
const result = await compareManagedMemberPaths({ leftPath, rightPath });
expect(result.ok).toBe(false);
if (result.ok) return;
expect(result.error.cause).toBe(failure);
expect(result.error).toMatchObject({
_tag: "AnalysisOutputError",
partialObservation: {
operation: "inspect_managed_members",
subject: { local_path: leftPath },
normalized_result: {
methods: [expect.objectContaining({ token: "0x06000001" })],
},
},
});
});
});
describe("ledger generation failure ownership through the public SDK", () => {
afterEach(() => vi.restoreAllMocks());
it.each(unexpectedResultFailures)(
"preserves an unexpected %s from generated ledger validation",
async (_label, createFailure) => {
await withSdk(async ({ client, session }) => {
const input = ledgerRequest([processEvidence()]);
const failure = createFailure();
vi.spyOn(
reconstructionObligationLedgerSchema,
"parse",
).mockImplementation(() => {
throw failure;
});
const response = await client.callTool({
name: "build_reconstruction_obligation_ledger",
arguments: input,
});
expectUnexpectedToolFailure(response, failure);
expect(session.exportEvidenceBundle().records).toEqual([]);
});
},
);
it.each(unexpectedResultFailures)(
"preserves an unexpected %s while deriving process candidates",
async (_label, createFailure) => {
await withSdk(async ({ client, session }) => {
const input = ledgerRequest([processEvidence()]);
const failure = createFailure();
vi.spyOn(processCaptureSchema, "safeParse").mockImplementation(() => {
throw failure;
});
const response = await client.callTool({
name: "build_reconstruction_obligation_ledger",
arguments: input,
});
expectUnexpectedToolFailure(response, failure);
expect(session.exportEvidenceBundle().records).toEqual([]);
});
},
);
});
describe("process capture CLI cleanup failure projection", () => {
afterEach(() => vi.restoreAllMocks());
it("preserves sanitized unknown-process IDs and reasons through the capture CLI boundary", async () => {
const root = await createTestTempDirectory("rea-process-cli-cleanup-");
const scenario = join(root, "scenario.json");
await writeFile(
scenario,
JSON.stringify({ executable: process.execPath, arguments: [] }),
);
const reason =
"process ownership token could not be read for 1 live process(es): environment_unavailable=1; live candidates 900=environment_unavailable";
const failure = new ProcessCaptureError("cleanup incomplete", {
reason: "cleanup_incomplete",
cleanup: { reason, resources: ["owned_process_group"] },
cleanupReport: {
owned_process_group: {
state: "unverified",
reason,
unverified_processes: [
{ pid: 900, reason: "environment_unavailable" },
],
},
terminal_renderer: { state: "cleaned", reason: null },
temporary_root: { state: "cleaned", reason: null },
},
});
const processHarness =
await import("../../src/process/capture/ProcessHarness.js");
vi.spyOn(processHarness, "captureProcessScenario").mockResolvedValue({
ok: false,
error: failure,
});
const projected = await captureProcessScenarioFile(scenario);
expect(projected).toMatchObject({
error: "Process command failed",
code: "cleanup_incomplete",
details: {
cleanup_report: {
owned_process_group: {
reason,
unverified_processes: [
{ pid: 900, reason: "environment_unavailable" },
],
},
},
},
});
});
});
describe("process comparison Evidence authentication failures through the public SDK", () => {
afterEach(() => vi.restoreAllMocks());
it.each(unexpectedResultFailures.filter(([kind]) => kind !== "ZodError"))(
"preserves an unexpected %s without retaining Evidence",
async (_label, createFailure) => {
await withSdk(async ({ client, session }) => {
const input = {
left: processEvidence(),
right: processEvidence(),
};
const failure = createFailure();
const evidenceModule = await import("../../src/domain/evidence.js");
vi.spyOn(evidenceModule, "parseEvidence").mockImplementation(() => {
throw failure;
});
const response = await client.callTool({
name: "compare_process_captures",
arguments: input,
});
expectUnexpectedToolFailure(response, failure);
expect(session.exportEvidenceBundle().records).toEqual([]);
expect(session.exportEvidenceBundle().unknowns).toEqual([]);
});
},
);
});
describe("semantic query output failures through the public SDK", () => {
afterEach(() => vi.restoreAllMocks());
it.each(unexpectedResultFailures)(
"preserves an unexpected %s from generated query validation",
async (_label, createFailure) => {
await withSdk(async ({ client, session }) => {
const application = JAVASCRIPT_APPLICATION_EVIDENCE_EXAMPLE;
const analysis = javascriptApplicationAnalysisResultSchema.parse(
application.normalized_result,
);
const node = analysis.semantic_graph.nodes[0];
if (node === undefined)
throw new Error("Expected a semantic fixture node");
const failure = createFailure();
vi.spyOn(
javaScriptSemanticQueryResultSchema,
"parse",
).mockImplementation(() => {
throw failure;
});
const response = await client.callTool({
name: "trace_javascript_semantics",
arguments: {
application,
query: {
seed: { kind: "semantic-node", node_id: node.node_id },
direction: "backward-provenance",
},
},
});
expectUnexpectedToolFailure(response, failure);
expect(session.exportEvidenceBundle().records).toEqual([]);
});
},
);
});
describe("native matching failure ownership through the public SDK", () => {
afterEach(() => vi.restoreAllMocks());
const matchingInput = () => ({
left: nativeMatchingInventory("1", [{ address: "0x10", value: "main" }]),
right: nativeMatchingInventory("2", [{ address: "0x20", value: "main" }]),
left_observations: nativeMatchingDetails("1", "0x10", "c3"),
right_observations: nativeMatchingDetails("2", "0x20", "c3"),
detail: "complete",
});
it.each(unexpectedResultFailures)(
"preserves an unexpected %s from native matching result validation",
async (_label, createFailure) => {
await withSdk(async ({ client, session }) => {
const input = matchingInput();
const failure = createFailure();
vi.spyOn(nativeFunctionMatchingSchema, "parse").mockImplementation(
() => {
throw failure;
},
);
const response = await client.callTool({
name: "match_native_functions",
arguments: input,
});
expectUnexpectedToolFailure(response, failure);
expect(session.exportEvidenceBundle().records).toEqual([]);
});
},
);
it.each(unexpectedResultFailures)(
"preserves an unexpected %s from native byte fingerprint derivation",
async (_label, createFailure) => {
await withSdk(async ({ client, session }) => {
const input = matchingInput();
const failure = createFailure();
vi.spyOn(
FunctionByteCoverage.prototype,
"fingerprint",
).mockRejectedValue(failure);
const response = await client.callTool({
name: "match_native_functions",
arguments: input,
});
expectUnexpectedToolFailure(response, failure);
expect(session.exportEvidenceBundle().records).toEqual([]);
});
},
);
});