Study Shells
The main app now supports dedicated study shells: focused operator modes that sit inside the same public operator window without requiring a separate app codebase.
Why They Exist
Many sessions do not need the full Quest Library, Runtime Config, or raw
Twin Monitor surfaces during the run itself. A study shell trims the operator
view down to:
- one approved APK identity
- one dedicated Quest device profile
- the live signals the experimenter actually needs to watch
- only the trigger buttons the study protocol allows
That keeps the participant-facing runtime simple while still letting the study team choose between two packaging modes:
- embedded study mode, where the operator can still return to the full app
- dedicated study package, where the app opens straight into one shell and keeps the broader operator surfaces hidden
When a study shell is activated from Start Here, the first tab becomes the
study workspace and the main header switches into that study mode as well. If
the catalog manifest sets a startup study plus lockToStartupStudy, the app
opens there immediately on launch and does not expose the route back to the
main operator tabs.
Startup And Locking
Study-shell startup behavior is controlled in samples/study-shells/manifest.json:
startupStudyId: opens that study automatically when the app startslockToStartupStudy: hides the broader operator tabs and theExit Study Modeaction for that package
That means dedicated study packages are now mainly a config choice:
- keep both fields empty/default for the full operator app
- set
startupStudyIdonly if you want a shell to open first but still allow return to the main app - set both fields when you want the packaged app to behave like a study-specific operator surface
Sussex University Shell
The first committed study shell is Sussex University, backed by
samples/study-shells/sussex-university.json.
The committed public Sussex package now uses the dedicated mode above:
- startup study:
sussex-university - startup lock:
true
That means the public Sussex packaged release is intended to behave like a dedicated researcher-facing operator surface, not like the broader multi-study app.
It currently pins:
- package id:
com.Viscereality.SussexExperiment - version:
0.1.2 - SHA256:
EF7DD259FF3ED9101505CEC936585E7B20213993890090BAB3D2DC78C2A30E79 - bundled APK path:
../quest-session-kit/APKs/SussexExperiment.apk - device profile:
CPU 5 / GPU 5 / static foveation level 1 - expected LSL input target:
HRV_Biofeedback / HRV - expected routing:
Controller Volume / LSL Heartbeat / LSL Direct - profile workspaces:
Visual Profiles,Breathing Profiles, andConditions - runtime launch mode: best-effort task pinning on launch
The shell also ships two active experiment-session conditions:
Current, which uses the current visual and controller-breathing condition profiles.Fixed Radius, No Orbit, which sets the visual orbit-distance envelope to0..0and locks the sphere-radius envelope to2..2through its visual profile.
The Conditions tab lets an operator inspect, edit, import, export, duplicate,
and activate conditions without touching the Unity APK. The Experiment Session
window only lists conditions whose Active flag is set. See
Sussex Conditions for the GUI and CLI workflow.
For the committed Sussex shell, the runtime toggle is intentionally a task-pinned launch/stop button rather than a plain launch/stop button:
Launch Study Runtimelaunches the Sussex APK, resolves the live Unity task, and pins it witham task lock <TASK_ID>- if the headset reports asleep, the launch surface now blocks the action and
tells the operator
Wake the headset to enable launching - if a concrete Guardian, tracking-loss, or ClearActivity blocker is active, the launch surface also stays blocked until that blocker is cleared in-headset
Stop Study Runtimesends the confirmed Home-return stack:automation_disable -> task lock stop -> HomeActivity -> force-stop Sussexwhen an operator intentionally invokes it from a visible on-head runtime stateCapture Quest Screenshotprefers the active Wi-Fi ADB endpoint when one is available and falls back to USB only if Wi-Fi ADB is not available- when Sussex itself is in front, the helper prefers the runtime-oriented screenshot path first so particle-scene and participant-view checks reflect the current Unity view more reliably
- when Horizon shell or Guardian truth matters, the shell-oriented capture path still remains available as a fallback
- it is the required operator-side truth source whenever HorizonOS shell state and the visible headset scene disagree
That behavior is specific to the Sussex study shell config, but on the current April 2026 Meta OS build it no longer guarantees that the controller Meta / menu button is visually neutralized while Sussex is active. Treat it as best-effort task pinning plus screenshot-confirmed foreground only. The public GUI also no longer exposes remote headset wake/sleep controls for Sussex; use manual headset wake/sleep only.
Current operator rule:
- if launch or stop only reaches shell-level confirmation, the Sussex shell must leave a visual-confirmation warning in place instead of claiming success
- on this machine, the shell can still end up in black / Guardian-blocked
states where
HomeActivity,FocusPlaceholderActivity, or even a resumed Sussex task is reported without a usable visible scene - treat the screenshot card as mandatory for launch/exit verification in those cases
- do not use
Stop Study Runtimeorviscereality study stop sussex-universityas off-face automated cleanup on this machine - if Sussex must be exited, ask the wearer to quit while the headset is on-face and visually confirm the Home-side result afterward
- for off-face functionality tests, quitting Sussex is optional and can be skipped
Current confirmed GUI behavior on this machine after the April 2026 Meta OS update:
- from visible Meta Home,
Launch Study Runtimecan still reach a working Sussex runtime in front - the controller Meta / menu button is no longer a reliable launch-success signal, because it can remain active even while Sussex stays in front
- from a worn-head, visible Sussex runtime state,
Stop Study Runtimecan still return the headset to visible Meta Home, but screenshot confirmation remains mandatory - if the headset is already asleep or in black
SensorLocklimbo before the operator starts, wake or recover it first; do not launch Sussex from sleep
Self-Contained Sussex Package
The public Sussex packaged release is designed to be self-contained:
- the packaged Windows install already includes the bundled Sussex APK
- the study shell already knows the approved hash and device profile
- the operator should not need a separate runtime source checkout or a second APK handoff
The committed samples/quest-session-kit/APKs/SussexExperiment.apk is intentionally the
same Sussex APK mirrored from the approved Sussex study build. It is stored
through Git LFS in the source repo, but the packaged Windows install exposes
the real file directly to the app at runtime.
When you approve a newer Sussex APK from the participant-facing runtime build, refresh the public bundle with:
powershell -ExecutionPolicy Bypass -File .\tools\app\Sync-Bundled-Sussex-Apk.ps1
That keeps the packaged app's samples/quest-session-kit/APKs/ layout stable
while updating the mirrored APK and the pinned Sussex hash in
compatibility.json and sussex-university.json.
The runtime build-and-approval step stays outside this public operator repo. Once a newer Sussex APK is approved, sync it here with the script above so the packaged Sussex operator app remains self-contained.
The embedded Sussex workspace checks:
whether the bundled APK matches the approved study hash
whether the same build is already installed on the headset
whether the pinned Quest device profile is currently active
live LSL target, connected stream, and inlet status from
quest_twin_staterouted
0..1inbound HRV biofeedback when the runtime publicly echoes itcontroller breathing, heartbeat, and coherence values from the study runtime
camera drift from the last recenter anchor
particle visibility and whether rendering is suppressed by the operator or HUD
current fps, frame time, and refresh-rate telemetry when the runtime publishes it
The active Sussex shell is organized into three operator views:
Pre-sessionfor connection, Sussex APK verification, and device-profile setupVisual Profilesfor named appearance-only Sussex presets that the experimenter can create, save, pin as the next-launch override, and apply over the existing hotload-file pathDuring sessionfor the live monitoring and command surfaceInspectfor detailed study-runtime settings, focused live values, and recent twin events
The Visual Profiles tab is intentionally narrower than the general runtime
editor. It only exposes the approved appearance controls for the Sussex scene:
- simplified tracer controls:
- tracers enabled
- tracer lifetime seconds
- tracers per oscillator
- sphere deformation on/off
- sphere radius minimum and maximum
- particle size relative to radius on/off
- particle-size minimum and maximum
- depth-wave minimum and maximum
- transparency minimum and maximum
- saturation minimum and maximum
- brightness minimum and maximum
- orbit-distance minimum and maximum
The Breathing Profiles tab uses the same saved-profile model for the Sussex
controller-volume breathing path. It exposes both dynamic-axis and fixed-axis
calibration settings, low-motion calibration thresholds, and the dedicated
controller vibration values now owned by the Sussex runtime:
- inhale vibration frequency and intensity
- exhale vibration frequency and intensity
- tracked low-motion retention vibration frequency and intensity
Bad tracking is intentionally not editable: the runtime always disables controller vibration while tracking is bad or the selected controller is not active. Controller vibration also waits for controller-breathing calibration; launching the APK or selecting controller mode must not vibrate the controller before the operator presses a calibration button and the runtime accepts a calibration.
The bundled release profiles include:
Small Motion Mild, which lowers the accepted-frame and travel thresholds moderately for operators whose controller movement is being rejected as too smallSmall Motion Conservative, the pinned startup controller profile for this release, which is more forgiving for low-motion users and gives calibration a longer watchdog before it gives up
Changing or applying a controller-breathing profile resets runtime controller calibration. Pinning a profile changes the next-launch startup profile; applying one live hotloads only the current running session. In both cases, recalibrate on-headset before a participant run.
Each saved profile is stored as one self-describing JSON file under the local
Companion profile library. The shell compiles saved profiles and runtime drafts
into a showcase_active_runtime_config_json hotload payload and uploads that
through the existing Sussex ADB file path. The headset never consumes the
partial source JSON directly.
The packaged app can also carry extra read-only Sussex visual profiles from:
samples/study-shells/sussex-university/visual-profiles/
Those bundled release profiles are listed after the bundled baseline and before the local writable profile library. They can be selected, applied, exported, and pinned for launch, but editing them requires copying them into the runtime draft and saving that draft as a new local profile.
The workflow is intentionally split into four separate surfaces plus the orientation-first Sussex home view:
- the Home tab:
- this is the operator landing page
- it summarizes pre-session state, live-session state, and the current sequential-guide step before the operator dives deeper
- the Experiment Session window:
- this is the dedicated live participant-run surface after the sequential guide has passed
- it keeps participant entry,
Start Recording,Stop Recording, live telemetry, clock/network consistency, recenter, particle toggles, screenshot capture, directStart Dynamic-Axis Calibration,Start Fixed-Axis Calibration,Reset Calibration, quick access to the Windows session folder, the pulled Quest backup folder, the generatedsession_review_report.pdf, and the condensed operator log on one low-distraction popout - one saved launch profile:
- this is the pinned saved profile the shell stages to the device-side startup CSV before Sussex launches
- one runtime working draft:
- the editable table is always this draft
- selecting a saved profile copies it into the draft
- runtime edits and
Apply To Current Sessiononly mutate the draft and the running Sussex session
- the saved profile library:
Save As New Profilecopies the current runtime draft into the library as a new saved profileSave Changes To Selected Profileoverwrites the currently selected saved local saved profile from the runtime draftSet Selected Profile For Next Launchpins a saved profile without changing the current running session
When preparing a public release, copy the machine-local visual profiles you want to ship into that bundled folder with:
powershell -ExecutionPolicy Bypass -File .\tools\app\Sync-Bundled-Sussex-VisualProfiles.ps1
That sync keeps the most recent local file for each visual profile name and
skips repo-local GUI/test artifacts such as zzz-*.
The parameter table always compares against the current saved launch profile. At shell startup, the runtime working draft is initialized from that same launch profile so the editable and comparison columns begin aligned, but later runtime edits stay temporary until the operator explicitly saves them back into the profile library. Row reset still returns a single value to the bundled Sussex baseline.
Agent Automation And CLI Parity
The packaged Sussex shell now exposes two agent-facing control modes:
- GUI-driving for rendered-state checks, screenshots, and visual confirmation
- CLI-driving for deterministic profile edits, startup/default changes, and machine-readable inspection
For GUI-driving, use real UI interactions: select the relevant Sussex tab or popout window, focus the editable cell or toggle, type or toggle through UI Automation / keyboard input, then invoke the matching button. For deterministic profile authoring and startup/default changes, prefer the CLI.
For automation, prefer the CLI. It now uses the same persisted profile JSON files, startup/default state, apply-state tracking, and device-side hotload sync rules as the GUI. The intended agentic Sussex workflow is:
- CLI for deterministic setup, launch, and profile work.
- GUI
Sequential Guideonce directly before the participant. - GUI
Experiment Sessionwindow for the live participant run and recording.
Do not invent ad hoc CLI replacements for the live participant recorder flow.
The current CLI parity stops at setup/runtime control and profile automation;
the real participant run is intentionally driven from the Experiment Session
window. The CLI can still help with post-run recovery or inspection through
viscereality hzdb ls ... and viscereality hzdb pull ..., but the normal
participant start/stop flow remains GUI-first.
The agent-readable field catalogs are:
viscereality sussex visual fields --json
viscereality sussex controller fields --json
Those commands expose the stable control ids, ranges, baseline values, runtime-key mappings, full tooltip text, and the effect/increase/decrease/ tradeoff metadata bundled in the Sussex schemas.
The core profile commands are:
viscereality sussex visual list --json
viscereality sussex visual show "<profile>" --json
viscereality sussex visual create --name "<new-name>" --from bundled-baseline --set ... --scale ... --json
viscereality sussex visual update "<profile>" --set ... --scale ... --json
viscereality sussex visual set-startup "<profile>" --json
viscereality sussex visual clear-startup --json
viscereality sussex visual apply-live "<profile>" --json
viscereality sussex controller list --json
viscereality sussex controller show "<profile>" --json
viscereality sussex controller create --name "<new-name>" --from bundled-baseline --set ... --scale ... --json
viscereality sussex controller update "<profile>" --set ... --scale ... --json
viscereality sussex controller set-startup "<profile>" --json
viscereality sussex controller clear-startup --json
viscereality sussex controller apply-live "<profile>" --json
For the controller profile table and CLI, calibration setup now lives in the same controller field catalog. The important ids are:
use_principal_axis_calibrationonmeans dynamic motion axisoffmeans fixed warmed-up controller orientation
min_accepted_delta- the smallest movement that still counts as a new accepted calibration sample
min_acceptable_travel- the total travel calibration must observe before it accepts the solve
Example:
viscereality sussex controller update "<profile>" `
--set use_principal_axis_calibration=off `
--set min_accepted_delta=0.0008 `
--set min_acceptable_travel=0.02 `
--set-startup `
--json
Current-session apply-live mirrors the GUI Apply To Current Session
buttons:
- it publishes over the live
quest_hotload_configtwin path - it requires the Sussex runtime to be in the foreground
- it does not rewrite the saved next-launch/default profile
Startup/default commands mirror the GUI next-launch actions:
- they change the persisted startup/default profile
- they sync the device-side startup CSV immediately when Sussex is not currently in the foreground
- if Sussex is running in the foreground, the saved startup/default change is
deferred until the next
viscereality study stop sussex-universityorviscereality study launch sussex-university - do not treat
viscereality study stop sussex-universityas the default off-face cleanup path; on this machine that quit flow can still end in Guardian / SensorLock / passthrough limbo - if exit is required, prefer a worn-head operator quit with visual confirmation afterward
- for normal functionality validation, leaving Sussex running is acceptable
For natural-language requests like "reduce particle size by 50%", agents should
usually adjust both particle_size_min and particle_size_max, because the
visual shell models that concept as a paired min/max envelope instead of one
single knob.
The Home tab now also offers Open Sequential Guide, a pop-out onboarding
window that walks the operator through the fixed Sussex protocol step by step:
- USB probe
- Wi-Fi ADB enable
- Wi-Fi match confirmation
- USB unplug and Wi-Fi-only confirmation
- APK and device-profile verification
- runtime launch
- LSL and particle verification
- controller-tracking guarded calibration
- 20 second validation capture with inline timing alignment, local and pulled Quest output folders, and a generated PDF review report
- reset-to-ready handoff into the dedicated
Experiment Sessionwindow or back to the main shell
The Wi-Fi portion of that guide is now split into two separate questions on purpose:
Headset Wi-Fi/PC Wi-Ficonfirms the obvious setup contract: both devices report the same SSID.Wi-Fi router paththen checks the transport the router is actually allowing: selector drift, host/Quest subnet shape, ICMP reachability, and whether Windows can open TCP port5555on the Quest IP.
That distinction matters because a router can put both devices on the same SSID and still block peer-to-peer traffic with guest-mode isolation or WLAN client isolation.
At the LSL step, the guide now exposes Probe Connection. That button does not
sniff raw LSL packets directly from Android. Instead, it combines the current
ADB-backed headset snapshot with the live Sussex twin telemetry so the operator
gets an explicit diagnosis of:
- whether the installed Sussex APK matches the pinned release hash
- whether the pinned Sussex device profile is active
- the current foreground, snapshot, and Wi-Fi context
- the expected Quest inlet stream name/type
- the runtime target currently configured on the headset
- the currently connected inlet stream and connection counts
- the fresh return path back to Windows on
quest_twin_state / quest.twin.state - the Windows-visible Quest twin-state outlet inventory, including whether the source id matches the pinned Sussex package contract
- the companion's operator-to-headset channels on
quest_twin_commands / quest.twin.commandandquest_hotload_config / quest.config - the currently measured Quest Wi-Fi router path so the guide can separate a
stale selector or blocked TCP
5555path from a pure Sussex runtime issue
The Sussex shell now exposes a dedicated Windows environment page so the
Windows-side diagnostics no longer crowd the Pre-session setup column. That
page includes the Machine LSL State and Analyze Windows Environment
surfaces, Generate Diagnostics Report, Open Report Folder, and Clean Install Footprint actions, plus the host-visible operator-data, tooling,
workspace, and liblsl paths the guided installer is supposed to keep aligned.
Use that page when the operator needs the Windows-side view instead of the
headset-side view. It compares:
- the currently visible
HRV_Biofeedback / HRVpublishers on Windows - a temporary local LSL outlet that should be rediscoverable from the same PC
- the companion-owned TEST sender and twin outlets
- the clock-alignment probe transport
- the packaged local-agent workspace CLI, including its current build hash and
whether the exported CLI still answers
--version - whether a stale unpackaged
agent-workspacemirror is still present beside the packaged workspace - when a local source checkout is available, whether the maintainer-only repo
dotnet test --no-build --list-testspath is blocked separately from the packaged consumer tooling - the passive upstream monitor used during recording
- when a live headset selector is available, the raw Quest Wi-Fi transport path from this PC to the headset endpoint
That makes duplicate upstream senders, stale companion-owned streams, and local
LSL advertisement/discovery failures visible without guessing from partial
symptoms. It also lets the operator catch the router-specific failure mode
where the PC and Quest share the same SSID but TCP 5555 is blocked by guest
Wi-Fi/client-isolation policy. If switching between the built-in TEST sender
and an external Python sender becomes unreliable, refresh Machine LSL State
first and then run Analyze Windows Environment. If another maintainer needs
to inspect the same state, press Generate Diagnostics Report; the app writes
a timestamped diagnostics folder with JSON, LaTeX source, and a native PDF.
The report also includes the Quest pinned APK/profile snapshot, the raw Quest
Wi-Fi transport path, the quest_twin_state publisher inventory, the Step 9
return-path interpretation, and a safe particle-off twin command
acknowledgement probe. The same card now exposes Open Report Folder so the
operator can jump directly to the shareable artifacts after generation, and
Clean Install Footprint removes stale shortcut files plus legacy generic CLI
exports when a branded Viscereality CLI.exe export already exists beside
them.
The validation step now keeps the timing workflow inside the same guide surface. Instead of opening a separate timing window, step 12 shows:
- the start clock-alignment burst
- the sparse drift probe state during the 20 second capture
- the matching end burst before pullback and PDF generation
That makes it easier for the operator to see which phase is currently running without losing the main workflow context.
The Sussex command path was also tightened so normal study buttons do not do a full pre-send wake + snapshot refresh when the headset is already awake. On a healthy live session, command presses should now reach the runtime noticeably faster than the earlier public builds.
The calibration buttons in the sequential guide and Experiment Session window
now guard on current controller tracking before they send a calibration command.
If the controller is not tracked, the GUI reports that state instead of moving
ahead optimistically. The Sussex runtime also echoes the calibration guard and
last command state through quest_twin_state, so the desktop window can keep
its operator state aligned with the APK after the command is received.
The current public shell can also send the study recenter command and the dedicated particle visibility on/off commands.
The During session surface now also exposes the dedicated breathing-driver
workflow for Sussex:
Use Automatic Driverswitches the study into the standalone automatic breathing cycleStart AutomaticandPause Automaticcontrol whether that automatic cycle is currently runningUse Controller Volume Driverreturns the study to the controller-volume path
That readback is intentionally driven by the dedicated Sussex automatic-cycle
telemetry (study.breathing.value01 plus routing.automatic_breathing.running)
instead of inferring state from routing.adaptive_pacer.enabled.
The dedicated Experiment Session window now keeps the other live-session
controls in one place during the participant run:
- live particles and performance status
- breathing-driver and coherence state
- recenter status and fresh Quest screenshot capture
- clock/network consistency plus the latest clock-alignment status
- one-click dynamic-axis and fixed-axis calibration start buttons plus reset calibration
Detailfoldouts on the operator cards so failures can be debugged without leaving the session window- the collapsible operator log for deeper troubleshooting without taking over the main live-monitoring layout
Start Recording preserves the current controller calibration. Operators can
calibrate in the Experiment Session window before pressing Start Recording,
then start the recording without the companion or runtime resetting that
calibration. If calibration is reset manually, or if a controller profile is
applied or pinned and then launched, the operator should recalibrate before
using the controller-breathing path.
The embedded During session surface remains available when the operator wants
broader shell context or deeper inspection, but the popout is now the preferred
live-run window.
Packaged installs now resolve operator data through the host-visible packaged
root (%LOCALAPPDATA%\Packages\<package-family>\LocalCache\Local\ViscerealityCompanion\...)
instead of exposing raw app-container aliases. That is the path the session
folder, pulled Quest backup, screenshots, logs, tooling cache, and local agent
workspace buttons now open. Unpackaged/source builds still use the normal
%LOCALAPPDATA%\ViscerealityCompanion\... root.
The Sussex shell now uses the bundled APK path from the app payload on startup, so packaged Windows installs do not depend on a machine-local runtime workspace just to find the Sussex APK.
Sussex Verification Harness
The repo now includes a tracked live harness:
- command:
powershell -ExecutionPolicy Bypass -File .\tools\app\Start-Sussex-VerificationHarness.ps1 - output:
artifacts/verify/sussex-study-mode-live/
That harness:
- opens the main WPF app
- activates
Sussex University experiment mode - starts a local float LSL sender on
HRV_Biofeedback / HRV - publishes smoothed
0..1HRV biofeedback packets from this Windows machine on an irregular heartbeat-timed cadence - installs, launches, and profiles the bundled Sussex APK
- captures GUI and Quest screenshots for runtime-launch and runtime-stop review
- writes a text report alongside those screenshots
The latest completed harness-driven Sussex validation pass on 2026-04-02:
- confirmed controller-breathing profile apply and restore readback through the embedded Sussex shell
- confirmed participant start/end in
participant_lockedmode on the rebuilt0.1.1Sussex APK - confirmed matching Windows and Quest session metadata for the participant run, including Windows
session_snapshot.jsonand Questsession_snapshot.json - updated the approved Sussex APK hash in the pinned public shell metadata to
B19921EE126B780B9530D94DA30ED298A58410D1FEDE58C077B27DD140A9E3A0 - confirmed the reduced Quest locked-mode file set (
session_events.csv,signals_long.csv,breathing_trace.csv,clock_alignment_samples.csv,timing_markers.csv,session_settings.json,session_snapshot.json) while broad legacy files such aslsl_samples.csvstayed intentionally absent
The current public 0.1.2 Sussex bundle regained a fresh live verification
baseline on 2026-04-03 through the accepted published GUI path:
- confirmed
Use Automatic Driverswitched Sussex into the standalone automatic breathing route with clear GUI readback - confirmed the automatic breathing value moved live on the headset after
Start Automatic, paused cleanly, resumed, and then returned toController Volume - confirmed the installed headset APK hash matched the pinned public Sussex hash
AFB296E22A5FFE1F648AC32D73CAA6CE3B335EAFFAD2A2B1847D16DDB06ECA29 - recorded the accepted-app run under
artifacts/verify/sussex-manual-accept-run/
After that off-face pass, the Sussex bundle was refreshed again on
2026-04-15 to the current pinned SHA256
EF7DD259FF3ED9101505CEC936585E7B20213993890090BAB3D2DC78C2A30E79. That
build adds the scene-side controller vibration module, controller-only input
configuration, controller-tracking calibration guards, no-reset recording
start behavior, and the current public LSL value mirrors. A CLI-driven live
check on the same day confirmed that the calibration command path reaches the
APK, that the runtime reports the controller guard state back through
quest_twin_state, and that an external Python HRV_Biofeedback / HRV sender
can be consumed by the headset and mirrored back to the desktop GUI. Treat the
2026-04-03 notes as the last published off-face behavior baseline before
these controller/LSL updates, and the newer hash above as the current shipped
Sussex bundle.
That 2026-04-03 pass was also run off-face, so runtime-stop verification was intentionally
skipped instead of being re-verified in the same run. On this machine, Windows
Application Control still blocks freshly republished local harness executables,
so the accepted published GUI path remains the reliable live-validation route
for now.
Treat those screenshots as evidence to inspect, not as an automatic proof that
Meta Home was visibly restored. On the current HorizonOS build, runtime stop can
still land in a passthrough / placeholder limbo even after HomeActivity has
focus again, so the operator must review the captured Quest screenshot before
calling the exit side "good". See docs/quest-adb-hzdb-recovery-notes.md for
the current blocked-shell findings on this machine.
The Sussex launch flow now arms the same direct prox_close keep-awake
override used in Quest Multi Stream before the APK starts. The guide and
Experiment Session window both show that state explicitly. If an unattended or
older run left the keep-awake override active, clear it first if you need to
return to normal wear-sensor behavior.
The operator-facing readback now mirrors the raw Quest state:
Virtual proximity state: CLOSEmeans the directprox_closeoverride is active.Virtual proximity state: DISABLEDmeansautomation_disablerestored the physical wear sensor.
On this machine, prefer that published harness launcher over raw
dotnet run because Windows Application Control can block unpackaged local
loads. If the harness still fails with Win32 4551 while loading lsl.dll,
treat that as the known machine policy blocker rather than as a Sussex scene or
bundle regression.
At the moment, the public study telemetry confirms full sender -> headset inlet
connectivity through study.lsl.connected_* and study.lsl.status. If the
runtime also exposes signal01.coherence_lsl or a driver.stream.*.value01
mirror entry, the harness will measure round-trip latency for the direct
coherence value. The currently verified public Sussex build does expose that
value, so the harness now reports measured coherence loop latency in the text
report.
If the Quest launches drift into Guardian / SensorLock / FocusPlaceholder
limbo, use docs/quest-adb-hzdb-recovery-notes.md as the source of truth for
tested adb / hzdb recovery commands and the observed Meta shell state
machine on this setup.
How Study Shell Discovery Works
The app looks for study-shell definitions in this order:
VISCEREALITY_STUDY_SHELL_ROOTsamples/study-shells/relative to the repo rootsamples/study-shells/next to the executable
That means new simplified study windows are primarily a data/config task:
- add a JSON definition
- optionally choose a startup study and whether that package should lock to it
- point it at the study package, hash, and device profile
- list the live keys and study commands to expose
- reopen the app and launch the shell from
Start Here
No Unity scene code needs to live in this repo for that operator window to be useful.