mirror of
https://github.com/morluto/rea.git
synced 2026-10-31 11:56:12 +00:00
* test: strengthen suite oracles and cleanup ownership * test: reuse setup across independent scenarios (#8153) * Potential fix for pull request finding 'CodeQL / Improper code sanitization' Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --------- Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
447 lines
14 KiB
TypeScript
447 lines
14 KiB
TypeScript
import { Client } from "@modelcontextprotocol/client";
|
|
import { StdioClientTransport } from "@modelcontextprotocol/client/stdio";
|
|
import { writeFile } from "node:fs/promises";
|
|
import { join, resolve } from "node:path";
|
|
import { afterAll, beforeAll, expect } from "vitest";
|
|
|
|
import { createEvidence, parseEvidence } from "../../../src/domain/evidence.js";
|
|
import { functionDossierSchema } from "../../../src/domain/native/functionDossier.js";
|
|
import {
|
|
MANAGED_APPLICATION_GRAPH_EXAMPLE,
|
|
MANAGED_NATIVE_VERIFICATION_EXAMPLE,
|
|
} from "../../../src/contracts/managed/managedWorkflowExamples.js";
|
|
import { managedMemberInspectionSchema } from "../../../src/domain/managed/managedArtifact.js";
|
|
import { managedApplicationGraphReferenceInputSchema } from "../../../src/contracts/managed/managedWorkflowToolContracts.js";
|
|
import { managedNativeVerificationResultSchema } from "../../../src/domain/managed/managedNativeVerificationSchemas.js";
|
|
import { buildManagedPeFixture } from "../../../src/dotnet/ManagedPe.fixture.js";
|
|
import { parseMcpToolError } from "../../fixtures/mcpToolError.js";
|
|
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
|
import { cliTest, runFileCli } from "../../support/cli/cliFixture.js";
|
|
|
|
const client = new Client({ name: "managed-native-adapters", version: "1" });
|
|
const transport = new StdioClientTransport({
|
|
command: process.execPath,
|
|
args: [resolve("scripts/rea.mjs"), "mcp"],
|
|
cwd: process.cwd(),
|
|
env: { PATH: process.env.PATH ?? "" },
|
|
stderr: "pipe",
|
|
});
|
|
beforeAll(async () => {
|
|
await client.connect(transport);
|
|
transport.stderr?.on("data", () => undefined);
|
|
});
|
|
afterAll(async () => {
|
|
await Promise.all([client.close(), transport.close()]);
|
|
});
|
|
|
|
cliTest(
|
|
"preserves managed graph identity failures and wrong-role controls through CLI and stdio MCP",
|
|
async ({ cli }) => {
|
|
const original = MANAGED_APPLICATION_GRAPH_EXAMPLE.managed_members;
|
|
const members = managedMemberInspectionSchema.parse(
|
|
original.normalized_result,
|
|
);
|
|
const otherDigest = "b".repeat(64);
|
|
const otherMvid = "ffffffff-ffff-ffff-ffff-ffffffffffff";
|
|
for (const variant of [
|
|
"subject-sha256",
|
|
"scope-sha256",
|
|
"scope-mvid",
|
|
] as const) {
|
|
const source = createEvidence(
|
|
variant === "subject-sha256"
|
|
? { path: members.artifact.path, format: "pe", sha256: otherDigest }
|
|
: undefined,
|
|
original.provider,
|
|
{
|
|
operation: original.operation,
|
|
parameters: {},
|
|
result: {
|
|
...members,
|
|
identity_scope: {
|
|
...members.identity_scope,
|
|
...(variant === "scope-sha256"
|
|
? { requires_artifact_sha256: otherDigest }
|
|
: {}),
|
|
...(variant === "scope-mvid" ? { requires_mvid: otherMvid } : {}),
|
|
},
|
|
},
|
|
rawResult: null,
|
|
},
|
|
);
|
|
// The record authenticates and the request has the advertised shape;
|
|
// rejection must identify the contradictory identities within that record.
|
|
const input = managedApplicationGraphReferenceInputSchema.parse({
|
|
managed_members: parseEvidence(JSON.parse(JSON.stringify(source))),
|
|
});
|
|
const response = await client.callTool({
|
|
name: "project_managed_application_graph",
|
|
arguments: input,
|
|
});
|
|
const error = parseMcpToolError(response).error;
|
|
const contradiction =
|
|
variant === "subject-sha256"
|
|
? `subject SHA-256 ${otherDigest} does not match normalized artifact SHA-256 ${members.artifact.sha256}`
|
|
: variant === "scope-sha256"
|
|
? `token scope SHA-256 ${otherDigest} does not match normalized artifact SHA-256 ${members.artifact.sha256}`
|
|
: `token scope MVID ${otherMvid} does not match module MVID ${String(members.module?.mvid)}`;
|
|
expect(error).toMatchObject({
|
|
code: "evidence_integrity_mismatch",
|
|
category: "integrity_mismatch",
|
|
retryable: false,
|
|
details: {
|
|
reason: `Managed Evidence inspect_managed_members (${source.evidence_id}) ${contradiction}`,
|
|
},
|
|
});
|
|
expect(error.recovery).toBeUndefined();
|
|
expect(response.structuredContent).toBeUndefined();
|
|
const command = await cli.run({
|
|
arguments: [
|
|
"project-managed-application-graph",
|
|
JSON.stringify(input),
|
|
"--json",
|
|
],
|
|
});
|
|
expect(command.exitCode, command.stderr).toBe(1);
|
|
expect(command.json).toMatchObject(error);
|
|
expect(command.json).not.toHaveProperty("recovery");
|
|
expect(command.json).not.toHaveProperty("evidence_id");
|
|
}
|
|
|
|
const wrongRole = MANAGED_NATIVE_VERIFICATION_EXAMPLE.managed_boundaries;
|
|
const wrongInput = { managed_members: wrongRole };
|
|
const wrongResponse = await client.callTool({
|
|
name: "project_managed_application_graph",
|
|
arguments: wrongInput,
|
|
});
|
|
const wrongError = parseMcpToolError(wrongResponse).error;
|
|
expect(wrongError).toMatchObject({
|
|
code: "invalid_request",
|
|
category: "invalid_input",
|
|
recovery: {
|
|
kind: "inspect_input_contract",
|
|
operation: "project_managed_application_graph",
|
|
},
|
|
details: {
|
|
issues: [
|
|
{
|
|
path: ["managed_members"],
|
|
reason: "invalid_value",
|
|
message: `Expected rea.analysis inspect_managed_members Evidence, received ${wrongRole.predicate_type} ${wrongRole.operation}`,
|
|
},
|
|
],
|
|
},
|
|
});
|
|
const wrongCommand = await cli.run({
|
|
arguments: [
|
|
"project-managed-application-graph",
|
|
JSON.stringify(wrongInput),
|
|
"--json",
|
|
],
|
|
});
|
|
expect(wrongCommand.exitCode, wrongCommand.stderr).toBe(1);
|
|
expect(wrongCommand.json).toMatchObject(wrongError);
|
|
|
|
const control = await client.callTool({
|
|
name: "project_managed_application_graph",
|
|
arguments: MANAGED_APPLICATION_GRAPH_EXAMPLE,
|
|
});
|
|
expect(control.isError, JSON.stringify(control.content)).not.toBe(true);
|
|
const commandControl = await cli.run({
|
|
arguments: [
|
|
"project-managed-application-graph",
|
|
JSON.stringify(MANAGED_APPLICATION_GRAPH_EXAMPLE),
|
|
"--json",
|
|
],
|
|
});
|
|
expect(commandControl.exitCode, commandControl.stderr).toBe(0);
|
|
const evidence = parseEvidence(control.structuredContent);
|
|
expect(parseEvidence(commandControl.json).normalized_result).toEqual(
|
|
evidence.normalized_result,
|
|
);
|
|
expect(evidence.evidence_links).toEqual([original.evidence_id]);
|
|
},
|
|
60_000,
|
|
);
|
|
|
|
/** Authentic native Evidence whose operation the workflow cannot read symbols from. */
|
|
const signatureEvidence = () =>
|
|
createEvidence(
|
|
{
|
|
path: "/usr/bin/true",
|
|
sha256: "a".repeat(64),
|
|
format: "mach-o",
|
|
architecture: "arm64",
|
|
},
|
|
{ id: "native", name: "Native", version: "simulated" },
|
|
{
|
|
predicateType: "rea.native-signature",
|
|
operation: "inspect_signature",
|
|
parameters: {},
|
|
result: { signed: true },
|
|
limitations: ["No native provider executed."],
|
|
},
|
|
);
|
|
|
|
const platformPinvokeCases = [
|
|
{
|
|
format: "pe",
|
|
scope: "nativehelper.dll",
|
|
module: "nativehelper.dll",
|
|
status: "verified",
|
|
},
|
|
{
|
|
format: "pe",
|
|
scope: "nativehelper.dll",
|
|
module: "nativehelper.exe",
|
|
status: "contradicted",
|
|
},
|
|
{
|
|
format: "pe",
|
|
scope: "nativehelper.dll",
|
|
module: "nativehelper.node",
|
|
status: "contradicted",
|
|
},
|
|
{
|
|
format: "pe",
|
|
scope: "nativehelper",
|
|
module: "nativehelper.dll",
|
|
status: "verified",
|
|
},
|
|
{
|
|
scope: "nativedep.so.6",
|
|
module: "libnativedep.so.6",
|
|
format: "elf",
|
|
status: "verified",
|
|
},
|
|
{
|
|
scope: "nativehelper",
|
|
module: "libnativehelper.so",
|
|
format: "elf",
|
|
flags: 0x202,
|
|
symbol: "open_nativeA",
|
|
status: "unresolved",
|
|
},
|
|
{
|
|
scope: "nativehelper",
|
|
module: "libnativehelper.dylib",
|
|
format: "mach-o",
|
|
flags: 0x204,
|
|
symbol: "open_nativeW",
|
|
status: "unresolved",
|
|
},
|
|
{
|
|
scope: "nativehelper",
|
|
module: "libnativehelper.so",
|
|
format: "elf",
|
|
flags: 0x204,
|
|
symbol: "open_native",
|
|
status: "verified",
|
|
},
|
|
{
|
|
scope: "nativehelper",
|
|
module: "nativehelper.dll",
|
|
format: "pe",
|
|
flags: 0x202,
|
|
symbol: "open_nativeA",
|
|
status: "inferred",
|
|
},
|
|
] as const;
|
|
|
|
cliTest(
|
|
"preserves platform-specific P/Invoke names and module matching through CLI and MCP",
|
|
async ({ cli }) => {
|
|
const root = await createTestTempDirectory(
|
|
"rea-managed-native-module-names-",
|
|
);
|
|
const nativeProvider = {
|
|
id: "native-fixture",
|
|
name: "Synthetic native fixture",
|
|
version: "1",
|
|
};
|
|
const dossier = functionDossierSchema.parse({
|
|
procedure: {
|
|
address: "0x1000",
|
|
name: "open_native",
|
|
classification: {
|
|
external: false,
|
|
thunk: false,
|
|
thunk_target: null,
|
|
provenance: "synthetic-provider",
|
|
},
|
|
body: { available: false, reason: "Synthetic test Evidence only." },
|
|
signature: null,
|
|
locals: [],
|
|
},
|
|
pseudocode: "",
|
|
assembly: [],
|
|
comments: [],
|
|
callers: [],
|
|
callees: [],
|
|
incoming_references: [],
|
|
outgoing_references: [],
|
|
referenced_strings: [],
|
|
referenced_names: [],
|
|
basic_blocks: [],
|
|
native_api: null,
|
|
native_value_flow: null,
|
|
limitations: ["No native provider was executed."],
|
|
});
|
|
|
|
for (const [index, item] of platformPinvokeCases.entries()) {
|
|
const managedPath = join(root, `managed-${String(index)}.dll`);
|
|
await writeFile(
|
|
managedPath,
|
|
buildManagedPeFixture({
|
|
pinvoke: {
|
|
importName: "open_native",
|
|
moduleName: item.scope,
|
|
...("flags" in item ? { mappingFlags: item.flags } : {}),
|
|
},
|
|
}),
|
|
);
|
|
const inspected = await client.callTool({
|
|
name: "inspect_managed_native_boundaries",
|
|
arguments: { path: managedPath },
|
|
});
|
|
expect(inspected.isError, JSON.stringify(inspected.content)).not.toBe(
|
|
true,
|
|
);
|
|
const managed = parseEvidence(inspected.structuredContent);
|
|
const native = createEvidence(
|
|
{
|
|
path: `/synthetic/${item.module}`,
|
|
sha256: "8".repeat(64),
|
|
format: item.format ?? "pe",
|
|
},
|
|
nativeProvider,
|
|
{
|
|
operation: "analyze_function",
|
|
parameters: {},
|
|
result: {
|
|
...dossier,
|
|
procedure: {
|
|
...dossier.procedure,
|
|
name: "symbol" in item ? item.symbol : "open_native",
|
|
},
|
|
},
|
|
rawResult: null,
|
|
limitations: ["Synthetic native Evidence; no provider executed."],
|
|
},
|
|
);
|
|
const input = {
|
|
managed_boundaries: managed,
|
|
native_observations: [native],
|
|
};
|
|
const mcp = await client.callTool({
|
|
name: "verify_managed_native_boundaries",
|
|
arguments: input,
|
|
});
|
|
expect(mcp.isError, JSON.stringify(mcp.content)).not.toBe(true);
|
|
const mcpResult = managedNativeVerificationResultSchema.parse(
|
|
parseEvidence(mcp.structuredContent).normalized_result,
|
|
);
|
|
const request = join(root, `verify-${String(index)}.json`);
|
|
await writeFile(request, JSON.stringify(input));
|
|
const invocation = {
|
|
arguments: ["verify-managed-native-boundaries", request, "--json"],
|
|
};
|
|
const cliRun =
|
|
index === 0
|
|
? await cli.run(invocation)
|
|
: await runFileCli(cli, invocation);
|
|
expect(cliRun.exitCode, cliRun.stderr).toBe(0);
|
|
const cliResult = managedNativeVerificationResultSchema.parse(
|
|
parseEvidence(cliRun.json).normalized_result,
|
|
);
|
|
expect(mcpResult).toEqual(cliResult);
|
|
expect(mcpResult.pinvoke_imports[0]).toMatchObject({
|
|
status: item.status,
|
|
...(item.status === "contradicted" ? { basis: "module-mismatch" } : {}),
|
|
...(item.status === "unresolved"
|
|
? {
|
|
basis: "no-native-candidate",
|
|
candidates: [],
|
|
matched_native: null,
|
|
}
|
|
: {}),
|
|
});
|
|
expect(mcpResult.evidence_links).toEqual([
|
|
managed.evidence_id,
|
|
native.evidence_id,
|
|
]);
|
|
}
|
|
},
|
|
60_000,
|
|
);
|
|
|
|
cliTest(
|
|
"counts authentic unsupported native Evidence identically through MCP and CLI",
|
|
async ({ cli }) => {
|
|
const root = await createTestTempDirectory("rea-managed-native-adapters-");
|
|
const path = join(root, "fixture.dll");
|
|
await writeFile(path, buildManagedPeFixture({ pinvoke: {} }));
|
|
const inspected = await client.callTool({
|
|
name: "inspect_managed_native_boundaries",
|
|
arguments: { path },
|
|
});
|
|
expect(inspected.isError).not.toBe(true);
|
|
const managed = parseEvidence(inspected.structuredContent);
|
|
const native = signatureEvidence();
|
|
const input = {
|
|
managed_boundaries: managed,
|
|
native_observations: [native],
|
|
};
|
|
|
|
const mcp = await client.callTool({
|
|
name: "verify_managed_native_boundaries",
|
|
arguments: input,
|
|
});
|
|
expect(mcp.isError, JSON.stringify(mcp.content)).not.toBe(true);
|
|
const mcpResult = managedNativeVerificationResultSchema.parse(
|
|
parseEvidence(mcp.structuredContent).normalized_result,
|
|
);
|
|
|
|
const request = join(root, "verify.json");
|
|
await writeFile(request, JSON.stringify(input));
|
|
const cliRun = await cli.run({
|
|
arguments: ["verify-managed-native-boundaries", request, "--json"],
|
|
});
|
|
expect(cliRun.exitCode, cliRun.stderr).toBe(0);
|
|
const cliResult = managedNativeVerificationResultSchema.parse(
|
|
parseEvidence(cliRun.json).normalized_result,
|
|
);
|
|
|
|
expect(mcpResult).toEqual(cliResult);
|
|
expect(mcpResult).toMatchObject({
|
|
native_observations: {
|
|
total: 1,
|
|
accepted: 0,
|
|
unsupported: 1,
|
|
symbols: 0,
|
|
},
|
|
summary: { unresolved: 1 },
|
|
pinvoke_imports: [
|
|
expect.objectContaining({ basis: "unsupported-native-evidence" }),
|
|
],
|
|
coverage: { status: "partial" },
|
|
evidence_links: [managed.evidence_id, native.evidence_id],
|
|
});
|
|
expect(mcpResult.limitations).toContain(
|
|
"Some native Evidence operations were unsupported by this workflow.",
|
|
);
|
|
|
|
const tampered = await client.callTool({
|
|
name: "verify_managed_native_boundaries",
|
|
arguments: {
|
|
...input,
|
|
native_observations: [{ ...native, operation: "inspect_macho" }],
|
|
},
|
|
});
|
|
expect(parseMcpToolError(tampered)).toMatchObject({
|
|
error: { code: "evidence_integrity_mismatch" },
|
|
});
|
|
},
|
|
60_000,
|
|
);
|