HARD PREREQUISITE for #734. Until this lands a Linux body cannot run anything, so every other phase is blocked on it.
Today pkg/provider/launch_other.go is:
func launchInSession(exePath, workDir string) error {
return fmt.Errorf("launch not supported on this platform")
}
and pkg/provider/experiences.go:16 is const experiencesDir = "C:\\experiences" with no platform variant, so install and launch paths are Windows-shaped even on a Linux build.
Scope:
- Platform-aware experiences directory. Pick and document the Linux location (/opt/experiencenet/ matches what we already use by hand on msi1060 for HelloHydra XR).
- Implement launchInSession for Linux. It must launch into the logged-in graphical session, not the service context: msi1060 runs Hyprland as user cederik (uid 1000), and both WiVRn and OpenXR clients need XDG_RUNTIME_DIR, DBUS_SESSION_BUS_ADDRESS and the Wayland/X display. This is the direct analogue of the Windows Session 0 problem recorded on #615: a SYSTEM-context launch gets no desktop and dies.
- Process supervision and stop: pkg/provider/stop_other.go is also a stub.
- Make the zip extraction path work with Linux binaries (no .exe assumption; preserve the executable bit, which Go's archive/zip does not restore by default).
Done when: an experience from hydraexperiencelibrary installs and launches on msi1060 through hydrabody alone, with no hand-run commands.
LARGELY DONE 2026-09-15, but NOT by this ticket alone. Read this before picking it up.
The install paths and the launch were implemented in parallel by hydrabody PR #1 (feat/omarchy-body) while this ticket was being worked. That work is merged and is the accepted implementation:
- experience_paths_unix.go / experience_paths_windows.go, with experiencesDir = /opt/hydra/experiences on Linux
- desktop_linux.go: desktopCommand() addresses the active seat0 session via runuser, then systemd-run --user
- launch_linux.go: launches through the desktop user's own systemd manager
Its approach to the session environment is better than the one attempted here: delegating to the user's systemd manager picks up DISPLAY/WAYLAND_DISPLAY that the compositor imported, instead of scraping another process's /proc environ. The duplicate implementation was discarded.
Two gaps in PR #1 were closed afterwards (hydrabody master 3d33a3b):
- killExperienceProcesses was still "stop not supported on this platform" on Linux, so a launched experience could never be stopped. Now matches the resolved /proc//exe, because the transient unit is auto-named and the kernel comm field truncates at 15 characters.
- makeExecutable restores the executable bit after extraction; archives built on Windows carry no Unix mode, so a Linux binary arrives 0666 and will not run.
STILL OPEN on this ticket:
- Nothing has been validated end to end on a real Linux body. Build, vet and unit tests pass for linux and windows; no experience has been installed, launched and stopped through hydrabody on msi1060. Testbook steps are drafted in the scratch notes but not committed, because they were written against the discarded path constant.
- hydrabody has not been released, so msi1060 still runs v2.0.70-rc.12 without any of this. Tagging deploys fleet-wide, including Windows venue bodies, and is an owner decision. The Windows risk is low: the moved constants keep their values and makeExecutable is a no-op there.
- See #743: hydrabody and the Omarchy bar plugin disagree on the Sunshine user unit name, on exactly these machines.