# HyperTwist Native XR Host And Plugin Decision Packet

Created on `2026-06-24`.

## Purpose

This note fixes the current native XR host/plugin posture so the project stops
leaving “maybe XR is already basically there” ambiguity in the Unreal lane.

## Current decision

Current decision: `No-Go` on broader native OpenXR/controller runtime widening
beyond the newly landed bounded desktop-training owner seam in the shipping
HyperTwist lane.

Current authoritative host posture:

- the shipping immersive lane remains a desktop-hosted Unreal training runtime
  with scenic presence, comfort, posture, and session-local settings ownership
- the project now **does** enable a deliberately bounded `OpenXR` + `XRBase`
  plugin stack in `UnrealHyperTwist.uproject`
- the project now **does** prove a first-party bounded runtime owner through a
  dedicated XR training pawn plus `MotionControllerComponent`-driven anchors,
  controller-binding ownership, and preference-profile ownership
- that bounded runtime-owner substrate must still be treated as truthful
  desktop-simulator ownership, not as proof of a finished launch-tier
  XR/controller product
- polished user-facing rebinding/settings ownership and live packaged
  headset/controller proof remain unfinished and continue to hold the wider
  lane closed

## Evidence checked

### Project plugin posture

- `UnrealHyperTwist/UnrealHyperTwist.uproject` currently enables:
  - `OpenXR`
  - `XRBase`
  - `RemoteControl`
  - `ProceduralMeshComponent`
  - `WebBrowserWidget`
  - editor-only tooling such as `MovieRenderPipeline`,
    `PythonScriptPlugin`, and `ModelingToolsEditorMode`

### Runtime ownership posture

- `UnrealHyperTwist/Config/DefaultInput.ini` now proves real bounded
  controller-axis and action ownership across the current controller-family
  roster instead of only broad motion-controller groundwork, and the current
  same-family hardening follow-up also adds a bounded dedicated vertical-adjust
  axis for desktop-hosted XR posture instead of leaving that owned preference
  field inert
- `UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistXR/HyperTwistXrRuntimeLibrary.h`
  and `.../Private/HyperTwistXR/HyperTwistXrRuntimeLibrary.cpp` now define the
  first-party bounded runtime-owner, preference-profile, and controller-binding
  contracts:
  - `xr/openxr-desktop-training-runtime-owner`
  - `xr-openxr-training-preferences/v1`
  - `xr-openxr-motion-controllers/v1`
- `UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistXR/HyperTwistXrTrainingPawn.h`
  and `.../Private/HyperTwistXR/HyperTwistXrTrainingPawn.cpp` now provide a
  bounded first-party XR training pawn with camera, controller anchors,
  posture switching, desktop fallback pitch handling, recentering, bounded
  manual vertical-adjust ownership, sanitized preference application, stale
  desktop-fallback rotation clearing on headset activation, and status
  reporting
- `UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingImmersiveEnvironmentLibrary.cpp`
  keeps the immersive lane explicitly bounded to scenic training ownership
- the same immersive library explicitly excludes:
  - `platform-global XR settings ownership`
  - `platform-level locomotion shell ownership`
  - `full locomotion rig ownership`
- `UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistImmersivePhaseIBPresenceControlContractTest.cpp`
  proves those exclusions are intentional and current

### Native truth surfaces

- the `2026-06-23` native control/input inspect surface already kept unfinished
  XR/runtime plus preferences truth explicit inside Unreal
- the `2026-06-24` native control/settings inspect surface now also keeps
  unfinished XR/controller rebinding truth explicit while still proving current
  camera, immersive, and dedicated-family view settings ownership
- a later same-day wording-alignment follow-up then updated those inspect
  surfaces so they now explicitly state the host/plugin posture as already
  fixed to desktop-hosted `No-Go`, instead of describing the host decision
  itself as a future packet
- that wording-alignment follow-up re-synced the touched training-panel and
  browser-test files into maintained validation root
  `C:\HyperTwist_worktrees\phase10validate`, rebuilt cleanly with
  `Result: Succeeded` and UnrealBuildTool `Total execution time: 121.33
  seconds`, then exported
  `Saved\AutomationReports\Browser-XrNoGoTruth-Verify\index.json` with all
  `20` `HyperTwist.Browser.*` tests green, including:
  - `CoachDashboard.ControlInputReadinessInspectSurface`
  - `TrainingPanel.ControlInputReadinessInspectSurface`
  - `CoachDashboard.ControlSettingsOwnershipInspectSurface`
  - `TrainingPanel.ControlSettingsOwnershipInspectSurface`
