HydraIssues

ensureSunshineVDDConfig should re-verify sunshine.conf integrity each tick (defense-in-depth for #123)
open improvement Project: hydrabody Reporter: claude (cederik) 29 Apr 2026 21:25

Description

Context

#123 fixed the proximate cause of sunshine.conf truncation by skipping Sunshine's /api/config endpoint entirely and writing the disk file directly from setSunshineConfig. That keeps output_name, audio_sink, encoder/encryption settings, and the hydracluster base in place across stream-starts and Sunshine restarts.

But the on-disk file is still vulnerable to any future external writer (a manual edit via Sunshine's web UI, a future Sunshine version that auto-saves on a timer, a sysadmin running Set-Content, an upgrade tool, etc.). If that ever happens, hydrabody won't notice until the next time restartSunshine reloads the file, by which point the body is back to the black-screen state and the only recovery is the manual procedure documented in the runbook (docs/runbooks/runbook.md → 'Sunshine config integrity').

Proposal

Remove the marker-file short-circuit in ensureSunshineVDDConfig (pkg/provider/vdd_windows.go:58-61) so every tickVirtualDisplay (every 30 s) verifies the on-disk content has both output_name and ensure_primary and re-runs writeSunshineConfig + restartSunshine if either is missing. The marker becomes an optimisation for skipping discoverVDDDeviceID (which is the expensive step), not a permanent skip.

Before #123 landed, this would have been catastrophic: every setSunshineConfig call truncated the file, so the next tick would have repair-restarted Sunshine 30 s later, breaking every stream. Now that v1.11.27+ preserves on-disk integrity, the tick-verifier is safe — it only fires when something external corrupts the file.

Files to change

  • pkg/provider/vdd_windows.go:57-93 — change ensureSunshineVDDConfig to:
    1. Always read sunshine.conf (regardless of marker presence).
    2. If the content has both output_name and ensure_primary, ensure marker exists and return.
    3. Otherwise: log [vdd] sunshine.conf missing required keys, repairing..., run discoverVDDDeviceID (use cached value from marker file content if present to avoid the discovery cost in the steady-state-but-marker-missing case), writeSunshineConfig, restartSunshine, write marker.

Verification

  1. With v1.11.29+ deployed, manually overwrite sunshine.conf with a stripped-down content (e.g. just dd_manual_resolution = 1920x1080).
  2. Within 30 s, [vdd] sunshine.conf missing required keys, repairing... appears in hydrabody.log.
  3. sunshine.conf is restored to the full content.
  4. Sunshine restarts via restartSunshine and serves the correct display.
  5. No regression: in normal operation (file healthy), there is no extra Sunshine restart per tick — the function should return at step 2.

Blocked by

#123 (the merge fix). Filed only after #123 closed (today, 2026-04-29) so we don't accidentally land the tick-verifier while the truncation bug is still active.

Plan file reference

/home/claude-user/.claude/plans/enumerated-cuddling-micali.md contains the prior plan including this defense-in-depth note.

Custom Fields

affected_repos
hydrabody
severity
low