Journey Docs
CMS

CMS Assistant

The constrained authoring agent — skills, proposal operations, guardrails, durable execution, and turn budgets

The assistant is a session-based agent that authors CMS pages through the same core services and validators the layout editor uses. It is not a free-form HTML generator: the model never writes JSONB directly, and every mutation is a typed operation that passes the ordinary validation path.

It reads the current page, the owner-scoped block palette, field schemas, theme, SEO, and media library, then proposes draft-only mutations.

Two authoring flows

  1. Create from a prompt — build a page from scratch, mixing existing palette modules with new owner-scoped custom block types and a complete SEO record. Validated create-from-scratch chains auto-apply in order to mint their drafts.
  2. Edit in place — create or modify a specific section, row, column, or module, rewrite block content, or revise page SEO. Every existing-page or component proposal stays pending until an editor explicitly applies it.

Proposal chains are canonical and idempotent: one page create, stable custom-schema identities, fresh-state validation, deterministic supersession, and terminal handling for failed dependent proposals. The server is authoritative for user-visible creation state, so the assistant cannot describe a pending proposal as live or applied.

Skills

CMS contracts and authoring guidance are versioned skills loaded into the cached system prompt rather than improvised per turn.

SkillCovers
cms-compositionthe layout hierarchy and grid math
cms-blocksblock schemas and field kinds
cms-modulesthe module compiler template dialect
cms-seothe seven fields the admin SEO form exposes
cms-theme-kitowner-scoped brand values
cms-page-themeper-page theme overrides
cms-ownerowner scoping and palette resolution
cms-designvisual composition
cms-uxpage purpose, narrative flow, readability, actions, accessibility, responsive composition, motion, and trustworthy guest-facing content
cms-inspirationreference and inspiration media handling
cms-member-datamember data tokens and personalization

Operations

A proposal is a list of typed operations. Ten are permitted:

OperationEffect
create_pagenew page with owner, slug, type, and optional member gate
ensure_draftclone the published row to a draft before editing
patch_pagetoggle memberAuthRequired
replace_layoutreplace the layout tree
update_block_contentrewrite one module's content
create_block_schemaregister an owner-scoped custom type with html / optional css
update_block_schemarevise an owned type
delete_block_schemaremove an owned type
patch_themepage theme colors, fonts, typography, buttons, grid
replace_seowrite the cms_page_seo row

Seven operations are explicitly forbidden and rejected rather than merely omitted from the prompt:

publish   archive   unpublish   delete_page
discard_draft   delete_section   delete_subtree

The agent therefore cannot put anything live, take anything down, or destroy an author's work. It also cannot mint platform-wide block types, add a new field kind, or emit raw CSS.

A custom block type is registered only when the live palette cannot express the request. It is always owner-scoped and composed from existing field kinds. create_block_schema uses a proposal-local alias so a replace_layout in the same proposal can reference the type before it exists; apply mints the real ULID block_type.

Brand grounding

Brand context comes from one approved, effective theme kit snapshot rather than free research inside the turn. Research and review happen in the owner-scoped theme-kit workflow; page generation consumes the approved kit and reuses the associated profile version, with no research controls in the page builder.

Official-site discovery uses same-origin links, sitemap and navigation discovery, redirect and challenge detection, and CSS/font/logo extraction, with bounded official-domain search — not guessed paths.

Inspiration media is staged against the assistant session and deduplicated on import; unused session-created assets are cleaned up after a failed or cancelled build.

Preview and apply

Before apply, the proposal tree drives the site iframe using the same postMessage render contract the layout editor already uses for unsaved work. Custom types preview through a schema-driven field-kind fallback on journey-website. Previews are built from the same canonicalized content shape apply uses, so what is previewed is what lands.

Apply persists; preview does not.

Durable execution

Every user message gets a durable execution record, kept separate from conversation and session state, so a worker restart cannot destroy in-flight work while leaving a session visibly running.

  • Executions are claimed with renewable leases, heartbeats, attempt ownership, and guarded terminal transitions. Lease renewal is independent of model stream traffic.
  • Model, tool, capture, proposal, and apply checkpoints persist in order as work completes, rather than flushing the whole turn at the end.
  • Every consequential tool effect carries a stable idempotency identity and request digest, so replay cannot duplicate a CMS write.
  • Abandoned executions are reconciled after worker loss or deployment, resuming only from an unambiguous checkpoint and otherwise failing explicitly with a retryable reason.
  • Harness, prompt, tool-schema, and worker versions are recorded so deployments can drain or resume compatible executions.

The admin UI reconstructs progress from an authoritative execution snapshot and reconnects to ordered events, so it never shows an indefinite Working… state.

Budgets

LimitValue
Message length8,000 characters
Images per turn2, up to 5 MB each
Model to tool rounds per send24 (a ceiling, not a target)
Synchronous turn4 minutes
Asynchronous turn25 minutes
Execution attempts3
Total execution elapsed30 minutes

Server-side context compaction starts well before the model's one-million-token limit, preserving author intent, current proposal identity, and durable restart state.

Multi-page requests are recognized before generation. Supported page sets get a shared site plan and coordinated page jobs; anything else stops early and presents the one-page boundary before spending research or generation budget.

Real event timing, rounds, tool latency, token usage, capture status, proposal lineage, and apply outcomes are persisted for evaluation and support, with an eval-cms-assistant suite covering the authoring cases.

Source: api/src/core/cms/assistant/, api/src/core/cms/assistant/operations/operations.ts, api/src/core/cms/assistant/skills/skills.ts.

On this page