HydraIssues

Phase 4: package and manage the WiVRn server
open unclassified Project: hydrabody Parent: #734 Reporter: 15 Sep 2026 18:46

Description

Part of #734. Can overlap Phases 2 and 3.

Today on msi1060 the server is a hand-built binary in /var/tmp/hydra-wivrn/build, started by a transient systemd-run unit typed by hand, reading a config file written by hand, behind ufw rules added by hand. None of that survives a rebuild or a reprovision.

Scope:

  • Install from the PKGBUILD already in the fork (contrib/arch/PKGBUILD) rather than a scratch build tree.
  • A real systemd unit owned by the body, running as the desktop user with the session environment, replacing systemd-run.
  • Managed config. The encoder selection and the application entry are currently hand-written JSON; they should be rendered by hydrabody from the assigned experience. Mind the traps recorded in the fork runbook: the key is encoder SINGULAR, the third stream is alpha and cannot be pyrowave, and bitrate is a CLIENT setting with no server-side key.
  • Firewall as provisioning, not ad-hoc: TCP+UDP 9757 and mDNS 5353 scoped to the venue LAN.
  • A release channel for the server build, so bodies pull a version rather than compiling in place.

LARGELY DONE 2026-09-15 on msi1060. The server no longer runs from a scratch build tree under a hand-typed systemd-run.

  • hydra-wivrn-server 0.0.0.pyrowave.r2795.abda7da8-1 built with makepkg from contrib/arch/PKGBUILD and installed with pacman -U. /usr/bin/wivrn-server is now a packaged file, which is also the path hydrabody checks when deciding whether the body can serve the wivrn driver.
  • The PKGBUILD was broken and had never been exercised. First build failed after configuring:
    GIT_DESC cannot be inferred from .git and was not provided at build time
    makepkg's checkout has no usable git description and GitVersion.cmake treats a missing one as fatal. Fixed by deriving GIT_DESC and GIT_COMMIT from the checkout and passing them at configure time (hydra-wivrn master).
  • Config is cluster-owned at /var/lib/hydra/wivrn/config/config.json, root-owned, mirroring the Sunshine arrangement already on this machine. The unit passes -f so ONLY that file is read; without it the server merges three locations including the user's own ~/.config/wivrn/config.json. Pairing state still lands in the user's config dir, which is right, since that is per-user trust rather than policy.
  • ~/.config/systemd/user/hydra-wivrn.service runs the packaged binary against that config. VERIFIED: started, active, listening on 9757, avahi-published as msi1060cederik, running as
    /usr/bin/wivrn-server -f /var/lib/hydra/wivrn/config/config.json
  • The unit is deliberately NOT enabled at boot, so an idle body serves nothing; hydrabody arms it. hydra-sunshine.service is unaffected and still active.

REMAINING for this ticket:

  • Firewall as provisioning rather than the ad-hoc ufw rules added by hand (9757 tcp+udp and mDNS 5353, scoped to the venue LAN).
  • A release channel for the package, so bodies pull a version instead of building in place. Today the package was built on the body itself.
  • Cosmetic: pkgver renders as 0.0.0.pyrowave.r2795. because the project() VERSION grep finds nothing. Harmless, but the version string would read better fixed.
  • /var/tmp/hydra-wivrn (1.5G scratch build tree) is now redundant and can be removed.

RECIPE WRITTEN 2026-09-15, hydracluster main e70cf08: recipes/wivrn-arch.yaml.

Assigning the wivrn role to an Omarchy body now provisions the whole lane: installs the hydra-wivrn-server package, writes the cluster-owned config, installs hydra-wivrn.service for the logged-in desktop user, and opens the LAN firewall. The role and the recipe ship in the same release, which is why it was worth batching them rather than deploying for a label.

Two bugs were caught by testing the steps against msi1060 before shipping:

  • The naive subnet detection picked the FIRST route with a prefix, which on a meshed body is the WireGuard 10.10.0.0/16. Scoping the firewall there would have left the headset unable to reach the body on the venue LAN, recreating the exact failure that cost hours earlier in this work. Corrected to take the subnet of the default-route interface; verified it now yields 192.168.68.0/22 rather than 10.10.0.0/16.
  • Desktop-user detection was verified to resolve "cederik" from the seated session, matching what hydrabody does.

REMAINING and now the only thing blocking install-on-assignment:

  • The package is not published anywhere. The recipe fetches
    https://releases.experiencenet.com/hydrawivrn/production/latest.json
    and the matching hydra-wivrn-server--x86_64.pkg.tar.zst, neither of which exists. Today's package was built ON the body with makepkg. Publishing it is the last piece of this ticket.
  • hydracluster has not been released, so neither the role nor the recipe is live. That deploy is an owner decision.
  • Cosmetic: pkgver renders as 0.0.0.pyrowave.r. because the project() VERSION grep finds nothing.

RELEASED 2026-09-16, owner approved.

  • hydrawivrn package PUBLISHED: releases.experiencenet.com/hydrawivrn/production/latest.json resolves to 0.0.0.pyrowave.r2795.abda7da8-1 and the exact URL the recipe constructs returns 200. This was the last blocker for install-on-assignment.
  • hydracluster v2.0.119 released and LIVE (health reports v2.0.119), carrying both the wivrn role and recipes/wivrn-arch.yaml.
  • hydrabody v2.0.70-rc.13 released; msi1060 auto-updated to it on its own. Note rc tags publish to the STAGING channel, and bodies carry release_channel: staging, so production/latest.json is the wrong place to look for them.
  • The wivrn role is assigned to msi1060: roles are now [hydrabody, hydraguard-air, wivrn], accepted by the endpoint, which is itself the proof the catalog change deployed.

STILL OWED on this ticket: the package was published BY HAND this once, uploading the makepkg output from the body through the hydrarelease API. That is not a release channel. Building the Arch package in CI needs an Arch container in Actions, and until that exists a new version means repeating the manual upload.