YYayaw
Docs

CMS Overview

How Yayaw content surfaces, data models, media, sections, pages, design tokens, and email templates fit together.

Overview

Yayaw's CMS is the content operating layer inside the dashboard. It combines structured data, reusable sections, pages, media assets, public design tokens, transactional email templates, and component recipes under one authorization model.

The main entry point is:

  • /dashboard/content

That dashboard summarizes page inventory, section inventory, media storage, published CMS data, AI jobs, publication health, and shortcuts to every content surface available to the current user.

Surface Map

SurfaceRoutePurpose
CMS dashboard/dashboard/contentOperational overview and content health
Pages/dashboard/content/pagesPublic and organization page composition
Sections/dashboard/content/sectionsReusable page sections and generated recipes
Data models/dashboard/content/data-modelsTyped CMS model definitions
Data entries/dashboard/content/dataPublished singleton and collection content
Media/dashboard/content/mediaOrganization-scoped binary assets and generated images
Components/dashboard/content/componentsUI component registry, previews, and imports
Design tokens/dashboard/content/design-tokensRuntime public-theme token overrides
Email templates/dashboard/content/email-templatesReact Email transactional templates

Content Stack

The CMS is layered deliberately:

  1. Data models define typed fields, localization rules, and cardinality.
  2. Data entries publish shared values such as header menus, footer menus, and site variables.
  3. Media assets provide durable public URLs for selected or generated files.
  4. Components define the reusable UI inventory and recipe renderers.
  5. Sections define reusable page units with neutral example content and editable inputs.
  6. Pages compose layout nodes, component references, and published section references into public or organization-member routes, then fill section inputs through page-level bindings.
  7. Design tokens affect public runtime presentation through global and organization layers. One global page can additionally own a bounded semantic color and sans/serif layer in its immutable revision.
  8. Transactional email templates reuse CMS variables where appropriate but send through the email runtime, not the public page renderer.

This split keeps reusable structure in one place while page-specific editorial copy stays on the page instance. Section templates should behave like a catalog or Storybook example: use neutral fixture copy such as Lorem Ipsum in the section itself, then bind final copy, links, JSON lists, and media through PageSection.inputBindings or PageSection.mediaBindings when the section is placed on a page.

Authoring Flow

A typical CMS change follows this path:

  1. Create or update the structured source in data models, data entries, or media.
  2. Build a reusable section when the content should appear on more than one page.
  3. Compose the page in the Puck editor using built-in layout nodes, section references, and direct component references only when needed.
  4. Publish the page or section after validation diagnostics are clean.
  5. Verify the public or organization-member runtime route.

Page width and section rhythm belong to the serialized layout. The public renderer never infers them from /, /table, or any other path. A contextual plan sets page.layout.bodyWidth, page.layout.sectionGap, and page.layout.sectionFrame; they compile to the root PageStack container, gap, and shared section-frame behavior. sectionFrame: "token" preserves the standard public spacing wrapper, while "none" lets art-directed sections own their boundaries without a second uniform frame. The shared contained layout still reads its maximum width and responsive gutters from the page-container-* public design tokens.

An isolated global-page art direction can set page.designTokens without changing the global token record. The optional versioned payload supports light/dark semantic colors and approved loaded sans/serif stacks only. A create plan inherits when the field is omitted or null; a rework preserves the target layer when omitted, clears it with null, or replaces it with a payload. Layout/effect tokens, mono fonts, arbitrary CSS, URLs, and unregistered families are rejected. The normalized layer is hash-bound to the page revision and uses the same scoped wrapper in immutable draft preview and published runtime.

AI-assisted flows follow the same persistence model. Page AI promotes generated content into reusable sections, Page AI image generation persists media through the media library, and missing section publication causes an explicit failure instead of an inline fallback.

MCP-assisted page design follows the same product model, but the connected Codex or ChatGPT client owns the creative reasoning and image generation. Yayaw does not call a server-side text model for this workflow. The MCP provides bounded design guidance, CMS inventory, durable media ingestion, validation, draft persistence, and previews so the client can spend its existing context instead of paying for a second model pass.

External design guidance used by this flow is managed as checksummed, license-preserving dependencies. See CMS Design Skill Dependencies for the update and verification workflow.

Contextual MCP design workflow

