/* RFC-0358/RFC-0379/RFC-0666: Zod schemas for deployment config, channel model, and propagation results. secretsFile field kept as z.string().optional() for detection (sternsystem.validate rejects any value); secretRefSchema removed as dead code. Do not introduce app-specific runtime composition or deployment behavior into this reusable package source file. RFC-0926: add optional workerVersionId to propagationResultSchema and lastPropagatedChannelSchema for release-aware rollback. RFC-1091: add github-pages to deploymentAdapterNameSchema enum. RFC-1097: step 6 — compass.migrate codemod run Mechanical v1 to v2 header migration across the workspace: 942 files rewritten — CHANGE_SUMMARY windows collapsed into history, forbidden v1 blocks stripped, KEY_DECISIONS seeded from @ai-invariant comments (5 files) or TODO placeholders (103 files), blocks reordered to canonical order. 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. RFC-1297: lastPropagatedChannelSchema gains states rolled-back + reconciled; healthy becomes nullable (unknown until re-verified). RFC-0358, RFC-0379, RFC-0595, RFC-0624, RFC-0627, RFC-0666, RFC-0790 */ import { z } from "zod"; export const deploymentAdapterNameSchema = z.enum([ "cloudflare-workers", "github-pages", "netlify", "null", ]); export const deploymentChannelSchema = z.object({ workerName: z.string(), url: z.string().url(), // RFC-0666: secretsFile kept as z.string().optional() for detection — sternsystem.validate rejects any value. // secretRefSchema removed (dead code — env vars were never set). secretsFile: z.string().optional(), }); export const purgeResultSchema = z.object({ success: z.boolean(), purgedUrls: z.number(), error: z.string().optional(), }); export const lastPropagatedChannelSchema = z.object({ releaseId: z.string(), at: z.string().datetime(), // RFC-1297: nullable — rollback/reconcile record the release but not its // health; health is re-established by the next leitstand.verify run. healthy: z.boolean().nullable(), state: z.enum([ "succeeded", "failed", "failed-stale", "in-progress", "rolled-back", "reconciled", ]), operationId: z.string(), leaseExpiresAt: z.string().datetime().nullable(), purgeResult: purgeResultSchema.optional(), workerVersionId: z.string().optional(), }); export const healthCheckSchema = z.object({ name: z.string(), url: z.string(), status: z.number().int(), passed: z.boolean(), detail: z.string(), expectedHash: z.string().optional(), actualHash: z.string().optional(), }); export const propagationResultSchema = z.object({ systemId: z.string(), releaseId: z.string(), state: z.enum(["succeeded", "failed", "failed-stale", "in-progress"]), deploymentUrl: z.string(), workerVersionId: z.string().optional(), startedAt: z.string().datetime(), completedAt: z.string().datetime().nullable(), healthChecks: z.array(healthCheckSchema), }); export const routeFactSchema = z.object({ path: z.string(), contentHash: z.string().nullable(), redirectTarget: z.string().optional(), }); export type DeploymentAdapterName = z.infer; export type DeploymentChannel = z.infer; export type LastPropagatedChannel = z.infer; export type PurgeResult = z.infer; export const deploymentStaticConfigSchema = z.object({ adapter: deploymentAdapterNameSchema, channels: z.object({ dev: deploymentChannelSchema, alt: deploymentChannelSchema, main: deploymentChannelSchema, }), }); export type DeploymentStaticConfig = z.infer; export type HealthCheck = z.infer; export type PropagationResult = z.infer; export type RouteFact = z.infer;