> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stackra.figentra.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 0270 — Builder architecture: one editor kernel, document kinds and collaboration levels

> Accepted · 2026-10-21

> [!NOTE]
>
> Amends [0112](/adr/0112-experience-packages-and-renderer-kit) (X5 editor wording, X14 build
> order), [0114](/adr/0114-page-builder-for-every-page), [0115](/adr/0115-form-builder) (F3),
> [0122](/adr/0122-workflow-studio-three-layers) (layer 3 editor),
> [0086](/adr/0086-notifications-full-engine-all-channels-free) (template editor and the package),
> [0225](/adr/0225-realtime-drivers-co-editing-and-the-commentable-trait) (RT2 home) and
> [0127](/adr/0127-package-categories-including-infrastructure) (experience and communication rows),
> [0035](/adr/0035-resend-email-with-spf-dkim-dmarc),
> [0078](/adr/0078-messaging-layer-eight-packages), [0096](/adr/0096-trait-naming-grammar),
> [0117](/adr/0117-contracts-placement-and-decorator-ownership) and
> [0223](/adr/0223-notifications-channels-cascading-templates-manual-sends-and-preferences) (the
> dropped notifications package), [0084](/adr/0084-figentra-os-package-port-plan) (six port-plan
> rows), [0202](/adr/0202-stackra-pro-is-developer-side-os-capability-is-free-code) (decision 1, the
> studio area) and [0213](/adr/0213-settings-v2-cascade-flags-as-a-kind-yaml-packs-and-revisions)
> (decision 8, preferences owner). Each carries a note pointing here.

## Context

Pages, forms, dashboards, email templates, menus, automations and pricing rules each had their own editor in the ADRs, some
Pro, some free ([0202](/adr/0202-stackra-pro-is-developer-side-os-capability-is-free-code) has since made every editor free
code unlocked by an app entitlement). Separate editors would each rebuild selection, undo, drag and drop, preview, comments
and publishing, and would drift apart. Co-editing with cursors is costly and only pays off on long free-form documents. The
owner settled the architecture on 2026-10-21.

## Decision

1. **Every builder saves an L2 document** ([0110](/adr/0110-experience-is-the-sdui-service-at-l2)): data that references
   registered code, never code, markup, CSS or logic ([0154](/adr/0154-tenant-code-runs-only-in-a-sandboxed-code-step)). One
   format, one validator and one set of renderers, in `@stackra/experience` ([0112](/adr/0112-experience-packages-and-renderer-kit)).

2. **Every builder document is a content type** of `@stackra/content` ([0116](/adr/0116-content-types-and-custom-fields)):
   draft, versions, publish, scheduled publish, i18n, SEO and permissions come from there.

3. **The palette is code.** Components and blocks are registered in code (`@Block`, panel `Blocks.*`) and published by the gen
   manifests ([0109](/adr/0109-registry-manifests-published-by-ci)).

4. **`@stackra/builder` (category `experience`) is the one editor kernel**: selection, an inspector generated from each block's
   Zod props, an undo and redo command stack, drag and drop, preview per device, locale and breakpoint, comments (`@Commentable`,
   [0225](/adr/0225-realtime-drivers-co-editing-and-the-commentable-trait)), the presence and co-edit binding, and the publish
   flow. Its surfaces are canvas, document (a block editor with slash commands), grid, tree and graph. It is separate from
   `@stackra/experience` so that render-only apps never load editor code.

5. **`@stackra/collaboration` (category `experience`) is free, on `@stackra/realtime`**: presence, cursors, the Yjs binding and snapshots. It implements
   0225 RT2 and is gated by entitlement per 0202. The Pro-only `@stackra-pro/collaboration` listing is dropped.

6. **Document kinds, surfaces and collaboration levels.** Co-editing with cursors is only for long free-form documents;
   structured documents get presence and optimistic concurrency control (OCC).

   | Kind | Surface | Drag and drop | Collaboration |
   | - | - | - | - |
   | page, screen, app-shell | canvas | yes | full (Yjs co-edit, presence, cursors) |
   | post, article, help article | document | reorder | full |
   | form | field list and logic panel | reorder | presence + OCC |
   | dashboard | grid | yes | presence + OCC (data refreshes live; editing is not co-edited) |
   | email and notification template | document, email-safe blocks only; rendered by the node renderer | reorder | presence + OCC |
   | navigation and menus | tree | reorder | OCC |
   | automation ([0122](/adr/0122-workflow-studio-three-layers) layer 3) | step list or graph, with dry run | yes | presence + OCC |
   | pricing rules ([0219](/adr/0219-the-merchant-account-chain-and-registered-price-models)) | block composer | no | OCC |

7. **New document kinds**: `app-shell` (navigation, home, theme and branding, route-to-page mapping), `screen` (mobile) and
   `email-template`.

8. **The page builder builds the app's experience, never its data, rules or code.** It builds pages, screens, the app shell and
   document slots in coded routes (`@Route({ document })`). It does not build data models (custom fields only; tenant content
   types stay later per 0116 decision 6), business rules or code. There are three levels: coded screens, coded screens with
   document slots, and fully document pages.

9. **One studio app area in the console hosts every editor.** Each kind is unlocked by an app entitlement (0202). This replaces
   the separate page-builder-and-forms app, the dashboard studio and the notifications editor.

10. **No report builder.** Reports are saved views ([0271](/adr/0271-saved-views)), `@Report` widgets
    ([0163](/adr/0163-reports-exports-imports-and-declared-read-models)) and dashboards. There is no tenant SQL or pivot engine
    (0154).

11. **Build order** keeps 0112 X14, with the kernel landing before the first editor.

12. **Package changes.** `@stackra/forms` is dropped: coded forms use `@stackra/ui/form` (`useSchemaForm`), and the form builder
    is a document kind on `@stackra/builder`. `@stackra/notifications` is dropped: notifications is a service
    (`@figentra/service-notifications`) that owns delivery, preferences, the log and the in-app inbox, and direct email goes
    through the `Mailer` driver in `@stackra/mail`.

13. **Forms can be multi-step.** A form document may have steps, a progress indicator, conditional steps, save-and-resume of a
    draft submission, and a chip multi-select field. The `@stackra/ui` contract gains a Stepper. Onboarding wizards are form
    documents of this shape.

## Consequences

* One editor to build, secure and test; each new kind is a surface configuration and a block set, not a new editor.
* Render-only apps stay small, because editor code lives only in `@stackra/builder`.
* Yjs runs only where it pays off; structured documents keep the simpler version check.
* The kernel is on the critical path: no editor ships before it.
* ADRs and docs that name `@stackra/forms`, `@stackra/notifications` or a Pro editor are stale and must point here.

## Enforcement

planned — the experience validator refusing a document of a kind whose blocks are not registered; a bundle check that a
render-only app does not depend on `@stackra/builder`; `FORBIDDEN_DEPENDENCIES` or the scaffold refusing new
`@stackra/forms` and `@stackra/notifications` packages. Nothing checks this today.

## Supersedes and sources

Supersedes: none. Amends: 0112, 0114, 0115, 0122, 0086, 0225, 0127, 0035, 0078, 0096, 0117, 0084, 0202, 0213 and 0223 (see the note above). Sources: owner decisions in chat,
2026-10-21 (builder architecture; D5 package amendments; multi-step forms from the screenshot review). Linear STA-274.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.