fix(daemon): preserve Homebrew stable symlink for launchd autostart on macOS - #164
Merged
Merged
Conversation
…n macOS On macOS, `routatic-proxy autostart enable` wrote the EvalSymlinks- resolved Cellar/X.Y.Z path into ProgramArguments[0] of ~/Library/LaunchAgents/com.routatic.proxy.plist. Homebrew deletes the old Cellar on `brew upgrade`/`brew cleanup`, so the plist became dangling and launchd failed on next login. The running daemon stayed in RAM via `start --_daemonize` (PPID 1), masking the failure. Fix: for darwin + Homebrew prefixes (/opt/homebrew, /usr/local), keep the stable symlink (/opt/homebrew/bin, /opt/homebrew/opt, /usr/local/bin, /usr/local/opt) via filepath.Abs instead of EvalSymlinks to Cellar. All other platforms and non-brew macOS installs keep current behavior; update symlink resolution unchanged. Tested: overlaid fixed binary to Cellar/0.6.4, `autostart disable/enable` now writes /opt/homebrew/bin/routatic-proxy (Cellar count 0), launchctl loaded, health ok. `brew reinstall` correctly leaves stale Cellar/0.6.3 plist until re-enable — fix makes next enable stable. Co-Authored-By: Claude Code <noreply@anthropic.com>
alecchen
marked this pull request as ready for review
September 3, 2026 03:24
Contributor
Code Review Roast 🔥Verdict: No Issues Found | Recommendation: Merge Oh wait, this PR is actually clean. I need to sit down. I had my flamethrower warmed up and everything. 📊 Overall: Like finding a unicorn in production — I didn't think clean PRs existed anymore, but here we are. Files Reviewed (4 files)
Reviewed by free · Input: 69.6K · Output: 8.6K · Cached: 177.3K Review guidance: REVIEW.md from base branch |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
autostart enableon macOS was saving the wrong binary path.It resolved the Homebrew symlink with
EvalSymlinks, so the plist got/opt/homebrew/Cellar/routatic-proxy/X.Y.Z/...instead of the stable link under/opt/homebrew/binor/opt/homebrew/opt. Homebrew removes the old Cellar directory onbrew upgrade, so the plist pointed at a missing file and launchd failed on next login. The old daemon kept running in RAM (it daemonizes to PPID 1), socurl /healthstill returned 200 until reboot. That hid the problem.brew upgradeandbrew reinstallnever touch the plist. The formula has nopost_installorservicehook. Onlyautostart enablewrites it.This fixes it for Homebrew on macOS only. If the binary is under
/opt/homebrewor/usr/local, we keep the stable symlink instead of resolving to Cellar. Everything else stays the same, includinginternal/update/update.go:146.#92 was closed by #105, but that PR only changed Windows. Same story for #24. There was no test for the Cellar pin.
Changes
internal/daemon/paths.go: keep the Homebrew stable path on darwin (newisHomebrewStablePathhelper,filepath.Absinstead ofEvalSymlinks)internal/daemon/daemon_test.go: new tests for stable path preservation (/opt/homebrewand/usr/localvariants) and forisHomebrewStablePathinternal/daemon/autostart_darwin_test.go: check that the plist does not containCellar/for Homebrew installsINSTALLATION.md: note thatbrew upgradeleaves the daemon in RAM until next login, and how to restart it nowTesting
gofmtandgo vetpass,go test ./...passes (15 ininternal/daemon)ProgramArguments[0]was.../Cellar/0.6.4/...and reinstall leftCellar/0.6.3behind. After the fix,autostart disable/enablewrites/opt/homebrew/bin/routatic-proxywith noCellar,launchctl listshows loaded, and/healthreturns ok.