Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,9 @@ standing on its own.
Run the proof: `cargo run -p counter-cli`.

Next (see `docs/ARCHITECTURE.md` § roadmap O3–O6):
- `positron-ratatui` — terminal renderer reference impl (O3)
- `positron-lit` — Lit DOM reference renderer + regenerate `@positron/core` (O4)
- `positron-ratatui` — terminal renderer + `Host` event loop (O3, outlier A)
- `positron-wgpu` — one Rust GPU renderer for native (Metal/Vulkan/DX12) + web (WebGPU/WASM) + AR/VR (O4, outlier B — "web ≠ DOM")
- `positron-lit` *(optional)* — Lit DOM renderer for a11y / text-reflow (O4b)
- `ContinuumHost` (in continuum) — session ↔ Commands/Events, first real `ViewState` (O5)
- persona `Observer` → RAG/tool bridge (O6)
- Theme pack (Loki / Matrix / Fallout / Tron) ported from the cyberpunk-cli experiment
Expand Down
61 changes: 50 additions & 11 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,52 @@ not rewriting the widget.
acts via CommandEnvelope
```

> The boxes illustrate the **role** — every surface is a `Renderer<S>` projection
> of the same `ViewState`. They are *not* the primary-renderer choice: as
> § *Renderer paradigms are GPU-first* (below) makes precise, one Rust wgpu
> renderer covers web + native + AR/VR, so "DOM" and "native" are not separate
> surfaces but two of that one renderer's targets.

The four "environments" collapse to **two roles**:

| Role | Consumes | Produces | Surfaces |
|---|---|---|---|
| `Renderer<S>` | the `ViewState` | a surface tree | web (Lit DOM), terminal (ratatui), mobile (native), AR/VR (Bevy) |
| `Renderer<S>` | the `ViewState` | a surface (GPU frame / cells / DOM) | **wgpu GPU frame** — one Rust renderer running native (Metal / Vulkan / DX12), web (WebGPU, WebGL fallback, via WASM), and AR/VR (Bevy is wgpu underneath); terminal (ratatui); optional DOM (Lit, a11y/text-reflow) |
| `Observer<S>` | the **same** `ViewState` | perception → RAG, then `CommandEnvelope`s | AI persona |

The AI persona is **not a special case**. It is the fourth projection of the
identical `ViewState` — it perceives what a human sees, and it acts through the
same command vocabulary a human's host emits. That is the positron principle,
made structural.

### Renderer paradigms are GPU-first — "web" ≠ "the DOM"

`Renderer<S>`'s `type Output` is renderer-specific, so nothing in the contract
assumes a CPU text tree or a DOM. That is what lets the **primary** surface be a
single Rust **wgpu** GPU renderer that compiles to *every* paradigm from one
codebase:

| Paradigm | How the one wgpu renderer reaches it |
|---|---|
| Native desktop | wgpu → Metal (macOS) / Vulkan (Linux) / DX12 (Windows) |
| Web | wgpu → WebGPU (WebGL fallback), shipped as WASM — **same source** |
| AR/VR | Bevy, which is wgpu underneath |
| Terminal | `positron-ratatui` — CPU cells, a genuinely different `Output` |
| DOM | `positron-lit` — optional a11y / text-reflow surface, not the primary web story |

The DOM (Lit) and terminal (ratatui) are **peer paradigms**, not the definition
of "web" and "native." This makes the GPU renderer the real **outlier B** for
validating `Renderer<S>`: `counter-cli`'s `String` vs `Vec<String>` are both CPU
text (a weak outlier pair); a GPU draw-list/frame is maximally different and
proves the trait carries no hidden CPU-tree assumption.

This also means positron does **not** invent a new GPU path — it *converges*
with one continuum already has: continuum's avatar renderer is Bevy/wgpu emitting
backend-neutral `RgbaFrame`s over a crossbeam channel that LiveKit and PNG
consume without knowing Bevy (a `RenderBackend` seam). `SceneDescription`/
`RgbaFrame` (continuum) is the same shape as `ViewState`/frame (positron); the
two reconcile at **O5**, not by rewriting either.

## Separation of concerns — the layer boundary (the load-bearing part)

Positron **owns**:
Expand Down Expand Up @@ -99,7 +133,7 @@ does not carry.
| Concern | Home | Why |
|---|---|---|
| The four traits + wire + session | **positron** (`positron-core`) | consumer-agnostic contract; independently versioned (the "airc test") |
| Reference renderer crates (`positron-ratatui`, `positron-lit`) | **positron** | surface projections anyone in the problem domain reuses |
| Reference renderer crates (`positron-ratatui`, `positron-wgpu`, `positron-lit`) | **positron** | surface projections anyone in the problem domain reuses |
| Concrete `ViewState` types (`ChatViewState`, …) | **continuum** | domain vocabulary — positron never knows what a "chat message" is |
| Command vocabulary (360+ commands) | **continuum** | already the single source of truth; positron frames, does not define |
| `ContinuumHost` adapter (session ↔ Commands/Events) | **continuum** | binds the contract to *this* substrate's primitives |
Expand Down Expand Up @@ -134,21 +168,26 @@ the view from `ViewState` alone, the state type is incomplete — not the render
is the recommended default rather than a primitive-enforced necessity; DESIGN.md
leans the same way.
- **`@positron/core` (npm) + `positron-lit` vs continuum `sdk/typescript`: decided
at O4, not before.** Both generate types from Rust via ts-rs; whether the positron
web stack *subsumes* or *complements* the continuum SDK is resolved when the web
renderer actually lands.
at O4b, not before.** Both generate types from Rust via ts-rs; whether the positron
DOM stack *subsumes* or *complements* the continuum SDK is resolved when the Lit
renderer actually lands. (O4 is `positron-wgpu`, the GPU surface — it has no bearing
on the npm/SDK reconcile, which is the DOM stack's concern.)

## Organizational task roadmap (one PR per unit)

| # | Unit | Proves | Depends on |
|---|---|---|---|
| **O1** | This separation contract | the boundary is pinned before any renderer is written | — |
| **O2** | `examples/counter-cli` | renderer-agnostic **and** AI-perceives-same-state, in-process, zero transport (one `Counter` `ViewState`, ≥2 `Renderer`s, 1 `Observer`) | O1 |
| **O3** | `positron-ratatui` | terminal `Renderer` reference (outlier A surface) | O2 |
| **O4** | `positron-lit` | web DOM `Renderer` + regenerate `@positron/core`; reconcile with continuum `sdk/typescript` (subsume vs complement) | O2 |
| **O5** | `ContinuumHost` (in continuum) | positron session ↔ Commands/Events; first real `ViewState` (`ChatViewState`) flows to a positron renderer; resolves the two-wire merge question | O3 or O4 |
| **O3** | `positron-ratatui` | terminal `Renderer` reference + `Host` event loop (**outlier A**: CPU cells, real stateful surface) | O2 |
| **O4** | `positron-wgpu` | the run-everywhere GPU `Renderer` (**outlier B**: native Metal/Vulkan/DX12 + web WebGPU/WASM from one codebase) — proves `Renderer<S>` carries no CPU-tree assumption; the load-bearing web+native surface | O2 |
| **O4b** | `positron-lit` *(optional)* | Lit DOM `Renderer` + regenerate `@positron/core`; a11y / text-reflow surface where the GPU path isn't ideal; reconcile with continuum `sdk/typescript` (subsume vs complement) | O4 |
| **O5** | `ContinuumHost` (in continuum) | positron session ↔ Commands/Events; first real `ViewState` (`ChatViewState`) flows to a positron renderer; reconciles positron's frame output with continuum's existing `RenderBackend`/`RgbaFrame` GPU seam; resolves the two-wire merge question | O3 or O4 |
| **O6** | persona `Observer` → RAG/tool bridge (in continuum) | perception into cognition + action as `CommandEnvelope` — closes "AI persona rag/tool integration" | O5 |

O2 is the next unit: it makes this doc non-vapor by proving "one `ViewState`,
many renderers, plus an observer perceiving the same state" in a single process,
before any transport or substrate is involved.
O1 and O2 have landed: the boundary is pinned, and `examples/counter-cli` proves
"one `ViewState`, many renderers, plus an observer perceiving the same state" in
a single process, before any transport or substrate. **O3 is the next unit** —
`positron-ratatui`, the first real stateful `Renderer` + `Host` event loop
(outlier A), ahead of the GPU renderer (O4, outlier B) that makes the "web ≠ DOM"
claim real.
Loading