import { z } from "zod"; export const approvalPolicy = z.enum(["allow", "ask", "never"]); export type ApprovalPolicy = z.infer; export const capabilitySource = z.strictObject({ kind: z.enum(["mcp", "skill"]), id: z.string().min(1).max(200), }); export const capabilityReference = z.strictObject({ source: capabilitySource, id: z.string().regex(/^[a-f0-9]{64}$/), fingerprint: z.string().regex(/^[a-f0-9]{64}$/), }); export type CapabilityReference = z.infer; export interface CapabilityMetadata extends CapabilityReference { name: string; sourceName: string; actionSummary: string; enabled: boolean; approval?: ApprovalPolicy; } export const capabilityPolicyConfiguration = z.strictObject({ defaultPolicy: approvalPolicy, sourceOverrides: z .array(z.strictObject({ source: capabilitySource, policy: approvalPolicy })) .max(128) .refine( (items) => new Set(items.map((item) => capabilitySourceKey(item.source))).size === items.length, ), }); export type CapabilityPolicyConfiguration = z.infer< typeof capabilityPolicyConfiguration >; export interface CapabilityPolicySnapshot extends CapabilityPolicyConfiguration { revision: number; } export const capabilityPolicyUpdate = capabilityPolicyConfiguration.extend({ revision: z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER), }); export function capabilitySourceKey(source: CapabilityReference["source"]) { return JSON.stringify([source.kind, source.id]); } export function effectiveCapabilityPolicy( metadata: CapabilityMetadata, configuration: CapabilityPolicyConfiguration, ) { const override = configuration.sourceOverrides.find( (item) => capabilitySourceKey(item.source) === capabilitySourceKey(metadata.source), ); // A Never choice cannot be relaxed by a broader Allow. Source overrides let // an owner require Ask (or Never) across a server/Skill in one operation. if (metadata.approval === "never") return { policy: "never", source: "capability" } as const; if (override) return { policy: override.policy, source: "source" } as const; if (metadata.approval) return { policy: metadata.approval, source: "capability" } as const; return { policy: configuration.defaultPolicy, source: "default" } as const; }