From 501c5d45fe60cae4a6337f38fc417f86d13e1ae8 Mon Sep 17 00:00:00 2001 From: ShitK <80999801+ShitK@users.noreply.github.com> Date: Wed, 14 Oct 2026 00:33:14 +0800 Subject: [PATCH] fix(managed): share native verification input diagnostics (#2901) --- .../managed/managedWorkflowToolContracts.ts | 32 +------ src/contracts/workflowInputContracts.test.ts | 92 ++++++++++++++++--- .../managedNativeVerificationSchemas.ts | 5 +- 3 files changed, 86 insertions(+), 43 deletions(-) diff --git a/src/contracts/managed/managedWorkflowToolContracts.ts b/src/contracts/managed/managedWorkflowToolContracts.ts index 3842c3814..519c2e125 100644 --- a/src/contracts/managed/managedWorkflowToolContracts.ts +++ b/src/contracts/managed/managedWorkflowToolContracts.ts @@ -1,5 +1,6 @@ import { z } from "zod"; import { evidenceSchema } from "../../domain/evidence.js"; +import { managedNativeVerificationInputSchema } from "../../domain/managed/managedNativeVerificationSchemas.js"; import { managedReconstructionImportInputSchema } from "../../domain/managed/managedReconstruction.js"; import type { ToolContract } from "../toolContractTypes.js"; @@ -34,35 +35,6 @@ export const managedReconstructionReferenceInputSchema = static_members: evidenceSchema, }); -/** Inline Evidence inputs for managed/native verification. */ -export const managedNativeVerificationReferenceInputSchema = z - .strictObject({ - managed_boundaries: evidenceSchema, - native_observations: z - .array(evidenceSchema) - .min(1) - .describe("Native function or export Evidence records"), - }) - .superRefine((input, context) => { - const ids = new Set([input.managed_boundaries.evidence_id]); - for (const [index, evidence] of input.native_observations.entries()) { - if (evidence.evidence_id === input.managed_boundaries.evidence_id) - context.addIssue({ - code: "custom", - path: ["native_observations", index], - message: - "Native observation Evidence must be distinct from managed boundary Evidence", - }); - if (ids.has(evidence.evidence_id)) - context.addIssue({ - code: "custom", - path: ["native_observations", index], - message: "Native observation Evidence IDs must be unique", - }); - ids.add(evidence.evidence_id); - } - }); - const managedApplicationGraphReferenceFacts = {} as const; const managedApplicationGraphReferenceShape = z.strictObject({ @@ -146,7 +118,7 @@ export const MANAGED_WORKFLOW_TOOL_CONTRACTS = [ description: "Verify managed P/Invoke/native-boundary declarations against authenticated native export or function Evidence without executing managed code or translating managed metadata tokens into native addresses. The workflow preserves declaration-only, verified, inferred, contradicted, and unresolved states.", kind: "application", - inputSchema: managedNativeVerificationReferenceInputSchema, + inputSchema: managedNativeVerificationInputSchema, outputSchema: nativeVerificationOutputSchema, examples: [ { diff --git a/src/contracts/workflowInputContracts.test.ts b/src/contracts/workflowInputContracts.test.ts index 32e1ddf02..237469487 100644 --- a/src/contracts/workflowInputContracts.test.ts +++ b/src/contracts/workflowInputContracts.test.ts @@ -1,5 +1,9 @@ import { describe, expect, it } from "vitest"; +import { managedNativeVerificationInputSchema } from "../domain/managed/managedNativeVerificationSchemas.js"; +import { toolContract } from "./toolContracts.js"; +import { toolInputSchemaWithMetadata } from "./toolSchemaMetadata.js"; + import { traceJavaScriptSemanticsRequestSchema } from "./javascript/applicationWorkflowInputContracts.js"; import { JAVASCRIPT_FEATURE_TRACE_EXAMPLE } from "./javascript/javascriptApplicationWorkflowExamples.js"; import { @@ -10,7 +14,6 @@ import { import { compareManagedMembersReferenceInputSchema, managedApplicationGraphReferenceInputSchema, - managedNativeVerificationReferenceInputSchema, } from "./managed/managedWorkflowToolContracts.js"; describe("workflow input contracts", () => { @@ -41,17 +44,6 @@ describe("workflow input contracts", () => { }).success, ).toBe(false); - expect( - managedNativeVerificationReferenceInputSchema.safeParse({ - managed_boundaries: - MANAGED_NATIVE_VERIFICATION_EXAMPLE.managed_boundaries, - native_observations: [ - MANAGED_NATIVE_VERIFICATION_EXAMPLE.native_observations[0], - MANAGED_NATIVE_VERIFICATION_EXAMPLE.native_observations[0], - ], - }).success, - ).toBe(false); - expect( managedApplicationGraphReferenceInputSchema.safeParse({ managed_artifact: MANAGED_APPLICATION_GRAPH_EXAMPLE.managed_members, @@ -62,4 +54,80 @@ describe("workflow input contracts", () => { managedApplicationGraphReferenceInputSchema.safeParse({}).success, ).toBe(false); }); + + it.each([ + { + name: "one observation reusing the boundary", + observations: [MANAGED_NATIVE_VERIFICATION_EXAMPLE.managed_boundaries], + issues: [ + { + path: ["native_observations", 0], + message: + "Native observation Evidence must be distinct from managed boundary Evidence", + }, + ], + }, + { + name: "repeated native observations", + observations: [ + MANAGED_NATIVE_VERIFICATION_EXAMPLE.native_observations[0], + MANAGED_NATIVE_VERIFICATION_EXAMPLE.native_observations[0], + ], + issues: [ + { + path: ["native_observations", 1], + message: "Native observation Evidence IDs must be unique", + }, + ], + }, + { + name: "repeated observations reusing the boundary", + observations: [ + MANAGED_NATIVE_VERIFICATION_EXAMPLE.managed_boundaries, + MANAGED_NATIVE_VERIFICATION_EXAMPLE.managed_boundaries, + ], + issues: [ + { + path: ["native_observations", 0], + message: + "Native observation Evidence must be distinct from managed boundary Evidence", + }, + { + path: ["native_observations", 1], + message: + "Native observation Evidence must be distinct from managed boundary Evidence", + }, + { + path: ["native_observations", 1], + message: "Native observation Evidence IDs must be unique", + }, + ], + }, + { + name: "distinct native observations", + observations: MANAGED_NATIVE_VERIFICATION_EXAMPLE.native_observations, + issues: [], + }, + ])( + "preserves managed/native diagnostics for $name", + async ({ observations, issues }) => { + const input = { + managed_boundaries: + MANAGED_NATIVE_VERIFICATION_EXAMPLE.managed_boundaries, + native_observations: observations, + }; + const contract = toolContract("verify_managed_native_boundaries"); + for (const schema of [ + managedNativeVerificationInputSchema, + contract.inputSchema, + toolInputSchemaWithMetadata(contract), + ]) { + const result = await schema["~standard"].validate(input); + expect( + result.issues?.map(({ path, message }) => ({ path, message })) ?? [], + ).toEqual(issues); + if (issues.length === 0) expect(result).toEqual({ value: input }); + } + }, + ); }); diff --git a/src/domain/managed/managedNativeVerificationSchemas.ts b/src/domain/managed/managedNativeVerificationSchemas.ts index 8e543bdab..16afe4048 100644 --- a/src/domain/managed/managedNativeVerificationSchemas.ts +++ b/src/domain/managed/managedNativeVerificationSchemas.ts @@ -92,7 +92,10 @@ export type PinvokeVerification = z.infer; export const managedNativeVerificationInputSchema = z .strictObject({ managed_boundaries: evidenceSchema, - native_observations: z.array(evidenceSchema).min(1), + native_observations: z + .array(evidenceSchema) + .min(1) + .describe("Native function or export Evidence records"), }) .superRefine((input, context) => { const ids = new Set();