What happened
engram update --yes on macOS (git-checkout install, 0.4.0 -> 0.4.0 re-run on 2026-09-21) failed at the restart step:
start mcp: mcp did not answer on its port within 90s
The automatic code-only rollback then failed at the same step, leaving /Users/devinmlowe/git/engram detached at the previous sha with all three services loaded but not running.
Root cause
The supervisor adapter in src/interfaces/cli/services.ts starts a launchd job with launchctl load <plist>. From this context (a non-login shell spawned by Claude Code inside tmux) that call registered the job but never ran it: launchctl print gui/501/ai.hermes.engram-mcp showed runs = 0, and launchctl list listed the label with no PID. The /health poll therefore timed out.
launchctl kickstart -k gui/501/<label> started each job immediately and /health answered within seconds.
Suggested fix
- After
launchctl load (or bootstrap), run launchctl kickstart -k gui/<uid>/<label> so the job actually starts regardless of RunAtLoad handling.
- Before polling
/health, check the job has a PID (launchctl print / launchctl list) and report "job registered but not running" instead of the generic port timeout.
- Rollback should use the same start path, otherwise a start-step failure also breaks the rollback and the install ends up detached.
Environment
macOS 26 (Darwin 25.6.0), engram 0.4.0 git checkout, launchd agents ai.hermes.engram-mcp, com.engram.visualizer, com.engram.dreamstate.
What happened
engram update --yeson macOS (git-checkout install, 0.4.0 -> 0.4.0 re-run on 2026-09-21) failed at the restart step:The automatic code-only rollback then failed at the same step, leaving
/Users/devinmlowe/git/engramdetached at the previous sha with all three services loaded but not running.Root cause
The supervisor adapter in
src/interfaces/cli/services.tsstarts a launchd job withlaunchctl load <plist>. From this context (a non-login shell spawned by Claude Code inside tmux) that call registered the job but never ran it:launchctl print gui/501/ai.hermes.engram-mcpshowedruns = 0, andlaunchctl listlisted the label with no PID. The/healthpoll therefore timed out.launchctl kickstart -k gui/501/<label>started each job immediately and/healthanswered within seconds.Suggested fix
launchctl load(orbootstrap), runlaunchctl kickstart -k gui/<uid>/<label>so the job actually starts regardless ofRunAtLoadhandling./health, check the job has a PID (launchctl print/launchctl list) and report "job registered but not running" instead of the generic port timeout.Environment
macOS 26 (Darwin 25.6.0), engram 0.4.0 git checkout, launchd agents
ai.hermes.engram-mcp,com.engram.visualizer,com.engram.dreamstate.