Files
reverse-engineering-anything/tests/boundary/cli/nativeFeatureTraceDelivery.test.ts
T
morlutoandCursor Agent f1622fc8b4 feat(native): page retained feature traces (#8585)
* feat(native): page retained feature traces

* fix(snapshot): retain linked source evidence for replay

* test(snapshot): verify linked foreign evidence stays scoped

* docs(mcp): clarify imported residual questions

* docs(mcp): guide trace reference classification

* fix(cli): report result sources when Evidence publication fails

A trace keeps linked sources on the result. Use those records for the
undelivered source closure as well as the bundle, so a refused output
does not report them as not captured.

* ci: rerun pull request checks

The merge of origin/main did not start the CI workflow for this head.

---------

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

227 lines
7.2 KiB
TypeScript

import { readFile, stat, writeFile } from "node:fs/promises";
import { join } from "node:path";
import { Cli } from "incur";
import pino from "pino";
import { expect, it } from "vitest";
import {
createAnalysisExecution,
type AnalysisProvider,
} from "../../../src/application/AnalysisProvider.js";
import { runDirectAnalysis } from "../../../src/application/DirectAnalysis.js";
import type { DirectAnalysisDependencies } from "../../../src/application/DirectAnalysisDependencies.js";
import { registerCoreBinaryCommands } from "../../../src/cli/coreBinaryCommands.js";
import { parseConfig } from "../../../src/config/parseConfig.js";
import { createAnalysisProfile } from "../../../src/domain/analysisProfile.js";
import { createEvidence } from "../../../src/domain/evidence.js";
import { parseEvidenceBundle } from "../../../src/domain/evidenceBundle.js";
import { ok } from "../../../src/domain/result.js";
import { createTestBinarySession } from "../../fixtures/binarySession.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
const identity = { id: "fixture", name: "Fixture", version: "1" } as const;
const effects = {
mutatesArtifact: false,
launchesProcess: false,
mayShowUi: false,
mayAccessNetwork: false,
mayWriteFilesystem: false,
changesPermissions: false,
requiresRoot: false,
};
const verifyReplay = async (
cli: ReturnType<typeof Cli.create>,
path: string,
snapshot: string,
root: string,
originalBundle: ReturnType<typeof parseEvidenceBundle>,
traceId: string | undefined,
) => {
const output = join(root, "replay-evidence.json");
let stdout = "";
await cli.serve(
[
"trace",
path,
"goal",
"--provider",
"fixture",
"--snapshot",
snapshot,
"--detail",
"summary",
"--evidence_output",
output,
"--json",
],
{
env: {},
stdout: (text) => {
stdout += text;
},
exit: () => undefined,
},
);
const response = JSON.parse(stdout);
expect(response, JSON.stringify(response)).toHaveProperty("summary");
const bundle = parseEvidenceBundle(
JSON.parse(await readFile(output, "utf8")),
);
expect(response.summary.normalized_result.parent_evidence_id).toBe(traceId);
expect(bundle.records.map((record) => record.evidence_id).sort()).toEqual(
originalBundle.records.map((record) => record.evidence_id).sort(),
);
};
it.each([
{ detail: "summary", missing: false },
{ detail: "complete", missing: false },
{ detail: "summary", missing: true },
{ detail: "summary", missing: false, replay: true },
])(
"publishes $detail trace only when its source closure is available (missing=$missing, replay=$replay)",
async ({ detail, missing, replay }) => {
const root = await createTestTempDirectory("rea-native-trace-cli-source-");
const path = join(root, "fixture.hop");
const output = join(root, "evidence.json");
const snapshot = join(root, "snapshot.json");
let allowProvider = true;
await writeFile(path, "synthetic analysis database");
const history = createEvidence(undefined, identity, {
operation: "health",
parameters: { facet: "historical-project-analysis-reports" },
result: { origin: "caller-project" },
confidence: "observed",
...(missing ? { evidenceLinks: ["ev_" + "a".repeat(64)] } : {}),
});
const provider: AnalysisProvider = {
identity: () => identity,
capabilities: () =>
(
[
"search_strings",
"search_procedures",
"xrefs",
"resolve_containing_procedure",
] as const
).map((operation) => ({
provider: identity,
operation,
available: true,
reason: null,
cachePolicy: replay ? "snapshot" : "live",
limitations: [],
effects,
})),
resolveAnalysisProfile: async () =>
ok({ profile: createAnalysisProfile(identity, { fixture: true }) }),
createClient: () => {
if (!allowProvider)
throw new Error("Snapshot replay reopened the provider");
return {
execute: async (operation) => {
const value =
operation === "search_procedures"
? [{ address: "0x1000", value: "goal" }]
: operation === "xrefs"
? ["0x1010"]
: operation === "resolve_containing_procedure"
? {
query_address: "0x1010",
found: false,
procedure: null,
reason: "not_in_procedure",
}
: operation === "search_strings"
? []
: null;
return ok(
createAnalysisExecution(value, identity, {
sourceEvidence: [history],
}),
);
},
close: async () => ok(null),
};
},
};
const createSession = () => createTestBinarySession(provider);
const dependencies: DirectAnalysisDependencies = {
readConfiguration: () => parseConfig({}),
createBinarySession: createSession,
createNativeDispatchBinarySession: createSession,
createArtifactBinarySession: createSession,
createNativeBinarySession: createSession,
createManagedBinarySession: createSession,
};
const cli = Cli.create("rea-native-trace-cli-source", { sync: false });
registerCoreBinaryCommands(
cli,
pino({ enabled: false }),
(target, tool, args, options) =>
runDirectAnalysis(dependencies, target, tool, args, options),
{},
);
let stdout = "";
await cli.serve(
[
"trace",
path,
"goal",
"--provider",
"fixture",
...(replay ? ["--snapshot", snapshot] : []),
"--detail",
detail,
"--evidence_output",
output,
"--json",
],
{
env: {},
stdout: (text) => {
stdout += text;
},
exit: () => undefined,
},
);
const response = JSON.parse(stdout);
if (missing) {
expect(response).toMatchObject({
code: "evidence_integrity_mismatch",
details: { reason: "missing", evidence_id: "ev_" + "a".repeat(64) },
});
await expect(stat(output)).rejects.toMatchObject({ code: "ENOENT" });
} else {
const bundle = parseEvidenceBundle(
JSON.parse(await readFile(output, "utf8")),
);
const trace = bundle.records.find(
(record) => record.operation === "trace_feature",
);
expect(
detail === "summary"
? response.summary.normalized_result.parent_evidence_id
: response.evidence_id,
).toBe(trace?.evidence_id);
expect(trace?.evidence_links).toContain(history.evidence_id);
expect(
bundle.records.some(
(record) => record.evidence_id === history.evidence_id,
),
).toBe(true);
if (replay) {
allowProvider = false;
await verifyReplay(
cli,
path,
snapshot,
root,
bundle,
trace?.evidence_id,
);
}
}
},
);