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
| Surface | Route | Purpose |
|---|---|---|
| CMS dashboard | /dashboard/content | Operational overview and content health |
| Pages | /dashboard/content/pages | Public and organization page composition |
| Sections | /dashboard/content/sections | Reusable page sections and generated recipes |
| Data models | /dashboard/content/data-models | Typed CMS model definitions |
| Data entries | /dashboard/content/data | Published singleton and collection content |
| Media | /dashboard/content/media | Organization-scoped binary assets and generated images |
| Components | /dashboard/content/components | UI component registry, previews, and imports |
| Design tokens | /dashboard/content/design-tokens | Runtime public-theme token overrides |
| Email templates | /dashboard/content/email-templates | React Email transactional templates |
Content Stack
The CMS is layered deliberately:
- Data models define typed fields, localization rules, and cardinality.
- Data entries publish shared values such as header menus, footer menus, and site variables.
- Media assets provide durable public URLs for selected or generated files.
- Components define the reusable UI inventory and recipe renderers.
- Sections define reusable page units with neutral example content and editable inputs.
- Pages compose layout nodes, component references, and published section references into public or organization-member routes, then fill section inputs through page-level bindings.
- 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.
- 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:
- Create or update the structured source in data models, data entries, or media.
- Build a reusable section when the content should appear on more than one page.
- Compose the page in the Puck editor using built-in layout nodes, section references, and direct component references only when needed.
- Publish the page or section after validation diagnostics are clean.
- 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:
- Read the active design-token layers first. Save any approved broad global or
organization change before creating a context, then call
yayaw_cms_design_preparewith the requested surface, scope, locales, audience, goal, visual direction, factual inputs, media strategy, andvisualIntent. When that intent is missing, preparation asks one localized kickoff question, by itself, to establish anew_art_direction,evolve_existing, orpreserve_existing. Only after that answer can it ask other outcome-changing questions. A caller cannot preselect the technicalcompositionStrategywithout that explicit intent. The server derives a compatiblecompositionStrategy; a caller cannot select a non-creative strategy to bypass prototypes for a new or evolved direction. It returns an actor-bound design context, itsexpiresAt, 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 stagebrief, states every required guidance stage, and explicitly reports whether exact-runtime prototype workflow version 2 is required. During long pauses,yayaw_cms_design_context_renewextends an unexpired context without changing its evidence, up to two hours from session creation. Expired contexts remain terminal. - Modern MCP clients answer those questions through form elicitation. Classic
clients receive the same
input_requiredstate and continue withyayaw_cms_design_resume; both paths produce the same prepared context. - Load the actor-bound guidance with
yayaw_cms_design_guidance_get.brief,composition, andcritiqueare required for every contextual plan;reworkis 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. Everyprototype_applicabledirective carries one observed passing artifact location for each candidate;implementation_onlydirectives name their server-selected later verification gate. A version-2 trace also carries the optional server-owned deterministicverificationCheckIdfor directives that can be proven later. The page plan acknowledges exactly that server-verifiableserver_checkedimplementation subset asguidanceVerification: [{ directiveId }]; it cannot supply a checker or evidence path. Yayaw runs the checker and stores the immutable proof ledger. Aprocess_onlydirective has noverificationCheckId: it remains binding through its structured registration decision and the normal process evidence or attestation at its assigned gate, but it does not enterguidanceVerificationor the deterministic proof ledger.not_applicableis available only where the server allows it, includes a concrete brief or surface reason, and is capped per stage to prevent blanket exclusions. - 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 exactpage.designTokensvalue into the later page plan. Outside global page scope, each candidate usesdesignTokens: null. - Upload or import all story and recipe media with the active
designContextId, finish direct-upload finalization throughyayaw_media_upload_complete, and keep only finalized image assets with pinned MIME type, dimensions, and SHA-256 file hash. Then perform one pre-selectionyayaw_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. - Build and inspect exactly three complete static composite boards, upload
them with the active
designContextId, and register them withyayaw_cms_prototypes_registerusingkind: "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 laterprototypeRegionRefvalues. 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 allowlistedrequiredCapabilitiesmanifest. 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: bothdisplay_typographyandresponsive_recomposition; at least one structural signature fromlayered_composition,sticky_narrative,custom_grid_ratios,continuous_canvas, orcompact_band; and at least one art-direction treatment fromimage_art_direction,paper_collage,watercolor_wash,media_texture, ordecorative_shapes. Handwritten note text alone does not inferpaper_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, thentree.children.Nrecursively), bounded props, the exact declarativerecipePropSchema, the equal-keyrecipePropNameslist, and exact instancerecipePropBindings.creative-compositionuses onlypropSchemafor runtime inputs:apiSchemaandharnessSchemaare omitted or empty,fixturesis empty, and their related settings cannot carry hidden runtime content. Responsive order (desktopOrderormobileOrder) requires a directgridorstackparent, while responsive span (desktopSpanormobileSpan) requires a directgridparent. Grid, directional stack, placement, and sticky recomposition use the samemdboundary.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 everyimage.srcmust be exactly$props.<identifier>backed by amedia_assetorlocalized_media_assetbinding 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 usewashor the strongerpigment-washdecoration treatment and the additivewatercolor-paper,deckle-paper, ortaped-paperframe materials. The historicalwash,paper,deckle, andtapedvalues keep their exact renderer output. Art-directed overflow is explicit:section.overflowandframe.overflowacceptcliporvisible. Visible overflow inferscontinuous_canvasonly when a descendant placement, rotated or taped frame, or large/washed decoration can actually cross the boundary. Images accept boundedblend(normal,multiply,screen,soft-light) andopacity(solid,soft,faint) treatments; non-default texture treatments infermedia_texture. Actions and submits exposebare,outline,paper,solid, andunderlineappearances; fields exposebare,line,outline, andpaper; uploads exposebare,dashed, andpaper. The canonical creative renderer preserves all exact bound prop values and never applies legacy catalog-demo normalization after the render manifest is validated.mediaAssetIdsmust 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 andrepeat/$item/$indexare rejected, so visible repeated items are explicit planned nodes. Yayaw rebuilds this recipe and validates it through the canonical runtime contract. It then computesfeasibility.compositionHashfrom node names, canonical paths, and structural props only, independently from content, media, actions, palette, and other non-structural props. It separately computesfeasibility.implementationHashfrom the exact prop names/schema/tree andfeasibility.renderManifestHashfrom that implementation plus its bindings; clients do not submit any of these hashes.reuse_publishedmust match its exact inventory component immediately, whilenew_recipecannot clone acompositionHashtopology 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 exactpageShellcontaininglayoutand either a bounded page-scopeddesignTokenslayer ornull. Every region supplies integer pixel baselineartifactBoundsplus an orderedscenarioArtifactBoundscrop 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 least2% / required scenario countof 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 addscompositionHash,implementationHash,renderManifestHash,pageShell.designTokensHash,pageShell.manifestHash, board and regionvisualFingerprintvalues, and each candidateruntimeHash. 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 fromNEXT_DEPLOYMENT_ID, resolvedgitCommitShasuch asDEPLOYMENT_GIT_COMMIT_SHA, or resolveddeploymentId. The"local"fallback exists only outside production. The fingerprint and renderer contract version are both part ofruntimeHash, 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 regionalcompositionHashvalues 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 regionalimplementationHashandrenderManifestHashvalues. 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. - 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; useyayaw_cms_prototype_runtime_previews_getonly 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 returneddesignContextId,designPlanHashequal to that candidate'sruntimeHash, and exactvisualRole. 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 from0to 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 throughyayaw_cms_prototype_runtime_review_completewith 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 usescms-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 contract7and prototype contract4. The explicitclient_observed_server_validatedtrust 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. - Only after a current runtime-review receipt exists does the client call
yayaw_cms_prototype_selectwithout 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 sameinput_requiredpresentation and resume with its boundedchallengeIdplus the chosenprototypeId. Exact-v2 rejects caller-authoreddecisionNotevalues; 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_clientis 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 immutabledesignBasisinto the plan. Import, compile, and publish any selectednew_recipecomponents with the samedesignContextId. Upload or import every additional final-page image that the plan will bind, then call one same-tokenyayaw_cms_design_inventory_refreshso the exact published revisions and every bound asset enter the inventory without rebasing the prototype. Temporary generation URLs are never bindings. - Submit the complete version-2 plan to
yayaw_cms_page_designoryayaw_cms_page_reworkwithdryRun: 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 thisdesignContextId, and referenced by its exact publishedslug@revisionas the root component of a newly created composition section. Every A/B/C candidate registered fordesign_system_extensionmust already expose at least one visiblenew_reciperegion; 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 exactpageShell.layoutand page-scopeddesignTokensvalue. The plan usesversion: 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 prototypedesignBasis, and prepared design-token hash. - Correct diagnostics, submit the identical hashed plan with
dryRun: false, then callyayaw_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_readymeans 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. AnA → B → Acorrection that matches an older immutable revision returns an explicit revision-reuse conflict instead of silently treating old revisionAas the new head. - 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
PASSfor 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 aprototypeRegionRef, 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 exactdesignContextId,designPlanHash, and requiredvisualRole. 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 asevidenceRef. Submit the evidence withyayaw_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. - 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
PASSfor 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_onlyforbids new composition sections.compose_existingintentionally permits catalog assembly.creative_reworkrequires at least three new composition sections, a newly composed hero and narrative section, and no more than 50% reused sections.design_system_extensionadds 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 declarativecreative-compositionrecipe for original nested layouts, media, actions, and explicitly expanded repeated structures. A source import that resolves to the genericcompositefallback 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_publicationsand render the publishedPuckPageDocumentV1 - 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
PageSectionbindings 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; recursivevalueShapecontracts 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
legalvariant - 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:
pagesectionsglobal-datamediacomponentsglobal-variablesemail-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.mdfirst 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 --noEmitRun 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.