/*
Site shell contract schema (RFC-1229) for the system manifest.
Declares named shell profiles (required regions + script policy) and the
route→profile binding consumed by site.shell.contract.validate on emitted
dist/client markup.
- Do not validate emitted markup — site.shell.contract.validate owns the postbuild gate.
- Do not declare component region signatures — those live next to shell components in werkstatt-site.
- RFC-1229: initial shell-contract schema — profiles, routeProfiles, closed-set regions, document-level script policy.
- RFC-1229: step 1 — shellContract schema in systemManifestSchema
Add packages/werkstatt-shared/src/ontology/schemas/system/shell-contract.ts:
closed-set region names, profile shape (regions + document-level script
policy + breadcrumbsScope), routeProfiles closed-set reference check via
superRefine, mode default report. Wire shellContract into
systemManifestSchema and profile into pages[].shell.
- RFC-1229 remediation: docstring example updated — no-script declares breadcrumbs and the bare/404 binding example is dropped (404 binds the default profile after the 404 remediation).
*/
import { z } from "zod";
/**
* The `shellContract:` block in src/content/system.md (RFC-1229).
*
* Example:
* shellContract:
* mode: strict
* profiles:
* default:
* regions: [header, footer, background, breadcrumbs]
* breadcrumbsScope: non-home
* scripts: required
* no-script:
* regions: [header, footer, background, breadcrumbs]
* scripts: forbidden
* routeProfiles:
* "r/**": no-script
* "**\/r/**": no-script
*/
export const shellRegionNameSchema = z.enum(["header", "footer", "background", "breadcrumbs"]);
export type ShellRegionName = z.infer;
export const systemShellProfileSchema = z.object({
/**
* Closed set: regions that MUST be present on routes bound to this profile.
* Regions not listed here are FORBIDDEN (SITE-SHELL-02).
*/
regions: z.array(shellRegionNameSchema),
/**
* Document-level script policy (shell scripts are emitted outside their
* region element — e.g. the header's