acpmux peer setup/update: Linux hosts run the daemon under a user systemd unit

Merged
TE
16d ago
+377-4

Summary

acpmux peer setup and acpmux peer update on a Linux host now run the daemon under one user systemd unit, ~/.config/systemd/user/acpmux.service (ACPMUX_HOME = ~/.acpmux, Restart=always). Before, they used a detached start, so each Linux host ended up with its own hand-written unit (huge-blue, big-red) or a daemon nothing supervised.

  • setup writes the unit. If a daemon started another way is running, setup shuts it down keeping its agents, then runs enable --now, so the unit's daemon adopts them and only one daemon serves the home.
  • update restarts the unit when it is running.
  • KillMode=process: a stop or restart signals only the daemon, whose SIGTERM leaves the hosted agents for the next daemon. With the default control-group, systemd also kills every __agent-host in the cgroup when the daemon exits, so a keep-agents handoff could not work. huge-blue's current unit has that bug.
  • No user manager (a container), or a host set up before this change with no unit: the detached restart, as before.

Part of the one-acpmux-per-machine plan: manaflow-ai/cmuxterm-hq#2699.

Changelog

Changed: acpmux peer setup on Linux installs a user systemd unit for the daemon.

Testing

cargo test -p acpmux --lib cli::hosts on huge-blue: 4 passed, 3 of them new. The new tests run the real remote script against a fake systemctl and a fake acpmux in a temporary HOME: a setup writes the unit and hands off a detached daemon; an update restarts a running unit and starts no second daemon; a host without a unit or without a user manager falls back to the detached restart. cargo clippy -p acpmux --lib --tests: no findings in this file.

Observed / Not run

Observed: the tests above. Not run: a real peer setup against a Linux host (that migration is step 2 in the plan, done by hand while the sessions on it are idle).

Agent session: huge-blue

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

acpmux peer setup and acpmux peer update on Linux now run the daemon under the user systemd unit ~/.config/systemd/user/acpmux.service, replacing the detached start that left each host with a hand-written unit or an unsupervised daemon.

  • setup writes the unit, shuts down a daemon started another way while keeping its agents, then runs enable --now so the unit adopts them.
  • update restarts the unit when it is running.
  • KillMode=process keeps hosted agents alive across a restart, and Restart=on-failure with a start limit keeps a deliberate shutdown down instead of looping.
  • A daemon under another acpmux unit is refused before anything stops; the script names the unit to stop and disable.
  • A daemon that stays up after its shutdown fails the handoff rather than leaving the unit retrying against a held lock.
  • The unit is used only when the user manager lingers (enabled when allowed at setup); otherwise, or when a unit fails to start, the detached restart is kept.