# V10 — Architecture (The Rail: The Ambient Companion Surface)

Status: concept-stage architecture, derived from the originating design document
[`V_SERIES_AMBIENT_RAIL.md`](V_SERIES_AMBIENT_RAIL.md) (this directory,
2026-07-16; decisions D1–D8 settled) and its implementation breakdown
[`V_SERIES_AMBIENT_RAIL_TODOS_2026-07-16.md`](V_SERIES_AMBIENT_RAIL_TODOS_2026-07-16.md).
Implementation has begun against this shape (the `libs/contracts/src/v10`
channel contract, the first `libs/v10/rail-kernel` policy modules, and the
V1-side ring-opt-in persistence models are in the tree); this document records
the decided shape the implementation checklist builds toward, and the existing
substrates it composes. Code namespaces (decided): `libs/contracts/src/v10`
(contract), `libs/v10/rail-*` (kernel + channel adapters), `apps/v10/shell`
(Tauri) and `apps/v10/web` (UI).

## 1. Position in the portfolio

V10 is a **venue, not a content producer**. Nine products publish ambient
channels into one companion surface through one contract; V10 owns composition,
batching, arbitration, and policy. Two prior decisions shape everything
structural:

- **D8 — V10 is its own product.** The attention arbiter is not owned by any of
  the nine contestants; V1's domains publish house channels under the same
  contract as every other V.
- **D7 — identity stays on V1.** Channel subscriptions, loudness grants, daypart
  overrides, and ring opt-ins persist on V1's account/entitlement graph (the
  consolidation audit's assignment), reached through `apps/oshun/bff`. The shell
  owns nothing account-shaped.

The consolidation constraint is architectural, not aspirational: the platform
audit's duplication census (7 matchmaking implementations, 5 rollback, ~6
battle-pass, 3 voice/SFU, 2 C2PA signers) is why the channel contract, the
streaming substrate, and the signer are each built exactly once, and why the
video lane generalizes Aphrodite's stack instead of growing a parallel one.

## 2. The channel contract (`libs/contracts/src/v10`)

Every V publishes a channel by implementing five primitives, expressed as zod
schemas with policy encoded at the type level wherever possible:

1. **Presence tile** — the 2-second-legible "now" render. Schema-required
   capabilities: renders meaningfully from cold cache, degrades to text-only,
   and `autoplayMotion: false` is the only accepted manifest default.
2. **Drip events** — discrete timestamped happenings emitted into one merged
   timeline. The event type carries **no priority or interrupt field**: channels
   structurally cannot request interruption; batching and delivery timing are
   Rail daypart policy.
3. **Micro-acts** — ≤30-second interactions executable in-Rail, with a
   schema-enforced duration budget and a deep-link fallback for acts that
   outgrow it.
4. **Dual faces** — `{ spectator: TileSpec; player?: TileSpec }`; spectator is
   mandatory (the front-door audience comes first), and the Rail selects the
   face from entitlement state.
5. **Live moments** — typed elevation _requests_ (`scheduled | emergent`) with a
   rate-limit class; the user's standing per-channel grant decides, never the
   channel.

The manifest composes these with a ring assignment (`wellness | games | adult`),
a per-surface availability matrix (the schema rejects an adult-ring channel that
claims mobile/watch/tv), lane source specs, daypart affinities, and
context-carrying deep links (bare product-root links are rejected — every dive
lands inside the moment that prompted it).

## 3. The policy kernel (`libs/v10/rail-*`)

The kernel is where "calm by default" stops being a slogan and becomes
enforcement:

- **Loudness engine** — `effective = min(daypart ceiling, channel grant)` (0–3),
  user-pinned exceptions, default grant 1, elevation budgets per channel per day
  with no accumulation.
- **Daypart engine** — the choreography spine (morning brief 2 · deep work 1 ·
  breaks 2 · lunch 3 · wind-down 3), user-tunable, with a fail-loud
  `CalendarSource` seam until calendar awareness ships; the audio lane is exempt
  from the deep-work clamp.