New pages and page reworks use one mandatory workflow:

  1. Read the active design-token layers first. Save any approved broad global or organization change before creating a context, then call yayaw_cms_design_prepare with the requested surface, scope, locales, audience, goal, visual direction, factual inputs, media strategy, and visualIntent. When that intent is missing, preparation asks one localized kickoff question, by itself, to establish a new_art_direction, evolve_existing, or preserve_existing. Only after that answer can it ask other outcome-changing questions. A caller cannot preselect the technical compositionStrategy without that explicit intent. The server derives a compatible compositionStrategy; a caller cannot select a non-creative strategy to bypass prototypes for a new or evolved direction. It returns an actor-bound design context, its expiresAt, inventory proof, relevant versioned guidance profile, and up to three outcome-changing questions when needed. Explicit brand media is resolved before the context becomes ready. For a global page, organization-owned assets are captured in the immutable inventory only after the actor can list the owning media library and read each selected asset; refreshes preserve the same checked references. A ready response starts at guidance stage brief, states every required guidance stage, and explicitly reports whether exact-runtime prototype workflow version 2 is required. During long pauses, yayaw_cms_design_context_renew extends an unexpired context without changing its evidence, up to two hours from session creation. Expired contexts remain terminal.
  2. Modern MCP clients answer those questions through form elicitation. Classic clients receive the same input_required state and continue with yayaw_cms_design_resume; both paths produce the same prepared context.
  3. Load the actor-bound guidance with yayaw_cms_design_guidance_get. brief, composition, and critique are required for every contextual plan; rework is additionally required for page reworks. The server records each stage in the design context only when its content is returned, hashes the exact stage-selected content and source trace, and blocks prototype registration or dry-run when one is skipped. Prototype registration submits structured decisions keyed by directive IDs. The submitted IDs must cover every directive returned by every required loaded stage exactly once; omitted, duplicated, or invented IDs are rejected. The server owns each directive's classification and later implementation gate, so the client cannot downgrade visual rules. Every prototype_applicable directive carries one observed passing artifact location for each candidate; implementation_only directives name their server-selected later verification gate. A version-2 trace also carries the optional server-owned deterministic verificationCheckId for directives that can be proven later. The page plan acknowledges exactly that server-verifiable server_checked implementation subset as guidanceVerification: [{ directiveId }]; it cannot supply a checker or evidence path. Yayaw runs the checker and stores the immutable proof ledger. A process_only directive has no verificationCheckId: it remains binding through its structured registration decision and the normal process evidence or attestation at its assigned gate, but it does not enter guidanceVerification or the deterministic proof ledger. not_applicable is available only where the server allows it, includes a concrete brief or surface reason, and is capped per stage to prevent blanket exclusions.
  4. The client model creates one shared page structure for every requested locale and freezes the inputs that the prototypes will render. It reuses published data, media, components, and sections before planning new composition sections. Copy, SEO fields, alternative text, and factual references are localized without changing structural node IDs. If a required broad token change is discovered only now, discard the context, save the layer, and start again at step 1; an existing context cannot refresh onto another token hash. For an isolated global-page direction, define a bounded page layer for each candidate, place it in that candidate's pageShell, and copy the selected candidate's exact page.designTokens value into the later page plan. Outside global page scope, each candidate uses designTokens: null.
  5. Upload or import all story and recipe media with the active designContextId, finish direct-upload finalization through yayaw_media_upload_complete, and keep only finalized image assets with pinned MIME type, dimensions, and SHA-256 file hash. Then perform one pre-selection yayaw_cms_design_inventory_refresh. That refresh may append only media uploaded for this exact context while the component, section, page, data, and design-token baselines remain unchanged.
  6. Build and inspect exactly three complete static composite boards, upload them with the active designContextId, and register them with yayaw_cms_prototypes_register using kind: "generated_set_v2". A user-supplied prototype may anchor one candidate, but it does not remove the three-candidate comparison. Each board contains the desktop and mobile hero plus every intended section at sufficient fidelity and has server-read dimensions of at least 1200 × 900. All three boards declare the same ordered stable region IDs and labels for later prototypeRegionRef values. Each candidate records distinct silhouette, typography, narrative rhythm, visual metaphor, signature-device, responsive/theme, anti-generic-layout, and inverse competitor evidence and a non-empty allowlisted requiredCapabilities manifest. Registration combines the client's applied guidance decisions with server-owned guidance hashes. A rejected set or requested combination produces a replacement set of exactly three registered boards. Every exact candidate must also pass a computed creative-richness floor: both display_typography and responsive_recomposition; at least one structural signature from layered_composition, sticky_narrative, custom_grid_ratios, continuous_canvas, or compact_band; and at least one art-direction treatment from image_art_direction, paper_collage, watercolor_wash, media_texture, or decorative_shapes. Handwritten note text alone does not infer paper_collage. At least one signature region must infer all four dimensions together; distributing inert primitives across unrelated regions does not pass the floor. Before presentation or registration, every candidate also needs a per-region feasibility ledger built against the advertised component schemas. Every stable region maps its visible composition, media, typography, interaction, responsive/theme behavior, and fallback to exact allowlisted nodes with canonical paths (tree, then tree.children.N recursively), bounded props, the exact declarative recipePropSchema, the equal-key recipePropNames list, and exact instance recipePropBindings. creative-composition uses only propSchema for runtime inputs: apiSchema and harnessSchema are omitted or empty, fixtures is empty, and their related settings cannot carry hidden runtime content. Responsive order (desktopOrder or mobileOrder) requires a direct grid or stack parent, while responsive span (desktopSpan or mobileSpan) requires a direct grid parent. Grid, directional stack, placement, and sticky recomposition use the same md boundary. mobileSpan: "2" is invalid because the base mobile grid has one explicit column. Required props without defaults need bindings, every binding must target the schema, and every image.src must be exactly $props.<identifier> backed by a media_asset or localized_media_asset binding to durable prepared media. Exact recipes also reject valid-but-inert combinations such as anchors outside overlays, desktop grid props on absolute overlays, collapsing overlay-only canvases, and fixed image heights combined with responsive aspect ratios. Handmade composition can use wash or the stronger pigment-wash decoration treatment and the additive watercolor-paper, deckle-paper, or taped-paper frame materials. The historical wash, paper, deckle, and taped values keep their exact renderer output. Art-directed overflow is explicit: section.overflow and frame.overflow accept clip or visible. Visible overflow infers continuous_canvas only when a descendant placement, rotated or taped frame, or large/washed decoration can actually cross the boundary. Images accept bounded blend (normal, multiply, screen, soft-light) and opacity (solid, soft, faint) treatments; non-default texture treatments infer media_texture. Actions and submits expose bare, outline, paper, solid, and underline appearances; fields expose bare, line, outline, and paper; uploads expose bare, dashed, and paper. The canonical creative renderer preserves all exact bound prop values and never applies legacy catalog-demo normalization after the render manifest is validated. mediaAssetIds must be the exact deduplicated set of IDs used by all media bindings. Every prototype-visible text, link, label, placeholder, image alt, or upload message is a direct $props.<identifier> sink. Text bindings are exact localized literals for every prepared locale; links use bounded safe literal or localized targets. Prototype-critical global-data bindings and repeat/$item/$index are rejected, so visible repeated items are explicit planned nodes. Yayaw rebuilds this recipe and validates it through the canonical runtime contract. It then computes feasibility.compositionHash from node names, canonical paths, and structural props only, independently from content, media, actions, palette, and other non-structural props. It separately computes feasibility.implementationHash from the exact prop names/schema/tree and feasibility.renderManifestHash from that implementation plus its bindings; clients do not submit any of these hashes. reuse_published must match its exact inventory component immediately, while new_recipe cannot clone a compositionHash topology already published in the prepared inventory and must later match a same-context created revision. A new ID, slug, or revision does not make a clone new. Final plan validation requires that exact published component at the mapped section root with the exact resolved literal, input, and media bindings. A blocked region, nested substitute, different tree with the same coarse capability labels, or changed bindings rejects the candidate. Each candidate also submits one exact pageShell containing layout and either a bounded page-scoped designTokens layer or null. Every region supplies integer pixel baseline artifactBounds plus an ordered scenarioArtifactBounds crop for every prepared locale × desktop/mobile × light/dark scenario. Every crop is at least 200 × 120 pixels. Baseline crops remain at least 2% of board area and cover at least 40% of the board; non-baseline crops are at least 2% / required scenario count of board area. Pairwise intersection across all scenario crops may not exceed 50% of the smaller crop. Yayaw fingerprints the baseline crops and later compares every exact scenario crop with its matching runtime band. For every candidate pair, at least one matching baseline region crop must be materially distinct; changing only board chrome fails. Clients submit the planned recipe data, not derived proof. The server alone adds compositionHash, implementationHash, renderManifestHash, pageShell.designTokensHash, pageShell.manifestHash, board and region visualFingerprint values, and each candidate runtimeHash. It computes the runtime hash only after resolving the exact shell, locale bindings, finalized media ledger, recipes, renderer contract, and deployment fingerprint through the canonical production page pipeline. In production, that resolution fails closed without an immutable fingerprint from NEXT_DEPLOYMENT_ID, resolved gitCommitSha such as DEPLOYMENT_GIT_COMMIT_SHA, or resolved deploymentId. The "local" fallback exists only outside production. The fingerprint and renderer contract version are both part of runtimeHash, so a renderer build change changes the hash and invalidates earlier review. Registration also persists exactly three structured pairwise comparisons: A/B, A/C, and B/C. Every comparison records material differences in silhouette, typography, narrative rhythm, visual metaphor, signature device, and mobile/theme resolution, with exact <artifactId>#<regionId> evidence for both candidates in every ordered region. Yayaw also requires distinct A/B/C structural, implementation, and render signatures. Ordered regional compositionHash values form the structural signature. The normalized page-shell manifest is pinned separately and must match the selected candidate exactly in the plan and runtime; it is not part of the candidate-distinctness signature. The other signatures use ordered regional implementationHash and renderManifestHash values. Content, media, palette, schema-default, or binding changes cannot make unchanged regional topology a separate direction. Yayaw also computes a normalized 16 × 16 grayscale edge-matrix fingerprint from each stored full board and rejects clones or boards below the minimum structural distance. This coarse normalized-structure guard is never sufficient proof of a distinct direction or fidelity; it supplements the three signatures, pairwise critique, visual inspection, and substantive Visual QA.
  7. Registration returns a runtimeHash, signed locale preview URLs, and an evidence-upload contract for every candidate. Open the canonical runtime previews for A, B, and C; use yayaw_cms_prototype_runtime_previews_get only to issue fresh URLs when the stored runtime is still current. For each candidate, capture every prepared locale at desktop/mobile and light/dark. Finalize every screenshot as a distinct durable image with the exact returned designContextId, designPlanHash equal to that candidate's runtimeHash, and exact visualRole. Desktop evidence is at least 1024 pixels wide; mobile evidence is 240–767 pixels wide. Each finalized screenshot also carries a version-1 capture attestation bound to its exact artifact hash, runtime hash, scenario ID, observed document height, and ordered region IDs. Its regions form one contiguous vertical partition from 0 to the image/document height, with unique IDs, bands of at least 24 pixels, and no gap or overlap. The image height must equal the attested document height and remain under the returned maximum. Distinct scenarios require distinct asset IDs and file hashes. These post-registration screenshots are queried directly by ID during review; do not inventory-refresh them. Complete the full matrix through yayaw_cms_prototype_runtime_review_complete with all eight fidelity fields passing, boardMatchesRuntime: true, and no blockers or unapproved deviations. reviewerRole: "visual_qa" is a logical workflow label tied to the current actor, not proof of a separate person or credential. The board and runtime preview remain separate artifacts: the reviewer compares them visually, while fingerprints, manifests, hashes, durable provenance, and capture bindings detect substitution, truncation, replay, and drift. A preview without live form context keeps the registered form's exact layout and controls but makes the wrapper inert and non-submittable, so form context does not change the reviewed composition. Server comparison uses cms-server-visual-comparison-v3: reference and runtime bands are normalized with contained 192 × 192 sampling and stricter structure, topology, aspect, edge, luma, and palette limits, so removing a signature wash or texture fails fidelity. The current immutable renderer boundary is page contract 7 and prototype contract 4. The explicit client_observed_server_validated trust boundary does not claim cryptographic proof that the client really drove a browser. Preview issuance, review completion, selection, planning, page review, and publication re-resolve the stored candidate. A changed renderer or deployment fingerprint, recipe, media file, screenshot ledger, or token snapshot makes the runtime review stale. Replace and re-register all three candidates before selection when the runtime no longer matches. If active design tokens change after a v2 gate is registered, create a new design context and repeat preparation, prototypes, and runtime review; inventory refresh cannot rebase the gate to a new token hash.
  8. Only after a current runtime-review receipt exists does the client call yayaw_cms_prototype_select without a candidate. The operation presents the canonical ordered A/B/C labels, originality comparison, and fresh runtime previews. Modern MCP clients collect the enum choice through form elicitation and commit it in the same call. Classic clients receive the same input_required presentation and resume with its bounded challengeId plus the chosen prototypeId. Exact-v2 rejects caller-authored decisionNote values; the server-generated immutable receipt binds the challenge, presentation, runtime-review evidence, response source, and selection. Planning and publication recompute that receipt and fail closed on missing or tampered proof. resumable_client is an actor-bound client attestation, not cryptographic proof of a human click; form elicitation is stronger in-protocol interaction evidence but remains client-mediated. Copy the returned immutable designBasis into the plan. Import, compile, and publish any selected new_recipe components with the same designContextId. Upload or import every additional final-page image that the plan will bind, then call one same-token yayaw_cms_design_inventory_refresh so the exact published revisions and every bound asset enter the inventory without rebasing the prototype. Temporary generation URLs are never bindings.
  9. Submit the complete version-2 plan to yayaw_cms_page_design or yayaw_cms_page_rework with dryRun: true. The MCP checks the context and inventory proofs, locales, facts, SEO, media, schemas, section references, and optimistic rework revision before persistence. The dry-run also enforces the strategy's originality contract and returns a readable section decision summary plus the creative critique. A component declared as newly created must be absent from the initial component baseline, imported only after explicit prototype selection with this designContextId, and referenced by its exact published slug@revision as the root component of a newly created composition section. Every A/B/C candidate registered for design_system_extension must already expose at least one visible new_recipe region; the selected candidate must implement that region with the same-context published recipe. Design-context provenance belongs to that immutable compiled recipe revision, not mutable registry metadata. The dry-run also revalidates the selected prototype artifact's image kind, context, file hash, and minimum dimensions. It requires every plan section, in order, to use the matching selected-prototype region as <prototypeId>#<regionId>; reordered, swapped, invented, or omitted region references fail. The page must also reproduce the selected candidate's exact pageShell.layout and page-scoped designTokens value. The plan uses version: 2; strict persistence issues the corresponding version-2 design proof. The post-selection inventory refresh must preserve the registered gate, runtime-review receipt, explicit selection, exact prototype designBasis, and prepared design-token hash.
  10. Correct diagnostics, submit the identical hashed plan with dryRun: false, then call yayaw_cms_page_review. Review returns static diagnostics and short-lived locale preview URLs, a resolved runtime hash, and a visual review contract bound to the immutable draft revision. review_ready means only that deterministic static/runtime checks passed; it is not visual approval. A corrected plan stays bound to the first contextual page, page path/slug, and stable section IDs/slugs: Yayaw creates new revisions instead of another route or suffixed duplicate sections. Page revisions, section revisions, session draft binding, and contextual media plan hashes commit together in one serializable transaction; a conflict rolls back every write. Registry rows carry a durable revision-head pointer that the database advances on immutable revision insertion, so correction continuity does not depend on timestamp ordering. A manual or external revision blocks that correction path. An A → B → A correction that matches an older immutable revision returns an explicit revision-reuse conflict instead of silently treating old revision A as the new head.
  11. Open every preview and complete the required locale × desktop/mobile × light/dark matrix, reduced-motion checks, and per-section detail checks. A Visual QA pass must return an explicit PASS for the exact immutable revision and runtime before any durable browser evidence is uploaded. The first immutable draft and every immutable correction require a new pass; an earlier pass cannot be reused. A separate reviewer is preferable when available, but the persisted workflow role is not proof of an independent person or credential. Prototype-based review additionally binds every section to a prototypeRegionRef, repeats the exact prototype artifact identity, and verifies composition silhouette, surface hierarchy, palette distribution, spacing rhythm, typographic character, media proportions, narrative pacing, and the signature device. Persist each scenario and reduced-motion capture as a durable image bound to the exact designContextId, designPlanHash, and required visualRole. Attach the returned version-1 full-page attestation to every scenario and reduced-motion artifact, using the exact runtime hash, scenario ID, document height, and contiguous ordered section bands. The returned role prefix is derived from the exact page revision and runtime hash, so captures from an older review cannot be reused. Review first revalidates the selected prototype artifact's image kind, design context, file hash, and minimum dimensions. Then use each capture asset ID as evidenceRef. Submit the evidence with yayaw_cms_page_review_complete; unapproved deviations block approval. Any correction, newer page revision, or changed published section/component dependency invalidates the receipt and requires a fresh review.
  12. Publishing remains a separate, explicit page or section publish call. Contextual page publication is blocked until an approved receipt matches the exact design context, plan, page revision, and resolved runtime. Publication revalidates the selected prototype and every screenshot-ledger row against its image kind, design context, plan hash, file hash, dimensions, and required role. Publication runs as one serializable check-and-write: revision heads, server-issued section pins, ever-published block/component provenance, media ledgers, global-data dependencies, design tokens, runtime hash, and receipt are locked and revalidated before the pointer advances. No prepare, design, rework, media, preview, or static review step publishes content. A matching receipt is evidence, not authorization: the client calls the page publish tool only after the user explicitly requests publication.

