# Unit tests were silently killing the machine's real fleet watchdog

Every instar agent machine runs a small "fleet watchdog" — a macOS launchd job that wakes every five minutes and makes sure all the agents on the machine are alive. The auto-update migrator installs and refreshes it, and to do that it talks to launchd, which is a machine-wide registry: there is exactly one "ai.instar.watchdog" service per user, no matter how many copies of the code are running.

Here's the trap. Our unit tests run the migrator inside a fake, throwaway home folder (they point `$HOME` at a temp directory so nothing real gets touched). The file writes respected that redirect — but the launchd calls did not, because launchd doesn't care what `$HOME` says. So every time a test ran the migrator on a Mac, it unloaded the REAL watchdog and loaded a replacement whose config lived in the test's temp folder. The replacement immediately started up and wrote its log files into that temp folder — right while the test was deleting it, which made a whole family of unrelated tests fail with "directory not empty." Worse: after the temp folder was deleted, the machine's watchdog service pointed at files that no longer existed. The fleet watchdog was effectively dead on the developer machine until the next real update reinstalled it. CI never noticed because CI runs Linux, which has no launchd at all.

The fix is one guard: when the code detects it is running under the test harness, it still writes all the files (so tests can verify them — that part is hermetic and home-scoped), but it never touches launchd. Real updates on real machines behave exactly as before. As part of this fix the machine's real watchdog was re-pointed at its canonical config and confirmed healthy.

What could go wrong with the guard itself? If the detection ever misfired in production (it checks the standard test-runner environment variables), the worst case is the watchdog plist gets updated on disk but launchd isn't told to reload it — the OLD watchdog keeps running until the next update or reboot. That is a mild, self-healing degradation, much smaller than the bug it prevents.
