Context: macOS, gortex installed via Homebrew. The formula replaces /opt/homebrew/bin/gortex, but a daemon that is already running keeps serving from the old binary indefinitely after brew upgrade. Nothing restarts it, and nothing surfaces the skew: the CLI and every MCP client keep connecting to the daemon on the old version.
Observed on my machine (v0.63.x line):
- a daemon started days before an upgrade was still serving afterwards;
gortex daemon status showed the old build while the on-disk binary was newer
- the launchd unit exists (
~/Library/LaunchAgents/com.zzet.gortex.plist) but reports not loaded, while a manually-started daemon holds the socket — so even a user who ran daemon install-service once can end up with a unit that owns nothing
Why I think this happens:
- A hand-started daemon (
gortex daemon start) has no supervisor and no upgrade hook; swapping the binary does not touch the running process. macOS keeps executing the old inode.
brew upgrade does not reload or restart launchd units. If the unit was never loaded (or the daemon was started manually anyway), there is nothing to bounce.
- The docs say
gortex mcp exits "if no compatible daemon can be reached" — but compatibility evidently is not binary-version-level, because a new CLI drives an old daemon silently. I could not find any build-version comparison on the connect path (the protocolVersion strings I found are MCP-protocol constants).
Impact: stale graph behavior and bugfixes; mixed versions between CLI and daemon (daemon status shows one build, the binary is another); store migrations and behavior changes land late or never until someone notices and restarts by hand.
Possible directions (not prescriptions):
- Version-skew detection on connect: CLI/
mcp proxy compares its build version against the daemon's (status already carries a version) and either refuses or prints a loud one-liner: daemon is vX, binary is vY, run gortex daemon restart.
- Make the restart story explicit after package-manager upgrades: a hint in
brew output is formula-side, but gortex could detect its own staleness (e.g. running image vs on-disk binary) and report it in daemon status/mcp logs.
- Consider making the supervised service the blessed path (KeepAlive restarts after upgrade), and have
daemon start warn when a launchd unit is installed but not loaded, or when a hand-started daemon is shadowing a unit.
Happy to work on a fix if any of the directions sound right.
Context: macOS, gortex installed via Homebrew. The formula replaces
/opt/homebrew/bin/gortex, but a daemon that is already running keeps serving from the old binary indefinitely afterbrew upgrade. Nothing restarts it, and nothing surfaces the skew: the CLI and every MCP client keep connecting to the daemon on the old version.Observed on my machine (v0.63.x line):
gortex daemon statusshowed the old build while the on-disk binary was newer~/Library/LaunchAgents/com.zzet.gortex.plist) but reportsnot loaded, while a manually-started daemon holds the socket — so even a user who randaemon install-serviceonce can end up with a unit that owns nothingWhy I think this happens:
gortex daemon start) has no supervisor and no upgrade hook; swapping the binary does not touch the running process. macOS keeps executing the old inode.brew upgradedoes not reload or restart launchd units. If the unit was never loaded (or the daemon was started manually anyway), there is nothing to bounce.gortex mcpexits "if no compatible daemon can be reached" — but compatibility evidently is not binary-version-level, because a new CLI drives an old daemon silently. I could not find any build-version comparison on the connect path (the protocolVersion strings I found are MCP-protocol constants).Impact: stale graph behavior and bugfixes; mixed versions between CLI and daemon (
daemon statusshows one build, the binary is another); store migrations and behavior changes land late or never until someone notices and restarts by hand.Possible directions (not prescriptions):
mcpproxy compares its build version against the daemon's (status already carries a version) and either refuses or prints a loud one-liner: daemon is vX, binary is vY, rungortex daemon restart.brewoutput is formula-side, but gortex could detect its own staleness (e.g. running image vs on-disk binary) and report it indaemon status/mcplogs.daemon startwarn when a launchd unit is installed but not loaded, or when a hand-started daemon is shadowing a unit.Happy to work on a fix if any of the directions sound right.