For rolling upgrades, reader-compatible servers understand legacy prototypeSet.kind: "generated_set" contexts and the separate prototypeGateV2.kind: "generated_set_v2" field, and fail closed when both are present. The separate field preserves reader discrimination but does not make a mixed fleet safe: a pre-reader instance can still operate on legacy state and write or select it. Production therefore uses two explicit, mutually exclusive writer switches. Deploy the reader build with CMS_LEGACY_PROTOTYPE_WRITES_ENABLED=true and CMS_PROTOTYPE_RUNTIME_V2_WRITES_ENABLED=false, drain every pre-reader instance, and make that build the rollback floor. Configure a distinct private STORAGE_MEDIA_STAGING_BUCKET, enable CMS_MEDIA_STAGED_UPLOADS_ENABLED=true, and verify promotion. Private grants use the opaque same-origin app proxy and keep S3_ENDPOINT internal by default. Only configure S3_SIGNED_PUBLIC_ENDPOINT when the application host cannot stream the 250 MB media contract; it must be a safe public HTTPS S3 API origin and switches uploads only. Both transports require conditional no-overwrite PUTs. The verified staging object remains private through grant expiry and a 24-hour settlement window so it blocks replay across instances. The reaper repeats deletion during settlement and marks cleanup complete only after its final delete. Then set both writer switches to false, restart, and drain the legacy writers before setting only v2 to true. Both switches set to true fail closed. Every later rolling renderer deployment must use the same trusted manual protocol: freeze and prove all typed resources on one full SHA, issue or explicitly resume its immutable receipt, revalidate the live drain, enter activating, deploy and revalidate exact, then consume the receipt. A failed activating run returns only to freeze and resumes the same operation with fresh evidence. If the fleet has already advanced to a strict main-history descendant, the operator explicitly supplies the old operation and SHA; the workflow proves the descendant frozen and atomically activates its replacement receipt while marking the old receipt terminal superseded. That recovery branch never advances the runtime floor. Normal automatic production deployment is reader-only. Development PR deployment may preserve an already configured and live-proven freeze, but it cannot initiate freeze or exact. After deploying the new immutable PR SHA, it proves every live app/worker container still has that SHA and freeze state before the operator runs exact manually. Production refuses v2 writes without private staging and a valid rollout operation ID. The first exact gate requires the matching consumed receipt and permanently binds that operation to the database runtime floor. Once any v2 context exists, never roll back below that floor or re-enable legacy writes. Existing legacy contexts remain readable and cancellable but cannot be renewed, selected, planned, drafted, reviewed, or published. A new exact workflow must not downgrade to legacy. Assets ever backed by a legacy direct-upload grant are permanently ineligible for exact prototypes and review evidence; re-upload them through private staging to obtain an unexposed final object key. A disabled v2 writer returns cms_design_prototype_runtime_rollout_pending; retry v2 after the floor is established and the flag is enabled. Local and other non-production environments default v2 writes to enabled when the variable is absent.

