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

# ADR 0001: Separate language, protocol, and runtime

> Why Rixx UI separates model-facing source, canonical protocol records, and the rendering runtime.

# ADR 0001: Separate Language, Protocol, and Runtime

* Status: Accepted
* Date: 2026-07-22
* Decision owners: Rixx UI maintainers

## Context

Rixx UI must let language models create polished, interactive interfaces without
allowing model output to execute code or bypass host policy. The primary product
is a provider-neutral React response renderer. Progressive rendering and
protocol evolution remain important implementation requirements; model hosting,
chat sessions, and persistence belong to the host application.

A single representation cannot optimize equally for model generation, network
transport, durable storage, validation, and rendering. Deep JSON trees are
awkward to stream and repair. A custom text language is compact for models but
is a poor long-term interchange format. React elements are framework-specific
and unsafe as an external contract.

## Decision

Rixx UI has three independent layers.

1. Rixx UI Language is the compact, line-oriented format generated by models.
2. Rixx UI Protocol is the canonical stream of framed, versioned JSON records.
3. The runtime stores a normalized graph and renders only host-registered
   components.

The language compiler is the only supported path from model text to protocol
records. Protocol records are validated structurally, semantically, and by host
policy before a committed graph becomes authoritative.

## Language properties

* One complete statement per physical line.
* Stable assignment IDs and flat references rather than nested component trees.
* Named component arguments only.
* Forward references are legal within one transaction.
* Data, host-provided drafts, item scope, and host context use distinct
  reference roots.
* No raw HTML, JavaScript, CSS, generated SVG, network definitions, or
  executable expressions. Sanitized Markdown is permitted only as an explicit
  `RichText` payload. URL values never grant fetching or navigation permission.
* A full authored document starts with `@rui` and ends with `@commit`. The
  normal model-facing fragment contains assignments only; a trusted host
  supplies the envelope and commit after provider completion and authoritative
  validation.
* Model generation recovers at physical-line boundaries. Invalid statements are
  quarantined while the last safe provisional graph remains visible and inert.

## Protocol properties

* JSON tuples minimize repeated envelope keys while retaining standard parsers.
* A transport supplies framing: one record per SSE event, WebSocket message, or
  RFC 7464 JSON text sequence.
* Sequence numbers are contiguous and transaction-local.
* Every transaction names its base revision and commits exactly one new
  revision.
* Graph changes become authoritative atomically at commit.
* An abort record is terminal and never changes the committed graph.
* Snapshots and resumable transport are internal/advanced concerns, not required
  by the public source-renderer API.

## Runtime properties

* Components are stored by stable node ID.
* UI structure and protocol data live in the normalized snapshot. Context and
  draft values are read-only host inputs in the current renderer.
* Actions are declarative names emitted to the host; they contain no code or
  arbitrary network requests and Rixx UI does not execute them.
* Accessibility, focus management, responsive layout, and motion semantics are
  renderer responsibilities.
* Native declarative components render directly. Executable third-party apps
  require a separate-origin sandbox and are not part of the core language.

## Alternatives rejected

### Model-generated React, HTML, or JavaScript

Rejected because it creates an executable injection boundary, makes consistent
design and accessibility difficult, and prevents deterministic validation.

### One nested JSON document

Rejected as the model-facing format because incomplete output cannot be safely
consumed, deep delimiter balancing is fragile, and updates replace too much
structure.

### Custom DSL as the wire format

Rejected because protocol consumers should not need the model parser, and
durable records require stronger framing, versioning, and replay semantics.

### Positional component arguments

Rejected because inserting or reordering a catalog property can silently change
meaning while remaining syntactically valid.

### Sandboxing every native component tree

Rejected because trusted renderer code never executes payload code. Universal
iframes would degrade accessibility, focus, theme integration, and performance
without strengthening this boundary. Sandboxing remains mandatory for executable
extensions.

## Consequences

* The project maintains a parser and compiler in addition to protocol schemas.
* Language and protocol versions evolve independently from component catalogs.
* Model output can be optimized independently from the internal protocol.
* Protocol fixtures and the private Studio can replay without invoking a model.
* Additional renderers can consume the canonical graph without parsing the DSL.
* Validation errors can identify the exact statement, record, path, and policy
  that failed.

## Follow-up decisions

* Define catalog negotiation and compatibility rules.
* Define stable public package and theme contracts.
* Define optional media/widget asset policies.
* Define optional forms/draft behavior without moving persistence into core.
* Production hosts must define action authorization and confirmation behavior.
* Benchmark the DSL against target model tokenizers and constrained decoders.
