/* component schemas — Zod schemas for component declaration validation and parsing. Do not register components — this module defines the schema only. RFC-1097: sweep — werkstatt-engine clean Sweep batch 4: 73 Compass headers on headerless engine files (certification, component-runtime, isolation, evolution, testing), real KEY_DECISIONS on 75 files (kernel, cache, dht, swim, gitmesh, runtime), ~80 purpose expansions (CONTRACT-02/PURPOSE-02), non-goals on 13 CONTRACT-03 files, CS-07 history literal fix repo-wide (253 files). Policy: .template.ts/.template.astro excludedPaths. werkstatt-engine now 0 diagnostics. */ import { z } from "zod"; import type { ComponentContractResult, ComponentContractViolation, ComponentDeclaration, ResolvedComponentSetV1, } from "@warpgogol/werkstatt-shared/component"; const COMPONENT_ID_RE = /^[a-z][a-z0-9-]*\/[a-z][a-z0-9-]*$/; const CAPABILITY_ID_RE = /^[a-z][a-z0-9-]*\/[a-z][a-z0-9-]*$/; const SEMVER_RE = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/; const SHA256_RE = /^sha256:[0-9a-f]{64}$/; const COMPAT_RE = /^(?:\^|~|>=?|<=?|=)?\s*(?:0|[1-9]\d*)\.(?:0|[1-9]\d*|x)\.(?:0|[1-9]\d*|x)(?:\.\d+)?$/; const MAX_PROVIDES = 64; const MAX_REQUIRES = 128; const MAX_GRANTS = 32; const MAX_EFFECTS = 64; const MAX_RESOURCES = 64; const MAX_COMPONENTS = 256; const MAX_STRING_BYTES = 4096; const MAX_DESC_BYTES = 2048; const MAX_PROFILE_ID_LEN = 128; const componentIdSchema = z .string() .min(1) .max(128) .regex( COMPONENT_ID_RE, "invalid componentId: must be namespace/name, lowercase alphanumeric and hyphens", ); const capabilityIdSchema = z .string() .min(1) .max(128) .regex( CAPABILITY_ID_RE, "invalid capability: must be namespace/name, lowercase alphanumeric and hyphens", ); const semverSchema = z.string().min(1).max(64).regex(SEMVER_RE, "invalid semver version"); const sha256Schema = z.string().min(1).max(80).regex(SHA256_RE, "invalid sha256 digest"); const compatSchema = z.string().min(1).max(64).regex(COMPAT_RE, "invalid compatibility range"); const boundedString = (max: number) => z.string().min(1).max(max); const effectClassSchema = z.enum([ "revertible", "transactional", "compensatable", "irreversible-emission", ]); const isolationTierSchema = z.union([z.literal(0), z.literal(1), z.literal(2), z.literal(3)]); const grantScopeSchema = z.enum(["read", "append", "deploy", "certify", "administer"]); const resourceKindSchema = z.enum(["cpu", "memory", "disk", "network", "timer", "subprocess"]); const lifecycleScopeSchema = z.enum(["process", "request", "session", "scheduled"]); const componentScopeSchema = z.enum([ "per-command", "per-mission", "per-session", "per-workshop", "per-fleet", ]); const capabilityProvideSchema = z .object({ capability: capabilityIdSchema, version: semverSchema, schemaHash: sha256Schema, }) .strict(); const capabilityRequireSchema = z .object({ capability: capabilityIdSchema, compatibility: compatSchema, schemaHash: sha256Schema.nullable(), optional: z.boolean(), }) .strict(); const grantRequestSchema = z .object({ scope: grantScopeSchema, resource: boundedString(MAX_STRING_BYTES), attenuated: z.boolean(), }) .strict(); const effectDeclarationSchema = z .object({ effectClass: effectClassSchema, description: boundedString(MAX_DESC_BYTES), recoveryCommand: z.string().max(MAX_STRING_BYTES).nullable(), commitMetadata: z.string().max(MAX_STRING_BYTES).nullable(), }) .strict(); const isolationRequirementSchema = z .object({ tier: isolationTierSchema, adapterId: z.string().max(128).nullable(), }) .strict(); const resourceBoundSchema = z .object({ kind: resourceKindSchema, limit: boundedString(MAX_STRING_BYTES), owner: componentIdSchema, lifecycle: lifecycleScopeSchema, }) .strict(); export const componentDeclarationSchema = z .object({ schema: z.literal("werkstatt/component-declaration@1"), componentId: componentIdSchema, version: semverSchema, artifactHash: sha256Schema, scope: componentScopeSchema, provides: z.array(capabilityProvideSchema).min(1).max(MAX_PROVIDES), requires: z.array(capabilityRequireSchema).max(MAX_REQUIRES), requestedGrants: z.array(grantRequestSchema).max(MAX_GRANTS), effects: z.array(effectDeclarationSchema).max(MAX_EFFECTS), isolation: isolationRequirementSchema, resources: z.array(resourceBoundSchema).max(MAX_RESOURCES), config: z.record(z.string(), z.unknown()).optional(), priority: z.number().int().min(0).max(1000), active: z.boolean(), }) .strict(); const resolvedComponentIdentitySchema = z .object({ componentId: componentIdSchema, version: semverSchema, artifactHash: sha256Schema, }) .strict(); export const resolvedComponentSetV1Schema = z .object({ schema: z.literal("werkstatt/resolved-component-set@1"), profileId: boundedString(MAX_PROFILE_ID_LEN), components: z.array(resolvedComponentIdentitySchema).min(1).max(MAX_COMPONENTS), dependencyGraphHash: sha256Schema, grantSetHash: sha256Schema, effectPolicyHash: sha256Schema, isolationPolicyHash: sha256Schema, setHash: sha256Schema, }) .strict(); const LAW_KERNEL_GRANT_SCOPES = new Set(["certify", "administer"]); function checkDuplicateProvides( manifest: z.infer, violations: ComponentContractViolation[], ): void { const seen = new Set(); for (let i = 0; i < manifest.provides.length; i++) { const p = manifest.provides[i]!; const key = `${p.capability}@${p.version}`; if (seen.has(key)) { violations.push({ rule: "COMPONENT-CONTRACT-03", path: `provides[${i}].capability`, message: "duplicate capability provide identity", }); } seen.add(key); } } function checkLawKernelAuthorityReservation( manifest: z.infer, violations: ComponentContractViolation[], ): void { for (let i = 0; i < manifest.requestedGrants.length; i++) { const g = manifest.requestedGrants[i]!; if (LAW_KERNEL_GRANT_SCOPES.has(g.scope)) { violations.push({ rule: "COMPONENT-CONTRACT-06", path: `requestedGrants[${i}].scope`, message: `manifest cannot request Law Kernel reserved scope: ${g.scope}`, }); } } } function checkResourceOwners( manifest: z.infer, violations: ComponentContractViolation[], ): void { for (let i = 0; i < manifest.resources.length; i++) { const r = manifest.resources[i]!; if (r.owner !== manifest.componentId) { violations.push({ rule: "COMPONENT-CONTRACT-05", path: `resources[${i}].owner`, message: `resource owner must be the manifest componentId, got ${r.owner}`, }); } } } export function parseComponentDeclaration( input: unknown, ): ComponentContractResult { const violations: ComponentContractViolation[] = []; const parsed = componentDeclarationSchema.safeParse(input); if (!parsed.success) { for (const issue of parsed.error.issues) { violations.push({ rule: "COMPONENT-CONTRACT-01", path: issue.path.join(".") || "(root)", message: issue.message, }); } return { status: "fail", data: null, violations }; } const manifest = parsed.data; checkDuplicateProvides(manifest, violations); checkLawKernelAuthorityReservation(manifest, violations); checkResourceOwners(manifest, violations); if (violations.length > 0) { return { status: "fail", data: null, violations }; } return { status: "pass", data: manifest as ComponentDeclaration, violations: [] }; } export function parseResolvedComponentSetV1( input: unknown, ): ComponentContractResult { const violations: ComponentContractViolation[] = []; const parsed = resolvedComponentSetV1Schema.safeParse(input); if (!parsed.success) { for (const issue of parsed.error.issues) { violations.push({ rule: "COMPONENT-CONTRACT-01", path: issue.path.join(".") || "(root)", message: issue.message, }); } return { status: "fail", data: null, violations }; } const set = parsed.data; const seenComponents = new Set(); for (let i = 0; i < set.components.length; i++) { const c = set.components[i]!; const key = `${c.componentId}@${c.version}`; if (seenComponents.has(key)) { violations.push({ rule: "COMPONENT-CONTRACT-04", path: `components[${i}].componentId`, message: "duplicate resolved component identity", }); } seenComponents.add(key); } if (violations.length > 0) { return { status: "fail", data: null, violations }; } return { status: "pass", data: set as ResolvedComponentSetV1, violations: [] }; }