The exact evidence guarantee is point-in-time through publication. A later behavioral renderer change does not automatically re-capture already-published pages. Until deployment can inventory published renderer contracts and provide either versioned backward-compatible rendering or migration plus visual re-review before promotion, every behavioral page/prototype renderer change is release-blocking. Review and deliberately bump the shared constants in cms-renderer-contract.ts; a version bump records the boundary but does not make an unsafe deployment acceptable.

The blocker loop is exact: dry-run and persist one immutable revision, obtain review_ready, then run Visual QA against that revision and runtime. If static/runtime diagnostics fail, or Visual QA finds a failed scenario, failed fidelity field, blocking issue, or unapproved deviation, do not upload visual-review:* evidence, complete review, or publish. Correct the same contextual plan, persist a new immutable revision, and restart from dry-run. Only a PASS with zero blockers and deviations unlocks evidence upload and review completion. Any later correction or dependency change invalidates that pass and receipt and restarts the loop.

When a design is based on an approved prototype, browser review must compare the immutable draft section by section against the exact hashed artifact, not only its broad theme. Review both light and dark modes at desktop and mobile widths in every prepared locale before publishing. The server independently pixel-compares every locale × viewport × theme capture with its matching immutable scenarioArtifactBounds crop; client pass booleans are not visual proof. Recipe presentation must use Yayaw/shadcn semantic design-token roles. Adjust brand color values through the CMS design-token layer when needed instead of hard-coding page-specific colors into reusable runtime components.

