/*
profile schemas — Zod schemas for certification site quality dimensions.
- Do not score sites — 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 {
humanReadableIdSchema,
digestSchema,
utcTimestampSchema,
environmentSchema,
} from "../contracts/identifiers.ts";
export const siteQualityDimensionSchema = z.enum([
"candidate-integrity",
"business-truth-compliance",
"editorial-localization",
"information-architecture-discoverability",
"ux-conversion",
"visual-accessibility",
"performance-runtime",
"security-operational-readiness",
"independent-qualitative-evaluation",
]);
export type SiteQualityDimension = z.infer;
export const certificationGateSchema = z.enum(["dev-deploy", "propagate-alt", "promote-main"]);
export type CertificationGate = z.infer;
export const requirementClassSchema = z.enum(["required", "conditional", "advisory"]);
export type RequirementClass = z.infer;
export const remediationClassSchema = z.enum([
"product-fix",
"infrastructure-retry",
"policy-defect",
]);
export type RemediationClass = z.infer;
export const driftActionSchema = z.enum(["retry", "incident-only", "rollback"]);
export type DriftAction = z.infer;
export const ownerRoleSchema = z.enum(["author-agent", "platform-agent", "operator-agent"]);
export type OwnerRole = z.infer;
export const producerKindSchema = z.enum(["kernel-command", "evaluator-agent", "remote-workload"]);
export type ProducerKind = z.infer;
export const versionSourceSchema = z.enum(["package-version", "module-hash", "evaluator-profile"]);
export type VersionSource = z.infer;
export const criticalitySchema = z.enum(["ordinary", "critical"]);
export type Criticality = z.infer;
export const applicabilityRuleV1Schema = z.discriminatedUnion("kind", [
z
.object({
kind: z.literal("always"),
})
.strict(),
z
.object({
kind: z.literal("entitlement"),
ref: z.string().min(1).max(256),
expected: z.boolean(),
})
.strict(),
z
.object({
kind: z.literal("config"),
ref: z.string().min(1).max(256),
predicate: z.string().min(1).max(256),
})
.strict(),
z
.object({
kind: z.literal("surface"),
ref: z.string().min(1).max(256),
predicate: z.string().min(1).max(256),
})
.strict(),
]);
export type ApplicabilityRuleV1 = z.infer;
export const freshnessV1Schema = z
.object({
maxAgeSeconds: z.number().int().nonnegative().nullable(),
schedule: z.string().min(1).max(128).optional(),
})
.strict();
export type FreshnessV1 = z.infer;
export const executionV1Schema = z
.object({
timeoutMs: z.number().int().positive().max(600000),
maxAttempts: z.number().int().min(1).max(10),
backoffMs: z.array(z.number().int().nonnegative().max(60000)).max(10),
})
.strict();
export type ExecutionV1 = z.infer;
export const remediationV1Schema = z
.object({
classification: remediationClassSchema,
ownerRole: ownerRoleSchema,
reproduceCommand: z.string().min(1).max(256),
verificationCommand: z.string().min(1).max(256),
})
.strict();
export type RemediationV1 = z.infer;
export const reuseV1Schema = z
.object({
environmentIndependent: z.boolean(),
allowedFrom: z.array(environmentSchema).max(10),
})
.strict();
export type ReuseV1 = z.infer;
export const certificationRequirementV1Schema = z
.object({
id: humanReadableIdSchema,
title: z.string().min(1).max(256),
dimension: z.union([siteQualityDimensionSchema, z.literal("core")]),
gates: z
.array(z.union([certificationGateSchema, z.literal("continuous-health")]))
.min(1)
.max(5),
classification: requirementClassSchema,
applicability: applicabilityRuleV1Schema,
producerId: humanReadableIdSchema,
evidenceSchema: z.string().min(1).max(128),
environments: z.array(environmentSchema).min(1).max(5),
reuse: reuseV1Schema,
freshness: freshnessV1Schema,
execution: executionV1Schema,
criticality: criticalitySchema,
driftAction: driftActionSchema,
remediation: remediationV1Schema,
normativeRefs: z.array(z.string().min(1).max(256)).min(1).max(20),
})
.strict();
export type CertificationRequirementV1 = z.infer;
export const producerDeclarationV1Schema = z
.object({
id: humanReadableIdSchema,
kind: producerKindSchema,
command: z.string().min(1).max(256).optional(),
moduleId: z.string().min(1).max(256).optional(),
outputSchema: z.string().min(1).max(128),
versionSource: versionSourceSchema,
requiredPayloadRoles: z.array(z.string().min(1).max(128)).max(20),
})
.strict();
export type ProducerDeclarationV1 = z.infer;
export const evaluatorPolicyV1Schema = z
.object({
ordinaryEvaluators: z.number().int().min(1).max(10),
criticalEvaluators: z.number().int().min(1).max(10),
borderlineEvaluators: z.number().int().min(1).max(10),
confidenceMargin: z.number().min(0).max(100),
})
.strict();
export type EvaluatorPolicyV1 = z.infer;
export const retentionPolicyV1Schema = z
.object({
minRetentionDays: z.number().int().nonnegative().max(36500),
maxRetentionDays: z.number().int().nonnegative().max(36500),
tombstoneAfterDays: z.number().int().nonnegative().max(36500),
})
.strict()
.refine((v) => v.minRetentionDays <= v.maxRetentionDays, {
message: "CERT-PROFILE-01: minRetentionDays must not exceed maxRetentionDays",
});
export type RetentionPolicyV1 = z.infer;
export const certificationProfileV1Schema = z
.object({
schema: z.literal("werkstatt/certification-profile@1"),
id: humanReadableIdSchema,
version: z.string().min(1).max(64),
plugin: z
.object({
id: humanReadableIdSchema,
profileId: humanReadableIdSchema,
})
.strict(),
dimensions: z.array(siteQualityDimensionSchema).min(1).max(20),
producers: z.record(z.string().min(1).max(256), producerDeclarationV1Schema),
requirements: z.array(certificationRequirementV1Schema).min(1).max(1000),
evaluatorPolicy: evaluatorPolicyV1Schema.optional(),
retentionPolicy: retentionPolicyV1Schema,
})
.strict();
export type CertificationProfileV1 = z.infer;
export const profileSourceRefV1Schema = z
.object({
sourcePath: z.string().min(1).max(1024),
sourceFileHash: digestSchema,
canonicalHash: digestSchema,
parsedAt: utcTimestampSchema,
})
.strict();
export type ProfileSourceRefV1 = z.infer;