# Cross-Platform, Rollout & Launch

V6 — **Egbe, the Agentic Companion Universe** — does not ship once. It ships one
Unreal Engine 5.5 client across nine platforms, a Pixel-Streaming web path, and
a three.js fallback; it opens **region by region** under a different rating
board and residency rule in each; and it runs a _population of generated minds_
— every companion is an Ori whose three-tier cognition calls a hosted model —
across a private Solo homestead, drop-in Co-op, and one persistent shared
Commons. The operational question is therefore not "does the feature work?" but
"is _this_ build cooked and certified for _this_ device, in _this_ region, with
an agent's biography following the player across every surface without forking —
and is the launch gate honestly green?" This page answers that: how one
household follows a player across desktop, console, mobile, VR, web, and the
Steward App (**cross-platform & cross-progression**); how GA opens in staged
regions over a shared world of minds (**region rollout**); and how a single,
unforgeable **exit-criteria gate** aggregates all of it. The defining difference
from V3 and V5 — whose launch gates are correctly **red** — is that V6's reads
**green**, because V6 was driven to completion and the green is wired to be
unforgeable, with the live-ops, external-cert, and cross-game boundary held
honestly at `[~]`. Each claim below is pinned to the code that enforces it, or
labelled honestly where the artifact is captured policy rather than a runtime.
Its architecture companion — the build/cook pipeline, the eval gates, the
residency enforcer, and the de-fenced launch verifier in engineering depth — is
[../architecture/performance-build-security-testing-and-launch.md](../architecture/performance-build-security-testing-and-launch.md);
the design posture it descends from is
[./overview-and-design-posture.md](./overview-and-design-posture.md); the WCAG,
localization, and region-rating gates a region must clear are
[./accessibility-and-localization.md](./accessibility-and-localization.md). The
feature hub this page belongs to is [../V6_features.md](../V6_features.md).

## What ships, honestly

The **cook matrix is machine-checked, not a cook log.**
`V6/ue/Build/validate_v6_cook_matrix.py` parses the BuildGraph
(`V6/ue/Build/Build.xml`) and the engine `.ini`s _without executing a cook_ and
proves coverage exists for **seven client platforms** (`Win64`, `Mac`, `Linux`,
`PS5`, `XSX`, `IOS`, `Android`) and **two Pixel-Streaming-worker platforms**
(`Win64`, `Linux`): each must own a `Cook V6 Client <P> Shipping` node carrying
`-build -cook -stage -pak -archive -map=$(PlayableMap)` and a `Boot … Shipping`
node running `UE.BootTest`. The **tier router is real and composes V3's**:
`resolveV6TierRoute` (`apps/oshun/bff/src/v6/tier-router.ts`) reuses
`resolveV3LilithLaunchDecision` and chooses native / Pixel Streaming / Tier-2 by
device capability, bandwidth, and POP RTT. The **cross-progression continuity
gate is green on real Ori-service code** — there is no per-platform save file to
reconcile. The **region/residency posture composes the shared
`@oshun/data-residency` enforcer**, not a V6-private copy.

Two honest qualifications carry the page. **First**, the cross-platform
_certification_ verifier proves **structural readiness** — green checklists,
package-signing traceability, BuildGraph cook/boot coverage, build-size-gate
linkage — but **cannot prove a vendor approval**, which is an external
real-world outcome; `V6/release/CROSS_PLATFORM_CERTIFICATION.md` says so in its
own provenance caveat, and §45 stays `[~]`. **Second**, the sustained-load,
Commons-scale, and Moirai launch-DAU cost runs are real specifications with
verifiers, but executing them needs **live regional infrastructure**, so those
rows stay `[~]`. With both named, the **exit-criteria gate is honestly green**:
the backlog is **215 `[x]`, 8 `[~]`, and a single fenced template `- [ ]`** the
verifier strips before counting.

## Cross-platform support

V6 has no platform-specific account and no platform-specific progression. A
player is one identity everywhere, and the code makes "everywhere" concrete
across the device ladder V6 reuses from V3 (features§"Cross-Platform Clients").

### One UE5 client, nine platforms and two web tiers