Client role orchestration and visual quality gate

For creative_rework, design_system_extension, or an approved prototype, clients that support delegation should parallelize bounded read-only work while keeping one MCP writer:

  • a Creative Director locks the design read, narrative, section contract, media/token intent, motion, and detail standard, then produces the three composite-board candidates and their guidance trace
  • one Implementer owns all catalog/page mutations, inventory refreshes, dry-runs, plan hashing, and draft persistence
  • a Visual QA role reviews all three candidates before selection and the immutable preview after implementation without mutating either; it returns an explicit PASS for the exact revision/runtime after the first immutable draft and every immutable correction
  • a Technical QA can run in parallel to check responsive behavior, themes, reduced motion, accessibility, media loading, and runtime errors

Agents hand off a compact ledger containing the guidance profile and trace, all prototype IDs and artifact references, the selected prototype ID, the exact prototype designBasis, designContextId, inventoryHash, exact component/section revisions, pageId, page revisionId, planHash, and runtimeHash. Visual QA reads the same full guidance profile rather than trusting an upstream summary. Parallel agents must not mutate the same catalog item or page. After catalog publication, yayaw_cms_design_inventory_refresh refreshes inventory on the same context without discarding the registered prototype set, selection, or basis. After a correction, review the new immutable revision from scratch. Clients without delegation can follow preparation and implementation sequentially, but prototype-based creative work cannot upload review evidence or publish without the Visual QA pass. This role is a quality workflow, not an independently authenticated identity boundary.