- a later same-family `2026-06-25` follow-up then projected the current
  project `OpenXR` plugin enabled/disabled fact into the structured and
  rendered native control/input, control/settings, and control/profile inspect
  surfaces, rebuilt the exact-source state on that same maintained validation
  root with `Result: Succeeded` and UnrealBuildTool `Total execution time:
  99.38 seconds`, and exported
  `Saved\AutomationReports\Browser-XrPluginProjectPosture-Verify\index.json`
  with all `20` `HyperTwist.Browser.*` tests green
- a later same-family bounded-runtime-owner follow-up on `2026-07-01` then
  carried the real first-party runtime-owner packet into those same native
  inspect surfaces as stable structured ids plus counts, rebuilt the exact
  source state on maintained validation root
  `C:\HyperTwist_worktrees\phase10validate` with:
  - `Result: Succeeded`
  - UnrealBuildTool `Total execution time: 3672.35 seconds`
  then exported:
  - `Saved\AutomationReports\XR-BoundedRuntimeOwner-Hardening-20260701\index.json`
    with `4` focused XR tests succeeded
  - `Saved\AutomationReports\Browser-XrHardening-20260701\index.json`
    with all `26` `HyperTwist.Browser.*` tests succeeded
- the current same-family hardening continuation then also keeps the dedicated
  vertical-adjust axis visible in native control/input inspect truth and keeps
  XR preference ownership explicit about vertical-adjust plus pointer-length
  control instead of relying on those facts to stay implicit in the preference
  struct alone

## Interpretation

HyperTwist already owns:

- desktop-screen simulator input
- scenic immersive training presentation
- session-local presence and comfort posture
- current camera and dedicated-family view settings ownership
- a bounded OpenXR runtime-owner substrate for desktop training, including
  first-party runtime owner, controller bindings, preference ownership, and XR
  training pawn scaffolding

HyperTwist does **not** yet own:

- polished controller rebinding/preferences ownership
- live packaged headset/controller proof
- broader launch-tier cross-device XR completion

Therefore the current truthful host decision is:

- keep the immersive lane desktop-hosted
- do not market VR/controller support as finished
- do not let browser-side retained XR grounding imply native XR completion
- keep the broader controller-widening branch closed until the remaining
  settings/rebinding and packaged-proof requirements are actually met

## Reopen criteria

Future native XR widening may reopen only when all of the following are true:

1. Windows build plus focused automation plus packaged validation prove actual
   headset/controller behavior on the shipping lane
2. public/product copy is updated only after those proofs exist

## Immediate consequence

No native XR implementation packet is currently open by default.

If the project later reopens this lane, the first implementation packet should
be packaged controller proof and shipping-lane validation above the now-landed
bounded runtime-owner plus controller-settings substrate, not public marketing
widening.

## Update - 2026-07-01 - controller-settings ownership continuation

- the next same-family continuation now adds first-party user-facing
  controller settings ownership, layout presets, and rebinding truth for the
  exact shipped XR input ids above the already-landed bounded runtime-owner
  substrate
- that means the broader native XR/controller widening gate no longer waits on
  a hypothetical settings/rebinding layer; it now waits on Windows packaged
  controller validation with controller truth on the shipping lane

## Update - 2026-07-02 - packaged validation proof now exists, live observation gate remains

- the next same-family continuation now adds a first-party packaged-validation
  seam for the bounded desktop-hosted XR lane instead of leaving packaged proof
  entirely hypothetical:
  - `UHyperTwistXrPackageValidationLibrary`
  - `AHyperTwistXrTrainingGameMode`
  - `scripts\Invoke-HyperTwistXrPackage.ps1`
  - `scripts\Launch-HyperTwistXrPackage.ps1`
  - checked-in aggregate proof:
    `docs/generated/xr/xr_packaged_validation_report_2026-07-02.json`
- the maintained reverse-SSH Windows lane on
  `C:\HyperTwist_worktrees\phase10validate` first exposed a real stale-
  packaged-artifact hazard: the old helper would allow `-SkipBuild` from an
  editor-green posture even when the packaged-game receipt and binary were no
  longer fresh against current source/config/plugin inputs
- that helper posture is now repaired: `-SkipBuild` is accepted only when the
  packaged-game receipt and binary are both present and fresh against the
  current `.uproject`, `Source`, `Config`, and `Plugins` inputs