- **Timeline** — merged ingest, daypart-driven batching (deep work holds, breaks
  flush), per-channel rate slices **and** a global drip budget; overflow
  degrades to per-channel rollup entries, never silent drops.
- **Live-moment arbitration** — grant-3 (or pinned) + budget + daypart + ring
  must all pass; every grant/denial is recorded for the calm SLO.
- **Rings and walls** — three brand rings; each adult-ring wall clause
  (directory exclusion, recommendation exclusion, surface matrix, daypart lock,
  Ori-input exclusion, watch-party exclusion, cross-promo exclusion) is an
  individually tested check. A gambling-adjacency guard rejects any micro-act
  schema with value-in/value-out semantics.
- **Discretion kernel** — `off | text-only | hidden`, a synchronous `panic()`
  transition bound to a global shortcut, and screen-share auto-engage that
  collapses personal tiles to neutral text with no auto-restore.
- **Calm metrics** — docked-hours, micro-act completion quality,
  voluntary-return rate, calm SLO. The interrupts-clicked counter does not exist
  in the module, and a test asserts the exported metric set equals the allowed
  list — the anti-engagement lock installed before launch, not after.

## 4. Lanes

**Audio lane:** exactly one holder at a time; the Rail is the mixing desk. The
API offers channels no "grab" verb — handoffs happen only on user action or
daypart transition. Brief voice interjections (Ori) are time-boxed ducking
overlays a holder declares support for, not a second holder. Candidate holders:
V3 adaptive work-music, V5 diegetic period radio, match commentary, Ori's voice,
the Veritas audio briefing.

**Video lane:** one primary holder, same arbitration, three content classes:

1. **First-party live** — HLS/DASH from the shared streaming substrate (§7);
   until that substrate is extracted the class reports `not_configured` and no
   channel may declare it (an honest fail-loud seam, not a fake player).
2. **Overlay / second-screen** — the video plays wherever it plays (YouTube,
   broadcast TV); the Rail runs the synced companion layer against an external
   clock, e.g. the Veritas live claim-verification ticker.
3. **Docked third-party** (decision D5) — the user's own YouTube/Twitch embed
   lives in the lane via official embed APIs. We host the slot geometry; we do
   not moderate the content. No-autoplay invariants apply to embeds too (muted +
   paused-until-user-acts at loudness ≤2).

**Attention-aware director profiles:** the V4/V5 auto-direction pipelines gain
two data-driven cut grammars — **ambient cut** (wide shots, slow cuts,
commentary murmur or off) for deep work and **highlight cut** (fast cuts,
replays, full commentary) for breaks and evenings — switched by daypart or by
the user. This is the concrete mechanism that makes a video lane compatible with
calm-by-default, and it is developed against Veritas/V3 Stage streams before any
game channel exists.

## 5. The shell and the surface family