The visual evidence matrix verifies media loading, horizontal overflow, text overlap, runtime errors, theme contrast, and typography fit for every required scenario. Each rendered section also verifies bullet rhythm, caption legibility, CTA states, icon semantics, separators, and optical alignment. Scenario and reduced-motion evidence references are durable media asset IDs; their server-verified image kind, design context, plan hash, static file bytes, viewport dimensions, roles, document height, and capture attestation are bound into the review receipt and retained as its artifact ledger. Publication re-downloads and re-inspects that ledger plus the source/runtime prototype evidence and treats removed, changed, animated, truncated, replayed, reclassified, or cross-context captures as stale review. Prototype work adds the eight fidelity dimensions and an exact prototype region reference per section; the Visual QA comparison must repeat the selected prototypeId, artifactId, and artifactHash, with no unapprovedDeviations. Mobile must be intentionally recomposed rather than treated as a collapsed desktop layout. Motion must remain purposeful and preserve a complete reduced-motion experience. Full evidence remains in the control-plane audit event; the page stores a compact hash-bound review receipt used by publication.

Composition strategies are explicit and cannot be silently downgraded:

  • content_only forbids new composition sections.
  • compose_existing intentionally permits catalog assembly.
  • creative_rework requires at least three new composition sections, a newly composed hero and narrative section, and no more than 50% reused sections.
  • design_system_extension adds the same composition gates and requires at least one runtime-renderable component recipe imported, compiled, published, present in the same-context refreshed inventory, and referenced by exact published revision from a new composition section. Use a declarative creative-composition recipe for original nested layouts, media, actions, and explicitly expanded repeated structures. A source import that resolves to the generic composite fallback does not satisfy this gate.

