# Experience and presentation

One keeps presentation meaning separate from any renderer. A place, an intent, a
complete page snapshot, renderer-local state, and the canonical operation states
are owned values that several languages and targets can share. Which framework
or target actually paints, dispatches, or hydrates them remains a removable
physical choice.

Experience is currently active only as a bounded cross-language slice. This page
describes that slice and the hold around it; it does not describe a general UI
framework or an Experience authoring grammar, and neither exists today.

## Renderer-neutral identities and one complete snapshot

The shared values are:

- `PlaceId` and `IntentId` — non-zero `u128` identities for a conceptual place
  and a user goal;
- `Page<T>` — one complete snapshot of a place together with its canonical
  operation state, never a partial patch a renderer must reconcile;
- `Local<T>` — explicitly renderer-local presentation state that is not part of
  the page snapshot and carries no domain meaning;
- `View` — the completion boundary that exposes the concrete document type
  without selecting HTML, a host, an operation binding, or authority; and
- the canonical operation-state vocabulary below.

Identity is nominal. Two structurally similar pages under different owners do
not become one page, and a renderer cannot mint a place or intent from a route,
a component name, or rendered HTML.

## Canonical operation states

Every realization consumes the same three state families.

`ResourceState`: `Empty`, `Loading`, `Ready`, `Refreshing`, `Stale`, `Offline`,
`Failed`.

`CommandState`: `Idle`, `Validating`, `Pending`, `Succeeded`, `Rejected`,
`OutcomeUnknown`, `Reconciling`, `Cancelled`, `Defect`, `Failed`.

`SubscriptionState`: `Connecting`, `Current`, `Reconnecting`, `GapDetected`,
`Resnapshotting`, `Exhausted`, `Revoked`, `Failed`.

The mappings are fixed, not renderer discretion:

| Real outcome | Canonical state |
| --- | --- |
| Declared domain failure | `Rejected` |
| Cancellation | `Cancelled` |
| Lost response after an effect may have committed | `OutcomeUnknown`, retaining the effect reference |
| Stream gap after a cursor | `GapDetected`, then `Resnapshotting` |
| Violated invariant | `Defect`, retaining an incident reference |

Only an `Idle` command may begin dispatch. An `OutcomeUnknown` retains its effect
reference and cannot be redispatched implicitly; the only forward path is
explicit reconciliation. A stream gap is never smoothed over as continuity. A
renderer may present target-specific detail but cannot reinterpret these states
as a generic error without a declared semantic loss.

## Two transparent language bindings

Rust exposes `one::experience`; TypeScript exposes `@one/experience`. Both carry
the same owned meaning rather than defining a second Experience model.

The TypeScript binding enforces the same unknown-outcome no-redispatch rule
through finite pure state helpers: non-zero place and intent identities, complete
snapshots, renderer-local values, an idle-only dispatch guard, and retention of
an unknown outcome's effect reference. It owns no async runtime, operation
transport, framework store, retry policy, or authority.

## Physical facades

Web delivery is a separate physical facade:

- Rust's opt-in `one::web::server` composes the deterministic escaped server-HTML
  adapter with one fixed host. Its routes are exactly `GET /`, `POST /submit`,
  `GET /style.css`, and `GET /health`. It sends no JavaScript or browser runtime,
  performs no hydration, and carries no authority. A finite server-HTML
  projection of the headless viewer frame is also available as
  `one::web::server::viewer_document`.
- TypeScript's `@one/web` maps one selected page and command state to finite inert
  DOM attribute records and decodes bounded, duplicate-free, text-only browser
  `FormData`. React/Next remains application-selected and keeps its own routes,
  components, state, layout, and interaction behavior.

Neither facade selects an operation implementation, provider, transport, or
authority. Ordinary applications that make no Experience claim should use their
framework directly, as described in [applications](/one/guides/applications).

## Desktop over a real data plane

