Files
Hydra-OS/docs/superpowers/plans/2026-10-13-graphics-session.md
T

7.4 KiB
Raw Blame History

HydraOS Graphics Session Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development or superpowers:executing-plans. Steps use checkbox syntax for tracking.

Goal: Validate independent VM management and fullscreen switching before Gentoo ISO packaging.

Architecture: Python CLI owns validated profiles, disks and private QMP connections. A separate labwc session owns viewer windows, workspaces and host shortcuts. Gentoo packaging follows in its own plan.

Tech Stack: Python3.11+ standard library, QEMU/KVM, virt-viewer/SPICE, labwc>=0.20.0.

Spec: ../specs/2026-10-13-graphics-session-design.md

Global Constraints

  • Gentoo, first target ASUS FX517ZC, UEFI, Secure Boot disabled.
  • Preserve current NixOS, Ubuntu, VM lab and existing disks.
  • Source in Ubuntu-owned project; temporary development tools permitted.
  • QEMU lifetime independent of compositor/viewer.
  • Tests use explicitly separate config/state/runtime paths.
  • Private Unix QMP/SPICE sockets; no public management listener.
  • Guest Meta/Alt+Tab; host Ctrl+Alt+Shift+Left/Right/Escape and brightness.
  • No clipboard/directory sharing or USB auto-redirection by default.
  • No overwrite of existing disks or unattended physical disk installation.

Review Focus

  • Stale records/reused PID must never stop another process: Task1 identity tests.
  • Concurrent starts must never attach one writable disk twice: Task1 lock tests.
  • Profile names and paths must not become shell syntax: Tasks1/2 escaping tests.
  • Held keys/buttons during switches must not stick: Task3 input test.
  • Missing display/GPU/ISO and viewer crash preserve guests: Tasks1–3 failure tests.

File Structure

bin/hydra is the source-checkout entry point. hydra/profiles.py, qmp.py, runtime.py, cli.py implement validated profiles, protocol, lifecycle, parsing. hydra/session.py owns session configuration/viewer launch. session/ contains launcher assets; patches/ holds necessary upstream adaptations. tests/ uses unittest; dev/ holds pinned tools and disposable integration probes.

Task 1: Independent VM lifecycle

Files: Create bin/hydra, hydra/{__init__,profiles,qmp,runtime,cli}.py, tests/test_{profiles,qmp,runtime}.py.

Interfaces:

  • CLI globals --config PATH, --state PATH, --runtime PATH; defaults from XDG.

  • Commands add NAME --iso PATH [--memory 4096] [--cpus 2] [--disk-size 40G], list, start NAME, status [NAME], shutdown NAME, stop NAME --force.

  • Names match [a-z][a-z0-9-]{0,31}; individual NAME.toml profiles.

  • Profile fields: name, iso, memory, cpus, disk_size, graphics(auto|software), network(user|bridge), bridge. Defaults: graphics auto, network user, bridge hydrabr0. Distribution networking follows later.

  • load_profile(path: Path) -> Profile, build_qemu_argv(profile: Profile, paths: VMPaths) -> list[str], QMPClient.command(name: str, arguments: dict | None = None) -> dict.

  • VMPaths provides disk, log, lock and private QMP/SPICE sockets. Session consumes stable name and socket paths only.

  • Write validation/QMP fake-server tests: invalid names/resources, missing ISO, paths containing spaces, greeting/capabilities, asynchronous events, IDs, timeouts.

  • Run python3 -m unittest discover -s tests -v; observe failure before implementation.

  • Implement validation and bounded QMP; subprocess argv arrays, named environment tool overrides for tests.

  • Add lifecycle tests: simultaneous start, existing-disk preservation, stale socket, failed boot, shutdown vs force, QMP VM identity.

  • Implement locked safe disk creation, detached QEMU, virtio disk/network, SPICE no clipboard/file transfer, optional Intel GL. No display dependency in manager and no PID-only stop.

  • Run complete suite, help, scratch QEMU lifecycle probe. Commit feat: add independent VM manager.

Task 2: Minimal fullscreen session

Files: Create hydra/session.py, session/hydra-session, tests/test_session.py, dev/tools.nix; amend CLI; optional narrow virt-viewer patch.

Interfaces: Consumes Task1 Profile/VMPaths. Produces hydra view NAME [--windowed], hydra session [--nested], labwc config only in selected runtime. Viewer title is deterministic from validated name; each VM maps to one workspace. Recovery opens host terminal; session never shuts down a VM.

  • Probe actual labwc version/overrideInhibition and remote-viewer kiosk USB behavior on disposable state; record versions.
  • Resolve manual USB dialog with a small upstream viewer adaptation if necessary; never auto-redirect USB.
  • Write tests for valid escaped XML, exact window/workspace/fullscreen rules, no default keyboard/mouse bindings, overrideInhibition on host keys, missing viewer/display errors.
  • Run session tests and observe missing implementation failure.
  • Implement session/viewer commands and pinned temporary tool environment; no host installation.
  • Run full tests and labwc config parsing. Commit feat: add fullscreen HydraOS session.

Task 3: Integration and recovery

Files: Create dev/smoke.py, docs/verification.md; update README with verified commands. Amend runtime/profile/CLI/session tests and dependency patches for integration defects and the installed-guest workflow below.

Interfaces: Consumes Tasks1/2, produces disposable-VM integration evidence.

  • Run two disposable KVM instances/viewers, never existing lab disks; verify private QMP and independent lifecycle.
  • Verify viewer/session exit preserves QEMU and reattach works; switching neither restarts nor reconnects guests.
  • Check input only in disposable session, without injecting into current host or user's guests; add regression tests for discovered defects.
  • Resolve Task 2's observed USB shortcut dispatch failure; demonstrate manual selector opening without automatic USB redirection on the private display. Check reserved switching/recovery actions with a standard keymap and keyboard inhibition.
  • Complete installed-guest boot workflow: optional installation media, explicit attach/detach while stopped, disk boot without the original ISO, and status/stop usable even if previously configured ISO disappears. Preserve exclusive disk creation and verified QMP control.
  • Add validated display dimensions/optional refresh and distribution defaults under /etc/hydra/defaults.toml. Defaults affect newly created profiles only; explicit CLI values win. Developer default remains user networking and stock-QEMU-compatible refresh; installed Hydra uses hydrabr0 and ASUS 1920x1080/144000 mHz preference.
  • Port the existing tested qemu-virtio-refresh-rate.patch from the old lab as a tracked dependency patch; validate the generated EDID and requested mode. Distinguish advertised refresh from achieved frame rate and physical display verification.
  • Record held-key, physical brightness and 144Hz checks needing dedicated TTY. Nested tests cannot prove them.
  • Run full suite and independent review; fix material findings with reproducing tests.
  • Commit evidence and push reviewed prototype branch to supplied repository.

Next plan

Stage3/rootfs, signed official binpkgs where suitable, kernel/firmware, dracut live boot, squashfs/UEFI ISO and guarded installer. Acceptance: ISO boot, install to blank disposable disk, reboot without ISO, persistent changes and working VM session. Real laptop installation requires a selected disk and final consent.