Creative strategies also require a blocking self-critique: the page must remain distinctive without its logo, tell a coherent story, include an original interaction or composition, and avoid collapsing into a feature checklist. If orchestration fails, the client must correct the structured plan or stop; it must never fall back to compose_existing without a new prepared brief.

yayaw_cms_page_design accepts only the contextual multilingual plan. Direct yayaw_pages_create_draft and yayaw_pages_save_draft are audited low-level maintenance bypasses reserved for control-plane:admin and disabled unless CMS_LOW_LEVEL_PAGE_ADMIN_BYPASS_ENABLED=true. The deprecated yayaw_cms_page_design_legacy_admin compatibility tool is also admin-only and remains disabled unless CMS_LEGACY_PAGE_DESIGN_ADMIN_BYPASS_ENABLED=true; it is intended only for a short migration or incident response, not normal authoring.

Draft preview URLs are bearer credentials. They expire after a short period, resolve one immutable revision, bypass public runtime caches and analytics, use noindex/nofollow, and are blocked on organization custom domains. Configure CMS_PREVIEW_SIGNING_SECRET as a dedicated high-entropy server secret in production; BETTER_AUTH_SECRET is the fallback signing source.

Runtime Resolution

Published content resolves from immutable revisions and publication rows:

  • pages load ui_page_publications and render the published PuckPageDocumentV1
  • section references resolve through ui_section_publications, first by current section ID and then by scoped slug/slug fallback so older page revisions keep rendering after section IDs are repaired
  • page-level PageSection bindings override section fixture props at runtime, so a catalog section can stay generic while each page instance carries the final localized content
  • literal component and section props accept bounded JSON values directly, including nested arrays, objects, and null; recursive valueShape contracts validate nested fields while legacy stringified JSON remains readable
  • data bindings resolve published global or organization CMS data entries
  • media bindings use the stored public URL from media_assets
  • public design tokens resolve from saved global/organization payloads, then an optional global-page revision layer applies inside that page wrapper
  • transactional emails load the active database template for the requested locale before falling back to component defaults

