/* Page output projection schema for the system manifest: controls per-page output settings like sitemap inclusion and canonical URLs. Do not introduce app-specific runtime composition or deployment behavior into this reusable package source file. RFC-0303 Phase 3: extracted from schemas/system.ts as part of the domain split. RFC-1106: step 4 — single-source SemanticPageType semanticPageTypeSchema (ontology/schemas/system/page-output.ts) is now the sole declaration of the closed DNA-19 vocabulary. semantic/models.ts derives the type via z.infer and SEMANTIC_PAGE_TYPES via schema.options — the hand-synced union/array and stale circular-dependency comments are deleted. */ import { z } from "zod"; /** * RFC-0042/RFC-0050: the semantic role of a page. Drives semantic model * construction and the default llms inclusion depth. Mirrors * SemanticPageType in @warpgogol/werkstatt-shared/semantic. */ // RFC-1106: this schema is the sole declaration of the SemanticPageType closed // vocabulary (DNA-19). `semantic/models.ts` derives the type and the runtime // array from it — do not declare a parallel union elsewhere. export const semanticPageTypeSchema = z.enum([ "home", "about", "projects", "donationContact", "openSource", "content", "article", "person", "participant", "legal", "collection", ]); /** RFC-0167: per-page article metadata (Article/BlogPosting JSON-LD + dates + author). */ export const articleMetadataSchema = z .object({ publishedAt: z.string().min(1), updatedAt: z.string().min(1).optional(), author: z.string().min(1).optional(), tags: z.array(z.string().min(1)).optional(), }) .strict(); /** RFC-0142: per-page llms inclusion depth value (string shorthand or object). */ const llmsDepthSchema = z.enum(["full", "summary", "index-only", "exclude"]); export const llmsPolicySchema = z.union([ llmsDepthSchema, z .object({ depth: llmsDepthSchema.optional(), sections: z.object({ exclude: z.array(z.string()).optional() }).optional(), }) .strict(), ]); /** RFC-0143: per-page sitemap projection value (boolean shorthand or object). */ export const sitemapProjectionSchema = z.union([ z.boolean(), z .object({ include: z.boolean().optional(), category: z.string().min(1).optional(), lastmod: z.string().min(1).optional(), includeLastmod: z.boolean().optional(), }) .strict(), ]); /** * RFC-0143: the per-page `output` block — a CLOSED container of per-page * projection generators. Each known generator owns exactly one key; unknown * keys are a validation error. A new per-page generator extends this schema * in the same change that adds the generator. */ /** RFC-0165: per-page robots/indexability (boolean shorthand or object). */ export const robotsProjectionSchema = z.union([ z.boolean(), z .object({ index: z.boolean().optional(), follow: z.boolean().optional(), }) .strict(), ]); export const pageOutputSchema = z .object({ sitemap: sitemapProjectionSchema.optional(), llms: llmsPolicySchema.optional(), robots: robotsProjectionSchema.optional(), /** RFC-0257: enable SSG PDF generation for this app. Default false. */ printPdf: z.boolean().optional(), }) .strict();