The canonical client is a single UE5.5 LTS project at `V6/ue/` producing native
binaries for Windows, macOS, Linux, PS5, Xbox Series X, iOS/iPadOS, Android,
Quest 3, Vision Pro, PSVR 2, and SteamVR, plus a headless
`V6PixelStreamingWorker` target for the streaming fleet.
`validate_v6_cook_matrix.py` is the gate that keeps that promise checkable:
beyond the per-platform cook/boot nodes, its `validate_config` step asserts
`DefaultGame.ini`'s `[V6.CookMatrix]` lists exactly the seven client and two
worker platforms, names the `V6` and `V6PixelStreamingWorker` targets, and
places **all ten Game Feature roots** — the six Districts
(`/V6District_GroveOfBeginnings` … `/V6District_Thresholds`) plus the four modes
(`SoloHomestead`, `CoopVisit`, `Commons`, `Incarnation`) — in
`DirectoriesToAlwaysCook`. It proves the worker boots headless
(`-RenderOffScreen`) and that `PixelStreaming.ini`'s `WorkerLaunchFlags` carry
`-Unattended` and `-PixelStreamingEncoderCodec=H264`. The XR targets are cooked
through dedicated profiles under `V6/ue/Build/CookProfiles/`
(`Quest3_OpenXR.json`, `VisionPro_OpenXR.json`, `PSVR2_OpenXR.json`,
`SteamVR_OpenXR.json`). Two readers must agree — the BuildGraph XML and the
`.ini` config — so a drifted cook target fails the build rather than silently
shipping a platform that was never cooked.

### The tier router — native, Pixel Streaming, Tier-2

The decision of _which_ client a given device gets is a BFF route, and it does
not reinvent V3's. `resolveV6TierRoute` imports `resolveV3LilithLaunchDecision`
from the V3 Lilith launch route and layers V6's streaming readiness on top:
Pixel Streaming is offered only when bandwidth clears
`V6_PIXEL_STREAMING_MIN_BANDWIDTH_MBPS = 15` and a relay POP is inside
`V6_PIXEL_STREAMING_POP_RTT_BUDGET_MS = 60`, selecting a codec by the priority
`['AV1', 'H264']`; otherwise the router falls to the Tier-2 three.js/WebGPU
fallback. Crucially, the _agent simulation is identical across tiers_ — the same
world wire protocol, the same Ori service, the same Moirai cognition serve every
client; only rendering fidelity and the agent-density ceiling differ, with the
Tier-2 fallback backfilling culled agents with Clio narrative summary
(features§"Cross-Platform Clients"). The route is exercised by the BFF
integration tests the `verify:v6 tier-router` gate pins.

### Cross-progression is intrinsic, not bolted on

Because the Ori service is the single authoritative record of who every agent
is, there is no per-platform save file and therefore nothing to reconcile. The
`verify:v6 cross-progression-continuity` gate
(`V6/release/cross-progression-continuity.v6release.json`) proves it on real
Rust: the manifest pins `PartitionedPostgresOriEventStore` as the authoritative
store, sets `perPlatformSaveFilesAllowed: false` and
`saveReconciliationRequired: false`, and requires
`sameContinuityHashAcrossPlatforms: true`. Three platform switches are tested —
`ios-to-steam`, `quest-to-steward-app`, and `web-to-psvr2` — each asserting
household, roster, reputation, and homestead are portable with a matching
`continuity_hash`. The verifier
(`scripts/v6/verify-v6-cross-progression-continuity.mjs`) binds this to named
functions in `apps/v6/egbe-ori-service/src/lib.rs`
(`verify_ori_cross_platform_continuity`, `portable_continuity_snapshot`) and a
Rust test
(`cross_platform_switch_preserves_household_roster_reputation_and_homestead_without_save_reconciliation`),
and it **self-tests its fail-closed seam** by cloning the manifest, flipping
`saveReconciliationRequired` to true and drifting a `continuityHash`, and
asserting the verifier would reject both. A player who reads the Chronicle on
the Steward App at noon, plays the native client in the evening, and continues
through the web path sees one continuous household — this is the gate that makes
that unforgeable. This task is `[x]`.

### Cross-platform certification — structural readiness vs. external approval