Global public pages feed /sitemap.xml and public SEO metadata. Organization member pages require membership and emit noindex metadata even when page-level SEO fields exist.

Localization

CMS documents use the configured app locales from src/config/i18n.config.ts. Current locales are English and French.

Localized content appears in:

  • page copy and SEO fields
  • global and organization data entry values
  • header and footer menu entries
  • generated section recipe values, including the legal-page legal variant
  • transactional email subjects, preview text, body HTML, and text exports

Generated page section bindings are stored as JSON object text in the Puck document (propsBindingsJson, apiBindingsJson, harnessBindingsJson, and related binding fields). Values inside those binding objects are real JSON values and do not need to be stringified independently. Validation applies bounded JSON limits, blocks unsafe object keys, checks recursive value shapes, and rejects generated sections without a valid variant binding so MCP or dashboard saves cannot silently publish runtime fallback sections.

The English docs are canonical. French content may exist in the product, but new technical documentation should update English first.

Authorization

The CMS uses Yayaw's group and role authorization model. Dashboard navigation is only a hint; server loaders, actions, services, and MCP operations must still authorize every read or mutation.

Common CMS resources:

  • page
  • sections
  • global-data
  • media
  • components
  • global-variables
  • email-template

Organization members normally receive list/read access for organization-scoped content. Managers, admins, owners, and superadmins receive manage access according to their group role bindings.

Control Plane

Operational CMS workflows should share service logic across the dashboard, MCP, CLI scripts, and tests when they are exposed outside the UI.

Current control-plane coverage includes:

  • page operations
  • component catalog operations
  • reusable section operations
  • draft CMS page design orchestration
  • CMS data operations
  • media generation operations
  • design token operations
  • transactional email template operations
  • billing catalog operations used by CMS variables

When adding a CMS feature, decide whether trusted MCP clients should operate it. If yes, add typed schemas, a reason for writes, audit records, authorization checks, and documentation updates. If no, document why the feature is intentionally dashboard-only.

Operational Rules

  • Store reusable content as published data, media, sections, or templates.
  • Keep page documents as composition documents, not duplicated content stores.
  • Do not execute DB-stored component source code.
  • Do not store media binaries in Postgres.
  • Keep public design tokens scoped outside dashboard and auth routes.
  • Keep global CMS data and organization CMS data scoped explicitly.
  • Revalidate affected dashboard and public runtime paths after publish/archive.
  • Treat generated assistant files as derived artifacts; update content/llm/llm-source.md first and regenerate them.

Validation

Useful checks after CMS documentation or CMS behavior changes:

bun run docs:generate
bun run docs:check-links
bun run docs:check-translations
bun run docs:llm:generate
bun run docs:llm:check
bun run check
bunx tsc --noEmit

Run domain tests as needed when implementation changes touch pages, sections, data models, media, components, tokens, or email templates.

Contextual plan validation reports prototype or existing-page basis mismatches, missing explicit layouts, an old or foreign component claimed as new, duplicate component decisions, and created_component_not_used before persistence. Prototype review rejects a substituted artifact, invented, duplicated, or uncovered prototype regions, invalid viewport class, missing section fidelity, or any unapprovedDeviations.