From f62b44971deee0e99df6fcf32758c8e5592400ed Mon Sep 17 00:00:00 2001 From: morluto <76467478+morluto@users.noreply.github.com> Date: Sat, 10 Oct 2026 03:15:54 +0800 Subject: [PATCH] fix(mcp): advertise primitive semantic literal seeds --- .../javascriptSemanticQuerySchemas.ts | 18 ++++-------- .../retainedApplicationEvidenceMcp.test.ts | 28 +++++++++++++++++++ 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/src/domain/javascript/javascriptSemanticQuerySchemas.ts b/src/domain/javascript/javascriptSemanticQuerySchemas.ts index d9c93446a..a88adc706 100644 --- a/src/domain/javascript/javascriptSemanticQuerySchemas.ts +++ b/src/domain/javascript/javascriptSemanticQuerySchemas.ts @@ -8,22 +8,16 @@ import { javaScriptSemanticEvidenceContextSchema, javaScriptSemanticUnknownSchema, } from "./javascriptSemanticGraphSchemas.js"; -import { jsonValueSchema } from "../jsonValue.js"; import { digestSchema } from "../digests.js"; import { prefixedDigestSchema } from "../digests.js"; const semanticNodeIdSchema = prefixedDigestSchema("jsrg_node"); -const literalValueSchema = jsonValueSchema.refine( - (value) => - value === null || - typeof value === "string" || - typeof value === "number" || - typeof value === "boolean", - "Literal seeds accept only JSON primitive values", -); -// Zod derivations drop the shared schema's JSON Schema projection override; -// re-apply it so MCP catalog generation keeps projecting `{}`. -literalValueSchema._zod.toJSONSchema = () => ({}); +const literalValueSchema = z.union([ + z.string(), + z.number(), + z.boolean(), + z.null(), +]); const literalSeedSchema = z.strictObject({ kind: z.literal("literal"), diff --git a/tests/boundary/mcp/retainedApplicationEvidenceMcp.test.ts b/tests/boundary/mcp/retainedApplicationEvidenceMcp.test.ts index ef90cd7e4..ebc7062a9 100644 --- a/tests/boundary/mcp/retainedApplicationEvidenceMcp.test.ts +++ b/tests/boundary/mcp/retainedApplicationEvidenceMcp.test.ts @@ -37,6 +37,34 @@ async function connect() { return { client, session }; } +it("advertises the primitive literal seeds accepted by semantic tracing", async () => { + const { client } = await connect(); + const { tools } = await client.listTools(); + const tool = tools.find(({ name }) => name === "trace_javascript_semantics"); + if (tool === undefined) throw new Error("Semantic trace tool is missing"); + const validate = new Ajv2020({ + strict: false, + validateFormats: false, + }).compile(tool.inputSchema); + for (const value of ["literal", 42, true, null, {}, []]) { + const primitive = value === null || typeof value !== "object"; + const arguments_ = { + application, + query: { + seed: { kind: "literal", value }, + direction: "backward-provenance", + }, + }; + expect(validate(arguments_), JSON.stringify(value)).toBe(primitive); + const result = await client.callTool({ + name: tool.name, + arguments: arguments_, + }); + if (primitive) expect(result.isError).not.toBe(true); + else expect(result.isError).toBe(true); + } +}); + it("runs the same trace/compare workflows with inline and retained application Evidence", async () => { const { client, session } = await connect(); expect(session.recordEvidence(pair.left).ok).toBe(true);