The desktop shell is **Tauri** (Rust core; decision D7 — smaller resident
footprint than Electron, consistent with the portfolio's Rust investment)
hosting the same web UI that ships as the P1 browser/PWA fallback. Window
behavior is the product: narrow launch sized to the monitor's work area, edge
docking, state persisted across restarts, always-on-top, tray/menu-bar presence
with tile glance lines and audio transport that outlives the panel, global
shortcuts (discretion `panic()` works unfocused), and native screen-share
detection feeding the discretion kernel — platforms without a capture signal
report `{ supported: false }` honestly. A typed IPC bridge contract (also in
`libs/contracts/src/v10`) keeps web and Rust in lockstep. Mobile renders the
timeline as a feed plus second-screen mode; watch is a pure glance satellite
(one tile, haptic-gentle alerts); TV/cast is the video lane full-screen and the
watch-party end state.

## 6. Identity, entitlements, persistence

All Rail user state — subscriptions, grants and pins, daypart overrides,
discretion preferences, ring opt-ins with audit trail — lives on V1's graph
behind `apps/oshun/bff` endpoints, following the BFF's existing composer
conventions. Face selection is a pure function of the channel manifest and the
user's entitlement state. The adult-ring opt-in path requires an
age-verification assertion from Aphrodite's own age-verification service and
throws `not_configured` until that integration lands (fail-loud, never
fail-open).

## 7. Subsystem → existing-code map

V10 is a re-aiming of substrates the portfolio already built (readiness per the
2026-07-13/14 content audits):

| Rail component        | Existing substrate                                                                                                      |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| Video lane infra      | `apps/aphrodite/*` — 17 deployable streaming services, generalized as the shared substrate; Aphrodite becomes tenant #1 |
| Auto-direction        | V4 commentary/director pipeline; V5 broadcast-director + highlight ranker (gain the two cut profiles)                   |
| Case channel          | `libs/v8/case-*`, `libs/yemaya/case-*` — CSP/DPLL uniqueness proofs, solve-first generation, Ed25519 receipts           |
| Learning cadence      | `libs/v9/*` — real FSRS/SM-2/IRT; the Rail is the consumer surface that cadence was missing                             |
| Trust/provenance      | Veritas 9-factor source scoring; `@oshun/content-signing` (the one canonical C2PA signer)                               |
| Presence/consent      | V6 consent architecture and Ori continuity guarantees — governance for everything presence-shaped                       |
| Fighting bridge       | `libs/shakti/fighting-ruleset-bridge` — Ghost Dojo's spine                                                              |
| UGC/economy           | `libs/maya/crucible-*` (incl. `crucible-live`), the Mawu economy sim                                                    |
| Morning ritual        | The Thread (V1 review §4.1/§5.1) + the Veritas audio briefing                                                           |
| Identity/entitlements | V1 account/entitlement graph via `apps/oshun/bff`                                                                       |

Complete-but-uncited assets flagged by the consolidation audit —
`libs/aphrodite/*` game-bridge adapters, the Calliope stage spec, Concordia —
are audited for reuse before anything overlapping is written.

## 8. Phases

- **Phase A (P0)** — the Rail exists: shell, tiles, timeline, loudness,
  dayparts, both lanes with third-party docking, discretion; four pilot channels
  (V8 Case Files anchor, V9 Wonder & Recall, V3 Motion, V3 Stage).
- **Phase B (P1)** — Veritas Live overlay-first (rights-light), Ori Presence
  believability beta behind a default-off flag with a hard inference-cost
  ceiling, proper extraction of the Aphrodite streaming substrate, browser and
  mobile surfaces.
- **Phase C (P2)** — the game broadcast wave as games ship: Ghost Dojo League,
  Realm Surf / My Realm (creator tile first), Period Channel (newspaper + radio
  before world windows), Match Channel; director cut profiles land here but are
  exercised earlier.
- **Phase D (P3)** — watch/TV satellites, watch parties, the Aphrodite adult
  ring behind its full wall, calendar-aware dayparts.

Gating philosophy: a channel that drips nothing is worse than no channel, so
Phase A channels were chosen because their engines are demonstrably real; the
magnetic-but-uncooked concepts (Ghost Dojo) are announced as destinations and
never gate the Rail.

## 9. What is genuinely new vs. composed

**New:** the channel contract and its policy-at-the-schema-level enforcement;
the loudness/daypart/timeline/arbitration kernel; the Tauri shell and its
window-management product surface; discretion mode with screen-share
auto-engage; the calm metric set with its structural anti-engagement lock; the
ring walls as tested code.

**Composed:** everything that plays inside it — cases, spaced repetition, music,
stages, verified news, companions, leagues, realms, worlds, streams — which is
precisely the point: the fastest route to daily relevance is not finishing nine
cathedrals, it is claiming the sidebar slot with one calm surface each V feeds
at whatever fidelity it can honestly sustain today.
