# HyperTwist Phase 8B browser-client backend contract matrix packet

Created on `2026-06-19`

## Status

- first-party HyperTwist packet
- bounded spec-only `Phase 8B` backend-contract continuation
- no implementation widening is granted by this packet

## Purpose

This packet turns the already-frozen optional full-browser client branch into a
more exact first-party backend contract matrix without reopening topology or
starting runtime implementation.

The granted slice is:

- define the transport-neutral operation families a later browser client may
  use above Unreal backend authority
- bind the minimum identity, freshness, and authority facts to already-owned
  first-party browser and tiling state envelopes
- define replay, persistence, continuity-push, and runtime-health semantics
  tightly enough that a later implementation packet does not need to restate
  contract truth from scratch

It is not:

- a live HTTP, WebSocket, or SSE implementation packet
- a replacement for the landed embedded browser/CEF shipping posture
- permission to widen into public hosting, auth, or offline-first mutation
- permission to widen into native `MagicTile` renderer ownership

## Current authority basis

This packet stands on:

- `docs/ops/HYPERTWIST_COMPREHENSIVE_RECONSTRUCTION_ROADMAP_2026-06-10.md`
- `docs/v6_5_deep_manual_pack/HyperTwist/ROADMAP.md`
- `docs/v6_5_deep_manual_pack/HyperTwist/ARCHITECTURE.md`
- `docs/v6_5_deep_manual_pack/HyperTwist/FEATURE_REGISTRY.md`
- `docs/ops/HYPERTWIST_IMPLEMENTATION_PHASE_1_KICKOFF.md`
- `docs/arch/HYPERTWIST_PHASE8B_OPTIONAL_FULL_BROWSER_CLIENT_HTTP_BACKEND_PREPARATION_PACKET_2026-06-19.md`
- `docs/arch/HYPERTWIST_PHASE8B_BROWSER_CLIENT_SPEC_EVIDENCE_HARDENING_PACKET_2026-06-19.md`

## Current evidence basis

The current first-party lane already owns the concrete payload anchors that a
later browser-client backend contract must preserve:

- `Content/Browser/src/runtime/bridge.ts` currently emits browser envelopes as
  `{ type, payload, emittedAtUtc }`, receives `hypertwist-command` plus
  `hypertwist-shell-state`, and emits `hypertwist-state`,
  `hypertwist-command-result`, and `hypertwist-runtime-ready`
- `FHyperTwistTrainingTilingStateEnvelope` already carries the authoritative
  state-snapshot identity chain through `SchemaVersion`, `HostDecisionId`,
  `BridgeContractId`, `SessionId`, `PuzzleFamilyId`, `PuzzleDefinitionId`,
  `TransportKind`, shared scramble data, `PuzzleState`, `TimerState`,
  `SourceRuntime`, and `CapturedAtUtc`
- `FHyperTwistBrowserRuntimeReadyPayload` already carries the authoritative
  runtime-ready facts through `Status`, `Runtime`, `Mode`, `AdapterCount`,
  `ShellAuthority`, and queue counts
- `FHyperTwistBrowserRuntimeStatusEnvelope` and
  `FHyperTwistBrowserRuntimeStatusSnapshot` already carry typed runtime-health
  facts through runtime identifiers, bootstrap or ready timestamps, shell
  authority, adapter count, queue carryover, bridge receive counts, last
  receipt timestamps, traffic status, and fallback reason

## Contract posture

Any later browser-client implementation must stay transport-neutral at the
spec level:

- the browser client may speak over HTTP request or response plus optional
  push transport
- operation names below are capability labels, not mandated URL paths
- field names may adapt per transport, but the carried first-party facts may
  not be dropped
- Unreal remains authoritative for session truth, puzzle legality, timer
  continuity, replay, and persistence
- browser-side buffering remains display-only and reconnect must rehydrate from
  authoritative Unreal state

## Canonical operation matrix

| Family | Canonical operation labels | Minimum carried facts | Authoritative response or push anchor |
| --- | --- | --- | --- |
| Catalog | `catalog.list` | client capability posture, requested browser-capable surfaces | launchable puzzle families, mode identifiers, browser-capable surface identifiers, bounded contract identifiers when applicable |
| Session | `session.open`, `session.resume`, `session.close`, `session.inspect` | session identity where present, requested puzzle or mode identity, bounded launch posture | authoritative `SessionId`, `HostDecisionId`, `BridgeContractId`, `PuzzleFamilyId`, `PuzzleDefinitionId`, and initial or current state snapshot |
| Action submission | `session.command.submit` | `SessionId`, client correlation token, bounded action or intent payload | authoritative accept or reject result, reason when rejected, and follow-on state or continuity facts when state changed |
| State snapshot | `session.state.get` | `SessionId` | transport form of the owned `FHyperTwistTrainingTilingStateEnvelope` fact set |
| Continuity push | `session.state.push` | `SessionId`, active continuity subscription posture | authoritative timer, replay, run-phase, and training continuity updates that remain session-matched and freshness-checked |
| Replay | `session.replay.list`, `session.replay.get`, `session.replay.persist` | `SessionId` or replay identity | authoritative replay metadata, event ordering, playback state, and persistence results |
| Persistence status | `session.persistence.status` | `SessionId` or save or restore identity | authoritative save, restore, validation, or recovery outcome facts |
| Runtime health | `runtime.health.get`, `runtime.health.push` | current runtime or shell posture when needed | transport form of the owned `hypertwist-runtime-ready` and `browser-runtime-status` fact sets |

