The daemon disappears
For most of the project's life, running EmptyOS meant a terminal window stuck somewhere on the screen, banner-printing the vault watcher's startup line and then sitting there for the rest of the day. Closing it killed the daemon. Minimising it forgot it was there until the next time you alt-tabbed past. The system was alive, but it was alive in the wrong frame — front-of-screen, lower-left, blinking cursor. It read like a thing you were debugging rather than a thing that was running.
The fix was three small moves stacked together. First, the launch path swapped from console-attached python to pythonw plus start /b, with stdout redirected into data/daemon.log. The launcher window still flashes briefly to do its port-cleanup work and then closes itself; nothing remains attached. Logs go to the file you'd grep anyway, not to a window you have to keep open to read.
Second, lifecycle moved into the tray. The system-tray plugin already had Open and Capture entries; we added Restart and Quit on top of them, both routing through a shared shutdown path that gives the kernel five seconds to tear apps and plugins down cleanly before exiting. Right-click, choose, gone — the same mental shape as any other native daemon on the OS. No window to find first.
Third, and this is the bit that took an hour of fiddling, restart had to actually survive its own death. The old approach spawned a fresh restart.bat and exited, which on Windows usually means the parent's process group takes the child with it. We wanted the bat to be properly orphaned — fully detached, in a new process group, broken out of any job object the launcher inherited — before the old daemon called os._exit. With the right combination of DETACHED_PROCESS plus CREATE_NEW_PROCESS_GROUP plus CREATE_BREAKAWAY_FROM_JOB, the bat script lives. It immediately notices port 9000 is already free (the old daemon just released it) and skips its kill loop, so the reboot is faster than the old terminal-attached version ever was.
The result is small in lines of code and load-bearing in feel. The desktop is yours again. The OS is on the system tray where every other daemon lives. The log is in a file. Restart is a menu item. Quit is a menu item. There's nothing to look at, and that's the point — a mind companion that demands a window of attention to itself every time you boot is selling the wrong story. The system should be present at the edges, not in the middle.
There's one piece we didn't migrate: the bat file's port-9000 kill logic is still brittle on the cold-start path, and we burned a couple of restarts during the session waiting for it to stop being flaky. The clean exit path is reliable now; the recovery-from-stuck path still needs work. That's a separate session, but the friction has dropped enough that it's no longer the first thing you notice every morning.