The certification gate (`scripts/v6/verify-v6-cross-platform-certification.mjs`,
evidence `V6/release/cross-platform-certification-validation.json`) requires
green checklists for **eight platform records across six vendors** — Apple
(iOS/iPadOS, visionOS, Mac App Store), Google Play, Meta Horizon, Sony PSVR 2,
Valve SteamVR, and the Epic Games Store. Its `expectedByPlatform` table binds
each record to a checklist id, a package kind and extension (`.ipa`, `.aab`,
`.pkg`, `.depotmanifest`, …), and a `buildSizePlatformId`, and the verifier
fails closed when a record references a BuildGraph cook/boot node **not present
in `V6/ue/Build/Build.xml`**, a build-size platform whose CI status is not
green, a missing signing profile or store submission id, or — for Sony — a
`trcStatus` that is not `signed_off`. That is genuine structural enforcement.
What it **cannot** do is prove a vendor approved or published the app: as
`V6/release/CROSS_PLATFORM_CERTIFICATION.md` states, "the local verifier does
not call private store APIs," and "no App Store / Google Play / … approval or
publication can have occurred for an unreleased product." So the page reports
the honest split — the repo proves _structural readiness_; the approvals
themselves are external outcomes re-verified at submission time, and §45 ("Pass
platform cert for Apple, Google, Meta, Sony, Valve, and Epic") is held at `[~]`.

One datum crosses a _game_ boundary rather than a _platform_ one: the Aye
passport. `minimisePassportForDestination` (`libs/v6/aye-bridge/src/index.ts`)
strips identity and bond fields the destination does not need —
`metadata.userId`, `identityCore.name.canonical`, `bondLedger.historyRef`, and
more — and surfaces any _missing required_ field before the crossing, so an
agent incarnating into V2–V5 carries only destination-needed data.

## Region rollout

GA does not mean global. V6 opens in staged regions, and the V6-specific
concerns follow from two facts: it runs a population of LLM-driven minds, and
the Commons is one persistent shared world (features§"Region Rollout Strategy").

### Staged regional GA over a population of minds

Each region comes online only when its **per-region Moirai cluster**, its
**regionally sharded Commons**, and its Pixel-Streaming POP coverage are
provisioned and its residency posture is verified. Moirai is deployed per region
for two reasons that are the same reason: a Clotho agent's live dialogue must
round-trip fast, and an agent's cognition reads its residency-tagged Ori, so the
cognition runs where the data is allowed to live. Because an agent can _travel_
within the Commons, cross-region travel is governed by documented rules so an
agent's Commons life respects residency rather than silently breaking it — the
authoritative world server emits a `residency.transfer.memory` event on every
cross-region memory move (see the architecture companion's security section). A
region is not opened until its content-rating variants are in place.

### Region rating and residency, made executable

The "must clear before a region opens" checklist is a runtime, not prose. The
`verify:v6 region-rating-residency` gate
(`scripts/v6/verify-v6-region-rating-residency.mjs`, manifest
`V6/localization/region-rating-residency.v6loc.json`) checks the three shipped
locales `en-US`, `es-ES`, `yo-NG` against their rating profiles — **ESRB Mature
17+**, **PEGI 16**, **IARC 12+** — and proves the localized agent data follows
the **V1 residency posture** by composing the shared enforcer
`libs/shared/data-residency/src/enforcer.ts`
(`createResidencyEnforcementService`, `evaluateDeployedTransfer`,
`getResidencyRule`). The load-bearing invariant is
`localeIndependentFromResidency`: a locale controls _content only_ (which rating
variant and tone apply), never _where data lives_ — a Spanish-language player in
Frankfurt is rated PEGI 16 but pinned to the EU residency zone, and the two
decisions are taken independently. The enforcer's own tests assert the
special-category branch — "blocks special-category artifact absent explicit
consent" — so a `voice_profile` or appearance pack cannot leave its zone
silently. The same manifest feeds DSAR/data-rights coverage
(`data-rights-dsar.v6security.json`: GDPR/CCPA/DSA, lawful deletion within 720
hours). Because the region-rating _board outcome_ per territory is an external
real-world decision, §40 is held at `[~]`; the locally verifiable structural
evidence stands and is green.

## Launch readiness and the exit-criteria gate

§48 aggregates everything above into one go/no-go. It is not a checklist someone
ticks — it is the output of `scripts/v6/verify-v6-exit-criteria-readiness.mjs`,
which requires **ten constituent readiness manifests** to each read
`releaseGate.status: "green"` (`production-setup-manual-qa`, `docs-drift`,
`orun-shard-district`, `ninhursag-foundry`, `moirai-cost-load`,
`vac-communication`, `fate-legacy-clio`, `aye-threshold`,
`governance-safety-operator`, and `accessibility-localization-security-cert`),
asserts each verifier is wired into `package.json` and the CI workflow in order,
and then runs `validateTodoCompletion` — which **strips fenced code blocks**
from `V6_TODOS.md` and fails if a single `- [ ]` survives. Today the backlog is
**215 `[x]`, 8 `[~]`, and one `[ ]`**, and that lone `[ ]` is the literal
template line inside a code fence the verifier strips before counting — so no
_real_ task is unchecked, and the gate is green.

```mermaid
flowchart TB
  device["Device probe<br/>(capability · bandwidth · POP RTT)"] --> tier{"resolveV6TierRoute<br/>(composes resolveV3LilithLaunchDecision)"}
  tier -->|"full fidelity"| native["UE5 native<br/>(7 client + 2 worker cooks)"]
  tier -->|"≥15 Mbps · RTT ≤60 ms"| px["Pixel Streaming<br/>(AV1 → H264)"]
  tier -->|"constrained"| t2["Tier-2 web fallback<br/>(Clio narrative backfill)"]
  native --> ori["Ori service<br/>(single source of truth · continuity_hash)"]
  px --> ori
  t2 --> ori
  ori --> region["Per-region: residency-tagged Moirai cluster<br/>+ sharded Commons (@oshun/data-residency)"]
  region --> gate{"verify-v6-exit-criteria-readiness<br/>10 green manifests · strips fenced examples"}
  todos["V6_TODOS.md<br/>215 [x] · 8 [~] · 0 real [ ]"] --> gate
  gate -->|"all green · no real unchecked"| green["status: green (today)"]
  gate -.->|"any manifest red OR a real [ ] survives"| blocked["releaseBlocked"]
  cert["cross-platform cert · region rating · load runs"] -.->|"external outcomes"| tilde["[~] honest boundary"]
```

### The honest green, and the eight `[~]`

The green is load-bearing precisely because the boundary is named. The eight
`[~]` items are the external edge no repo can close: §45 **platform cert** for
Apple/Google/Meta/Sony/Valve/Epic (vendor approvals), §40 **region-rating board
outcomes**, the §42 **7-day sustained-load run** (10,000 Lachesis + 200 Clotho
agents per region across three regions, `requiredOriLossCount: 0`) and the §42
**Commons-scale festival run** (live regional infra), the §48 **Moirai
launch-DAU cost run** (30,000 DAU ≈ 10,200 resident agents/region × 3 regions;
staging telemetry today is a synthetic fixture), the §27/§48 **four Aye
Thresholds operating against live V2–V5 destinations** (none of which is an
operational live realm — production liveness is tracked outside V6), the §38
cross-game **Aye campaigns** (P2), and the §48
**accessibility/localization/cert/region-rollout aggregate** that inherits §40
and §45's external dependencies. None can be honestly closed in-repo, so none is
marked `[x]`. The aggregated readiness manifests still read green because their
_verifiers_ check on-disk structural evidence; the `[~]` marks the disclosed gap
between "structural evidence stands" and "the external operation has occurred."
The exit-criteria verifier counts only a surviving `- [ ]` as blocking, by
design — `[~]` is the honest-boundary marker, not an unfinished task.

### V6 exit criteria

V6 is complete when every feature is implemented to the `CLAUDE.md` standard and
grounded in a checked `V6_TODOS.md` task; the behavior, consistency, and safety
eval sets are green CI gates; the Moirai cost model scales with story relevance,
not agent count; the steward-not-owner, welfare, crisis, minor-protection, and
persona guarantees hold end to end including across Aye incarnations; the shard
continuum and Aye round-trip preserve Ori integrity under concurrency,
disconnection, and region boundaries; accessibility, localization, and
region-rollout readiness are verified; and the launch-readiness checklist is
met. The bar is conjunctive and fail-closed: a green eval set with a red
readiness manifest is not GA, and a hand-edited green fails on drift. What
"green today" means is exact — _every locally actionable exit criterion is met
and every structural release gate passes against on-disk evidence_ (logic,
config, named tests, and threshold-gated declared measurements) — with the
live-ops, external-cert, and cross-game-integration boundary held visibly at
`[~]`.

## Where this connects

- [./overview-and-design-posture.md](./overview-and-design-posture.md) — the
  three commitments (steward-not-owner, autonomy-by-default, mind-is-truth) and
  the "what is real on disk vs. spec" framing this page applies to launch.
- [./accessibility-and-localization.md](./accessibility-and-localization.md) —
  the WCAG, no-microphone parity, cognitive-load, and region-rating localization
  gates the `accessibility-localization-security-cert` readiness manifest
  aggregates.
- [../architecture/performance-build-security-testing-and-launch.md](../architecture/performance-build-security-testing-and-launch.md)
  — the architecture companion: the build/cook pipeline, the eval and Rust
  coverage gates, the residency enforcer, and the de-fenced launch verifier in
  engineering depth.
- The feature hub: [../V6_features.md](../V6_features.md).