## Minimum cross-transport metadata expectations

Any later implementation packet must preserve these minimum facts at the
transport or envelope layer:

1. operation or message family identity
2. session identity for any stateful exchange
3. backend contract or host identity when the exchange depends on a selected
   runtime bridge
4. correlation identity for request or response and action or result pairing
5. capture or emission timestamp suitable for freshness checks
6. authoritative source identity for runtime-health or status facts

Current anchor rule:

- the embedded browser lane already owns `type`, `emittedAtUtc`,
  `HostDecisionId`, `BridgeContractId`, `SessionId`, `CapturedAtUtc`,
  `RuntimeStatusId`, and shell-authority/runtime-ready facts
- later transport packets may rename those fields, but they may not erase the
  underlying first-party identity chain

## Owned payload anchors

### Authoritative state snapshot

The later browser-client branch must treat the current
`FHyperTwistTrainingTilingStateEnvelope` fact set as the minimum owned state
snapshot anchor.

That means later transport forms must continue to preserve:

- state schema identity
- host decision identity
- bridge contract identity
- session identity
- puzzle family and definition identity
- transport kind
- shared scramble data
- full puzzle state
- full timer state
- source runtime identity
- capture timestamp

### Runtime-ready and runtime-health

The later browser-client branch must treat the current
`hypertwist-runtime-ready` and `browser-runtime-status` facts as the minimum
owned runtime-health anchor.

That means later transport forms must continue to preserve:

- ready versus waiting or fallback posture
- runtime or mode identity
- shell authority
- adapter count
- queued-command and queued-shell-state carryover at runtime ready
- bootstrap or runtime-ready timestamps where available
- bridge receive counts and last receipt timestamps where available
- fallback reason where present

### Command result

The current lane does not yet expose an Unreal-typed dedicated
`hypertwist-command-result` struct, so a later implementation packet must still
preserve at least:

- session identity
- action or request correlation identity
- authoritative accept or reject outcome
- rejection or failure reason when applicable
- any authoritative follow-on state or continuity reference when the action was
  applied

## Freshness, replay, and reconnect rules

The later browser-client branch must obey these rules:

1. a browser client must not treat locally buffered state as authoritative
   after disconnect
2. reconnect must rehydrate from authoritative Unreal snapshot or inspect
   surfaces before fresh browser mutation is treated as current
3. state for one `SessionId` must never be applied to another `SessionId`
4. a changed `HostDecisionId` or `BridgeContractId` must invalidate stale
   browser-held state for the prior bridge selection
5. older authoritative state, identified by carried capture or emission
   freshness facts, must not displace newer same-session state
6. replay metadata, event ordering, and persistence acceptance remain backend
   authority rather than browser-derived truth

## Explicit deferrals

This packet still keeps the following deferred:

- live backend route or controller implementation
- auth, accounts, and public deployment posture
- offline-first mutation or merge arbitration
- browser-owned save acceptance
- browser-owned replay truth
- any native renderer widening

## Acceptance criteria

- the optional full-browser client branch now records transport-neutral
  operation labels rather than only seam-family names
- the packet binds later transport work to the owned first-party state and
  runtime-health envelopes already present in code
- the packet records minimum correlation, freshness, and reconnect rules
  without claiming implementation
- roadmap, architecture, feature-registry, and kickoff docs are updated to
  reflect this tighter spec posture

## Validation target

Validate this packet through doc-consistency only:

1. the earlier `Phase 8B` preparation and seam-hardening packets must remain
   consistent with this contract matrix
2. roadmap, architecture, feature-registry, and kickoff docs must agree on the
   new backend-contract posture
3. no Unreal build, browser-client runtime, or packaging proof may be inferred
   from this document alone

## Queue effect

If this packet lands cleanly:

- the optional full-browser client branch remains bounded and deferred, but it
  now has a concrete first-party backend contract matrix
- any future implementation packet can scope itself against explicit operation,
  identity, freshness, and runtime-health rules instead of re-opening those
  questions
- the branch remains separate from current embedded-browser shipping work and
  from any native renderer widening branch
