Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/product-catalog.json
Original file line number Diff line number Diff line change
Expand Up @@ -680,10 +680,10 @@
"mcp_resource_templates": 11
},
"digests": {
"tools_sha256": "8021786c901ca9225ba8e2477f220c8c15d61b8df5618b221f61417cae8c8a36",
"tools_sha256": "b0e8b9c894ef347b6680a3a5bfdb4cba5c10e9129eeaa43a5ea22ce4d398d417",
"prompts_sha256": "3886a3bf55a448def79e3eb429e6a56eb2ba075423c5cb1e5747642b389ef8fe",
"resources_sha256": "e0e872276ebf6f88e916ef24930a99eed27ce4c93e494e60820e9bd8cc8497c3",
"combined_sha256": "2da444fd95a40c28a6c0332a5970edca6b984f0c2922e4c02eaf7458a6f3dd0e",
"combined_sha256": "bab5657d9525ec4f798d0a9ef6001412d9c11f77fb0ddc925c7076fd10921dc9",
"providers_sha256": "7446b51788734ebf6f4f702e3a5a8c9f0b61967490c245f30bd37b2060827e6b"
}
}
Expand Down
4 changes: 2 additions & 2 deletions docs/verification/managed-conformance-manifest.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"schema_version": 1,
"manifest_id": "ecm_aba877529714e59795e8a7b51c5513b17081bd701cea1ffee31422a1d95dfa31",
"manifest_id": "ecm_c44391ed8e365e21871664422aa38fa6c12598006cde731d65a9d9e271b0fa5f",
"verifier": {
"id": "rea-managed-conformance",
"version": "1"
Expand All @@ -14,7 +14,7 @@
"skill_digests": [
{
"skill_id": "reverse-engineer-anything",
"sha256": "43fccde70ab600dfc86785a37b414865cb8c0f2cb479eb4ed6c2a90998e0f6a6"
"sha256": "97a5bc5d29f162fe171ddbb8f4f5ba9fcba34ad336d4cdcae0c564223aa4cfe8"
}
],
"claims": [
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
"mcp-registry:check": "node scripts/verify-mcp-registry-metadata.mjs",
"mcp-catalog:generate": "npm run build:cached && node scripts/generate-mcp-tool-catalog.mjs",
"mcp-catalog:check": "node scripts/generate-mcp-tool-catalog.mjs --check",
"prebuild": "npm run deps:check && npm run metadata:check",
"prebuild": "npm run deps:check && npm run metadata:check && node scripts/clean-build-output.mjs",
"build": "tsc -p tsconfig.build.json",
"precheck": "npm run deps:check",
"check": "turbo run typecheck lint format:check knip metadata:check",
Expand Down
10 changes: 10 additions & 0 deletions scripts/clean-build-output.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { rm } from "node:fs/promises";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";

const root = join(dirname(fileURLToPath(import.meta.url)), "..");

await Promise.all([
rm(join(root, "dist"), { recursive: true, force: true }),
rm(join(root, ".cache", "tsconfig.build.tsbuildinfo"), { force: true }),
]);
49 changes: 35 additions & 14 deletions scripts/generate-mcp-tool-catalog.mjs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import { format } from "prettier";
import { Client, InMemoryTransport } from "@modelcontextprotocol/client";
import { McpServer } from "@modelcontextprotocol/server";

import { TOOL_CONTRACTS } from "../dist/contracts/toolContracts.js";
import { MANAGED_WORKFLOW_TOOL_CONTRACTS } from "../dist/contracts/managedWorkflowToolContracts.js";
import { ArtifactProvider } from "../dist/artifacts/ArtifactProvider.js";
import { ManagedStaticProvider } from "../dist/dotnet/ManagedStaticProvider.js";
import { NativeMacOSProvider } from "../dist/native/NativeMacOSProvider.js";
import { toolRegistrationOptions } from "../dist/server/toolRegistrationOptions.js";
import { applyToolInputJsonSchemaOverride } from "../dist/contracts/toolSchemaJsonOverrides.js";
import { ensureGeneratedFile } from "./lib/generated-file.mjs";

const arguments_ = new Set(process.argv.slice(2));
Expand All @@ -26,8 +27,11 @@ const sessionToolNames = new Set([
),
...MANAGED_WORKFLOW_TOOL_CONTRACTS.map(({ name }) => name),
]);
const advertisedTools = await sdkToolCatalog();
const catalog = TOOL_CONTRACTS.map((contract) => {
const options = toolRegistrationOptions(contract);
const advertised = advertisedTools.get(contract.name);
if (advertised === undefined)
throw new Error(`MCP SDK omitted registered tool ${contract.name}`);
return {
name: contract.name,
analysisOperation: [
Expand All @@ -39,23 +43,40 @@ const catalog = TOOL_CONTRACTS.map((contract) => {
].includes(contract.kind)
? contract.name
: null,
title: options.title,
description: options.description,
title: advertised.title,
description: advertised.description,
kind: contract.kind,
requiresSession: sessionToolNames.has(contract.name),
inputSchema: applyToolInputJsonSchemaOverride(
contract.name,
options.inputSchema["~standard"].jsonSchema.input({
target: "draft-2020-12",
}),
),
outputSchema: options.outputSchema["~standard"].jsonSchema.output({
target: "draft-2020-12",
}),
annotations: options.annotations,
inputSchema: advertised.inputSchema,
outputSchema: advertised.outputSchema,
annotations: advertised.annotations,
effects: contract.effects,
};
});

async function sdkToolCatalog() {
const server = new McpServer({ name: "rea-catalog-generator", version: "0" });
for (const contract of TOOL_CONTRACTS)
server.registerTool(
contract.name,
toolRegistrationOptions(contract),
async () => ({
content: [{ type: "text", text: "Catalog-only handler" }],
isError: true,
}),
);
const client = new Client({ name: "rea-catalog-generator", version: "0" });
const [clientTransport, serverTransport] =
InMemoryTransport.createLinkedPair();
try {
await server.connect(serverTransport);
await client.connect(clientTransport);
const { tools } = await client.listTools();
return new Map(tools.map((tool) => [tool.name, tool]));
} finally {
await Promise.allSettled([client.close(), server.close()]);
}
}
const auxiliaryProviders = [
new ArtifactProvider(false, false),
new NativeMacOSProvider(undefined, CATALOG_PLATFORM),
Expand Down
11 changes: 4 additions & 7 deletions scripts/lib/verify-package-core.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ export const runWithStatus = async (command, args, env) => {
/** Parse JSON from a command output string. */
export const json = (text) => JSON.parse(text);

/** Verify that the advertised MCP catalog matches the session's available tools. */
export const verifyAvailableToolCatalog = async (client, options) => {
/** Verify that the complete advertised MCP catalog matches session metadata. */
export const verifyCompleteToolCatalog = async (client, options) => {
const listed = await client.listTools(undefined, options);
const status = await client.callTool(
{ name: "binary_session", arguments: { detail: "full" } },
Expand All @@ -38,14 +38,11 @@ export const verifyAvailableToolCatalog = async (client, options) => {
const availability = status.structuredContent?.result?.tool_availability;
if (!Array.isArray(availability))
throw new Error("packaged MCP omitted tool availability");
const expected = availability
.filter(({ available }) => available === true)
.map(({ name }) => name)
.sort();
const expected = availability.map(({ name }) => name).sort();
const observed = listed.tools.map(({ name }) => name).sort();
if (JSON.stringify(observed) !== JSON.stringify(expected))
throw new Error(
"packaged MCP tool inventory diverged from session availability",
"packaged MCP tool inventory diverged from session metadata",
);
return observed;
};
Expand Down
6 changes: 3 additions & 3 deletions scripts/verify-managed-conformance.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -344,11 +344,11 @@ try {
assert.equal(reconstructionImport.value.confidence, "inferred");
const runtimePlan = await planManagedRuntimeCorrelationEvidence(
{
policy: {
enabled: true,
policy: () => ({
status: "enabled",
roots: [workspace],
executablePath: runtimeExecutable,
},
}),
authority: runtimeAuthority.value,
},
{
Expand Down
34 changes: 21 additions & 13 deletions scripts/verify-package-mcp.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,12 @@ import { Client } from "@modelcontextprotocol/client";
import { StdioClientTransport } from "@modelcontextprotocol/client/stdio";
import { MCP_STARTUP_POLICY } from "../dist/mcpStartupPolicy.js";
import * as prompts from "./verify-package-prompts.mjs";
import {
json,
verifyAvailableToolCatalog,
} from "./lib/verify-package-core.mjs";
import { json, verifyCompleteToolCatalog } from "./lib/verify-package-core.mjs";

const execute = promisify(execFile);

const verifyMcpToolsAndPrompts = async (client, mcpOptions) => {
await verifyAvailableToolCatalog(client, mcpOptions);
await verifyCompleteToolCatalog(client, mcpOptions);
await prompts.verifyPromptCatalog(client, mcpOptions, prompts.names);
await prompts.verifyPromptCompletion(client, mcpOptions, false);
};
Expand Down Expand Up @@ -43,11 +40,21 @@ const verifyMcpReplay = async (client, mcpOptions, investigationReplay) => {
};

const verifyMcpTargetFree = async (client, mcpOptions) => {
const names = (await client.listTools(undefined, mcpOptions)).tools.map(
({ name }) => name,
const status = await client.callTool(
{ name: "binary_session", arguments: { detail: "full" } },
mcpOptions,
);
if (names.includes("current_document"))
throw new Error("packaged target-free MCP advertised a target-bound tool");
const currentDocument =
status.structuredContent?.result?.tool_availability?.find(
({ name }) => name === "current_document",
);
if (
currentDocument?.available !== false ||
currentDocument.reason !== "target_required"
)
throw new Error(
"packaged target-free MCP omitted target-bound availability metadata",
);
};

const verifyMcpUnknownProvider = async (client, mcpOptions) => {
Expand Down Expand Up @@ -96,11 +103,12 @@ const verifyMcpOpenAndBind = async (client, mcpOptions) => {
};

const verifyMcpLinuxToolAvailability = async (client, mcpOptions) => {
const names = (await client.listTools(undefined, mcpOptions)).tools.map(
({ name }) => name,
const current = await client.callTool(
{ name: "current_document", arguments: {} },
mcpOptions,
);
if (names.includes("current_document"))
throw new Error("packaged Linux MCP advertised unavailable Hopper tools");
if (current.isError !== true)
throw new Error("packaged Linux MCP executed an unavailable Hopper tool");
};

const verifyMcpNonLinuxCurrentDocument = async (
Expand Down
34 changes: 24 additions & 10 deletions scripts/verify-real-javascript-replay.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const roots = [
),
];
const policy = {
enabled: true,
status: "enabled",
roots,
nodePath: process.execPath,
bubblewrapPath:
Expand Down Expand Up @@ -93,7 +93,7 @@ const authority = new PermissionAuthority(
),
);
const dependencies = {
policy,
policy: () => policy,
host: new SystemJavaScriptReplayHost(),
runner: new LinuxJavaScriptReplayRunner(),
authority,
Expand Down Expand Up @@ -131,18 +131,20 @@ const defaultInput = {
{ case_id: "plain", arguments: ["plain"] },
],
generator: { preset: "parser-boundaries", seed: 7, count: 4 },
approved: false,
};
const input =
const suppliedPlanInput =
suppliedInput === undefined
? undefined
: (({ approved: _approved, plan_digest: _planDigest, ...planInput }) =>
planInput)(suppliedInput);
const input =
suppliedPlanInput === undefined
? defaultInput
: {
...suppliedInput,
...suppliedPlanInput,
mode: "plan",
left: suppliedLeft,
...(suppliedRight === undefined ? {} : { right: suppliedRight }),
approved: false,
plan_digest: undefined,
reproducer_export: undefined,
};

Expand Down Expand Up @@ -177,7 +179,21 @@ if (
({ status }) => status === "unknown",
) === true
)
throw new Error("Real replay verifier received incomplete Evidence");
throw new Error(
`Real replay verifier received incomplete Evidence: ${JSON.stringify({
authority: evidence?.authority ?? null,
isolation: evidence?.environment?.isolation ?? null,
termination: evidence?.normalized_result?.termination ?? null,
cleanup: evidence?.normalized_result?.cleanup?.state ?? null,
outcomes:
evidence?.normalized_result?.outcomes?.map(({ outcome }) => outcome) ??
[],
stderr: evidence?.normalized_result?.stderr ?? null,
comparison_statuses:
evidence?.normalized_result?.comparison?.map(({ status }) => status) ??
[],
})}`,
);

if (suppliedInput !== undefined) {
process.stdout.write(
Expand Down Expand Up @@ -222,7 +238,6 @@ const runSingle = async (path, limits = undefined) => {
},
cases: [{ case_id: "probe", arguments: [] }],
...(limits === undefined ? {} : { limits }),
approved: false,
};
const proposed = await runControlledReplay(dependencies, manifest);
if (!proposed.ok || proposed.value.plan === null)
Expand Down Expand Up @@ -288,7 +303,6 @@ const differentialTimeoutInput = {
},
cases: [{ case_id: "probe", arguments: [] }],
limits: { wall_time_ms: 100 },
approved: false,
};
const differentialTimeoutPlan = await runControlledReplay(
dependencies,
Expand Down
4 changes: 2 additions & 2 deletions scripts/verify-windows-package.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { promisify } from "node:util";
import { Client } from "@modelcontextprotocol/client";
import { StdioClientTransport } from "@modelcontextprotocol/client/stdio";

import { verifyAvailableToolCatalog } from "./lib/verify-package-core.mjs";
import { verifyCompleteToolCatalog } from "./lib/verify-package-core.mjs";
import { completeVerifierRun, createVerifierRun } from "./lib/verifier-run.mjs";

const exec = promisify(execFile);
Expand Down Expand Up @@ -84,7 +84,7 @@ try {
let toolCount = 0;
try {
await client.connect(server);
toolCount = (await verifyAvailableToolCatalog(client)).length;
toolCount = (await verifyCompleteToolCatalog(client)).length;
} finally {
await client.close();
}
Expand Down
2 changes: 1 addition & 1 deletion skills/reverse-engineer-anything/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: Reverse engineer native, managed, Electron/JavaScript, packaged, an
metadata:
version: "23"
tool_count: 116
catalog_digest: "2da444fd95a40c28a6c0332a5970edca6b984f0c2922e4c02eaf7458a6f3dd0e"
catalog_digest: "bab5657d9525ec4f798d0a9ef6001412d9c11f77fb0ddc925c7076fd10921dc9"
---

# REA
Expand Down
Loading
Loading