2026-07-02 Launchd Reload Workaround Removed After Upstream Fix

What I set out to do

Confirm whether home-manager PR #9587 actually fixed issue #9585, the launchd bootout --wait reload bug I’d worked around in nix/home-manager/modules/launchd-reload-fix.nix, and if so, remove the workaround. Continuation of 2026-07-01 HM Bump Breaks Launchd via User-Domain Default.

What I actually did

Verified #9587 is genuinely merged (issue closed as COMPLETED, not a stale-bot close) and that its merge commit ebc87da is already pinned in nix/flake.lock (pulled in by 283dad8 Update flake inputs).

Read the actual diff and found the fix is bigger than the one-line --wait gate the PR title advertises: setupLaunchAgents was rewritten so the launchd domain now defaults to gui, bootout is version-gated (bootout --wait on macOS 26+, plain bootout + sleep 1 below), and failed activations roll back per-agent via restoreAgent instead of only hard-exiting. Crucially, #9587 changed nothing on the macOS-26 code path (this machine is 26.6) — the real fix is the surrounding rewrite, not the gate.

Probed launchctl bootout --wait gui/$UID/<nonexistent> and got a normal Boot-out failed: 3: No such process, proving --wait is a recognized flag on 26.6 (contradicting the old workaround comment). Then removed the module, staged the deletion, built the new generation to confirm the workaround was gone, and ran a controlled verification: perturbed the deployed tldr-update plist so it differed while the agent stayed loaded, ran hm switch, and watched HM’s own code stop and re-bootstrap it cleanly (exit 0, no Bootstrap failed: 5: Input/output error). The perturbation self-healed. Updated the stale comments in the litellm and obsidian-remote-mcp modules and the file-based memory note. Committed as f90296d.

What was striking

The PR’s headline (“only use —wait on macOS 26 and later”) is aimed at macOS 15 users and is a no-op for my machine’s path — I nearly took it at face value. The thing that actually made the workaround redundant was the unrelated restoreAgent + gui-default rewrite that landed in the same window. Also: the workaround’s own premise (“--wait does not exist in macOS launchctl”) was just wrong on 26.6; the original failure was almost certainly the user-domain EIO, not a missing flag.

Still open

The per-agent launchd.agents.<name>.domain = "gui" overrides on atuin/tldr stay necessary — #9587 didn’t touch the upstream modules’ domain = lib.mkDefault "user", so those agents would still flip to the user domain and hit EIO on macOS 26 without the override.