/* isolation schemas — Zod schemas for isolation property evidence validation. Do not isolate — 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 { Sha256Digest } from "@warpgogol/werkstatt-shared/fingerprint"; const sha256Regex = /^sha256:[0-9a-f]{64}$/; const sha256Schema = z.string().regex(sha256Regex) as unknown as z.ZodType; const isolationPropertyKindSchema = z.enum([ "containment", "clean-room-startup", "artifact-immutability", "grant-enforcement", "egress-controls", "resource-limits", "secret-non-inheritance", "teardown", "crash-recovery", "concurrent-workload-separation", "bridge-confusion-replay", "host-compromise-assumptions", ]); export const isolationPropertyEvidenceV1Schema = z .object({ schema: z.literal("werkstatt/isolation-property-evidence@1"), properties: z .array( z .object({ kind: isolationPropertyKindSchema, proven: z.boolean(), evidenceHash: sha256Schema, description: z.string().min(1).max(4096), }) .strict(), ) .max(64), unsupported: z.array(isolationPropertyKindSchema).max(32), }) .strict(); const grantScopeSchema = z.enum(["read", "append", "deploy", "certify", "administer"]); export const attenuatedGrantV1Schema = z .object({ scope: grantScopeSchema, resource: z.string().min(1).max(1024), maxDuration: z.number().int().nonnegative(), maxOperations: z.number().int().nonnegative(), }) .strict(); export const attenuatedGrantSetV1Schema = z .object({ schema: z.literal("werkstatt/attenuated-grant-set@1"), grants: z.array(attenuatedGrantV1Schema).max(256), grantSetHash: sha256Schema, }) .strict(); export const workloadLimitsV1Schema = z .object({ maxMemoryBytes: z.number().int().positive(), maxCpuTimeMs: z.number().int().positive(), maxWallTimeMs: z.number().int().positive(), maxConcurrency: z.number().int().positive(), maxResponseBytes: z.number().int().positive(), maxRequestBytes: z.number().int().positive(), }) .strict(); const capabilityIdSchema = z.string().regex(/^[a-z0-9-]+\/[a-z0-9-]+$/); export const capabilityBridgeRequestV1Schema = z .object({ schema: z.literal("werkstatt/capability-bridge-request@1"), requestId: z.string().min(1).max(128), capability: capabilityIdSchema, grant: attenuatedGrantV1Schema, payload: z.instanceof(Uint8Array), deadline: z.number().int().positive(), }) .strict(); export const capabilityBridgeResponseV1Schema = z .object({ schema: z.literal("werkstatt/capability-bridge-response@1"), requestId: z.string().min(1).max(128), status: z.enum(["ok", "denied", "error", "timeout"]), payload: z.instanceof(Uint8Array), diagnostics: z.array(z.string().max(4096)).max(128), }) .strict(); export const terminationReportV1Schema = z .object({ schema: z.literal("werkstatt/termination-report@1"), workloadId: z.string().min(1).max(128), reason: z.string().min(1).max(4096), terminated: z.boolean(), quarantined: z.boolean(), diagnostics: z.array(z.string().max(4096)).max(128), }) .strict(); export const sandboxedWorkloadCreateV1Schema = z .object({ workloadId: z.string().min(1).max(128), artifactHash: sha256Schema, grantSet: attenuatedGrantSetV1Schema, limits: workloadLimitsV1Schema, bridgeSchemaHash: sha256Schema, idempotencyKey: z.string().min(1).max(128), }) .strict(); const adversarialCaseKindSchema = z.enum([ "filesystem-escape", "network-escape", "process-escape", "environment-escape", "credential-escape", "descriptor-escape", "resource-exhaustion", "workload-separation", "teardown", "crash", "bridge-confusion", "bridge-replay", "vm-theatre", "worker-threads-theatre", "subprocess-theatre", ]); export const adversarialCaseResultV1Schema = z .object({ caseKind: adversarialCaseKindSchema, passed: z.boolean(), violations: z.array(z.string().max(4096)).max(128), detail: z.string().max(4096), }) .strict(); export const isolationConformanceResultV1Schema = z .object({ schema: z.literal("werkstatt/isolation-conformance-result@1"), adapterId: z.string().min(1).max(128), propertyEvidenceHash: sha256Schema, grantSetHash: sha256Schema, fixtureHash: sha256Schema, cases: z.array(adversarialCaseResultV1Schema).max(64), violations: z.array(z.string().max(4096)).max(256), status: z.enum(["pass", "fail", "incomplete"]), testOnly: z.literal(true), }) .strict(); export const isolationAdapterV1Schema = z .object({ schema: z.literal("werkstatt/isolation-adapter@1"), adapterId: z.string().min(1).max(128), properties: isolationPropertyEvidenceV1Schema, }) .strict(); export type IsolationContractViolation = { readonly rule: string; readonly path: string; readonly message: string; }; export function validateIsolationAdapter(adapter: unknown): { status: "pass" | "fail"; violations: IsolationContractViolation[]; } { if (typeof adapter === "object" && adapter !== null && "create" in adapter) { const { create: _create, ...dataFields } = adapter as Record; const result = isolationAdapterV1Schema.safeParse(dataFields); if (result.success) { return { status: "pass", violations: [] }; } const violations: IsolationContractViolation[] = result.error.issues.map((issue) => ({ rule: `ISOLATION-${issue.code}`, path: issue.path.join("."), message: issue.message, })); return { status: "fail", violations }; } const result = isolationAdapterV1Schema.safeParse(adapter); if (result.success) { return { status: "pass", violations: [] }; } const violations: IsolationContractViolation[] = result.error.issues.map((issue) => ({ rule: `ISOLATION-${issue.code}`, path: issue.path.join("."), message: issue.message, })); return { status: "fail", violations }; } export function validateBridgeRequest(request: unknown): { status: "pass" | "fail"; violations: IsolationContractViolation[]; } { const result = capabilityBridgeRequestV1Schema.safeParse(request); if (result.success) { return { status: "pass", violations: [] }; } const violations: IsolationContractViolation[] = result.error.issues.map((issue) => ({ rule: `ISOLATION-BRIDGE-${issue.code}`, path: issue.path.join("."), message: issue.message, })); return { status: "fail", violations }; }