From ad398a17f551f976a5ed45ef1698fe473bc117ea Mon Sep 17 00:00:00 2001
From: morluto <76467478+morluto@users.noreply.github.com>
Date: Thu, 16 Jul 2026 18:49:02 +0800
Subject: [PATCH 01/19] chore(deps): detect stale direct dependency installs
---
scripts/check-dependency-install.mjs | 60 ++++++++++++++++++++
tests/dependencyInstall.test.ts | 82 ++++++++++++++++++++++++++++
2 files changed, 142 insertions(+)
create mode 100644 scripts/check-dependency-install.mjs
create mode 100644 tests/dependencyInstall.test.ts
diff --git a/scripts/check-dependency-install.mjs b/scripts/check-dependency-install.mjs
new file mode 100644
index 000000000..e3b9fbffd
--- /dev/null
+++ b/scripts/check-dependency-install.mjs
@@ -0,0 +1,60 @@
+import { readFile } from "node:fs/promises";
+import { resolve } from "node:path";
+
+const REMEDIATION = "Run `npm ci`, then retry.";
+
+const readJson = async (path) => JSON.parse(await readFile(path, "utf8"));
+
+const directDependencies = (rootPackage) => ({
+ ...rootPackage.dependencies,
+ ...rootPackage.devDependencies,
+});
+
+const installedPackageKey = (name) => `node_modules/${name}`;
+
+/** Compare root direct dependencies with npm's hidden installed lockfile. */
+export const dependencyInstallProblems = (rootLock, installedLock) => {
+ const rootPackage = rootLock.packages?.[""];
+ if (rootPackage === undefined)
+ return ["package-lock.json does not contain a root package entry"];
+ const installedPackages = installedLock.packages ?? {};
+ return Object.keys(directDependencies(rootPackage))
+ .sort()
+ .flatMap((name) => {
+ const key = installedPackageKey(name);
+ const expected = rootLock.packages?.[key]?.version;
+ const actual = installedPackages[key]?.version;
+ if (expected === undefined)
+ return [`${name}: missing resolved version in package-lock.json`];
+ if (actual === undefined)
+ return [`${name}: missing from the installed dependency lockfile`];
+ return actual === expected
+ ? []
+ : [`${name}: installed ${actual}, expected ${expected}`];
+ });
+};
+
+const main = async () => {
+ const root = process.cwd();
+ try {
+ const [rootLock, installedLock] = await Promise.all([
+ readJson(resolve(root, "package-lock.json")),
+ readJson(resolve(root, "node_modules/.package-lock.json")),
+ ]);
+ const problems = dependencyInstallProblems(rootLock, installedLock);
+ if (problems.length === 0) return;
+ process.stderr.write(
+ `Direct dependency installation is stale:\n${problems.map((problem) => `- ${problem}`).join("\n")}\n${REMEDIATION}\n`,
+ );
+ process.exitCode = 1;
+ } catch (error) {
+ const reason =
+ error instanceof Error ? error.message : "unreadable lockfile";
+ process.stderr.write(
+ `Could not verify the installed direct dependencies: ${reason}\n${REMEDIATION}\n`,
+ );
+ process.exitCode = 1;
+ }
+};
+
+if (process.argv[1] === new URL(import.meta.url).pathname) await main();
diff --git a/tests/dependencyInstall.test.ts b/tests/dependencyInstall.test.ts
new file mode 100644
index 000000000..46e6da91e
--- /dev/null
+++ b/tests/dependencyInstall.test.ts
@@ -0,0 +1,82 @@
+import { mkdtemp, mkdir, rm, writeFile } from "node:fs/promises";
+import { tmpdir } from "node:os";
+import { join } from "node:path";
+import { spawnSync } from "node:child_process";
+
+import { afterEach, describe, expect, it } from "vitest";
+
+const roots: string[] = [];
+const script = join(process.cwd(), "scripts", "check-dependency-install.mjs");
+
+afterEach(async () => {
+ await Promise.all(
+ roots.splice(0).map((root) => rm(root, { recursive: true })),
+ );
+});
+
+const fixture = async (
+ installedVersion?: string,
+ omitDevDependency = false,
+) => {
+ const root = await mkdtemp(join(tmpdir(), "rea-deps-"));
+ roots.push(root);
+ await mkdir(join(root, "node_modules"));
+ await writeFile(
+ join(root, "package-lock.json"),
+ JSON.stringify({
+ packages: {
+ "": {
+ dependencies: { alpha: "1.0.0" },
+ devDependencies: { beta: "2.0.0" },
+ },
+ "node_modules/alpha": { version: "1.0.0" },
+ "node_modules/beta": { version: "2.0.0" },
+ },
+ }),
+ );
+ await writeFile(
+ join(root, "node_modules", ".package-lock.json"),
+ JSON.stringify({
+ packages: {
+ "node_modules/alpha": { version: installedVersion ?? "1.0.0" },
+ ...(omitDevDependency
+ ? {}
+ : { "node_modules/beta": { version: "2.0.0" } }),
+ "node_modules/unrelated": { version: "9.0.0" },
+ },
+ }),
+ );
+ return root;
+};
+
+describe("dependency install freshness", () => {
+ it("accepts matching direct packages and ignores extraneous packages", async () => {
+ const result = spawnSync(process.execPath, [script], {
+ cwd: await fixture(),
+ encoding: "utf8",
+ });
+ expect(result.status, result.stderr).toBe(0);
+ });
+
+ it("reports a direct version mismatch with one remediation", async () => {
+ const result = spawnSync(process.execPath, [script], {
+ cwd: await fixture("0.9.0"),
+ encoding: "utf8",
+ });
+ expect(result.status).toBe(1);
+ expect(result.stderr).toContain("alpha: installed 0.9.0, expected 1.0.0");
+ expect(result.stderr.match(/npm ci/gu)).toHaveLength(1);
+ });
+
+ it("reports a missing direct development dependency", async () => {
+ const result = spawnSync(process.execPath, [script], {
+ cwd: await fixture(undefined, true),
+ encoding: "utf8",
+ });
+ expect(result.status).toBe(1);
+ expect(result.stderr).toContain(
+ "beta: missing from the installed dependency lockfile",
+ );
+ expect(result.stderr.match(/npm ci/gu)).toHaveLength(1);
+ });
+});
From ee1cd40405405097b9d5f9686cbcc765ab03d96a Mon Sep 17 00:00:00 2001
From: morluto <76467478+morluto@users.noreply.github.com>
Date: Thu, 16 Jul 2026 18:49:35 +0800
Subject: [PATCH 02/19] feat(mcp)!: harden contracts and evidence references
BREAKING CHANGE: comparison tools now require session-owned Evidence IDs or approved bundle paths, and structured Evidence results use compact references.
---
package.json | 11 +-
scripts/generate-mcp-schema-report.mjs | 69 +++++++
scripts/rea.mjs | 2 +-
scripts/verify-package.mjs | 19 +-
scripts/verify-published-package.mjs | 6 +-
scripts/verify-real-hopper.mjs | 4 +-
src/application/CapabilityInventory.ts | 1 +
.../JavaScriptApplicationWorkflowService.ts | 19 +-
src/application/JavaScriptReplayService.ts | 9 +-
.../JavaScriptRuntimeReconciliationService.ts | 10 +-
src/catalogIdentity.ts | 5 +-
src/cliJsonInput.ts | 16 +-
src/contracts/applicationToolContracts.ts | 34 +---
src/contracts/artifactToolContracts.ts | 11 +-
src/contracts/browserToolContracts.ts | 79 ++------
src/contracts/electronToolContracts.ts | 51 ++---
src/contracts/investigationExamples.ts | 6 -
src/contracts/managedToolContracts.ts | 8 +-
src/contracts/nativeToolContracts.ts | 8 +-
src/contracts/toolContractExamples.ts | 35 +---
src/contracts/toolContractTypes.ts | 7 +-
src/contracts/toolContracts.ts | 111 +++++-----
src/contracts/toolEffects.ts | 181 +++++++++++++++++
src/contracts/toolOutputSchemas.ts | 77 +++----
src/domain/artifactComparison.ts | 7 +-
src/domain/bundleComparison.ts | 7 +-
src/domain/errors.ts | 49 +++++
src/domain/functionComparisonSchemas.ts | 12 +-
src/domain/inputIssueProjection.ts | 83 ++++++++
.../reconstructionVerificationSchemas.ts | 5 +-
src/server/registerApplicationTools.ts | 26 ++-
src/server/registerArtifactComparisonTool.ts | 50 +++--
src/server/registerBrowserTools.ts | 71 ++++++-
src/server/registerBundleComparisonTool.ts | 62 ++----
src/server/registerElectronTools.ts | 36 +++-
src/server/registerEnhancedTools.ts | 17 +-
src/server/registerEvidenceTools.ts | 9 +-
src/server/registerFunctionComparisonTool.ts | 36 +++-
src/server/registerInvestigationTools.ts | 63 +++---
src/server/registerOfficialTools.ts | 19 +-
src/server/registerProcessComparisonTool.ts | 100 ++++-----
src/server/registerSessionStatusTool.ts | 17 +-
src/server/registerSessionTools.ts | 174 ++++++++--------
src/server/sessionEvidence.ts | 64 +++---
src/server/toolInputValidation.ts | 128 ++++++++++++
src/server/toolRegistrationOptions.ts | 191 +++++++++++++++++-
src/server/toolResult.ts | 54 +++--
47 files changed, 1387 insertions(+), 672 deletions(-)
create mode 100644 scripts/generate-mcp-schema-report.mjs
create mode 100644 src/contracts/toolEffects.ts
create mode 100644 src/domain/inputIssueProjection.ts
create mode 100644 src/server/toolInputValidation.ts
diff --git a/package.json b/package.json
index 1c2352228..761338fe2 100644
--- a/package.json
+++ b/package.json
@@ -50,9 +50,11 @@
"LICENSE"
],
"scripts": {
- "prebuild": "node scripts/generate-package-metadata.mjs",
+ "deps:check": "node scripts/check-dependency-install.mjs",
+ "prebuild": "npm run deps:check && node scripts/generate-package-metadata.mjs",
"build": "tsc -p tsconfig.build.json",
"postbuild": "node scripts/record-build-cache.mjs",
+ "precheck": "npm run deps:check",
"check": "npm run typecheck && npm run lint && npm run format:check && npm run docs:check && npm test",
"format": "prettier --write .",
"format:check": "prettier --check .",
@@ -85,9 +87,12 @@
"verify:package": "npm run build && node scripts/verify-package.mjs",
"verify:published": "node scripts/verify-published-package.mjs",
"config:print": "node scripts/print-mcp-config.mjs",
- "docs:generate": "npm run build && node scripts/generate-product-catalog.mjs && typedoc && node scripts/generate-error-schema.mjs",
- "docs:check": "node scripts/generate-package-metadata.mjs --check && npm run build && node scripts/generate-product-catalog.mjs --check && node scripts/check-doc-facts.mjs && node scripts/check-typedoc.mjs && node scripts/generate-error-schema.mjs --check",
+ "docs:generate": "npm run build && node scripts/generate-skill-metadata.mjs && node scripts/generate-mcp-schema-report.mjs && node scripts/generate-product-catalog.mjs && typedoc && node scripts/generate-error-schema.mjs",
+ "docs:check": "node scripts/generate-package-metadata.mjs --check && npm run build && node scripts/generate-skill-metadata.mjs --check && node scripts/generate-mcp-schema-report.mjs --check && node scripts/generate-product-catalog.mjs --check && node scripts/check-doc-facts.mjs && node scripts/check-typedoc.mjs && node scripts/generate-error-schema.mjs --check",
+ "schemas:report": "npm run build && node scripts/generate-mcp-schema-report.mjs",
"docs:error-schema": "npm run build && node scripts/generate-error-schema.mjs",
+ "prepack": "npm run deps:check && node scripts/generate-skill-metadata.mjs --check",
+ "prepublishOnly": "npm run deps:check && node scripts/generate-skill-metadata.mjs --check",
"prepare": "npm run build && husky",
"rebuild:native": "node scripts/rebuild-native.mjs"
},
diff --git a/scripts/generate-mcp-schema-report.mjs b/scripts/generate-mcp-schema-report.mjs
new file mode 100644
index 000000000..808b75710
--- /dev/null
+++ b/scripts/generate-mcp-schema-report.mjs
@@ -0,0 +1,69 @@
+import { Buffer } from "node:buffer";
+import { dirname, join } from "node:path";
+import { fileURLToPath, pathToFileURL } from "node:url";
+
+import { ensureGeneratedFile } from "./lib/generated-file.mjs";
+
+const arguments_ = new Set(process.argv.slice(2));
+for (const argument of arguments_)
+ if (argument !== "--check")
+ throw new Error(`Unknown MCP schema report option: ${argument}`);
+
+const root = join(dirname(fileURLToPath(import.meta.url)), "..");
+const cachebuster = `?${String(Date.now())}`;
+const { TOOL_CONTRACTS } = await import(
+ `${pathToFileURL(join(root, "dist/contracts/toolContracts.js")).href}${cachebuster}`
+);
+const { toolRegistrationOptions } = await import(
+ `${pathToFileURL(join(root, "dist/server/toolRegistrationOptions.js")).href}${cachebuster}`
+);
+
+const bytes = (value) => Buffer.byteLength(JSON.stringify(value), "utf8");
+const tools = TOOL_CONTRACTS.map((contract) => {
+ const registration = toolRegistrationOptions(contract);
+ const inputSchema = registration.inputSchema["~standard"].jsonSchema.input();
+ const outputSchema =
+ registration.outputSchema["~standard"].jsonSchema.output();
+ const wire = {
+ name: contract.name,
+ title: registration.title,
+ description: registration.description,
+ inputSchema,
+ outputSchema,
+ annotations: registration.annotations,
+ };
+ return {
+ name: contract.name,
+ bytes: bytes(wire),
+ input_schema_bytes: bytes(inputSchema),
+ output_schema_bytes: bytes(outputSchema),
+ wire,
+ };
+}).sort((left, right) => left.name.localeCompare(right.name));
+
+const maximumToolBytes = 64 * 1024;
+const maximumListBytes = 512 * 1024;
+const listBytes = bytes({ tools: tools.map(({ wire }) => wire) });
+const oversized = tools.filter((tool) => tool.bytes > maximumToolBytes);
+if (oversized.length > 0 || listBytes > maximumListBytes)
+ throw new Error(
+ `MCP schema budget exceeded: tools/list=${String(listBytes)}, oversized=${oversized.map(({ name, bytes: size }) => `${name}:${String(size)}`).join(",")}`,
+ );
+
+const report = {
+ generated_from: "@modelcontextprotocol/server 2.0.0-beta.4 wire registration",
+ tool_count: tools.length,
+ tools_list_bytes: listBytes,
+ budgets: {
+ tools_list_bytes: maximumListBytes,
+ per_tool_bytes: maximumToolBytes,
+ },
+ tools: tools.map(({ wire: _wire, ...tool }) => tool),
+};
+
+await ensureGeneratedFile({
+ path: join(root, "docs/mcp-schema-report.json"),
+ source: `${JSON.stringify(report, null, 2)}\n`,
+ check: arguments_.has("--check"),
+ generateCommand: "npm run docs:generate",
+});
diff --git a/scripts/rea.mjs b/scripts/rea.mjs
index b01a7abce..167c13402 100755
--- a/scripts/rea.mjs
+++ b/scripts/rea.mjs
@@ -5,7 +5,7 @@ import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
// Route production MCP before importing Incur. Incur owns registration helpers
-// such as `mcp add`, while only dist/main.js may serve the 80-tool stdio server.
+// such as `mcp add`, while only dist/main.js may serve the stdio tool catalog.
const args = process.argv.slice(2);
const { default: packageJson } = await import("../package.json", {
with: { type: "json" },
diff --git a/scripts/verify-package.mjs b/scripts/verify-package.mjs
index b2feb15fe..8c008505a 100644
--- a/scripts/verify-package.mjs
+++ b/scripts/verify-package.mjs
@@ -692,6 +692,18 @@ try {
(await readFile(siblingSkillPath, "utf8")) !== "unrelated skill\n"
)
throw new Error("packaged stale-skill upgrade was not isolated");
+ const alignedDoctor = json(
+ await run(cli, ["doctor", "--json"], environment),
+ );
+ if (
+ alignedDoctor.identity?.skill?.state !== "aligned" ||
+ alignedDoctor.identity?.skill?.installed_tool_count !==
+ TOOL_CONTRACTS.length ||
+ alignedDoctor.checks?.some(({ name }) => name === "skill:identity")
+ )
+ throw new Error(
+ "packaged doctor did not report the upgraded skill aligned",
+ );
await writeFile(claudeConfig, "malformed");
await writeFile(cursorConfig, '{"existing":true}\n');
@@ -860,7 +872,7 @@ try {
);
if (opened.isError === true)
throw new Error("packaged MCP could not open a binary");
- const providerStatus = json(
+ const providerStatusEnvelope = json(
prompts.mcpText(
await client.callTool(
{ name: "binary_session", arguments: {} },
@@ -868,6 +880,7 @@ try {
),
),
);
+ const providerStatus = providerStatusEnvelope.result;
if (
providerStatus.analysis_provider_binding?.provider?.id !== "hopper" ||
providerStatus.analysis_provider_binding?.selection_source !== "request"
@@ -891,13 +904,13 @@ try {
)
throw new Error("packaged Linux MCP did not reject an unpinned Hopper");
} else {
- if (json(prompts.mcpText(current)).normalized_result !== "fixture")
+ if (json(prompts.mcpText(current)).result !== "fixture")
throw new Error("packaged MCP bridge call failed");
const batch = await client.callTool(
{ name: "batch_decompile", arguments: { addresses: ["0x1000"] } },
mcpOptions,
);
- const batchResult = json(prompts.mcpText(batch)).normalized_result;
+ const batchResult = json(prompts.mcpText(batch)).result;
if (
batch.isError === true ||
batchResult?.total !== 1 ||
diff --git a/scripts/verify-published-package.mjs b/scripts/verify-published-package.mjs
index c3b2b3d6f..ffdc56ced 100644
--- a/scripts/verify-published-package.mjs
+++ b/scripts/verify-published-package.mjs
@@ -1,6 +1,8 @@
import { Client } from "@modelcontextprotocol/client";
import { StdioClientTransport } from "@modelcontextprotocol/client/stdio";
+import { CATALOG_IDENTITY } from "../dist/catalogIdentity.js";
+
const version = process.argv[2];
if (!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u.test(version ?? ""))
throw new Error("Usage: node scripts/verify-published-package.mjs ");
@@ -22,7 +24,7 @@ transport.stderr?.on("data", (chunk) => {
try {
await client.connect(transport);
const tools = await client.listTools();
- if (tools.tools.length !== 80)
+ if (tools.tools.length !== CATALOG_IDENTITY.counts.mcp_tools)
throw new Error(
`Published MCP exposed ${String(tools.tools.length)} tools`,
);
@@ -40,5 +42,5 @@ try {
}
process.stdout.write(
- `${JSON.stringify({ package: "rea-agents", version, mcpTools: 80 })}\n`,
+ `${JSON.stringify({ package: "rea-agents", version, mcpTools: CATALOG_IDENTITY.counts.mcp_tools })}\n`,
);
diff --git a/scripts/verify-real-hopper.mjs b/scripts/verify-real-hopper.mjs
index a52688ef8..de009ba2f 100644
--- a/scripts/verify-real-hopper.mjs
+++ b/scripts/verify-real-hopper.mjs
@@ -362,7 +362,9 @@ try {
const expectedNames = TOOL_CONTRACTS.map(({ name }) => name).sort();
const actualNames = listed.tools.map(({ name }) => name).sort();
if (JSON.stringify(actualNames) !== JSON.stringify(expectedNames)) {
- throw new Error("The real server did not expose the intended 80 tools");
+ throw new Error(
+ "The real server tool inventory did not match its contracts",
+ );
}
const options = { timeout };
diff --git a/src/application/CapabilityInventory.ts b/src/application/CapabilityInventory.ts
index 911d427c2..1ec2b05e3 100644
--- a/src/application/CapabilityInventory.ts
+++ b/src/application/CapabilityInventory.ts
@@ -79,6 +79,7 @@ export const buildCapabilityInventory = (
available: availability.reason === "available",
reason: availability.reason,
remediation: availability.remediation,
+ effects: { ...contract.effects },
annotations: {
read_only: contract.annotations.readOnlyHint ?? false,
destructive: contract.annotations.destructiveHint ?? false,
diff --git a/src/application/JavaScriptApplicationWorkflowService.ts b/src/application/JavaScriptApplicationWorkflowService.ts
index 1c94a3447..f1e6d36cd 100644
--- a/src/application/JavaScriptApplicationWorkflowService.ts
+++ b/src/application/JavaScriptApplicationWorkflowService.ts
@@ -6,6 +6,7 @@ import {
type AnalysisError,
} from "../domain/errors.js";
import type { Evidence } from "../domain/evidence.js";
+import { projectInputIssues } from "../domain/inputIssueProjection.js";
import { compareJavaScriptApplicationVersions } from "../domain/javascriptApplicationVersionComparison.js";
import { compareApplicationVersionsInputSchema } from "../domain/javascriptApplicationVersionComparisonSchemas.js";
import { traceApplicationFeature } from "../domain/javascriptFeatureTrace.js";
@@ -26,7 +27,14 @@ export const traceApplicationFeatureEvidence = (
): Result => {
const operation = "trace_application_feature";
const parsed = traceApplicationFeatureInputSchema.safeParse(rawInput);
- if (!parsed.success) return err(new AnalysisInputError(operation));
+ if (!parsed.success)
+ return err(
+ new AnalysisInputError(
+ operation,
+ undefined,
+ projectInputIssues(parsed.error.issues, rawInput),
+ ),
+ );
try {
const source = parseApplicationGraphEvidence(parsed.data.application);
const nativeEvidence = parseNativeApplicationEvidence(
@@ -63,7 +71,14 @@ export const compareApplicationVersionsEvidence = (
): Result => {
const operation = "compare_application_versions";
const parsed = compareApplicationVersionsInputSchema.safeParse(rawInput);
- if (!parsed.success) return err(new AnalysisInputError(operation));
+ if (!parsed.success)
+ return err(
+ new AnalysisInputError(
+ operation,
+ undefined,
+ projectInputIssues(parsed.error.issues, rawInput),
+ ),
+ );
try {
const left = parseApplicationGraphEvidence(parsed.data.left);
const right = parseApplicationGraphEvidence(parsed.data.right);
diff --git a/src/application/JavaScriptReplayService.ts b/src/application/JavaScriptReplayService.ts
index d89992032..1bbc342e5 100644
--- a/src/application/JavaScriptReplayService.ts
+++ b/src/application/JavaScriptReplayService.ts
@@ -17,6 +17,7 @@ import {
type AnalysisError,
} from "../domain/errors.js";
import { createEvidence } from "../domain/evidence.js";
+import { projectInputIssues } from "../domain/inputIssueProjection.js";
import { jsonValueSchema, type JsonValue } from "../domain/jsonValue.js";
import { err, ok, type Result } from "../domain/result.js";
import type { ExecutionOptions } from "./AnalysisProvider.js";
@@ -48,7 +49,13 @@ export const runControlledReplay = async (
): Promise> => {
const parsed = controlledReplayInputSchema.safeParse(rawInput);
if (!parsed.success)
- return err(new AnalysisInputError(OPERATION, { cause: parsed.error }));
+ return err(
+ new AnalysisInputError(
+ OPERATION,
+ { cause: parsed.error },
+ projectInputIssues(parsed.error.issues, rawInput),
+ ),
+ );
if (!dependencies.policy.enabled)
return err(
new AnalysisCapabilityUnavailableError(
diff --git a/src/application/JavaScriptRuntimeReconciliationService.ts b/src/application/JavaScriptRuntimeReconciliationService.ts
index 8676d4aaf..46bcb08f9 100644
--- a/src/application/JavaScriptRuntimeReconciliationService.ts
+++ b/src/application/JavaScriptRuntimeReconciliationService.ts
@@ -6,6 +6,7 @@ import {
type AnalysisError,
} from "../domain/errors.js";
import type { Evidence } from "../domain/evidence.js";
+import { projectInputIssues } from "../domain/inputIssueProjection.js";
import { reconcileJavaScriptRuntime } from "../domain/javascriptRuntimeReconciliation.js";
import { reconcileJavaScriptRuntimeInputSchema } from "../domain/javascriptRuntimeReconciliationSchemas.js";
import { err, ok, type Result } from "../domain/result.js";
@@ -18,7 +19,14 @@ export const reconcileJavaScriptRuntimeEvidence = (
rawInput: unknown,
): Result => {
const parsed = reconcileJavaScriptRuntimeInputSchema.safeParse(rawInput);
- if (!parsed.success) return err(new AnalysisInputError(OPERATION));
+ if (!parsed.success)
+ return err(
+ new AnalysisInputError(
+ OPERATION,
+ undefined,
+ projectInputIssues(parsed.error.issues, rawInput),
+ ),
+ );
try {
const result = reconcileJavaScriptRuntime(parsed.data);
return ok(
diff --git a/src/catalogIdentity.ts b/src/catalogIdentity.ts
index a0b4914b6..229764837 100644
--- a/src/catalogIdentity.ts
+++ b/src/catalogIdentity.ts
@@ -11,8 +11,10 @@ export { CLI_COMMAND_NAMES } from "./cliCommandNames.js";
const toolCatalog = TOOL_CONTRACTS.map((contract) => ({
name: contract.name,
+ title: contract.title,
surface: contract.kind,
description: contract.description,
+ effects: { ...contract.effects },
annotations: contract.annotations,
input_schema: z.toJSONSchema(contract.inputSchema, {
unrepresentable: "any",
@@ -87,9 +89,10 @@ export const CATALOG_IDENTITY = {
resource_templates: resourceTemplateCatalog,
}),
},
- tools: toolCatalog.map(({ name, surface, annotations }) => ({
+ tools: toolCatalog.map(({ name, surface, effects, annotations }) => ({
name,
surface,
+ effects,
annotations: {
read_only: annotations.readOnlyHint ?? false,
destructive: annotations.destructiveHint ?? false,
diff --git a/src/cliJsonInput.ts b/src/cliJsonInput.ts
index deca5b7bc..7c9ee3663 100644
--- a/src/cliJsonInput.ts
+++ b/src/cliJsonInput.ts
@@ -44,7 +44,11 @@ const parseJson = (value: string): unknown => {
const inputError = (operation: string): JsonValue => ({
error: "Application workflow failed",
- ...projectAnalysisError(new AnalysisInputError(operation)),
+ ...projectAnalysisError(
+ new AnalysisInputError(operation, undefined, [
+ { path: [], reason: "invalid_format", expected: "JSON" },
+ ]),
+ ),
});
const jsonFileError = (
@@ -55,7 +59,15 @@ const jsonFileError = (
ok: false as const,
error: {
error: "Application workflow failed",
- ...projectAnalysisError(new AnalysisInputError(operation)),
+ ...projectAnalysisError(
+ new AnalysisInputError(
+ operation,
+ undefined,
+ reason === "invalid-json"
+ ? [{ path: [], reason: "invalid_format", expected: "JSON" }]
+ : [],
+ ),
+ ),
input_path: path,
input_reason: reason,
maximum_input_bytes: MAX_JSON_INPUT_BYTES,
diff --git a/src/contracts/applicationToolContracts.ts b/src/contracts/applicationToolContracts.ts
index 612b11513..24f236c5a 100644
--- a/src/contracts/applicationToolContracts.ts
+++ b/src/contracts/applicationToolContracts.ts
@@ -6,39 +6,33 @@ import {
applicationFeatureTraceResultSchema,
traceApplicationFeatureInputSchema,
} from "../domain/javascriptFeatureTraceSchemas.js";
-import { evidenceEnvelopeSchema } from "../domain/evidence.js";
import {
controlledReplayInputSchema,
controlledReplayOutputSchema,
} from "../domain/javascriptReplay.js";
import type { ToolContract } from "./toolContracts.js";
+import { toolContractMetadata } from "./toolEffects.js";
+import { evidenceResultOf } from "./toolOutputSchemas.js";
import {
JAVASCRIPT_APPLICATION_VERSION_COMPARISON_EXAMPLE,
JAVASCRIPT_FEATURE_TRACE_EXAMPLE,
} from "./javascriptApplicationWorkflowExamples.js";
-const traceOutputSchema = evidenceEnvelopeSchema
- .omit({ normalized_result: true })
- .extend({ normalized_result: applicationFeatureTraceResultSchema });
-const comparisonOutputSchema = evidenceEnvelopeSchema
- .omit({ normalized_result: true })
- .extend({ normalized_result: applicationVersionComparisonResultSchema });
+const traceOutputSchema = evidenceResultOf(applicationFeatureTraceResultSchema);
+const comparisonOutputSchema = evidenceResultOf(
+ applicationVersionComparisonResultSchema,
+);
/** Provider-neutral graph workflow contracts shared by MCP and CLI adapters. */
export const APPLICATION_TOOL_CONTRACTS = [
{
name: "trace_application_feature",
+ ...toolContractMetadata("trace_application_feature"),
description:
"Trace a typed literal seed through an authenticated JavaScript Application Graph with explicit direction, depth, node, edge, and path bounds. Original static, native, passive-runtime, inferred, and unknown authorities remain distinct; native addon handoffs never open a provider or execute the application.",
kind: "application",
inputSchema: traceApplicationFeatureInputSchema,
outputSchema: traceOutputSchema,
- annotations: {
- readOnlyHint: true,
- destructiveHint: false,
- idempotentHint: true,
- openWorldHint: false,
- },
examples: [
{
title: "Trace one module seed through a retained application graph",
@@ -48,17 +42,12 @@ export const APPLICATION_TOOL_CONTRACTS = [
},
{
name: "compare_application_versions",
+ ...toolContractMetadata("compare_application_versions"),
description:
"Compare two authenticated JavaScript Application Graph versions using unique-only exact digest, module source digest, source-map identity, structural fingerprint, and non-module semantic-key tiers. Reports added, removed, changed, ambiguous, and unknown entities plus a bounded changed_from graph without fuzzy or module-ordinal pairing.",
kind: "application",
inputSchema: compareApplicationVersionsInputSchema,
outputSchema: comparisonOutputSchema,
- annotations: {
- readOnlyHint: true,
- destructiveHint: false,
- idempotentHint: true,
- openWorldHint: false,
- },
examples: [
{
title: "Compare authenticated static and reconciled application graphs",
@@ -68,17 +57,12 @@ export const APPLICATION_TOOL_CONTRACTS = [
},
{
name: "run_controlled_replay",
+ ...toolContractMetadata("run_controlled_replay"),
description:
"Plan or execute a content-bound extracted-module JavaScript replay inside the Linux Bubblewrap, seccomp, and cgroup boundary. Execution requires approved: true and the exact plan digest. Supports deterministic boundary cases and optional left/right differential comparison; observations have controlled-replay authority and do not claim real application runtime behavior.",
kind: "application",
inputSchema: controlledReplayInputSchema,
outputSchema: controlledReplayOutputSchema,
- annotations: {
- readOnlyHint: false,
- destructiveHint: true,
- idempotentHint: true,
- openWorldHint: false,
- },
examples: [
{
title: "Plan one extracted ESM parser replay",
diff --git a/src/contracts/artifactToolContracts.ts b/src/contracts/artifactToolContracts.ts
index ecaf77771..7ada8bcdb 100644
--- a/src/contracts/artifactToolContracts.ts
+++ b/src/contracts/artifactToolContracts.ts
@@ -3,6 +3,7 @@ import { z } from "zod";
import type { ToolContract } from "./toolContracts.js";
import { artifactOutputSchemas } from "./toolOutputSchemas.js";
import { jsonValueSchema } from "../domain/jsonValue.js";
+import { toolContractMetadata } from "./toolEffects.js";
const pageInput = {
node_offset: z.number().int().min(0).default(0),
@@ -81,23 +82,17 @@ const artifact = (
name: Name,
description: string,
inputSchema: z.ZodObject,
- mutatesFilesystem: boolean,
): ToolContract => {
const outputSchema = artifactOutputSchemas[name];
if (outputSchema === undefined)
throw new Error(`Missing artifact output schema for ${name}`);
return {
name,
+ ...toolContractMetadata(name),
description,
kind: "artifact-provider",
inputSchema,
outputSchema,
- annotations: {
- readOnlyHint: !mutatesFilesystem,
- destructiveHint: false,
- idempotentHint: true,
- openWorldHint: false,
- },
examples: [
{
title: `Example ${name.replaceAll("_", " ")} request`,
@@ -113,13 +108,11 @@ export const ARTIFACT_TOOL_CONTRACTS = [
"inventory_artifact",
"Inventory the active application or package as a deterministic, content-addressed artifact graph. Returns bounded node and edge pages without extracting or mounting by default.",
artifactInventoryInputSchema,
- false,
),
artifact(
"extract_artifact",
"Extract selected graph artifacts beneath an explicit output root. Requires approval, rejects traversal and symlink escapes, never overwrites, enforces bomb limits, and verifies cleanup.",
artifactExtractionInputSchema,
- true,
),
] as const satisfies readonly ToolContract[];
diff --git a/src/contracts/browserToolContracts.ts b/src/contracts/browserToolContracts.ts
index 8bc479fbf..7bf708b20 100644
--- a/src/contracts/browserToolContracts.ts
+++ b/src/contracts/browserToolContracts.ts
@@ -1,6 +1,4 @@
import type { ToolContract } from "./toolContracts.js";
-import { z } from "zod";
-import { evidenceEnvelopeSchema } from "../domain/evidence.js";
import {
browserTargetListSchema,
inspectWebPageInputSchema,
@@ -29,21 +27,16 @@ import {
webScreenshotDiffSchema,
webScreenshotSchema,
} from "../domain/webScreenshot.js";
+import { toolContractMetadata } from "./toolEffects.js";
+import { evidenceResultOf } from "./toolOutputSchemas.js";
-const evidenceResult = (schema: Schema) =>
- evidenceEnvelopeSchema
- .omit({ normalized_result: true })
- .extend({ normalized_result: schema });
+const evidenceResult = evidenceResultOf;
const listOutputSchema = evidenceResult(browserTargetListSchema);
-const inspectionOutputSchema = evidenceEnvelopeSchema
- .omit({ normalized_result: true })
- .extend({ normalized_result: webPageInspectionSchema });
-const bundleOutputSchema = evidenceEnvelopeSchema
- .omit({ normalized_result: true })
- .extend({ normalized_result: webBundleAnalysisSchema });
-const observationSessionOutputSchema = evidenceEnvelopeSchema
- .omit({ normalized_result: true })
- .extend({ normalized_result: webObservationSessionSchema });
+const inspectionOutputSchema = evidenceResult(webPageInspectionSchema);
+const bundleOutputSchema = evidenceResult(webBundleAnalysisSchema);
+const observationSessionOutputSchema = evidenceResult(
+ webObservationSessionSchema,
+);
const webMcpOutputSchema = evidenceResult(webMcpDiscoverySchema);
const captureDiffOutputSchema = evidenceResult(webCaptureDiffSchema);
const screenshotOutputSchema = evidenceResult(webScreenshotSchema);
@@ -56,17 +49,12 @@ const origin = "https://app.example.test";
export const BROWSER_TOOL_CONTRACTS = [
{
name: "list_browser_targets",
+ ...toolContractMetadata("list_browser_targets"),
description:
"List bounded page targets from an approved user-owned loopback Chrome DevTools Protocol endpoint. Only targets whose current URL matches an approved exact origin are returned; URL credentials, query values, and fragments are redacted.",
kind: "browser-provider",
inputSchema: listBrowserTargetsInputSchema,
outputSchema: listOutputSchema,
- annotations: {
- readOnlyHint: true,
- destructiveHint: false,
- idempotentHint: true,
- openWorldHint: true,
- },
examples: [
{
title: "List approved browser page targets",
@@ -82,17 +70,12 @@ export const BROWSER_TOOL_CONTRACTS = [
},
{
name: "inspect_web_page",
+ ...toolContractMetadata("inspect_web_page"),
description:
"Passively inspect one approved page target through CDP without evaluating JavaScript, navigating, clicking, closing, or mutating the page. Returns bounded DOM structure, accessibility, scripts, resources, attach-window network and console metadata, workers, and redacted storage inventory as Evidence v2.",
kind: "browser-provider",
inputSchema: inspectWebPageInputSchema,
outputSchema: inspectionOutputSchema,
- annotations: {
- readOnlyHint: true,
- destructiveHint: false,
- idempotentHint: true,
- openWorldHint: true,
- },
examples: [
{
title: "Inspect one approved browser page",
@@ -141,17 +124,12 @@ export const BROWSER_TOOL_CONTRACTS = [
},
{
name: "analyze_web_bundle",
+ ...toolContractMetadata("analyze_web_bundle"),
description:
"Capture explicitly approved JavaScript source from one approved CDP page and statically derive a bounded chunk graph, route and endpoint candidates, vendor fingerprints, page-declared WebMCP metadata, and optional separately approved source-map evidence. JavaScript is parsed but never executed.",
kind: "browser-provider",
inputSchema: analyzeWebBundleInputSchema,
outputSchema: bundleOutputSchema,
- annotations: {
- readOnlyHint: true,
- destructiveHint: false,
- idempotentHint: true,
- openWorldHint: true,
- },
examples: [
{
title: "Analyze an approved page bundle",
@@ -182,17 +160,12 @@ export const BROWSER_TOOL_CONTRACTS = [
},
{
name: "observe_web_session",
+ ...toolContractMetadata("observe_web_session"),
description:
"Arm a bounded CDP observation window while the user operates the page. Allows approved same-origin reload and SPA navigation, records ordered navigation, redirect, lifecycle, and failure metadata, and stops before retaining an out-of-policy destination.",
kind: "browser-provider",
inputSchema: observeWebSessionInputSchema,
outputSchema: observationSessionOutputSchema,
- annotations: {
- readOnlyHint: true,
- destructiveHint: false,
- idempotentHint: false,
- openWorldHint: true,
- },
examples: [
{
title: "Observe one external user action",
@@ -209,17 +182,12 @@ export const BROWSER_TOOL_CONTRACTS = [
},
{
name: "discover_webmcp_tools",
+ ...toolContractMetadata("discover_webmcp_tools"),
description:
"Passively inventory page-registered WebMCP tools using the experimental CDP WebMCP domain. Metadata is bounded and page-declared-untrusted; REA never registers or invokes discovered tools.",
kind: "browser-provider",
inputSchema: discoverWebMcpToolsInputSchema,
outputSchema: webMcpOutputSchema,
- annotations: {
- readOnlyHint: true,
- destructiveHint: false,
- idempotentHint: true,
- openWorldHint: true,
- },
examples: [
{
title: "Discover current WebMCP declarations",
@@ -239,17 +207,12 @@ export const BROWSER_TOOL_CONTRACTS = [
},
{
name: "compare_web_captures",
+ ...toolContractMetadata("compare_web_captures"),
description:
"Compare two normalized web captures across DOM, scripts, resources, network, safe metadata, and optional WebMCP inventories. Stable observed changes are distinguished from unknown absence caused by incomplete capture coverage.",
kind: "browser-provider",
inputSchema: compareWebCapturesInputSchema,
outputSchema: captureDiffOutputSchema,
- annotations: {
- readOnlyHint: true,
- destructiveHint: false,
- idempotentHint: true,
- openWorldHint: false,
- },
examples: [
{
title: "Compare two normalized captures",
@@ -263,17 +226,12 @@ export const BROWSER_TOOL_CONTRACTS = [
},
{
name: "capture_web_screenshot",
+ ...toolContractMetadata("capture_web_screenshot"),
description:
"Capture the current visible viewport of one approved page as a bounded, content-addressed PNG artifact. Screenshot capture requires separate explicit approval and never scrolls, navigates, or evaluates page JavaScript.",
kind: "browser-provider",
inputSchema: captureWebScreenshotInputSchema,
outputSchema: screenshotOutputSchema,
- annotations: {
- readOnlyHint: true,
- destructiveHint: false,
- idempotentHint: false,
- openWorldHint: true,
- },
examples: [
{
title: "Capture an approved viewport",
@@ -290,17 +248,12 @@ export const BROWSER_TOOL_CONTRACTS = [
},
{
name: "compare_web_screenshots",
+ ...toolContractMetadata("compare_web_screenshots"),
description:
"Compare two self-verifying PNG screenshot artifacts with bounded local pixel metrics. Returns exact changed-pixel ratios and channel deltas without OCR or external services.",
kind: "browser-provider",
inputSchema: compareWebScreenshotsInputSchema,
outputSchema: screenshotDiffOutputSchema,
- annotations: {
- readOnlyHint: true,
- destructiveHint: false,
- idempotentHint: true,
- openWorldHint: false,
- },
examples: [
{
title: "Compare two screenshot artifacts",
diff --git a/src/contracts/electronToolContracts.ts b/src/contracts/electronToolContracts.ts
index c46de2773..1299e5a0d 100644
--- a/src/contracts/electronToolContracts.ts
+++ b/src/contracts/electronToolContracts.ts
@@ -1,5 +1,6 @@
import type { ToolContract } from "./toolContracts.js";
-import { evidenceEnvelopeSchema } from "../domain/evidence.js";
+import { toolContractMetadata } from "./toolEffects.js";
+import { evidenceResultOf } from "./toolOutputSchemas.js";
import {
electronPageInspectionSchema,
electronTargetListSchema,
@@ -16,18 +17,14 @@ import {
} from "../domain/javascriptRuntimeReconciliationSchemas.js";
import { JAVASCRIPT_RUNTIME_RECONCILIATION_EXAMPLE } from "./javascriptRuntimeReconciliationExample.js";
-const listOutputSchema = evidenceEnvelopeSchema
- .omit({ normalized_result: true })
- .extend({ normalized_result: electronTargetListSchema });
-const inspectionOutputSchema = evidenceEnvelopeSchema
- .omit({ normalized_result: true })
- .extend({ normalized_result: electronPageInspectionSchema });
-const applicationOutputSchema = evidenceEnvelopeSchema
- .omit({ normalized_result: true })
- .extend({ normalized_result: javascriptApplicationAnalysisResultSchema });
-const reconciliationOutputSchema = evidenceEnvelopeSchema
- .omit({ normalized_result: true })
- .extend({ normalized_result: javascriptRuntimeReconciliationResultSchema });
+const listOutputSchema = evidenceResultOf(electronTargetListSchema);
+const inspectionOutputSchema = evidenceResultOf(electronPageInspectionSchema);
+const applicationOutputSchema = evidenceResultOf(
+ javascriptApplicationAnalysisResultSchema,
+);
+const reconciliationOutputSchema = evidenceResultOf(
+ javascriptRuntimeReconciliationResultSchema,
+);
const endpoint = "http://127.0.0.1:9223";
const root = "/Applications/Example.app/Contents/Resources";
@@ -36,17 +33,12 @@ const root = "/Applications/Example.app/Contents/Resources";
export const ELECTRON_TOOL_CONTRACTS = [
{
name: "list_electron_targets",
+ ...toolContractMetadata("list_electron_targets"),
description:
"List Electron file:// page targets from an approved user-owned loopback CDP endpoint. Every path is canonicalized and must remain contained by an approved filesystem root, including after symlink resolution.",
kind: "electron-provider",
inputSchema: listElectronTargetsInputSchema,
outputSchema: listOutputSchema,
- annotations: {
- readOnlyHint: true,
- destructiveHint: false,
- idempotentHint: true,
- openWorldHint: true,
- },
examples: [
{
title: "List approved Electron file pages",
@@ -62,17 +54,12 @@ export const ELECTRON_TOOL_CONTRACTS = [
},
{
name: "inspect_electron_page",
+ ...toolContractMetadata("inspect_electron_page"),
description:
"Passively inspect one approved Electron file page through CDP. Returns root-confined frames, DOM structure, resource paths, and scripts without evaluating renderer JavaScript or invoking Electron APIs; script contents require separate approval.",
kind: "electron-provider",
inputSchema: inspectElectronPageInputSchema,
outputSchema: inspectionOutputSchema,
- annotations: {
- readOnlyHint: true,
- destructiveHint: false,
- idempotentHint: true,
- openWorldHint: true,
- },
examples: [
{
title: "Inspect an approved Electron page",
@@ -99,17 +86,12 @@ export const ELECTRON_TOOL_CONTRACTS = [
},
{
name: "analyze_javascript_application",
+ ...toolContractMetadata("analyze_javascript_application"),
description:
"Statically reconstruct one approved local ASAR or extracted JavaScript application as Evidence v2 and JavaScript Application Graph v1. Maps BrowserWindow preferences, preload and contextBridge APIs, literal and dynamic IPC, handler locations, sender-validation observations, utility processes, and requested native addon bindings without executing JavaScript; source-map contents require separate approval.",
kind: "electron-provider",
inputSchema: analyzeJavaScriptApplicationInputSchema,
outputSchema: applicationOutputSchema,
- annotations: {
- readOnlyHint: true,
- destructiveHint: false,
- idempotentHint: true,
- openWorldHint: false,
- },
examples: [
{
title: "Analyze one approved local Electron application",
@@ -124,17 +106,12 @@ export const ELECTRON_TOOL_CONTRACTS = [
},
{
name: "reconcile_javascript_runtime",
+ ...toolContractMetadata("reconcile_javascript_runtime"),
description:
"Reconcile verified static JavaScript application graphs with existing passive web or Electron CDP Evidence. Exact captured-source digests take priority over caller-declared file/URL mappings; target, frame, script, and worker ambiguity remains explicit, and source-map authority stays separate.",
kind: "electron-provider",
inputSchema: reconcileJavaScriptRuntimeInputSchema,
outputSchema: reconciliationOutputSchema,
- annotations: {
- readOnlyHint: true,
- destructiveHint: false,
- idempotentHint: true,
- openWorldHint: false,
- },
examples: [
{
title: "Reconcile one passive Electron capture",
diff --git a/src/contracts/investigationExamples.ts b/src/contracts/investigationExamples.ts
index 6b74affc9..1f3109e73 100644
--- a/src/contracts/investigationExamples.ts
+++ b/src/contracts/investigationExamples.ts
@@ -1,7 +1,6 @@
import { compareFunctions } from "../domain/functionComparison.js";
import { createEvidence } from "../domain/evidence.js";
import { jsonValueSchema } from "../domain/jsonValue.js";
-import { createEvidenceBundle } from "../domain/evidenceBundle.js";
import {
compareProcessCaptures,
processCaptureSchema,
@@ -130,10 +129,5 @@ export const INVESTIGATION_EXAMPLES = {
},
],
},
- evidence_bundle: createEvidenceBundle([
- PROCESS_CAPTURE_REFERENCE,
- PROCESS_CAPTURE_RECONSTRUCTION,
- PROCESS_COMPARISON_EVIDENCE,
- ]),
},
};
diff --git a/src/contracts/managedToolContracts.ts b/src/contracts/managedToolContracts.ts
index 49254ceb5..8b390dd09 100644
--- a/src/contracts/managedToolContracts.ts
+++ b/src/contracts/managedToolContracts.ts
@@ -2,6 +2,7 @@ import { z } from "zod";
import type { ToolContract } from "./toolContracts.js";
import { managedOutputSchemas } from "./toolOutputSchemas.js";
+import { toolContractMetadata } from "./toolEffects.js";
/** Exact caller boundary for execution-free PE/CLI triage and identity. */
export const managedArtifactInputSchema = z.object({
@@ -119,17 +120,12 @@ if (nativeBoundaryOutputSchema === undefined)
export const MANAGED_TOOL_CONTRACTS = [
{
name: "inspect_managed_artifact",
+ ...toolContractMetadata("inspect_managed_artifact"),
description:
"Classify the active PE/CLI artifact and inventory exact assembly/module identity, target framework evidence, references, resources, and custom attributes without loading or executing target code. Returns bounded pages and explicit partial or malformed coverage.",
kind: "managed-provider",
inputSchema: managedArtifactInputSchema,
outputSchema,
- annotations: {
- readOnlyHint: true,
- destructiveHint: false,
- idempotentHint: true,
- openWorldHint: false,
- },
examples: [
{
title: "Example inspect managed artifact request",
diff --git a/src/contracts/nativeToolContracts.ts b/src/contracts/nativeToolContracts.ts
index 4ed43be98..589c43e95 100644
--- a/src/contracts/nativeToolContracts.ts
+++ b/src/contracts/nativeToolContracts.ts
@@ -3,6 +3,7 @@ import { z } from "zod";
import type { ToolContract } from "./toolContracts.js";
import { nativeOutputSchemas } from "./toolOutputSchemas.js";
import { jsonValueSchema } from "../domain/jsonValue.js";
+import { toolContractMetadata } from "./toolEffects.js";
const examples: Readonly>>> = {
inspect_macho: {},
@@ -22,16 +23,11 @@ const native = (
throw new Error(`Missing native output schema for ${name}`);
return {
name,
+ ...toolContractMetadata(name),
description,
kind: "native-provider",
inputSchema,
outputSchema,
- annotations: {
- readOnlyHint: true,
- destructiveHint: false,
- idempotentHint: true,
- openWorldHint: false,
- },
examples: [
{
title: `Example ${name.replaceAll("_", " ")} request`,
diff --git a/src/contracts/toolContractExamples.ts b/src/contracts/toolContractExamples.ts
index d6d452960..de4fe5838 100644
--- a/src/contracts/toolContractExamples.ts
+++ b/src/contracts/toolContractExamples.ts
@@ -1,5 +1,4 @@
import type { JsonValue } from "../domain/jsonValue.js";
-import { EMPTY_PROCESS_CAPTURE_EXAMPLE } from "./processCaptureExample.js";
import { UNKNOWN_CONTRACT_EXAMPLES } from "./unknownContractExamples.js";
import { ARTIFACT_COMPARISON_EXAMPLE } from "./artifactComparisonExample.js";
import { FUNCTION_COMPARISON_EXAMPLE } from "./functionComparisonExample.js";
@@ -42,32 +41,18 @@ export const TOOL_EXAMPLE_OVERRIDES: Readonly<
},
compare_process_captures: {
left_evidence_id: `ev_${"0".repeat(64)}`,
- left: EMPTY_PROCESS_CAPTURE_EXAMPLE,
right_evidence_id: `ev_${"1".repeat(64)}`,
- right: EMPTY_PROCESS_CAPTURE_EXAMPLE,
},
- compare_artifacts: ARTIFACT_COMPARISON_EXAMPLE,
- compare_functions: FUNCTION_COMPARISON_EXAMPLE,
+ compare_artifacts: {
+ left_evidence_ids: [ARTIFACT_COMPARISON_EXAMPLE.left.evidence_id],
+ right_evidence_ids: [ARTIFACT_COMPARISON_EXAMPLE.right.evidence_id],
+ },
+ compare_functions: {
+ left_evidence_ids: [FUNCTION_COMPARISON_EXAMPLE.left.evidence_id],
+ right_evidence_ids: [FUNCTION_COMPARISON_EXAMPLE.right.evidence_id],
+ },
compare_bundles: {
- left: {
- bundle_version: 2,
- artifacts: [],
- providers: [],
- environments: [],
- scenarios: [],
- captures: [],
- unknowns: [],
- records: [],
- },
- right: {
- bundle_version: 2,
- artifacts: [],
- providers: [],
- environments: [],
- scenarios: [],
- captures: [],
- unknowns: [],
- records: [],
- },
+ left_bundle_path: "/approved/left-evidence.json",
+ right_bundle_path: "/approved/right-evidence.json",
},
};
diff --git a/src/contracts/toolContractTypes.ts b/src/contracts/toolContractTypes.ts
index 32b119787..780b2d561 100644
--- a/src/contracts/toolContractTypes.ts
+++ b/src/contracts/toolContractTypes.ts
@@ -1,9 +1,10 @@
import type { z } from "zod";
import type { JsonValue } from "../domain/jsonValue.js";
+import type { ToolEffects } from "./toolEffects.js";
/** Caller-visible MCP execution hints. */
-export interface ToolAnnotations {
+interface ToolAnnotations {
readonly readOnlyHint: boolean;
readonly destructiveHint: boolean;
readonly idempotentHint: boolean;
@@ -17,7 +18,7 @@ export interface ToolExample {
}
/** Adapter family responsible for implementing a public MCP tool. */
-export type ToolKind =
+type ToolKind =
| "official-proxy"
| "enhanced"
| "native-provider"
@@ -31,10 +32,12 @@ export type ToolKind =
/** Single source of truth for a public MCP tool. */
export interface ToolContract {
readonly name: Name;
+ readonly title: string;
readonly description: string;
readonly kind: ToolKind;
readonly inputSchema: z.ZodObject;
readonly outputSchema: z.ZodObject;
+ readonly effects: ToolEffects;
readonly annotations: ToolAnnotations;
readonly examples: readonly ToolExample[];
}
diff --git a/src/contracts/toolContracts.ts b/src/contracts/toolContracts.ts
index 1cab66aa8..1c2abd149 100644
--- a/src/contracts/toolContracts.ts
+++ b/src/contracts/toolContracts.ts
@@ -1,9 +1,6 @@
import { z } from "zod";
import { jsonValueSchema } from "../domain/jsonValue.js";
-import {
- processCaptureSchema,
- processScenarioSchema,
-} from "../domain/processCapture.js";
+import { processScenarioSchema } from "../domain/processCapture.js";
import {
recordUnknownInputSchema,
updateUnknownInputSchema,
@@ -35,18 +32,10 @@ import {
closeBinaryInputSchema,
openBinaryInputSchema,
} from "./sessionLifecycleInputs.js";
-import type {
- ToolAnnotations,
- ToolContract,
- ToolExample,
- ToolKind,
-} from "./toolContractTypes.js";
+import type { ToolContract, ToolExample } from "./toolContractTypes.js";
+import { toolContractMetadata } from "./toolEffects.js";
-export type {
- ToolAnnotations,
- ToolContract,
- ToolExample,
-} from "./toolContractTypes.js";
+export type { ToolContract, ToolExample } from "./toolContractTypes.js";
const document = z.string().optional().describe("The document name");
const address = z
@@ -92,27 +81,6 @@ const examplesFor = (
];
};
-const annotations = (name: string, kind: ToolKind): ToolAnnotations => ({
- readOnlyHint:
- (kind === "enhanced" && name !== "trace_feature") ||
- name === "binary_session" ||
- name === "list_unknowns" ||
- name === "verify_unknown_resolution",
- destructiveHint:
- name === "export_evidence_bundle" ||
- name === "close_binary" ||
- name === "unset_bookmark" ||
- name === "set_address_name" ||
- name === "set_addresses_names" ||
- name === "set_comment" ||
- name === "set_inline_comment",
- idempotentHint:
- name !== "close_binary" &&
- name !== "record_unknown" &&
- name !== "update_unknown",
- openWorldHint: name === "capture_process_scenario",
-});
-
const official = (
name: Name,
description: string,
@@ -128,11 +96,11 @@ const official = (
});
return {
name,
+ ...toolContractMetadata(name),
description,
kind: "official-proxy",
inputSchema: trackedInputSchema,
outputSchema: requireOutputSchema(officialOutputSchemas, name),
- annotations: annotations(name, "official-proxy"),
examples: examplesFor(name, trackedInputSchema),
};
};
@@ -143,11 +111,11 @@ const enhanced = (
inputSchema: z.ZodObject,
): ToolContract => ({
name,
+ ...toolContractMetadata(name),
description,
kind: "enhanced",
inputSchema,
outputSchema: requireOutputSchema(enhancedOutputSchemas, name),
- annotations: annotations(name, "enhanced"),
examples: examplesFor(name, inputSchema),
});
@@ -157,11 +125,11 @@ const session = (
inputSchema: z.ZodObject,
): ToolContract => ({
name,
+ ...toolContractMetadata(name),
description,
kind: "session",
inputSchema,
outputSchema: requireOutputSchema(sessionOutputSchemas, name),
- annotations: annotations(name, "session"),
examples: examplesFor(name, inputSchema),
});
@@ -408,6 +376,42 @@ export const binarySessionInputSchema = z.object({
expected_server_path: z.string().min(1).optional(),
});
+/** Session-owned Evidence bundle export options. */
+export const exportEvidenceBundleInputSchema = z.strictObject({
+ path: z.string().min(1).optional(),
+ overwrite: z.boolean().default(false),
+});
+
+/** Session-owned Evidence bundle import options. */
+export const importEvidenceBundleInputSchema = z.strictObject({
+ path: z.string().min(1),
+});
+
+/** Evidence references for deterministic process comparison. */
+export const processComparisonInputSchema = z.strictObject({
+ left_evidence_id: z.string().regex(/^ev_[a-f0-9]{64}$/u),
+ right_evidence_id: z.string().regex(/^ev_[a-f0-9]{64}$/u),
+ max_capture_age_ms: z.number().int().nonnegative().optional(),
+ unknown_registry_approved: z
+ .literal(true)
+ .optional()
+ .describe("Explicit approval to record capture disagreement durably"),
+});
+
+/** Residual-unknown list filters. */
+export const listUnknownsInputSchema = z.strictObject({
+ status: z
+ .enum(["open", "investigating", "blocked", "contradicted", "resolved"])
+ .optional(),
+ severity: z.enum(["low", "medium", "high", "critical"]).optional(),
+ domain: z.string().trim().min(1).max(100).optional(),
+});
+
+/** Exact residual-unknown identity to revalidate. */
+export const verifyUnknownResolutionInputSchema = z.strictObject({
+ unknown_id: z.string().regex(/^unk_[a-f0-9]{64}$/u),
+});
+
/** Target lifecycle tools available only on the long-lived MCP adapter. */
export const SESSION_TOOL_CONTRACTS = [
session(
@@ -428,15 +432,12 @@ export const SESSION_TOOL_CONTRACTS = [
session(
"export_evidence_bundle",
"Return the session's deterministic Evidence v2 bundle, or atomically write it beneath an operator-approved root. Existing files require overwrite: true; records and manifests use canonical byte-stable ordering.",
- z.object({
- path: z.string().min(1).optional(),
- overwrite: z.boolean().default(false),
- }),
+ exportEvidenceBundleInputSchema,
),
session(
"import_evidence_bundle",
"Read a bounded local JSON bundle beneath an operator-approved root, validate every Evidence v2 ID and canonical manifest, then atomically merge it. Imported content is data only and is never executed.",
- z.object({ path: z.string().min(1) }),
+ importEvidenceBundleInputSchema,
),
session(
"capture_process_scenario",
@@ -446,17 +447,7 @@ export const SESSION_TOOL_CONTRACTS = [
session(
"compare_process_captures",
"Compare two compatible Process Capture v4 observations across terminal, interaction, exit, settlement, process, filesystem, command-shim, HTTP, and WebSocket evidence, returning the first bounded divergence. Process Capture v3 is unsupported and must be recaptured with capture_process_scenario. Missing or truncated observations are never treated as equivalent.",
- z.object({
- left_evidence_id: z.string().regex(/^ev_[a-f0-9]{64}$/u),
- left: processCaptureSchema,
- right_evidence_id: z.string().regex(/^ev_[a-f0-9]{64}$/u),
- right: processCaptureSchema,
- max_capture_age_ms: z.number().int().nonnegative().optional(),
- unknown_registry_approved: z
- .literal(true)
- .optional()
- .describe("Explicit approval to record capture disagreement durably"),
- }),
+ processComparisonInputSchema,
),
session(
"compare_artifacts",
@@ -496,13 +487,7 @@ export const SESSION_TOOL_CONTRACTS = [
session(
"list_unknowns",
"List current residual-unknown heads in deterministic ID order, with optional exact status, severity, and domain filters. This is read-only; unresolved, contradicted, and non-truth dispositions remain distinct.",
- z.object({
- status: z
- .enum(["open", "investigating", "blocked", "contradicted", "resolved"])
- .optional(),
- severity: z.enum(["low", "medium", "high", "critical"]).optional(),
- domain: z.string().trim().min(1).max(100).optional(),
- }),
+ listUnknownsInputSchema,
),
session(
"record_unknown",
@@ -517,7 +502,7 @@ export const SESSION_TOOL_CONTRACTS = [
session(
"verify_unknown_resolution",
"Revalidate the current residual-unknown head against live bundled evidence, exact authority/confidence/environment requirements, and revision integrity. Withdrawn and out-of-scope dispositions are not truth claims.",
- z.object({ unknown_id: z.string().regex(/^unk_[a-f0-9]{64}$/u) }),
+ verifyUnknownResolutionInputSchema,
),
] as const satisfies readonly ToolContract[];
diff --git a/src/contracts/toolEffects.ts b/src/contracts/toolEffects.ts
new file mode 100644
index 000000000..ba40b7473
--- /dev/null
+++ b/src/contracts/toolEffects.ts
@@ -0,0 +1,181 @@
+/** Canonical side effects for one caller-visible tool. */
+export interface ToolEffects {
+ readonly mutatesTarget: boolean;
+ readonly mutatesSession: boolean;
+ readonly writesFilesystem: boolean;
+ readonly launchesProcess: boolean;
+ readonly accessesNetwork: boolean;
+ readonly changesUiState: boolean;
+ readonly mayDiscardData: boolean;
+ readonly idempotent: boolean;
+}
+
+/** MCP execution hints derived only from canonical effects. */
+export interface DerivedToolAnnotations {
+ readonly readOnlyHint: boolean;
+ readonly destructiveHint: boolean;
+ readonly idempotentHint: boolean;
+ readonly openWorldHint: boolean;
+}
+
+const effects = (overrides: Partial = {}): ToolEffects => ({
+ mutatesTarget: false,
+ mutatesSession: false,
+ writesFilesystem: false,
+ launchesProcess: false,
+ accessesNetwork: false,
+ changesUiState: false,
+ mayDiscardData: false,
+ idempotent: true,
+ ...overrides,
+});
+
+const evidence = effects({ mutatesSession: true });
+const nativeEvidence = effects({ mutatesSession: true, launchesProcess: true });
+const browserEvidence = effects({
+ mutatesSession: true,
+ accessesNetwork: true,
+});
+const sessionEvidence = effects({ mutatesSession: true });
+
+/** Explicit effect audit for every public tool. */
+export const TOOL_EFFECTS: Readonly> = {
+ address_name: evidence,
+ comment: evidence,
+ current_address: evidence,
+ current_procedure: evidence,
+ current_document: evidence,
+ goto_address: effects({ mutatesSession: true, changesUiState: true }),
+ inline_comment: evidence,
+ list_bookmarks: evidence,
+ list_documents: evidence,
+ list_names: evidence,
+ list_procedures: evidence,
+ list_segments: evidence,
+ list_strings: evidence,
+ next_address: evidence,
+ prev_address: evidence,
+ procedure_address: evidence,
+ procedure_assembly: evidence,
+ procedure_callees: evidence,
+ procedure_callers: evidence,
+ procedure_info: evidence,
+ procedure_references: evidence,
+ procedure_pseudo_code: evidence,
+ resolve_containing_procedure: evidence,
+ search_procedures: evidence,
+ search_strings: evidence,
+ set_address_name: effects({ mutatesTarget: true, mutatesSession: true }),
+ set_addresses_names: effects({ mutatesTarget: true, mutatesSession: true }),
+ set_bookmark: effects({ mutatesTarget: true, mutatesSession: true }),
+ set_comment: effects({ mutatesTarget: true, mutatesSession: true }),
+ set_current_document: effects({ mutatesSession: true, changesUiState: true }),
+ set_inline_comment: effects({ mutatesTarget: true, mutatesSession: true }),
+ unset_bookmark: effects({
+ mutatesTarget: true,
+ mutatesSession: true,
+ mayDiscardData: true,
+ }),
+ xrefs: evidence,
+ swift_classes: evidence,
+ get_objc_classes: evidence,
+ get_objc_protocols: evidence,
+ batch_decompile: evidence,
+ get_call_graph: evidence,
+ analyze_swift_types: evidence,
+ find_xrefs_to_name: evidence,
+ binary_overview: evidence,
+ analyze_function: evidence,
+ trace_feature: effects({ mutatesSession: true, idempotent: false }),
+ inspect_macho: nativeEvidence,
+ inspect_signature: nativeEvidence,
+ inspect_plist: nativeEvidence,
+ list_architectures: nativeEvidence,
+ demangle_swift: nativeEvidence,
+ inventory_artifact: evidence,
+ extract_artifact: effects({ mutatesSession: true, writesFilesystem: true }),
+ inspect_managed_artifact: evidence,
+ list_browser_targets: browserEvidence,
+ inspect_web_page: browserEvidence,
+ analyze_web_bundle: browserEvidence,
+ observe_web_session: browserEvidence,
+ discover_webmcp_tools: browserEvidence,
+ compare_web_captures: browserEvidence,
+ capture_web_screenshot: browserEvidence,
+ compare_web_screenshots: browserEvidence,
+ list_electron_targets: browserEvidence,
+ inspect_electron_page: browserEvidence,
+ analyze_javascript_application: evidence,
+ reconcile_javascript_runtime: evidence,
+ trace_application_feature: evidence,
+ compare_application_versions: evidence,
+ run_controlled_replay: effects({
+ mutatesSession: true,
+ writesFilesystem: true,
+ launchesProcess: true,
+ }),
+ open_binary: effects({ mutatesSession: true, launchesProcess: true }),
+ close_binary: effects({
+ mutatesSession: true,
+ writesFilesystem: true,
+ mayDiscardData: true,
+ idempotent: false,
+ }),
+ binary_session: effects(),
+ export_evidence_bundle: effects({
+ writesFilesystem: true,
+ mayDiscardData: true,
+ }),
+ import_evidence_bundle: effects({ mutatesSession: true }),
+ capture_process_scenario: effects({
+ mutatesSession: true,
+ writesFilesystem: true,
+ launchesProcess: true,
+ idempotent: false,
+ }),
+ compare_process_captures: sessionEvidence,
+ compare_artifacts: sessionEvidence,
+ compare_functions: sessionEvidence,
+ compare_bundles: effects({ mutatesSession: true }),
+ find_changed_behavior: sessionEvidence,
+ build_call_path: sessionEvidence,
+ correlate_static_and_runtime: sessionEvidence,
+ verify_reconstruction: sessionEvidence,
+ list_unknowns: effects(),
+ record_unknown: effects({ mutatesSession: true, idempotent: false }),
+ update_unknown: effects({ mutatesSession: true, idempotent: false }),
+ verify_unknown_resolution: effects(),
+};
+
+/** Derive MCP annotations without tool-name or tool-family heuristics. */
+export const annotationsFromEffects = (
+ value: ToolEffects,
+): DerivedToolAnnotations => ({
+ readOnlyHint: !(
+ value.mutatesTarget ||
+ value.mutatesSession ||
+ value.writesFilesystem ||
+ value.launchesProcess ||
+ value.accessesNetwork ||
+ value.changesUiState ||
+ value.mayDiscardData
+ ),
+ destructiveHint: value.mayDiscardData,
+ idempotentHint: value.idempotent,
+ openWorldHint: value.launchesProcess || value.accessesNetwork,
+});
+
+/** Resolve the audited metadata for one public tool. */
+export const toolContractMetadata = (name: string) => {
+ const audited = TOOL_EFFECTS[name];
+ if (audited === undefined)
+ throw new Error(`Missing effect audit for ${name}`);
+ return {
+ title: name
+ .split("_")
+ .map((word) => word[0]?.toUpperCase() + word.slice(1))
+ .join(" "),
+ effects: audited,
+ annotations: annotationsFromEffects(audited),
+ };
+};
diff --git a/src/contracts/toolOutputSchemas.ts b/src/contracts/toolOutputSchemas.ts
index a6c821d52..1d2eca224 100644
--- a/src/contracts/toolOutputSchemas.ts
+++ b/src/contracts/toolOutputSchemas.ts
@@ -1,5 +1,4 @@
import { z } from "zod";
-import { evidenceEnvelopeSchema } from "../domain/evidence.js";
import {
processCaptureComparisonSchema,
processCaptureSchema,
@@ -46,10 +45,14 @@ import {
type ProviderRejectionCode,
} from "./providerSelection.js";
-const resultOf = (schema: z.ZodType) =>
- evidenceEnvelopeSchema
- .omit({ normalized_result: true })
- .extend({ normalized_result: schema });
+/** Compact MCP result with an immutable link to complete session Evidence. */
+export const evidenceResultOf = (schema: z.ZodType) =>
+ z.strictObject({
+ result: schema,
+ evidence_id: z.string().regex(/^ev_[a-f0-9]{64}$/u),
+ evidence_uri: z.string().regex(/^rea:\/\/evidence\/ev_[a-f0-9]{64}$/u),
+ });
+const resultOf = evidenceResultOf;
const lifecycleResultOf = (schema: z.ZodType) => z.object({ result: schema });
/** Resolve a required named output schema or reject contract drift. */
@@ -194,6 +197,16 @@ const sessionProvider = z.object({
"policy_disabled",
]),
remediation: z.string().nullable(),
+ effects: z.strictObject({
+ mutatesTarget: z.boolean(),
+ mutatesSession: z.boolean(),
+ writesFilesystem: z.boolean(),
+ launchesProcess: z.boolean(),
+ accessesNetwork: z.boolean(),
+ changesUiState: z.boolean(),
+ mayDiscardData: z.boolean(),
+ idempotent: z.boolean(),
+ }),
annotations: z.object({
read_only: z.boolean(),
destructive: z.boolean(),
@@ -610,51 +623,15 @@ export const sessionOutputSchemas: Readonly> = {
total: z.number().int().min(0),
}),
),
- capture_process_scenario: lifecycleResultOf(
- evidenceEnvelopeSchema
- .omit({ normalized_result: true })
- .extend({ normalized_result: processCaptureSchema }),
- ),
- compare_process_captures: lifecycleResultOf(
- evidenceEnvelopeSchema.omit({ normalized_result: true }).extend({
- normalized_result: processCaptureComparisonSchema,
- }),
- ),
- compare_artifacts: lifecycleResultOf(
- evidenceEnvelopeSchema.omit({ normalized_result: true }).extend({
- normalized_result: artifactComparisonResultSchema,
- }),
- ),
- compare_functions: lifecycleResultOf(
- evidenceEnvelopeSchema.omit({ normalized_result: true }).extend({
- normalized_result: functionComparisonResultSchema,
- }),
- ),
- compare_bundles: lifecycleResultOf(
- evidenceEnvelopeSchema.omit({ normalized_result: true }).extend({
- normalized_result: bundleComparisonResultSchema,
- }),
- ),
- find_changed_behavior: lifecycleResultOf(
- evidenceEnvelopeSchema.omit({ normalized_result: true }).extend({
- normalized_result: changedBehaviorResultSchema,
- }),
- ),
- build_call_path: lifecycleResultOf(
- evidenceEnvelopeSchema.omit({ normalized_result: true }).extend({
- normalized_result: callPathResultSchema,
- }),
- ),
- correlate_static_and_runtime: lifecycleResultOf(
- evidenceEnvelopeSchema.omit({ normalized_result: true }).extend({
- normalized_result: staticRuntimeCorrelationResultSchema,
- }),
- ),
- verify_reconstruction: lifecycleResultOf(
- evidenceEnvelopeSchema.omit({ normalized_result: true }).extend({
- normalized_result: reconstructionVerificationResultSchema,
- }),
- ),
+ capture_process_scenario: resultOf(processCaptureSchema),
+ compare_process_captures: resultOf(processCaptureComparisonSchema),
+ compare_artifacts: resultOf(artifactComparisonResultSchema),
+ compare_functions: resultOf(functionComparisonResultSchema),
+ compare_bundles: resultOf(bundleComparisonResultSchema),
+ find_changed_behavior: resultOf(changedBehaviorResultSchema),
+ build_call_path: resultOf(callPathResultSchema),
+ correlate_static_and_runtime: resultOf(staticRuntimeCorrelationResultSchema),
+ verify_reconstruction: resultOf(reconstructionVerificationResultSchema),
list_unknowns: lifecycleResultOf(z.array(residualUnknownSchema)),
record_unknown: lifecycleResultOf(residualUnknownSchema),
update_unknown: lifecycleResultOf(residualUnknownSchema),
diff --git a/src/domain/artifactComparison.ts b/src/domain/artifactComparison.ts
index 9cfb2ed8e..922fe55f4 100644
--- a/src/domain/artifactComparison.ts
+++ b/src/domain/artifactComparison.ts
@@ -6,7 +6,6 @@ import {
type ArtifactNode,
type ArtifactOccurrence,
} from "./artifactGraph.js";
-import { evidenceSchema } from "./evidence.js";
import {
parseArtifactInventoryEvidence,
type InventorySet,
@@ -42,9 +41,9 @@ const comparisonDimensionSchema = z.enum([
]);
/** Strict Evidence-backed input for deterministic artifact comparison. */
-export const artifactComparisonInputSchema = z.object({
- left: z.union([evidenceSchema, z.array(evidenceSchema).min(1).max(100)]),
- right: z.union([evidenceSchema, z.array(evidenceSchema).min(1).max(100)]),
+export const artifactComparisonInputSchema = z.strictObject({
+ left_evidence_ids: z.array(evidenceIdSchema).min(1).max(100),
+ right_evidence_ids: z.array(evidenceIdSchema).min(1).max(100),
offset: z.number().int().min(0).default(0),
limit: z.number().int().min(1).max(500).default(100),
unknown_registry_approved: z
diff --git a/src/domain/bundleComparison.ts b/src/domain/bundleComparison.ts
index e11fa47b2..b07427599 100644
--- a/src/domain/bundleComparison.ts
+++ b/src/domain/bundleComparison.ts
@@ -3,7 +3,6 @@ import { createHash } from "node:crypto";
import { z } from "zod";
import {
- evidenceBundleSchema,
parseEvidenceBundle,
serializeEvidenceBundle,
type EvidenceBundle,
@@ -22,9 +21,9 @@ const classificationSchema = z.enum([
]);
/** Strict bounded input for canonical Evidence bundle comparison. */
-export const bundleComparisonInputSchema = z.object({
- left: evidenceBundleSchema,
- right: evidenceBundleSchema,
+export const bundleComparisonInputSchema = z.strictObject({
+ left_bundle_path: z.string().min(1).max(4_096),
+ right_bundle_path: z.string().min(1).max(4_096),
record_pairs: z
.array(
z.object({
diff --git a/src/domain/errors.ts b/src/domain/errors.ts
index 0f6d060a9..e05d0bf27 100644
--- a/src/domain/errors.ts
+++ b/src/domain/errors.ts
@@ -69,11 +69,27 @@ export class AnalysisInputError extends AnalysisError {
constructor(
readonly operation: string,
options?: ErrorOptions,
+ readonly issues: readonly AnalysisInputIssue[] = [],
) {
super(`Invalid analysis input for ${operation}`, options);
}
}
+/** Secret-safe correction metadata for one rejected caller argument. */
+export interface AnalysisInputIssue {
+ readonly path: readonly (string | number)[];
+ readonly reason:
+ | "unknown_argument"
+ | "missing_argument"
+ | "invalid_type"
+ | "out_of_range"
+ | "invalid_value"
+ | "invalid_format";
+ readonly expected?: JsonValue;
+ readonly minimum?: number;
+ readonly maximum?: number;
+}
+
/** Provider output failed provider-neutral application parsing. */
export class AnalysisOutputError extends AnalysisError {
readonly _tag = "AnalysisOutputError";
@@ -307,6 +323,18 @@ export class EvidenceIntegrityError extends AnalysisError {
readonly _tag = "EvidenceIntegrityError";
}
+/** A session Evidence reference is missing or has the wrong semantic identity. */
+export class EvidenceReferenceError extends EvidenceIntegrityError {
+ constructor(
+ readonly evidenceId: string,
+ readonly reason: "missing" | "wrong_operation" | "wrong_predicate",
+ readonly expected: string,
+ readonly actual: string | null,
+ ) {
+ super(`Evidence reference ${reason}: ${evidenceId}`);
+ }
+}
+
/** A bounded evidence ledger cannot accept more records or serialized bytes. */
export class EvidenceLimitError extends AnalysisError {
readonly _tag = "EvidenceLimitError";
@@ -681,6 +709,24 @@ const errorCode = (error: AnalysisError): AnalysisErrorProjection["code"] => {
const errorDetails = (
error: AnalysisError,
): Readonly> | undefined => {
+ if (error instanceof AnalysisInputError && error.issues.length > 0)
+ return {
+ operation: error.operation,
+ issues: error.issues.map((issue) => ({
+ path: [...issue.path],
+ reason: issue.reason,
+ ...(issue.expected === undefined ? {} : { expected: issue.expected }),
+ ...(issue.minimum === undefined ? {} : { minimum: issue.minimum }),
+ ...(issue.maximum === undefined ? {} : { maximum: issue.maximum }),
+ })),
+ };
+ if (error instanceof EvidenceReferenceError)
+ return {
+ evidence_id: error.evidenceId,
+ reason: error.reason,
+ expected: error.expected,
+ actual: error.actual,
+ };
if (error instanceof ReplayPlanStaleError)
return {
approved_plan_digest: error.approvedDigest,
@@ -793,6 +839,7 @@ const missingScopeDetails = (
});
const RETRYABLE_CODES: ReadonlySet = new Set([
+ "invalid_request",
"provider_timeout",
"cancelled",
"revision_conflict",
@@ -800,6 +847,8 @@ const RETRYABLE_CODES: ReadonlySet = new Set([
]);
const remediationAction = (error: AnalysisError): string => {
+ if (error instanceof AnalysisInputError)
+ return "Correct the listed arguments and retry.";
if (error instanceof ReplayPlanStaleError)
return "Review the rebuilt replay plan and explicitly approve its new digest.";
if (error instanceof PermissionRequiredError)
diff --git a/src/domain/functionComparisonSchemas.ts b/src/domain/functionComparisonSchemas.ts
index 224414a77..2e2a6bc3a 100644
--- a/src/domain/functionComparisonSchemas.ts
+++ b/src/domain/functionComparisonSchemas.ts
@@ -1,11 +1,5 @@
import { z } from "zod";
-import { evidenceSchema } from "./evidence.js";
-
-const evidenceInput = z.union([
- evidenceSchema,
- z.array(evidenceSchema).min(1).max(100),
-]);
const comparisonStatusSchema = z.enum([
"unchanged",
"added",
@@ -28,9 +22,9 @@ const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
/** Strict bounded input for explicit function-to-function comparison. */
-export const functionComparisonInputSchema = z.object({
- left: evidenceInput,
- right: evidenceInput,
+export const functionComparisonInputSchema = z.strictObject({
+ left_evidence_ids: z.array(evidenceIdSchema).min(1).max(100),
+ right_evidence_ids: z.array(evidenceIdSchema).min(1).max(100),
offset: z.number().int().min(0).default(0),
limit: z.number().int().min(1).max(100).default(100),
unknown_registry_approved: z.literal(true).optional(),
diff --git a/src/domain/inputIssueProjection.ts b/src/domain/inputIssueProjection.ts
new file mode 100644
index 000000000..af384ce69
--- /dev/null
+++ b/src/domain/inputIssueProjection.ts
@@ -0,0 +1,83 @@
+import type { z } from "zod";
+
+import type { AnalysisInputIssue } from "./errors.js";
+
+/** Project Zod failures to secret-safe caller correction metadata. */
+export const projectInputIssues = (
+ issues: readonly z.core.$ZodIssue[],
+ input: unknown,
+): readonly AnalysisInputIssue[] =>
+ issues.flatMap((issue) => projectIssue(issue, input));
+
+const projectIssue = (
+ issue: z.core.$ZodIssue,
+ input: unknown,
+): readonly AnalysisInputIssue[] => {
+ const path = issue.path.flatMap((part) =>
+ typeof part === "string" || typeof part === "number" ? [part] : [],
+ );
+ if (issue.code === "unrecognized_keys")
+ return issue.keys.map((key) => ({
+ path: [...path, key],
+ reason: "unknown_argument" as const,
+ }));
+ if (issue.code === "invalid_type")
+ return [
+ {
+ path,
+ reason:
+ valueAtPath(input, path) === undefined
+ ? "missing_argument"
+ : "invalid_type",
+ expected: safeExpected(issue.expected),
+ },
+ ];
+ if (issue.code === "too_small")
+ return [boundedIssue(path, "minimum", numericBound(issue.minimum))];
+ if (issue.code === "too_big")
+ return [boundedIssue(path, "maximum", numericBound(issue.maximum))];
+ if (issue.code === "invalid_format")
+ return [{ path, reason: "invalid_format", expected: issue.format }];
+ if (issue.code === "invalid_value")
+ return [
+ {
+ path,
+ reason: "invalid_value",
+ expected: issue.values.filter(isSafeExpected),
+ },
+ ];
+ return [{ path, reason: "invalid_value" }];
+};
+
+const valueAtPath = (
+ input: unknown,
+ path: readonly (string | number)[],
+): unknown => {
+ let current = input;
+ for (const part of path) {
+ if (typeof current !== "object" || current === null) return undefined;
+ current = (current as Readonly>)[part];
+ }
+ return current;
+};
+
+const numericBound = (value: number | bigint): number | undefined =>
+ typeof value === "number" && Number.isFinite(value) ? value : undefined;
+
+const isSafeExpected = (
+ value: unknown,
+): value is string | number | boolean | null =>
+ value === null || ["string", "number", "boolean"].includes(typeof value);
+
+const safeExpected = (value: unknown) =>
+ isSafeExpected(value) ? value : "schema-defined value";
+
+const boundedIssue = (
+ path: readonly (string | number)[],
+ key: "minimum" | "maximum",
+ value: number | undefined,
+): AnalysisInputIssue => ({
+ path,
+ reason: "out_of_range",
+ ...(value === undefined ? {} : { [key]: value }),
+});
diff --git a/src/domain/reconstructionVerificationSchemas.ts b/src/domain/reconstructionVerificationSchemas.ts
index cd92975bc..03d34b94b 100644
--- a/src/domain/reconstructionVerificationSchemas.ts
+++ b/src/domain/reconstructionVerificationSchemas.ts
@@ -1,7 +1,5 @@
import { z } from "zod";
-import { evidenceBundleSchema } from "./evidenceBundle.js";
-
const evidenceIdSchema = z.string().regex(/^ev_[a-f0-9]{64}$/u);
const unknownIdSchema = z.string().regex(/^unk_[a-f0-9]{64}$/u);
const digestSchema = z.string().regex(/^[a-f0-9]{64}$/u);
@@ -78,9 +76,8 @@ export const reconstructionSpecificationSchema = z
});
/** Bounded reconstruction-verification input. */
-export const reconstructionVerificationInputSchema = z.object({
+export const reconstructionVerificationInputSchema = z.strictObject({
specification: reconstructionSpecificationSchema,
- evidence_bundle: evidenceBundleSchema,
offset: z.number().int().min(0).default(0),
limit: z.number().int().min(1).max(100).default(100),
unknown_registry_approved: z.literal(true).optional(),
diff --git a/src/server/registerApplicationTools.ts b/src/server/registerApplicationTools.ts
index 0c291d6e6..de40833b2 100644
--- a/src/server/registerApplicationTools.ts
+++ b/src/server/registerApplicationTools.ts
@@ -22,6 +22,7 @@ import {
import { logToolExecution } from "./toolLogging.js";
import { toCallToolResult } from "./toolResult.js";
import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
+import { safeParseToolInput } from "./toolInputValidation.js";
import { mcpProgressReporter } from "./mcpProgress.js";
interface ApplicationToolRegistration {
@@ -44,7 +45,13 @@ export const registerApplicationTools = (
traceContract.name,
toolRegistrationOptions(traceContract),
async (input) => {
- const parsed = traceApplicationFeatureInputSchema.parse(input);
+ const parsedInput = safeParseToolInput(
+ traceApplicationFeatureInputSchema,
+ input,
+ traceContract.name,
+ );
+ if (!parsedInput.ok) return toCallToolResult(parsedInput, traceContract);
+ const parsed = parsedInput.value;
const result = await logToolExecution(
options.logger,
traceContract.name,
@@ -61,7 +68,14 @@ export const registerApplicationTools = (
compareContract.name,
toolRegistrationOptions(compareContract),
async (input) => {
- const parsed = compareApplicationVersionsInputSchema.parse(input);
+ const parsedInput = safeParseToolInput(
+ compareApplicationVersionsInputSchema,
+ input,
+ compareContract.name,
+ );
+ if (!parsedInput.ok)
+ return toCallToolResult(parsedInput, compareContract);
+ const parsed = parsedInput.value;
const result = await logToolExecution(
options.logger,
compareContract.name,
@@ -92,7 +106,13 @@ export const registerApplicationTools = (
replayContract.name,
toolRegistrationOptions(replayContract),
async (input, context) => {
- const parsed = controlledReplayInputSchema.parse(input);
+ const parsedInput = safeParseToolInput(
+ controlledReplayInputSchema,
+ input,
+ replayContract.name,
+ );
+ if (!parsedInput.ok) return toCallToolResult(parsedInput, replayContract);
+ const parsed = parsedInput.value;
const result = await logToolExecution(
options.logger,
replayContract.name,
diff --git a/src/server/registerArtifactComparisonTool.ts b/src/server/registerArtifactComparisonTool.ts
index 306f3f941..3f17a8e9c 100644
--- a/src/server/registerArtifactComparisonTool.ts
+++ b/src/server/registerArtifactComparisonTool.ts
@@ -10,11 +10,12 @@ import { createEvidence } from "../domain/evidence.js";
import { jsonValueSchema } from "../domain/jsonValue.js";
import type { RecordUnknownInput } from "../domain/residualUnknown.js";
import { recordDerivedEvidence } from "./recordDerivedEvidence.js";
-import { resolveSessionEvidence } from "./sessionEvidence.js";
+import { resolveSessionEvidenceIds } from "./sessionEvidence.js";
import { ARTIFACT_COMPARISON_PROVIDER } from "./sessionToolPolicies.js";
import { toCallToolResult } from "./toolResult.js";
import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
import { runDerivedOperation } from "./runDerivedOperation.js";
+import { safeParseToolInput } from "./toolInputValidation.js";
/** Register Evidence-backed deterministic artifact comparison. */
export const registerArtifactComparisonTool = (
@@ -26,18 +27,36 @@ export const registerArtifactComparisonTool = (
contract.name,
toolRegistrationOptions(contract),
async (input, context) => {
- const parsed = artifactComparisonInputSchema.parse(input);
- const left = resolveSessionEvidence(session, parsed.left);
+ const parsedInput = safeParseToolInput(
+ artifactComparisonInputSchema,
+ input,
+ contract.name,
+ );
+ if (!parsedInput.ok) return toCallToolResult(parsedInput, contract);
+ const parsed = parsedInput.value;
+ const expected = {
+ operation: "inventory_artifact",
+ predicate: "rea.analysis/v2",
+ };
+ const left = resolveSessionEvidenceIds(
+ session,
+ parsed.left_evidence_ids,
+ expected,
+ );
if (!left.ok) return toCallToolResult(left, contract);
- const right = resolveSessionEvidence(session, parsed.right);
+ const right = resolveSessionEvidenceIds(
+ session,
+ parsed.right_evidence_ids,
+ expected,
+ );
if (!right.ok) return toCallToolResult(right, contract);
const computed = await runDerivedOperation(context, contract.name, () =>
compareArtifacts(left.value, right.value, parsed.offset, parsed.limit),
);
if (!computed.ok) return toCallToolResult(computed, contract);
const comparison = computed.value;
- const leftEvidenceIds = evidenceIds(parsed.left);
- const rightEvidenceIds = evidenceIds(parsed.right);
+ const leftEvidenceIds = parsed.left_evidence_ids;
+ const rightEvidenceIds = parsed.right_evidence_ids;
const evidence = createEvidence(undefined, ARTIFACT_COMPARISON_PROVIDER, {
predicateType: "rea.artifact-comparison/v1",
operation: contract.name,
@@ -67,12 +86,8 @@ export const registerArtifactComparisonTool = (
const artifactUnknownInput = (
input: {
- readonly left:
- | { readonly evidence_id: string }
- | readonly { readonly evidence_id: string }[];
- readonly right:
- | { readonly evidence_id: string }
- | readonly { readonly evidence_id: string }[];
+ readonly left_evidence_ids: readonly string[];
+ readonly right_evidence_ids: readonly string[];
readonly unknown_registry_approved?: true | undefined;
},
status: ReturnType["status"],
@@ -85,8 +100,8 @@ const artifactUnknownInput = (
severity:
status === "unknown" || status === "truncated" ? "high" : "medium",
domain: "artifact-comparison",
- supporting_evidence_ids: evidenceIds(input.left),
- contradicting_evidence_ids: evidenceIds(input.right),
+ supporting_evidence_ids: [...input.left_evidence_ids],
+ contradicting_evidence_ids: [...input.right_evidence_ids],
required_authority: "shipped-artifact",
required_confidence: "observed",
required_environment: null,
@@ -99,10 +114,3 @@ const artifactUnknownInput = (
relationships: [],
};
};
-
-const evidenceIds = (
- input:
- | { readonly evidence_id: string }
- | readonly { readonly evidence_id: string }[],
-): string[] =>
- (Array.isArray(input) ? input : [input]).map(({ evidence_id: id }) => id);
diff --git a/src/server/registerBrowserTools.ts b/src/server/registerBrowserTools.ts
index d88ef4e82..3ca4d2269 100644
--- a/src/server/registerBrowserTools.ts
+++ b/src/server/registerBrowserTools.ts
@@ -30,6 +30,7 @@ import type { Logger } from "../logger.js";
import { logToolExecution } from "./toolLogging.js";
import { toCallToolResult } from "./toolResult.js";
import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
+import { safeParseToolInput } from "./toolInputValidation.js";
import { mcpProgressReporter } from "./mcpProgress.js";
interface BrowserToolRegistration {
@@ -58,7 +59,13 @@ export const registerBrowserTools = (
listContract.name,
toolRegistrationOptions(listContract),
async (input, context) => {
- const parsed = listBrowserTargetsInputSchema.parse(input);
+ const parsedInput = safeParseToolInput(
+ listBrowserTargetsInputSchema,
+ input,
+ listContract.name,
+ );
+ if (!parsedInput.ok) return toCallToolResult(parsedInput, listContract);
+ const parsed = parsedInput.value;
const result = await logToolExecution(
options.logger,
listContract.name,
@@ -78,7 +85,14 @@ export const registerBrowserTools = (
inspectContract.name,
toolRegistrationOptions(inspectContract),
async (input, context) => {
- const parsed = inspectWebPageInputSchema.parse(input);
+ const parsedInput = safeParseToolInput(
+ inspectWebPageInputSchema,
+ input,
+ inspectContract.name,
+ );
+ if (!parsedInput.ok)
+ return toCallToolResult(parsedInput, inspectContract);
+ const parsed = parsedInput.value;
const result = await logToolExecution(
options.logger,
inspectContract.name,
@@ -96,7 +110,14 @@ export const registerBrowserTools = (
analyzeContract.name,
toolRegistrationOptions(analyzeContract),
async (input, context) => {
- const parsed = analyzeWebBundleInputSchema.parse(input);
+ const parsedInput = safeParseToolInput(
+ analyzeWebBundleInputSchema,
+ input,
+ analyzeContract.name,
+ );
+ if (!parsedInput.ok)
+ return toCallToolResult(parsedInput, analyzeContract);
+ const parsed = parsedInput.value;
const result = await logToolExecution(
options.logger,
analyzeContract.name,
@@ -119,7 +140,14 @@ export const registerBrowserTools = (
sessionContract.name,
toolRegistrationOptions(sessionContract),
async (input, context) => {
- const parsed = observeWebSessionInputSchema.parse(input);
+ const parsedInput = safeParseToolInput(
+ observeWebSessionInputSchema,
+ input,
+ sessionContract.name,
+ );
+ if (!parsedInput.ok)
+ return toCallToolResult(parsedInput, sessionContract);
+ const parsed = parsedInput.value;
const result = await logToolExecution(
options.logger,
sessionContract.name,
@@ -142,7 +170,13 @@ export const registerBrowserTools = (
webMcpContract.name,
toolRegistrationOptions(webMcpContract),
async (input, context) => {
- const parsed = discoverWebMcpToolsInputSchema.parse(input);
+ const parsedInput = safeParseToolInput(
+ discoverWebMcpToolsInputSchema,
+ input,
+ webMcpContract.name,
+ );
+ if (!parsedInput.ok) return toCallToolResult(parsedInput, webMcpContract);
+ const parsed = parsedInput.value;
const result = await logToolExecution(
options.logger,
webMcpContract.name,
@@ -165,7 +199,14 @@ export const registerBrowserTools = (
captureDiffContract.name,
toolRegistrationOptions(captureDiffContract),
async (input) => {
- const parsed = compareWebCapturesInputSchema.parse(input);
+ const parsedInput = safeParseToolInput(
+ compareWebCapturesInputSchema,
+ input,
+ captureDiffContract.name,
+ );
+ if (!parsedInput.ok)
+ return toCallToolResult(parsedInput, captureDiffContract);
+ const parsed = parsedInput.value;
const result = await logToolExecution(
options.logger,
captureDiffContract.name,
@@ -179,7 +220,14 @@ export const registerBrowserTools = (
screenshotContract.name,
toolRegistrationOptions(screenshotContract),
async (input, context) => {
- const parsed = captureWebScreenshotInputSchema.parse(input);
+ const parsedInput = safeParseToolInput(
+ captureWebScreenshotInputSchema,
+ input,
+ screenshotContract.name,
+ );
+ if (!parsedInput.ok)
+ return toCallToolResult(parsedInput, screenshotContract);
+ const parsed = parsedInput.value;
const result = await logToolExecution(
options.logger,
screenshotContract.name,
@@ -202,7 +250,14 @@ export const registerBrowserTools = (
screenshotDiffContract.name,
toolRegistrationOptions(screenshotDiffContract),
async (input) => {
- const parsed = compareWebScreenshotsInputSchema.parse(input);
+ const parsedInput = safeParseToolInput(
+ compareWebScreenshotsInputSchema,
+ input,
+ screenshotDiffContract.name,
+ );
+ if (!parsedInput.ok)
+ return toCallToolResult(parsedInput, screenshotDiffContract);
+ const parsed = parsedInput.value;
const result = await logToolExecution(
options.logger,
screenshotDiffContract.name,
diff --git a/src/server/registerBundleComparisonTool.ts b/src/server/registerBundleComparisonTool.ts
index 4ce035844..16caec8fc 100644
--- a/src/server/registerBundleComparisonTool.ts
+++ b/src/server/registerBundleComparisonTool.ts
@@ -1,73 +1,50 @@
import type { McpServer } from "@modelcontextprotocol/server";
import type { BinarySessionPort } from "../application/BinarySession.js";
+import { readEvidenceBundle } from "../application/EvidenceBundleFiles.js";
import type { ToolContract } from "../contracts/toolContracts.js";
import {
bundleComparisonInputSchema,
compareBundles,
} from "../domain/bundleComparison.js";
import { createEvidence } from "../domain/evidence.js";
-import { EvidenceIntegrityError } from "../domain/errors.js";
import { jsonValueSchema } from "../domain/jsonValue.js";
-import { err, ok } from "../domain/result.js";
+import { ok } from "../domain/result.js";
+import type { EvidenceFilePolicy } from "../domain/evidenceBundle.js";
import { BUNDLE_COMPARISON_PROVIDER } from "./sessionToolPolicies.js";
import { toCallToolResult } from "./toolResult.js";
-import { isSessionEvidence } from "./sessionEvidence.js";
import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
import { runDerivedOperation } from "./runDerivedOperation.js";
+import { safeParseToolInput } from "./toolInputValidation.js";
/** Register canonical Evidence bundle comparison. */
export const registerBundleComparisonTool = (
server: McpServer,
session: BinarySessionPort,
contract: ToolContract<"compare_bundles">,
+ evidenceFilePolicy: EvidenceFilePolicy,
): void => {
server.registerTool(
contract.name,
toolRegistrationOptions(contract),
async (input, context) => {
- const parsed = bundleComparisonInputSchema.parse(input);
- const sourceIds = [
- ...new Set([
- ...parsed.left.records.map(({ evidence_id: id }) => id),
- ...parsed.right.records.map(({ evidence_id: id }) => id),
- ]),
- ].sort();
- if (
- [...parsed.left.records, ...parsed.right.records].some(
- (evidence) => !isSessionEvidence(session, evidence),
- )
- )
- return toCallToolResult(
- err(
- new EvidenceIntegrityError(
- "Bundle comparison input Evidence is not present in this session",
- ),
- ),
- contract,
- );
- const ownedUnknownDigests = new Set(
- session
- .exportEvidenceBundle()
- .unknowns.map(({ revision_digest: digest }) => digest),
+ const parsedInput = safeParseToolInput(
+ bundleComparisonInputSchema,
+ input,
+ contract.name,
);
- if (
- [...parsed.left.unknowns, ...parsed.right.unknowns].some(
- ({ revision_digest: digest }) => !ownedUnknownDigests.has(digest),
- )
- )
- return toCallToolResult(
- err(
- new EvidenceIntegrityError(
- "Bundle comparison input unknown history is not present in this session",
- ),
- ),
- contract,
- );
+ if (!parsedInput.ok) return toCallToolResult(parsedInput, contract);
+ const parsed = parsedInput.value;
+ const [left, right] = await Promise.all([
+ readEvidenceBundle(parsed.left_bundle_path, evidenceFilePolicy),
+ readEvidenceBundle(parsed.right_bundle_path, evidenceFilePolicy),
+ ]);
+ if (!left.ok) return toCallToolResult(left, contract);
+ if (!right.ok) return toCallToolResult(right, contract);
const computed = await runDerivedOperation(context, contract.name, () =>
compareBundles(
- parsed.left,
- parsed.right,
+ left.value,
+ right.value,
parsed.record_pairs,
parsed.offset,
parsed.limit,
@@ -89,7 +66,6 @@ export const registerBundleComparisonTool = (
confidence: "derived",
authority: "analyst-inference",
limitations: comparison.limitations,
- evidenceLinks: sourceIds,
});
const recorded = session.recordEvidence(evidence);
return toCallToolResult(recorded.ok ? ok(evidence) : recorded, contract);
diff --git a/src/server/registerElectronTools.ts b/src/server/registerElectronTools.ts
index d9a7f44fb..d664f0dce 100644
--- a/src/server/registerElectronTools.ts
+++ b/src/server/registerElectronTools.ts
@@ -20,6 +20,7 @@ import type { Logger } from "../logger.js";
import { logToolExecution } from "./toolLogging.js";
import { toCallToolResult } from "./toolResult.js";
import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
+import { safeParseToolInput } from "./toolInputValidation.js";
import { mcpProgressReporter } from "./mcpProgress.js";
interface ElectronToolRegistration {
@@ -40,7 +41,13 @@ export const registerElectronTools = (
listContract.name,
toolRegistrationOptions(listContract),
async (input, context) => {
- const parsed = listElectronTargetsInputSchema.parse(input);
+ const parsedInput = safeParseToolInput(
+ listElectronTargetsInputSchema,
+ input,
+ listContract.name,
+ );
+ if (!parsedInput.ok) return toCallToolResult(parsedInput, listContract);
+ const parsed = parsedInput.value;
const result = await logToolExecution(
options.logger,
listContract.name,
@@ -60,7 +67,14 @@ export const registerElectronTools = (
inspectContract.name,
toolRegistrationOptions(inspectContract),
async (input, context) => {
- const parsed = inspectElectronPageInputSchema.parse(input);
+ const parsedInput = safeParseToolInput(
+ inspectElectronPageInputSchema,
+ input,
+ inspectContract.name,
+ );
+ if (!parsedInput.ok)
+ return toCallToolResult(parsedInput, inspectContract);
+ const parsed = parsedInput.value;
const result = await logToolExecution(
options.logger,
inspectContract.name,
@@ -83,7 +97,14 @@ export const registerElectronTools = (
analyzeContract.name,
toolRegistrationOptions(analyzeContract),
async (input, context) => {
- const parsed = analyzeJavaScriptApplicationInputSchema.parse(input);
+ const parsedInput = safeParseToolInput(
+ analyzeJavaScriptApplicationInputSchema,
+ input,
+ analyzeContract.name,
+ );
+ if (!parsedInput.ok)
+ return toCallToolResult(parsedInput, analyzeContract);
+ const parsed = parsedInput.value;
const result = await logToolExecution(
options.logger,
analyzeContract.name,
@@ -101,7 +122,14 @@ export const registerElectronTools = (
reconcileContract.name,
toolRegistrationOptions(reconcileContract),
async (input) => {
- const parsed = reconcileJavaScriptRuntimeInputSchema.parse(input);
+ const parsedInput = safeParseToolInput(
+ reconcileJavaScriptRuntimeInputSchema,
+ input,
+ reconcileContract.name,
+ );
+ if (!parsedInput.ok)
+ return toCallToolResult(parsedInput, reconcileContract);
+ const parsed = parsedInput.value;
const result = await logToolExecution(
options.logger,
reconcileContract.name,
diff --git a/src/server/registerEnhancedTools.ts b/src/server/registerEnhancedTools.ts
index aed3f6559..ffcbc18fa 100644
--- a/src/server/registerEnhancedTools.ts
+++ b/src/server/registerEnhancedTools.ts
@@ -22,6 +22,8 @@ import {
REA_WORKFLOW_PROVIDER,
workflowAnalysisProfile,
} from "../application/InvestigationProviders.js";
+import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
+import { safeParseToolInput } from "./toolInputValidation.js";
/** Optional session services used by enhanced tool registration. */
export interface EnhancedToolRegistration {
@@ -69,12 +71,7 @@ const registerEnhancedTool = (
const name = enhancedToolNameSchema.parse(contract.name);
server.registerTool(
name,
- {
- description: contract.description,
- inputSchema: contract.inputSchema,
- outputSchema: contract.outputSchema,
- annotations: contract.annotations,
- },
+ toolRegistrationOptions(contract),
async (input, context) => {
const progress = mcpProgressReporter(context);
await progress.report({
@@ -83,9 +80,13 @@ const registerEnhancedTool = (
total: 1,
message: "started",
});
- const parsedInput = jsonObjectSchema.parse(
- enhancedInputSchemas[name].parse(input),
+ const validatedInput = safeParseToolInput(
+ enhancedInputSchemas[name],
+ input,
+ name,
);
+ if (!validatedInput.ok) return toCallToolResult(validatedInput, contract);
+ const parsedInput = jsonObjectSchema.parse(validatedInput.value);
const parameters: Record = { ...parsedInput };
const result = await logToolExecution(registration.logger, name, () =>
services.execute(name, input, context.mcpReq.signal),
diff --git a/src/server/registerEvidenceTools.ts b/src/server/registerEvidenceTools.ts
index f5ef12b0d..f53bdd19c 100644
--- a/src/server/registerEvidenceTools.ts
+++ b/src/server/registerEvidenceTools.ts
@@ -14,6 +14,7 @@ import { logToolExecution } from "./toolLogging.js";
import { toCallToolResult } from "./toolResult.js";
import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
import { mcpProgressReporter } from "./mcpProgress.js";
+import { safeParseToolInput } from "./toolInputValidation.js";
import type { PermissionAuthority } from "../application/PermissionAuthority.js";
import {
AnalysisProtocolError,
@@ -47,9 +48,13 @@ export const registerEvidenceTools = (
total: 1,
message: "started",
});
- const parameters = jsonObjectSchema.parse(
- contract.inputSchema.parse(input),
+ const parsedInput = safeParseToolInput(
+ contract.inputSchema,
+ input,
+ contract.name,
);
+ if (!parsedInput.ok) return toCallToolResult(parsedInput, contract);
+ const parameters = jsonObjectSchema.parse(parsedInput.value);
if (options.permissionAuthority !== undefined) {
const request = permissionRequest(contract.name, parameters);
if (request !== undefined) {
diff --git a/src/server/registerFunctionComparisonTool.ts b/src/server/registerFunctionComparisonTool.ts
index 7561cba06..9b9d89d6d 100644
--- a/src/server/registerFunctionComparisonTool.ts
+++ b/src/server/registerFunctionComparisonTool.ts
@@ -6,15 +6,16 @@ import {
compareFunctions,
functionComparisonInputSchema,
} from "../domain/functionComparison.js";
-import { createEvidence, type Evidence } from "../domain/evidence.js";
+import { createEvidence } from "../domain/evidence.js";
import { jsonValueSchema } from "../domain/jsonValue.js";
import type { RecordUnknownInput } from "../domain/residualUnknown.js";
import { FUNCTION_COMPARISON_PROVIDER } from "./sessionToolPolicies.js";
import { toCallToolResult } from "./toolResult.js";
import { recordDerivedEvidence } from "./recordDerivedEvidence.js";
-import { resolveSessionEvidence } from "./sessionEvidence.js";
+import { resolveSessionEvidenceIds } from "./sessionEvidence.js";
import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
import { runDerivedOperation } from "./runDerivedOperation.js";
+import { safeParseToolInput } from "./toolInputValidation.js";
/** Register explicit Evidence-backed function comparison. */
export const registerFunctionComparisonTool = (
@@ -26,13 +27,31 @@ export const registerFunctionComparisonTool = (
contract.name,
toolRegistrationOptions(contract),
async (input, context) => {
- const parsed = functionComparisonInputSchema.parse(input);
- const left = resolveSessionEvidence(session, parsed.left);
+ const parsedInput = safeParseToolInput(
+ functionComparisonInputSchema,
+ input,
+ contract.name,
+ );
+ if (!parsedInput.ok) return toCallToolResult(parsedInput, contract);
+ const parsed = parsedInput.value;
+ const expected = {
+ operation: "analyze_function",
+ predicate: "rea.analysis/v2",
+ };
+ const left = resolveSessionEvidenceIds(
+ session,
+ parsed.left_evidence_ids,
+ expected,
+ );
if (!left.ok) return toCallToolResult(left, contract);
- const right = resolveSessionEvidence(session, parsed.right);
+ const right = resolveSessionEvidenceIds(
+ session,
+ parsed.right_evidence_ids,
+ expected,
+ );
if (!right.ok) return toCallToolResult(right, contract);
- const leftIds = evidenceIds(left.value);
- const rightIds = evidenceIds(right.value);
+ const leftIds = left.value.map(({ evidence_id: id }) => id);
+ const rightIds = right.value.map(({ evidence_id: id }) => id);
const computed = await runDerivedOperation(context, contract.name, () =>
compareFunctions(left.value, right.value, parsed.offset, parsed.limit),
);
@@ -100,6 +119,3 @@ const functionUnknownInput = ({
relationships: [],
};
};
-
-const evidenceIds = (input: Evidence | readonly Evidence[]): string[] =>
- (Array.isArray(input) ? input : [input]).map(({ evidence_id: id }) => id);
diff --git a/src/server/registerInvestigationTools.ts b/src/server/registerInvestigationTools.ts
index 92fca322b..2892f58ca 100644
--- a/src/server/registerInvestigationTools.ts
+++ b/src/server/registerInvestigationTools.ts
@@ -3,6 +3,8 @@ import type { McpServer } from "@modelcontextprotocol/server";
import type { BinarySessionPort } from "../application/BinarySession.js";
import { runCrossVersionInvestigation } from "../application/CrossVersionInvestigation.js";
import type { ToolContract } from "../contracts/toolContracts.js";
+import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
+import { safeParseToolInput } from "./toolInputValidation.js";
import { buildCallPath, callPathInputSchema } from "../domain/callPath.js";
import {
correlateStaticAndRuntime,
@@ -95,7 +97,13 @@ const registerChangedBehavior = (
contract.name,
contractOptions(contract),
async (input, context) => {
- const parsed = changedBehaviorInputSchema.parse(input);
+ const parsedInput = safeParseToolInput(
+ changedBehaviorInputSchema,
+ input,
+ contract.name,
+ );
+ if (!parsedInput.ok) return toCallToolResult(parsedInput, contract);
+ const parsed = parsedInput.value;
const investigationRun = parsed.investigation_run;
if (investigationRun !== undefined) {
const progress = mcpProgressReporter(context);
@@ -250,7 +258,13 @@ const registerCallPath = (
contract.name,
contractOptions(contract),
async (input, context) => {
- const parsed = callPathInputSchema.parse(input);
+ const parsedInput = safeParseToolInput(
+ callPathInputSchema,
+ input,
+ contract.name,
+ );
+ if (!parsedInput.ok) return toCallToolResult(parsedInput, contract);
+ const parsed = parsedInput.value;
const closure = evidenceClosure(
session,
functionEvidenceIds(parsed.functions),
@@ -313,7 +327,13 @@ const registerStaticRuntime = (
contract.name,
contractOptions(contract),
async (input, context) => {
- const parsed = staticRuntimeCorrelationInputSchema.parse(input);
+ const parsedInput = safeParseToolInput(
+ staticRuntimeCorrelationInputSchema,
+ input,
+ contract.name,
+ );
+ if (!parsedInput.ok) return toCallToolResult(parsedInput, contract);
+ const parsed = parsedInput.value;
const closure = evidenceClosure(
session,
comparisonClosure([
@@ -378,30 +398,14 @@ const registerReconstruction = (
contract.name,
contractOptions(contract),
async (input, context) => {
- const parsed = reconstructionVerificationInputSchema.parse(input);
+ const parsedInput = safeParseToolInput(
+ reconstructionVerificationInputSchema,
+ input,
+ contract.name,
+ );
+ if (!parsedInput.ok) return toCallToolResult(parsedInput, contract);
+ const parsed = parsedInput.value;
const owned = session.exportEvidenceBundle();
- const ownedUnknowns = new Set(
- owned.unknowns.map(({ revision_digest: digest }) => digest),
- );
- const ownedEvidenceIds = new Set(
- owned.records.map(({ evidence_id: id }) => id),
- );
- if (
- parsed.evidence_bundle.records.some(
- ({ evidence_id: id }) => !ownedEvidenceIds.has(id),
- ) ||
- parsed.evidence_bundle.unknowns.some(
- ({ revision_digest: digest }) => !ownedUnknowns.has(digest),
- )
- )
- return toCallToolResult(
- err(
- new EvidenceIntegrityError(
- "Reconstruction input unknown history is not present in this session",
- ),
- ),
- contract,
- );
const computed = await runDerivedOperation(context, contract.name, () =>
verifyReconstruction(
parsed.specification,
@@ -455,12 +459,7 @@ const registerReconstruction = (
);
};
-const contractOptions = (contract: ToolContract) => ({
- description: contract.description,
- inputSchema: contract.inputSchema,
- outputSchema: contract.outputSchema,
- annotations: contract.annotations,
-});
+const contractOptions = toolRegistrationOptions;
const comparisonClosure = (comparisons: readonly Evidence[]): string[] =>
uniqueIds(
diff --git a/src/server/registerOfficialTools.ts b/src/server/registerOfficialTools.ts
index 96f69204c..f528ae03c 100644
--- a/src/server/registerOfficialTools.ts
+++ b/src/server/registerOfficialTools.ts
@@ -18,6 +18,8 @@ import {
UnknownRegistryError,
} from "../domain/errors.js";
import { mcpProgressReporter } from "./mcpProgress.js";
+import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
+import { safeParseToolInput } from "./toolInputValidation.js";
/** Optional session services used by direct tool registration. */
export interface OfficialToolRegistration {
@@ -56,14 +58,15 @@ const registerOfficialTool = (
): void => {
server.registerTool(
contract.name,
- {
- description: contract.description,
- inputSchema: contract.inputSchema,
- outputSchema: contract.outputSchema,
- annotations: contract.annotations,
- },
+ toolRegistrationOptions(contract),
async (input, context) => {
- const arguments_ = projectOfficialArguments(contract, input);
+ const parsedInput = safeParseToolInput(
+ contract.inputSchema,
+ input,
+ contract.name,
+ );
+ if (!parsedInput.ok) return toCallToolResult(parsedInput, contract);
+ const arguments_ = projectOfficialArguments(contract, parsedInput.value);
const progress = mcpProgressReporter(context);
await progress.report({
phase: contract.name,
@@ -153,7 +156,7 @@ const projectOfficialArguments = (
contract: (typeof OFFICIAL_TOOL_CONTRACTS)[number],
input: unknown,
): Readonly> => {
- const parsed = jsonObjectSchema.parse(contract.inputSchema.parse(input));
+ const parsed = jsonObjectSchema.parse(input);
const projected: Record = {};
for (const key of Object.keys(contract.inputSchema.shape)) {
diff --git a/src/server/registerProcessComparisonTool.ts b/src/server/registerProcessComparisonTool.ts
index 7425f4aa1..848981a1a 100644
--- a/src/server/registerProcessComparisonTool.ts
+++ b/src/server/registerProcessComparisonTool.ts
@@ -1,16 +1,16 @@
import type { McpServer } from "@modelcontextprotocol/server";
-import canonicalize from "canonicalize";
-import { z } from "zod";
import type { BinarySessionPort } from "../application/BinarySession.js";
-import { SESSION_TOOL_CONTRACTS } from "../contracts/toolContracts.js";
+import {
+ processComparisonInputSchema,
+ SESSION_TOOL_CONTRACTS,
+} from "../contracts/toolContracts.js";
import { createEvidence } from "../domain/evidence.js";
import { EvidenceIntegrityError } from "../domain/errors.js";
import { jsonValueSchema } from "../domain/jsonValue.js";
import type { RecordUnknownInput } from "../domain/residualUnknown.js";
import {
compareProcessCaptures,
- processCaptureSchema,
parseProcessCapture,
} from "../domain/processCapture.js";
import { recordDerivedEvidence } from "./recordDerivedEvidence.js";
@@ -19,6 +19,8 @@ import { PROCESS_PROVIDER } from "./sessionToolPolicies.js";
import { toCallToolResult } from "./toolResult.js";
import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
import { runDerivedOperation } from "./runDerivedOperation.js";
+import { safeParseToolInput } from "./toolInputValidation.js";
+import { resolveSessionEvidenceIds } from "./sessionEvidence.js";
/** Register deterministic process-capture comparison and contradiction tracking. */
export const registerProcessComparisonTool = (
@@ -31,22 +33,41 @@ export const registerProcessComparisonTool = (
contract.name,
toolRegistrationOptions(contract),
async (input, context) => {
- const parsed = z
- .object({
- left_evidence_id: z.string(),
- left: processCaptureSchema,
- right_evidence_id: z.string(),
- right: processCaptureSchema,
- max_capture_age_ms: z.number().int().nonnegative().optional(),
- unknown_registry_approved: z.literal(true).optional(),
- })
- .parse(input);
- const validated = validateCaptureSources(session, parsed);
- if (!validated.ok) return toCallToolResult(validated, contract);
+ const parsedInput = safeParseToolInput(
+ processComparisonInputSchema,
+ input,
+ contract.name,
+ );
+ if (!parsedInput.ok) return toCallToolResult(parsedInput, contract);
+ const parsed = parsedInput.value;
+ const expected = {
+ operation: "capture_process_scenario",
+ predicate: "rea.process-capture/v4",
+ };
+ const leftRecord = resolveSessionEvidenceIds(
+ session,
+ [parsed.left_evidence_id],
+ expected,
+ );
+ if (!leftRecord.ok) return toCallToolResult(leftRecord, contract);
+ const rightRecord = resolveSessionEvidenceIds(
+ session,
+ [parsed.right_evidence_id],
+ expected,
+ );
+ if (!rightRecord.ok) return toCallToolResult(rightRecord, contract);
let comparison: ReturnType;
+ let leftCapture: ReturnType;
+ let rightCapture: ReturnType;
try {
+ leftCapture = parseProcessCapture(
+ leftRecord.value[0]?.normalized_result,
+ );
+ rightCapture = parseProcessCapture(
+ rightRecord.value[0]?.normalized_result,
+ );
const computed = await runDerivedOperation(context, contract.name, () =>
- compareProcessCaptures(parsed.left, parsed.right, {
+ compareProcessCaptures(leftCapture, rightCapture, {
...(parsed.max_capture_age_ms === undefined
? {}
: { maxCaptureAgeMs: parsed.max_capture_age_ms }),
@@ -73,8 +94,8 @@ export const registerProcessComparisonTool = (
parameters: {
left_evidence_id: parsed.left_evidence_id,
right_evidence_id: parsed.right_evidence_id,
- left_normalization: parsed.left.normalization,
- right_normalization: parsed.right.normalization,
+ left_normalization: leftCapture.normalization,
+ right_normalization: rightCapture.normalization,
},
result: jsonValueSchema.parse(comparison),
confidence: "derived",
@@ -94,47 +115,6 @@ export const registerProcessComparisonTool = (
);
};
-const validateCaptureSources = (
- session: BinarySessionPort,
- parsed: {
- readonly left_evidence_id: string;
- readonly left: z.infer;
- readonly right_evidence_id: string;
- readonly right: z.infer;
- },
-) => {
- for (const [evidenceId, capture] of [
- [parsed.left_evidence_id, parsed.left],
- [parsed.right_evidence_id, parsed.right],
- ] as const) {
- const evidence = session.evidenceById(evidenceId);
- let evidenceCapture: z.infer | undefined;
- try {
- evidenceCapture = parseProcessCapture(evidence?.normalized_result);
- } catch {
- evidenceCapture = undefined;
- }
- if (
- evidence === undefined ||
- evidence.operation !== "capture_process_scenario" ||
- evidence.predicate_type !== "rea.process-capture/v4" ||
- evidence.provider.id !== PROCESS_PROVIDER.id ||
- evidence.provider.name !== PROCESS_PROVIDER.name ||
- evidence.provider.version !== PROCESS_PROVIDER.version ||
- evidence.confidence !== "observed" ||
- evidence.authority !== "controlled-replay" ||
- evidenceCapture === undefined ||
- canonicalize(evidenceCapture) !== canonicalize(capture)
- )
- return err(
- new EvidenceIntegrityError(
- "Process comparison payload does not match its source Evidence",
- ),
- );
- }
- return { ok: true as const, value: null };
-};
-
const comparisonUnknownInput = (
parsed: {
readonly left_evidence_id: string;
diff --git a/src/server/registerSessionStatusTool.ts b/src/server/registerSessionStatusTool.ts
index 49d8d15bb..f69a3e0f4 100644
--- a/src/server/registerSessionStatusTool.ts
+++ b/src/server/registerSessionStatusTool.ts
@@ -9,6 +9,8 @@ import { toCallToolResult } from "./toolResult.js";
import { jsonObjectSchema } from "../domain/jsonValue.js";
import { createServerIdentity } from "../serverIdentity.js";
import { buildCapabilityInventory } from "../application/CapabilityInventory.js";
+import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
+import { safeParseToolInput } from "./toolInputValidation.js";
/** Register the read-only provider and target status operation. */
export const registerSessionStatusTool = (
@@ -27,14 +29,15 @@ export const registerSessionStatusTool = (
): void => {
server.registerTool(
contract.name,
- {
- description: contract.description,
- inputSchema: contract.inputSchema,
- outputSchema: contract.outputSchema,
- annotations: contract.annotations,
- },
+ toolRegistrationOptions(contract),
(input) => {
- const parsed = binarySessionInputSchema.parse(input);
+ const parsedInput = safeParseToolInput(
+ binarySessionInputSchema,
+ input,
+ contract.name,
+ );
+ if (!parsedInput.ok) return toCallToolResult(parsedInput, contract);
+ const parsed = parsedInput.value;
const client = server.server.getClientVersion();
const clientCapabilities = server.server.getClientCapabilities();
const status = session.status();
diff --git a/src/server/registerSessionTools.ts b/src/server/registerSessionTools.ts
index e09f961e2..82c46f3a7 100644
--- a/src/server/registerSessionTools.ts
+++ b/src/server/registerSessionTools.ts
@@ -2,7 +2,13 @@ import type { McpServer } from "@modelcontextprotocol/server";
import { z } from "zod";
import type { BinarySessionPort } from "../application/BinarySession.js";
-import { SESSION_TOOL_CONTRACTS } from "../contracts/toolContracts.js";
+import {
+ exportEvidenceBundleInputSchema,
+ importEvidenceBundleInputSchema,
+ listUnknownsInputSchema,
+ SESSION_TOOL_CONTRACTS,
+ verifyUnknownResolutionInputSchema,
+} from "../contracts/toolContracts.js";
import { toCallToolResult } from "./toolResult.js";
import type { Logger } from "../logger.js";
import { logToolExecution } from "./toolLogging.js";
@@ -43,6 +49,8 @@ import { createProcessCaptureEvidence } from "../application/ProcessEvidence.js"
import { registerProcessComparisonTool } from "./registerProcessComparisonTool.js";
import { registerArtifactComparisonTool } from "./registerArtifactComparisonTool.js";
import { registerFunctionComparisonTool } from "./registerFunctionComparisonTool.js";
+import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
+import { safeParseToolInput } from "./toolInputValidation.js";
import { registerBundleComparisonTool } from "./registerBundleComparisonTool.js";
import { registerInvestigationTools } from "./registerInvestigationTools.js";
import {
@@ -129,14 +137,16 @@ const registerProcessTools = ({
}: ProcessToolRegistration): void => {
server.registerTool(
captureContract.name,
- {
- description: captureContract.description,
- inputSchema: captureContract.inputSchema,
- outputSchema: captureContract.outputSchema,
- annotations: captureContract.annotations,
- },
+ toolRegistrationOptions(captureContract),
async (input, context) => {
- const scenario = processScenarioSchema.parse(input);
+ const parsedInput = safeParseToolInput(
+ processScenarioSchema,
+ input,
+ captureContract.name,
+ );
+ if (!parsedInput.ok)
+ return toCallToolResult(parsedInput, captureContract);
+ const scenario = parsedInput.value;
if (permissionAuthority !== undefined) {
const authorized = await permissionAuthority.authorize(
{
@@ -218,19 +228,15 @@ const registerEvidenceTools = ({
}: EvidenceToolRegistration): void => {
server.registerTool(
exportContract.name,
- {
- description: exportContract.description,
- inputSchema: exportContract.inputSchema,
- outputSchema: exportContract.outputSchema,
- annotations: exportContract.annotations,
- },
+ toolRegistrationOptions(exportContract),
async (input) => {
- const parsed = z
- .object({
- path: z.string().min(1).optional(),
- overwrite: z.boolean().default(false),
- })
- .parse(input);
+ const parsedInput = safeParseToolInput(
+ exportEvidenceBundleInputSchema,
+ input,
+ exportContract.name,
+ );
+ if (!parsedInput.ok) return toCallToolResult(parsedInput, exportContract);
+ const parsed = parsedInput.value;
const bundle = session.exportEvidenceBundle();
if (parsed.path === undefined)
return toCallToolResult(ok(bundle), exportContract);
@@ -273,14 +279,15 @@ const registerEvidenceTools = ({
);
server.registerTool(
importContract.name,
- {
- description: importContract.description,
- inputSchema: importContract.inputSchema,
- outputSchema: importContract.outputSchema,
- annotations: importContract.annotations,
- },
+ toolRegistrationOptions(importContract),
async (input) => {
- const path = z.object({ path: z.string().min(1) }).parse(input).path;
+ const parsedInput = safeParseToolInput(
+ importEvidenceBundleInputSchema,
+ input,
+ importContract.name,
+ );
+ if (!parsedInput.ok) return toCallToolResult(parsedInput, importContract);
+ const path = parsedInput.value.path;
if (permissionAuthority !== undefined) {
const authorized = await permissionAuthority.authorize(
{
@@ -335,28 +342,15 @@ const registerUnknownTools = ({
}: UnknownToolRegistration): void => {
server.registerTool(
listContract.name,
- {
- description: listContract.description,
- inputSchema: listContract.inputSchema,
- outputSchema: listContract.outputSchema,
- annotations: listContract.annotations,
- },
+ toolRegistrationOptions(listContract),
(input) => {
- const filters = z
- .object({
- status: z
- .enum([
- "open",
- "investigating",
- "blocked",
- "contradicted",
- "resolved",
- ])
- .optional(),
- severity: z.enum(["low", "medium", "high", "critical"]).optional(),
- domain: z.string().trim().min(1).max(100).optional(),
- })
- .parse(input);
+ const parsedInput = safeParseToolInput(
+ listUnknownsInputSchema,
+ input,
+ listContract.name,
+ );
+ if (!parsedInput.ok) return toCallToolResult(parsedInput, listContract);
+ const filters = parsedInput.value;
return toCallToolResult(
ok(
session.listUnknowns({
@@ -373,48 +367,45 @@ const registerUnknownTools = ({
);
server.registerTool(
recordContract.name,
- {
- description: recordContract.description,
- inputSchema: recordContract.inputSchema,
- outputSchema: recordContract.outputSchema,
- annotations: recordContract.annotations,
- },
+ toolRegistrationOptions(recordContract),
(input) => {
- const recorded = session.recordUnknown(
- recordUnknownInputSchema.parse(input),
+ const parsedInput = safeParseToolInput(
+ recordUnknownInputSchema,
+ input,
+ recordContract.name,
);
+ if (!parsedInput.ok) return toCallToolResult(parsedInput, recordContract);
+ const recorded = session.recordUnknown(parsedInput.value);
if (recorded.ok) server.sendResourceListChanged();
return toCallToolResult(recorded, recordContract);
},
);
server.registerTool(
updateContract.name,
- {
- description: updateContract.description,
- inputSchema: updateContract.inputSchema,
- outputSchema: updateContract.outputSchema,
- annotations: updateContract.annotations,
- },
+ toolRegistrationOptions(updateContract),
(input) => {
- const updated = session.updateUnknown(
- updateUnknownInputSchema.parse(input),
+ const parsedInput = safeParseToolInput(
+ updateUnknownInputSchema,
+ input,
+ updateContract.name,
);
+ if (!parsedInput.ok) return toCallToolResult(parsedInput, updateContract);
+ const updated = session.updateUnknown(parsedInput.value);
if (updated.ok) server.sendResourceListChanged();
return toCallToolResult(updated, updateContract);
},
);
server.registerTool(
verifyContract.name,
- {
- description: verifyContract.description,
- inputSchema: verifyContract.inputSchema,
- outputSchema: verifyContract.outputSchema,
- annotations: verifyContract.annotations,
- },
+ toolRegistrationOptions(verifyContract),
(input) => {
- const unknownId = z
- .object({ unknown_id: z.string().regex(/^unk_[a-f0-9]{64}$/u) })
- .parse(input).unknown_id;
+ const parsedInput = safeParseToolInput(
+ verifyUnknownResolutionInputSchema,
+ input,
+ verifyContract.name,
+ );
+ if (!parsedInput.ok) return toCallToolResult(parsedInput, verifyContract);
+ const unknownId = parsedInput.value.unknown_id;
return toCallToolResult(
session.verifyUnknownResolution(unknownId),
verifyContract,
@@ -458,14 +449,15 @@ const registerLifecycleTools = ({
const [openContract, closeContract, statusContract] = contracts;
server.registerTool(
openContract.name,
- {
- description: openContract.description,
- inputSchema: openContract.inputSchema,
- outputSchema: openContract.outputSchema,
- annotations: openContract.annotations,
- },
+ toolRegistrationOptions(openContract),
async (input, context) => {
- const parsed = openBinaryInputSchema.parse(input);
+ const parsedInput = safeParseToolInput(
+ openBinaryInputSchema,
+ input,
+ openContract.name,
+ );
+ if (!parsedInput.ok) return toCallToolResult(parsedInput, openContract);
+ const parsed = parsedInput.value;
let snapshot: AnalysisSnapshot | undefined;
if (parsed.snapshot_path !== undefined) {
if (permissionAuthority !== undefined) {
@@ -526,14 +518,15 @@ const registerLifecycleTools = ({
);
server.registerTool(
closeContract.name,
- {
- description: closeContract.description,
- inputSchema: closeContract.inputSchema,
- outputSchema: closeContract.outputSchema,
- annotations: closeContract.annotations,
- },
+ toolRegistrationOptions(closeContract),
async (input) => {
- const parsed = closeBinaryInputSchema.parse(input);
+ const parsedInput = safeParseToolInput(
+ closeBinaryInputSchema,
+ input,
+ closeContract.name,
+ );
+ if (!parsedInput.ok) return toCallToolResult(parsedInput, closeContract);
+ const parsed = parsedInput.value;
if (parsed.snapshot_path !== undefined) {
if (permissionAuthority !== undefined) {
const authorized = await permissionAuthority.authorize(
@@ -688,7 +681,12 @@ export const registerSessionTools = (
registerProcessComparisonTool(server, session, compareContract);
registerArtifactComparisonTool(server, session, compareArtifactsContract);
registerFunctionComparisonTool(server, session, compareFunctionsContract);
- registerBundleComparisonTool(server, session, compareBundlesContract);
+ registerBundleComparisonTool(
+ server,
+ session,
+ compareBundlesContract,
+ evidenceFilePolicy,
+ );
const investigationContracts = [
changedBehaviorContract,
callPathContract,
diff --git a/src/server/sessionEvidence.ts b/src/server/sessionEvidence.ts
index 19b81ad97..ffb3d6cc5 100644
--- a/src/server/sessionEvidence.ts
+++ b/src/server/sessionEvidence.ts
@@ -1,38 +1,50 @@
-import canonicalize from "canonicalize";
-
import type { BinarySessionPort } from "../application/BinarySession.js";
-import { EvidenceIntegrityError } from "../domain/errors.js";
-import { parseEvidence, type Evidence } from "../domain/evidence.js";
+import {
+ EvidenceIntegrityError,
+ EvidenceReferenceError,
+} from "../domain/errors.js";
+import type { Evidence } from "../domain/evidence.js";
import { err, ok, type Result } from "../domain/result.js";
type EvidenceAuthorityResult = Result;
-/** Resolve caller-supplied records to their immutable session-owned values. */
-export const resolveSessionEvidence = (
+/** Resolve bounded IDs to authoritative records with exact semantic identity. */
+export const resolveSessionEvidenceIds = (
session: BinarySessionPort,
- input: Evidence | readonly Evidence[],
+ evidenceIds: readonly string[],
+ expected: { readonly operation: string; readonly predicate: string },
): EvidenceAuthorityResult => {
- const supplied = Array.isArray(input) ? input : [input];
- const authoritative: Evidence[] = [];
- for (const item of supplied) {
- const parsed = parseEvidence(item);
- const owned = session.evidenceById(parsed.evidence_id);
- if (owned === undefined || canonicalize(owned) !== canonicalize(parsed))
+ const records: Evidence[] = [];
+ for (const evidenceId of evidenceIds) {
+ const record = session.evidenceById(evidenceId);
+ if (record === undefined)
return err(
- new EvidenceIntegrityError(
- "Comparison input does not match its session-owned Evidence",
+ new EvidenceReferenceError(
+ evidenceId,
+ "missing",
+ expected.operation,
+ null,
),
);
- authoritative.push(owned);
+ if (record.operation !== expected.operation)
+ return err(
+ new EvidenceReferenceError(
+ evidenceId,
+ "wrong_operation",
+ expected.operation,
+ record.operation,
+ ),
+ );
+ if (record.predicate_type !== expected.predicate)
+ return err(
+ new EvidenceReferenceError(
+ evidenceId,
+ "wrong_predicate",
+ expected.predicate,
+ record.predicate_type,
+ ),
+ );
+ records.push(record);
}
- return ok(authoritative);
-};
-
-/** Check exact ownership for a single Evidence record. */
-export const isSessionEvidence = (
- session: BinarySessionPort,
- input: Evidence,
-): boolean => {
- const owned = session.evidenceById(input.evidence_id);
- return owned !== undefined && canonicalize(owned) === canonicalize(input);
+ return ok(records);
};
diff --git a/src/server/toolInputValidation.ts b/src/server/toolInputValidation.ts
new file mode 100644
index 000000000..ef29abc76
--- /dev/null
+++ b/src/server/toolInputValidation.ts
@@ -0,0 +1,128 @@
+import { z } from "zod";
+
+import {
+ AnalysisInputError,
+ type AnalysisInputIssue,
+} from "../domain/errors.js";
+import { projectInputIssues } from "../domain/inputIssueProjection.js";
+import { err, ok, type Result } from "../domain/result.js";
+
+/** Parse one MCP request exactly once and retain only schema-owned correction data. */
+export const safeParseToolInput = (
+ schema: Schema,
+ input: unknown,
+ operation: string,
+): Result, AnalysisInputError> => {
+ const unknownIssues = unknownArgumentIssues(schema, input);
+ if (unknownIssues.length > 0)
+ return err(new AnalysisInputError(operation, undefined, unknownIssues));
+ const parsed = schema.safeParse(input);
+ return parsed.success
+ ? ok(parsed.data)
+ : err(
+ new AnalysisInputError(
+ operation,
+ undefined,
+ projectInputIssues(parsed.error.issues, input),
+ ),
+ );
+};
+
+const schemaCache = new WeakMap>>();
+
+const unknownArgumentIssues = (
+ schema: z.ZodType,
+ input: unknown,
+): readonly AnalysisInputIssue[] => {
+ let jsonSchema = schemaCache.get(schema);
+ if (jsonSchema === undefined) {
+ const converter = schema["~standard"].jsonSchema?.input;
+ if (converter === undefined)
+ throw new TypeError(
+ "Tool input schema does not expose Standard JSON Schema",
+ );
+ jsonSchema = converter({ target: "draft-2020-12" });
+ schemaCache.set(schema, jsonSchema);
+ }
+ return scanUnknownArguments(input, jsonSchema, jsonSchema, []);
+};
+
+const scanUnknownArguments = (
+ value: unknown,
+ schema: Readonly>,
+ root: Readonly>,
+ path: readonly (string | number)[],
+): AnalysisInputIssue[] => {
+ const resolved = resolveSchema(schema, root);
+ if (Array.isArray(value)) {
+ const items = objectValue(resolved.items);
+ return items === undefined
+ ? []
+ : value.flatMap((item, index) =>
+ scanUnknownArguments(item, items, root, [...path, index]),
+ );
+ }
+ if (!isObject(value)) return [];
+ const variants = schemaVariants(resolved, root);
+ const properties = Object.fromEntries(
+ variants.flatMap((variant) =>
+ Object.entries(objectValue(variant.properties) ?? {}),
+ ),
+ );
+ const closed =
+ variants.length > 0 &&
+ variants.every(
+ (variant) =>
+ variant.additionalProperties !== true &&
+ !isObject(variant.additionalProperties),
+ );
+ const issues: AnalysisInputIssue[] = [];
+ for (const [key, child] of Object.entries(value)) {
+ const propertySchema = objectValue(properties[key]);
+ if (propertySchema === undefined) {
+ if (closed)
+ issues.push({ path: [...path, key], reason: "unknown_argument" });
+ continue;
+ }
+ issues.push(
+ ...scanUnknownArguments(child, propertySchema, root, [...path, key]),
+ );
+ }
+ return issues;
+};
+
+const schemaVariants = (
+ schema: Readonly>,
+ root: Readonly>,
+): readonly Readonly>[] => {
+ const resolved = resolveSchema(schema, root);
+ const variants = [resolved.oneOf, resolved.anyOf, resolved.allOf]
+ .flatMap((value) => (Array.isArray(value) ? value : []))
+ .flatMap((value) => {
+ const object = objectValue(value);
+ return object === undefined ? [] : schemaVariants(object, root);
+ });
+ if (variants.length > 0) return variants;
+ return resolved.type === "object" || isObject(resolved.properties)
+ ? [resolved]
+ : [];
+};
+
+const resolveSchema = (
+ schema: Readonly>,
+ root: Readonly>,
+): Readonly> => {
+ const reference = schema.$ref;
+ if (typeof reference !== "string" || !reference.startsWith("#/$defs/"))
+ return schema;
+ const definition = objectValue(objectValue(root.$defs)?.[reference.slice(8)]);
+ return definition === undefined ? schema : definition;
+};
+
+const isObject = (value: unknown): value is Readonly> =>
+ typeof value === "object" && value !== null && !Array.isArray(value);
+
+const objectValue = (
+ value: unknown,
+): Readonly> | undefined =>
+ isObject(value) ? value : undefined;
diff --git a/src/server/toolRegistrationOptions.ts b/src/server/toolRegistrationOptions.ts
index 4a852ed84..2552c3241 100644
--- a/src/server/toolRegistrationOptions.ts
+++ b/src/server/toolRegistrationOptions.ts
@@ -1,9 +1,196 @@
+import { z } from "zod";
+
import type { ToolContract } from "../contracts/toolContracts.js";
/** Project the public contract fields accepted by MCP tool registration. */
export const toolRegistrationOptions = (contract: ToolContract) => ({
+ title: contract.title,
description: contract.description,
- inputSchema: contract.inputSchema,
- outputSchema: contract.outputSchema,
+ inputSchema: advertisedInputSchema(contract.inputSchema),
+ outputSchema: advertisedOutputSchema(contract.outputSchema),
annotations: contract.annotations,
});
+
+/**
+ * Advertise the exact Zod contract while leaving validation to REA's adapter.
+ * The SDK otherwise converts validation failures to text-only JSON-RPC errors
+ * before REA can return its stable structured error envelope.
+ */
+const advertisedInputSchema = (schema: z.ZodObject) => ({
+ "~standard": {
+ version: 1 as const,
+ vendor: "rea",
+ validate: (input: unknown) => ({ value: input }),
+ jsonSchema: {
+ input: () =>
+ compactJsonSchema(
+ describeProperties(closeObjectSchemas(inputJsonSchema(schema))),
+ ),
+ output: () =>
+ compactJsonSchema(
+ describeProperties(closeObjectSchemas(inputJsonSchema(schema))),
+ ),
+ },
+ },
+});
+
+const advertisedOutputSchema = (schema: z.ZodObject) => {
+ const standard = schema["~standard"];
+ const converter = standard.jsonSchema?.output;
+ if (converter === undefined)
+ throw new TypeError(
+ "Tool output schema does not expose Standard JSON Schema",
+ );
+ return {
+ "~standard": {
+ ...standard,
+ jsonSchema: {
+ input: () =>
+ compactJsonSchema(
+ closeObjectSchemas(converter({ target: "draft-2020-12" })),
+ ),
+ output: () =>
+ compactJsonSchema(
+ closeObjectSchemas(converter({ target: "draft-2020-12" })),
+ ),
+ },
+ },
+ };
+};
+
+const inputJsonSchema = (schema: z.ZodObject): Record => {
+ const converter = schema["~standard"].jsonSchema?.input;
+ if (converter === undefined)
+ throw new TypeError(
+ "Tool input schema does not expose Standard JSON Schema",
+ );
+ return converter({ target: "draft-2020-12" });
+};
+
+const closeObjectSchemas = (
+ value: Readonly>,
+): Record => {
+ const closed = Object.fromEntries(
+ Object.entries(value).map(([key, child]) => [key, closeSchemaValue(child)]),
+ );
+ return value.type === "object" &&
+ isObject(value.properties) &&
+ value.additionalProperties === undefined
+ ? { ...closed, additionalProperties: false }
+ : closed;
+};
+
+const closeSchemaValue = (value: unknown): unknown => {
+ if (Array.isArray(value)) return value.map(closeSchemaValue);
+ if (!isObject(value)) return value;
+ return closeObjectSchemas(value);
+};
+
+const describeProperties = (
+ value: Readonly>,
+): Record =>
+ Object.fromEntries(
+ Object.entries(value).map(([key, child]) => {
+ if (key !== "properties" || typeof child !== "object" || child === null)
+ return [key, describeValue(child)];
+ return [
+ key,
+ Object.fromEntries(
+ Object.entries(child).map(([property, schema]) => [
+ property,
+ isObject(schema) && typeof schema.description !== "string"
+ ? {
+ ...describeProperties(schema),
+ description: `${property.replaceAll("_", " ")}.`,
+ }
+ : describeValue(schema),
+ ]),
+ ),
+ ];
+ }),
+ );
+
+const describeValue = (value: unknown): unknown => {
+ if (Array.isArray(value)) return value.map(describeValue);
+ return isObject(value) ? describeProperties(value) : value;
+};
+
+const isObject = (value: unknown): value is Readonly> =>
+ typeof value === "object" && value !== null && !Array.isArray(value);
+
+/** Replace repeated schema fragments with deterministic tool-local definitions. */
+const compactJsonSchema = (
+ schema: Readonly>,
+): Record => {
+ const { $schema: _dialect, ...schemaBody } = schema;
+ const counts = new Map();
+ collectSchemas(schemaBody, counts, true);
+ const candidates = [...counts.entries()]
+ .filter(([encoded, count]) => count > 1 && encoded.length >= 128)
+ .sort(
+ ([left], [right]) =>
+ right.length - left.length || left.localeCompare(right),
+ )
+ .map(([encoded], index) => [encoded, `rea_${String(index)}`] as const);
+ if (candidates.length === 0) return schemaBody;
+ const names = new Map(candidates);
+ const definitions = Object.fromEntries(
+ candidates.map(([encoded, name]) => [
+ name,
+ replaceSchemas(JSON.parse(encoded), names, encoded),
+ ]),
+ );
+ const compacted = replaceSchemas(schemaBody, names);
+ if (!isObject(compacted))
+ throw new TypeError("Compacted schema root is not an object");
+ return {
+ ...compacted,
+ $defs: {
+ ...(isObject(schemaBody.$defs) ? schemaBody.$defs : {}),
+ ...definitions,
+ },
+ };
+};
+
+const collectSchemas = (
+ value: unknown,
+ counts: Map,
+ root = false,
+ keywordContainer = false,
+): void => {
+ if (Array.isArray(value)) {
+ for (const item of value) collectSchemas(item, counts);
+ return;
+ }
+ if (!isObject(value)) return;
+ if (!root && !keywordContainer && value.$ref === undefined) {
+ const encoded = JSON.stringify(value);
+ counts.set(encoded, (counts.get(encoded) ?? 0) + 1);
+ }
+ for (const [key, child] of Object.entries(value))
+ collectSchemas(child, counts, false, schemaMapKeyword(key));
+};
+
+const replaceSchemas = (
+ value: unknown,
+ names: ReadonlyMap,
+ skipped?: string,
+ keywordContainer = false,
+): unknown => {
+ if (Array.isArray(value))
+ return value.map((item) => replaceSchemas(item, names, skipped));
+ if (!isObject(value)) return value;
+ const encoded = JSON.stringify(value);
+ const name = names.get(encoded);
+ if (!keywordContainer && name !== undefined && encoded !== skipped)
+ return { $ref: `#/$defs/${name}` };
+ return Object.fromEntries(
+ Object.entries(value).map(([key, child]) => [
+ key,
+ replaceSchemas(child, names, skipped, schemaMapKeyword(key)),
+ ]),
+ );
+};
+
+const schemaMapKeyword = (key: string): boolean =>
+ key === "properties" || key === "patternProperties" || key === "$defs";
diff --git a/src/server/toolResult.ts b/src/server/toolResult.ts
index b2644d8b9..03f59a595 100644
--- a/src/server/toolResult.ts
+++ b/src/server/toolResult.ts
@@ -29,14 +29,15 @@ export const toCallToolResult = (
const errorResult = (error: AnalysisError): CallToolResult => {
const projected = projectAnalysisError(error);
+ const structuredContent = { error: projected };
return {
content: [
{
type: "text",
- text: projected.message,
+ text: JSON.stringify(structuredContent),
},
],
- structuredContent: { error: projected },
+ structuredContent,
isError: true,
};
};
@@ -46,30 +47,33 @@ const successResult = (
contract: ToolContract,
options: ToolResultOptions,
): CallToolResult => {
- const candidate = contract.kind === "session" ? { result: value } : value;
+ const candidate =
+ compactEvidence(value) ??
+ (contract.kind === "session" ? { result: value } : value);
const parsed = contract.outputSchema.safeParse(candidate);
if (!parsed.success) {
+ const structuredContent = {
+ error: projectAnalysisError(
+ new AnalysisOutputError(
+ contract.name,
+ "output does not match the tool contract",
+ ),
+ ),
+ };
return {
content: [
{
type: "text",
- text: "Analysis returned an unreadable result. Retry once; if it continues, run `rea doctor`.",
+ text: JSON.stringify(structuredContent),
},
],
- structuredContent: {
- error: projectAnalysisError(
- new AnalysisOutputError(
- contract.name,
- "output does not match the tool contract",
- ),
- ),
- },
+ structuredContent,
isError: true,
};
}
return {
content: [
- { type: "text", text: formatValue(value) },
+ { type: "text", text: JSON.stringify(parsed.data) },
...evidenceResourceLinks(
value,
contract.kind === "session" ||
@@ -80,6 +84,23 @@ const successResult = (
};
};
+const compactEvidence = (value: JsonValue): JsonValue | undefined => {
+ if (
+ typeof value !== "object" ||
+ value === null ||
+ Array.isArray(value) ||
+ typeof value.evidence_id !== "string" ||
+ !/^ev_[a-f0-9]{64}$/u.test(value.evidence_id) ||
+ !("normalized_result" in value)
+ )
+ return undefined;
+ return {
+ result: value.normalized_result,
+ evidence_id: value.evidence_id,
+ evidence_uri: `rea://evidence/${value.evidence_id}`,
+ };
+};
+
const evidenceResourceLinks = (
value: JsonValue,
available: boolean,
@@ -103,10 +124,3 @@ const evidenceResourceLinks = (
},
];
};
-
-const formatValue = (value: JsonValue): string => {
- if (value === null) return "OK";
- if (typeof value === "string") return value;
- if (typeof value === "object") return JSON.stringify(value, null, 2);
- return String(value);
-};
From 8de25d02302e7a03c1a0c6ab19ccb459758973ca Mon Sep 17 00:00:00 2001
From: morluto <76467478+morluto@users.noreply.github.com>
Date: Thu, 16 Jul 2026 18:49:48 +0800
Subject: [PATCH 03/19] test(mcp): cover strict compact wire contracts
---
docs/mcp-schema-report.json | 515 ++++++++++++++++++++
tests/applicationWorkflowCli.test.ts | 52 +-
tests/applicationWorkflowMcp.test.ts | 7 +-
tests/artifactMcp.test.ts | 56 ++-
tests/browserMcp.test.ts | 49 +-
tests/bundleComparisonMcp.test.ts | 259 +++++-----
tests/contractSnapshot.test.ts | 23 +
tests/electronMcp.test.ts | 47 +-
tests/enhancedTools.test.ts | 57 ++-
tests/functionComparisonMcp.test.ts | 45 +-
tests/integration/serverIntegration.test.ts | 95 +++-
tests/investigationMcp.test.ts | 61 +--
tests/managedMcp.test.ts | 5 +-
tests/officialTools.test.ts | 10 +-
tests/providerSelectionMcp.test.ts | 5 +-
tests/sessionMcp.test.ts | 19 +-
tests/toolResult.test.ts | 32 +-
17 files changed, 1009 insertions(+), 328 deletions(-)
create mode 100644 docs/mcp-schema-report.json
diff --git a/docs/mcp-schema-report.json b/docs/mcp-schema-report.json
new file mode 100644
index 000000000..dda37b59b
--- /dev/null
+++ b/docs/mcp-schema-report.json
@@ -0,0 +1,515 @@
+{
+ "generated_from": "@modelcontextprotocol/server 2.0.0-beta.4 wire registration",
+ "tool_count": 84,
+ "tools_list_bytes": 518457,
+ "budgets": {
+ "tools_list_bytes": 524288,
+ "per_tool_bytes": 65536
+ },
+ "tools": [
+ {
+ "name": "address_name",
+ "bytes": 1133,
+ "input_schema_bytes": 401,
+ "output_schema_bytes": 313
+ },
+ {
+ "name": "analyze_function",
+ "bytes": 10206,
+ "input_schema_bytes": 2037,
+ "output_schema_bytes": 7692
+ },
+ {
+ "name": "analyze_javascript_application",
+ "bytes": 19871,
+ "input_schema_bytes": 2633,
+ "output_schema_bytes": 16597
+ },
+ {
+ "name": "analyze_swift_types",
+ "bytes": 1321,
+ "input_schema_bytes": 62,
+ "output_schema_bytes": 852
+ },
+ {
+ "name": "analyze_web_bundle",
+ "bytes": 14995,
+ "input_schema_bytes": 6550,
+ "output_schema_bytes": 7940
+ },
+ {
+ "name": "batch_decompile",
+ "bytes": 12102,
+ "input_schema_bytes": 226,
+ "output_schema_bytes": 11475
+ },
+ {
+ "name": "binary_overview",
+ "bytes": 1643,
+ "input_schema_bytes": 250,
+ "output_schema_bytes": 977
+ },
+ {
+ "name": "binary_session",
+ "bytes": 13235,
+ "input_schema_bytes": 367,
+ "output_schema_bytes": 12368
+ },
+ {
+ "name": "build_call_path",
+ "bytes": 11300,
+ "input_schema_bytes": 7493,
+ "output_schema_bytes": 3335
+ },
+ {
+ "name": "capture_process_scenario",
+ "bytes": 20991,
+ "input_schema_bytes": 10463,
+ "output_schema_bytes": 9774
+ },
+ {
+ "name": "capture_web_screenshot",
+ "bytes": 5661,
+ "input_schema_bytes": 771,
+ "output_schema_bytes": 4454
+ },
+ {
+ "name": "close_binary",
+ "bytes": 1073,
+ "input_schema_bytes": 214,
+ "output_schema_bytes": 379
+ },
+ {
+ "name": "comment",
+ "bytes": 1082,
+ "input_schema_bytes": 401,
+ "output_schema_bytes": 313
+ },
+ {
+ "name": "compare_application_versions",
+ "bytes": 27986,
+ "input_schema_bytes": 10250,
+ "output_schema_bytes": 17168
+ },
+ {
+ "name": "compare_artifacts",
+ "bytes": 4095,
+ "input_schema_bytes": 759,
+ "output_schema_bytes": 2851
+ },
+ {
+ "name": "compare_bundles",
+ "bytes": 4559,
+ "input_schema_bytes": 928,
+ "output_schema_bytes": 3132
+ },
+ {
+ "name": "compare_functions",
+ "bytes": 4828,
+ "input_schema_bytes": 725,
+ "output_schema_bytes": 3611
+ },
+ {
+ "name": "compare_process_captures",
+ "bytes": 3866,
+ "input_schema_bytes": 565,
+ "output_schema_bytes": 2716
+ },
+ {
+ "name": "compare_web_captures",
+ "bytes": 33869,
+ "input_schema_bytes": 31489,
+ "output_schema_bytes": 1940
+ },
+ {
+ "name": "compare_web_screenshots",
+ "bytes": 3428,
+ "input_schema_bytes": 1489,
+ "output_schema_bytes": 1546
+ },
+ {
+ "name": "correlate_static_and_runtime",
+ "bytes": 13332,
+ "input_schema_bytes": 8963,
+ "output_schema_bytes": 3876
+ },
+ {
+ "name": "current_address",
+ "bytes": 938,
+ "input_schema_bytes": 282,
+ "output_schema_bytes": 285
+ },
+ {
+ "name": "current_document",
+ "bytes": 842,
+ "input_schema_bytes": 219,
+ "output_schema_bytes": 285
+ },
+ {
+ "name": "current_procedure",
+ "bytes": 952,
+ "input_schema_bytes": 282,
+ "output_schema_bytes": 285
+ },
+ {
+ "name": "demangle_swift",
+ "bytes": 2276,
+ "input_schema_bytes": 221,
+ "output_schema_bytes": 1717
+ },
+ {
+ "name": "discover_webmcp_tools",
+ "bytes": 7256,
+ "input_schema_bytes": 1087,
+ "output_schema_bytes": 5765
+ },
+ {
+ "name": "export_evidence_bundle",
+ "bytes": 12103,
+ "input_schema_bytes": 196,
+ "output_schema_bytes": 11479
+ },
+ {
+ "name": "extract_artifact",
+ "bytes": 6414,
+ "input_schema_bytes": 1321,
+ "output_schema_bytes": 4701
+ },
+ {
+ "name": "find_changed_behavior",
+ "bytes": 12296,
+ "input_schema_bytes": 8586,
+ "output_schema_bytes": 3182
+ },
+ {
+ "name": "find_xrefs_to_name",
+ "bytes": 1346,
+ "input_schema_bytes": 128,
+ "output_schema_bytes": 763
+ },
+ {
+ "name": "get_call_graph",
+ "bytes": 12061,
+ "input_schema_bytes": 361,
+ "output_schema_bytes": 11228
+ },
+ {
+ "name": "get_objc_classes",
+ "bytes": 1141,
+ "input_schema_bytes": 127,
+ "output_schema_bytes": 606
+ },
+ {
+ "name": "get_objc_protocols",
+ "bytes": 1079,
+ "input_schema_bytes": 62,
+ "output_schema_bytes": 610
+ },
+ {
+ "name": "goto_address",
+ "bytes": 1094,
+ "input_schema_bytes": 424,
+ "output_schema_bytes": 285
+ },
+ {
+ "name": "import_evidence_bundle",
+ "bytes": 882,
+ "input_schema_bytes": 142,
+ "output_schema_bytes": 321
+ },
+ {
+ "name": "inline_comment",
+ "bytes": 1064,
+ "input_schema_bytes": 401,
+ "output_schema_bytes": 313
+ },
+ {
+ "name": "inspect_electron_page",
+ "bytes": 10081,
+ "input_schema_bytes": 1936,
+ "output_schema_bytes": 7685
+ },
+ {
+ "name": "inspect_macho",
+ "bytes": 9368,
+ "input_schema_bytes": 62,
+ "output_schema_bytes": 8933
+ },
+ {
+ "name": "inspect_managed_artifact",
+ "bytes": 12894,
+ "input_schema_bytes": 1251,
+ "output_schema_bytes": 11159
+ },
+ {
+ "name": "inspect_plist",
+ "bytes": 2883,
+ "input_schema_bytes": 189,
+ "output_schema_bytes": 2320
+ },
+ {
+ "name": "inspect_signature",
+ "bytes": 2946,
+ "input_schema_bytes": 62,
+ "output_schema_bytes": 2519
+ },
+ {
+ "name": "inspect_web_page",
+ "bytes": 23933,
+ "input_schema_bytes": 5042,
+ "output_schema_bytes": 18381
+ },
+ {
+ "name": "inventory_artifact",
+ "bytes": 10608,
+ "input_schema_bytes": 1885,
+ "output_schema_bytes": 8336
+ },
+ {
+ "name": "list_architectures",
+ "bytes": 2782,
+ "input_schema_bytes": 62,
+ "output_schema_bytes": 2387
+ },
+ {
+ "name": "list_bookmarks",
+ "bytes": 1091,
+ "input_schema_bytes": 282,
+ "output_schema_bytes": 437
+ },
+ {
+ "name": "list_browser_targets",
+ "bytes": 3072,
+ "input_schema_bytes": 658,
+ "output_schema_bytes": 1966
+ },
+ {
+ "name": "list_documents",
+ "bytes": 883,
+ "input_schema_bytes": 219,
+ "output_schema_bytes": 310
+ },
+ {
+ "name": "list_electron_targets",
+ "bytes": 2991,
+ "input_schema_bytes": 636,
+ "output_schema_bytes": 1932
+ },
+ {
+ "name": "list_names",
+ "bytes": 2842,
+ "input_schema_bytes": 594,
+ "output_schema_bytes": 1818
+ },
+ {
+ "name": "list_procedures",
+ "bytes": 2739,
+ "input_schema_bytes": 475,
+ "output_schema_bytes": 1818
+ },
+ {
+ "name": "list_segments",
+ "bytes": 2817,
+ "input_schema_bytes": 282,
+ "output_schema_bytes": 2128
+ },
+ {
+ "name": "list_strings",
+ "bytes": 2837,
+ "input_schema_bytes": 594,
+ "output_schema_bytes": 1818
+ },
+ {
+ "name": "list_unknowns",
+ "bytes": 4477,
+ "input_schema_bytes": 358,
+ "output_schema_bytes": 3710
+ },
+ {
+ "name": "next_address",
+ "bytes": 1039,
+ "input_schema_bytes": 401,
+ "output_schema_bytes": 285
+ },
+ {
+ "name": "observe_web_session",
+ "bytes": 6320,
+ "input_schema_bytes": 765,
+ "output_schema_bytes": 5090
+ },
+ {
+ "name": "open_binary",
+ "bytes": 1702,
+ "input_schema_bytes": 386,
+ "output_schema_bytes": 696
+ },
+ {
+ "name": "prev_address",
+ "bytes": 1045,
+ "input_schema_bytes": 401,
+ "output_schema_bytes": 285
+ },
+ {
+ "name": "procedure_address",
+ "bytes": 1082,
+ "input_schema_bytes": 383,
+ "output_schema_bytes": 285
+ },
+ {
+ "name": "procedure_assembly",
+ "bytes": 1096,
+ "input_schema_bytes": 383,
+ "output_schema_bytes": 285
+ },
+ {
+ "name": "procedure_callees",
+ "bytes": 1121,
+ "input_schema_bytes": 383,
+ "output_schema_bytes": 310
+ },
+ {
+ "name": "procedure_callers",
+ "bytes": 1085,
+ "input_schema_bytes": 383,
+ "output_schema_bytes": 310
+ },
+ {
+ "name": "procedure_info",
+ "bytes": 1982,
+ "input_schema_bytes": 383,
+ "output_schema_bytes": 1216
+ },
+ {
+ "name": "procedure_pseudo_code",
+ "bytes": 1172,
+ "input_schema_bytes": 383,
+ "output_schema_bytes": 313
+ },
+ {
+ "name": "procedure_references",
+ "bytes": 4319,
+ "input_schema_bytes": 798,
+ "output_schema_bytes": 3054
+ },
+ {
+ "name": "reconcile_javascript_runtime",
+ "bytes": 30201,
+ "input_schema_bytes": 9566,
+ "output_schema_bytes": 20110
+ },
+ {
+ "name": "record_unknown",
+ "bytes": 6725,
+ "input_schema_bytes": 2646,
+ "output_schema_bytes": 3685
+ },
+ {
+ "name": "resolve_containing_procedure",
+ "bytes": 2185,
+ "input_schema_bytes": 424,
+ "output_schema_bytes": 1280
+ },
+ {
+ "name": "run_controlled_replay",
+ "bytes": 21072,
+ "input_schema_bytes": 6098,
+ "output_schema_bytes": 14387
+ },
+ {
+ "name": "search_procedures",
+ "bytes": 2238,
+ "input_schema_bytes": 812,
+ "output_schema_bytes": 964
+ },
+ {
+ "name": "search_strings",
+ "bytes": 2247,
+ "input_schema_bytes": 812,
+ "output_schema_bytes": 964
+ },
+ {
+ "name": "set_address_name",
+ "bytes": 1141,
+ "input_schema_bytes": 478,
+ "output_schema_bytes": 286
+ },
+ {
+ "name": "set_addresses_names",
+ "bytes": 1175,
+ "input_schema_bytes": 427,
+ "output_schema_bytes": 361
+ },
+ {
+ "name": "set_bookmark",
+ "bytes": 1118,
+ "input_schema_bytes": 471,
+ "output_schema_bytes": 286
+ },
+ {
+ "name": "set_comment",
+ "bytes": 1148,
+ "input_schema_bytes": 487,
+ "output_schema_bytes": 286
+ },
+ {
+ "name": "set_current_document",
+ "bytes": 1003,
+ "input_schema_bytes": 298,
+ "output_schema_bytes": 285
+ },
+ {
+ "name": "set_inline_comment",
+ "bytes": 1142,
+ "input_schema_bytes": 487,
+ "output_schema_bytes": 286
+ },
+ {
+ "name": "swift_classes",
+ "bytes": 1135,
+ "input_schema_bytes": 127,
+ "output_schema_bytes": 606
+ },
+ {
+ "name": "trace_application_feature",
+ "bytes": 27741,
+ "input_schema_bytes": 9241,
+ "output_schema_bytes": 17969
+ },
+ {
+ "name": "trace_feature",
+ "bytes": 3340,
+ "input_schema_bytes": 555,
+ "output_schema_bytes": 2299
+ },
+ {
+ "name": "unset_bookmark",
+ "bytes": 1055,
+ "input_schema_bytes": 424,
+ "output_schema_bytes": 286
+ },
+ {
+ "name": "update_unknown",
+ "bytes": 7884,
+ "input_schema_bytes": 3810,
+ "output_schema_bytes": 3685
+ },
+ {
+ "name": "verify_reconstruction",
+ "bytes": 6692,
+ "input_schema_bytes": 2688,
+ "output_schema_bytes": 3510
+ },
+ {
+ "name": "verify_unknown_resolution",
+ "bytes": 4481,
+ "input_schema_bytes": 177,
+ "output_schema_bytes": 3866
+ },
+ {
+ "name": "xrefs",
+ "bytes": 1112,
+ "input_schema_bytes": 401,
+ "output_schema_bytes": 310
+ }
+ ]
+}
diff --git a/tests/applicationWorkflowCli.test.ts b/tests/applicationWorkflowCli.test.ts
index 2c51385f8..44220f044 100644
--- a/tests/applicationWorkflowCli.test.ts
+++ b/tests/applicationWorkflowCli.test.ts
@@ -55,13 +55,53 @@ describe("application workflow CLI parity", () => {
},
});
}, 20_000);
+
+ it("returns safe actionable JSON validation details", async () => {
+ const malformed = await runCli([
+ "trace-application-feature",
+ "{not-json",
+ "--json",
+ ]);
+ expect(malformed).toMatchObject({
+ code: "invalid_request",
+ retryable: true,
+ details: {
+ issues: [{ path: [], reason: "invalid_format", expected: "JSON" }],
+ },
+ });
+ expect(JSON.stringify(malformed)).not.toContain("not-json");
+
+ const missing = await runCli(["trace-application-feature", "{}", "--json"]);
+ expect(missing).toMatchObject({
+ code: "invalid_request",
+ details: {
+ issues: expect.arrayContaining([
+ expect.objectContaining({
+ path: ["application"],
+ reason: "missing_argument",
+ }),
+ ]),
+ },
+ });
+ });
});
const runCli = async (arguments_: readonly string[]): Promise => {
- const { stdout } = await execute(
- process.execPath,
- ["scripts/rea.mjs", ...arguments_],
- { cwd: process.cwd(), env: process.env, maxBuffer: 16 * 1_024 * 1_024 },
- );
- return JSON.parse(stdout);
+ try {
+ const { stdout } = await execute(
+ process.execPath,
+ ["scripts/rea.mjs", ...arguments_],
+ { cwd: process.cwd(), env: process.env, maxBuffer: 16 * 1_024 * 1_024 },
+ );
+ return JSON.parse(stdout);
+ } catch (cause: unknown) {
+ if (
+ typeof cause === "object" &&
+ cause !== null &&
+ "stdout" in cause &&
+ typeof cause.stdout === "string"
+ )
+ return JSON.parse(cause.stdout);
+ throw cause;
+ }
};
diff --git a/tests/applicationWorkflowMcp.test.ts b/tests/applicationWorkflowMcp.test.ts
index 7fcbecfde..913ec293e 100644
--- a/tests/applicationWorkflowMcp.test.ts
+++ b/tests/applicationWorkflowMcp.test.ts
@@ -37,9 +37,7 @@ describe("application workflow MCP parity", () => {
});
expect(traced.isError).not.toBe(true);
expect(traced.structuredContent).toMatchObject({
- operation: "trace_application_feature",
- provider: { id: "rea-javascript-application-workflows" },
- normalized_result: {
+ result: {
schema_version: 1,
coverage: { status: expect.any(String) },
},
@@ -54,8 +52,7 @@ describe("application workflow MCP parity", () => {
});
expect(compared.isError).not.toBe(true);
expect(compared.structuredContent).toMatchObject({
- operation: "compare_application_versions",
- normalized_result: {
+ result: {
schema_version: 1,
summary: { unknown: expect.any(Number) },
coverage: { status: expect.any(String) },
diff --git a/tests/artifactMcp.test.ts b/tests/artifactMcp.test.ts
index 5259c95b2..bf48295bd 100644
--- a/tests/artifactMcp.test.ts
+++ b/tests/artifactMcp.test.ts
@@ -12,7 +12,6 @@ import { BinarySession } from "../src/application/BinarySession.js";
import { ArtifactProvider } from "../src/artifacts/ArtifactProvider.js";
import { ARTIFACT_COMPARISON_EXAMPLE } from "../src/contracts/artifactComparisonExample.js";
import { evidenceBundleSchema } from "../src/domain/evidenceBundle.js";
-import { parseEvidence } from "../src/domain/evidence.js";
import { createServer } from "../src/server/createServer.js";
import { observed } from "./fixtures/analysisExecution.js";
@@ -148,7 +147,9 @@ describe("artifact graph MCP integration", () => {
},
});
expect(result.isError).not.toBe(true);
- const evidence = parseEvidence(result.structuredContent);
+ const compact = compactResult(result.structuredContent);
+ const evidence = session.evidenceById(compact.evidence_id);
+ if (evidence === undefined) throw new Error("missing inventory Evidence");
const inventory = z
.object({
occurrences: z.object({
@@ -165,7 +166,7 @@ describe("artifact graph MCP integration", () => {
}),
),
})
- .parse(evidence.normalized_result);
+ .parse(compact.result);
expect(inventory.integrity_contradictions).toEqual(
expect.arrayContaining([
expect.objectContaining({
@@ -197,16 +198,12 @@ describe("artifact graph MCP integration", () => {
const compared = await client.callTool({
name: "compare_artifacts",
arguments: {
- left: evidence,
- right: evidence,
+ left_evidence_ids: [evidence.evidence_id],
+ right_evidence_ids: [evidence.evidence_id],
},
});
expect(compared.isError).not.toBe(true);
- const comparison = parseEvidence(
- z.object({ result: z.unknown() }).parse(compared.structuredContent)
- .result,
- );
- expect(comparison.normalized_result).toMatchObject({
+ expect(compactResult(compared.structuredContent).result).toMatchObject({
status: "contradiction",
summary: { contradiction: 2 },
changes: {
@@ -333,13 +330,15 @@ describe("artifact graph MCP integration", () => {
arguments: {},
});
expect(inventory.isError).not.toBe(true);
- const evidence = parseEvidence(inventory.structuredContent);
+ const inventoryResult = compactResult(inventory.structuredContent);
+ const evidence = session.evidenceById(inventoryResult.evidence_id);
+ if (evidence === undefined) throw new Error("missing inventory Evidence");
expect(evidence).toMatchObject({
provider: { id: "rea-artifact-graph" },
subject: { format: "ipa" },
- normalized_result: {
- manifest: { root_format: "ipa" },
- },
+ });
+ expect(inventoryResult.result).toMatchObject({
+ manifest: { root_format: "ipa" },
});
const openedChanged = await client.callTool({
name: "open_binary",
@@ -350,24 +349,22 @@ describe("artifact graph MCP integration", () => {
name: "inventory_artifact",
arguments: {},
});
- const changedEvidence = parseEvidence(changedInventory.structuredContent);
+ const changedResult = compactResult(changedInventory.structuredContent);
+ const changedEvidence = session.evidenceById(changedResult.evidence_id);
+ if (changedEvidence === undefined)
+ throw new Error("missing changed Evidence");
const compared = await client.callTool({
name: "compare_artifacts",
arguments: {
- left: evidence,
- right: changedEvidence,
+ left_evidence_ids: [evidence.evidence_id],
+ right_evidence_ids: [changedEvidence.evidence_id],
unknown_registry_approved: true,
},
});
expect(compared.isError).not.toBe(true);
- const comparisonEvidence = parseEvidence(
- z.object({ result: z.unknown() }).parse(compared.structuredContent)
- .result,
- );
- expect(comparisonEvidence).toMatchObject({
- provider: { id: "rea-artifact-comparison" },
- evidence_links: [evidence.evidence_id, changedEvidence.evidence_id],
- normalized_result: { status: "changed" },
+ expect(compactResult(compared.structuredContent)).toMatchObject({
+ result: { status: "changed" },
+ evidence_id: expect.stringMatching(/^ev_/u),
});
const unknowns = await client.callTool({
name: "list_unknowns",
@@ -398,3 +395,12 @@ describe("artifact graph MCP integration", () => {
}
});
});
+
+const compactResult = (value: unknown) =>
+ z
+ .object({
+ result: z.unknown(),
+ evidence_id: z.string(),
+ evidence_uri: z.string(),
+ })
+ .parse(value);
diff --git a/tests/browserMcp.test.ts b/tests/browserMcp.test.ts
index 769c71c92..41af7a0fc 100644
--- a/tests/browserMcp.test.ts
+++ b/tests/browserMcp.test.ts
@@ -77,12 +77,7 @@ describe("browser MCP tools", () => {
});
expect(listed.isError).not.toBe(true);
expect(listed.structuredContent).toMatchObject({
- operation: "list_browser_targets",
- authority: "external-service",
- confidence: "observed",
- subject: null,
- provider: { id: "rea-cdp-browser", version: "2" },
- normalized_result: {
+ result: {
targets: { items: [{ target_id: "allowed-page" }] },
},
});
@@ -105,8 +100,7 @@ describe("browser MCP tools", () => {
});
expect(inspected.isError).not.toBe(true);
expect(inspected.structuredContent).toMatchObject({
- operation: "inspect_web_page",
- normalized_result: {
+ result: {
target: { target_id: "allowed-page" },
console: { prior_activity_available: false },
network: {
@@ -124,14 +118,14 @@ describe("browser MCP tools", () => {
arguments: {
static_layers:
JAVASCRIPT_RUNTIME_RECONCILIATION_EXAMPLE.static_layers,
- runtime_observations: [inspected.structuredContent],
+ runtime_observations: [
+ evidenceFor(connected.session, inspected.structuredContent),
+ ],
},
});
expect(reconciled.isError).not.toBe(true);
expect(reconciled.structuredContent).toMatchObject({
- operation: "reconcile_javascript_runtime",
- provider: { id: "rea-javascript-runtime-reconciliation" },
- normalized_result: { summary: { runtime_scripts: 1 } },
+ result: { summary: { runtime_scripts: 1 } },
});
expect(JSON.stringify(reconciled.structuredContent)).not.toContain(
"source-secret",
@@ -149,8 +143,7 @@ describe("browser MCP tools", () => {
});
expect(analyzed.isError).not.toBe(true);
expect(analyzed.structuredContent).toMatchObject({
- operation: "analyze_web_bundle",
- normalized_result: {
+ result: {
capture: { scripts_analyzed: 1 },
observations: { source_maps: { status: "not_requested" } },
},
@@ -167,8 +160,7 @@ describe("browser MCP tools", () => {
});
expect(observedSession.isError).not.toBe(true);
expect(observedSession.structuredContent).toMatchObject({
- operation: "observe_web_session",
- normalized_result: {
+ result: {
window: { end_reason: "window_elapsed" },
timeline: expect.arrayContaining([
expect.objectContaining({ type: "same_origin_reload" }),
@@ -187,8 +179,7 @@ describe("browser MCP tools", () => {
});
expect(webMcp.isError).not.toBe(true);
expect(webMcp.structuredContent).toMatchObject({
- operation: "discover_webmcp_tools",
- normalized_result: {
+ result: {
tools: {
items: [expect.objectContaining({ name: "search_orders" })],
},
@@ -204,8 +195,7 @@ describe("browser MCP tools", () => {
});
expect(compared.isError).not.toBe(true);
expect(compared.structuredContent).toMatchObject({
- operation: "compare_web_captures",
- normalized_result: { overall_status: "unknown" },
+ result: { overall_status: "unknown" },
});
const screenshot = await connected.client.callTool({
name: "capture_web_screenshot",
@@ -228,8 +218,7 @@ describe("browser MCP tools", () => {
});
expect(visual.isError).not.toBe(true);
expect(visual.structuredContent).toMatchObject({
- operation: "compare_web_screenshots",
- normalized_result: { status: "identical", changed_pixels: 0 },
+ result: { status: "identical", changed_pixels: 0 },
});
const evidenceId = evidenceIdOf(inspected.structuredContent);
const evidence = await connected.client.readResource({
@@ -297,7 +286,7 @@ const connectBrowser = async (browser: FakeCdpBrowser) => {
resources.push(client, server, session);
await server.connect(serverTransport);
await client.connect(clientTransport);
- return { client };
+ return { client, session };
};
const evidenceIdOf = (value: unknown): string => {
@@ -312,13 +301,15 @@ const evidenceIdOf = (value: unknown): string => {
};
const normalizedResultOf = (value: unknown): unknown => {
- if (
- typeof value !== "object" ||
- value === null ||
- !("normalized_result" in value)
- )
+ if (typeof value !== "object" || value === null || !("result" in value))
throw new TypeError("Missing normalized browser result");
- return value.normalized_result;
+ return value.result;
+};
+
+const evidenceFor = (session: BinarySession, value: unknown) => {
+ const evidence = session.evidenceById(evidenceIdOf(value));
+ if (evidence === undefined) throw new TypeError("Missing session Evidence");
+ return evidence;
};
const artifactOf = (value: unknown): unknown => {
diff --git a/tests/bundleComparisonMcp.test.ts b/tests/bundleComparisonMcp.test.ts
index 767d5210b..8506a7f24 100644
--- a/tests/bundleComparisonMcp.test.ts
+++ b/tests/bundleComparisonMcp.test.ts
@@ -1,14 +1,26 @@
+import { mkdtemp, rm, writeFile } from "node:fs/promises";
+import { tmpdir } from "node:os";
+import { join } from "node:path";
+
import { Client, InMemoryTransport } from "@modelcontextprotocol/client";
-import { describe, expect, it } from "vitest";
-import { z } from "zod";
+import { afterEach, describe, expect, it } from "vitest";
import { BinarySession } from "../src/application/BinarySession.js";
-import { createEvidence, parseEvidence } from "../src/domain/evidence.js";
-import { createEvidenceBundle } from "../src/domain/evidenceBundle.js";
-import { createResidualUnknown } from "../src/domain/residualUnknown.js";
+import { createEvidence } from "../src/domain/evidence.js";
+import {
+ createEvidenceBundle,
+ serializeEvidenceBundle,
+} from "../src/domain/evidenceBundle.js";
import { createServer } from "../src/server/createServer.js";
import { observed } from "./fixtures/analysisExecution.js";
+const roots: string[] = [];
+afterEach(async () => {
+ await Promise.all(
+ roots.splice(0).map((root) => rm(root, { recursive: true, force: true })),
+ );
+});
+
const sourceEvidence = (label: string) =>
createEvidence(
undefined,
@@ -23,124 +35,30 @@ const sourceEvidence = (label: string) =>
);
describe("bundle comparison MCP integration", () => {
- it("rejects altered records that reuse session Evidence IDs", async () => {
- const session = new BinarySession(() => ({
- health: () => Promise.resolve(),
- execute: () => Promise.resolve(observed(null)),
- close: () => Promise.resolve(),
- }));
- const leftRecord = sourceEvidence("left-authority");
- const rightRecord = sourceEvidence("right-authority");
- session.recordEvidence(leftRecord);
- session.recordEvidence(rightRecord);
- const altered = {
- ...leftRecord,
- limitations: ["caller altered this record"],
- };
- const server = createServer(session, session);
- const client = new Client({ name: "bundle-authority-test", version: "1" });
- const [clientTransport, serverTransport] =
- InMemoryTransport.createLinkedPair();
- try {
- await server.connect(serverTransport);
- await client.connect(clientTransport);
- const result = await client.callTool({
- name: "compare_bundles",
- arguments: {
- left: createEvidenceBundle([altered]),
- right: createEvidenceBundle([rightRecord]),
- },
- });
- expect(result.isError).toBe(true);
- expect(session.exportEvidenceBundle().records).toHaveLength(2);
- } finally {
- await Promise.allSettled([
- client.close(),
- server.close(),
- session.close(),
- ]);
- }
- });
-
- it("rejects unknown histories that are not owned by the session", async () => {
- const session = new BinarySession(() => ({
- health: () => Promise.resolve(),
- execute: () => Promise.resolve(observed(null)),
- close: () => Promise.resolve(),
- }));
- const leftRecord = sourceEvidence("left-unowned-unknown");
- const rightRecord = sourceEvidence("right-unowned-unknown");
- expect(session.recordEvidence(leftRecord).ok).toBe(true);
- expect(session.recordEvidence(rightRecord).ok).toBe(true);
- const unknown = createResidualUnknown(
- {
- approved: true,
- question: "Unowned history?",
- severity: "high",
- domain: "bundle-comparison-test",
- supporting_evidence_ids: [leftRecord.evidence_id],
- contradicting_evidence_ids: [],
- required_authority: "shipped-artifact",
- required_confidence: "observed",
- required_environment: null,
- recommended_probes: [],
- relationships: [],
- },
- leftRecord.evidence_id,
- null,
- );
- const server = createServer(session, session);
- const client = new Client({ name: "bundle-unknown-test", version: "1" });
- const [clientTransport, serverTransport] =
- InMemoryTransport.createLinkedPair();
- try {
- await server.connect(serverTransport);
- await client.connect(clientTransport);
- const result = await client.callTool({
- name: "compare_bundles",
- arguments: {
- left: createEvidenceBundle([leftRecord], [unknown]),
- right: createEvidenceBundle([rightRecord]),
- },
- });
- expect(result.isError).toBe(true);
- expect(session.exportEvidenceBundle()).toMatchObject({
- records: [leftRecord, rightRecord].sort((left, right) =>
- left.evidence_id.localeCompare(right.evidence_id),
- ),
- unknowns: [],
- });
- } finally {
- await Promise.allSettled([
- client.close(),
- server.close(),
- session.close(),
- ]);
- }
- });
-
- it("records a digest-anchored comparison linked to every source record", async () => {
- const session = new BinarySession(() => ({
- health: () => Promise.resolve(),
- execute: () => Promise.resolve(observed(null)),
- close: () => Promise.resolve(),
- }));
+ it("reads two approved bounded bundle files and records a compact result", async () => {
+ const root = await mkdtemp(join(tmpdir(), "rea-bundle-mcp-"));
+ roots.push(root);
+ const leftPath = join(root, "left.json");
+ const rightPath = join(root, "right.json");
const leftRecord = sourceEvidence("left");
const rightRecord = sourceEvidence("right");
- expect(session.recordEvidence(leftRecord).ok).toBe(true);
- expect(session.recordEvidence(rightRecord).ok).toBe(true);
- const server = createServer(session, session);
- const client = new Client({ name: "bundle-comparison-test", version: "1" });
- const [clientTransport, serverTransport] =
- InMemoryTransport.createLinkedPair();
+ await Promise.all([
+ writeFile(
+ leftPath,
+ serializeEvidenceBundle(createEvidenceBundle([leftRecord])),
+ ),
+ writeFile(
+ rightPath,
+ serializeEvidenceBundle(createEvidenceBundle([rightRecord])),
+ ),
+ ]);
+ const connected = await connect(root);
try {
- await server.connect(serverTransport);
- await client.connect(clientTransport);
- const result = await client.callTool({
+ const result = await connected.client.callTool({
name: "compare_bundles",
arguments: {
- left: createEvidenceBundle([leftRecord]),
- right: createEvidenceBundle([rightRecord]),
+ left_bundle_path: leftPath,
+ right_bundle_path: rightPath,
record_pairs: [
{
left_evidence_id: leftRecord.evidence_id,
@@ -150,24 +68,101 @@ describe("bundle comparison MCP integration", () => {
},
});
expect(result.isError).not.toBe(true);
- const evidence = parseEvidence(
- z.object({ result: z.unknown() }).parse(result.structuredContent)
- .result,
- );
- expect(evidence).toMatchObject({
- provider: { id: "rea-bundle-comparison" },
- evidence_links: [
- leftRecord.evidence_id,
- rightRecord.evidence_id,
- ].sort(),
- normalized_result: { status: "changed" },
+ expect(result.structuredContent).toMatchObject({
+ result: { status: "changed" },
+ evidence_id: expect.stringMatching(/^ev_[a-f0-9]{64}$/u),
+ evidence_uri: expect.stringMatching(/^rea:\/\/evidence\/ev_/u),
});
} finally {
+ await connected.close();
+ }
+ });
+
+ it("rejects a bundle path outside the approved root", async () => {
+ const root = await mkdtemp(join(tmpdir(), "rea-bundle-root-"));
+ const outside = await mkdtemp(join(tmpdir(), "rea-bundle-outside-"));
+ roots.push(root, outside);
+ const leftPath = join(root, "left.json");
+ const rightPath = join(outside, "right.json");
+ const encoded = serializeEvidenceBundle(createEvidenceBundle([]));
+ await Promise.all([
+ writeFile(leftPath, encoded),
+ writeFile(rightPath, encoded),
+ ]);
+ const connected = await connect(root);
+ try {
+ const result = await connected.client.callTool({
+ name: "compare_bundles",
+ arguments: {
+ left_bundle_path: leftPath,
+ right_bundle_path: rightPath,
+ },
+ });
+ expect(result).toMatchObject({
+ isError: true,
+ structuredContent: { error: { code: "outside_approved_root" } },
+ });
+ } finally {
+ await connected.close();
+ }
+ });
+
+ it("rejects an oversized approved bundle", async () => {
+ const root = await mkdtemp(join(tmpdir(), "rea-bundle-size-"));
+ roots.push(root);
+ const leftPath = join(root, "left.json");
+ const rightPath = join(root, "right.json");
+ await Promise.all([
+ writeFile(leftPath, " ".repeat(2_000)),
+ writeFile(rightPath, serializeEvidenceBundle(createEvidenceBundle([]))),
+ ]);
+ const connected = await connect(root, 1_024);
+ try {
+ const result = await connected.client.callTool({
+ name: "compare_bundles",
+ arguments: {
+ left_bundle_path: leftPath,
+ right_bundle_path: rightPath,
+ },
+ });
+ expect(result).toMatchObject({
+ isError: true,
+ structuredContent: { error: { code: "truncated" } },
+ });
+ } finally {
+ await connected.close();
+ }
+ });
+});
+
+const connect = async (root: string, maxBytes = 1024 * 1024) => {
+ const session = new BinarySession(() => ({
+ health: () => Promise.resolve(),
+ execute: () => Promise.resolve(observed(null)),
+ close: () => Promise.resolve(),
+ }));
+ const server = createServer(session, session, {
+ evidenceFilePolicy: {
+ roots: [root],
+ maxBytes,
+ maxDepth: 68,
+ maxStringLength: 1024 * 1024,
+ maxNodes: 100_000,
+ },
+ });
+ const client = new Client({ name: "bundle-comparison-test", version: "1" });
+ const [clientTransport, serverTransport] =
+ InMemoryTransport.createLinkedPair();
+ await server.connect(serverTransport);
+ await client.connect(clientTransport);
+ return {
+ client,
+ close: async () => {
await Promise.allSettled([
client.close(),
server.close(),
session.close(),
]);
- }
- });
-});
+ },
+ };
+};
diff --git a/tests/contractSnapshot.test.ts b/tests/contractSnapshot.test.ts
index 1127d8526..ce2adc529 100644
--- a/tests/contractSnapshot.test.ts
+++ b/tests/contractSnapshot.test.ts
@@ -20,6 +20,10 @@ import {
officialOutputSchemas,
sessionOutputSchemas,
} from "../src/contracts/toolOutputSchemas.js";
+import {
+ annotationsFromEffects,
+ TOOL_EFFECTS,
+} from "../src/contracts/toolEffects.js";
const convertContractJsonSchema = (schema: z.ZodType) =>
z.toJSONSchema(schema, {
@@ -72,6 +76,10 @@ describe("tool contract surface", () => {
const outputSchema = contractJsonSchema(contract.outputSchema);
expect(inputSchema.type).toBe("object");
expect(outputSchema.type).toBe("object");
+ expect(contract.title.length).toBeGreaterThan(2);
+ expect(contract.annotations).toEqual(
+ annotationsFromEffects(contract.effects),
+ );
expect(typeof contract.annotations.idempotentHint).toBe("boolean");
expect(typeof contract.annotations.openWorldHint).toBe("boolean");
expect(typeof contract.annotations.readOnlyHint).toBe("boolean");
@@ -86,6 +94,21 @@ describe("tool contract surface", () => {
}
});
+ it("audits every tool effect explicitly with no heuristic fallback", () => {
+ const names = [
+ ...OFFICIAL_TOOL_CONTRACTS,
+ ...ENHANCED_TOOL_CONTRACTS,
+ ...NATIVE_TOOL_CONTRACTS,
+ ...ARTIFACT_TOOL_CONTRACTS,
+ ...MANAGED_TOOL_CONTRACTS,
+ ...BROWSER_TOOL_CONTRACTS,
+ ...ELECTRON_TOOL_CONTRACTS,
+ ...APPLICATION_TOOL_CONTRACTS,
+ ...SESSION_TOOL_CONTRACTS,
+ ].map(({ name }) => name);
+ expect(Object.keys(TOOL_EFFECTS).sort()).toEqual(names.sort());
+ });
+
it("keeps exactly eighteen additive session contracts", () => {
expect(
SESSION_TOOL_CONTRACTS.map(({ name, kind }) => ({ name, kind })),
diff --git a/tests/electronMcp.test.ts b/tests/electronMcp.test.ts
index 9a2b52ff9..91864a7b8 100644
--- a/tests/electronMcp.test.ts
+++ b/tests/electronMcp.test.ts
@@ -91,9 +91,7 @@ describe("Electron MCP tools", () => {
});
expect(listed.isError).not.toBe(true);
expect(listed.structuredContent).toMatchObject({
- operation: "list_electron_targets",
- provider: { id: "rea-cdp-electron" },
- normalized_result: {
+ result: {
targets: { items: [{ target_id: "electron-page" }] },
},
});
@@ -118,30 +116,32 @@ describe("Electron MCP tools", () => {
name: "reconcile_javascript_runtime",
arguments: {
static_layers: [
- { role: "application", analysis: analyzed.structuredContent },
+ {
+ role: "application",
+ analysis: evidenceFor(session, analyzed.structuredContent),
+ },
+ ],
+ runtime_observations: [
+ evidenceFor(session, inspected.structuredContent),
],
- runtime_observations: [inspected.structuredContent],
},
});
expect(reconciled.isError).not.toBe(true);
expect(reconciled.structuredContent).toMatchObject({
- operation: "reconcile_javascript_runtime",
- provider: { id: "rea-javascript-runtime-reconciliation" },
- normalized_result: {
+ result: {
summary: { runtime_scripts: 1, matched: expect.any(Number) },
source_map_authority: { used_for_primary_matching: false },
},
});
expect(inspected.isError).not.toBe(true);
expect(inspected.structuredContent).toMatchObject({
- operation: "inspect_electron_page",
- normalized_result: {
- target: { file_path: join(root, "index.html") },
+ result: {
+ target: { file_path: expect.stringMatching(/\/index\.html$/u) },
scripts: {
items: [
expect.objectContaining({
frame_id: "frame-main",
- file_path: join(root, "app.js"),
+ file_path: expect.stringMatching(/\/app\.js$/u),
}),
],
},
@@ -149,7 +149,7 @@ describe("Electron MCP tools", () => {
expect.objectContaining({
target_id: "electron-worker",
opener_target_id: "electron-page",
- file_path: join(root, "worker.js"),
+ file_path: expect.stringMatching(/\/worker\.js$/u),
}),
],
},
@@ -170,7 +170,7 @@ describe("Electron MCP tools", () => {
expect(denied.structuredContent).toMatchObject({
error: {
code: "permission_required",
- details: { missing: { roots: [outside] } },
+ details: { missing: { roots: [expect.stringMatching(/outside-/u)] } },
},
});
expect(browser.commands).toHaveLength(commandsBeforeDenial);
@@ -214,11 +214,9 @@ describe("Electron MCP tools", () => {
expect(analyzed.isError).not.toBe(true);
expect(analyzed.structuredContent).toMatchObject({
- operation: "analyze_javascript_application",
- provider: { id: "rea-javascript-application" },
- normalized_result: {
+ result: {
schema_version: 1,
- input_path: root,
+ input_path: expect.stringMatching(/rea-electron-static-mcp-/u),
summary: {
browser_windows: 3,
context_bridge_apis: 2,
@@ -228,4 +226,17 @@ describe("Electron MCP tools", () => {
},
});
});
+
+ const evidenceFor = (session: BinarySession, value: unknown) => {
+ if (
+ typeof value !== "object" ||
+ value === null ||
+ !("evidence_id" in value) ||
+ typeof value.evidence_id !== "string"
+ )
+ throw new TypeError("Missing compact Evidence ID");
+ const evidence = session.evidenceById(value.evidence_id);
+ if (evidence === undefined) throw new TypeError("Missing session Evidence");
+ return evidence;
+ };
});
diff --git a/tests/enhancedTools.test.ts b/tests/enhancedTools.test.ts
index 70ab4c67c..06dc20cf7 100644
--- a/tests/enhancedTools.test.ts
+++ b/tests/enhancedTools.test.ts
@@ -174,6 +174,14 @@ const jsonResult = (result: CallToolResult): JsonValue => {
) {
return structured.data.normalized_result ?? null;
}
+ if (
+ typeof structured.data === "object" &&
+ structured.data !== null &&
+ !Array.isArray(structured.data) &&
+ "evidence_id" in structured.data &&
+ "result" in structured.data
+ )
+ return structured.data.result ?? null;
const text = result.content.find((item) => item.type === "text");
if (text?.type !== "text")
throw new Error("Tool result omitted text content");
@@ -567,7 +575,7 @@ describe("enhanced MCP tools", () => {
expect(result.isError).toBe(true);
const text = result.content.find((item) => item.type === "text");
expect(text?.type === "text" ? text.text : "").toBe(
- "Analysis returned an unreadable result. Retry once; if it continues, run `rea doctor`.",
+ JSON.stringify(result.structuredContent),
);
});
@@ -603,6 +611,47 @@ describe("enhanced MCP tools", () => {
expect(JSON.stringify(result)).toContain("operation budget");
});
+ it("returns correction-only structured validation issues", async () => {
+ const client = await connect();
+ const misspelled = await client.callTool({
+ name: "trace_feature",
+ arguments: { query: "needle", max_operatons: 1 },
+ });
+ expect(misspelled).toMatchObject({
+ isError: true,
+ structuredContent: {
+ error: {
+ code: "invalid_request",
+ retryable: true,
+ details: {
+ issues: [{ path: ["max_operatons"], reason: "unknown_argument" }],
+ },
+ },
+ },
+ });
+ const bounded = await client.callTool({
+ name: "trace_feature",
+ arguments: { query: "needle", max_operations: 101 },
+ });
+ expect(bounded.structuredContent).toMatchObject({
+ error: {
+ details: {
+ issues: [
+ {
+ path: ["max_operations"],
+ reason: "out_of_range",
+ maximum: 100,
+ },
+ ],
+ },
+ },
+ });
+ expect(bounded.content[0]).toEqual({
+ type: "text",
+ text: JSON.stringify(bounded.structuredContent),
+ });
+ });
+
it("returns a typed tool error for malformed Hopper boundary values", async () => {
const client = await connect({
execute: () => Promise.resolve(ok(["not", "a", "procedure", "map"])),
@@ -614,7 +663,7 @@ describe("enhanced MCP tools", () => {
expect(result.isError).toBe(true);
const text = result.content.find((item) => item.type === "text");
expect(text?.type === "text" ? text.text : "").toBe(
- "Analysis returned an unreadable result. Retry once; if it continues, run `rea doctor`.",
+ JSON.stringify(result.structuredContent),
);
});
@@ -635,7 +684,7 @@ describe("enhanced MCP tools", () => {
expect(result.isError).toBe(true);
const text = result.content.find((item) => item.type === "text");
expect(text?.type === "text" ? text.text : "").toBe(
- "Analysis returned an unreadable result. Retry once; if it continues, run `rea doctor`.",
+ JSON.stringify(result.structuredContent),
);
});
@@ -671,7 +720,7 @@ describe("enhanced MCP tools", () => {
expect(result.isError).toBe(true);
const text = result.content.find((item) => item.type === "text");
expect(text?.type === "text" ? text.text : "").toBe(
- "Analysis returned an unreadable result. Retry once; if it continues, run `rea doctor`.",
+ JSON.stringify(result.structuredContent),
);
});
diff --git a/tests/functionComparisonMcp.test.ts b/tests/functionComparisonMcp.test.ts
index 4eec8b1f7..c84a67feb 100644
--- a/tests/functionComparisonMcp.test.ts
+++ b/tests/functionComparisonMcp.test.ts
@@ -1,10 +1,9 @@
import { Client, InMemoryTransport } from "@modelcontextprotocol/client";
import { describe, expect, it } from "vitest";
-import { z } from "zod";
import { BinarySession } from "../src/application/BinarySession.js";
import { FUNCTION_COMPARISON_EXAMPLE } from "../src/contracts/functionComparisonExample.js";
-import { parseEvidence } from "../src/domain/evidence.js";
+import { createEvidence } from "../src/domain/evidence.js";
import { createServer } from "../src/server/createServer.js";
import { observed } from "./fixtures/analysisExecution.js";
@@ -34,22 +33,16 @@ describe("function comparison MCP integration", () => {
const result = await client.callTool({
name: "compare_functions",
arguments: {
- left: FUNCTION_COMPARISON_EXAMPLE.left,
- right: FUNCTION_COMPARISON_EXAMPLE.right,
+ left_evidence_ids: [FUNCTION_COMPARISON_EXAMPLE.left.evidence_id],
+ right_evidence_ids: [FUNCTION_COMPARISON_EXAMPLE.right.evidence_id],
unknown_registry_approved: true,
},
});
expect(result.isError).not.toBe(true);
- const evidence = parseEvidence(
- z.object({ result: z.unknown() }).parse(result.structuredContent)
- .result,
- );
- expect(evidence).toMatchObject({
- provider: { id: "rea-function-comparison" },
- evidence_links: [
- FUNCTION_COMPARISON_EXAMPLE.left.evidence_id,
- FUNCTION_COMPARISON_EXAMPLE.right.evidence_id,
- ],
+ expect(result.structuredContent).toMatchObject({
+ result: { status: expect.any(String) },
+ evidence_id: expect.stringMatching(/^ev_[a-f0-9]{64}$/u),
+ evidence_uri: expect.stringMatching(/^rea:\/\/evidence\/ev_/u),
});
const unknowns = await client.callTool({
name: "list_unknowns",
@@ -93,8 +86,8 @@ describe("function comparison MCP integration", () => {
const result = await client.callTool({
name: "compare_functions",
arguments: {
- left: FUNCTION_COMPARISON_EXAMPLE.left,
- right: FUNCTION_COMPARISON_EXAMPLE.right,
+ left_evidence_ids: [FUNCTION_COMPARISON_EXAMPLE.left.evidence_id],
+ right_evidence_ids: [FUNCTION_COMPARISON_EXAMPLE.right.evidence_id],
},
});
expect(result.isError).toBe(true);
@@ -108,13 +101,22 @@ describe("function comparison MCP integration", () => {
}
});
- it("rejects altered payloads that reuse session Evidence IDs", async () => {
+ it("rejects Evidence IDs with the wrong operation", async () => {
const session = new BinarySession(() => ({
health: () => Promise.resolve(),
execute: () => Promise.resolve(observed(null)),
close: () => Promise.resolve(),
}));
- session.recordEvidence(FUNCTION_COMPARISON_EXAMPLE.left);
+ const wrong = createEvidence(
+ undefined,
+ { id: "fixture", name: "Fixture", version: "1" },
+ {
+ operation: "inventory_artifact",
+ parameters: {},
+ result: {},
+ },
+ );
+ session.recordEvidence(wrong);
session.recordEvidence(FUNCTION_COMPARISON_EXAMPLE.right);
const server = createServer(session, session);
const client = new Client({
@@ -129,11 +131,8 @@ describe("function comparison MCP integration", () => {
const result = await client.callTool({
name: "compare_functions",
arguments: {
- left: {
- ...FUNCTION_COMPARISON_EXAMPLE.left,
- limitations: ["caller altered this record"],
- },
- right: FUNCTION_COMPARISON_EXAMPLE.right,
+ left_evidence_ids: [wrong.evidence_id],
+ right_evidence_ids: [FUNCTION_COMPARISON_EXAMPLE.right.evidence_id],
},
});
expect(result.isError).toBe(true);
diff --git a/tests/integration/serverIntegration.test.ts b/tests/integration/serverIntegration.test.ts
index 21fb6dcf6..3c17e4ef4 100644
--- a/tests/integration/serverIntegration.test.ts
+++ b/tests/integration/serverIntegration.test.ts
@@ -61,6 +61,59 @@ const structured = (result: CallToolResult): Record => {
return Object.fromEntries(Object.entries(result.structuredContent));
};
+const objectEntries = (value: unknown): readonly [string, unknown][] =>
+ typeof value === "object" && value !== null && !Array.isArray(value)
+ ? Object.entries(value)
+ : [];
+
+const referencedSchema = (schema: unknown, root: unknown): unknown => {
+ const object = Object.fromEntries(objectEntries(schema));
+ const reference = object.$ref;
+ if (typeof reference !== "string" || !reference.startsWith("#/$defs/"))
+ return schema;
+ return Object.fromEntries(objectEntries(root)).$defs instanceof Object
+ ? Object.fromEntries(
+ objectEntries(Object.fromEntries(objectEntries(root)).$defs),
+ )[reference.slice(8)]
+ : schema;
+};
+
+const assertDescribedStrictObjects = (
+ schema: unknown,
+ root = schema,
+ path = "$",
+): void => {
+ for (const [key, value] of objectEntries(schema)) {
+ if (key === "properties") {
+ const properties = objectEntries(value);
+ for (const [property, propertySchema] of properties) {
+ const resolved = referencedSchema(propertySchema, root);
+ const propertyObject = Object.fromEntries(
+ objectEntries(propertySchema),
+ );
+ expect(
+ propertyObject.description ??
+ Object.fromEntries(objectEntries(resolved)).description,
+ `${path}.properties.${property}`,
+ ).toEqual(expect.any(String));
+ assertDescribedStrictObjects(
+ propertySchema,
+ root,
+ `${path}.properties.${property}`,
+ );
+ }
+ expect(
+ Object.fromEntries(objectEntries(schema)).additionalProperties,
+ ).toBe(false);
+ continue;
+ }
+ assertDescribedStrictObjects(value, root, `${path}.${key}`);
+ }
+ if (Array.isArray(schema))
+ for (const [index, value] of schema.entries())
+ assertDescribedStrictObjects(value, root, `${path}[${String(index)}]`);
+};
+
describe("full MCP integration with multi-tool sequences", () => {
it("executes a realistic workflow: list methods, decompile selected, get xrefs", async () => {
const client = await connect({
@@ -98,10 +151,7 @@ describe("full MCP integration with multi-tool sequences", () => {
});
expect(listResult.isError).not.toBe(true);
expect(structured(listResult)).toMatchObject({
- subject: null,
- operation: "list_procedures",
- provider: { id: "fixture", version: "1" },
- normalized_result: {
+ result: {
items: [
{ address: "0x1000", value: "main" },
{ address: "0x2000", value: "helper" },
@@ -116,9 +166,7 @@ describe("full MCP integration with multi-tool sequences", () => {
arguments: { procedure: "0x1000" },
});
expect(structured(decompileResult)).toMatchObject({
- operation: "procedure_pseudo_code",
- parameters: { document: null, procedure: "0x1000" },
- normalized_result: "pseudo for 0x1000",
+ result: "pseudo for 0x1000",
});
const xrefResult = await client.callTool({
@@ -126,8 +174,7 @@ describe("full MCP integration with multi-tool sequences", () => {
arguments: {},
});
expect(structured(xrefResult)).toMatchObject({
- operation: "xrefs",
- normalized_result: ["0x1000"],
+ result: ["0x1000"],
});
});
@@ -161,6 +208,30 @@ describe("full MCP integration with multi-tool sequences", () => {
expect(names).toContain("binary_session");
expect(names).toContain("binary_overview");
expect(names).toContain("batch_decompile");
+
+ expect(
+ Buffer.byteLength(JSON.stringify(listed), "utf8"),
+ ).toBeLessThanOrEqual(512 * 1024);
+ const contracts = new Map(
+ TOOL_CONTRACTS.map((contract) => [contract.name, contract]),
+ );
+ for (const tool of listed.tools) {
+ expect(
+ Buffer.byteLength(JSON.stringify(tool), "utf8"),
+ tool.name,
+ ).toBeLessThanOrEqual(64 * 1024);
+ const contract = contracts.get(tool.name);
+ expect(contract, tool.name).toBeDefined();
+ expect(tool.title, tool.name).toBe(contract?.title);
+ expect(tool.description, tool.name).toBe(contract?.description);
+ expect(tool.annotations, tool.name).toEqual(contract?.annotations);
+ expect(tool.outputSchema, tool.name).toBeDefined();
+ assertDescribedStrictObjects(
+ tool.inputSchema,
+ tool.inputSchema,
+ tool.name,
+ );
+ }
});
it("records approved trace truncation as a deduplicated residual unknown", async () => {
@@ -355,9 +426,7 @@ describe("full MCP integration with multi-tool sequences", () => {
name: "compare_process_captures",
arguments: {
left_evidence_id: leftEvidence.evidence_id,
- left,
right_evidence_id: rightEvidence.evidence_id,
- right,
unknown_registry_approved: true,
},
});
@@ -408,9 +477,7 @@ describe("full MCP integration with multi-tool sequences", () => {
category: "execution_failure",
},
});
- expect(text(result)).toBe(
- "Analysis could not complete. Retry once; if it continues, run `rea doctor`.",
- );
+ expect(text(result)).toBe(JSON.stringify(result.structuredContent));
});
it("handles concurrent tool calls without corruption", async () => {
diff --git a/tests/investigationMcp.test.ts b/tests/investigationMcp.test.ts
index 89cc31daf..7c8228bd9 100644
--- a/tests/investigationMcp.test.ts
+++ b/tests/investigationMcp.test.ts
@@ -15,7 +15,7 @@ import {
PROCESS_COMPARISON_EVIDENCE,
} from "../src/contracts/investigationExamples.js";
import { changedBehaviorResultSchema } from "../src/domain/changedBehavior.js";
-import { createEvidence, parseEvidence } from "../src/domain/evidence.js";
+import { createEvidence } from "../src/domain/evidence.js";
import { jsonObjectSchema, jsonValueSchema } from "../src/domain/jsonValue.js";
import { createServer } from "../src/server/createServer.js";
import { observed } from "./fixtures/analysisExecution.js";
@@ -96,9 +96,7 @@ describe("investigation MCP workflows", () => {
arguments: arguments_,
});
expect(first.isError).not.toBe(true);
- const firstEvidence = parseEvidence(
- z.object({ result: z.unknown() }).parse(first.structuredContent).result,
- );
+ const firstEvidence = sessionEvidence(session, first.structuredContent);
expect(firstEvidence.normalized_result).toMatchObject({
behavior_status: "unknown",
summary: { static_candidates: 2 },
@@ -136,10 +134,7 @@ describe("investigation MCP workflows", () => {
arguments: arguments_,
});
expect(second.isError, JSON.stringify(second)).not.toBe(true);
- const secondEvidence = parseEvidence(
- z.object({ result: z.unknown() }).parse(second.structuredContent)
- .result,
- );
+ const secondEvidence = sessionEvidence(session, second.structuredContent);
expect(secondEvidence.evidence_id).toBe(firstEvidence.evidence_id);
expect(
await readInvestigationWorkspace(workspace, filePolicy),
@@ -245,9 +240,9 @@ describe("investigation MCP workflows", () => {
arguments: { investigation_run: investigationRun },
});
expect(created.isError, JSON.stringify(created)).not.toBe(true);
- const evidence = parseEvidence(
- z.object({ result: z.unknown() }).parse(created.structuredContent)
- .result,
+ const evidence = sessionEvidence(
+ initial.session,
+ created.structuredContent,
);
const result = changedBehaviorResultSchema.parse(
evidence.normalized_result,
@@ -322,12 +317,10 @@ describe("investigation MCP workflows", () => {
},
});
expect(response.isError).toBe(true);
- expect(response.content).toEqual([
- {
- type: "text",
- text: "Artifact path is not allowed. Choose a path inside the artifact and try again.",
- },
- ]);
+ expect(response.content[0]).toEqual({
+ type: "text",
+ text: JSON.stringify(response.structuredContent),
+ });
} finally {
await close(session, server, client);
await rm(directory, { recursive: true, force: true });
@@ -354,10 +347,7 @@ describe("investigation MCP workflows", () => {
},
});
expect(response.isError, JSON.stringify(response)).not.toBe(true);
- const evidence = parseEvidence(
- z.object({ result: z.unknown() }).parse(response.structuredContent)
- .result,
- );
+ const evidence = sessionEvidence(session, response.structuredContent);
expect(evidence).toMatchObject({
provider: { id: "rea-changed-behavior" },
normalized_result: { behavior_status: "unknown" },
@@ -386,10 +376,7 @@ describe("investigation MCP workflows", () => {
arguments: INVESTIGATION_EXAMPLES.build_call_path,
});
expect(response.isError).not.toBe(true);
- const evidence = parseEvidence(
- z.object({ result: z.unknown() }).parse(response.structuredContent)
- .result,
- );
+ const evidence = sessionEvidence(session, response.structuredContent);
expect(evidence).toMatchObject({
provider: { id: "rea-call-path" },
normalized_result: {
@@ -481,10 +468,7 @@ describe("investigation MCP workflows", () => {
arguments: INVESTIGATION_EXAMPLES.correlate_static_and_runtime,
});
expect(response.isError).not.toBe(true);
- const evidence = parseEvidence(
- z.object({ result: z.unknown() }).parse(response.structuredContent)
- .result,
- );
+ const evidence = sessionEvidence(session, response.structuredContent);
expect(evidence).toMatchObject({
provider: { id: "rea-static-runtime-correlation" },
confidence: "inferred",
@@ -560,10 +544,7 @@ describe("investigation MCP workflows", () => {
},
});
expect(response.isError).not.toBe(true);
- const evidence = parseEvidence(
- z.object({ result: z.unknown() }).parse(response.structuredContent)
- .result,
- );
+ const evidence = sessionEvidence(session, response.structuredContent);
expect(evidence).toMatchObject({
provider: { id: "rea-reconstruction-verifier" },
normalized_result: { status: "pass", summary: { passed: 1 } },
@@ -613,10 +594,7 @@ describe("investigation MCP workflows", () => {
},
});
expect(response.isError).not.toBe(true);
- const evidence = parseEvidence(
- z.object({ result: z.unknown() }).parse(response.structuredContent)
- .result,
- );
+ const evidence = sessionEvidence(session, response.structuredContent);
expect(evidence.normalized_result).toMatchObject({
status: "unknown",
summary: { unknown: 1 },
@@ -669,6 +647,15 @@ const evidencePolicy = (root: string): EvidenceFilePolicy => ({
maxNodes: 1_000_000,
});
+const sessionEvidence = (session: BinarySession, value: unknown) => {
+ const parsed = z
+ .object({ evidence_id: z.string().regex(/^ev_[a-f0-9]{64}$/u) })
+ .parse(value);
+ const evidence = session.evidenceById(parsed.evidence_id);
+ if (evidence === undefined) throw new TypeError("Missing session Evidence");
+ return evidence;
+};
+
const investigationAuthority = async (
root: string,
includeWrite: boolean,
diff --git a/tests/managedMcp.test.ts b/tests/managedMcp.test.ts
index 3b20a9a89..ef83b8c08 100644
--- a/tests/managedMcp.test.ts
+++ b/tests/managedMcp.test.ts
@@ -108,10 +108,7 @@ describe("managed artifact MCP tools", () => {
);
expect(inspected).toMatchObject({
- operation: "inspect_managed_artifact",
- provider: { id: "rea-dotnet-static" },
- subject: { local_path: path, format: "pe" },
- normalized_result: {
+ result: {
classification: {
status: "managed",
runtime_family: "modern-dotnet",
diff --git a/tests/officialTools.test.ts b/tests/officialTools.test.ts
index 8f614655e..bcd8dcada 100644
--- a/tests/officialTools.test.ts
+++ b/tests/officialTools.test.ts
@@ -201,11 +201,9 @@ describe("official Hopper proxy tools", () => {
arguments: {},
});
expect(result.isError).toBe(true);
- expect(result.content).toEqual([
- {
- type: "text",
- text: "Analysis could not complete. Retry once; if it continues, run `rea doctor`.",
- },
- ]);
+ expect(result.content[0]).toEqual({
+ type: "text",
+ text: JSON.stringify(result.structuredContent),
+ });
});
});
diff --git a/tests/providerSelectionMcp.test.ts b/tests/providerSelectionMcp.test.ts
index 74deb1948..36ccaf4b9 100644
--- a/tests/providerSelectionMcp.test.ts
+++ b/tests/providerSelectionMcp.test.ts
@@ -111,9 +111,8 @@ describe("provider selection over MCP", () => {
});
expect(observed.isError).not.toBe(true);
expect(structured(observed)).toMatchObject({
- provider: { id: "beta", version: "1" },
- analysis_profile: { provider: { id: "beta", version: "1" } },
- normalized_result: "beta:address_name",
+ result: "beta:address_name",
+ evidence_id: expect.stringMatching(/^ev_/u),
});
expect(starts).toEqual(["beta"]);
diff --git a/tests/sessionMcp.test.ts b/tests/sessionMcp.test.ts
index 564b1ffa6..701e2dffe 100644
--- a/tests/sessionMcp.test.ts
+++ b/tests/sessionMcp.test.ts
@@ -1,4 +1,4 @@
-import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
+import { mkdtemp, readFile, realpath, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
@@ -73,12 +73,13 @@ describe("target-free MCP lifecycle", () => {
}),
).result;
- expect(first).toMatchObject({ path: targetPath });
- expect(second).toMatchObject({ path: targetPath });
+ const canonicalTargetPath = await realpath(targetPath);
+ expect(first).toMatchObject({ path: canonicalTargetPath });
+ expect(second).toMatchObject({ path: canonicalTargetPath });
expect(z.object({ sha256: z.string() }).parse(second).sha256).not.toBe(
z.object({ sha256: z.string() }).parse(first).sha256,
);
- expect(closed).toEqual([targetPath]);
+ expect(closed).toEqual([canonicalTargetPath]);
expect(
z
.object({ result: z.object({ path: z.string(), sha256: z.string() }) })
@@ -88,7 +89,7 @@ describe("target-free MCP lifecycle", () => {
),
).result,
).toEqual({
- path: targetPath,
+ path: canonicalTargetPath,
sha256: z.object({ sha256: z.string() }).parse(second).sha256,
});
});
@@ -139,9 +140,7 @@ describe("target-free MCP lifecycle", () => {
arguments: {},
});
expect(before.isError).toBe(true);
- expect(text(before)).toBe(
- "No app is open. Ask the user which app to investigate, then call open_binary with its local path.",
- );
+ expect(text(before)).toBe(JSON.stringify(before.structuredContent));
expect((await mcp.listTools()).tools).toHaveLength(89);
const deniedCapture = await mcp.callTool({
name: "capture_process_scenario",
@@ -158,7 +157,7 @@ describe("target-free MCP lifecycle", () => {
},
});
expect(text(deniedCapture)).toBe(
- "Process capture is disabled. Set `REA_PROCESS_CAPTURE_ENABLED=true`, configure approved roots, then restart REA.",
+ JSON.stringify(deniedCapture.structuredContent),
);
expect(
(await mcp.callTool({ name: "open_binary", arguments: { path: first } }))
@@ -304,7 +303,7 @@ describe("target-free MCP lifecycle", () => {
});
expect(
text(await mcp.callTool({ name: "binary_session", arguments: {} })),
- ).toContain('"open": false');
+ ).toContain('"open":false');
expect(
(
await mcp.callTool({
diff --git a/tests/toolResult.test.ts b/tests/toolResult.test.ts
index 5a8f13ed3..1921403e5 100644
--- a/tests/toolResult.test.ts
+++ b/tests/toolResult.test.ts
@@ -6,17 +6,26 @@ import { ok } from "../src/domain/result.js";
import { err } from "../src/domain/result.js";
import { HopperProcessError } from "../src/domain/errors.js";
import { toCallToolResult } from "../src/server/toolResult.js";
-import {
- createEvidence,
- evidenceEnvelopeSchema,
-} from "../src/domain/evidence.js";
+import { createEvidence } from "../src/domain/evidence.js";
+import { evidenceResultOf } from "../src/contracts/toolOutputSchemas.js";
const contract: ToolContract = {
name: "provider_neutral_fixture",
+ title: "Provider Neutral Fixture",
description: "Fixture contract for provider-neutral output validation.",
kind: "enhanced",
inputSchema: z.object({}),
outputSchema: z.object({ value: z.string() }),
+ effects: {
+ mutatesTarget: false,
+ mutatesSession: false,
+ writesFilesystem: false,
+ launchesProcess: false,
+ accessesNetwork: false,
+ changesUiState: false,
+ mayDiscardData: false,
+ idempotent: true,
+ },
annotations: {
readOnlyHint: true,
destructiveHint: false,
@@ -39,13 +48,8 @@ describe("tool result projection", () => {
expect(JSON.stringify(result)).not.toContain("expected Hopper");
});
it("classifies output contract failures without naming a provider", () => {
- expect(toCallToolResult(ok({ value: 42 }), contract)).toEqual({
- content: [
- {
- type: "text",
- text: "Analysis returned an unreadable result. Retry once; if it continues, run `rea doctor`.",
- },
- ],
+ const result = toCallToolResult(ok({ value: 42 }), contract);
+ expect(result).toMatchObject({
structuredContent: {
error: {
code: "unreadable_output",
@@ -62,6 +66,10 @@ describe("tool result projection", () => {
},
isError: true,
});
+ expect(result.content[0]).toEqual({
+ type: "text",
+ text: JSON.stringify(result.structuredContent),
+ });
});
it("links successful evidence only when its session resource exists", () => {
@@ -77,7 +85,7 @@ describe("tool result projection", () => {
);
const evidenceContract: ToolContract = {
...contract,
- outputSchema: evidenceEnvelopeSchema,
+ outputSchema: evidenceResultOf(z.object({ value: z.string() })),
};
expect(
From b2d1f2affdc7faa0e1c56feefe596eb39dea0612 Mon Sep 17 00:00:00 2001
From: morluto <76467478+morluto@users.noreply.github.com>
Date: Thu, 16 Jul 2026 18:51:05 +0800
Subject: [PATCH 04/19] feat(setup): verify installed skill catalog identity
---
README.md | 6 +-
README_ar.md | 6 +-
README_ja.md | 6 +-
README_ko.md | 6 +-
README_zh.md | 6 +-
docs/architecture.mermaid | 2 +-
docs/mcp-prompts.md | 2 +-
scripts/generate-skill-metadata.mjs | 35 ++++++++++++
scripts/lib/docs-facts.mjs | 37 +++++-------
skills/rea-analysis/SKILL.md | 1 +
src/application/Doctor.ts | 87 +++++++++++++++++++++++++----
tests/doctor.test.ts | 34 ++++++++++-
tests/ghidraDoctor.test.ts | 8 +++
tests/identity.test.ts | 10 +++-
tests/readmeConsistency.test.ts | 35 ++++--------
15 files changed, 203 insertions(+), 78 deletions(-)
create mode 100644 scripts/generate-skill-metadata.mjs
diff --git a/README.md b/README.md
index ac552ed8f..1fc8e6c21 100644
--- a/README.md
+++ b/README.md
@@ -10,11 +10,11 @@
[](https://www.npmjs.com/package/rea-agents)
[](https://github.com/morluto/rea/actions/workflows/ci.yml)
-[](#89-tools-for-investigation)
+[](#tool-catalog-for-investigation)
[](https://nodejs.org/)
[](LICENSE)
-[Quick start](#quick-start) · [Current status](#current-status) · [Investigation model](#the-investigation-model) · [89 tools](#89-tools-for-investigation) · [Roadmap](#roadmap) · [How it works](#how-it-works)
+[Quick start](#quick-start) · [Current status](#current-status) · [Investigation model](#the-investigation-model) · [Tool catalog](#tool-catalog-for-investigation) · [Roadmap](#roadmap) · [How it works](#how-it-works)
@@ -320,7 +320,7 @@ REA handles the app analysis in steps 1–5. The agent performs step 6 with its
- Analyze Swift and Objective-C metadata without manually untangling every mangled symbol.
- Leave names, comments, and bookmarks in Hopper so human and agent analysis reinforce each other.
-## 89 tools for investigation
+## Tool catalog for investigation
| Tool family | Count | Examples |
| ------------------------- | ----: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
diff --git a/README_ar.md b/README_ar.md
index 35715586c..6c693e856 100644
--- a/README_ar.md
+++ b/README_ar.md
@@ -10,11 +10,11 @@
[](https://www.npmjs.com/package/rea-agents)
[](https://github.com/morluto/rea/actions/workflows/ci.yml)
-[](#منصة-من-89-أداة)
+[](#منصة-أدوات-التحقيق)
[](https://nodejs.org/)
[](LICENSE)
-[البدء السريع](#البدء-السريع) · [من الملف التنفيذي إلى السلوك](#من-الملف-التنفيذي-إلى-السلوك) · [89 أداة](#منصة-من-89-أداة) · [كيف يعمل](#كيف-يعمل) · [الأسئلة الشائعة](#الأسئلة-الشائعة)
+[البدء السريع](#البدء-السريع) · [من الملف التنفيذي إلى السلوك](#من-الملف-التنفيذي-إلى-السلوك) · [دليل الأدوات](#منصة-أدوات-التحقيق) · [كيف يعمل](#كيف-يعمل) · [الأسئلة الشائعة](#الأسئلة-الشائعة)
@@ -157,7 +157,7 @@ rea uninstall --purge-data
افحص التحقق من الإدخال، والتشفير، والصلاحيات، والتخزين، ومسارات الأخطاء من دون رفع الملف التنفيذي إلى خدمة بعيدة.
-## منصة من 89 أداة
+## منصة أدوات التحقيق
| عائلة الأدوات | العدد | أمثلة |
| --------------------- | ----: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
diff --git a/README_ja.md b/README_ja.md
index 84405f1bd..a6ddce770 100644
--- a/README_ja.md
+++ b/README_ja.md
@@ -10,11 +10,11 @@
[](https://www.npmjs.com/package/rea-agents)
[](https://github.com/morluto/rea/actions/workflows/ci.yml)
-[](#89-ツールのワークベンチ)
+[](#調査ツールカタログ)
[](https://nodejs.org/)
[](LICENSE)
-[クイックスタート](#クイックスタート) · [バイナリから動作へ](#バイナリから動作へ) · [89 ツール](#89-ツールのワークベンチ) · [仕組み](#仕組み) · [FAQ](#faq)
+[クイックスタート](#クイックスタート) · [バイナリから動作へ](#バイナリから動作へ) · [ツールカタログ](#調査ツールカタログ) · [仕組み](#仕組み) · [FAQ](#faq)
@@ -147,7 +147,7 @@ REA は手順 1〜5 のバイナリ解析を処理し、手順 6 はエージェ
- Swift / Objective-C のメタデータを解析する。
- Hopper に名前、コメント、ブックマークを残し、人間とエージェントの調査を共有する。
-## 89 ツールのワークベンチ
+## 調査ツールカタログ
| ツール群 | 数 | 例 |
| ---------------------- | --: | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
diff --git a/README_ko.md b/README_ko.md
index 5b11f0eef..244f590f3 100644
--- a/README_ko.md
+++ b/README_ko.md
@@ -10,11 +10,11 @@
[](https://www.npmjs.com/package/rea-agents)
[](https://github.com/morluto/rea/actions/workflows/ci.yml)
-[](#89개-도구로-구성된-워크벤치)
+[](#조사-도구-카탈로그)
[](https://nodejs.org/)
[](LICENSE)
-[빠른 시작](#빠른-시작) · [바이너리에서 동작까지](#바이너리에서-동작까지) · [89개 도구](#89개-도구로-구성된-워크벤치) · [작동 방식](#작동-방식) · [FAQ](#faq)
+[빠른 시작](#빠른-시작) · [바이너리에서 동작까지](#바이너리에서-동작까지) · [도구 카탈로그](#조사-도구-카탈로그) · [작동 방식](#작동-방식) · [FAQ](#faq)
@@ -147,7 +147,7 @@ REA는 1–5단계의 바이너리 분석을 처리합니다. 6단계는 에이
- Swift 및 Objective-C 메타데이터를 분석합니다.
- Hopper에 이름, 주석, 북마크를 남겨 사람과 에이전트의 분석을 연결합니다.
-## 89개 도구로 구성된 워크벤치
+## 조사 도구 카탈로그
| 도구 그룹 | 수 | 예시 |
| ------------------- | --: | --------------------------------------------------------------------------------------------------------------------------------------------- |
diff --git a/README_zh.md b/README_zh.md
index 456674d9d..9d30dd0a8 100644
--- a/README_zh.md
+++ b/README_zh.md
@@ -10,11 +10,11 @@
[](https://www.npmjs.com/package/rea-agents)
[](https://github.com/morluto/rea/actions/workflows/ci.yml)
-[](#89-个工具组成的工作台)
+[](#调查工具目录)
[](https://nodejs.org/)
[](LICENSE)
-[快速开始](#快速开始) · [从二进制到行为](#从二进制到行为) · [89 个工具](#89-个工具组成的工作台) · [工作原理](#工作原理) · [常见问题](#常见问题)
+[快速开始](#快速开始) · [从二进制到行为](#从二进制到行为) · [工具目录](#调查工具目录) · [工作原理](#工作原理) · [常见问题](#常见问题)
@@ -147,7 +147,7 @@ REA 负责第 1–5 步中的二进制分析。第 6 步由智能体使用其常
- 分析 Swift 和 Objective-C 元数据。
- 在 Hopper 中留下名称、注释与书签,使人与智能体的分析互相增强。
-## 89 个工具组成的工作台
+## 调查工具目录
| 工具类别 | 数量 | 示例 |
| -------------- | ---: | ------------------------------------------------------------------------------------------------------------------------- |
diff --git a/docs/architecture.mermaid b/docs/architecture.mermaid
index 091fcf491..db6384914 100644
--- a/docs/architecture.mermaid
+++ b/docs/architecture.mermaid
@@ -33,7 +33,7 @@ graph TD
end
subgraph "Contracts Layer"
- CONTRACTS["src/contracts/ Caller-visible tool schemas 86 analysis, managed, browser, Electron, application, and session tools"]
+ CONTRACTS["src/contracts/ Caller-visible schemas for analysis, managed, browser, Electron, application, and session tools"]
end
subgraph "Domain Layer"
diff --git a/docs/mcp-prompts.md b/docs/mcp-prompts.md
index e6349a580..ff2ce7aec 100644
--- a/docs/mcp-prompts.md
+++ b/docs/mcp-prompts.md
@@ -1,7 +1,7 @@
# Guided MCP prompts and completion
REA exposes six provider-neutral investigation workflows through the MCP
-`prompts` capability. They complement the 89 tools; they do not add, remove, or
+`prompts` capability. They complement the generated tool catalog; they do not add, remove, or
invoke tools by themselves.
## Prompt inventory
diff --git a/scripts/generate-skill-metadata.mjs b/scripts/generate-skill-metadata.mjs
new file mode 100644
index 000000000..3c683aca6
--- /dev/null
+++ b/scripts/generate-skill-metadata.mjs
@@ -0,0 +1,35 @@
+import { readFile } from "node:fs/promises";
+import { dirname, join } from "node:path";
+import { fileURLToPath, pathToFileURL } from "node:url";
+
+import { ensureGeneratedFile } from "./lib/generated-file.mjs";
+
+const arguments_ = new Set(process.argv.slice(2));
+for (const argument of arguments_)
+ if (argument !== "--check")
+ throw new Error(`Unknown skill metadata option: ${argument}`);
+
+const root = join(dirname(fileURLToPath(import.meta.url)), "..");
+const path = join(root, "skills/rea-analysis/SKILL.md");
+const current = await readFile(path, "utf8");
+const { CATALOG_IDENTITY } = await import(
+ `${pathToFileURL(join(root, "dist/catalogIdentity.js")).href}?${String(Date.now())}`
+);
+const withCount = current.replace(
+ /^\s{2}tool_count:\s*\d+\s*$/mu,
+ ` tool_count: ${String(CATALOG_IDENTITY.counts.mcp_tools)}`,
+);
+const digestLine = ` catalog_digest: "${CATALOG_IDENTITY.digests.combined_sha256}"`;
+const source = /^\s{2}catalog_digest:/mu.test(withCount)
+ ? withCount.replace(
+ /^\s{2}catalog_digest:\s*"[a-f0-9]{64}"\s*$/mu,
+ digestLine,
+ )
+ : withCount.replace(/^(\s{2}tool_count:\s*\d+\s*)$/mu, `$1\n${digestLine}`);
+
+await ensureGeneratedFile({
+ path,
+ source,
+ check: arguments_.has("--check"),
+ generateCommand: "npm run docs:generate",
+});
diff --git a/scripts/lib/docs-facts.mjs b/scripts/lib/docs-facts.mjs
index 4171544a1..3c14951b2 100644
--- a/scripts/lib/docs-facts.mjs
+++ b/scripts/lib/docs-facts.mjs
@@ -10,26 +10,20 @@ const README_PATHS = [
];
const familyLabel = (id) => (id === "electron" ? "Electron" : id);
-const tableCounts = (content, path, total) => {
+const tableCounts = (content, path, expectedCounts) => {
const lines = content.split(/\r?\n/u);
- const headingIndex = lines.findIndex(
- (line) => line.startsWith("## ") && line.includes(String(total)),
- );
- if (headingIndex === -1) {
- throw new Error(`Missing ${total}-tool heading in ${path}`);
- }
- const counts = [];
- for (const line of lines.slice(headingIndex + 1)) {
- if (line.startsWith("## ")) break;
- if (!line.trim().startsWith("|") || /^\|\s*-/u.test(line)) continue;
- const count = Number(line.split("|")[2]?.trim());
- if (!Number.isInteger(count)) {
- if (counts.length === 0) continue;
- throw new Error(`Non-numeric tool count in ${path}`);
+ for (const [index, line] of lines.entries()) {
+ if (!/^\|\s*-/u.test(line)) continue;
+ const counts = [];
+ for (const row of lines.slice(index + 1)) {
+ if (!row.trim().startsWith("|")) break;
+ const count = Number(row.split("|")[2]?.trim());
+ if (!Number.isInteger(count)) break;
+ counts.push(count);
}
- counts.push(count);
+ if (counts.length === expectedCounts.length) return counts;
}
- return counts;
+ throw new Error(`Missing tool-family inventory table in ${path}`);
};
const requireText = (issues, path, content, expected) => {
@@ -42,16 +36,11 @@ export const documentationFactIssues = async (root, catalog) => {
const expectedCounts = catalog.tools.families.map(({ count }) => count);
for (const path of README_PATHS) {
const content = await readFile(join(root, path), "utf8");
- requireText(
- issues,
- path,
- content,
- `MCP_tools-${String(catalog.tools.total)}`,
- );
+ requireText(issues, path, content, "MCP-tool_catalog");
for (const client of catalog.setup_clients)
requireText(issues, path, content, client.display_name);
try {
- const actualCounts = tableCounts(content, path, catalog.tools.total);
+ const actualCounts = tableCounts(content, path, expectedCounts);
if (JSON.stringify(actualCounts) !== JSON.stringify(expectedCounts))
issues.push(
`${path}: tool family counts ${JSON.stringify(actualCounts)} do not match ${JSON.stringify(expectedCounts)}`,
diff --git a/skills/rea-analysis/SKILL.md b/skills/rea-analysis/SKILL.md
index a82349914..280c2111f 100644
--- a/skills/rea-analysis/SKILL.md
+++ b/skills/rea-analysis/SKILL.md
@@ -4,6 +4,7 @@ description: Reverse engineer native, Electron/JavaScript, and web applications
metadata:
version: "20"
tool_count: 89
+ catalog_digest: "59253c96793f162725d5dc08e611c1e0c19938b23de1e9490dcc1cc800dde955"
---
# REA
diff --git a/src/application/Doctor.ts b/src/application/Doctor.ts
index 1df5b9e7c..4bbfa28c7 100644
--- a/src/application/Doctor.ts
+++ b/src/application/Doctor.ts
@@ -77,10 +77,18 @@ export interface DoctorHost {
providerInspections?(): Promise;
installationPaths?(): Promise;
installedSkillVersion?(): Promise;
+ installedSkillIdentity?(): Promise;
clientRegistrations?(): Promise;
javascriptReplayCheck?(): Promise;
}
+/** Parsed identity committed by an installed REA skill. */
+interface InstalledSkillIdentity {
+ readonly version: string | null;
+ readonly toolCount: number | null;
+ readonly catalogDigest: string | null;
+}
+
/**
* Check requirements and an optional target without mutating the host.
* Every failed check includes remediation suitable for either the one-shot CLI
@@ -109,7 +117,9 @@ export const runDoctor = async (
};
readonly skill: {
readonly installed_version: string | null;
- readonly state: "aligned" | "stale" | "unknown";
+ readonly installed_tool_count: number | null;
+ readonly installed_catalog_digest: string | null;
+ readonly state: "aligned" | "stale" | "missing";
readonly remediation: string | null;
};
readonly registrations: readonly ClientRegistrationStatus[];
@@ -216,7 +226,37 @@ export const runDoctor = async (
}),
);
const installationPaths = (await host.installationPaths?.()) ?? [];
- const installedSkillVersion = await host.installedSkillVersion?.();
+ const observedSkillIdentity = await host.installedSkillIdentity?.();
+ const legacySkillVersion =
+ observedSkillIdentity === undefined
+ ? await host.installedSkillVersion?.()
+ : undefined;
+ const installedSkillIdentity =
+ observedSkillIdentity ??
+ (legacySkillVersion === undefined
+ ? undefined
+ : {
+ version: legacySkillVersion,
+ toolCount: null,
+ catalogDigest: null,
+ });
+ const installedSkillVersion = installedSkillIdentity?.version ?? undefined;
+ const skillAligned =
+ installedSkillIdentity?.version === PRODUCT_IDENTITY.skillVersion &&
+ installedSkillIdentity.toolCount === CATALOG_IDENTITY.counts.mcp_tools &&
+ installedSkillIdentity.catalogDigest ===
+ CATALOG_IDENTITY.digests.combined_sha256;
+ if (!skillAligned)
+ checks.push({
+ name: "skill:identity",
+ ok: false,
+ classification: "config_drift",
+ detail:
+ installedSkillIdentity === undefined
+ ? "Installed REA skill identity is missing."
+ : "Installed REA skill identity is stale.",
+ remediation: "Run rea setup to update the installed REA skill.",
+ });
const registrations = (await host.clientRegistrations?.()) ?? [];
for (const registration of registrations)
if (registration.state !== "aligned")
@@ -263,17 +303,17 @@ export const runDoctor = async (
},
skill: {
installed_version: installedSkillVersion ?? null,
+ installed_tool_count: installedSkillIdentity?.toolCount ?? null,
+ installed_catalog_digest: installedSkillIdentity?.catalogDigest ?? null,
state:
- installedSkillVersion === undefined
- ? "unknown"
- : installedSkillVersion === PRODUCT_IDENTITY.skillVersion
+ installedSkillIdentity === undefined
+ ? "missing"
+ : skillAligned
? "aligned"
: "stale",
- remediation:
- installedSkillVersion === undefined ||
- installedSkillVersion === PRODUCT_IDENTITY.skillVersion
- ? null
- : "Run rea setup to update the installed REA skill.",
+ remediation: skillAligned
+ ? null
+ : "Run rea setup to update the installed REA skill.",
},
registrations,
},
@@ -407,6 +447,33 @@ export const systemDoctorHost = (
return undefined;
}
},
+ async installedSkillIdentity() {
+ try {
+ const content = await readFile(
+ join(
+ homedir(),
+ ".agents/skills",
+ PRODUCT_IDENTITY.skillName,
+ "SKILL.md",
+ ),
+ "utf8",
+ );
+ const version =
+ /^\s{2}version:\s*"([^"]+)"\s*$/mu.exec(content)?.[1] ?? null;
+ const countText = /^\s{2}tool_count:\s*(\d+)\s*$/mu.exec(content)?.[1];
+ const catalogDigest =
+ /^\s{2}catalog_digest:\s*"([a-f0-9]{64})"\s*$/mu.exec(content)?.[1] ??
+ null;
+ return {
+ version,
+ toolCount:
+ countText === undefined ? null : Number.parseInt(countText, 10),
+ catalogDigest,
+ };
+ } catch {
+ return undefined;
+ }
+ },
clientRegistrations: () => readClientRegistrationStatuses(homedir()),
});
diff --git a/tests/doctor.test.ts b/tests/doctor.test.ts
index e7ed68d2c..b949912b0 100644
--- a/tests/doctor.test.ts
+++ b/tests/doctor.test.ts
@@ -1,5 +1,7 @@
import { describe, expect, it } from "vitest";
import { runDoctor, type DoctorHost } from "../src/application/Doctor.js";
+import { CATALOG_IDENTITY } from "../src/catalogIdentity.js";
+import { PRODUCT_IDENTITY } from "../src/identity.js";
const host = (overrides: Partial = {}): DoctorHost => ({
platform: "darwin",
@@ -12,6 +14,12 @@ const host = (overrides: Partial = {}): DoctorHost => ({
linuxDemoRuntimeReady: () => Promise.resolve(true),
brewHopperPath: () => Promise.resolve(undefined),
manualHopperPaths: () => Promise.resolve([]),
+ installedSkillIdentity: () =>
+ Promise.resolve({
+ version: PRODUCT_IDENTITY.skillVersion,
+ toolCount: CATALOG_IDENTITY.counts.mcp_tools,
+ catalogDigest: CATALOG_IDENTITY.digests.combined_sha256,
+ }),
...overrides,
});
@@ -85,7 +93,12 @@ describe("doctor", () => {
host({
installationPaths: () =>
Promise.resolve(["/usr/local/bin/rea", "/home/user/bin/rea"]),
- installedSkillVersion: () => Promise.resolve("10"),
+ installedSkillIdentity: () =>
+ Promise.resolve({
+ version: "10",
+ toolCount: null,
+ catalogDigest: null,
+ }),
}),
);
@@ -99,6 +112,25 @@ describe("doctor", () => {
},
});
});
+ it("reports a missing installed skill as unhealthy", async () => {
+ const result = await runDoctor(
+ undefined,
+ host({ installedSkillIdentity: () => Promise.resolve(undefined) }),
+ );
+
+ expect(result.healthy).toBe(false);
+ expect(result.identity?.skill).toMatchObject({
+ state: "missing",
+ remediation: "Run rea setup to update the installed REA skill.",
+ });
+ expect(result.checks).toContainEqual({
+ name: "skill:identity",
+ ok: false,
+ classification: "config_drift",
+ detail: "Installed REA skill identity is missing.",
+ remediation: "Run rea setup to update the installed REA skill.",
+ });
+ });
it("reports stale client registration paths without claiming live state", async () => {
const result = await runDoctor(
undefined,
diff --git a/tests/ghidraDoctor.test.ts b/tests/ghidraDoctor.test.ts
index 7dd2edc6c..fd798614e 100644
--- a/tests/ghidraDoctor.test.ts
+++ b/tests/ghidraDoctor.test.ts
@@ -7,6 +7,8 @@ import {
type GhidraInstallationInspection,
} from "../src/ghidra/GhidraInstallation.js";
import { projectGhidraDoctorInspection } from "../src/ghidra/GhidraDoctor.js";
+import { CATALOG_IDENTITY } from "../src/catalogIdentity.js";
+import { PRODUCT_IDENTITY } from "../src/identity.js";
const INSTALL = "/opt/ghidra_12.1.2_PUBLIC";
const installationHost = (
@@ -65,6 +67,12 @@ const doctorHost = (
manualHopperPaths: () => Promise.resolve([]),
providerInspections: () =>
Promise.resolve([projectGhidraDoctorInspection(ghidra)]),
+ installedSkillIdentity: () =>
+ Promise.resolve({
+ version: PRODUCT_IDENTITY.skillVersion,
+ toolCount: CATALOG_IDENTITY.counts.mcp_tools,
+ catalogDigest: CATALOG_IDENTITY.digests.combined_sha256,
+ }),
});
describe("Ghidra doctor integration", () => {
diff --git a/tests/identity.test.ts b/tests/identity.test.ts
index 98fca65bd..8243f482a 100644
--- a/tests/identity.test.ts
+++ b/tests/identity.test.ts
@@ -14,7 +14,8 @@ describe("package identity", () => {
scripts: z.object({
start: z.string(),
prepare: z.string(),
- prepack: z.string().optional(),
+ prepack: z.string(),
+ prepublishOnly: z.string(),
}),
})
.parse(
@@ -30,6 +31,11 @@ describe("package identity", () => {
expect(PRODUCT_IDENTITY.mcpCommand).toBe(`npx -y ${packageJson.name} mcp`);
expect(packageJson.scripts.start).toBe("node scripts/rea.mjs mcp");
expect(packageJson.scripts.prepare).toBe("npm run build && husky");
- expect(packageJson.scripts.prepack).toBeUndefined();
+ expect(packageJson.scripts.prepack).toBe(
+ "npm run deps:check && node scripts/generate-skill-metadata.mjs --check",
+ );
+ expect(packageJson.scripts.prepublishOnly).toBe(
+ "npm run deps:check && node scripts/generate-skill-metadata.mjs --check",
+ );
});
});
diff --git a/tests/readmeConsistency.test.ts b/tests/readmeConsistency.test.ts
index 12af7244e..ce0a56c8d 100644
--- a/tests/readmeConsistency.test.ts
+++ b/tests/readmeConsistency.test.ts
@@ -6,7 +6,6 @@ import {
ENHANCED_TOOL_CONTRACTS,
OFFICIAL_TOOL_CONTRACTS,
SESSION_TOOL_CONTRACTS,
- TOOL_CONTRACTS,
} from "../src/contracts/toolContracts.js";
import { NATIVE_TOOL_CONTRACTS } from "../src/contracts/nativeToolContracts.js";
import { ARTIFACT_TOOL_CONTRACTS } from "../src/contracts/artifactToolContracts.js";
@@ -39,30 +38,18 @@ const expectedToolCounts = [
const toolCountsFromReadme = (content: string, path: string): number[] => {
const lines = content.split(/\r?\n/u);
- const headingIndex = lines.findIndex((line) =>
- new RegExp(`^## .*${String(TOOL_CONTRACTS.length)}`, "u").test(line),
- );
- if (headingIndex === -1)
- throw new Error(
- `Missing ${String(TOOL_CONTRACTS.length)}-tool heading in ${path}`,
- );
-
- const counts: number[] = [];
- for (const line of lines.slice(headingIndex + 1)) {
- if (line.startsWith("## ")) break;
- if (!line.trim().startsWith("|") || /^\|\s*-/.test(line)) continue;
- const cells = line.split("|").map((cell) => cell.trim());
- const countCell = cells[2];
- if (countCell === undefined)
- throw new Error(`Malformed table row in ${path}`);
- const count = Number(countCell);
- if (!Number.isInteger(count)) {
- if (counts.length === 0) continue;
- throw new Error(`Non-numeric tool count in ${path}`);
+ for (const [index, line] of lines.entries()) {
+ if (!/^\|\s*-/u.test(line)) continue;
+ const counts: number[] = [];
+ for (const row of lines.slice(index + 1)) {
+ if (!row.trim().startsWith("|")) break;
+ const count = Number(row.split("|")[2]?.trim());
+ if (!Number.isInteger(count)) break;
+ counts.push(count);
}
- counts.push(count);
+ if (counts.length === expectedToolCounts.length) return counts;
}
- return counts;
+ throw new Error(`Missing tool-family inventory table in ${path}`);
};
describe("localized README product facts", () => {
@@ -87,7 +74,7 @@ describe("localized README product facts", () => {
expect(content).toContain(client.displayName);
if (path === "README_ar.md")
expect(content).toContain("Windows غير مدعوم حاليًا");
- expect(content).toContain(`MCP_tools-${String(TOOL_CONTRACTS.length)}`);
+ expect(content).toContain("MCP-tool_catalog");
expect(toolCountsFromReadme(content, path)).toEqual(expectedToolCounts);
},
);
From f23f52903cb6df4eed6fec0e09f79c82ad9825dc Mon Sep 17 00:00:00 2001
From: morluto <76467478+morluto@users.noreply.github.com>
Date: Thu, 16 Jul 2026 18:51:14 +0800
Subject: [PATCH 05/19] fix(test): make host fixtures portable
---
src/application/ProcessSampling.ts | 30 +++++++++++++++----------
src/ghidra/GhidraInstallation.ts | 2 ++
src/ghidra/GhidraProvider.ts | 6 +++++
tests/ghidraMcp.test.ts | 32 ++++++++++++++++++++++-----
tests/ghidraProvider.test.ts | 2 ++
tests/installScript.test.ts | 2 +-
tests/nativeDmgArtifactReader.test.ts | 2 +-
tests/nativeProvider.test.ts | 2 +-
tests/permissionMcp.test.ts | 7 ++++--
tests/processCapture.test.ts | 9 ++++++++
vitest.config.ts | 3 +++
11 files changed, 74 insertions(+), 23 deletions(-)
diff --git a/src/application/ProcessSampling.ts b/src/application/ProcessSampling.ts
index 5f2a07289..fe5f51a21 100644
--- a/src/application/ProcessSampling.ts
+++ b/src/application/ProcessSampling.ts
@@ -40,16 +40,22 @@ export const isInitializedPtyRoot = (options: {
readonly before: ProcessIdentitySnapshot;
readonly observedRunId: string | undefined;
readonly after: ProcessIdentitySnapshot;
-}): boolean =>
- options.before.pid === options.rootPid &&
- options.before.process_group_id === options.rootPid &&
- options.before.session_id === options.rootPid &&
- options.after.pid === options.rootPid &&
- options.after.parent_pid === options.before.parent_pid &&
- options.after.process_group_id === options.rootPid &&
- options.after.session_id === options.rootPid &&
- options.after.startTime === options.before.startTime &&
- options.observedRunId === options.expectedRunId;
+}): boolean => {
+ const sessionIdentityMatches =
+ (options.before.session_id === options.rootPid &&
+ options.after.session_id === options.rootPid) ||
+ (options.before.session_id === null && options.after.session_id === null);
+ return (
+ options.before.pid === options.rootPid &&
+ options.before.process_group_id === options.rootPid &&
+ sessionIdentityMatches &&
+ options.after.pid === options.rootPid &&
+ options.after.parent_pid === options.before.parent_pid &&
+ options.after.process_group_id === options.rootPid &&
+ options.after.startTime === options.before.startTime &&
+ options.observedRunId === options.expectedRunId
+ );
+};
const isExpectedProcReadFailure = (cause: unknown): boolean =>
cause instanceof Error &&
@@ -315,7 +321,7 @@ const readPsRows = async (
pid: Number(match[1]),
parent_pid: Number(match[2]),
process_group_id: Number(match[3]),
- session_id: Number(match[4]),
+ session_id: Number(match[4]) || null,
command: match[5] ?? "",
startTime: undefined,
}))
@@ -346,7 +352,7 @@ const inspectInitializedPtyRoot = async (
if (
before === undefined ||
before.process_group_id !== rootPid ||
- before.session_id !== rootPid
+ (before.session_id !== rootPid && before.session_id !== null)
)
return undefined;
let observedRunId: string | undefined;
diff --git a/src/ghidra/GhidraInstallation.ts b/src/ghidra/GhidraInstallation.ts
index e10d74a69..f71c465f8 100644
--- a/src/ghidra/GhidraInstallation.ts
+++ b/src/ghidra/GhidraInstallation.ts
@@ -63,6 +63,8 @@ export interface GhidraJavaObservation {
/** Narrow synchronous seam used by provider discovery without launching Ghidra. */
export interface GhidraInstallationHost {
+ readonly platform?: NodeJS.Platform;
+ readonly architecture?: NodeJS.Architecture;
readText(path: string): string | undefined;
executable(path: string): boolean;
probeJava(
diff --git a/src/ghidra/GhidraProvider.ts b/src/ghidra/GhidraProvider.ts
index c9efc666b..5bc699391 100644
--- a/src/ghidra/GhidraProvider.ts
+++ b/src/ghidra/GhidraProvider.ts
@@ -415,6 +415,12 @@ export class GhidraProvider implements AnalysisProviderCandidate {
...(this.config.ghidraJavaHome === undefined
? {}
: { javaHome: this.config.ghidraJavaHome }),
+ ...(this.installationHost?.platform === undefined
+ ? {}
+ : { platform: this.installationHost.platform }),
+ ...(this.installationHost?.architecture === undefined
+ ? {}
+ : { architecture: this.installationHost.architecture }),
};
this.#installation ??=
this.installationHost === undefined
diff --git a/tests/ghidraMcp.test.ts b/tests/ghidraMcp.test.ts
index a825640ea..30d665f44 100644
--- a/tests/ghidraMcp.test.ts
+++ b/tests/ghidraMcp.test.ts
@@ -6,7 +6,6 @@ import { EnhancedTools } from "../src/application/EnhancedTools.js";
import { AnalysisProviderRegistry } from "../src/application/AnalysisProviderRegistry.js";
import { SessionProviderRouter } from "../src/application/SessionProviderRouter.js";
import { parseConfig } from "../src/config.js";
-import { parseEvidence } from "../src/domain/evidence.js";
import type { JsonValue } from "../src/domain/jsonValue.js";
import { ok } from "../src/domain/result.js";
import type { GhidraInstallationHost } from "../src/ghidra/GhidraInstallation.js";
@@ -67,7 +66,8 @@ describe("Ghidra MCP and shared CLI composition", () => {
});
expect(opened.isError).not.toBe(true);
- const listed = parseEvidence(
+ const listed = sessionEvidence(
+ session,
(
await mcp.callTool({
name: "list_procedures",
@@ -104,7 +104,8 @@ describe("Ghidra MCP and shared CLI composition", () => {
},
});
- const mcpOverview = parseEvidence(
+ const mcpOverview = sessionEvidence(
+ session,
(
await mcp.callTool({
name: "binary_overview",
@@ -131,7 +132,8 @@ describe("Ghidra MCP and shared CLI composition", () => {
},
});
- const pseudocode = parseEvidence(
+ const pseudocode = sessionEvidence(
+ session,
(
await mcp.callTool({
name: "procedure_pseudo_code",
@@ -149,7 +151,8 @@ describe("Ghidra MCP and shared CLI composition", () => {
]),
});
- const analyzed = parseEvidence(
+ const analyzed = sessionEvidence(
+ session,
(
await mcp.callTool({
name: "analyze_function",
@@ -206,7 +209,7 @@ describe("Ghidra MCP and shared CLI composition", () => {
});
expect(batch.isError).not.toBe(true);
expect(batch.structuredContent).toMatchObject({
- normalized_result: {
+ result: {
succeeded: 1,
failed: 0,
items: [{ status: "ok" }],
@@ -269,7 +272,24 @@ describe("Ghidra MCP and shared CLI composition", () => {
});
});
+const sessionEvidence = (session: BinarySession, value: unknown) => {
+ if (
+ typeof value !== "object" ||
+ value === null ||
+ !("evidence_id" in value) ||
+ typeof value.evidence_id !== "string"
+ )
+ throw new TypeError(
+ `Missing compact Evidence ID: ${JSON.stringify(value)}`,
+ );
+ const evidence = session.evidenceById(value.evidence_id);
+ if (evidence === undefined) throw new TypeError("Missing session Evidence");
+ return evidence;
+};
+
const installationHost = (): GhidraInstallationHost => ({
+ platform: "linux",
+ architecture: "x64",
readText: () => "application.version=12.1.2\n",
executable: () => true,
probeJava: () => ({
diff --git a/tests/ghidraProvider.test.ts b/tests/ghidraProvider.test.ts
index 4e81fcb9f..1b32487bf 100644
--- a/tests/ghidraProvider.test.ts
+++ b/tests/ghidraProvider.test.ts
@@ -16,6 +16,8 @@ import { silentLogger } from "../src/logger.js";
const INSTALL = "/opt/ghidra_12.1.2_PUBLIC";
const installationHost = (): GhidraInstallationHost => ({
+ platform: "linux",
+ architecture: "x64",
readText: () => "application.version=12.1.2\n",
executable: () => true,
probeJava: () => ({
diff --git a/tests/installScript.test.ts b/tests/installScript.test.ts
index b1b182ec9..db7aa4b01 100644
--- a/tests/installScript.test.ts
+++ b/tests/installScript.test.ts
@@ -24,7 +24,7 @@ afterEach(async () => {
);
});
-describe("curl installer scenarios", () => {
+describe("curl installer scenarios", { timeout: 20_000 }, () => {
it("installs only a pinned REA CLI with closed stdin", async () => {
const fixture = await createFixture();
const result = await runInstaller(fixture, ["--version", "0.3.0"]);
diff --git a/tests/nativeDmgArtifactReader.test.ts b/tests/nativeDmgArtifactReader.test.ts
index 8959f4fc3..73cc1e50f 100644
--- a/tests/nativeDmgArtifactReader.test.ts
+++ b/tests/nativeDmgArtifactReader.test.ts
@@ -44,7 +44,7 @@ describe("native DMG artifact reader", () => {
const provenance = reader.provenance();
if (provenance[0] !== undefined)
Reflect.set(provenance[0], "tool", "forged");
- expect(reader.provenance()[0]?.tool).toBe("hdiutil");
+ expect(reader.provenance()[0]?.tool).toBe("/usr/bin/hdiutil");
await reader.close();
expect(calls).toContainEqual(["verify", "/tmp/image.dmg"]);
expect(calls).toContainEqual(["detach", "/dev/disk-fixture"]);
diff --git a/tests/nativeProvider.test.ts b/tests/nativeProvider.test.ts
index c54916727..fecb0ae6d 100644
--- a/tests/nativeProvider.test.ts
+++ b/tests/nativeProvider.test.ts
@@ -30,7 +30,7 @@ describe("native macOS provider", () => {
return Promise.resolve(
resolutions === 1
? err(new NativeCommandFailure(tool, "unavailable"))
- : ok({ path: "/bin/true", sha256: "a".repeat(64) }),
+ : ok({ path: "/usr/bin/true", sha256: "a".repeat(64) }),
);
});
const options = { timeoutMs: 1_000, maxOutputBytes: 1_024 };
diff --git a/tests/permissionMcp.test.ts b/tests/permissionMcp.test.ts
index 012de05d1..698404acb 100644
--- a/tests/permissionMcp.test.ts
+++ b/tests/permissionMcp.test.ts
@@ -1,4 +1,6 @@
import { Client, InMemoryTransport } from "@modelcontextprotocol/client";
+import { realpath } from "node:fs/promises";
+import { join } from "node:path";
import { describe, expect, it } from "vitest";
import type { AnalysisOperationPort } from "../src/application/AnalysisProvider.js";
@@ -8,6 +10,7 @@ import { createServer } from "../src/server/createServer.js";
describe("MCP permission preflight", () => {
it("denies extraction before dispatch and returns exact typed remediation", async () => {
+ const outputRoot = join(await realpath("/tmp"), "rea-permission-denied");
let dispatches = 0;
const analysis: AnalysisOperationPort = {
execute: () => {
@@ -28,7 +31,7 @@ describe("MCP permission preflight", () => {
name: "extract_artifact",
arguments: {
approved: true,
- output_root: "/tmp/rea-permission-denied",
+ output_root: outputRoot,
occurrence_ids: [`occ_${"0".repeat(64)}`],
},
});
@@ -41,7 +44,7 @@ describe("MCP permission preflight", () => {
code: "permission_required",
details: {
capability: "artifact_extract",
- missing: { roots: ["/tmp/rea-permission-denied"] },
+ missing: { roots: [outputRoot] },
},
remediation: {
restart_required: false,
diff --git a/tests/processCapture.test.ts b/tests/processCapture.test.ts
index 5d64a20e6..73808b0b8 100644
--- a/tests/processCapture.test.ts
+++ b/tests/processCapture.test.ts
@@ -249,6 +249,15 @@ describe("process capture domain", () => {
after: initialized,
}),
).toBe(true);
+ expect(
+ isInitializedPtyRoot({
+ rootPid: 100,
+ expectedRunId: "run-token",
+ before: { ...initialized, session_id: null },
+ observedRunId: "run-token",
+ after: { ...initialized, session_id: null },
+ }),
+ ).toBe(true);
});
it("keeps interaction and shim residual uncertainty in separate scopes", () => {
diff --git a/vitest.config.ts b/vitest.config.ts
index 10acb3978..a71b18fdc 100644
--- a/vitest.config.ts
+++ b/vitest.config.ts
@@ -1,3 +1,4 @@
+import { realpathSync } from "node:fs";
import { availableParallelism, tmpdir } from "node:os";
import { join } from "node:path";
@@ -5,6 +6,7 @@ import { defineConfig } from "vitest/config";
const TEST_FILES = ["tests/**/*.test.ts"];
const PROCESS_CAPTURE_TEST = "tests/processCapture.test.ts";
+const CANONICAL_TEMPORARY_DIRECTORY = realpathSync(tmpdir());
const SERIAL_INTEGRATION_TESTS = [
"tests/browserCli.test.ts",
"tests/cliOutput.test.ts",
@@ -37,6 +39,7 @@ const dualCoreProjects =
export default defineConfig({
test: {
include: TEST_FILES,
+ env: { TMPDIR: CANONICAL_TEMPORARY_DIRECTORY },
...dualCoreProjects,
retry: 2,
reporters: ["default", "verbose"],
From 8a1c128b67ee41ce054fe984946a5d7bfcc1a3b4 Mon Sep 17 00:00:00 2001
From: morluto <76467478+morluto@users.noreply.github.com>
Date: Thu, 16 Jul 2026 18:55:41 +0800
Subject: [PATCH 06/19] fix(deps): run freshness check from escaped paths
---
scripts/check-dependency-install.mjs | 3 ++-
tests/dependencyInstall.test.ts | 18 +++++++++++++++++-
2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/scripts/check-dependency-install.mjs b/scripts/check-dependency-install.mjs
index e3b9fbffd..dcdbd64dd 100644
--- a/scripts/check-dependency-install.mjs
+++ b/scripts/check-dependency-install.mjs
@@ -1,5 +1,6 @@
import { readFile } from "node:fs/promises";
import { resolve } from "node:path";
+import { fileURLToPath } from "node:url";
const REMEDIATION = "Run `npm ci`, then retry.";
@@ -57,4 +58,4 @@ const main = async () => {
}
};
-if (process.argv[1] === new URL(import.meta.url).pathname) await main();
+if (process.argv[1] === fileURLToPath(import.meta.url)) await main();
diff --git a/tests/dependencyInstall.test.ts b/tests/dependencyInstall.test.ts
index 46e6da91e..ad3a85cfd 100644
--- a/tests/dependencyInstall.test.ts
+++ b/tests/dependencyInstall.test.ts
@@ -1,4 +1,4 @@
-import { mkdtemp, mkdir, rm, writeFile } from "node:fs/promises";
+import { copyFile, mkdtemp, mkdir, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { spawnSync } from "node:child_process";
@@ -79,4 +79,20 @@ describe("dependency install freshness", () => {
);
expect(result.stderr.match(/npm ci/gu)).toHaveLength(1);
});
+
+ it("runs from a script path containing URL-escaped characters", async () => {
+ const root = await fixture("0.9.0");
+ const scriptDirectory = join(root, "path with spaces");
+ const copiedScript = join(scriptDirectory, "check-dependency-install.mjs");
+ await mkdir(scriptDirectory);
+ await copyFile(script, copiedScript);
+
+ const result = spawnSync(process.execPath, [copiedScript], {
+ cwd: root,
+ encoding: "utf8",
+ });
+
+ expect(result.status).toBe(1);
+ expect(result.stderr).toContain("alpha: installed 0.9.0, expected 1.0.0");
+ });
});
From d1e72207f48609e3214a66c2a248c70a2a1abd6c Mon Sep 17 00:00:00 2001
From: morluto <76467478+morluto@users.noreply.github.com>
Date: Thu, 16 Jul 2026 19:01:35 +0800
Subject: [PATCH 07/19] fix(mcp): align runtime unknown argument validation
---
src/server/toolInputValidation.ts | 3 ++-
src/server/toolRegistrationOptions.ts | 3 ++-
tests/enhancedTools.test.ts | 22 ++++++++++++++++++++++
3 files changed, 26 insertions(+), 2 deletions(-)
diff --git a/src/server/toolInputValidation.ts b/src/server/toolInputValidation.ts
index ef29abc76..f8973dc62 100644
--- a/src/server/toolInputValidation.ts
+++ b/src/server/toolInputValidation.ts
@@ -6,6 +6,7 @@ import {
} from "../domain/errors.js";
import { projectInputIssues } from "../domain/inputIssueProjection.js";
import { err, ok, type Result } from "../domain/result.js";
+import { closeObjectSchemas } from "./toolRegistrationOptions.js";
/** Parse one MCP request exactly once and retain only schema-owned correction data. */
export const safeParseToolInput = (
@@ -41,7 +42,7 @@ const unknownArgumentIssues = (
throw new TypeError(
"Tool input schema does not expose Standard JSON Schema",
);
- jsonSchema = converter({ target: "draft-2020-12" });
+ jsonSchema = closeObjectSchemas(converter({ target: "draft-2020-12" }));
schemaCache.set(schema, jsonSchema);
}
return scanUnknownArguments(input, jsonSchema, jsonSchema, []);
diff --git a/src/server/toolRegistrationOptions.ts b/src/server/toolRegistrationOptions.ts
index 2552c3241..f5d6616f3 100644
--- a/src/server/toolRegistrationOptions.ts
+++ b/src/server/toolRegistrationOptions.ts
@@ -67,7 +67,8 @@ const inputJsonSchema = (schema: z.ZodObject): Record => {
return converter({ target: "draft-2020-12" });
};
-const closeObjectSchemas = (
+/** Close fixed-shape JSON Schema objects while preserving explicit maps. */
+export const closeObjectSchemas = (
value: Readonly>,
): Record => {
const closed = Object.fromEntries(
diff --git a/tests/enhancedTools.test.ts b/tests/enhancedTools.test.ts
index 06dc20cf7..3899b6a57 100644
--- a/tests/enhancedTools.test.ts
+++ b/tests/enhancedTools.test.ts
@@ -629,6 +629,28 @@ describe("enhanced MCP tools", () => {
},
},
});
+ const nestedMisspelled = await client.callTool({
+ name: "analyze_function",
+ arguments: {
+ procedure: "0x1",
+ collection_offset: { commentz: 1 },
+ },
+ });
+ expect(nestedMisspelled).toMatchObject({
+ isError: true,
+ structuredContent: {
+ error: {
+ details: {
+ issues: [
+ {
+ path: ["collection_offset", "commentz"],
+ reason: "unknown_argument",
+ },
+ ],
+ },
+ },
+ },
+ });
const bounded = await client.callTool({
name: "trace_feature",
arguments: { query: "needle", max_operations: 101 },
From 37c0f399544c9424c55e468d6784da61426a458e Mon Sep 17 00:00:00 2001
From: morluto <76467478+morluto@users.noreply.github.com>
Date: Thu, 16 Jul 2026 19:16:04 +0800
Subject: [PATCH 08/19] fix(mcp): parse adapter inputs exactly once
---
src/application/CrossVersionInvestigation.ts | 24 ++--
src/application/EnhancedTools.ts | 64 +++++++--
.../JavaScriptApplicationService.ts | 25 ++--
.../JavaScriptApplicationWorkflowService.ts | 44 +++++--
src/application/JavaScriptReplayService.ts | 33 +++--
.../JavaScriptRuntimeReconciliationService.ts | 13 +-
src/server/registerApplicationTools.ts | 13 +-
src/server/registerElectronTools.ts | 19 ++-
src/server/registerEnhancedTools.ts | 123 ++++++++++++++++--
src/server/registerInvestigationTools.ts | 4 +-
tests/enhancedTools.test.ts | 15 ++-
11 files changed, 288 insertions(+), 89 deletions(-)
diff --git a/src/application/CrossVersionInvestigation.ts b/src/application/CrossVersionInvestigation.ts
index 19b43056f..1db251793 100644
--- a/src/application/CrossVersionInvestigation.ts
+++ b/src/application/CrossVersionInvestigation.ts
@@ -72,20 +72,26 @@ export const runCrossVersionInvestigation = async (
cause: parsed.error,
}),
);
+ return runCrossVersionInvestigationValidated(parsed.data, policy, execution);
+};
+
+/** Run input already parsed by a trusted adapter boundary. */
+export const runCrossVersionInvestigationValidated = async (
+ input: CrossVersionInvestigationInput,
+ policy: EvidenceFilePolicy,
+ execution: CrossVersionInvestigationExecution,
+): Promise> => {
const initial = await readInvestigationWorkspace(
- parsed.data.workspace_path,
+ input.workspace_path,
policy,
);
if (!initial.ok) return initial;
- const preflight = validateWorkspaceRequest(initial.value, parsed.data);
+ const preflight = validateWorkspaceRequest(initial.value, input);
if (!preflight.ok) return preflight;
if (isCancelled(execution.signal))
return err(new AnalysisCancelledError("find_changed_behavior"));
- if (parsed.data.replay_run_id !== undefined) {
- const replay = selectCompletedInvestigationReplay(
- initial.value,
- parsed.data,
- );
+ if (input.replay_run_id !== undefined) {
+ const replay = selectCompletedInvestigationReplay(initial.value, input);
if (!replay.ok) return replay;
return completeOutcome(
replay.value.workspace,
@@ -106,7 +112,7 @@ export const runCrossVersionInvestigation = async (
});
const snapshots = await scanVersions(
- parsed.data,
+ input,
execution.inputRoots,
execution.signal,
execution.integrityContinueEnabled,
@@ -119,7 +125,7 @@ export const runCrossVersionInvestigation = async (
message: "Version inputs scanned",
});
return continueInvestigation({
- input: parsed.data,
+ input,
initial: initial.value,
snapshots: snapshots.value,
policy,
diff --git a/src/application/EnhancedTools.ts b/src/application/EnhancedTools.ts
index a481760de..6c7bbf631 100644
--- a/src/application/EnhancedTools.ts
+++ b/src/application/EnhancedTools.ts
@@ -2,6 +2,7 @@ import type {
AnalysisOperation,
AnalysisOperationPort,
} from "./AnalysisProvider.js";
+import type { z } from "zod";
import type { EnhancedToolName } from "../contracts/enhancedInputs.js";
import { enhancedInputSchemas } from "../contracts/enhancedInputs.js";
import {
@@ -37,15 +38,23 @@ type TraceReference = {
containing_procedure: JsonValue;
};
+/** One enhanced call whose input was parsed at its owning adapter boundary. */
+export type ValidatedEnhancedCall = {
+ [Name in EnhancedToolName]: {
+ readonly name: Name;
+ readonly input: z.output<(typeof enhancedInputSchemas)[Name]>;
+ };
+}[EnhancedToolName];
+
/**
* Composes direct provider operations into bounded reverse-engineering tools.
- * Inputs are parsed again at this application boundary even though MCP normally
- * validates them, allowing direct callers to use the same service safely.
+ * Direct callers use `execute`; adapters that own validation use
+ * `executeValidated` so an MCP input is parsed exactly once.
*/
export class EnhancedTools {
constructor(private readonly analysis: AnalysisOperationPort) {}
- /** Parse inputs again at the direct-call boundary, then dispatch exhaustively. */
+ /** Parse an untrusted direct-call input once, then dispatch exhaustively. */
execute(
name: EnhancedToolName,
input: unknown,
@@ -55,58 +64,87 @@ export class EnhancedTools {
case "swift_classes": {
const parsed = enhancedInputSchemas.swift_classes.safeParse(input);
return parsed.success
- ? this.#swiftClasses(parsed.data.pattern, signal)
+ ? this.executeValidated({ name, input: parsed.data }, signal)
: invalidInput(name, parsed.error);
}
case "get_objc_classes": {
const parsed = enhancedInputSchemas.get_objc_classes.safeParse(input);
return parsed.success
- ? this.#objcClasses(parsed.data.pattern, signal)
+ ? this.executeValidated({ name, input: parsed.data }, signal)
: invalidInput(name, parsed.error);
}
case "get_objc_protocols":
- return this.#objcProtocols(signal);
+ return this.executeValidated({ name, input: {} }, signal);
case "batch_decompile": {
const parsed = enhancedInputSchemas.batch_decompile.safeParse(input);
return parsed.success
- ? this.#batchDecompile(parsed.data.addresses, signal)
+ ? this.executeValidated({ name, input: parsed.data }, signal)
: invalidInput(name, parsed.error);
}
case "get_call_graph": {
const parsed = enhancedInputSchemas.get_call_graph.safeParse(input);
return parsed.success
- ? this.#callGraph(parsed.data, signal)
+ ? this.executeValidated({ name, input: parsed.data }, signal)
: invalidInput(name, parsed.error);
}
case "analyze_swift_types":
- return this.#analyzeSwiftTypes(signal);
+ return this.executeValidated({ name, input: {} }, signal);
case "find_xrefs_to_name": {
const parsed = enhancedInputSchemas.find_xrefs_to_name.safeParse(input);
return parsed.success
- ? this.#findXrefs(parsed.data.name, signal)
+ ? this.executeValidated({ name, input: parsed.data }, signal)
: invalidInput(name, parsed.error);
}
case "binary_overview": {
const parsed = enhancedInputSchemas.binary_overview.safeParse(input);
return parsed.success
- ? this.#binaryOverview(parsed.data, signal)
+ ? this.executeValidated({ name, input: parsed.data }, signal)
: invalidInput(name, parsed.error);
}
case "analyze_function": {
const parsed = enhancedInputSchemas.analyze_function.safeParse(input);
return parsed.success
- ? this.#analyzeFunction(parsed.data, signal)
+ ? this.executeValidated({ name, input: parsed.data }, signal)
: invalidInput(name, parsed.error);
}
case "trace_feature": {
const parsed = enhancedInputSchemas.trace_feature.safeParse(input);
return parsed.success
- ? this.#traceFeature(parsed.data, signal)
+ ? this.executeValidated({ name, input: parsed.data }, signal)
: invalidInput(name, parsed.error);
}
}
}
+ /** Dispatch input already parsed by a trusted adapter boundary. */
+ executeValidated(
+ call: ValidatedEnhancedCall,
+ signal?: AbortSignal,
+ ): EnhancedResult {
+ switch (call.name) {
+ case "swift_classes":
+ return this.#swiftClasses(call.input.pattern, signal);
+ case "get_objc_classes":
+ return this.#objcClasses(call.input.pattern, signal);
+ case "get_objc_protocols":
+ return this.#objcProtocols(signal);
+ case "batch_decompile":
+ return this.#batchDecompile(call.input.addresses, signal);
+ case "get_call_graph":
+ return this.#callGraph(call.input, signal);
+ case "analyze_swift_types":
+ return this.#analyzeSwiftTypes(signal);
+ case "find_xrefs_to_name":
+ return this.#findXrefs(call.input.name, signal);
+ case "binary_overview":
+ return this.#binaryOverview(call.input, signal);
+ case "analyze_function":
+ return this.#analyzeFunction(call.input, signal);
+ case "trace_feature":
+ return this.#traceFeature(call.input, signal);
+ }
+ }
+
async #analyzeFunction(
input: Readonly>,
signal?: AbortSignal,
diff --git a/src/application/JavaScriptApplicationService.ts b/src/application/JavaScriptApplicationService.ts
index c33d2825d..7e78e82c1 100644
--- a/src/application/JavaScriptApplicationService.ts
+++ b/src/application/JavaScriptApplicationService.ts
@@ -30,6 +30,15 @@ export const analyzeJavaScriptApplication = async (
): Promise> => {
const parsed = analyzeJavaScriptApplicationInputSchema.safeParse(rawInput);
if (!parsed.success) return err(new AnalysisInputError(OPERATION));
+ return analyzeJavaScriptApplicationValidated(authority, parsed.data, options);
+};
+
+/** Analyze input already parsed by a trusted adapter boundary. */
+export const analyzeJavaScriptApplicationValidated = async (
+ authority: PermissionAuthority | undefined,
+ input: z.output,
+ options: ExecutionOptions = {},
+): Promise> => {
if (authority === undefined)
return err(
new AnalysisCapabilityUnavailableError(
@@ -41,12 +50,12 @@ export const analyzeJavaScriptApplication = async (
const authorized = await authority.authorize(
{
capability: "investigation_input",
- roots: [parsed.data.input_path],
+ roots: [input.input_path],
executables: [],
environment_names: [],
network: "none",
mount: false,
- operation_identity: `${OPERATION}:${parsed.data.input_path}`,
+ operation_identity: `${OPERATION}:${input.input_path}`,
},
"read",
);
@@ -55,7 +64,7 @@ export const analyzeJavaScriptApplication = async (
authorized.error instanceof PermissionRequiredError
? authorized.error
: new ArtifactOperationError(OPERATION, "path", {
- logicalPath: parsed.data.input_path,
+ logicalPath: input.input_path,
declaredSha256: null,
calculatedSha256: null,
unpacked: false,
@@ -70,10 +79,10 @@ export const analyzeJavaScriptApplication = async (
try {
const reconstructed = await reconstructJavaScriptArtifact(
{
- input_path: parsed.data.input_path,
- format: parsed.data.format,
- source_map_read_approved: parsed.data.source_map_read_approved,
- limits: parsed.data.limits,
+ input_path: input.input_path,
+ format: input.format,
+ source_map_read_approved: input.source_map_read_approved,
+ limits: input.limits,
},
options.signal,
);
@@ -91,7 +100,7 @@ export const analyzeJavaScriptApplication = async (
message: "Application graph and Electron boundaries reconstructed",
terminal: true,
});
- return ok(createJavaScriptApplicationEvidence(parsed.data, result));
+ return ok(createJavaScriptApplicationEvidence(input, result));
} catch (cause: unknown) {
if (cause instanceof ArtifactReaderFailure)
return err(
diff --git a/src/application/JavaScriptApplicationWorkflowService.ts b/src/application/JavaScriptApplicationWorkflowService.ts
index f1e6d36cd..2f2da0db1 100644
--- a/src/application/JavaScriptApplicationWorkflowService.ts
+++ b/src/application/JavaScriptApplicationWorkflowService.ts
@@ -35,27 +35,35 @@ export const traceApplicationFeatureEvidence = (
projectInputIssues(parsed.error.issues, rawInput),
),
);
+ return traceApplicationFeatureEvidenceValidated(parsed.data);
+};
+
+/** Derive one feature trace from input parsed by a trusted adapter. */
+export const traceApplicationFeatureEvidenceValidated = (
+ input: z.output,
+): Result => {
+ const operation = "trace_application_feature";
try {
- const source = parseApplicationGraphEvidence(parsed.data.application);
+ const source = parseApplicationGraphEvidence(input.application);
const nativeEvidence = parseNativeApplicationEvidence(
- parsed.data.native_observations,
+ input.native_observations,
);
const result = traceApplicationFeature({
sourceEvidenceId: source.evidence.evidence_id,
graph: source.graph,
nativeEvidence,
- seed: parsed.data.seed,
- direction: parsed.data.direction,
- limits: parsed.data.limits,
+ seed: input.seed,
+ direction: input.direction,
+ limits: input.limits,
});
return ok(
createApplicationFeatureTraceEvidence(
{
application_evidence_id: source.evidence.evidence_id,
native_evidence_ids: nativeEvidence.map(({ evidence_id: id }) => id),
- seed: parsed.data.seed,
- direction: parsed.data.direction,
- limits: parsed.data.limits,
+ seed: input.seed,
+ direction: input.direction,
+ limits: input.limits,
},
result,
),
@@ -79,14 +87,22 @@ export const compareApplicationVersionsEvidence = (
projectInputIssues(parsed.error.issues, rawInput),
),
);
+ return compareApplicationVersionsEvidenceValidated(parsed.data);
+};
+
+/** Compare versions from input parsed by a trusted adapter. */
+export const compareApplicationVersionsEvidenceValidated = (
+ input: z.output,
+): Result => {
+ const operation = "compare_application_versions";
try {
- const left = parseApplicationGraphEvidence(parsed.data.left);
- const right = parseApplicationGraphEvidence(parsed.data.right);
+ const left = parseApplicationGraphEvidence(input.left);
+ const right = parseApplicationGraphEvidence(input.right);
const leftNative = parseNativeApplicationEvidence(
- parsed.data.left_native_observations,
+ input.left_native_observations,
);
const rightNative = parseNativeApplicationEvidence(
- parsed.data.right_native_observations,
+ input.right_native_observations,
);
const result = compareJavaScriptApplicationVersions({
left: {
@@ -101,7 +117,7 @@ export const compareApplicationVersionsEvidence = (
},
leftNativeEvidence: leftNative,
rightNativeEvidence: rightNative,
- limits: parsed.data.limits,
+ limits: input.limits,
});
return ok(
createApplicationVersionComparisonEvidence(
@@ -112,7 +128,7 @@ export const compareApplicationVersionsEvidence = (
right_native_evidence_ids: rightNative.map(
({ evidence_id: id }) => id,
),
- limits: parsed.data.limits,
+ limits: input.limits,
},
result,
),
diff --git a/src/application/JavaScriptReplayService.ts b/src/application/JavaScriptReplayService.ts
index 1bbc342e5..b283cf5dd 100644
--- a/src/application/JavaScriptReplayService.ts
+++ b/src/application/JavaScriptReplayService.ts
@@ -56,6 +56,15 @@ export const runControlledReplay = async (
projectInputIssues(parsed.error.issues, rawInput),
),
);
+ return runControlledReplayValidated(dependencies, parsed.data, options);
+};
+
+/** Plan or execute replay input already parsed by a trusted adapter. */
+export const runControlledReplayValidated = async (
+ dependencies: JavaScriptReplayDependencies,
+ input: z.output,
+ options: ExecutionOptions = {},
+): Promise> => {
if (!dependencies.policy.enabled)
return err(
new AnalysisCapabilityUnavailableError(
@@ -74,9 +83,9 @@ export const runControlledReplay = async (
);
if (isAborted(options.signal))
return err(new AnalysisCancelledError(OPERATION));
- const request = permissionRequest(parsed.data, dependencies.policy);
+ const request = permissionRequest(input, dependencies.policy);
const authorized =
- parsed.data.mode === "plan"
+ input.mode === "plan"
? await dependencies.authority.explain(request, "read")
: await dependencies.authority.authorize(request, "read");
if (!authorized.ok)
@@ -90,7 +99,7 @@ export const runControlledReplay = async (
let prepared;
try {
prepared = await prepareReplayPlan(
- parsed.data,
+ input,
dependencies.policy,
dependencies.host,
);
@@ -105,7 +114,7 @@ export const runControlledReplay = async (
}
if (isAborted(options.signal))
return err(new AnalysisCancelledError(OPERATION));
- if (parsed.data.mode === "plan")
+ if (input.mode === "plan")
return ok(
asJson({
phase: "plan",
@@ -114,21 +123,21 @@ export const runControlledReplay = async (
evidence: null,
}),
);
- if (parsed.data.plan_digest !== prepared.publicPlan.plan_digest)
+ if (input.plan_digest !== prepared.publicPlan.plan_digest)
return err(
new ReplayPlanStaleError(
- parsed.data.plan_digest ?? "",
+ input.plan_digest ?? "",
prepared.publicPlan.plan_digest,
),
);
let canonicalExportPath: string | undefined;
- if (parsed.data.reproducer_export !== undefined) {
- if (parsed.data.reproducer_export.approved !== true)
+ if (input.reproducer_export !== undefined) {
+ if (input.reproducer_export.approved !== true)
return err(new AnalysisInputError(`${OPERATION}:reproducer_export`));
const exportAuthorized = await dependencies.authority.authorize(
{
capability: "evidence_write",
- roots: [parsed.data.reproducer_export.path],
+ roots: [input.reproducer_export.path],
executables: [],
environment_names: [],
network: "none",
@@ -146,7 +155,7 @@ export const runControlledReplay = async (
}),
);
canonicalExportPath = exportAuthorized.value.request.roots[0];
- if (canonicalExportPath !== parsed.data.reproducer_export.path)
+ if (canonicalExportPath !== input.reproducer_export.path)
return err(
new AnalysisInputError(`${OPERATION}:reproducer_export:path`, {
cause: new TypeError(
@@ -183,7 +192,7 @@ export const runControlledReplay = async (
if (executed.termination === "cancelled")
return err(new AnalysisCancelledError(OPERATION));
if (
- parsed.data.reproducer_export !== undefined &&
+ input.reproducer_export !== undefined &&
canonicalExportPath !== undefined &&
executed.cleanup.state === "complete"
) {
@@ -191,7 +200,7 @@ export const runControlledReplay = async (
schema_version: 1,
plan: prepared.publicPlan,
result: executed,
- sources: parsed.data.reproducer_export.include_sources
+ sources: input.reproducer_export.include_sources
? {
left: prepared.leftSources,
...(prepared.rightSources === undefined
diff --git a/src/application/JavaScriptRuntimeReconciliationService.ts b/src/application/JavaScriptRuntimeReconciliationService.ts
index 46bcb08f9..f78f5bf75 100644
--- a/src/application/JavaScriptRuntimeReconciliationService.ts
+++ b/src/application/JavaScriptRuntimeReconciliationService.ts
@@ -27,11 +27,16 @@ export const reconcileJavaScriptRuntimeEvidence = (
projectInputIssues(parsed.error.issues, rawInput),
),
);
+ return reconcileJavaScriptRuntimeEvidenceValidated(parsed.data);
+};
+
+/** Reconcile input already parsed by a trusted adapter boundary. */
+export const reconcileJavaScriptRuntimeEvidenceValidated = (
+ input: z.output,
+): Result => {
try {
- const result = reconcileJavaScriptRuntime(parsed.data);
- return ok(
- createJavaScriptRuntimeReconciliationEvidence(parsed.data, result),
- );
+ const result = reconcileJavaScriptRuntime(input);
+ return ok(createJavaScriptRuntimeReconciliationEvidence(input, result));
} catch (cause: unknown) {
return err(
cause instanceof z.ZodError || cause instanceof TypeError
diff --git a/src/server/registerApplicationTools.ts b/src/server/registerApplicationTools.ts
index de40833b2..60d159bbf 100644
--- a/src/server/registerApplicationTools.ts
+++ b/src/server/registerApplicationTools.ts
@@ -2,11 +2,11 @@ import type { McpServer } from "@modelcontextprotocol/server";
import type { BinarySessionPort } from "../application/BinarySession.js";
import {
- compareApplicationVersionsEvidence,
- traceApplicationFeatureEvidence,
+ compareApplicationVersionsEvidenceValidated,
+ traceApplicationFeatureEvidenceValidated,
} from "../application/JavaScriptApplicationWorkflowService.js";
import {
- runControlledReplay,
+ runControlledReplayValidated,
type JavaScriptReplayDependencies,
} from "../application/JavaScriptReplayService.js";
import { APPLICATION_TOOL_CONTRACTS } from "../contracts/applicationToolContracts.js";
@@ -55,7 +55,7 @@ export const registerApplicationTools = (
const result = await logToolExecution(
options.logger,
traceContract.name,
- () => Promise.resolve(traceApplicationFeatureEvidence(parsed)),
+ () => Promise.resolve(traceApplicationFeatureEvidenceValidated(parsed)),
);
if (!result.ok) return toCallToolResult(result, traceContract);
const sources = [parsed.application, ...parsed.native_observations];
@@ -79,7 +79,8 @@ export const registerApplicationTools = (
const result = await logToolExecution(
options.logger,
compareContract.name,
- () => Promise.resolve(compareApplicationVersionsEvidence(parsed)),
+ () =>
+ Promise.resolve(compareApplicationVersionsEvidenceValidated(parsed)),
);
if (!result.ok) return toCallToolResult(result, compareContract);
const sources = [
@@ -117,7 +118,7 @@ export const registerApplicationTools = (
options.logger,
replayContract.name,
() =>
- runControlledReplay(options.replay, parsed, {
+ runControlledReplayValidated(options.replay, parsed, {
signal: context.mcpReq.signal,
progress: mcpProgressReporter(context),
}),
diff --git a/src/server/registerElectronTools.ts b/src/server/registerElectronTools.ts
index d664f0dce..10a778a5b 100644
--- a/src/server/registerElectronTools.ts
+++ b/src/server/registerElectronTools.ts
@@ -2,8 +2,8 @@ import type { McpServer } from "@modelcontextprotocol/server";
import type { BinarySessionPort } from "../application/BinarySession.js";
import type { ElectronObservationPort } from "../application/ElectronObservationPort.js";
-import { analyzeJavaScriptApplication } from "../application/JavaScriptApplicationService.js";
-import { reconcileJavaScriptRuntimeEvidence } from "../application/JavaScriptRuntimeReconciliationService.js";
+import { analyzeJavaScriptApplicationValidated } from "../application/JavaScriptApplicationService.js";
+import { reconcileJavaScriptRuntimeEvidenceValidated } from "../application/JavaScriptRuntimeReconciliationService.js";
import {
inspectElectronPage,
listElectronTargets,
@@ -109,10 +109,14 @@ export const registerElectronTools = (
options.logger,
analyzeContract.name,
() =>
- analyzeJavaScriptApplication(options.permissionAuthority, parsed, {
- signal: context.mcpReq.signal,
- progress: mcpProgressReporter(context),
- }),
+ analyzeJavaScriptApplicationValidated(
+ options.permissionAuthority,
+ parsed,
+ {
+ signal: context.mcpReq.signal,
+ progress: mcpProgressReporter(context),
+ },
+ ),
);
if (!result.ok) return toCallToolResult(result, analyzeContract);
return evidenceResult(options, analyzeContract, result.value);
@@ -133,7 +137,8 @@ export const registerElectronTools = (
const result = await logToolExecution(
options.logger,
reconcileContract.name,
- () => Promise.resolve(reconcileJavaScriptRuntimeEvidence(parsed)),
+ () =>
+ Promise.resolve(reconcileJavaScriptRuntimeEvidenceValidated(parsed)),
);
if (!result.ok) return toCallToolResult(result, reconcileContract);
for (const source of [
diff --git a/src/server/registerEnhancedTools.ts b/src/server/registerEnhancedTools.ts
index ffcbc18fa..fd6928595 100644
--- a/src/server/registerEnhancedTools.ts
+++ b/src/server/registerEnhancedTools.ts
@@ -1,6 +1,9 @@
import type { McpServer } from "@modelcontextprotocol/server";
-import { EnhancedTools } from "../application/EnhancedTools.js";
+import {
+ EnhancedTools,
+ type ValidatedEnhancedCall,
+} from "../application/EnhancedTools.js";
import type { AnalysisOperationPort } from "../application/AnalysisProvider.js";
import type { BinarySessionPort } from "../application/BinarySession.js";
import { enhancedToolNameSchema } from "../contracts/enhancedInputs.js";
@@ -13,9 +16,10 @@ import type { Logger } from "../logger.js";
import { logToolExecution } from "./toolLogging.js";
import type { BinaryTarget } from "../domain/binaryTarget.js";
import { createEvidence } from "../domain/evidence.js";
-import { jsonObjectSchema, type JsonValue } from "../domain/jsonValue.js";
+import type { JsonValue } from "../domain/jsonValue.js";
import { enhancedInputSchemas } from "../contracts/enhancedInputs.js";
-import { UnknownRegistryError } from "../domain/errors.js";
+import { AnalysisInputError, UnknownRegistryError } from "../domain/errors.js";
+import { ok, type Result } from "../domain/result.js";
import { mcpProgressReporter } from "./mcpProgress.js";
import type { AnalysisProfileCommitment } from "../domain/analysisProfile.js";
import {
@@ -80,16 +84,12 @@ const registerEnhancedTool = (
total: 1,
message: "started",
});
- const validatedInput = safeParseToolInput(
- enhancedInputSchemas[name],
- input,
- name,
- );
- if (!validatedInput.ok) return toCallToolResult(validatedInput, contract);
- const parsedInput = jsonObjectSchema.parse(validatedInput.value);
- const parameters: Record = { ...parsedInput };
+ const validatedCall = parseEnhancedCall(name, input);
+ if (!validatedCall.ok) return toCallToolResult(validatedCall, contract);
+ const parsedInput = validatedCall.value.input;
+ const parameters = jsonParameters(parsedInput);
const result = await logToolExecution(registration.logger, name, () =>
- services.execute(name, input, context.mcpReq.signal),
+ services.executeValidated(validatedCall.value, context.mcpReq.signal),
);
await progress.report({
phase: name,
@@ -123,7 +123,7 @@ const registerEnhancedTool = (
return toCallToolResult(recorded, contract);
const unknowns = recordWorkflowUnknowns({
name,
- input: parsedInput,
+ input: parameters,
result: result.value,
evidenceId: evidence.evidence_id,
recordUnknown: registration.recordUnknown,
@@ -138,6 +138,103 @@ const registerEnhancedTool = (
);
};
+const jsonParameters = (
+ input: Readonly>,
+): Record =>
+ Object.fromEntries(
+ Object.entries(input).filter(
+ (entry): entry is [string, JsonValue] => entry[1] !== undefined,
+ ),
+ );
+
+const parseEnhancedCall = (
+ name: ValidatedEnhancedCall["name"],
+ input: unknown,
+): Result => {
+ switch (name) {
+ case "swift_classes": {
+ const parsed = safeParseToolInput(
+ enhancedInputSchemas.swift_classes,
+ input,
+ name,
+ );
+ return parsed.ok ? ok({ name, input: parsed.value }) : parsed;
+ }
+ case "get_objc_classes": {
+ const parsed = safeParseToolInput(
+ enhancedInputSchemas.get_objc_classes,
+ input,
+ name,
+ );
+ return parsed.ok ? ok({ name, input: parsed.value }) : parsed;
+ }
+ case "get_objc_protocols": {
+ const parsed = safeParseToolInput(
+ enhancedInputSchemas.get_objc_protocols,
+ input,
+ name,
+ );
+ return parsed.ok ? ok({ name, input: parsed.value }) : parsed;
+ }
+ case "batch_decompile": {
+ const parsed = safeParseToolInput(
+ enhancedInputSchemas.batch_decompile,
+ input,
+ name,
+ );
+ return parsed.ok ? ok({ name, input: parsed.value }) : parsed;
+ }
+ case "get_call_graph": {
+ const parsed = safeParseToolInput(
+ enhancedInputSchemas.get_call_graph,
+ input,
+ name,
+ );
+ return parsed.ok ? ok({ name, input: parsed.value }) : parsed;
+ }
+ case "analyze_swift_types": {
+ const parsed = safeParseToolInput(
+ enhancedInputSchemas.analyze_swift_types,
+ input,
+ name,
+ );
+ return parsed.ok ? ok({ name, input: parsed.value }) : parsed;
+ }
+ case "find_xrefs_to_name": {
+ const parsed = safeParseToolInput(
+ enhancedInputSchemas.find_xrefs_to_name,
+ input,
+ name,
+ );
+ return parsed.ok ? ok({ name, input: parsed.value }) : parsed;
+ }
+ case "binary_overview": {
+ const parsed = safeParseToolInput(
+ enhancedInputSchemas.binary_overview,
+ input,
+ name,
+ );
+ return parsed.ok ? ok({ name, input: parsed.value }) : parsed;
+ }
+ case "analyze_function": {
+ const parsed = safeParseToolInput(
+ enhancedInputSchemas.analyze_function,
+ input,
+ name,
+ );
+ return parsed.ok ? ok({ name, input: parsed.value }) : parsed;
+ }
+ case "trace_feature": {
+ const parsed = safeParseToolInput(
+ enhancedInputSchemas.trace_feature,
+ input,
+ name,
+ );
+ return parsed.ok ? ok({ name, input: parsed.value }) : parsed;
+ }
+ }
+};
+
interface WorkflowUnknownInput {
readonly name: string;
readonly input: Readonly>;
diff --git a/src/server/registerInvestigationTools.ts b/src/server/registerInvestigationTools.ts
index 2892f58ca..18522d746 100644
--- a/src/server/registerInvestigationTools.ts
+++ b/src/server/registerInvestigationTools.ts
@@ -1,7 +1,7 @@
import type { McpServer } from "@modelcontextprotocol/server";
import type { BinarySessionPort } from "../application/BinarySession.js";
-import { runCrossVersionInvestigation } from "../application/CrossVersionInvestigation.js";
+import { runCrossVersionInvestigationValidated } from "../application/CrossVersionInvestigation.js";
import type { ToolContract } from "../contracts/toolContracts.js";
import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
import { safeParseToolInput } from "./toolInputValidation.js";
@@ -133,7 +133,7 @@ const registerChangedBehavior = (
operation: contract.name,
});
}
- const investigated = await runCrossVersionInvestigation(
+ const investigated = await runCrossVersionInvestigationValidated(
investigationRun,
policies.evidenceFiles,
{
diff --git a/tests/enhancedTools.test.ts b/tests/enhancedTools.test.ts
index 3899b6a57..1b39645a6 100644
--- a/tests/enhancedTools.test.ts
+++ b/tests/enhancedTools.test.ts
@@ -1,6 +1,6 @@
import { Client, InMemoryTransport } from "@modelcontextprotocol/client";
import type { CallToolResult } from "@modelcontextprotocol/server";
-import { afterEach, describe, expect, it } from "vitest";
+import { afterEach, describe, expect, it, vi } from "vitest";
import type { AnalysisOperationPort } from "../src/application/AnalysisProvider.js";
import { EnhancedTools } from "../src/application/EnhancedTools.js";
@@ -9,6 +9,7 @@ import {
SESSION_TOOL_CONTRACTS,
TOOL_CONTRACTS,
} from "../src/contracts/toolContracts.js";
+import { enhancedInputSchemas } from "../src/contracts/enhancedInputs.js";
import { AnalysisOutputError } from "../src/domain/errors.js";
import { jsonValueSchema, type JsonValue } from "../src/domain/jsonValue.js";
import { err } from "../src/domain/result.js";
@@ -144,6 +145,7 @@ const emptyBounded = () => ({
const resources: Array<{ close(): Promise }> = [];
afterEach(async () => {
+ vi.restoreAllMocks();
await Promise.all(
resources.splice(0).map(async (resource) => resource.close()),
);
@@ -613,6 +615,16 @@ describe("enhanced MCP tools", () => {
it("returns correction-only structured validation issues", async () => {
const client = await connect();
+ const traceParser = vi.spyOn(
+ enhancedInputSchemas.trace_feature,
+ "safeParse",
+ );
+ await client.callTool({
+ name: "trace_feature",
+ arguments: { query: "needle", max_operations: 1 },
+ });
+ expect(traceParser).toHaveBeenCalledTimes(1);
+ traceParser.mockClear();
const misspelled = await client.callTool({
name: "trace_feature",
arguments: { query: "needle", max_operatons: 1 },
@@ -629,6 +641,7 @@ describe("enhanced MCP tools", () => {
},
},
});
+ expect(traceParser).not.toHaveBeenCalled();
const nestedMisspelled = await client.callTool({
name: "analyze_function",
arguments: {
From 6e6827cd76fc080a959695ab19bfcc34b80c270c Mon Sep 17 00:00:00 2001
From: morluto <76467478+morluto@users.noreply.github.com>
Date: Thu, 16 Jul 2026 19:19:28 +0800
Subject: [PATCH 09/19] test(hopper): avoid scheduler-sensitive exit timing
---
tests/hopperClient.test.ts | 2 --
1 file changed, 2 deletions(-)
diff --git a/tests/hopperClient.test.ts b/tests/hopperClient.test.ts
index 5f94279c8..e1f8bffdd 100644
--- a/tests/hopperClient.test.ts
+++ b/tests/hopperClient.test.ts
@@ -269,7 +269,6 @@ describe("HopperClient", () => {
startupTimeoutMs: 10_000,
});
clients.push(client);
- const startedAt = Date.now();
const result = await client.start();
expect(result.ok).toBe(false);
if (!result.ok)
@@ -277,7 +276,6 @@ describe("HopperClient", () => {
_tag: "HopperProcessError",
exitCode,
});
- expect(Date.now() - startedAt).toBeLessThan(500);
},
);
From 9c4a93d9b1be36155bd9c0a39d8b541ec3986c64 Mon Sep 17 00:00:00 2001
From: morluto <76467478+morluto@users.noreply.github.com>
Date: Thu, 16 Jul 2026 19:34:57 +0800
Subject: [PATCH 10/19] fix(mcp): integrate managed contracts after rebase
---
docs/mcp-schema-report.json | 242 ++++++++++--------
.../ManagedMemberComparisonService.ts | 16 +-
.../ManagedRuntimeCorrelationService.ts | 25 +-
src/contracts/managedToolContracts.ts | 14 +-
src/contracts/managedWorkflowToolContracts.ts | 66 +++--
src/contracts/toolEffects.ts | 4 +
src/server/createServer.ts | 1 +
src/server/registerManagedWorkflowTools.ts | 92 ++++++-
src/server/toolRegistrationOptions.ts | 26 +-
tests/contractSnapshot.test.ts | 1 +
tests/managedMcp.test.ts | 36 ++-
11 files changed, 350 insertions(+), 173 deletions(-)
diff --git a/docs/mcp-schema-report.json b/docs/mcp-schema-report.json
index dda37b59b..edd6f7449 100644
--- a/docs/mcp-schema-report.json
+++ b/docs/mcp-schema-report.json
@@ -1,7 +1,7 @@
{
"generated_from": "@modelcontextprotocol/server 2.0.0-beta.4 wire registration",
- "tool_count": 84,
- "tools_list_bytes": 518457,
+ "tool_count": 88,
+ "tools_list_bytes": 517143,
"budgets": {
"tools_list_bytes": 524288,
"per_tool_bytes": 65536
@@ -15,15 +15,15 @@
},
{
"name": "analyze_function",
- "bytes": 10206,
+ "bytes": 8935,
"input_schema_bytes": 2037,
- "output_schema_bytes": 7692
+ "output_schema_bytes": 6421
},
{
"name": "analyze_javascript_application",
- "bytes": 19871,
+ "bytes": 17446,
"input_schema_bytes": 2633,
- "output_schema_bytes": 16597
+ "output_schema_bytes": 14172
},
{
"name": "analyze_swift_types",
@@ -33,45 +33,45 @@
},
{
"name": "analyze_web_bundle",
- "bytes": 14995,
+ "bytes": 14276,
"input_schema_bytes": 6550,
- "output_schema_bytes": 7940
+ "output_schema_bytes": 7221
},
{
"name": "batch_decompile",
- "bytes": 12102,
+ "bytes": 10638,
"input_schema_bytes": 226,
- "output_schema_bytes": 11475
+ "output_schema_bytes": 10011
},
{
"name": "binary_overview",
- "bytes": 1643,
+ "bytes": 1620,
"input_schema_bytes": 250,
- "output_schema_bytes": 977
+ "output_schema_bytes": 954
},
{
"name": "binary_session",
- "bytes": 13235,
+ "bytes": 11822,
"input_schema_bytes": 367,
- "output_schema_bytes": 12368
+ "output_schema_bytes": 10955
},
{
"name": "build_call_path",
- "bytes": 11300,
- "input_schema_bytes": 7493,
- "output_schema_bytes": 3335
+ "bytes": 10235,
+ "input_schema_bytes": 6850,
+ "output_schema_bytes": 2913
},
{
"name": "capture_process_scenario",
- "bytes": 20991,
- "input_schema_bytes": 10463,
- "output_schema_bytes": 9774
+ "bytes": 19830,
+ "input_schema_bytes": 10303,
+ "output_schema_bytes": 8773
},
{
"name": "capture_web_screenshot",
- "bytes": 5661,
+ "bytes": 5389,
"input_schema_bytes": 771,
- "output_schema_bytes": 4454
+ "output_schema_bytes": 4182
},
{
"name": "close_binary",
@@ -87,51 +87,57 @@
},
{
"name": "compare_application_versions",
- "bytes": 27986,
- "input_schema_bytes": 10250,
- "output_schema_bytes": 17168
+ "bytes": 24888,
+ "input_schema_bytes": 9296,
+ "output_schema_bytes": 15024
},
{
"name": "compare_artifacts",
- "bytes": 4095,
+ "bytes": 3869,
"input_schema_bytes": 759,
- "output_schema_bytes": 2851
+ "output_schema_bytes": 2625
},
{
"name": "compare_bundles",
- "bytes": 4559,
+ "bytes": 4169,
"input_schema_bytes": 928,
- "output_schema_bytes": 3132
+ "output_schema_bytes": 2742
},
{
"name": "compare_functions",
- "bytes": 4828,
+ "bytes": 4356,
"input_schema_bytes": 725,
- "output_schema_bytes": 3611
+ "output_schema_bytes": 3139
+ },
+ {
+ "name": "compare_managed_members",
+ "bytes": 7583,
+ "input_schema_bytes": 960,
+ "output_schema_bytes": 6099
},
{
"name": "compare_process_captures",
- "bytes": 3866,
+ "bytes": 3311,
"input_schema_bytes": 565,
- "output_schema_bytes": 2716
+ "output_schema_bytes": 2161
},
{
"name": "compare_web_captures",
- "bytes": 33869,
- "input_schema_bytes": 31489,
- "output_schema_bytes": 1940
+ "bytes": 29996,
+ "input_schema_bytes": 27683,
+ "output_schema_bytes": 1873
},
{
"name": "compare_web_screenshots",
- "bytes": 3428,
- "input_schema_bytes": 1489,
+ "bytes": 3351,
+ "input_schema_bytes": 1412,
"output_schema_bytes": 1546
},
{
"name": "correlate_static_and_runtime",
- "bytes": 13332,
- "input_schema_bytes": 8963,
- "output_schema_bytes": 3876
+ "bytes": 12426,
+ "input_schema_bytes": 8307,
+ "output_schema_bytes": 3626
},
{
"name": "current_address",
@@ -159,27 +165,27 @@
},
{
"name": "discover_webmcp_tools",
- "bytes": 7256,
+ "bytes": 6797,
"input_schema_bytes": 1087,
- "output_schema_bytes": 5765
+ "output_schema_bytes": 5306
},
{
"name": "export_evidence_bundle",
- "bytes": 12103,
+ "bytes": 11008,
"input_schema_bytes": 196,
- "output_schema_bytes": 11479
+ "output_schema_bytes": 10384
},
{
"name": "extract_artifact",
- "bytes": 6414,
+ "bytes": 6212,
"input_schema_bytes": 1321,
- "output_schema_bytes": 4701
+ "output_schema_bytes": 4499
},
{
"name": "find_changed_behavior",
- "bytes": 12296,
- "input_schema_bytes": 8586,
- "output_schema_bytes": 3182
+ "bytes": 12036,
+ "input_schema_bytes": 8540,
+ "output_schema_bytes": 2968
},
{
"name": "find_xrefs_to_name",
@@ -189,9 +195,9 @@
},
{
"name": "get_call_graph",
- "bytes": 12061,
+ "bytes": 10619,
"input_schema_bytes": 361,
- "output_schema_bytes": 11228
+ "output_schema_bytes": 9786
},
{
"name": "get_objc_classes",
@@ -225,51 +231,63 @@
},
{
"name": "inspect_electron_page",
- "bytes": 10081,
+ "bytes": 9514,
"input_schema_bytes": 1936,
- "output_schema_bytes": 7685
+ "output_schema_bytes": 7118
},
{
"name": "inspect_macho",
- "bytes": 9368,
+ "bytes": 7672,
"input_schema_bytes": 62,
- "output_schema_bytes": 8933
+ "output_schema_bytes": 7237
},
{
"name": "inspect_managed_artifact",
- "bytes": 12894,
+ "bytes": 11489,
"input_schema_bytes": 1251,
- "output_schema_bytes": 11159
+ "output_schema_bytes": 9754
+ },
+ {
+ "name": "inspect_managed_members",
+ "bytes": 13925,
+ "input_schema_bytes": 2048,
+ "output_schema_bytes": 11387
+ },
+ {
+ "name": "inspect_managed_native_boundaries",
+ "bytes": 9704,
+ "input_schema_bytes": 1267,
+ "output_schema_bytes": 7912
},
{
"name": "inspect_plist",
- "bytes": 2883,
+ "bytes": 2769,
"input_schema_bytes": 189,
- "output_schema_bytes": 2320
+ "output_schema_bytes": 2206
},
{
"name": "inspect_signature",
- "bytes": 2946,
+ "bytes": 2793,
"input_schema_bytes": 62,
- "output_schema_bytes": 2519
+ "output_schema_bytes": 2366
},
{
"name": "inspect_web_page",
- "bytes": 23933,
+ "bytes": 21829,
"input_schema_bytes": 5042,
- "output_schema_bytes": 18381
+ "output_schema_bytes": 16277
},
{
"name": "inventory_artifact",
- "bytes": 10608,
+ "bytes": 9791,
"input_schema_bytes": 1885,
- "output_schema_bytes": 8336
+ "output_schema_bytes": 7519
},
{
"name": "list_architectures",
- "bytes": 2782,
+ "bytes": 2555,
"input_schema_bytes": 62,
- "output_schema_bytes": 2387
+ "output_schema_bytes": 2160
},
{
"name": "list_bookmarks",
@@ -279,9 +297,9 @@
},
{
"name": "list_browser_targets",
- "bytes": 3072,
+ "bytes": 2950,
"input_schema_bytes": 658,
- "output_schema_bytes": 1966
+ "output_schema_bytes": 1844
},
{
"name": "list_documents",
@@ -291,39 +309,39 @@
},
{
"name": "list_electron_targets",
- "bytes": 2991,
+ "bytes": 2869,
"input_schema_bytes": 636,
- "output_schema_bytes": 1932
+ "output_schema_bytes": 1810
},
{
"name": "list_names",
- "bytes": 2842,
+ "bytes": 2786,
"input_schema_bytes": 594,
- "output_schema_bytes": 1818
+ "output_schema_bytes": 1762
},
{
"name": "list_procedures",
- "bytes": 2739,
+ "bytes": 2683,
"input_schema_bytes": 475,
- "output_schema_bytes": 1818
+ "output_schema_bytes": 1762
},
{
"name": "list_segments",
- "bytes": 2817,
+ "bytes": 2656,
"input_schema_bytes": 282,
- "output_schema_bytes": 2128
+ "output_schema_bytes": 1967
},
{
"name": "list_strings",
- "bytes": 2837,
+ "bytes": 2781,
"input_schema_bytes": 594,
- "output_schema_bytes": 1818
+ "output_schema_bytes": 1762
},
{
"name": "list_unknowns",
- "bytes": 4477,
+ "bytes": 4279,
"input_schema_bytes": 358,
- "output_schema_bytes": 3710
+ "output_schema_bytes": 3512
},
{
"name": "next_address",
@@ -333,9 +351,9 @@
},
{
"name": "observe_web_session",
- "bytes": 6320,
+ "bytes": 5976,
"input_schema_bytes": 765,
- "output_schema_bytes": 5090
+ "output_schema_bytes": 4746
},
{
"name": "open_binary",
@@ -343,6 +361,12 @@
"input_schema_bytes": 386,
"output_schema_bytes": 696
},
+ {
+ "name": "plan_managed_runtime_correlation",
+ "bytes": 7556,
+ "input_schema_bytes": 2128,
+ "output_schema_bytes": 4768
+ },
{
"name": "prev_address",
"bytes": 1045,
@@ -387,21 +411,21 @@
},
{
"name": "procedure_references",
- "bytes": 4319,
+ "bytes": 4192,
"input_schema_bytes": 798,
- "output_schema_bytes": 3054
+ "output_schema_bytes": 2927
},
{
"name": "reconcile_javascript_runtime",
- "bytes": 30201,
- "input_schema_bytes": 9566,
- "output_schema_bytes": 20110
+ "bytes": 27214,
+ "input_schema_bytes": 8993,
+ "output_schema_bytes": 17696
},
{
"name": "record_unknown",
- "bytes": 6725,
+ "bytes": 6527,
"input_schema_bytes": 2646,
- "output_schema_bytes": 3685
+ "output_schema_bytes": 3487
},
{
"name": "resolve_containing_procedure",
@@ -411,21 +435,21 @@
},
{
"name": "run_controlled_replay",
- "bytes": 21072,
- "input_schema_bytes": 6098,
- "output_schema_bytes": 14387
+ "bytes": 19234,
+ "input_schema_bytes": 5922,
+ "output_schema_bytes": 12725
},
{
"name": "search_procedures",
- "bytes": 2238,
+ "bytes": 2215,
"input_schema_bytes": 812,
- "output_schema_bytes": 964
+ "output_schema_bytes": 941
},
{
"name": "search_strings",
- "bytes": 2247,
+ "bytes": 2224,
"input_schema_bytes": 812,
- "output_schema_bytes": 964
+ "output_schema_bytes": 941
},
{
"name": "set_address_name",
@@ -471,9 +495,9 @@
},
{
"name": "trace_application_feature",
- "bytes": 27741,
- "input_schema_bytes": 9241,
- "output_schema_bytes": 17969
+ "bytes": 24958,
+ "input_schema_bytes": 8688,
+ "output_schema_bytes": 15739
},
{
"name": "trace_feature",
@@ -489,21 +513,21 @@
},
{
"name": "update_unknown",
- "bytes": 7884,
- "input_schema_bytes": 3810,
- "output_schema_bytes": 3685
+ "bytes": 7572,
+ "input_schema_bytes": 3696,
+ "output_schema_bytes": 3487
},
{
"name": "verify_reconstruction",
- "bytes": 6692,
- "input_schema_bytes": 2688,
- "output_schema_bytes": 3510
+ "bytes": 6161,
+ "input_schema_bytes": 2455,
+ "output_schema_bytes": 3212
},
{
"name": "verify_unknown_resolution",
- "bytes": 4481,
+ "bytes": 4283,
"input_schema_bytes": 177,
- "output_schema_bytes": 3866
+ "output_schema_bytes": 3668
},
{
"name": "xrefs",
diff --git a/src/application/ManagedMemberComparisonService.ts b/src/application/ManagedMemberComparisonService.ts
index 5eb2b4242..754bcf5f5 100644
--- a/src/application/ManagedMemberComparisonService.ts
+++ b/src/application/ManagedMemberComparisonService.ts
@@ -29,15 +29,23 @@ export const compareManagedMembersEvidence = (
const operation = "compare_managed_members";
const parsed = compareManagedMembersInputSchema.safeParse(rawInput);
if (!parsed.success) return err(new AnalysisInputError(operation));
+ return compareManagedMembersEvidenceValidated(parsed.data);
+};
+
+/** Compare managed members from input parsed by a trusted adapter. */
+export const compareManagedMembersEvidenceValidated = (
+ input: CompareManagedMembersInput,
+): Result => {
+ const operation = "compare_managed_members";
try {
- const left = parseManagedMemberEvidence(parsed.data.left);
- const right = parseManagedMemberEvidence(parsed.data.right);
+ const left = parseManagedMemberEvidence(input.left);
+ const right = parseManagedMemberEvidence(input.right);
const result = compareManagedMembers(
{ evidenceId: left.evidenceId, result: left.result },
{ evidenceId: right.evidenceId, result: right.result },
- parsed.data.limits,
+ input.limits,
);
- return ok(createManagedMemberComparisonEvidence(parsed.data, result));
+ return ok(createManagedMemberComparisonEvidence(input, result));
} catch (cause: unknown) {
return workflowFailure(operation, cause);
}
diff --git a/src/application/ManagedRuntimeCorrelationService.ts b/src/application/ManagedRuntimeCorrelationService.ts
index 5bebb46b6..160b29a6d 100644
--- a/src/application/ManagedRuntimeCorrelationService.ts
+++ b/src/application/ManagedRuntimeCorrelationService.ts
@@ -42,6 +42,17 @@ export const planManagedRuntimeCorrelationEvidence = async (
const parsed = managedRuntimeCorrelationInputSchema.safeParse(rawInput);
if (!parsed.success)
return err(new AnalysisInputError(OPERATION, { cause: parsed.error }));
+ return planManagedRuntimeCorrelationEvidenceValidated(
+ dependencies,
+ parsed.data,
+ );
+};
+
+/** Plan runtime correlation from input parsed by a trusted adapter. */
+export const planManagedRuntimeCorrelationEvidenceValidated = async (
+ dependencies: ManagedRuntimeCorrelationDependencies,
+ input: ManagedRuntimeCorrelationInput,
+): Promise> => {
if (!dependencies.policy.enabled)
return err(
new AnalysisCapabilityUnavailableError(
@@ -61,7 +72,7 @@ export const planManagedRuntimeCorrelationEvidence = async (
let staticEvidence: Evidence;
let artifactPath: string;
try {
- staticEvidence = parseEvidence(parsed.data.static_members);
+ staticEvidence = parseEvidence(input.static_members);
artifactPath = artifactPathFor(staticEvidence);
} catch (cause: unknown) {
return err(new AnalysisInputError(OPERATION, { cause }));
@@ -74,7 +85,7 @@ export const planManagedRuntimeCorrelationEvidence = async (
environment_names: [],
network: "none",
mount: false,
- operation_identity: operationIdentity(parsed.data, staticEvidence),
+ operation_identity: operationIdentity(input, staticEvidence),
},
"read",
{ restartRequired: true },
@@ -89,7 +100,7 @@ export const planManagedRuntimeCorrelationEvidence = async (
);
try {
const result = planManagedRuntimeCorrelation(
- parsed.data,
+ input,
dependencies.policy.executablePath,
authorized.value.grant_id,
);
@@ -106,10 +117,10 @@ export const planManagedRuntimeCorrelationEvidence = async (
operation: OPERATION,
parameters: {
static_members_evidence_id: staticEvidence.evidence_id,
- method: jsonValueSchema.parse(parsed.data.method),
- requested_effect: parsed.data.requested_effect,
- host: jsonValueSchema.parse(parsed.data.host),
- bounds: jsonValueSchema.parse(parsed.data.bounds),
+ method: jsonValueSchema.parse(input.method),
+ requested_effect: input.requested_effect,
+ host: jsonValueSchema.parse(input.host),
+ bounds: jsonValueSchema.parse(input.bounds),
},
result: jsonValueSchema.parse(result),
rawResult: null,
diff --git a/src/contracts/managedToolContracts.ts b/src/contracts/managedToolContracts.ts
index 8b390dd09..35a6da1b2 100644
--- a/src/contracts/managedToolContracts.ts
+++ b/src/contracts/managedToolContracts.ts
@@ -135,17 +135,12 @@ export const MANAGED_TOOL_CONTRACTS = [
},
{
name: "inspect_managed_members",
+ ...toolContractMetadata("inspect_managed_members"),
description:
"Inspect bounded PE/CLI metadata members, signatures, method body IL hashes, exception regions, call edges, and field-access anchors without loading or executing target code. Metadata tokens are reported as build-local coordinates bound to the artifact SHA-256 and MVID.",
kind: "managed-provider",
inputSchema: managedMemberInputSchema,
outputSchema: memberOutputSchema,
- annotations: {
- readOnlyHint: true,
- destructiveHint: false,
- idempotentHint: true,
- openWorldHint: false,
- },
examples: [
{
title: "Example inspect managed members request",
@@ -155,17 +150,12 @@ export const MANAGED_TOOL_CONTRACTS = [
},
{
name: "inspect_managed_native_boundaries",
+ ...toolContractMetadata("inspect_managed_native_boundaries"),
description:
"Inspect PE/CLI ModuleRef, ImplMap/PInvoke declarations, CLI native-header indicators, and non-IL method implementation flags without loading or executing target code. Results are managed declarations and degraded native-boundary observations, not verified native exports or addresses.",
kind: "managed-provider",
inputSchema: managedNativeBoundaryInputSchema,
outputSchema: nativeBoundaryOutputSchema,
- annotations: {
- readOnlyHint: true,
- destructiveHint: false,
- idempotentHint: true,
- openWorldHint: false,
- },
examples: [
{
title: "Example inspect managed/native boundary request",
diff --git a/src/contracts/managedWorkflowToolContracts.ts b/src/contracts/managedWorkflowToolContracts.ts
index 627b34edc..b689e7b1c 100644
--- a/src/contracts/managedWorkflowToolContracts.ts
+++ b/src/contracts/managedWorkflowToolContracts.ts
@@ -8,6 +8,36 @@ import {
MANAGED_RECONSTRUCTION_IMPORT_EXAMPLE,
MANAGED_RUNTIME_CORRELATION_EXAMPLE,
} from "./managedWorkflowExamples.js";
+import { toolContractMetadata } from "./toolEffects.js";
+
+const managedEvidenceIdSchema = z
+ .string()
+ .regex(/^ev_[a-f0-9]{64}$/u)
+ .describe("Session-owned inspect_managed_members Evidence ID");
+
+/** MCP references for comparing two session-owned managed observations. */
+export const compareManagedMembersReferenceInputSchema = z
+ .strictObject({
+ left_evidence_id: managedEvidenceIdSchema,
+ right_evidence_id: managedEvidenceIdSchema,
+ limits: compareManagedMembersInputSchema.shape.limits,
+ unknown_registry_approved:
+ compareManagedMembersInputSchema.shape.unknown_registry_approved,
+ })
+ .superRefine((input, context) => {
+ if (input.left_evidence_id === input.right_evidence_id)
+ context.addIssue({
+ code: "custom",
+ path: ["right_evidence_id"],
+ message: "Managed member Evidence must be distinct",
+ });
+ });
+
+/** MCP reference for planning from one session-owned managed observation. */
+export const managedRuntimeCorrelationReferenceInputSchema =
+ managedRuntimeCorrelationInputSchema
+ .omit({ static_members: true })
+ .extend({ static_members_evidence_id: managedEvidenceIdSchema });
const comparisonOutputSchema =
managedWorkflowOutputSchemas.compare_managed_members;
@@ -32,21 +62,21 @@ if (reconstructionOutputSchema === undefined)
export const MANAGED_WORKFLOW_TOOL_CONTRACTS = [
{
name: "compare_managed_members",
+ ...toolContractMetadata("compare_managed_members"),
description:
"Compare two authenticated inspect_managed_members Evidence records using unique-only CIL/signature and structural method-shape tiers. Names are reported as observations but are not used as a matching basis; metadata tokens are remapped as build-local coordinates bound to each artifact SHA-256 and MVID.",
kind: "application",
- inputSchema: compareManagedMembersInputSchema,
+ inputSchema: compareManagedMembersReferenceInputSchema,
outputSchema: comparisonOutputSchema,
- annotations: {
- readOnlyHint: true,
- destructiveHint: false,
- idempotentHint: true,
- openWorldHint: false,
- },
examples: [
{
title: "Compare two managed member observations",
- input: MANAGED_MEMBER_COMPARISON_EXAMPLE,
+ input: {
+ left_evidence_id: MANAGED_MEMBER_COMPARISON_EXAMPLE.left.evidence_id,
+ right_evidence_id:
+ MANAGED_MEMBER_COMPARISON_EXAMPLE.right.evidence_id,
+ limits: MANAGED_MEMBER_COMPARISON_EXAMPLE.limits,
+ },
},
],
},
@@ -72,22 +102,26 @@ export const MANAGED_WORKFLOW_TOOL_CONTRACTS = [
},
{
name: "plan_managed_runtime_correlation",
+ ...toolContractMetadata("plan_managed_runtime_correlation"),
description:
"Prepare a separately authorized managed runtime-correlation admission plan from authenticated inspect_managed_members Evidence. The operation is default-disabled, requires the managed_runtime permission ceiling and grant, locks the exact artifact SHA-256, MVID, method signature, and normalized IL shape, distinguishes attach/load/debugger/reflection/instrumentation effects, and records that no target code was executed.",
kind: "application",
- inputSchema: managedRuntimeCorrelationInputSchema,
+ inputSchema: managedRuntimeCorrelationReferenceInputSchema,
outputSchema: runtimeOutputSchema,
- annotations: {
- readOnlyHint: true,
- destructiveHint: false,
- idempotentHint: true,
- openWorldHint: false,
- },
examples: [
{
title: "Plan an exact-build managed runtime correlation",
- input: MANAGED_RUNTIME_CORRELATION_EXAMPLE,
+ input: {
+ static_members_evidence_id:
+ MANAGED_RUNTIME_CORRELATION_EXAMPLE.static_members.evidence_id,
+ method: MANAGED_RUNTIME_CORRELATION_EXAMPLE.method,
+ requested_effect:
+ MANAGED_RUNTIME_CORRELATION_EXAMPLE.requested_effect,
+ host: MANAGED_RUNTIME_CORRELATION_EXAMPLE.host,
+ bounds: MANAGED_RUNTIME_CORRELATION_EXAMPLE.bounds,
+ },
},
],
},
] as const satisfies readonly ToolContract[];
+import { z } from "zod";
diff --git a/src/contracts/toolEffects.ts b/src/contracts/toolEffects.ts
index ba40b7473..9c266a87d 100644
--- a/src/contracts/toolEffects.ts
+++ b/src/contracts/toolEffects.ts
@@ -95,6 +95,10 @@ export const TOOL_EFFECTS: Readonly> = {
inventory_artifact: evidence,
extract_artifact: effects({ mutatesSession: true, writesFilesystem: true }),
inspect_managed_artifact: evidence,
+ inspect_managed_members: evidence,
+ inspect_managed_native_boundaries: evidence,
+ compare_managed_members: sessionEvidence,
+ plan_managed_runtime_correlation: sessionEvidence,
list_browser_targets: browserEvidence,
inspect_web_page: browserEvidence,
analyze_web_bundle: browserEvidence,
diff --git a/src/server/createServer.ts b/src/server/createServer.ts
index 100942c9d..b9bdb496e 100644
--- a/src/server/createServer.ts
+++ b/src/server/createServer.ts
@@ -183,6 +183,7 @@ export const createServer = (
logger: toolLogger,
recordEvidence,
recordEvidenceWithUnknown,
+ session,
runtime: {
policy: options.managedRuntimePolicy ?? {
enabled: false,
diff --git a/src/server/registerManagedWorkflowTools.ts b/src/server/registerManagedWorkflowTools.ts
index b34709cbf..65a7b1f23 100644
--- a/src/server/registerManagedWorkflowTools.ts
+++ b/src/server/registerManagedWorkflowTools.ts
@@ -1,24 +1,31 @@
import type { McpServer } from "@modelcontextprotocol/server";
import type { BinarySessionPort } from "../application/BinarySession.js";
-import { compareManagedMembersEvidence } from "../application/ManagedMemberComparisonService.js";
+import { compareManagedMembersEvidenceValidated } from "../application/ManagedMemberComparisonService.js";
import { importManagedReconstructionEvidence } from "../application/ManagedReconstructionService.js";
import {
- planManagedRuntimeCorrelationEvidence,
+ planManagedRuntimeCorrelationEvidenceValidated,
type ManagedRuntimeCorrelationDependencies,
} from "../application/ManagedRuntimeCorrelationService.js";
-import { MANAGED_WORKFLOW_TOOL_CONTRACTS } from "../contracts/managedWorkflowToolContracts.js";
import {
- compareManagedMembersInputSchema,
- managedMemberComparisonResultSchema,
-} from "../domain/managedMemberComparison.js";
+ compareManagedMembersReferenceInputSchema,
+ managedRuntimeCorrelationReferenceInputSchema,
+ MANAGED_WORKFLOW_TOOL_CONTRACTS,
+} from "../contracts/managedWorkflowToolContracts.js";
+import { managedMemberComparisonResultSchema } from "../domain/managedMemberComparison.js";
import { managedReconstructionImportInputSchema } from "../domain/managedReconstruction.js";
-import { managedRuntimeCorrelationInputSchema } from "../domain/managedRuntimeCorrelation.js";
import type { Evidence } from "../domain/evidence.js";
+import {
+ EvidenceIntegrityError,
+ EvidenceReferenceError,
+} from "../domain/errors.js";
+import { err, type Result } from "../domain/result.js";
import type { Logger } from "../logger.js";
import { logToolExecution } from "./toolLogging.js";
import { toCallToolResult } from "./toolResult.js";
import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
+import { safeParseToolInput } from "./toolInputValidation.js";
+import { resolveSessionEvidenceIds } from "./sessionEvidence.js";
interface ManagedWorkflowToolRegistration {
readonly logger: Logger;
@@ -27,6 +34,7 @@ interface ManagedWorkflowToolRegistration {
| BinarySessionPort["recordEvidenceWithUnknown"]
| undefined;
readonly runtime: ManagedRuntimeCorrelationDependencies;
+ readonly session: BinarySessionPort | undefined;
}
/** Register provider-neutral managed-code workflows. */
@@ -41,11 +49,31 @@ export const registerManagedWorkflowTools = (
compareContract.name,
toolRegistrationOptions(compareContract),
async (input) => {
- const parsed = compareManagedMembersInputSchema.parse(input);
+ const parsedInput = safeParseToolInput(
+ compareManagedMembersReferenceInputSchema,
+ input,
+ compareContract.name,
+ );
+ if (!parsedInput.ok)
+ return toCallToolResult(parsedInput, compareContract);
+ const resolved = resolveManagedEvidence(options.session, [
+ parsedInput.value.left_evidence_id,
+ parsedInput.value.right_evidence_id,
+ ]);
+ if (!resolved.ok) return toCallToolResult(resolved, compareContract);
+ const [left, right] = resolved.value;
+ if (left === undefined || right === undefined)
+ throw new TypeError("Managed comparison Evidence resolution failed");
+ const {
+ left_evidence_id: _leftEvidenceId,
+ right_evidence_id: _rightEvidenceId,
+ ...referencedInput
+ } = parsedInput.value;
+ const parsed = { ...referencedInput, left, right };
const result = await logToolExecution(
options.logger,
compareContract.name,
- () => Promise.resolve(compareManagedMembersEvidence(parsed)),
+ () => Promise.resolve(compareManagedMembersEvidenceValidated(parsed)),
);
if (!result.ok) return toCallToolResult(result, compareContract);
const recorded = recordSources(options.recordEvidence, [
@@ -117,11 +145,33 @@ export const registerManagedWorkflowTools = (
runtimeContract.name,
toolRegistrationOptions(runtimeContract),
async (input) => {
- const parsed = managedRuntimeCorrelationInputSchema.parse(input);
+ const parsedInput = safeParseToolInput(
+ managedRuntimeCorrelationReferenceInputSchema,
+ input,
+ runtimeContract.name,
+ );
+ if (!parsedInput.ok)
+ return toCallToolResult(parsedInput, runtimeContract);
+ const resolved = resolveManagedEvidence(options.session, [
+ parsedInput.value.static_members_evidence_id,
+ ]);
+ if (!resolved.ok) return toCallToolResult(resolved, runtimeContract);
+ const staticMembers = resolved.value[0];
+ if (staticMembers === undefined)
+ throw new TypeError("Managed runtime Evidence resolution failed");
+ const {
+ static_members_evidence_id: _staticMembersEvidenceId,
+ ...referencedInput
+ } = parsedInput.value;
+ const parsed = { ...referencedInput, static_members: staticMembers };
const result = await logToolExecution(
options.logger,
runtimeContract.name,
- () => planManagedRuntimeCorrelationEvidence(options.runtime, parsed),
+ () =>
+ planManagedRuntimeCorrelationEvidenceValidated(
+ options.runtime,
+ parsed,
+ ),
);
if (!result.ok) return toCallToolResult(result, runtimeContract);
const recordedSource = options.recordEvidence?.(parsed.static_members);
@@ -147,6 +197,26 @@ const contract = (
return found;
};
+const resolveManagedEvidence = (
+ session: BinarySessionPort | undefined,
+ evidenceIds: readonly string[],
+): Result => {
+ const firstId = evidenceIds[0] ?? "ev_missing";
+ return session === undefined
+ ? err(
+ new EvidenceReferenceError(
+ firstId,
+ "missing",
+ "inspect_managed_members",
+ null,
+ ),
+ )
+ : resolveSessionEvidenceIds(session, evidenceIds, {
+ operation: "inspect_managed_members",
+ predicate: "rea.analysis/v2",
+ });
+};
+
const recordSources = (
recordEvidence: ManagedWorkflowToolRegistration["recordEvidence"],
sources: readonly Evidence[],
diff --git a/src/server/toolRegistrationOptions.ts b/src/server/toolRegistrationOptions.ts
index f5d6616f3..a584a79df 100644
--- a/src/server/toolRegistrationOptions.ts
+++ b/src/server/toolRegistrationOptions.ts
@@ -127,13 +127,35 @@ const compactJsonSchema = (
const counts = new Map();
collectSchemas(schemaBody, counts, true);
const candidates = [...counts.entries()]
- .filter(([encoded, count]) => count > 1 && encoded.length >= 128)
+ .filter(([, count]) => count > 1)
.sort(
([left], [right]) =>
right.length - left.length || left.localeCompare(right),
)
- .map(([encoded], index) => [encoded, `rea_${String(index)}`] as const);
+ .map(([encoded]) => encoded);
if (candidates.length === 0) return schemaBody;
+ let compacted: Record = schemaBody;
+ let compactedBytes = JSON.stringify(compacted).length;
+ const selected: Array = [];
+ for (const encoded of candidates) {
+ const proposed = [
+ ...selected,
+ [encoded, `rea_${String(selected.length)}`] as const,
+ ];
+ const candidate = compactWithDefinitions(schemaBody, proposed);
+ const candidateBytes = JSON.stringify(candidate).length;
+ if (candidateBytes >= compactedBytes) continue;
+ selected.push([encoded, `rea_${String(selected.length)}`]);
+ compacted = candidate;
+ compactedBytes = candidateBytes;
+ }
+ return compacted;
+};
+
+const compactWithDefinitions = (
+ schemaBody: Readonly>,
+ candidates: readonly (readonly [string, string])[],
+): Record => {
const names = new Map(candidates);
const definitions = Object.fromEntries(
candidates.map(([encoded, name]) => [
diff --git a/tests/contractSnapshot.test.ts b/tests/contractSnapshot.test.ts
index ce2adc529..81a635f8f 100644
--- a/tests/contractSnapshot.test.ts
+++ b/tests/contractSnapshot.test.ts
@@ -101,6 +101,7 @@ describe("tool contract surface", () => {
...NATIVE_TOOL_CONTRACTS,
...ARTIFACT_TOOL_CONTRACTS,
...MANAGED_TOOL_CONTRACTS,
+ ...MANAGED_WORKFLOW_TOOL_CONTRACTS,
...BROWSER_TOOL_CONTRACTS,
...ELECTRON_TOOL_CONTRACTS,
...APPLICATION_TOOL_CONTRACTS,
diff --git a/tests/managedMcp.test.ts b/tests/managedMcp.test.ts
index ef83b8c08..666b53cc6 100644
--- a/tests/managedMcp.test.ts
+++ b/tests/managedMcp.test.ts
@@ -117,12 +117,13 @@ describe("managed artifact MCP tools", () => {
},
});
- const members = structured(
+ const membersResult = structured(
await client.callTool({
name: "inspect_managed_members",
arguments: { method_limit: 1 },
}),
);
+ const members = sessionEvidence(session, membersResult);
expect(members).toMatchObject({
operation: "inspect_managed_members",
@@ -144,10 +145,7 @@ describe("managed artifact MCP tools", () => {
);
expect(boundaries).toMatchObject({
- operation: "inspect_managed_native_boundaries",
- provider: { id: "rea-dotnet-static" },
- subject: { local_path: path, format: "pe" },
- normalized_result: {
+ result: {
identity_scope: { token_identity: "build-local" },
pinvoke_imports: { total: 0, limit: 1 },
native_implementations: { total: 0 },
@@ -158,18 +156,19 @@ describe("managed artifact MCP tools", () => {
name: "open_binary",
arguments: { path: rightPath },
});
- const rightMembers = structured(
+ const rightMembersResult = structured(
await client.callTool({
name: "inspect_managed_members",
arguments: { method_limit: 1 },
}),
);
- const compared = structured(
+ const rightMembers = sessionEvidence(session, rightMembersResult);
+ const comparedResult = structured(
await client.callTool({
name: "compare_managed_members",
arguments: {
- left: members,
- right: rightMembers,
+ left_evidence_id: members.evidence_id,
+ right_evidence_id: rightMembers.evidence_id,
limits: {
max_method_matches: 100,
max_field_matches: 100,
@@ -178,6 +177,7 @@ describe("managed artifact MCP tools", () => {
},
}),
);
+ const compared = sessionEvidence(session, comparedResult);
expect(compared).toMatchObject({
operation: "compare_managed_members",
@@ -205,7 +205,7 @@ describe("managed artifact MCP tools", () => {
.parse(method).items[0];
expect(methodItem).toBeDefined();
if (methodItem === undefined) return;
- const imported = structured(
+ const importedResult = structured(
await client.callTool({
name: "import_managed_reconstruction",
arguments: {
@@ -233,6 +233,7 @@ describe("managed artifact MCP tools", () => {
},
}),
);
+ const imported = sessionEvidence(session, importedResult);
expect(imported).toMatchObject({
operation: "import_managed_reconstruction",
@@ -249,11 +250,11 @@ describe("managed artifact MCP tools", () => {
],
},
});
- const planned = structured(
+ const plannedResult = structured(
await client.callTool({
name: "plan_managed_runtime_correlation",
arguments: {
- static_members: members,
+ static_members_evidence_id: members.evidence_id,
method: {
token: methodItem.token,
signature_sha256: methodItem.signature.raw_sha256,
@@ -275,6 +276,7 @@ describe("managed artifact MCP tools", () => {
},
}),
);
+ const planned = sessionEvidence(session, plannedResult);
expect(planned).toMatchObject({
operation: "plan_managed_runtime_correlation",
@@ -302,3 +304,13 @@ const structured = (result: CallToolResult): Record => {
throw new Error("missing structured result");
return z.record(z.string(), z.unknown()).parse(result.structuredContent);
};
+
+const sessionEvidence = (
+ session: BinarySession,
+ result: Readonly>,
+): Record => {
+ const evidenceId = z.string().parse(result.evidence_id);
+ const evidence = session.evidenceById(evidenceId);
+ if (evidence === undefined) throw new Error("missing session Evidence");
+ return z.record(z.string(), z.unknown()).parse(evidence);
+};
From 412bbaf05e0d6fa5add68303c83325628cc2e7da Mon Sep 17 00:00:00 2001
From: morluto <76467478+morluto@users.noreply.github.com>
Date: Thu, 16 Jul 2026 19:39:21 +0800
Subject: [PATCH 11/19] fix(mcp): hide managed workflows without a session
---
src/server/createServer.ts | 27 +++++++++---------
src/server/registerManagedWorkflowTools.ts | 32 ++++++----------------
tests/createServer.test.ts | 3 ++
3 files changed, 26 insertions(+), 36 deletions(-)
diff --git a/src/server/createServer.ts b/src/server/createServer.ts
index b9bdb496e..5ef7a5529 100644
--- a/src/server/createServer.ts
+++ b/src/server/createServer.ts
@@ -179,20 +179,21 @@ export const createServer = (
activeTarget,
recordEvidence,
});
- registerManagedWorkflowTools(server, {
- logger: toolLogger,
- recordEvidence,
- recordEvidenceWithUnknown,
- session,
- runtime: {
- policy: options.managedRuntimePolicy ?? {
- enabled: false,
- roots: [],
- executablePath: "/usr/bin/dotnet",
+ if (session !== undefined)
+ registerManagedWorkflowTools(server, {
+ logger: toolLogger,
+ recordEvidence,
+ recordEvidenceWithUnknown,
+ session,
+ runtime: {
+ policy: options.managedRuntimePolicy ?? {
+ enabled: false,
+ roots: [],
+ executablePath: "/usr/bin/dotnet",
+ },
+ authority: options.permissionAuthority,
},
- authority: options.permissionAuthority,
- },
- });
+ });
registerBrowserTools(server, {
logger: toolLogger,
browser: options.browserObservation,
diff --git a/src/server/registerManagedWorkflowTools.ts b/src/server/registerManagedWorkflowTools.ts
index 65a7b1f23..98036fcd7 100644
--- a/src/server/registerManagedWorkflowTools.ts
+++ b/src/server/registerManagedWorkflowTools.ts
@@ -15,11 +15,8 @@ import {
import { managedMemberComparisonResultSchema } from "../domain/managedMemberComparison.js";
import { managedReconstructionImportInputSchema } from "../domain/managedReconstruction.js";
import type { Evidence } from "../domain/evidence.js";
-import {
- EvidenceIntegrityError,
- EvidenceReferenceError,
-} from "../domain/errors.js";
-import { err, type Result } from "../domain/result.js";
+import type { EvidenceIntegrityError } from "../domain/errors.js";
+import type { Result } from "../domain/result.js";
import type { Logger } from "../logger.js";
import { logToolExecution } from "./toolLogging.js";
import { toCallToolResult } from "./toolResult.js";
@@ -34,7 +31,7 @@ interface ManagedWorkflowToolRegistration {
| BinarySessionPort["recordEvidenceWithUnknown"]
| undefined;
readonly runtime: ManagedRuntimeCorrelationDependencies;
- readonly session: BinarySessionPort | undefined;
+ readonly session: BinarySessionPort;
}
/** Register provider-neutral managed-code workflows. */
@@ -198,24 +195,13 @@ const contract = (
};
const resolveManagedEvidence = (
- session: BinarySessionPort | undefined,
+ session: BinarySessionPort,
evidenceIds: readonly string[],
-): Result => {
- const firstId = evidenceIds[0] ?? "ev_missing";
- return session === undefined
- ? err(
- new EvidenceReferenceError(
- firstId,
- "missing",
- "inspect_managed_members",
- null,
- ),
- )
- : resolveSessionEvidenceIds(session, evidenceIds, {
- operation: "inspect_managed_members",
- predicate: "rea.analysis/v2",
- });
-};
+): Result =>
+ resolveSessionEvidenceIds(session, evidenceIds, {
+ operation: "inspect_managed_members",
+ predicate: "rea.analysis/v2",
+ });
const recordSources = (
recordEvidence: ManagedWorkflowToolRegistration["recordEvidence"],
diff --git a/tests/createServer.test.ts b/tests/createServer.test.ts
index 6a9080114..d1eb97334 100644
--- a/tests/createServer.test.ts
+++ b/tests/createServer.test.ts
@@ -21,6 +21,9 @@ describe("beta.3 server composition", () => {
await server.connect(serverTransport);
await client.connect(clientTransport);
expect(client.getInstructions()).not.toContain("open_binary");
+ const names = (await client.listTools()).tools.map(({ name }) => name);
+ expect(names).not.toContain("compare_managed_members");
+ expect(names).not.toContain("plan_managed_runtime_correlation");
await client.close();
await server.close();
});
From cab7c4a5212eb5bf2b233c835ac57b5764a4e0f3 Mon Sep 17 00:00:00 2001
From: morluto <76467478+morluto@users.noreply.github.com>
Date: Thu, 16 Jul 2026 19:42:23 +0800
Subject: [PATCH 12/19] test(mcp): derive sessionless managed inventory
---
tests/enhancedTools.test.ts | 5 ++++-
tests/integration/serverIntegration.test.ts | 5 ++++-
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/tests/enhancedTools.test.ts b/tests/enhancedTools.test.ts
index 1b39645a6..58d923164 100644
--- a/tests/enhancedTools.test.ts
+++ b/tests/enhancedTools.test.ts
@@ -10,6 +10,7 @@ import {
TOOL_CONTRACTS,
} from "../src/contracts/toolContracts.js";
import { enhancedInputSchemas } from "../src/contracts/enhancedInputs.js";
+import { MANAGED_WORKFLOW_TOOL_CONTRACTS } from "../src/contracts/managedWorkflowToolContracts.js";
import { AnalysisOutputError } from "../src/domain/errors.js";
import { jsonValueSchema, type JsonValue } from "../src/domain/jsonValue.js";
import { err } from "../src/domain/result.js";
@@ -198,7 +199,9 @@ describe("enhanced MCP tools", () => {
const client = await connect();
const listed = await client.listTools();
expect(listed.tools).toHaveLength(
- TOOL_CONTRACTS.length - SESSION_TOOL_CONTRACTS.length,
+ TOOL_CONTRACTS.length -
+ SESSION_TOOL_CONTRACTS.length -
+ MANAGED_WORKFLOW_TOOL_CONTRACTS.length,
);
expect(
listed.tools
diff --git a/tests/integration/serverIntegration.test.ts b/tests/integration/serverIntegration.test.ts
index 3c17e4ef4..7d35a505a 100644
--- a/tests/integration/serverIntegration.test.ts
+++ b/tests/integration/serverIntegration.test.ts
@@ -23,6 +23,7 @@ import {
SESSION_TOOL_CONTRACTS,
TOOL_CONTRACTS,
} from "../../src/contracts/toolContracts.js";
+import { MANAGED_WORKFLOW_TOOL_CONTRACTS } from "../../src/contracts/managedWorkflowToolContracts.js";
const resources: Array<{ close(): Promise }> = [];
@@ -453,7 +454,9 @@ describe("full MCP integration with multi-tool sequences", () => {
});
const listed = await client.listTools();
expect(listed.tools).toHaveLength(
- TOOL_CONTRACTS.length - SESSION_TOOL_CONTRACTS.length,
+ TOOL_CONTRACTS.length -
+ SESSION_TOOL_CONTRACTS.length -
+ MANAGED_WORKFLOW_TOOL_CONTRACTS.length,
);
const names = listed.tools.map((t) => t.name);
expect(names).toContain("binary_overview");
From f7aa19154d9bc24b3ccdb8bde40ee926f06049a1 Mon Sep 17 00:00:00 2001
From: morluto <76467478+morluto@users.noreply.github.com>
Date: Thu, 16 Jul 2026 19:45:39 +0800
Subject: [PATCH 13/19] refactor(mcp): remove obsolete managed evidence parser
---
src/application/ManagedMemberComparisonService.ts | 11 -----------
1 file changed, 11 deletions(-)
diff --git a/src/application/ManagedMemberComparisonService.ts b/src/application/ManagedMemberComparisonService.ts
index 754bcf5f5..103435acd 100644
--- a/src/application/ManagedMemberComparisonService.ts
+++ b/src/application/ManagedMemberComparisonService.ts
@@ -4,7 +4,6 @@ import { z } from "zod";
import {
compareManagedMembers,
- compareManagedMembersInputSchema,
managedMemberComparisonResultSchema,
parseManagedMemberEvidence,
type CompareManagedMembersInput,
@@ -22,16 +21,6 @@ import { inspectManagedMembersBytes } from "../dotnet/ManagedMemberInspector.js"
import { MANAGED_STATIC_PROVIDER } from "./InvestigationProviders.js";
import { MANAGED_WORKFLOW_PROVIDER } from "./InvestigationProviders.js";
-/** Authenticate two managed member Evidence records and compare token remaps. */
-export const compareManagedMembersEvidence = (
- rawInput: unknown,
-): Result => {
- const operation = "compare_managed_members";
- const parsed = compareManagedMembersInputSchema.safeParse(rawInput);
- if (!parsed.success) return err(new AnalysisInputError(operation));
- return compareManagedMembersEvidenceValidated(parsed.data);
-};
-
/** Compare managed members from input parsed by a trusted adapter. */
export const compareManagedMembersEvidenceValidated = (
input: CompareManagedMembersInput,
From fd08025dcd21cc31fa1e7356c90e76b4863b1af2 Mon Sep 17 00:00:00 2001
From: morluto <76467478+morluto@users.noreply.github.com>
Date: Thu, 16 Jul 2026 20:09:14 +0800
Subject: [PATCH 14/19] fix(mcp): remove arbitrary schema byte gate
---
.github/pull_request_template.md | 2 +-
AGENTS.md | 11 +-
CONTRIBUTING.md | 4 +-
docs/mcp-schema-report.json | 539 -------------------------
package.json | 5 +-
scripts/generate-mcp-schema-report.mjs | 69 ----
scripts/lib/docs-facts.mjs | 28 --
tests/createServer.test.ts | 2 +-
tests/productCatalog.test.ts | 20 +-
9 files changed, 26 insertions(+), 654 deletions(-)
delete mode 100644 docs/mcp-schema-report.json
delete mode 100644 scripts/generate-mcp-schema-report.mjs
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 49457378b..8c3078530 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -27,7 +27,7 @@
## Tool Contract Impact
-
+
## Related Issues
diff --git a/AGENTS.md b/AGENTS.md
index fc8505ae7..89a92d735 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -26,7 +26,7 @@ See [docs/architecture.mermaid](docs/architecture.mermaid) for a visual architec
- `src/cli.ts`: one-shot CLI adapter for setup, diagnostics, analysis, and decompilation.
- `src/config.ts`: Zod-validated parsing of environment configuration into `AppConfig`.
- `src/domain/`: pure, side-effect-free modules. `errors.ts` owns the tagged error algebra; `result.ts` owns `Result`/`ok`/`err`; `hopperValues.ts` owns shared function-dossier values plus Hopper boundary parsers; `symbolAnalysis.ts` parses Swift/ObjC names; `javascriptApplicationGraph.ts` validates and canonically commits the provider-neutral JavaScript Application Graph; `javascriptStaticAnalysis.ts` performs bounded AST-only JavaScript structure recovery.
-- `src/contracts/`: caller-visible schemas for 33 direct, 10 enhanced, 5 native, 2 artifact, 6 managed, 8 browser, 4 Electron, 3 application, and 18 session tools; `enhancedInputs.ts` owns enhanced input parsing.
+- `src/contracts/`: caller-visible tool schemas and catalog metadata; `toolContracts.ts` owns the canonical inventory and `enhancedInputs.ts` owns enhanced input parsing.
- `src/process/`: provider-neutral process ownership and lifecycle primitives. It owns private runtime roots, absolute startup deadlines, correlated request waits, bounded output capture, and TERM-to-KILL cleanup without defining any provider wire protocol.
- `src/replay/`: Linux x64 controlled-JavaScript-replay adapter. It owns exact runtime closure inspection, Bubblewrap/seccomp/cgroup admission, the disposable worker, strict parent/worker protocol validation, and complete cleanup observation.
- `src/browser/`: loopback CDP discovery, bounded WebSocket transport, exact-origin target authorization, and passive browser observation normalization.
@@ -47,13 +47,14 @@ See [docs/architecture.mermaid](docs/architecture.mermaid) for a visual architec
## Build, Test, and Development Commands
- `npm ci`: install exact lockfile dependencies.
+- `npm run deps:check`: verify that installed direct dependency versions match the root lockfile; on failure, run `npm ci`, then retry.
- `npm run build`: compile `src/` into `dist/`.
- `npm test`: build, then run the Vitest suite once.
- `npm run typecheck`: run strict TypeScript checks without emitting files.
- `npm run lint`: apply oxlint rules (complexity, max-lines, unused vars, and TypeScript-specific checks).
- `npm run lint:fix`: auto-fix oxlint violations where possible.
- `npm run format:check`: verify Prettier formatting.
-- `npm run check`: run typecheck, lint, format:check, and tests.
+- `npm run check`: run typecheck, lint, format:check, generated-document freshness checks, and tests.
- `npm run knip`: detect unused files, dependencies, and exports.
- `npm run jscpd`: detect duplicate code blocks.
- `npm run scan:todos`: scan for TODO, FIXME, and HACK markers.
@@ -62,7 +63,7 @@ See [docs/architecture.mermaid](docs/architecture.mermaid) for a visual architec
- `npm run verify:browser`: build and run the real Chrome verifier against `REA_BROWSER_EXECUTABLE` or a platform-default Chrome-family executable.
- `npm run verify:managed`: build and run the source-owned managed PE/CLI conformance verifier for artifact triage, member inspection, managed/native boundary declarations, token drift comparison, malformed metadata, and non-managed degradation.
- `npm run verify:replay`: build and run the real Linux Bubblewrap/seccomp/cgroup verifier against source-owned replay fixtures; set `REA_REPLAY_INPUT_PATH` to verify an operator-local manifest.
-- `npm run verify:package`: pack and test the CLI, setup transaction, skill, and 89-tool target-free MCP server in an isolated environment.
+- `npm run verify:package`: pack and test the CLI, setup transaction, skill, and canonical target-free MCP catalog in an isolated environment.
- `npm run docs:generate`: generate API documentation from JSDoc comments into `docs/api/` using TypeDoc.
- `npm run docs:check`: verify generated package metadata, the canonical product catalog, caller-visible documentation facts, TypeDoc output, and the error JSON schema without rewriting them.
- `npm run config:print -- /path/to/binary`: print an MCP server config with absolute paths.
@@ -96,7 +97,9 @@ Use ESM TypeScript, two-space indentation, and Prettier defaults. Keep compiler
## Testing Guidelines
-Name tests `*.test.ts`. Use Vitest and production seams (`tests/fixtures/`) rather than module mocks. Domain tests assert pure behavior; adapter tests use fake launcher/socket seams; MCP tests connect with the beta.3 client. Preserve the 33 direct, 10 enhanced, 5 native, 2 artifact, 6 managed, 8 browser, 4 Electron, 3 application, and 18 session tool inventory (89 total). Cover malformed input, cancellation, timeouts, process exit, concurrency, limits, and clean shutdown. Real Hopper, Ghidra, browser, JavaScript replay, managed conformance, and any real managed-tool claims cannot be replaced by mocks; use the corresponding `verify:*` command.
+Name tests `*.test.ts`. Use Vitest and production seams (`tests/fixtures/`) rather than module mocks. Domain tests assert pure behavior; adapter tests use fake launcher/socket seams; MCP tests connect with the client SDK version pinned in `package.json`. Preserve the canonical tool inventory defined by `TOOL_CONTRACTS` and verified through `CATALOG_IDENTITY` and generated product metadata. Cover malformed input, cancellation, timeouts, process exit, concurrency, limits, and clean shutdown. Real Hopper, Ghidra, browser, JavaScript replay, managed conformance, and any real managed-tool claims cannot be replaced by mocks; use the corresponding `verify:*` command.
+
+MCP tool catalogs must remain complete and self-describing. Prefer capability- and session-scoped tool advertisement over schema truncation. Do not impose arbitrary serialized-byte ceilings on tool schemas or `tools/list`; assess model-context cost only against a named client's actual model-facing projection and tokenizer.
## Commit & Pull Request Guidelines
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 666caaedf..36bfddcbe 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -17,7 +17,7 @@ the package `prepare` lifecycle, and prepares the Husky hook. Run
`npm run build` again after source changes when you need the standalone CLI or
MCP server without running the test prebuild.
-Keep dependencies flowing inward through the existing domain, contracts, provider, application, server, and adapter layers. Parse unknown values at process and protocol boundaries, model expected failures with `Result`, and preserve the 33 direct, 10 enhanced, 5 native, 2 artifact, 8 browser, 4 Electron, 2 application workflow, and 18 session tools (82 total) unless a deliberate contract change updates every verifier and snapshot.
+Keep dependencies flowing inward through the existing domain, contracts, provider, application, server, and adapter layers. Parse unknown values at process and protocol boundaries, model expected failures with `Result`, and preserve the canonical tool inventory defined by `TOOL_CONTRACTS` unless a deliberate contract change updates every verifier, generated catalog artifact, and snapshot. Prefer capability- and session-scoped tool advertisement over schema truncation.
Before submitting a pull request, run:
@@ -75,7 +75,7 @@ Publish the public package:
npm publish --access public
```
-After npm registry propagation, verify the published CLI and connect a beta.3 MCP client to the published server to confirm all 82 tools:
+After npm registry propagation, verify the published CLI and connect the client SDK version pinned in `package.json` to the published server to confirm the canonical tool catalog:
```bash
npx -y rea-agents --help
diff --git a/docs/mcp-schema-report.json b/docs/mcp-schema-report.json
deleted file mode 100644
index edd6f7449..000000000
--- a/docs/mcp-schema-report.json
+++ /dev/null
@@ -1,539 +0,0 @@
-{
- "generated_from": "@modelcontextprotocol/server 2.0.0-beta.4 wire registration",
- "tool_count": 88,
- "tools_list_bytes": 517143,
- "budgets": {
- "tools_list_bytes": 524288,
- "per_tool_bytes": 65536
- },
- "tools": [
- {
- "name": "address_name",
- "bytes": 1133,
- "input_schema_bytes": 401,
- "output_schema_bytes": 313
- },
- {
- "name": "analyze_function",
- "bytes": 8935,
- "input_schema_bytes": 2037,
- "output_schema_bytes": 6421
- },
- {
- "name": "analyze_javascript_application",
- "bytes": 17446,
- "input_schema_bytes": 2633,
- "output_schema_bytes": 14172
- },
- {
- "name": "analyze_swift_types",
- "bytes": 1321,
- "input_schema_bytes": 62,
- "output_schema_bytes": 852
- },
- {
- "name": "analyze_web_bundle",
- "bytes": 14276,
- "input_schema_bytes": 6550,
- "output_schema_bytes": 7221
- },
- {
- "name": "batch_decompile",
- "bytes": 10638,
- "input_schema_bytes": 226,
- "output_schema_bytes": 10011
- },
- {
- "name": "binary_overview",
- "bytes": 1620,
- "input_schema_bytes": 250,
- "output_schema_bytes": 954
- },
- {
- "name": "binary_session",
- "bytes": 11822,
- "input_schema_bytes": 367,
- "output_schema_bytes": 10955
- },
- {
- "name": "build_call_path",
- "bytes": 10235,
- "input_schema_bytes": 6850,
- "output_schema_bytes": 2913
- },
- {
- "name": "capture_process_scenario",
- "bytes": 19830,
- "input_schema_bytes": 10303,
- "output_schema_bytes": 8773
- },
- {
- "name": "capture_web_screenshot",
- "bytes": 5389,
- "input_schema_bytes": 771,
- "output_schema_bytes": 4182
- },
- {
- "name": "close_binary",
- "bytes": 1073,
- "input_schema_bytes": 214,
- "output_schema_bytes": 379
- },
- {
- "name": "comment",
- "bytes": 1082,
- "input_schema_bytes": 401,
- "output_schema_bytes": 313
- },
- {
- "name": "compare_application_versions",
- "bytes": 24888,
- "input_schema_bytes": 9296,
- "output_schema_bytes": 15024
- },
- {
- "name": "compare_artifacts",
- "bytes": 3869,
- "input_schema_bytes": 759,
- "output_schema_bytes": 2625
- },
- {
- "name": "compare_bundles",
- "bytes": 4169,
- "input_schema_bytes": 928,
- "output_schema_bytes": 2742
- },
- {
- "name": "compare_functions",
- "bytes": 4356,
- "input_schema_bytes": 725,
- "output_schema_bytes": 3139
- },
- {
- "name": "compare_managed_members",
- "bytes": 7583,
- "input_schema_bytes": 960,
- "output_schema_bytes": 6099
- },
- {
- "name": "compare_process_captures",
- "bytes": 3311,
- "input_schema_bytes": 565,
- "output_schema_bytes": 2161
- },
- {
- "name": "compare_web_captures",
- "bytes": 29996,
- "input_schema_bytes": 27683,
- "output_schema_bytes": 1873
- },
- {
- "name": "compare_web_screenshots",
- "bytes": 3351,
- "input_schema_bytes": 1412,
- "output_schema_bytes": 1546
- },
- {
- "name": "correlate_static_and_runtime",
- "bytes": 12426,
- "input_schema_bytes": 8307,
- "output_schema_bytes": 3626
- },
- {
- "name": "current_address",
- "bytes": 938,
- "input_schema_bytes": 282,
- "output_schema_bytes": 285
- },
- {
- "name": "current_document",
- "bytes": 842,
- "input_schema_bytes": 219,
- "output_schema_bytes": 285
- },
- {
- "name": "current_procedure",
- "bytes": 952,
- "input_schema_bytes": 282,
- "output_schema_bytes": 285
- },
- {
- "name": "demangle_swift",
- "bytes": 2276,
- "input_schema_bytes": 221,
- "output_schema_bytes": 1717
- },
- {
- "name": "discover_webmcp_tools",
- "bytes": 6797,
- "input_schema_bytes": 1087,
- "output_schema_bytes": 5306
- },
- {
- "name": "export_evidence_bundle",
- "bytes": 11008,
- "input_schema_bytes": 196,
- "output_schema_bytes": 10384
- },
- {
- "name": "extract_artifact",
- "bytes": 6212,
- "input_schema_bytes": 1321,
- "output_schema_bytes": 4499
- },
- {
- "name": "find_changed_behavior",
- "bytes": 12036,
- "input_schema_bytes": 8540,
- "output_schema_bytes": 2968
- },
- {
- "name": "find_xrefs_to_name",
- "bytes": 1346,
- "input_schema_bytes": 128,
- "output_schema_bytes": 763
- },
- {
- "name": "get_call_graph",
- "bytes": 10619,
- "input_schema_bytes": 361,
- "output_schema_bytes": 9786
- },
- {
- "name": "get_objc_classes",
- "bytes": 1141,
- "input_schema_bytes": 127,
- "output_schema_bytes": 606
- },
- {
- "name": "get_objc_protocols",
- "bytes": 1079,
- "input_schema_bytes": 62,
- "output_schema_bytes": 610
- },
- {
- "name": "goto_address",
- "bytes": 1094,
- "input_schema_bytes": 424,
- "output_schema_bytes": 285
- },
- {
- "name": "import_evidence_bundle",
- "bytes": 882,
- "input_schema_bytes": 142,
- "output_schema_bytes": 321
- },
- {
- "name": "inline_comment",
- "bytes": 1064,
- "input_schema_bytes": 401,
- "output_schema_bytes": 313
- },
- {
- "name": "inspect_electron_page",
- "bytes": 9514,
- "input_schema_bytes": 1936,
- "output_schema_bytes": 7118
- },
- {
- "name": "inspect_macho",
- "bytes": 7672,
- "input_schema_bytes": 62,
- "output_schema_bytes": 7237
- },
- {
- "name": "inspect_managed_artifact",
- "bytes": 11489,
- "input_schema_bytes": 1251,
- "output_schema_bytes": 9754
- },
- {
- "name": "inspect_managed_members",
- "bytes": 13925,
- "input_schema_bytes": 2048,
- "output_schema_bytes": 11387
- },
- {
- "name": "inspect_managed_native_boundaries",
- "bytes": 9704,
- "input_schema_bytes": 1267,
- "output_schema_bytes": 7912
- },
- {
- "name": "inspect_plist",
- "bytes": 2769,
- "input_schema_bytes": 189,
- "output_schema_bytes": 2206
- },
- {
- "name": "inspect_signature",
- "bytes": 2793,
- "input_schema_bytes": 62,
- "output_schema_bytes": 2366
- },
- {
- "name": "inspect_web_page",
- "bytes": 21829,
- "input_schema_bytes": 5042,
- "output_schema_bytes": 16277
- },
- {
- "name": "inventory_artifact",
- "bytes": 9791,
- "input_schema_bytes": 1885,
- "output_schema_bytes": 7519
- },
- {
- "name": "list_architectures",
- "bytes": 2555,
- "input_schema_bytes": 62,
- "output_schema_bytes": 2160
- },
- {
- "name": "list_bookmarks",
- "bytes": 1091,
- "input_schema_bytes": 282,
- "output_schema_bytes": 437
- },
- {
- "name": "list_browser_targets",
- "bytes": 2950,
- "input_schema_bytes": 658,
- "output_schema_bytes": 1844
- },
- {
- "name": "list_documents",
- "bytes": 883,
- "input_schema_bytes": 219,
- "output_schema_bytes": 310
- },
- {
- "name": "list_electron_targets",
- "bytes": 2869,
- "input_schema_bytes": 636,
- "output_schema_bytes": 1810
- },
- {
- "name": "list_names",
- "bytes": 2786,
- "input_schema_bytes": 594,
- "output_schema_bytes": 1762
- },
- {
- "name": "list_procedures",
- "bytes": 2683,
- "input_schema_bytes": 475,
- "output_schema_bytes": 1762
- },
- {
- "name": "list_segments",
- "bytes": 2656,
- "input_schema_bytes": 282,
- "output_schema_bytes": 1967
- },
- {
- "name": "list_strings",
- "bytes": 2781,
- "input_schema_bytes": 594,
- "output_schema_bytes": 1762
- },
- {
- "name": "list_unknowns",
- "bytes": 4279,
- "input_schema_bytes": 358,
- "output_schema_bytes": 3512
- },
- {
- "name": "next_address",
- "bytes": 1039,
- "input_schema_bytes": 401,
- "output_schema_bytes": 285
- },
- {
- "name": "observe_web_session",
- "bytes": 5976,
- "input_schema_bytes": 765,
- "output_schema_bytes": 4746
- },
- {
- "name": "open_binary",
- "bytes": 1702,
- "input_schema_bytes": 386,
- "output_schema_bytes": 696
- },
- {
- "name": "plan_managed_runtime_correlation",
- "bytes": 7556,
- "input_schema_bytes": 2128,
- "output_schema_bytes": 4768
- },
- {
- "name": "prev_address",
- "bytes": 1045,
- "input_schema_bytes": 401,
- "output_schema_bytes": 285
- },
- {
- "name": "procedure_address",
- "bytes": 1082,
- "input_schema_bytes": 383,
- "output_schema_bytes": 285
- },
- {
- "name": "procedure_assembly",
- "bytes": 1096,
- "input_schema_bytes": 383,
- "output_schema_bytes": 285
- },
- {
- "name": "procedure_callees",
- "bytes": 1121,
- "input_schema_bytes": 383,
- "output_schema_bytes": 310
- },
- {
- "name": "procedure_callers",
- "bytes": 1085,
- "input_schema_bytes": 383,
- "output_schema_bytes": 310
- },
- {
- "name": "procedure_info",
- "bytes": 1982,
- "input_schema_bytes": 383,
- "output_schema_bytes": 1216
- },
- {
- "name": "procedure_pseudo_code",
- "bytes": 1172,
- "input_schema_bytes": 383,
- "output_schema_bytes": 313
- },
- {
- "name": "procedure_references",
- "bytes": 4192,
- "input_schema_bytes": 798,
- "output_schema_bytes": 2927
- },
- {
- "name": "reconcile_javascript_runtime",
- "bytes": 27214,
- "input_schema_bytes": 8993,
- "output_schema_bytes": 17696
- },
- {
- "name": "record_unknown",
- "bytes": 6527,
- "input_schema_bytes": 2646,
- "output_schema_bytes": 3487
- },
- {
- "name": "resolve_containing_procedure",
- "bytes": 2185,
- "input_schema_bytes": 424,
- "output_schema_bytes": 1280
- },
- {
- "name": "run_controlled_replay",
- "bytes": 19234,
- "input_schema_bytes": 5922,
- "output_schema_bytes": 12725
- },
- {
- "name": "search_procedures",
- "bytes": 2215,
- "input_schema_bytes": 812,
- "output_schema_bytes": 941
- },
- {
- "name": "search_strings",
- "bytes": 2224,
- "input_schema_bytes": 812,
- "output_schema_bytes": 941
- },
- {
- "name": "set_address_name",
- "bytes": 1141,
- "input_schema_bytes": 478,
- "output_schema_bytes": 286
- },
- {
- "name": "set_addresses_names",
- "bytes": 1175,
- "input_schema_bytes": 427,
- "output_schema_bytes": 361
- },
- {
- "name": "set_bookmark",
- "bytes": 1118,
- "input_schema_bytes": 471,
- "output_schema_bytes": 286
- },
- {
- "name": "set_comment",
- "bytes": 1148,
- "input_schema_bytes": 487,
- "output_schema_bytes": 286
- },
- {
- "name": "set_current_document",
- "bytes": 1003,
- "input_schema_bytes": 298,
- "output_schema_bytes": 285
- },
- {
- "name": "set_inline_comment",
- "bytes": 1142,
- "input_schema_bytes": 487,
- "output_schema_bytes": 286
- },
- {
- "name": "swift_classes",
- "bytes": 1135,
- "input_schema_bytes": 127,
- "output_schema_bytes": 606
- },
- {
- "name": "trace_application_feature",
- "bytes": 24958,
- "input_schema_bytes": 8688,
- "output_schema_bytes": 15739
- },
- {
- "name": "trace_feature",
- "bytes": 3340,
- "input_schema_bytes": 555,
- "output_schema_bytes": 2299
- },
- {
- "name": "unset_bookmark",
- "bytes": 1055,
- "input_schema_bytes": 424,
- "output_schema_bytes": 286
- },
- {
- "name": "update_unknown",
- "bytes": 7572,
- "input_schema_bytes": 3696,
- "output_schema_bytes": 3487
- },
- {
- "name": "verify_reconstruction",
- "bytes": 6161,
- "input_schema_bytes": 2455,
- "output_schema_bytes": 3212
- },
- {
- "name": "verify_unknown_resolution",
- "bytes": 4283,
- "input_schema_bytes": 177,
- "output_schema_bytes": 3668
- },
- {
- "name": "xrefs",
- "bytes": 1112,
- "input_schema_bytes": 401,
- "output_schema_bytes": 310
- }
- ]
-}
diff --git a/package.json b/package.json
index 761338fe2..6c39fd456 100644
--- a/package.json
+++ b/package.json
@@ -87,9 +87,8 @@
"verify:package": "npm run build && node scripts/verify-package.mjs",
"verify:published": "node scripts/verify-published-package.mjs",
"config:print": "node scripts/print-mcp-config.mjs",
- "docs:generate": "npm run build && node scripts/generate-skill-metadata.mjs && node scripts/generate-mcp-schema-report.mjs && node scripts/generate-product-catalog.mjs && typedoc && node scripts/generate-error-schema.mjs",
- "docs:check": "node scripts/generate-package-metadata.mjs --check && npm run build && node scripts/generate-skill-metadata.mjs --check && node scripts/generate-mcp-schema-report.mjs --check && node scripts/generate-product-catalog.mjs --check && node scripts/check-doc-facts.mjs && node scripts/check-typedoc.mjs && node scripts/generate-error-schema.mjs --check",
- "schemas:report": "npm run build && node scripts/generate-mcp-schema-report.mjs",
+ "docs:generate": "npm run build && node scripts/generate-skill-metadata.mjs && node scripts/generate-product-catalog.mjs && typedoc && node scripts/generate-error-schema.mjs",
+ "docs:check": "node scripts/generate-package-metadata.mjs --check && npm run build && node scripts/generate-skill-metadata.mjs --check && node scripts/generate-product-catalog.mjs --check && node scripts/check-doc-facts.mjs && node scripts/check-typedoc.mjs && node scripts/generate-error-schema.mjs --check",
"docs:error-schema": "npm run build && node scripts/generate-error-schema.mjs",
"prepack": "npm run deps:check && node scripts/generate-skill-metadata.mjs --check",
"prepublishOnly": "npm run deps:check && node scripts/generate-skill-metadata.mjs --check",
diff --git a/scripts/generate-mcp-schema-report.mjs b/scripts/generate-mcp-schema-report.mjs
deleted file mode 100644
index 808b75710..000000000
--- a/scripts/generate-mcp-schema-report.mjs
+++ /dev/null
@@ -1,69 +0,0 @@
-import { Buffer } from "node:buffer";
-import { dirname, join } from "node:path";
-import { fileURLToPath, pathToFileURL } from "node:url";
-
-import { ensureGeneratedFile } from "./lib/generated-file.mjs";
-
-const arguments_ = new Set(process.argv.slice(2));
-for (const argument of arguments_)
- if (argument !== "--check")
- throw new Error(`Unknown MCP schema report option: ${argument}`);
-
-const root = join(dirname(fileURLToPath(import.meta.url)), "..");
-const cachebuster = `?${String(Date.now())}`;
-const { TOOL_CONTRACTS } = await import(
- `${pathToFileURL(join(root, "dist/contracts/toolContracts.js")).href}${cachebuster}`
-);
-const { toolRegistrationOptions } = await import(
- `${pathToFileURL(join(root, "dist/server/toolRegistrationOptions.js")).href}${cachebuster}`
-);
-
-const bytes = (value) => Buffer.byteLength(JSON.stringify(value), "utf8");
-const tools = TOOL_CONTRACTS.map((contract) => {
- const registration = toolRegistrationOptions(contract);
- const inputSchema = registration.inputSchema["~standard"].jsonSchema.input();
- const outputSchema =
- registration.outputSchema["~standard"].jsonSchema.output();
- const wire = {
- name: contract.name,
- title: registration.title,
- description: registration.description,
- inputSchema,
- outputSchema,
- annotations: registration.annotations,
- };
- return {
- name: contract.name,
- bytes: bytes(wire),
- input_schema_bytes: bytes(inputSchema),
- output_schema_bytes: bytes(outputSchema),
- wire,
- };
-}).sort((left, right) => left.name.localeCompare(right.name));
-
-const maximumToolBytes = 64 * 1024;
-const maximumListBytes = 512 * 1024;
-const listBytes = bytes({ tools: tools.map(({ wire }) => wire) });
-const oversized = tools.filter((tool) => tool.bytes > maximumToolBytes);
-if (oversized.length > 0 || listBytes > maximumListBytes)
- throw new Error(
- `MCP schema budget exceeded: tools/list=${String(listBytes)}, oversized=${oversized.map(({ name, bytes: size }) => `${name}:${String(size)}`).join(",")}`,
- );
-
-const report = {
- generated_from: "@modelcontextprotocol/server 2.0.0-beta.4 wire registration",
- tool_count: tools.length,
- tools_list_bytes: listBytes,
- budgets: {
- tools_list_bytes: maximumListBytes,
- per_tool_bytes: maximumToolBytes,
- },
- tools: tools.map(({ wire: _wire, ...tool }) => tool),
-};
-
-await ensureGeneratedFile({
- path: join(root, "docs/mcp-schema-report.json"),
- source: `${JSON.stringify(report, null, 2)}\n`,
- check: arguments_.has("--check"),
- generateCommand: "npm run docs:generate",
-});
diff --git a/scripts/lib/docs-facts.mjs b/scripts/lib/docs-facts.mjs
index 3c14951b2..0aed20f37 100644
--- a/scripts/lib/docs-facts.mjs
+++ b/scripts/lib/docs-facts.mjs
@@ -8,8 +8,6 @@ const README_PATHS = [
"README_ko.md",
"README_ar.md",
];
-const familyLabel = (id) => (id === "electron" ? "Electron" : id);
-
const tableCounts = (content, path, expectedCounts) => {
const lines = content.split(/\r?\n/u);
for (const [index, line] of lines.entries()) {
@@ -50,37 +48,11 @@ export const documentationFactIssues = async (root, catalog) => {
}
}
- const inventory = catalog.tools.families
- .map(({ id, count }) => `${String(count)} ${familyLabel(id)}`)
- .join(", ")
- .replace(/, ([^,]+)$/u, ", and $1");
- const plusInventory = catalog.tools.families
- .map(({ id, count }) => `${String(count)} ${familyLabel(id)}`)
- .join(" + ");
const agents = await readFile(join(root, "AGENTS.md"), "utf8");
- requireText(issues, "AGENTS.md", agents, inventory);
- requireText(
- issues,
- "AGENTS.md",
- agents,
- `(${String(catalog.tools.total)} total)`,
- );
- requireText(
- issues,
- "AGENTS.md",
- agents,
- `${String(catalog.tools.total)}-tool target-free MCP server`,
- );
requireText(issues, "AGENTS.md", agents, "docs/product-catalog.json");
const templatePath = ".github/pull_request_template.md";
const template = await readFile(join(root, templatePath), "utf8");
- requireText(
- issues,
- templatePath,
- template,
- `current inventory is ${String(catalog.tools.total)} tools (${plusInventory})`,
- );
requireText(issues, templatePath, template, "docs/product-catalog.json");
const english = await readFile(join(root, "README.md"), "utf8");
diff --git a/tests/createServer.test.ts b/tests/createServer.test.ts
index d1eb97334..219a2e1a0 100644
--- a/tests/createServer.test.ts
+++ b/tests/createServer.test.ts
@@ -8,7 +8,7 @@ const analysis = {
execute: () => Promise.resolve(ok(null)),
};
-describe("beta.3 server composition", () => {
+describe("MCP server composition", () => {
it("constructs independent MCP server instances", () => {
expect(createServer(analysis)).not.toBe(createServer(analysis));
});
diff --git a/tests/productCatalog.test.ts b/tests/productCatalog.test.ts
index c8fbd6f10..d34ced48b 100644
--- a/tests/productCatalog.test.ts
+++ b/tests/productCatalog.test.ts
@@ -170,11 +170,19 @@ describe("canonical product catalog", () => {
}
});
- it("reports tool, setup-client, and schema fact drift", async () => {
+ it("reports tool-family, setup-client, and schema fact drift", async () => {
const catalog = await createProductCatalog(root);
+ const firstFamily = catalog.tools.families[0];
+ if (firstFamily === undefined) throw new TypeError("Missing tool family");
const drifted = {
...catalog,
- tools: { ...catalog.tools, total: catalog.tools.total + 1 },
+ tools: {
+ ...catalog.tools,
+ families: [
+ { ...firstFamily, count: firstFamily.count + 1 },
+ ...catalog.tools.families.slice(1),
+ ],
+ },
setup_clients: [
...catalog.setup_clients,
{
@@ -191,11 +199,9 @@ describe("canonical product catalog", () => {
),
};
const issues = await documentationFactIssues(root, drifted);
- expect(
- issues.some((issue) =>
- issue.includes(`${String(catalog.tools.total + 1)}-tool`),
- ),
- ).toBe(true);
+ expect(issues.some((issue) => issue.includes("tool family counts"))).toBe(
+ true,
+ );
expect(issues.some((issue) => issue.includes("Future Client"))).toBe(true);
expect(issues.some((issue) => issue.includes("Process Capture v5"))).toBe(
true,
From d36af5d0f708637f514f356521242b2b1066c8ed Mon Sep 17 00:00:00 2001
From: morluto <76467478+morluto@users.noreply.github.com>
Date: Thu, 16 Jul 2026 20:15:24 +0800
Subject: [PATCH 15/19] feat(mcp)!: require Evidence for managed reconstruction
---
.../ManagedReconstructionService.ts | 11 +++++--
src/contracts/managedWorkflowToolContracts.ts | 23 +++++++++-----
src/contracts/toolEffects.ts | 1 +
src/server/registerManagedWorkflowTools.ts | 30 ++++++++++++++++---
tests/managedMcp.test.ts | 2 +-
5 files changed, 52 insertions(+), 15 deletions(-)
diff --git a/src/application/ManagedReconstructionService.ts b/src/application/ManagedReconstructionService.ts
index 872f73c04..b867450f2 100644
--- a/src/application/ManagedReconstructionService.ts
+++ b/src/application/ManagedReconstructionService.ts
@@ -25,9 +25,16 @@ export const importManagedReconstructionEvidence = (
const parsed = managedReconstructionImportInputSchema.safeParse(rawInput);
if (!parsed.success)
return err(new AnalysisInputError(OPERATION, { cause: parsed.error }));
+ return importManagedReconstructionEvidenceValidated(parsed.data);
+};
+
+/** Import reconstruction from input parsed by a trusted adapter. */
+export const importManagedReconstructionEvidenceValidated = (
+ input: ManagedReconstructionImportInput,
+): Result => {
try {
- const result = importManagedReconstruction(parsed.data);
- return ok(createManagedReconstructionEvidence(parsed.data, result));
+ const result = importManagedReconstruction(input);
+ return ok(createManagedReconstructionEvidence(input, result));
} catch (cause: unknown) {
return err(
cause instanceof TypeError || cause instanceof z.ZodError
diff --git a/src/contracts/managedWorkflowToolContracts.ts b/src/contracts/managedWorkflowToolContracts.ts
index b689e7b1c..58ef1beea 100644
--- a/src/contracts/managedWorkflowToolContracts.ts
+++ b/src/contracts/managedWorkflowToolContracts.ts
@@ -39,6 +39,12 @@ export const managedRuntimeCorrelationReferenceInputSchema =
.omit({ static_members: true })
.extend({ static_members_evidence_id: managedEvidenceIdSchema });
+/** MCP reference for importing reconstruction against session Evidence. */
+export const managedReconstructionReferenceInputSchema =
+ managedReconstructionImportInputSchema
+ .omit({ static_members: true })
+ .extend({ static_members_evidence_id: managedEvidenceIdSchema });
+
const comparisonOutputSchema =
managedWorkflowOutputSchemas.compare_managed_members;
if (comparisonOutputSchema === undefined)
@@ -82,21 +88,22 @@ export const MANAGED_WORKFLOW_TOOL_CONTRACTS = [
},
{
name: "import_managed_reconstruction",
+ ...toolContractMetadata("import_managed_reconstruction"),
description:
"Import decompiler-produced managed reconstruction against authenticated inspect_managed_members Evidence. The workflow locks each method to artifact SHA-256, MVID, metadata token, signature hash, and normalized IL hash, records the decompiler identity and options, and marks C# or pseudocode as analyst inference rather than canonical byte observation.",
kind: "application",
- inputSchema: managedReconstructionImportInputSchema,
+ inputSchema: managedReconstructionReferenceInputSchema,
outputSchema: reconstructionOutputSchema,
- annotations: {
- readOnlyHint: true,
- destructiveHint: false,
- idempotentHint: true,
- openWorldHint: false,
- },
examples: [
{
title: "Import a decompiler reconstruction for one managed method",
- input: MANAGED_RECONSTRUCTION_IMPORT_EXAMPLE,
+ input: {
+ static_members_evidence_id:
+ MANAGED_RECONSTRUCTION_IMPORT_EXAMPLE.static_members.evidence_id,
+ decompiler: MANAGED_RECONSTRUCTION_IMPORT_EXAMPLE.decompiler,
+ methods: MANAGED_RECONSTRUCTION_IMPORT_EXAMPLE.methods,
+ notes: MANAGED_RECONSTRUCTION_IMPORT_EXAMPLE.notes,
+ },
},
],
},
diff --git a/src/contracts/toolEffects.ts b/src/contracts/toolEffects.ts
index 9c266a87d..a24cfe50b 100644
--- a/src/contracts/toolEffects.ts
+++ b/src/contracts/toolEffects.ts
@@ -98,6 +98,7 @@ export const TOOL_EFFECTS: Readonly> = {
inspect_managed_members: evidence,
inspect_managed_native_boundaries: evidence,
compare_managed_members: sessionEvidence,
+ import_managed_reconstruction: sessionEvidence,
plan_managed_runtime_correlation: sessionEvidence,
list_browser_targets: browserEvidence,
inspect_web_page: browserEvidence,
diff --git a/src/server/registerManagedWorkflowTools.ts b/src/server/registerManagedWorkflowTools.ts
index 98036fcd7..c811f0550 100644
--- a/src/server/registerManagedWorkflowTools.ts
+++ b/src/server/registerManagedWorkflowTools.ts
@@ -2,18 +2,18 @@ import type { McpServer } from "@modelcontextprotocol/server";
import type { BinarySessionPort } from "../application/BinarySession.js";
import { compareManagedMembersEvidenceValidated } from "../application/ManagedMemberComparisonService.js";
-import { importManagedReconstructionEvidence } from "../application/ManagedReconstructionService.js";
+import { importManagedReconstructionEvidenceValidated } from "../application/ManagedReconstructionService.js";
import {
planManagedRuntimeCorrelationEvidenceValidated,
type ManagedRuntimeCorrelationDependencies,
} from "../application/ManagedRuntimeCorrelationService.js";
import {
compareManagedMembersReferenceInputSchema,
+ managedReconstructionReferenceInputSchema,
managedRuntimeCorrelationReferenceInputSchema,
MANAGED_WORKFLOW_TOOL_CONTRACTS,
} from "../contracts/managedWorkflowToolContracts.js";
import { managedMemberComparisonResultSchema } from "../domain/managedMemberComparison.js";
-import { managedReconstructionImportInputSchema } from "../domain/managedReconstruction.js";
import type { Evidence } from "../domain/evidence.js";
import type { EvidenceIntegrityError } from "../domain/errors.js";
import type { Result } from "../domain/result.js";
@@ -120,11 +120,33 @@ export const registerManagedWorkflowTools = (
reconstructionContract.name,
toolRegistrationOptions(reconstructionContract),
async (input) => {
- const parsed = managedReconstructionImportInputSchema.parse(input);
+ const parsedInput = safeParseToolInput(
+ managedReconstructionReferenceInputSchema,
+ input,
+ reconstructionContract.name,
+ );
+ if (!parsedInput.ok)
+ return toCallToolResult(parsedInput, reconstructionContract);
+ const resolved = resolveManagedEvidence(options.session, [
+ parsedInput.value.static_members_evidence_id,
+ ]);
+ if (!resolved.ok)
+ return toCallToolResult(resolved, reconstructionContract);
+ const staticMembers = resolved.value[0];
+ if (staticMembers === undefined)
+ throw new TypeError(
+ "Managed reconstruction Evidence resolution failed",
+ );
+ const {
+ static_members_evidence_id: _staticMembersEvidenceId,
+ ...referencedInput
+ } = parsedInput.value;
+ const parsed = { ...referencedInput, static_members: staticMembers };
const result = await logToolExecution(
options.logger,
reconstructionContract.name,
- () => Promise.resolve(importManagedReconstructionEvidence(parsed)),
+ () =>
+ Promise.resolve(importManagedReconstructionEvidenceValidated(parsed)),
);
if (!result.ok) return toCallToolResult(result, reconstructionContract);
const recordedSource = options.recordEvidence?.(parsed.static_members);
diff --git a/tests/managedMcp.test.ts b/tests/managedMcp.test.ts
index 666b53cc6..ecef778ee 100644
--- a/tests/managedMcp.test.ts
+++ b/tests/managedMcp.test.ts
@@ -209,7 +209,7 @@ describe("managed artifact MCP tools", () => {
await client.callTool({
name: "import_managed_reconstruction",
arguments: {
- static_members: members,
+ static_members_evidence_id: members.evidence_id,
decompiler: {
name: "ilspycmd",
version: "9.1.0.7988",
From a807471e4e612e215ef82ebd2d16a1c454d5ad31 Mon Sep 17 00:00:00 2001
From: morluto <76467478+morluto@users.noreply.github.com>
Date: Thu, 16 Jul 2026 20:15:33 +0800
Subject: [PATCH 16/19] fix(mcp): normalize inferred field descriptions
---
src/server/toolRegistrationOptions.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/server/toolRegistrationOptions.ts b/src/server/toolRegistrationOptions.ts
index a584a79df..c94b89db7 100644
--- a/src/server/toolRegistrationOptions.ts
+++ b/src/server/toolRegistrationOptions.ts
@@ -102,7 +102,7 @@ const describeProperties = (
isObject(schema) && typeof schema.description !== "string"
? {
...describeProperties(schema),
- description: `${property.replaceAll("_", " ")}.`,
+ description: property.replaceAll("_", " "),
}
: describeValue(schema),
]),
From 2b064335ea63db4484d16b35544dd5e8024ecf6d Mon Sep 17 00:00:00 2001
From: morluto <76467478+morluto@users.noreply.github.com>
Date: Thu, 16 Jul 2026 20:15:48 +0800
Subject: [PATCH 17/19] docs(api): refresh managed reconstruction contracts
---
docs/api/assets/hierarchy.js | 2 +-
docs/api/assets/navigation.js | 2 +-
docs/api/assets/search.js | 2 +-
...plication_EnhancedTools.EnhancedTools.html | 31 +++-
...rmissionAuthority.PermissionPathError.html | 2 +-
...ocessCaptureError.ProcessCaptureError.html | 2 +-
...sionStore.ProjectPermissionStoreError.html | 2 +-
.../domain_errors.AnalysisCancelledError.html | 10 +-
...rs.AnalysisCapabilityUnavailableError.html | 14 +-
.../classes/domain_errors.AnalysisError.html | 2 +-
.../domain_errors.AnalysisInputError.html | 15 +-
.../domain_errors.AnalysisOutputError.html | 12 +-
.../domain_errors.AnalysisProtocolError.html | 2 +-
.../domain_errors.AnalysisTimeoutError.html | 12 +-
.../domain_errors.ArtifactOperationError.html | 14 +-
.../domain_errors.BinaryTargetError.html | 10 +-
...domain_errors.BrowserObservationError.html | 12 +-
.../domain_errors.ConfigurationError.html | 6 +-
.../domain_errors.EvidenceFileError.html | 12 +-
.../domain_errors.EvidenceIntegrityError.html | 10 +-
.../domain_errors.EvidenceLimitError.html | 12 +-
.../domain_errors.EvidenceReferenceError.html | 142 ++++++++++++++++++
.../domain_errors.HopperCancelledError.html | 8 +-
.../classes/domain_errors.HopperError.html | 2 +-
.../domain_errors.HopperProcessError.html | 14 +-
.../domain_errors.HopperProtocolError.html | 6 +-
.../domain_errors.HopperRemoteError.html | 14 +-
.../domain_errors.HopperStartError.html | 8 +-
.../domain_errors.HopperTimeoutError.html | 10 +-
...in_errors.InvestigationWorkspaceError.html | 12 +-
.../domain_errors.NoBinaryOpenError.html | 8 +-
...domain_errors.PermissionRequiredError.html | 18 +--
.../domain_errors.ProviderAdapterError.html | 14 +-
.../domain_errors.ProviderSelectionError.html | 20 +--
.../domain_errors.ReplayPlanStaleError.html | 12 +-
.../domain_errors.UnknownRegistryError.html | 10 +-
...permissionPolicy.PermissionGrantError.html | 2 +-
...idra_GhidraLauncher.GhidraLaunchError.html | 2 +-
...GhidraSessionError.GhidraSessionError.html | 2 +-
.../ghidra_protocol.GhidraRemoteError.html | 2 +-
...ityInventory.buildCapabilityInventory.html | 4 +-
...runCrossVersionInvestigationValidated.html | 46 ++++++
.../application_Doctor.runDoctor.html | 6 +-
.../application_Doctor.systemDoctorHost.html | 2 +-
...analyzeJavaScriptApplicationValidated.html | 46 ++++++
...ce.compareApplicationVersionsEvidence.html | 2 +-
...eApplicationVersionsEvidenceValidated.html | 44 ++++++
...rvice.traceApplicationFeatureEvidence.html | 2 +-
...ceApplicationFeatureEvidenceValidated.html | 44 ++++++
...riptReplayService.runControlledReplay.html | 2 +-
...yService.runControlledReplayValidated.html | 46 ++++++
...ce.reconcileJavaScriptRuntimeEvidence.html | 2 +-
...ileJavaScriptRuntimeEvidenceValidated.html | 44 ++++++
...isonService.compareManagedMemberPaths.html | 2 +-
...Service.compareManagedMembersEvidence.html | 44 ------
...ompareManagedMembersEvidenceValidated.html | 44 ++++++
...anagedReconstructionEvidenceValidated.html | 44 ++++++
...edRuntimeCorrelationEvidenceValidated.html | 45 ++++++
...ion_ProcessSampling.readLinuxChildren.html | 2 +-
...n_ProcessSampling.startProcessSampler.html | 2 +-
...ts_toolEffects.annotationsFromEffects.html | 44 ++++++
...acts_toolEffects.toolContractMetadata.html | 44 ++++++
...ts_toolOutputSchemas.evidenceResultOf.html | 44 ++++++
...toolOutputSchemas.requireOutputSchema.html | 2 +-
...n_artifactComparison.compareArtifacts.html | 2 +-
...omain_bundleComparison.compareBundles.html | 2 +-
.../domain_errors.projectAnalysisError.html | 2 +-
...putIssueProjection.projectInputIssues.html | 45 ++++++
...llation.ghidraInstallationDiagnostics.html | 2 +-
...draInstallation.ghidraJavaEnvironment.html | 2 +-
...nstallation.inspectGhidraInstallation.html | 2 +-
...icationTools.registerApplicationTools.html | 2 +-
...onTool.registerArtifactComparisonTool.html | 2 +-
...sterBrowserTools.registerBrowserTools.html | 2 +-
...isonTool.registerBundleComparisonTool.html | 7 +-
...erElectronTools.registerElectronTools.html | 2 +-
...erEnhancedTools.registerEnhancedTools.html | 2 +-
...erEvidenceTools.registerEvidenceTools.html | 2 +-
...onTool.registerFunctionComparisonTool.html | 2 +-
...ationTools.registerInvestigationTools.html | 2 +-
...lowTools.registerManagedWorkflowTools.html | 2 +-
...erOfficialTools.registerOfficialTools.html | 2 +-
...sonTool.registerProcessComparisonTool.html | 2 +-
...nStatusTool.registerSessionStatusTool.html | 2 +-
...sterSessionTools.registerSessionTools.html | 2 +-
...ver_sessionEvidence.isSessionEvidence.html | 45 ------
...essionEvidence.resolveSessionEvidence.html | 45 ------
...ionEvidence.resolveSessionEvidenceIds.html | 46 ++++++
...oolInputValidation.safeParseToolInput.html | 50 ++++++
...egistrationOptions.closeObjectSchemas.html | 44 ++++++
...rationOptions.toolRegistrationOptions.html | 6 +-
docs/api/hierarchy.html | 114 +++++++-------
docs/api/index.html | 4 +-
...ation_AnalysisProvider.AnalysisClient.html | 2 +-
...nalysisProvider.AnalysisOperationPort.html | 2 +-
...ion_AnalysisProvider.AnalysisProvider.html | 2 +-
...sisProvider.AnalysisProviderCandidate.html | 2 +-
...n_BinarySessionPort.BinarySessionPort.html | 2 +-
.../application_Doctor.DoctorHost.html | 18 ++-
...cation_Doctor.SystemDoctorHostOptions.html | 6 +-
...riptArtifactGraphContext.AstEdgeInput.html | 2 +-
...tifactGraphContext.InferenceEdgeInput.html | 2 +-
...yService.JavaScriptReplayDependencies.html | 10 +-
...ice.ManagedMemberPathInspectionLimits.html | 36 ++---
...ion_ProcessSampling.LinuxChildrenHost.html | 6 +-
.../application_Setup.SetupHost.html | 6 +-
.../application_Setup.SetupResult.html | 4 +-
...tracts_toolContractTypes.ToolContract.html | 36 +++--
...ntracts_toolContractTypes.ToolExample.html | 6 +-
...s_toolEffects.DerivedToolAnnotations.html} | 22 +--
.../contracts_toolEffects.ToolEffects.html | 100 ++++++++++++
...domain_errors.AnalysisErrorProjection.html | 16 +-
.../domain_errors.AnalysisInputIssue.html | 82 ++++++++++
...in_errors.ProviderAdapterErrorOptions.html | 6 +-
..._errors.ProviderSelectionErrorOptions.html | 12 +-
...ain_errors.ProviderSelectionRejection.html | 10 +-
...main_permissionPolicy.PermissionGrant.html | 2 +-
...in_permissionPolicy.PermissionRequest.html | 2 +-
...main_permissionPolicy.PermissionScope.html | 2 +-
...domain_webInventory.StableWebResource.html | 2 +-
...ebInventory.WebInventoryResourceInput.html | 2 +-
...raInstallation.GhidraInstallationHost.html | 28 +++-
.../ghidra_GhidraLauncher.GhidraLaunch.html | 2 +-
...essionError.GhidraSessionErrorOptions.html | 2 +-
.../hopper_BridgeLauncher.BridgeLaunch.html | 2 +-
...ProviderProcess.ProviderProcessLaunch.html | 2 +-
...nhancedTools.EnhancedToolRegistration.html | 12 +-
...fficialTools.OfficialToolRegistration.html | 10 +-
...gisterSessionTools.SessionToolOptions.html | 18 +--
...application_CrossVersionInvestigation.html | 4 +-
.../modules/application_EnhancedTools.html | 8 +-
...lication_JavaScriptApplicationService.html | 4 +-
..._JavaScriptApplicationWorkflowService.html | 4 +-
.../application_JavaScriptReplayService.html | 4 +-
...avaScriptRuntimeReconciliationService.html | 4 +-
...cation_ManagedMemberComparisonService.html | 4 +-
...lication_ManagedReconstructionService.html | 4 +-
...tion_ManagedRuntimeCorrelationService.html | 4 +-
...ontracts_managedWorkflowToolContracts.html | 4 +-
.../modules/contracts_toolContractTypes.html | 8 +-
docs/api/modules/contracts_toolContracts.html | 8 +-
docs/api/modules/contracts_toolEffects.html | 44 ++++++
.../modules/contracts_toolOutputSchemas.html | 4 +-
docs/api/modules/domain_errors.html | 8 +-
.../modules/domain_inputIssueProjection.html | 36 +++++
docs/api/modules/server_sessionEvidence.html | 4 +-
.../modules/server_toolInputValidation.html | 36 +++++
.../server_toolRegistrationOptions.html | 4 +-
...n_EnhancedTools.ValidatedEnhancedCall.html | 35 +++++
...rtifactToolContracts.ArtifactToolName.html | 2 +-
..._managedToolContracts.ManagedToolName.html | 2 +-
...ts_nativeToolContracts.NativeToolName.html | 2 +-
...tracts_toolContracts.OfficialToolName.html | 2 +-
...ctComparison.ArtifactComparisonResult.html | 2 +-
...ndleComparison.BundleComparisonResult.html | 2 +-
...in_errors.BrowserObservationOperation.html | 2 +-
.../domain_errors.HopperDiagnosticType.html | 2 +-
...errors.ProviderSelectionFailureReason.html | 2 +-
...nctionComparisonSchemas.DimensionName.html | 2 +-
...risonSchemas.FunctionComparisonResult.html | 2 +-
...onComparisonSchemas.FunctionDimension.html | 2 +-
...rificationSchemas.ReconstructionClaim.html | 2 +-
...tionSchemas.ReconstructionClaimResult.html | 2 +-
...nSchemas.ReconstructionObservedStatus.html | 2 +-
...emas.ReconstructionVerificationResult.html | 2 +-
...lContracts.APPLICATION_TOOL_CONTRACTS.html | 4 +-
...ToolContracts.ARTIFACT_TOOL_CONTRACTS.html | 2 +-
...ntracts.artifactExtractionInputSchema.html | 2 +-
...ontracts.artifactInventoryInputSchema.html | 2 +-
...rToolContracts.BROWSER_TOOL_CONTRACTS.html | 4 +-
...ToolContracts.ELECTRON_TOOL_CONTRACTS.html | 4 +-
...Examples.FUNCTION_COMPARISON_EVIDENCE.html | 2 +-
...gationExamples.INVESTIGATION_EXAMPLES.html | 6 +-
...amples.PROCESS_CAPTURE_RECONSTRUCTION.html | 2 +-
...ionExamples.PROCESS_CAPTURE_REFERENCE.html | 2 +-
...nExamples.PROCESS_COMPARISON_EVIDENCE.html | 2 +-
...dToolContracts.MANAGED_TOOL_CONTRACTS.html | 4 +-
...lContracts.managedArtifactInputSchema.html | 2 +-
...oolContracts.managedMemberInputSchema.html | 2 +-
...acts.managedNativeBoundaryInputSchema.html | 2 +-
...racts.MANAGED_WORKFLOW_TOOL_CONTRACTS.html | 4 +-
...areManagedMembersReferenceInputSchema.html | 35 +++++
...gedReconstructionReferenceInputSchema.html | 35 +++++
...untimeCorrelationReferenceInputSchema.html | 35 +++++
...veToolContracts.NATIVE_TOOL_CONTRACTS.html | 2 +-
...ntractExamples.TOOL_EXAMPLE_OVERRIDES.html | 2 +-
...toolContracts.ENHANCED_TOOL_CONTRACTS.html | 2 +-
...toolContracts.OFFICIAL_TOOL_CONTRACTS.html | 2 +-
..._toolContracts.SESSION_TOOL_CONTRACTS.html | 2 +-
...ontracts_toolContracts.TOOL_CONTRACTS.html | 4 +-
...oolContracts.binarySessionInputSchema.html | 2 +-
...racts.exportEvidenceBundleInputSchema.html | 35 +++++
...acts.importEvidenceBundleInputSchema.html} | 14 +-
...toolContracts.listUnknownsInputSchema.html | 35 +++++
...ontracts.processComparisonInputSchema.html | 35 +++++
...ts.verifyUnknownResolutionInputSchema.html | 35 +++++
.../contracts_toolEffects.TOOL_EFFECTS.html | 35 +++++
...olOutputSchemas.artifactOutputSchemas.html | 2 +-
...olOutputSchemas.enhancedOutputSchemas.html | 2 +-
...oolOutputSchemas.managedOutputSchemas.html | 2 +-
...tSchemas.managedWorkflowOutputSchemas.html | 2 +-
...toolOutputSchemas.nativeOutputSchemas.html | 2 +-
...olOutputSchemas.officialOutputSchemas.html | 2 +-
...oolOutputSchemas.sessionOutputSchemas.html | 2 +-
...parison.artifactComparisonInputSchema.html | 4 +-
...arison.artifactComparisonResultSchema.html | 2 +-
...omparison.bundleComparisonInputSchema.html | 4 +-
...mparison.bundleComparisonResultSchema.html | 2 +-
...Schemas.functionComparisonInputSchema.html | 4 +-
...chemas.functionComparisonResultSchema.html | 2 +-
...hemas.reconstructionClaimResultSchema.html | 2 +-
...mas.reconstructionSpecificationSchema.html | 2 +-
...reconstructionVerificationInputSchema.html | 4 +-
...econstructionVerificationResultSchema.html | 2 +-
docs/product-catalog.json | 4 +-
skills/rea-analysis/SKILL.md | 2 +-
216 files changed, 2049 insertions(+), 637 deletions(-)
create mode 100644 docs/api/classes/domain_errors.EvidenceReferenceError.html
create mode 100644 docs/api/functions/application_CrossVersionInvestigation.runCrossVersionInvestigationValidated.html
create mode 100644 docs/api/functions/application_JavaScriptApplicationService.analyzeJavaScriptApplicationValidated.html
create mode 100644 docs/api/functions/application_JavaScriptApplicationWorkflowService.compareApplicationVersionsEvidenceValidated.html
create mode 100644 docs/api/functions/application_JavaScriptApplicationWorkflowService.traceApplicationFeatureEvidenceValidated.html
create mode 100644 docs/api/functions/application_JavaScriptReplayService.runControlledReplayValidated.html
create mode 100644 docs/api/functions/application_JavaScriptRuntimeReconciliationService.reconcileJavaScriptRuntimeEvidenceValidated.html
delete mode 100644 docs/api/functions/application_ManagedMemberComparisonService.compareManagedMembersEvidence.html
create mode 100644 docs/api/functions/application_ManagedMemberComparisonService.compareManagedMembersEvidenceValidated.html
create mode 100644 docs/api/functions/application_ManagedReconstructionService.importManagedReconstructionEvidenceValidated.html
create mode 100644 docs/api/functions/application_ManagedRuntimeCorrelationService.planManagedRuntimeCorrelationEvidenceValidated.html
create mode 100644 docs/api/functions/contracts_toolEffects.annotationsFromEffects.html
create mode 100644 docs/api/functions/contracts_toolEffects.toolContractMetadata.html
create mode 100644 docs/api/functions/contracts_toolOutputSchemas.evidenceResultOf.html
create mode 100644 docs/api/functions/domain_inputIssueProjection.projectInputIssues.html
delete mode 100644 docs/api/functions/server_sessionEvidence.isSessionEvidence.html
delete mode 100644 docs/api/functions/server_sessionEvidence.resolveSessionEvidence.html
create mode 100644 docs/api/functions/server_sessionEvidence.resolveSessionEvidenceIds.html
create mode 100644 docs/api/functions/server_toolInputValidation.safeParseToolInput.html
create mode 100644 docs/api/functions/server_toolRegistrationOptions.closeObjectSchemas.html
rename docs/api/interfaces/{contracts_toolContractTypes.ToolAnnotations.html => contracts_toolEffects.DerivedToolAnnotations.html} (77%)
create mode 100644 docs/api/interfaces/contracts_toolEffects.ToolEffects.html
create mode 100644 docs/api/interfaces/domain_errors.AnalysisInputIssue.html
create mode 100644 docs/api/modules/contracts_toolEffects.html
create mode 100644 docs/api/modules/domain_inputIssueProjection.html
create mode 100644 docs/api/modules/server_toolInputValidation.html
create mode 100644 docs/api/types/application_EnhancedTools.ValidatedEnhancedCall.html
create mode 100644 docs/api/variables/contracts_managedWorkflowToolContracts.compareManagedMembersReferenceInputSchema.html
create mode 100644 docs/api/variables/contracts_managedWorkflowToolContracts.managedReconstructionReferenceInputSchema.html
create mode 100644 docs/api/variables/contracts_managedWorkflowToolContracts.managedRuntimeCorrelationReferenceInputSchema.html
create mode 100644 docs/api/variables/contracts_toolContracts.exportEvidenceBundleInputSchema.html
rename docs/api/{types/contracts_toolContractTypes.ToolKind.html => variables/contracts_toolContracts.importEvidenceBundleInputSchema.html} (58%)
create mode 100644 docs/api/variables/contracts_toolContracts.listUnknownsInputSchema.html
create mode 100644 docs/api/variables/contracts_toolContracts.processComparisonInputSchema.html
create mode 100644 docs/api/variables/contracts_toolContracts.verifyUnknownResolutionInputSchema.html
create mode 100644 docs/api/variables/contracts_toolEffects.TOOL_EFFECTS.html
diff --git a/docs/api/assets/hierarchy.js b/docs/api/assets/hierarchy.js
index 808e5473c..416b20d92 100644
--- a/docs/api/assets/hierarchy.js
+++ b/docs/api/assets/hierarchy.js
@@ -1 +1 @@
-window.hierarchyData = "eJy1mVFv3CgQx7+Ln6nPxhjsfUtXuTan6rLKturDKYqITTYoXvBhNr1V1e9eYW8SHOMYO7qXJCb+z/yAYYDxz0BJqZtg9Q9K8wSkMUTQ/MxjQBKURgDhFEKQ5nFGAE5zDAEiEU4ARBAjgEgKEwDzJIbXIFDsrmKF5lI0wepnYCya34LuWbAKzgStjg1vzpWSKgDBAxdlsIphBoKDqoJVUFS0aVjzRyn3lIsbZt5rwp4svNf7KgDdq8Eq0E35wdj50DWAoLjnVamYMB3CUQoQjglAGOYAYdT2JgEIY9NGiOlKDBAxr5DE9AylABGcA0Qy8488ASiLMEBZnAOU5SlAeUQAymPzl7GXpxkgJE3Q9S8QGI9Whz/LumZqZnct0azOZkkEUIbaHxlAGY4BykgKUJbhji0mjsnYKKllIauFk9KTT/C2EDB3QFyI+qAXErxofdyjyOH+8qCX+7fEPgCpa0WsaU1vecX18Zugj5RX9LZiC3nGbfngYVeMrKkoWFWxcjGSrffBIC6Mr3zP5OJ5stUeCCSKLYSNko+8ZGrLTvltJoRb74PRW7RPZs5KWuvZmcWl9kFIoIXwUckfDVOXtw1Tj3TBUIwY8AFBdnI9U5rf0UJf1kwt4XDrfTCwncLOzZCKgl0IzXaK6+NMDLfeByOLHRhf+J7PXSFDrY/73tb+ZOJPPjtvDaQezrMIW84vxCNrNN+1s/hdqoempsVcjDeM+ADFdkx8Ew9C/hBXbMcbreZGhEvtg5BEg6PHsow51Pq4R0P3S/cNl9oLIRsgLDzeOMQ+ADgeAFyxvdRzg3Eg9XFOhkfPjZIFa+YeuIdaH/cZHrjfaqqWBd+L0sd1bvd8LcUd3x0W7QlDrYf7PLK36L/lRy6oOl7WbK73gdTHeWz3vdN/pWrH5o77QOrjvLfmN0ztedNwKa7YvweuZi/7EQM+IKm98q9YXdHjpqJiq+ns/cilnkZob8POwdgWsmbP7mGKn9xzoZm6o8ULQf0s2siKF8fwlZVRjGdT/TshRJBAc1HP4HXHSODohLFGv5vyZMeDs8PJ3DifFBXvh2mteKKY+oWF8p3dmvOA0FIdr1gjD8oc0OqDJ9QPSx6O2po9m3kC0+uOFtqrfqvNFe87u30yv4ByYMNv4BBO+wlI8XLHvtCDKO4nKO7bRH9jK5gK7UdvBAhHEJh6NwQbX/wj82Tu+KeKS5oMN8Wzuq540e4wA0hHcnITjpryuuNj50mhvRt6oPQF4atHn5t1amfKT/e8VNQrZHbtqze2gqnQfvQMGVPAHEGYDJlpiAUhQyKSX3dkJB+QfWa0rFjT+MTLW3iv7XjVH3qnm86OT7D0OJ6j49Wjh/8UJo4CyOlw6hU1dffuzStt6LS1YLGbUrCJ6W7+cO8Ssi7rU73DZ8xuu1dvhqrQ0TQ5eGkUp7APc27KT0qKmTSvZaGrbZrHfFtwlV+fKjAbqaZ2WPqS8m6sGnRH4DQ4d0YNZQZSjJPs+gSdOaDXFWeThxQv2s6SX+ZqP8y4q/j9+XwHz+SEjgwchiTJQRon3e7X/vEG6pqKkpdUT51WZjE/G52fgWPzXcfsjS18kuFscLHasvZg+daisWl7orD/NL1YTACOEcxcKANtOGyZu0rMALUjZT4MvlkfngvrNOAoGy/BbvOzwW6DtVc12Ney4Zr5ZEYbdyAMhy2Tk91+V7XLqafcunwURyyEY+1zp99sLWYc22/E9ipv9Hm587os2bh/0Ue6LRSv9VNZ/pOi9f1aCs3+06FtdS4qSUiMO1QS98vGd0yZyvP/ADy07Zff2y/J/fOOOZusaa0ParqSYRM6pKGrbSI4f/36DZ2D+0A="
\ No newline at end of file
+window.hierarchyData = "eJytmVFv3CgQx7+Ln6nPBmzsvLWrXJtTdYmyrfJwiiJikw2KF3yYTW9V9btXeDcJjnEMzr1sbMf/mZ9hgGH4GSkpdRed/INKnAIMYZaY37IEeQZJDhDJYAGyJC0zkJEEJgAVCUkBRChLASoylAJYwJRcg0ixu4ZVmkvRRSc/I2PR/BV0y6KT6KOgzb7j3alSUkUgeuCijk5SWIBop5roJKoa2nWs+6OWW8rFDTPvdfFAFt/rbROBw6vRSaS7+oOx8+HwAETVPW9qxUT/QRkCqMwzgEpCACrLHOAkKQFOIAI4QeYnIwAnxFwVBcBpkgKcwgzgNEMAp7m5IuYfpWmbnAAMSQkwLAjAKIUAI5QAksA0uf4FIuPR+uAvsm2ZCvxcSxTysRgmEGBokCA0PWi+DmIDnBUHtjxzdMaFklpWslnYKQP5DG8PQYgD4ky0O72Q4EXr477MHe7Pd3q5f0s8D2DCzwGwoi295Q3X+++CPlLe0NuGLeSZtuWDB5ETT1SsaVi9GMnW+2AgF8Y3vmVycT/Zah+EzA7UCyUfec3Umh3nt0AIt94HgyAHxseatjp4ZnGpfRCKwkL4pOSPjqnz246pR7qgKSYMeICkyWA1UZrf0Uqft0wt4XDrfTCgPY+emiYVFTsTmm0U1/tADLc+aOZPEbnuwRBxgF2yO6bMxUKwod6nfQZr4JOZr3zLQ4fuWOvjPnd1z588eEIdSX2cE3usnIlH1mm+6cPrSqqHrqXB/fCGER+g0h4z38WDkD/EJdvwTqvQUHWpPRBgAkc50bKpfKz1cZ+O3S9d0FxqHwSYjBAW5l0OsQ8AGqell2wrdWgwjqQ+zjFxfX3FutCdwFjr4z4rRu7Xmqplwfei9HGd21++kuKOb3aLFqux1sc9sXPNv+UnLqjan7cs1PtI6uO8sL/9oP9G1YaFtvtI6uEcDcb8BVNb3nVcikv2746r4GE/YcAHBNkj/5K1Dd1fNFSsNQ1ej1zqeYR+m+5sjHUlW/bsHmb5k3suNFN3tHohaJ9FF7Lh1T5+ZWUS49nUMGUxUKWpIOTl9ZGxnOww1ul3Ux7teHAecHI3zmdFxftheiueKKawYqFcsVuTDwgt1f6SdXKnTObY7jyhfljyeNJWcG8WEPXlj/7Col1rs/e8YrdP5hdQjmz4NZypWqWDbQuvN+wr3Ynqfobivp/ob2wFU7F9649QTCAw9W4INj34J/oJkQzD6wMZHidFH9u24VW/wowgHZOTm3DSlEdxhuQkdWUK/abVA2UoiF/dzvsvktxulc/3vFbUK2Q2/as3toKp2L71DBlTWZ1AmA2ZeYgFIVMkRb+57C9GZF8YrRvWdT7x8hbeazs+nZWm2YjHJ1gGHM/R8erWw3+GBsvqUXlMTr2ipj28e/NKGzttLRjs0JTnk/ww5Is8s0ufq7o9FmJ82uz28OrNWBU7HnnsStM8GcKcmrqYkiKQ5rUsdj3z2aBlNs9zafepNHQh1dwKS1+mvBurOH4gcBoM7VFDmQNMcpxfH6FdxexVw9lskuJFe7DkN3P1J0bu44Vhf76DZ7ZDJxouQ8Sc8kCE8aHhEMZvoK6oqHlN9Vy2EsT8bDR8Bk7TDPRrYw+PC5KPNlZr1ieWbw0am3Ygiod384PFBOAUQeBAGWnj8ZPQUWIayLRUf2L5ZuE6FNZpwFHPXoLdz889tgnWQdVg28qOa+YzM9q4I2E8fjLb2f2Br11OPc6ty1txwkI89Ty0+83SYtqxP7y2R3mnT+uN12bJxv2LPtJ1pXirn84LPiva3q+k0Ow/HdtWQ1Hz7JiO9xeDsvFTxf3/Bx7b9pvf+yPuYb5jcpMVbfVOzVcybEKHNHY9mwnOX79+A8E8LfY="
\ No newline at end of file
diff --git a/docs/api/assets/navigation.js b/docs/api/assets/navigation.js
index 8537f7af4..45f6c2b19 100644
--- a/docs/api/assets/navigation.js
+++ b/docs/api/assets/navigation.js
@@ -1 +1 @@
-window.navigationData = "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"
\ No newline at end of file
+window.navigationData = "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"
\ No newline at end of file
diff --git a/docs/api/assets/search.js b/docs/api/assets/search.js
index 313242cd6..42bbebaea 100644
--- a/docs/api/assets/search.js
+++ b/docs/api/assets/search.js
@@ -1 +1 @@
-window.searchData = "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";
\ No newline at end of file
+window.searchData = "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";
\ No newline at end of file
diff --git a/docs/api/classes/application_EnhancedTools.EnhancedTools.html b/docs/api/classes/application_EnhancedTools.EnhancedTools.html
index 7397e0cbf..82515ba07 100644
--- a/docs/api/classes/application_EnhancedTools.EnhancedTools.html
+++ b/docs/api/classes/application_EnhancedTools.EnhancedTools.html
@@ -13,11 +13,11 @@
Class EnhancedTools
+Defined in src/application/EnhancedTools.ts:54
@@ -30,6 +30,7 @@ validates them, allowing direct callers to use the same service safely.
Constructors
@@ -46,7 +47,7 @@ validates them, allowing direct callers to use the same service safely.
analysis : AnalysisOperationPort
+Defined in src/application/EnhancedTools.ts:55
Methods
@@ -56,7 +57,7 @@ validates them, allowing direct callers to use the same service safely.
execute ( name : | "swift_classes" | "get_objc_classes" | "get_objc_protocols" | "batch_decompile" | "get_call_graph" | "analyze_swift_types" | "find_xrefs_to_name" | "binary_overview" | "analyze_function" | "trace_feature" , input : unknown , signal ?: AbortSignal , ) : EnhancedResult
-
+ Defined in src/application/EnhancedTools.ts:58
+
+execute Validated
+
+
+
+
+
+
+
Returns EnhancedResult
+Defined in src/domain/errors.ts:123
Properties
@@ -65,7 +65,7 @@
_tag : "AnalysisCancelledError"
+Defined in src/domain/errors.ts:121
Readonlycleanup Incomplete
cleanupIncomplete : boolean = false
@@ -82,7 +82,7 @@
Readonlyoperation
operation : string
+Defined in src/domain/errors.ts:123
Readonlyuser Category
userCategory : "permission_required" | "cancelled" | undefined = undefined
diff --git a/docs/api/classes/domain_errors.AnalysisCapabilityUnavailableError.html b/docs/api/classes/domain_errors.AnalysisCapabilityUnavailableError.html
index ce59b3536..3a8e118f8 100644
--- a/docs/api/classes/domain_errors.AnalysisCapabilityUnavailableError.html
+++ b/docs/api/classes/domain_errors.AnalysisCapabilityUnavailableError.html
@@ -14,14 +14,14 @@
-
+Defined in src/domain/errors.ts:110
Properties
@@ -69,7 +69,7 @@
_tag : "AnalysisCapabilityUnavailableError"
+Defined in src/domain/errors.ts:108
Readonlycleanup Incomplete
cleanupIncomplete : boolean = false
@@ -86,17 +86,17 @@
Readonlyoperation
operation : string
+Defined in src/domain/errors.ts:112
Readonlyprovider Id
providerId : string
+Defined in src/domain/errors.ts:111
Readonlyreason
reason : string
+Defined in src/domain/errors.ts:113
Readonlyuser Category
userCategory : "permission_required" | "cancelled" | undefined = undefined
diff --git a/docs/api/classes/domain_errors.AnalysisError.html b/docs/api/classes/domain_errors.AnalysisError.html
index 8b409bc38..0ad64c8d0 100644
--- a/docs/api/classes/domain_errors.AnalysisError.html
+++ b/docs/api/classes/domain_errors.AnalysisError.html
@@ -14,7 +14,7 @@
-
+
Error
diff --git a/docs/api/classes/domain_errors.AnalysisInputError.html b/docs/api/classes/domain_errors.AnalysisInputError.html
index 5fb9696cf..47bd07d20 100644
--- a/docs/api/classes/domain_errors.AnalysisInputError.html
+++ b/docs/api/classes/domain_errors.AnalysisInputError.html
@@ -14,7 +14,7 @@
-
+
+Defined in src/domain/errors.ts:97
Properties
@@ -68,7 +68,7 @@
_tag : "AnalysisOutputError"
+Defined in src/domain/errors.ts:95
Readonlycleanup Incomplete
cleanupIncomplete : boolean = false
@@ -85,12 +85,12 @@
Readonlyoperation
operation : string
+Defined in src/domain/errors.ts:98
Readonlyreason
reason : string
+Defined in src/domain/errors.ts:99
Readonlyuser Category
userCategory : "permission_required" | "cancelled" | undefined = undefined
diff --git a/docs/api/classes/domain_errors.AnalysisProtocolError.html b/docs/api/classes/domain_errors.AnalysisProtocolError.html
index 25c4cb7e9..b75d22ea5 100644
--- a/docs/api/classes/domain_errors.AnalysisProtocolError.html
+++ b/docs/api/classes/domain_errors.AnalysisProtocolError.html
@@ -14,7 +14,7 @@
-
+
AnalysisError
diff --git a/docs/api/classes/domain_errors.AnalysisTimeoutError.html b/docs/api/classes/domain_errors.AnalysisTimeoutError.html
index 21886f9a1..31bf38020 100644
--- a/docs/api/classes/domain_errors.AnalysisTimeoutError.html
+++ b/docs/api/classes/domain_errors.AnalysisTimeoutError.html
@@ -14,14 +14,14 @@
-
+Defined in src/domain/errors.ts:132
Properties
@@ -67,7 +67,7 @@
_tag : "AnalysisTimeoutError"
+Defined in src/domain/errors.ts:130
Readonlycleanup Incomplete
cleanupIncomplete : boolean = false
@@ -84,12 +84,12 @@
Readonlyoperation
operation : string
+Defined in src/domain/errors.ts:133
Readonlytimeout Ms
timeoutMs : number
+Defined in src/domain/errors.ts:134
Readonlyuser Category
userCategory : "permission_required" | "cancelled" | undefined = undefined
diff --git a/docs/api/classes/domain_errors.ArtifactOperationError.html b/docs/api/classes/domain_errors.ArtifactOperationError.html
index 82434cb42..c964e8583 100644
--- a/docs/api/classes/domain_errors.ArtifactOperationError.html
+++ b/docs/api/classes/domain_errors.ArtifactOperationError.html
@@ -14,14 +14,14 @@
-
+Defined in src/domain/errors.ts:293
Properties
@@ -69,12 +69,12 @@
_tag : "ArtifactOperationError"
+Defined in src/domain/errors.ts:291
Optional Readonlyartifact Details
artifactDetails ?: Readonly < { calculatedSha256 : string | null ; declaredSha256 : string | null ; logicalPath : string ; unpacked : boolean ; } , >
+Defined in src/domain/errors.ts:306
Readonlycleanup Incomplete
cleanupIncomplete : boolean = false
+Defined in src/domain/errors.ts:294
Readonlyreason
reason : | "format" | "path" | "io" | "unavailable" | "limit" | "cancelled" | "integrity"
+Defined in src/domain/errors.ts:298
Readonlyuser Category
userCategory : "permission_required" | "cancelled" | undefined = undefined
diff --git a/docs/api/classes/domain_errors.BinaryTargetError.html b/docs/api/classes/domain_errors.BinaryTargetError.html
index 010d373d7..f9e64c79e 100644
--- a/docs/api/classes/domain_errors.BinaryTargetError.html
+++ b/docs/api/classes/domain_errors.BinaryTargetError.html
@@ -14,14 +14,14 @@
-
+Defined in src/domain/errors.ts:494
Properties
@@ -67,7 +67,7 @@
_tag : "BinaryTargetError"
+Defined in src/domain/errors.ts:493
Readonlycleanup Incomplete
cleanupIncomplete : boolean = false
@@ -84,7 +84,7 @@
Readonlypath
path : string
+Defined in src/domain/errors.ts:495
Readonlyuser Category
userCategory : "permission_required" | "cancelled" | undefined = undefined
diff --git a/docs/api/classes/domain_errors.BrowserObservationError.html b/docs/api/classes/domain_errors.BrowserObservationError.html
index e4f96cb99..48fb8c58f 100644
--- a/docs/api/classes/domain_errors.BrowserObservationError.html
+++ b/docs/api/classes/domain_errors.BrowserObservationError.html
@@ -14,14 +14,14 @@
-
+Defined in src/domain/errors.ts:272
Properties
@@ -68,7 +68,7 @@
_tag : "BrowserObservationError"
+Defined in src/domain/errors.ts:270
Readonlycleanup Incomplete
cleanupIncomplete : boolean = false
@@ -85,12 +85,12 @@
Readonlyoperation
+Defined in src/domain/errors.ts:273
Readonlyreason
reason : | "disconnected" | "endpoint_unreachable" | "invalid_endpoint_response" | "target_not_found" | "target_not_allowed" | "target_changed" | "protocol_error" | "payload_limit"
+Defined in src/domain/errors.ts:274
Readonlyuser Category
userCategory : "permission_required" | "cancelled" | undefined = undefined
diff --git a/docs/api/classes/domain_errors.ConfigurationError.html b/docs/api/classes/domain_errors.ConfigurationError.html
index 0d3d8def8..1063b3532 100644
--- a/docs/api/classes/domain_errors.ConfigurationError.html
+++ b/docs/api/classes/domain_errors.ConfigurationError.html
@@ -14,14 +14,14 @@
-
Readonlycleanup Incomplete
cleanupIncomplete : boolean = false
diff --git a/docs/api/classes/domain_errors.EvidenceFileError.html b/docs/api/classes/domain_errors.EvidenceFileError.html
index a0f8be7a1..97a4704e4 100644
--- a/docs/api/classes/domain_errors.EvidenceFileError.html
+++ b/docs/api/classes/domain_errors.EvidenceFileError.html
@@ -14,14 +14,14 @@
-
+Defined in src/domain/errors.ts:354
Properties
@@ -68,7 +68,7 @@
_tag : "EvidenceFileError"
+Defined in src/domain/errors.ts:352
Readonlycleanup Incomplete
cleanupIncomplete : boolean = false
+Defined in src/domain/errors.ts:355
Readonlyreason
reason : | "io" | "disabled" | "outside-root" | "not-file" | "too-large" | "exists" | "invalid-json"
+Defined in src/domain/errors.ts:356
Readonlyuser Category
userCategory : "permission_required" | "cancelled" | undefined = undefined
diff --git a/docs/api/classes/domain_errors.EvidenceIntegrityError.html b/docs/api/classes/domain_errors.EvidenceIntegrityError.html
index 6d3292869..6afced485 100644
--- a/docs/api/classes/domain_errors.EvidenceIntegrityError.html
+++ b/docs/api/classes/domain_errors.EvidenceIntegrityError.html
@@ -14,14 +14,16 @@
-
+
+EvidenceIntegrityError
+
+Defined in src/domain/errors.ts:322
Readonlycleanup Incomplete
cleanupIncomplete : boolean = false
diff --git a/docs/api/classes/domain_errors.EvidenceLimitError.html b/docs/api/classes/domain_errors.EvidenceLimitError.html
index 8b63bbdeb..4d252da7a 100644
--- a/docs/api/classes/domain_errors.EvidenceLimitError.html
+++ b/docs/api/classes/domain_errors.EvidenceLimitError.html
@@ -14,14 +14,14 @@
-
+Defined in src/domain/errors.ts:342
Properties
@@ -67,7 +67,7 @@
_tag : "EvidenceLimitError"
+Defined in src/domain/errors.ts:340
Readonlycleanup Incomplete
cleanupIncomplete : boolean = false
+Defined in src/domain/errors.ts:343
Readonlymaximum
maximum : number
+Defined in src/domain/errors.ts:344
Readonlyuser Category
userCategory : "permission_required" | "cancelled" | undefined = undefined
diff --git a/docs/api/classes/domain_errors.EvidenceReferenceError.html b/docs/api/classes/domain_errors.EvidenceReferenceError.html
new file mode 100644
index 000000000..a3c95cc68
--- /dev/null
+++ b/docs/api/classes/domain_errors.EvidenceReferenceError.html
@@ -0,0 +1,142 @@
+EvidenceReferenceError | rea-agents - v1.7.0
+
+
+
+
+
Class EvidenceReferenceError
+
+
+
+
+Constructors
+
+
+constructor
+
+
+new EvidenceReferenceError ( evidenceId : string , reason : "missing" | "wrong_operation" | "wrong_predicate" , expected : string , actual : string | null , ) : EvidenceReferenceError
+
+
+
Parameters
+
+evidenceId : string
+reason : "missing" | "wrong_operation" | "wrong_predicate"
+expected : string
+actual : string | null
+
+
+Properties
+
+
+Readonly_ tag
+_tag : "EvidenceIntegrityError"
+
+Readonlyactual
+actual : string | null
+
+Readonlycleanup Incomplete
+cleanupIncomplete : boolean = false
+
+Readonlycleanup Resources
+cleanupResources : readonly string [] = []
+
+Readonlyevidence Id
+evidenceId : string
+
+Readonlyexpected
+expected : string
+
+Readonlyreason
+reason : "missing" | "wrong_operation" | "wrong_predicate"
+
+Readonlyuser Category
+userCategory : "permission_required" | "cancelled" | undefined = undefined
+
+Readonlyuser Message
+userMessage : string | undefined = undefined
+
+
diff --git a/docs/api/classes/domain_errors.HopperCancelledError.html b/docs/api/classes/domain_errors.HopperCancelledError.html
index 10c498f24..b5df9e664 100644
--- a/docs/api/classes/domain_errors.HopperCancelledError.html
+++ b/docs/api/classes/domain_errors.HopperCancelledError.html
@@ -14,14 +14,14 @@
-
+Defined in src/domain/errors.ts:424
Properties
@@ -60,7 +60,7 @@
_tag : "HopperCancelledError"
+Defined in src/domain/errors.ts:422
Readonlycleanup Incomplete
cleanupIncomplete : boolean = false
diff --git a/docs/api/classes/domain_errors.HopperError.html b/docs/api/classes/domain_errors.HopperError.html
index af67ada8c..ddaf1ee68 100644
--- a/docs/api/classes/domain_errors.HopperError.html
+++ b/docs/api/classes/domain_errors.HopperError.html
@@ -14,7 +14,7 @@
-
+
AnalysisError
diff --git a/docs/api/classes/domain_errors.HopperProcessError.html b/docs/api/classes/domain_errors.HopperProcessError.html
index c27b83966..375d1362c 100644
--- a/docs/api/classes/domain_errors.HopperProcessError.html
+++ b/docs/api/classes/domain_errors.HopperProcessError.html
@@ -14,14 +14,14 @@
-
+Defined in src/domain/errors.ts:459
Properties
@@ -66,7 +66,7 @@
_tag : "HopperProcessError"
+Defined in src/domain/errors.ts:455
Readonlycleanup Incomplete
cleanupIncomplete : boolean = false
@@ -83,12 +83,12 @@
Readonlyexit Code
exitCode : number | null
+Defined in src/domain/errors.ts:459
+Defined in src/domain/errors.ts:456
Readonlyuser Category
userCategory : "permission_required" | "cancelled" | undefined = undefined
@@ -100,7 +100,7 @@
userMessage : string | undefined
+Defined in src/domain/errors.ts:457
+Defined in src/domain/errors.ts:471
Properties
@@ -64,7 +64,7 @@
_tag : "HopperStartError"
+Defined in src/domain/errors.ts:469
Readonlycleanup Incomplete
cleanupIncomplete : boolean = false
diff --git a/docs/api/classes/domain_errors.HopperTimeoutError.html b/docs/api/classes/domain_errors.HopperTimeoutError.html
index ab2eefb08..ac6ebc2da 100644
--- a/docs/api/classes/domain_errors.HopperTimeoutError.html
+++ b/docs/api/classes/domain_errors.HopperTimeoutError.html
@@ -14,14 +14,14 @@
-
+Defined in src/domain/errors.ts:415
Properties
@@ -65,7 +65,7 @@
_tag : "HopperTimeoutError"
+Defined in src/domain/errors.ts:413
Readonlycleanup Incomplete
cleanupIncomplete : boolean = false
@@ -82,7 +82,7 @@
Readonlytimeout Ms
timeoutMs : number
+Defined in src/domain/errors.ts:415
Readonlyuser Category
userCategory : "permission_required" | "cancelled" | undefined = undefined
diff --git a/docs/api/classes/domain_errors.InvestigationWorkspaceError.html b/docs/api/classes/domain_errors.InvestigationWorkspaceError.html
index 8453e4a8b..dbc20d902 100644
--- a/docs/api/classes/domain_errors.InvestigationWorkspaceError.html
+++ b/docs/api/classes/domain_errors.InvestigationWorkspaceError.html
@@ -14,14 +14,14 @@
-
+Defined in src/domain/errors.ts:374
Properties
@@ -68,7 +68,7 @@
_tag : "InvestigationWorkspaceError"
+Defined in src/domain/errors.ts:372
Readonlycleanup Incomplete
cleanupIncomplete : boolean = false
+Defined in src/domain/errors.ts:375
Readonlyreason
reason : | "io" | "integrity" | "disabled" | "outside-root" | "not-file" | "too-large" | "invalid-json" | "locked" | "revision-conflict" | "name-conflict"
+Defined in src/domain/errors.ts:376
Readonlyuser Category
userCategory : "permission_required" | "cancelled" | undefined = undefined
diff --git a/docs/api/classes/domain_errors.NoBinaryOpenError.html b/docs/api/classes/domain_errors.NoBinaryOpenError.html
index 2f86f51ca..cd4b3aea4 100644
--- a/docs/api/classes/domain_errors.NoBinaryOpenError.html
+++ b/docs/api/classes/domain_errors.NoBinaryOpenError.html
@@ -14,14 +14,14 @@
-
+Defined in src/domain/errors.ts:484
Properties
@@ -60,7 +60,7 @@
_tag : "NoBinaryOpenError"
+Defined in src/domain/errors.ts:483
Readonlycleanup Incomplete
cleanupIncomplete : boolean = false
diff --git a/docs/api/classes/domain_errors.PermissionRequiredError.html b/docs/api/classes/domain_errors.PermissionRequiredError.html
index 60a02204d..86e0f9683 100644
--- a/docs/api/classes/domain_errors.PermissionRequiredError.html
+++ b/docs/api/classes/domain_errors.PermissionRequiredError.html
@@ -14,14 +14,14 @@
-
+Defined in src/domain/errors.ts:549
Properties
@@ -73,12 +73,12 @@
_tag : "PermissionRequiredError" = ...
+Defined in src/domain/errors.ts:547
+Defined in src/domain/errors.ts:552
Readonlycleanup Incomplete
cleanupIncomplete : boolean = false
+Defined in src/domain/errors.ts:553
+Defined in src/domain/errors.ts:551
+Defined in src/domain/errors.ts:550
Readonlyrestart Required
restartRequired : boolean
+Defined in src/domain/errors.ts:554
Readonlyuser Category
userCategory : "permission_required" | "cancelled" | undefined = undefined
diff --git a/docs/api/classes/domain_errors.ProviderAdapterError.html b/docs/api/classes/domain_errors.ProviderAdapterError.html
index e1c318ba3..8c78d947b 100644
--- a/docs/api/classes/domain_errors.ProviderAdapterError.html
+++ b/docs/api/classes/domain_errors.ProviderAdapterError.html
@@ -14,14 +14,14 @@
-
+Defined in src/domain/errors.ts:242
Properties
@@ -69,7 +69,7 @@
_tag : "ProviderAdapterError"
+Defined in src/domain/errors.ts:239
Readonlycleanup Incomplete
cleanupIncomplete : boolean = false
@@ -86,17 +86,17 @@
Readonlydiagnostics
diagnostics : Readonly < Record < string , JSONType > > | undefined
+Defined in src/domain/errors.ts:240
Readonlyoperation
operation : string
+Defined in src/domain/errors.ts:244
Readonlyprovider Id
providerId : string
+Defined in src/domain/errors.ts:243
Readonlyuser Category
userCategory : "permission_required" | "cancelled" | undefined = undefined
diff --git a/docs/api/classes/domain_errors.ProviderSelectionError.html b/docs/api/classes/domain_errors.ProviderSelectionError.html
index b428ec31f..98ed0f490 100644
--- a/docs/api/classes/domain_errors.ProviderSelectionError.html
+++ b/docs/api/classes/domain_errors.ProviderSelectionError.html
@@ -14,14 +14,14 @@
-
+Defined in src/domain/errors.ts:177
Properties
@@ -69,12 +69,12 @@
_tag : "ProviderSelectionError"
+Defined in src/domain/errors.ts:169
Readonlycandidate Ids
candidateIds : readonly string []
+Defined in src/domain/errors.ts:173
Readonlycleanup Incomplete
cleanupIncomplete : boolean = false
@@ -91,22 +91,22 @@
Readonlyoperation
operation : string
+Defined in src/domain/errors.ts:170
+Defined in src/domain/errors.ts:171
+Defined in src/domain/errors.ts:174
Readonlyrequested Provider Id
requestedProviderId : string
+Defined in src/domain/errors.ts:172
Readonlyuser Category
userCategory : "permission_required" | "cancelled" | undefined = undefined
+Defined in src/domain/errors.ts:175
+Defined in src/domain/errors.ts:397
Properties
@@ -66,7 +66,7 @@
_tag : "UnknownRegistryError"
+Defined in src/domain/errors.ts:395
Readonlycleanup Incomplete
cleanupIncomplete : boolean = false
@@ -83,7 +83,7 @@
Readonlyreason
reason : | "limit" | "integrity" | "revision-conflict" | "not-found" | "already-exists" | "invalid-transition"
+Defined in src/domain/errors.ts:398
Readonlyuser Category
userCategory : "permission_required" | "cancelled" | undefined = undefined
diff --git a/docs/api/classes/domain_permissionPolicy.PermissionGrantError.html b/docs/api/classes/domain_permissionPolicy.PermissionGrantError.html
index b3459a920..188d1e7ae 100644
--- a/docs/api/classes/domain_permissionPolicy.PermissionGrantError.html
+++ b/docs/api/classes/domain_permissionPolicy.PermissionGrantError.html
@@ -14,7 +14,7 @@
-
+
Hierarchy
Error
diff --git a/docs/api/classes/ghidra_GhidraLauncher.GhidraLaunchError.html b/docs/api/classes/ghidra_GhidraLauncher.GhidraLaunchError.html
index 41c2eed6c..1ddbf1369 100644
--- a/docs/api/classes/ghidra_GhidraLauncher.GhidraLaunchError.html
+++ b/docs/api/classes/ghidra_GhidraLauncher.GhidraLaunchError.html
@@ -14,7 +14,7 @@
-
+
Hierarchy
Error
diff --git a/docs/api/classes/ghidra_GhidraSessionError.GhidraSessionError.html b/docs/api/classes/ghidra_GhidraSessionError.GhidraSessionError.html
index e020fd701..6626a5278 100644
--- a/docs/api/classes/ghidra_GhidraSessionError.GhidraSessionError.html
+++ b/docs/api/classes/ghidra_GhidraSessionError.GhidraSessionError.html
@@ -14,7 +14,7 @@
-
+
Hierarchy
Error
diff --git a/docs/api/classes/ghidra_protocol.GhidraRemoteError.html b/docs/api/classes/ghidra_protocol.GhidraRemoteError.html
index ea156cdd0..f353835ea 100644
--- a/docs/api/classes/ghidra_protocol.GhidraRemoteError.html
+++ b/docs/api/classes/ghidra_protocol.GhidraRemoteError.html
@@ -14,7 +14,7 @@
-
+
Hierarchy
Error
diff --git a/docs/api/functions/application_CapabilityInventory.buildCapabilityInventory.html b/docs/api/functions/application_CapabilityInventory.buildCapabilityInventory.html
index 6f89b1053..cf14bb737 100644
--- a/docs/api/functions/application_CapabilityInventory.buildCapabilityInventory.html
+++ b/docs/api/functions/application_CapabilityInventory.buildCapabilityInventory.html
@@ -14,7 +14,7 @@
-buildCapabilityInventory ( sessionStatus : JSONType , policy : { browserObservationEnabled ?: boolean ; electronObservationEnabled ?: boolean ; evidenceFileRoots : number ; javascriptReplayEnabled ?: boolean ; managedRuntimeEnabled ?: boolean ; processCaptureEnabled : boolean ; } , ) : { annotations : { destructive : boolean ; idempotent : boolean ; open_world : boolean ; read_only : boolean ; } ; available : boolean ; name : | "open_binary" | "list_browser_targets" | "inspect_web_page" | "analyze_web_bundle" | "observe_web_session" | "discover_webmcp_tools" | "compare_web_captures" | "capture_web_screenshot" | "compare_web_screenshots" | "list_electron_targets" | "inspect_electron_page" | "inventory_artifact" | "extract_artifact" | "analyze_javascript_application" | "swift_classes" | "get_objc_classes" | "get_objc_protocols" | "batch_decompile" | "get_call_graph" | "analyze_swift_types" | "find_xrefs_to_name" | "binary_overview" | "analyze_function" | "trace_feature" | "comment" | "compare_artifacts" | "find_changed_behavior" | "compare_process_captures" | "compare_functions" | "capture_process_scenario" | "inspect_managed_members" | "address_name" | "current_address" | "current_procedure" | "current_document" | "goto_address" | "inline_comment" | "list_bookmarks" | "list_documents" | "list_names" | "list_procedures" | "list_segments" | "list_strings" | "next_address" | "prev_address" | "procedure_address" | "procedure_assembly" | "procedure_callees" | "procedure_callers" | "procedure_info" | "procedure_references" | "procedure_pseudo_code" | "resolve_containing_procedure" | "search_procedures" | "search_strings" | "set_address_name" | "set_addresses_names" | "set_bookmark" | "set_comment" | "set_current_document" | "set_inline_comment" | "unset_bookmark" | "xrefs" | "inspect_macho" | "inspect_signature" | "inspect_plist" | "list_architectures" | "demangle_swift" | "inspect_managed_artifact" | "inspect_managed_native_boundaries" | "compare_managed_members" | "import_managed_reconstruction" | "plan_managed_runtime_correlation" | "close_binary" | "binary_session" | "export_evidence_bundle" | "import_evidence_bundle" | "compare_bundles" | "build_call_path" | "correlate_static_and_runtime" | "verify_reconstruction" | "list_unknowns" | "record_unknown" | "update_unknown" | "verify_unknown_resolution" | "reconcile_javascript_runtime" | "trace_application_feature" | "compare_application_versions" | "run_controlled_replay" ; reason : ToolAvailabilityReason ; remediation : string | null ; surface : ToolKind ; } []
+buildCapabilityInventory ( sessionStatus : JSONType , policy : { browserObservationEnabled ?: boolean ; electronObservationEnabled ?: boolean ; evidenceFileRoots : number ; javascriptReplayEnabled ?: boolean ; managedRuntimeEnabled ?: boolean ; processCaptureEnabled : boolean ; } , ) : { annotations : { destructive : boolean ; idempotent : boolean ; open_world : boolean ; read_only : boolean ; } ; available : boolean ; effects : { accessesNetwork : boolean ; changesUiState : boolean ; idempotent : boolean ; launchesProcess : boolean ; mayDiscardData : boolean ; mutatesSession : boolean ; mutatesTarget : boolean ; writesFilesystem : boolean ; } ; name : | "open_binary" | "list_browser_targets" | "inspect_web_page" | "analyze_web_bundle" | "observe_web_session" | "discover_webmcp_tools" | "compare_web_captures" | "capture_web_screenshot" | "compare_web_screenshots" | "list_electron_targets" | "inspect_electron_page" | "inventory_artifact" | "extract_artifact" | "analyze_javascript_application" | "swift_classes" | "get_objc_classes" | "get_objc_protocols" | "batch_decompile" | "get_call_graph" | "analyze_swift_types" | "find_xrefs_to_name" | "binary_overview" | "analyze_function" | "trace_feature" | "comment" | "compare_artifacts" | "find_changed_behavior" | "compare_process_captures" | "compare_functions" | "capture_process_scenario" | "inspect_managed_members" | "address_name" | "current_address" | "current_procedure" | "current_document" | "goto_address" | "inline_comment" | "list_bookmarks" | "list_documents" | "list_names" | "list_procedures" | "list_segments" | "list_strings" | "next_address" | "prev_address" | "procedure_address" | "procedure_assembly" | "procedure_callees" | "procedure_callers" | "procedure_info" | "procedure_references" | "procedure_pseudo_code" | "resolve_containing_procedure" | "search_procedures" | "search_strings" | "set_address_name" | "set_addresses_names" | "set_bookmark" | "set_comment" | "set_current_document" | "set_inline_comment" | "unset_bookmark" | "xrefs" | "inspect_macho" | "inspect_signature" | "inspect_plist" | "list_architectures" | "demangle_swift" | "inspect_managed_artifact" | "inspect_managed_native_boundaries" | "compare_managed_members" | "import_managed_reconstruction" | "plan_managed_runtime_correlation" | "close_binary" | "binary_session" | "export_evidence_bundle" | "import_evidence_bundle" | "compare_bundles" | "build_call_path" | "correlate_static_and_runtime" | "verify_reconstruction" | "list_unknowns" | "record_unknown" | "update_unknown" | "verify_unknown_resolution" | "reconcile_javascript_runtime" | "trace_application_feature" | "compare_application_versions" | "run_controlled_replay" ; reason : ToolAvailabilityReason ; remediation : string | null ; surface : ToolKind ; } []
@@ -23,7 +23,7 @@
sessionStatus : JSONType
policy : { browserObservationEnabled ?: boolean ; electronObservationEnabled ?: boolean ; evidenceFileRoots : number ; javascriptReplayEnabled ?: boolean ; managedRuntimeEnabled ?: boolean ; processCaptureEnabled : boolean ; }
-Returns { annotations : { destructive : boolean ; idempotent : boolean ; open_world : boolean ; read_only : boolean ; } ; available : boolean ; name : | "open_binary" | "list_browser_targets" | "inspect_web_page" | "analyze_web_bundle" | "observe_web_session" | "discover_webmcp_tools" | "compare_web_captures" | "capture_web_screenshot" | "compare_web_screenshots" | "list_electron_targets" | "inspect_electron_page" | "inventory_artifact" | "extract_artifact" | "analyze_javascript_application" | "swift_classes" | "get_objc_classes" | "get_objc_protocols" | "batch_decompile" | "get_call_graph" | "analyze_swift_types" | "find_xrefs_to_name" | "binary_overview" | "analyze_function" | "trace_feature" | "comment" | "compare_artifacts" | "find_changed_behavior" | "compare_process_captures" | "compare_functions" | "capture_process_scenario" | "inspect_managed_members" | "address_name" | "current_address" | "current_procedure" | "current_document" | "goto_address" | "inline_comment" | "list_bookmarks" | "list_documents" | "list_names" | "list_procedures" | "list_segments" | "list_strings" | "next_address" | "prev_address" | "procedure_address" | "procedure_assembly" | "procedure_callees" | "procedure_callers" | "procedure_info" | "procedure_references" | "procedure_pseudo_code" | "resolve_containing_procedure" | "search_procedures" | "search_strings" | "set_address_name" | "set_addresses_names" | "set_bookmark" | "set_comment" | "set_current_document" | "set_inline_comment" | "unset_bookmark" | "xrefs" | "inspect_macho" | "inspect_signature" | "inspect_plist" | "list_architectures" | "demangle_swift" | "inspect_managed_artifact" | "inspect_managed_native_boundaries" | "compare_managed_members" | "import_managed_reconstruction" | "plan_managed_runtime_correlation" | "close_binary" | "binary_session" | "export_evidence_bundle" | "import_evidence_bundle" | "compare_bundles" | "build_call_path" | "correlate_static_and_runtime" | "verify_reconstruction" | "list_unknowns" | "record_unknown" | "update_unknown" | "verify_unknown_resolution" | "reconcile_javascript_runtime" | "trace_application_feature" | "compare_application_versions" | "run_controlled_replay" ; reason : ToolAvailabilityReason ; remediation : string | null ; surface : ToolKind ; } []
+Returns { annotations : { destructive : boolean ; idempotent : boolean ; open_world : boolean ; read_only : boolean ; } ; available : boolean ; effects : { accessesNetwork : boolean ; changesUiState : boolean ; idempotent : boolean ; launchesProcess : boolean ; mayDiscardData : boolean ; mutatesSession : boolean ; mutatesTarget : boolean ; writesFilesystem : boolean ; } ; name : | "open_binary" | "list_browser_targets" | "inspect_web_page" | "analyze_web_bundle" | "observe_web_session" | "discover_webmcp_tools" | "compare_web_captures" | "capture_web_screenshot" | "compare_web_screenshots" | "list_electron_targets" | "inspect_electron_page" | "inventory_artifact" | "extract_artifact" | "analyze_javascript_application" | "swift_classes" | "get_objc_classes" | "get_objc_protocols" | "batch_decompile" | "get_call_graph" | "analyze_swift_types" | "find_xrefs_to_name" | "binary_overview" | "analyze_function" | "trace_feature" | "comment" | "compare_artifacts" | "find_changed_behavior" | "compare_process_captures" | "compare_functions" | "capture_process_scenario" | "inspect_managed_members" | "address_name" | "current_address" | "current_procedure" | "current_document" | "goto_address" | "inline_comment" | "list_bookmarks" | "list_documents" | "list_names" | "list_procedures" | "list_segments" | "list_strings" | "next_address" | "prev_address" | "procedure_address" | "procedure_assembly" | "procedure_callees" | "procedure_callers" | "procedure_info" | "procedure_references" | "procedure_pseudo_code" | "resolve_containing_procedure" | "search_procedures" | "search_strings" | "set_address_name" | "set_addresses_names" | "set_bookmark" | "set_comment" | "set_current_document" | "set_inline_comment" | "unset_bookmark" | "xrefs" | "inspect_macho" | "inspect_signature" | "inspect_plist" | "list_architectures" | "demangle_swift" | "inspect_managed_artifact" | "inspect_managed_native_boundaries" | "compare_managed_members" | "import_managed_reconstruction" | "plan_managed_runtime_correlation" | "close_binary" | "binary_session" | "export_evidence_bundle" | "import_evidence_bundle" | "compare_bundles" | "build_call_path" | "correlate_static_and_runtime" | "verify_reconstruction" | "list_unknowns" | "record_unknown" | "update_unknown" | "verify_unknown_resolution" | "reconcile_javascript_runtime" | "trace_application_feature" | "compare_application_versions" | "run_controlled_replay" ; reason : ToolAvailabilityReason ; remediation : string | null ; surface : ToolKind ; } []
+Defined in src/application/Doctor.ts:97
+Defined in src/application/Doctor.ts:337
+Defined in src/application/JavaScriptApplicationWorkflowService.ts:77
+Defined in src/application/JavaScriptApplicationWorkflowService.ts:25
+Defined in src/application/JavaScriptReplayService.ts:45
+Defined in src/application/JavaScriptRuntimeReconciliationService.ts:18
+Defined in src/application/ManagedMemberComparisonService.ts:44
+Defined in src/application/ProcessSampling.ts:178
+Defined in src/application/ProcessSampling.ts:449
+Defined in src/contracts/toolOutputSchemas.ts:59
+Defined in src/domain/artifactComparison.ts:108
+Defined in src/domain/bundleComparison.ts:94
+Defined in src/domain/errors.ts:573
+Defined in src/ghidra/GhidraInstallation.ts:224
+Defined in src/ghidra/GhidraInstallation.ts:245
+Defined in src/ghidra/GhidraInstallation.ts:95
+Defined in src/server/registerApplicationTools.ts:38
+Defined in src/server/registerArtifactComparisonTool.ts:21
+Defined in src/server/registerBrowserTools.ts:44
+Defined in src/server/registerBundleComparisonTool.ts:21
+Defined in src/server/registerElectronTools.ts:34
+Defined in src/server/registerEnhancedTools.ts:44
+Defined in src/server/registerEvidenceTools.ts:33
+Defined in src/server/registerFunctionComparisonTool.ts:21
+Defined in src/server/registerInvestigationTools.ts:49
+Defined in src/server/registerManagedWorkflowTools.ts:38
+Defined in src/server/registerOfficialTools.ts:33
+Defined in src/server/registerProcessComparisonTool.ts:26
+Defined in src/server/registerSessionStatusTool.ts:16
+Defined in src/server/registerSessionTools.ts:609
+Optionalinstalled Skill Identity
+
+
+installedSkillIdentity ? () : Promise < InstalledSkillIdentity | undefined >
+
+
Returns Promise < InstalledSkillIdentity | undefined >
+
Optionalinstalled Skill Version
+Defined in src/application/Doctor.ts:82
linux Demo Runtime Ready
@@ -211,7 +221,7 @@
Properties
Methods
-
+
+Defined in src/application/Doctor.ts:329
Optional Readonlyprovider Inspections
+Defined in src/application/Doctor.ts:330
+Defined in src/application/ProcessSampling.ts:143
task Ids
@@ -58,7 +58,7 @@
signal : AbortSignal
Returns Promise < readonly number [] | undefined >
+Defined in src/application/ProcessSampling.ts:139
Properties
Readonlydescription
description : string
+Defined in src/contracts/toolContractTypes.ts:36
+
+Defined in src/contracts/toolContractTypes.ts:42
+Defined in src/contracts/toolContractTypes.ts:38
+Defined in src/contracts/toolContractTypes.ts:37
+Defined in src/contracts/toolContractTypes.ts:34
Readonlyoutput Schema
outputSchema : ZodObject
+Defined in src/contracts/toolContractTypes.ts:39
+
+Readonlytitle
+title : string
+Defined in src/contracts/toolContractTypes.ts:15
Readonlytitle
title : string
+Defined in src/contracts/toolContractTypes.ts:16
+Defined in src/ghidra/GhidraInstallation.ts:70
read Text
@@ -70,7 +88,7 @@
path : string
Returns string | undefined
+Defined in src/ghidra/GhidraInstallation.ts:68
-Classes EnhancedTools
+Classes EnhancedTools
+
+Type Aliases ValidatedEnhancedCall
-Functions analyzeJavaScriptApplication
+Functions analyzeJavaScriptApplication analyzeJavaScriptApplicationValidated
-Functions compareApplicationVersionsEvidence traceApplicationFeatureEvidence
+Functions compareApplicationVersionsEvidence compareApplicationVersionsEvidenceValidated traceApplicationFeatureEvidence traceApplicationFeatureEvidenceValidated
+Functions runControlledReplay runControlledReplayValidated
-Functions reconcileJavaScriptRuntimeEvidence
+Functions reconcileJavaScriptRuntimeEvidence reconcileJavaScriptRuntimeEvidenceValidated
+Functions compareManagedMemberPaths compareManagedMembersEvidenceValidated
-Functions importManagedReconstructionEvidence
+Functions importManagedReconstructionEvidence importManagedReconstructionEvidenceValidated
+Functions planManagedRuntimeCorrelationEvidence planManagedRuntimeCorrelationEvidenceValidated
-Variables MANAGED_WORKFLOW_TOOL_CONTRACTS
+Variables compareManagedMembersReferenceInputSchema MANAGED_WORKFLOW_TOOL_CONTRACTS managedReconstructionReferenceInputSchema managedRuntimeCorrelationReferenceInputSchema
-Interfaces ToolAnnotations ToolContract ToolExample
-
-Type Aliases ToolKind
+Interfaces ToolContract ToolExample
+References ToolContract → ToolContract ToolExample → ToolExample
+Functions evidenceResultOf requireOutputSchema
-Classes AnalysisCancelledError AnalysisCapabilityUnavailableError AnalysisError AnalysisInputError AnalysisOutputError AnalysisProtocolError AnalysisTimeoutError ArtifactOperationError BinaryTargetError BrowserObservationError ConfigurationError EvidenceFileError EvidenceIntegrityError EvidenceLimitError HopperCancelledError HopperError HopperProcessError HopperProtocolError HopperRemoteError HopperStartError HopperTimeoutError InvestigationWorkspaceError NoBinaryOpenError PermissionRequiredError ProviderAdapterError ProviderSelectionError ReplayPlanStaleError UnknownRegistryError
+Classes AnalysisCancelledError AnalysisCapabilityUnavailableError AnalysisError AnalysisInputError AnalysisOutputError AnalysisProtocolError AnalysisTimeoutError ArtifactOperationError BinaryTargetError BrowserObservationError ConfigurationError EvidenceFileError EvidenceIntegrityError EvidenceLimitError EvidenceReferenceError HopperCancelledError HopperError HopperProcessError HopperProtocolError HopperRemoteError HopperStartError HopperTimeoutError InvestigationWorkspaceError NoBinaryOpenError PermissionRequiredError ProviderAdapterError ProviderSelectionError ReplayPlanStaleError UnknownRegistryError
-Interfaces AnalysisErrorProjection ProviderAdapterErrorOptions ProviderSelectionErrorOptions ProviderSelectionRejection
+Interfaces AnalysisErrorProjection AnalysisInputIssue ProviderAdapterErrorOptions ProviderSelectionErrorOptions ProviderSelectionRejection
Type Aliases AnalysisErrorTag BrowserObservationOperation HopperDiagnosticType ProviderSelectionFailureReason
@@ -35,9 +35,9 @@
On This Page
Classes
-
+
Interfaces
-
+
Type Aliases
Functions
diff --git a/docs/api/modules/domain_inputIssueProjection.html b/docs/api/modules/domain_inputIssueProjection.html
new file mode 100644
index 000000000..a6a782e1b
--- /dev/null
+++ b/docs/api/modules/domain_inputIssueProjection.html
@@ -0,0 +1,36 @@
+domain/inputIssueProjection | rea-agents - v1.7.0
+
+
+
+
+
Module domain/inputIssueProjection
+
+Functions projectInputIssues
+
+
diff --git a/docs/api/modules/server_sessionEvidence.html b/docs/api/modules/server_sessionEvidence.html
index 12c3394a6..b42f6569f 100644
--- a/docs/api/modules/server_sessionEvidence.html
+++ b/docs/api/modules/server_sessionEvidence.html
@@ -11,7 +11,7 @@
server/sessionEvidence
Module server/sessionEvidence
-Functions isSessionEvidence resolveSessionEvidence
+Functions resolveSessionEvidenceIds
-Functions toolRegistrationOptions
+Functions closeObjectSchemas toolRegistrationOptions
+Defined in src/contracts/artifactToolContracts.ts:120
Composes direct provider operations into bounded reverse-engineering tools. -Inputs are parsed again at this application boundary even though MCP normally -validates them, allowing direct callers to use the same service safely.
+Direct callers useexecute; adapters that own validation use +executeValidatedso an MCP input is parsed exactly once.