Files
reverse-engineering-anything/tests/boundary/mcp/sameFunctionObservation.test.ts
T
morlutoandCursor Agent 2d25a09c0f fix(native)!: recognize identical function evidence (#8442)
* fix(native)!: recognize identical function evidence

* test(native): verify same-evidence dimension citations

* fix(compare): reject impossible same-evidence changes

A comparison of one Evidence record cannot report a changed dimension,
unequal subject hashes, or unequal digests on an unchanged dimension.

* test(compare): admit the partial same-evidence fixture explicitly

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-11-07 21:06:39 +00:00

212 lines
7.5 KiB
TypeScript

import { afterAll, expect, it } from "vitest";
import { Ajv2020 } from "ajv/dist/2020.js";
import type { AnySchema } from "ajv";
import type { Client } from "@modelcontextprotocol/client";
import { createApplicationMcpHarness } from "../../fixtures/applicationMcpHarness.js";
import { createTestBinarySession } from "../../fixtures/binarySession.js";
import { createMcpSchemaValidation } from "../../fixtures/mcpSchemaValidation.js";
import { parseMcpToolError } from "../../fixtures/mcpToolError.js";
import { FUNCTION_COMPARISON_EXAMPLE } from "../../../src/contracts/functionComparisonExample.js";
import {
createEvidence,
parseEvidence,
type Evidence,
} from "../../../src/domain/evidence.js";
import { functionDossierSchema } from "../../../src/domain/native/functionDossier.js";
import { functionComparisonResultSchema } from "../../../src/domain/functionComparisonSchemas.js";
const example = FUNCTION_COMPARISON_EXAMPLE.left;
const dossier = functionDossierSchema.parse(example.normalized_result);
const { symbol: _symbol, ...procedure } = dossier.procedure;
const observation = (request: string) =>
createEvidence(
{ path: "/tmp/fixture", sha256: "0".repeat(64), format: "mach-o" },
example.provider,
{
operation: "analyze_function",
parameters: { procedure: request },
result: {
...dossier,
procedure,
comments: [],
facet_availability: {
...dossier.facet_availability,
comments: { available: false, reason: "Fixture has no comments." },
},
},
confidence: "derived",
authority: "shipped-artifact",
relationshipCoverage: { status: "complete" },
},
);
const main = observation("main");
const another = observation("another-selector");
const schemaValidation = createMcpSchemaValidation();
afterAll(() => schemaValidation.clear());
const ref = (evidence_id: string) => ({
kind: "retained-evidence",
evidence_id,
});
const expectRejectedDimensionCitation = async (
client: Client,
comparison: Evidence,
) => {
const original = functionComparisonResultSchema.parse(
comparison.normalized_result,
);
const altered = (dimension: (typeof original.dimensions)[number]) =>
dimension.dimension === "comments"
? {
...dimension,
evidence_links: [main.evidence_id, another.evidence_id],
}
: dimension;
const result = functionComparisonResultSchema.parse({
...original,
dimensions: original.dimensions.map(altered),
changes: original.changes.map(altered),
});
const invalid = createEvidence(undefined, comparison.provider, {
predicateType: comparison.predicate_type,
operation: comparison.operation,
parameters: comparison.parameters,
result,
confidence: comparison.confidence,
authority: comparison.authority,
limitations: comparison.limitations,
evidenceLinks: [main.evidence_id, another.evidence_id],
});
const response = await client.callTool({
name: "find_changed_behavior",
arguments: { comparisons: [invalid] },
});
expect(response.isError).toBe(true);
expect(parseMcpToolError(response).error.code).toBe(
"evidence_integrity_mismatch",
);
};
it.each(["full", "compact"] as const)(
"compares the same authenticated observation while preserving incomplete facets (%s)",
async (profile) => {
const session = createTestBinarySession(() => {
throw new Error("offline comparison must not launch a provider");
});
expect(session.recordEvidence(main).ok).toBe(true);
expect(session.recordEvidence(another).ok).toBe(true);
const { client } = await createApplicationMcpHarness({
session,
schemaValidator: schemaValidation,
serverOptions: {
environment: { REA_MCP_OUTPUT_SCHEMA_PROFILE: profile },
},
});
const schema = (await client.listTools()).tools.find(
({ name }) => name === "compare_functions",
)?.outputSchema;
if (schema === undefined) throw new Error("Missing output schema");
const reply = await client.callTool({
name: "compare_functions",
arguments: { left: ref(main.evidence_id), right: ref(main.evidence_id) },
});
expect(reply.isError, JSON.stringify(reply.content)).not.toBe(true);
expect(
new Ajv2020({ strict: false }).validate(
schema as AnySchema,
reply.structuredContent,
),
).toBe(true);
const result = parseEvidence(reply.structuredContent).normalized_result;
expect(result).toMatchObject({
status: "unknown",
function_match: { status: "matched", method: "same-evidence" },
dimensions: expect.arrayContaining([
expect.objectContaining({ dimension: "identity", status: "unchanged" }),
expect.objectContaining({ dimension: "comments", status: "unknown" }),
]),
});
const comparison = parseEvidence(reply.structuredContent);
const behavior = await client.callTool({
name: "find_changed_behavior",
arguments: { comparisons: [ref(comparison.evidence_id)] },
});
expect(behavior.isError, JSON.stringify(behavior.content)).not.toBe(true);
const behaviorResult = parseEvidence(
behavior.structuredContent,
).normalized_result;
expect(behaviorResult).toMatchObject({
behavior_status: "unknown",
findings: {
items: expect.arrayContaining([
expect.objectContaining({ dimension: "comments", status: "unknown" }),
]),
},
});
expect(behaviorResult).toMatchObject({
findings: {
items: expect.not.arrayContaining([
expect.objectContaining({ dimension: "identity" }),
]),
},
});
const contradictory = createEvidence(undefined, comparison.provider, {
predicateType: comparison.predicate_type,
operation: comparison.operation,
parameters: {
left_evidence_id: main.evidence_id,
right_evidence_id: another.evidence_id,
},
result: comparison.normalized_result,
confidence: comparison.confidence,
authority: comparison.authority,
limitations: comparison.limitations,
evidenceLinks: [main.evidence_id, another.evidence_id],
});
const contradictoryBehavior = await client.callTool({
name: "find_changed_behavior",
arguments: { comparisons: [contradictory] },
});
expect(contradictoryBehavior.isError).toBe(true);
expect(parseMcpToolError(contradictoryBehavior).error.code).toBe(
"evidence_integrity_mismatch",
);
await expectRejectedDimensionCitation(client, comparison);
const distinct = await client.callTool({
name: "compare_functions",
arguments: {
left: ref(main.evidence_id),
right: ref(another.evidence_id),
},
});
expect(
parseEvidence(distinct.structuredContent).normalized_result,
).toMatchObject({
function_match: { status: "ambiguous" },
});
const rebound = await client.callTool({
name: "compare_functions",
arguments: {
left: main,
right: { ...main, caller_input_path: "/tmp/alternate-spelling" },
},
});
expect(
parseEvidence(rebound.structuredContent).normalized_result,
).toMatchObject({
function_match: { status: "matched", method: "same-evidence" },
});
const tampered = await client.callTool({
name: "compare_functions",
arguments: {
left: ref(main.evidence_id),
right: { ...main, normalized_result: { ...dossier, procedure } },
},
});
expect(tampered.isError).toBe(true);
expect(parseMcpToolError(tampered).error.code).toBe(
"evidence_integrity_mismatch",
);
},
);