/** * Protocol-level schema-compatibility invariants for `DataContract`. * * Ships one stable error code: * * - `CTR_SCHEMA_INCOMPAT` — an `actionSpec[*].schema` is not a * subset of the referenced `agentCapabilities.tools[*].inputSchema`, * OR a `streamSpec[*].schema` is not a superset of the * referenced `agentCapabilities.tools[*].outputSchema`. Direction is * fixed by the data flow: action payloads travel UI → tool, so * the action's accepted values must fit the tool's accepted * inputs; stream payloads travel tool → channel, so the * channel's accepted values must cover the tool's possible * outputs. * * **Scope vs server-level F4.** This invariant runs PURELY against * the contract's own catalog — `actionSpec[*].schema` / * `streamSpec[*].schema` vs `agentCapabilities.tools[*].inputSchema` / * `outputSchema`, all of which are author-declared JSON Schemas * already on the contract. No tool registry, no zod conversion, no * server state. The server-level F4 check (`checkRenderSchemaCompat` * in `@ggui-ai/mcp-server`) compares the same `actionSpec` / * `streamSpec` schemas against the SERVER-REGISTERED tools' actual * zod schemas; it covers the operator-side "did the deployed tool * change schema since the contract was authored?" failure mode. Both * checks compose: * * - Protocol-level CTR_SCHEMA_INCOMPAT: author-visible bug. * "Your contract's action.schema doesn't fit the inputSchema * you yourself declared on this tool entry." * - Server-level SchemaCompatError: operator-visible bug. "The * deployed tool's actual inputSchema doesn't match what the * contract declares." * * Skipped silently when the referenced agentTool has no declared * `inputSchema`/`outputSchema` (the catalog entry is incomplete; the * check has no anchor and degrades to "no opinion"). Skipped when * the action/channel has no `schema` (void-payload entries — nothing * to compare). * * Companion to `cross-references` and `name-invariants` — together * they ship companion rule registries to cross-references and * name-invariants under the unified `lintContract` API. */ import type { AgentCapabilitiesSpec, DataContract } from '../types/data-contract.js'; import type { ContractViolation } from './contract-validator.js'; /** * Stable error code for protocol-level schema-compatibility * violations on action ⊆ inputSchema or channel ⊇ outputSchema. */ export declare const CTR_SCHEMA_INCOMPAT = "CTR_SCHEMA_INCOMPAT"; /** * Discriminator on the side of the contract the violation came * from. Surfaced on the violation so consumers can render the * action vs. stream cases differently without parsing the field * path. */ export type SchemaCompatSide = 'action' | 'stream'; /** * Schema-compat invariant violation. Carries the stable error code * plus side / specName / toolName so consumers can pivot rendering * on the action vs stream case without parsing the field path. * * The granular `isSchemaSubset` violation list is NOT carried on the * violation (the rich `SubsetViolation` shape doesn't fit the * `ContractViolation extends JsonObject` constraint). The message * includes the first mismatch's reason + path; callers needing the * full list can re-run {@link checkSchemaCompat} subcomponents * directly. */ export interface SchemaCompatViolation extends ContractViolation { code: typeof CTR_SCHEMA_INCOMPAT; /** Which side of the contract was checked. */ side: SchemaCompatSide; /** The action / channel name on the contract. */ specName: string; /** The agentCapabilities.tools key resolved to perform the check. */ toolName: string; } /** * Validate every `actionSpec[*].schema` is a subset of the * referenced `agentCapabilities.tools[nextStep].inputSchema`. * * Skips entries where: * - no `nextStep` is declared (pure event signal — the agent owns * dispatch; nothing to compare), * - the referenced agentTool has no declared `inputSchema` (the * catalog entry is incomplete; the check has no anchor), * - the referenced agentTool is missing entirely (a separate * invariant `CTR_REF_NEXT_STEP` covers that). * * When the action has no `schema`, the wire shape is modeled as * `{type: 'object', properties: {}, additionalProperties: false}` — * "void payload." This matches the F4 convention so the protocol- * level check stays compatible with the server-level posture. */ export declare function checkActionSchemaCompat(actionSpec: DataContract['actionSpec'] | undefined, agentCapabilities: AgentCapabilitiesSpec | undefined): SchemaCompatViolation[]; /** * Validate every `streamSpec[*].schema` is a SUPERSET of the * referenced `agentCapabilities.tools[source.tool].outputSchema`. Direction * inverts: streams travel tool → channel, so the channel schema * must accept everything the tool can return. * * Skips entries where: * - no `source` is declared, * - the referenced agentTool has no declared `outputSchema`, * - the referenced agentTool is missing entirely * (`CTR_REF_STREAM_SOURCE` covers that), * - the channel has no `schema` (declarative validation is * impossible without the channel's accepted shape). */ export declare function checkStreamSchemaCompat(streamSpec: DataContract['streamSpec'] | undefined, agentCapabilities: AgentCapabilitiesSpec | undefined): SchemaCompatViolation[]; /** * Run every protocol-level schema-compat invariant. Aggregates action * + stream violations; order is stable (action checks first). */ export declare function checkSchemaCompat(contract: DataContract): SchemaCompatViolation[]; /** * Throwable form of {@link checkSchemaCompat}. Use at protocol * boundaries where a schema-compat violation is a contract bug the * author must fix. */ export declare class SchemaCompatInvariantError extends Error { readonly code: "schema_compat_incompat"; readonly violations: readonly SchemaCompatViolation[]; constructor(violations: readonly SchemaCompatViolation[]); } /** * Throw-on-violation wrapper around {@link checkSchemaCompat}. * No-op when the contract's schemas align with its own * agentCapabilities catalog. * * Slots alongside `assertCrossReferences` + `assertNameInvariants` * at render time. Different scope from the server-level * `SchemaCompatError` thrown by `checkRenderSchemaCompat` in * `@ggui-ai/mcp-server`: this check uses ONLY the contract's own * catalog; the server-level check uses the runtime tool registry. */ export declare function assertSchemaCompat(contract: DataContract): void; //# sourceMappingURL=schema-compat-invariants.d.ts.map