Network/Journal/Inline Ugc Cms Architecture
All entries
Entry 037

The contribution surface — a live editor, not wikitext, and never user code

Date
2026-06-05
Status
Decided
Authority
Creator

Decision

OLN rejected wikitext as a contribution surface (Entry 029, Entry 009). This is the replacement, and four architecture forks were settled up front because each one constrains the rest of the build:

  1. Editor engine — a block editor (TipTap / ProseMirror). Blocks map 1:1 to the rendered page (the "edit live" feel), with a mature extension API for custom nodes (entity references, structured fields, plugin blocks) and a path to real-time collaboration later.
  2. MDX is interchange, not the execution path — the security crux. UGC is never compiled or evaluated. The source of truth is ProseMirror JSON, rendered through a component allowlist under a strict CSP — no raw HTML injection. We serialize to and from a safe MDX subset only for export, diffing, and portability; anything unrecognised deserializes to an inert placeholder and never runs.
  3. Collaboration — presence + single-writer at launch. Live cursors and viewer presence, with a soft edit lock (heartbeat TTL, steal-after-expiry). No CRDT at launch; the block structure lets real-time co-editing drop in later.
  4. Plugins and themes — allowlist now, sandbox later. v1 runs no user JavaScript. A plugin is a manifest + field schema that configures an OLN-reviewed, allowlisted component; a theme is validated design tokens plus a checked asset bundle — no arbitrary CSS or JS. Both marketplaces ship day one over this safe substrate. The block API is data-in → vnodes-out and capability-gated, so a future sandbox can execute real user logic behind the same interface with no rewrite — built when creator demand for custom logic outweighs the cost of reviewing components.

Why

"User-extensible" at launch means extensible in data and configuration, not in logic. That is the trade that makes the security review tractable while still letting the plugin and theme marketplaces launch. Source-of-truth-as-JSON plus an allowlist renderer means there is no code path from user content to execution — the single most important property for a platform that invites strangers to author pages.

Open threads

  • The exact safe-MDX subset grammar — which marks and nodes round-trip.
  • Attribution rendering for user-uploaded theme and plugin assets.
  • The capability surface of the eventual logic sandbox (data in, vnodes out; no DOM, no network unless granted) — designed when the revisit trigger fires.

Related

  • Entry 029 — the Fact-grounded wiki thesis (why not wikitext)
  • Entry 010 — LoreLines as a third contribution surface
  • Entry 036 — the communities this editor authors
  • G-015 — Content authoring / editor interface
  • G-050 — Theme system and user-content security