Rust's opt-in `one::desktop` composes place, intent, page, local, view, and
canonical command-state identities with the removable desktop renderer adapter's
headless frame: top bar, tile viewport, blueprint tree, selection panel, time
panel, command-palette index, and welcome/toast state, together with spatial
2D/3D, time-series, bar, dataframe, graph, map, tensor, text-document, text-log,
and state-timeline views.

Ownership is split so no adapter becomes the meaning owner:

- Data owns entity paths, timeline and time coordinates, and the ported columnar
  chunk and query model;
- Experience owns geometry, cameras, ruler axes, selections, blueprints,
  playback, views, and design semantics; and
- the adapter owns only its finite headless panel and view mapping plus its
  explicit losses.

The facade owns only the fixed present and dispatch composition. The executable
consumers are the adapter's `one-desktop` binary, the facade-only dummy viewer
fixture, and `products/rerun`. The removable `one-provider-desktop-egui-host`
realizes the same frames in a native window and is selected per root; a
first-party renderer or UI may replace it behind the same owned contracts.

This desktop frame reads the data plane described in
[the ported data plane](/one/model/ported-data).

## The Experience hold

Outside the bounded cross-language and ported-desktop slice above, the
Experience hold applies. It prohibits, until the hold is lifted:

- new Experience declaration grammar;
- automatic Experience-to-document lowering;
- a shared client runtime or hydration;
- unrelated framework abstraction or adapters;
- additional renderers beyond the named desktop provider; and
- generalized cross-target conformance machinery.

The hold ends only through an owner-approved update to the root `AGENTS.md` and
`systems/experience/AGENTS.md` after an executable consumer demonstrates a
repeated renderer-independent need that existing operations, schemas, SDKs,
components, and ordinary framework code cannot satisfy. Merely declaring that a
target could be realized does not place its framework or capabilities in another
root's closure.

One Cloud, the public website, documentation, and dashboards MUST NOT depend on
Experience contracts merely to dogfood One. They use ordinary application
frameworks and integrate through the narrow public One contracts they actually
consume.

## Demonstrated example

The snippet below is drawn from the demonstrated Rust facade and its physical
server host; `Page::new` and `one::web::server::view!` are exercised by the
standalone Order Review Web product. It is a fixed composition, not an
authoring grammar.

```rust
use one::experience::{CommandStateKind, IntentId, Page, PlaceId};
use one::web::server::{Document, view};

fn order_page(state: CommandStateKind) -> Document {
    let page = Page::new(PlaceId::new(1).unwrap(), state);
    view! {
        page: &page,
        title: "Order Review";
        <h1>{"Order Review"}</h1>
        <button intent={IntentId::new(1).unwrap()}>{"Review order"}</button>
    }
}
```

Follow [One Web](/one/guides/one-web) for the fixed routes and
[Build a Rust One Web application](/one/examples/one-web) for the complete
standalone product.

## There is no Experience authoring kind today

There is no `experience`, `place`, or `intent` declaration kind to author in
`.one` today. The active slice consumes existing owned identities through the
Rust and TypeScript bindings; it does not add declaration grammar. A future
grammar would require the owner-approved update described in the hold.

Next: read [the ported data plane](/one/model/ported-data) or
[root and composition](/one/model/composition).

## Normative owner & evidence

The normative owner is
[systems/experience/AGENTS.md](https://github.com/muijf/one/blob/main/systems/experience/AGENTS.md),
under the repository composition law in
[AGENTS.md](https://github.com/muijf/one/blob/main/AGENTS.md).

Demonstrated today: the `one::experience` and `@one/experience` bindings and
their canonical states and dispatch guard; the `one::web::server` fixed-route
host; the `@one/web` inert DOM and `FormData` mapping; the `one::desktop`
headless frame over the removable adapter; and the named `one-desktop`, dummy
viewer, and `products/rerun` consumers, each with owning tests.

Illustrative or deferred: any `experience`, `place`, or `intent` `.one`
declaration kind, automatic Experience-to-document lowering, a shared client
runtime or hydration, additional renderers, and generalized cross-target
conformance. The `AGENTS.md` prose that describes broader lowering, modules, and
renderer providers defines the owned boundary and validation shape, not a claim
that those integrations can be selected today.
