Files
reverse-engineering-anything/src/application/native/NativeValueTraceStops.test.ts
T
morlutoandCursor Agent 52bca6de41 fix(native): retain value trace source evidence (#8384)
* fix(native): retain value trace source evidence

* fix(native): build trace error evidence only on failure

* test(mcp): expect unowned value trace refusal

* test(mcp): avoid freezing trace error wording

* test(native): keep value-trace stop coverage with source evidence

Main's stop and continuation cases now meet the trace's evidence-owner
precondition: direct calls supply a source id, and a completed MCP trace
runs in a session that can retain it.

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-11-05 00:19:50 +08:00

161 lines
5.4 KiB
TypeScript

import { describe, expect, it } from "vitest";
import type { AnalysisOperationPort } from "../AnalysisProvider.js";
import { ok } from "../../domain/result.js";
import {
AnalysisCancelledError,
AnalysisCapabilityUnavailableError,
} from "../../domain/analysisErrorCore.js";
import { nativeValueTraceSchema } from "../../domain/native/nativeValueTrace.js";
import {
CLEANUP_STOPPED_VALUE_TRACE,
traceNativeValues,
} from "./NativeValueTrace.js";
import {
failingValueTraceReads,
valueTraceDiamond,
valueTraceProvider as provider,
VALUE_TRACE_DIAMOND_READS,
type ValueTraceDiamondRead,
} from "./NativeValueTrace.fixture.js";
describe("native value trace child stops", () => {
const cleanup = {
cleanup: { reason: "cleanup proof refused", resources: ["owned worker"] },
};
const operationOf = (read: ValueTraceDiamondRead) =>
read.startsWith("analyze_function")
? "analyze_function"
: "resolve_native_call_targets";
const childReads = [
"resolve_native_call_targets:0x1004",
"analyze_function:0x2000",
] as const;
const readsThrough = (read: ValueTraceDiamondRead) =>
VALUE_TRACE_DIAMOND_READS.slice(
0,
VALUE_TRACE_DIAMOND_READS.indexOf(read) + 1,
);
// The trace cites each completed dossier. These cases cover stop behavior,
// so the fixture only has to satisfy that precondition.
const withSourceEvidence = (
port: AnalysisOperationPort,
): AnalysisOperationPort => ({
execute: async (operation, parameters, options) => {
const execution = await port.execute(operation, parameters, options);
if (!execution.ok || execution.value.evidenceId !== undefined)
return execution;
return ok({
...execution.value,
evidenceId: `ev_${"ab".repeat(32)}`,
});
},
});
it.each(childReads)(
"returns a cancelled %s read without a partial trace",
async (read) => {
const cancelled = new AnalysisCancelledError(operationOf(read));
const { port, reads } = failingValueTraceReads(valueTraceDiamond().port, {
[read]: cancelled,
});
const result = await traceNativeValues(withSourceEvidence(port), {
procedure: "0x1000",
max_depth: 1,
});
expect(result).toStrictEqual({ ok: false, error: cancelled });
expect(reads).toEqual(readsThrough(read));
},
);
it.each(
childReads.flatMap((read) =>
(["caller abort", "cancelled read"] as const).map((race) => ({
read,
race,
})),
),
)(
"keeps unconfirmed cleanup primary over a $race at $read",
async ({ read, race }) => {
const controller = new AbortController();
const failure =
race === "cancelled read"
? new AnalysisCancelledError(operationOf(read), cleanup)
: new AnalysisCapabilityUnavailableError(
provider.id,
operationOf(read),
"controlled child failure",
cleanup,
);
const { port, reads } = failingValueTraceReads(valueTraceDiamond().port, {
[read]: failure,
});
// The caller aborts while the failing read settles.
const aborting: AnalysisOperationPort = {
execute: async (operation, parameters, options) => {
const selector = `${operation}:${String(parameters.procedure ?? parameters.address)}`;
if (selector === read) controller.abort("caller stopped the trace");
return port.execute(operation, parameters, options);
},
};
const result = await traceNativeValues(
withSourceEvidence(aborting),
{ procedure: "0x1000", max_depth: 1 },
controller.signal,
);
expect(reads).toEqual(readsThrough(read));
if (result.ok || !("partialResult" in result))
throw new Error("Expected a stopped trace with its admitted result");
expect(result.error).toBe(failure);
expect(nativeValueTraceSchema.parse(result.partialResult)).toMatchObject({
procedures: [{ address: "0x1000" }],
traversal: { status: "truncated", reasons: ["cleanup_incomplete"] },
truncated: true,
});
},
);
it("records the stop as a located unknown in the admitted trace", async () => {
const failure = new AnalysisCapabilityUnavailableError(
provider.id,
"resolve_native_call_targets",
"controlled child failure",
cleanup,
);
const { port } = failingValueTraceReads(valueTraceDiamond().port, {
"resolve_native_call_targets:0x1008": failure,
});
const result = await traceNativeValues(withSourceEvidence(port), {
procedure: "0x1000",
max_depth: 1,
});
if (result.ok || !("partialResult" in result))
throw new Error("Expected a stopped trace with its admitted result");
const admitted = nativeValueTraceSchema.parse(result.partialResult);
// 0x2000 was queued from 0x1004 but never analyzed; the stop, not a depth
// limit, accounts for it, and the admitted call edge to it remains.
expect(admitted.traversal).toEqual({
status: "truncated",
reasons: ["cleanup_incomplete"],
});
expect(admitted.unknowns.filter(({ address }) => address !== null)).toEqual(
[
{
procedure: "0x1000",
address: "0x1008",
reason: CLEANUP_STOPPED_VALUE_TRACE,
},
],
);
expect(admitted.edges).toContainEqual(
expect.objectContaining({ kind: "call", target: "0x2000" }),
);
});
});