From 44bac35c501c62d94c347e7e689852ae0bac00a9 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 22 Oct 2026 06:00:52 +0000 Subject: [PATCH] fix(erlang): use the shared public input constructor inspect_erlang_beam advertised a bare strict object. Public tool inputs now go through publicInputStrictObject so later shared input policy has one owner. Co-authored-by: morluto --- src/domain/erlang/beam.ts | 3 ++- src/domain/publicInput.test.ts | 16 ++++++++++++++++ src/domain/publicInput.ts | 9 +++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 src/domain/publicInput.test.ts create mode 100644 src/domain/publicInput.ts diff --git a/src/domain/erlang/beam.ts b/src/domain/erlang/beam.ts index 87170b6eaf..f5344e53dd 100644 --- a/src/domain/erlang/beam.ts +++ b/src/domain/erlang/beam.ts @@ -2,6 +2,7 @@ import { z } from "zod"; import { digestSchema } from "../digests.js"; import { absoluteLocalPathStringSchema } from "../localPath.js"; +import { publicInputStrictObject } from "../publicInput.js"; const uint = z.number().int().min(0).max(0xffffffff); const range = z.strictObject({ offset: uint, bytes: uint }); @@ -16,7 +17,7 @@ export const MAX_INSPECT_ERLANG_BEAM_ATOMS = 65536; export const MAX_INSPECT_ERLANG_BEAM_TABLE_ROWS = 65536; /** Complete bounded inspection of one Erlang BEAM IFF container. */ -export const inspectErlangBeamInputSchema = z.strictObject({ +export const inspectErlangBeamInputSchema = publicInputStrictObject({ path: absoluteLocalPathStringSchema.describe( "Absolute filesystem path to a BEAM file", ), diff --git a/src/domain/publicInput.test.ts b/src/domain/publicInput.test.ts new file mode 100644 index 0000000000..04b46983bd --- /dev/null +++ b/src/domain/publicInput.test.ts @@ -0,0 +1,16 @@ +import { expect, it } from "vitest"; +import { z } from "zod"; + +import { publicInputStrictObject } from "./publicInput.js"; + +it("rejects unknown keys on a public tool input", () => { + const schema = publicInputStrictObject({ + path: z.string(), + block_size: z.number().default(4096), + }); + expect(schema.parse({ path: "/file" })).toEqual({ + path: "/file", + block_size: 4096, + }); + expect(schema.safeParse({ path: "/file", extra: true }).success).toBe(false); +}); diff --git a/src/domain/publicInput.ts b/src/domain/publicInput.ts new file mode 100644 index 0000000000..09093bc6ae --- /dev/null +++ b/src/domain/publicInput.ts @@ -0,0 +1,9 @@ +import { z } from "zod"; + +/** + * Closed object schema for a public CLI or MCP tool input. + * + * Unknown keys fail here so public input policy has one owner. Result and + * internal objects stay on their own constructors. + */ +export const publicInputStrictObject = z.strictObject;