- after that correction, a truthful full packaged-game rebuild on the same
  maintained root completed with:
  - `Result: Succeeded`
  - UnrealBuildTool `Total execution time: 2499.70 seconds`
  - `BuildCookRun time: 2593.82 s`
- the first packaged smoke after that rebuild then exposed a second real host-
  context fact: the reverse-SSH headless lane cannot truthfully claim windowed
  packaged XR proof when swapchain creation fails under that unattended
  session
- the owned XR package smoke helpers are therefore now explicitly bifurcated:
  - `RuntimeLaunchMode=windowed` remains the lane for any future live
    headset/controller observation proof
  - `RuntimeLaunchMode=nullrhi` is the bounded current reverse-SSH packaged
    structural launch and ownership proof path
- the final exact-source rerun on that same maintained root then stayed green
  in headless `nullrhi` mode with:
  - `BuildCookRun time: 85.47 s`
  - both packaged smoke maps passed:
    - `/Game/HyperTwistTraining/Maps/L_HyperTwist_FollowAlongTraining`
    - `/Game/HyperTwistTraining/Maps/L_HyperTwist_ClassicTraining`
  - aggregate report `result: passed`
  - stable owned ids preserved:
    - `xr/openxr-desktop-training-runtime-owner`
    - `xr-openxr-training-preferences/v1`
    - `xr-openxr-motion-controllers/v1`
    - `xr-openxr-controller-settings-owner/v1`
  - explicit remaining gate ids:
    - `xr/windows-packaged-headset-session-observation`
    - `xr/windows-packaged-controller-input-observation`
- current truthful reading after this packaged continuation:
  - HyperTwist now owns first-party Windows packaged structural launch and XR
    ownership proof on the shipping lane
  - HyperTwist still does not own live packaged headset-session observation or
    live packaged controller-input observation
  - the broader native XR/controller widening branch therefore remains closed
    until those two remaining live packaged gates are actually proven
- the next same-day probe then fixed the truthful host reading for that final
  live gate itself:
  - the repo now carries `scripts\Invoke-HyperTwistXrWindowedObservation.ps1`
    as the bounded interactive-desktop wrapper for the remaining live proof
  - checked-in probe
    `docs/generated/xr/xr_windowed_live_observation_probe_2026-07-02.json`
    proves the reverse-SSH/OpenSSH launcher is currently Session `0` while the
    active Explorer desktop remains Session `1`, and that no `OpenXR` active
    runtime is currently registered on the host
  - therefore the remaining headset/controller reopen gate is no longer merely
    “some future windowed proof”; it is specifically:
    1. activate a real local `OpenXR` runtime on the Windows desktop
    2. run the first-party windowed observation wrapper from that interactive
       desktop session rather than through the reverse-SSH/OpenSSH session
- the next same-day bridge continuation then tightened that host reading again:
  - the repo now also carries
    `scripts\Invoke-HyperTwistInteractiveDesktopTask.ps1`
  - checked-in bridge proof
    `docs/generated/xr/xr_interactive_desktop_task_probe_2026-07-02.json`
    now proves the reverse-SSH Session `0` lane can launch a bounded first-
    party task into the real Explorer desktop Session `1`
  - the XR lane then reran through that bridge and checked in
    `docs/generated/xr/xr_windowed_interactive_desktop_probe_2026-07-02.json`
  - that rerun shows the interactive-desktop requirement is now satisfied and
    the remaining blocker has narrowed further to one host fact only:
    `OpenXR` still has no active runtime registered on the desktop
- the latest same-day continuation then closed even that runtime-resolution
  blocker without mutating the machine-wide registry:
  - `scripts\Launch-HyperTwistXrPackage.ps1` and
    `scripts\Invoke-HyperTwistXrWindowedObservation.ps1` now also accept a
    bounded per-process `OpenXrRuntimePathOverride`
  - the maintained lane used that override to point at existing host manifest
    `C:\Windows\System32\MixedRealityRuntime.json`
  - checked-in corrected proof now lives at:
    `docs/generated/xr/xr_interactive_desktop_task_probe_wmr_override_grace_2026-07-02.json`
    and
    `docs/generated/xr/xr_windowed_interactive_desktop_probe_wmr_override_grace_2026-07-02.json`
  - that corrected rerun proves the packaged follow-along map now reaches
    runtime report result `passed` with packaged proof status
    `pending-hmd-session-observation`
  - the remaining live blockers are therefore no longer runtime resolution but
    the actual physical observation facts:
    `bHeadMountedDisplayConnected: false`,
    `bHeadMountedDisplayEnabled: false`, and no controller-input activity yet
