acpmux: make remote recovery commands explicit
What changed
Remote acpmux recovery now returns stable reasons plus data.try commands, keeps a saved offline host add successful with an actionable warning, keeps enroll listener behavior scoped to hb-acpmux #25286, recognizes PATH-discovered remote harnesses, classifies Codex app-server protocol mismatches, explains reconnects, and renders an intentional code-0 stop as stopped. The remote guide and acpmux README carry the isolation and recovery recipes.
Leo: “this + more i was talking to workspace-218 i wanted them to help work on ergonomics too” and “these issues and such all need to be addressed”.
Inventory
| Error | Message today | Message after |
|---|---|---|
inherited ACPMUX_SOCKET while using another ACPMUX_HOME | status reports the enclosing daemon; start is a no-op | docs give env -u ACPMUX_SOCKET ACPMUX_HOME=... acpmux daemon status and warn to inspect the selected socket |
SSH alias unavailable during host add | exit 0 with an offline peer | exit 0 after saving, with a stderr warning or JSON warning containing reason: "peer_unreachable", the SSH probe in try, and reconnect detail |
| named harness profile absent locally | doctor fails despite remote PATH discovery | doctor says the harness was discovered remotely; verify acpmux daemon harnesses and a real new --host session |
Codex app-server sent ACP session/new | says login is needed | harness_protocol_mismatch; use the acpmux bridge/session recipe, with no false login advice |
| enroll against an existing non-default listener | assumes 47811, restarts the wrong daemon/listener | handled by hb-acpmux #25286; this PR keeps the recovery wording and stable error fields |
remote cwd outside webRoots | generic known-project refusal | guide names the exact merge-preserving config, same-home/listener restart, and retry |
| permission request on remote prompt | prints forbidden CLI session allow route | docs say approval belongs in the cmux Mac app pending-permission card; deny/cancel remain CLI routes |
| peer reconnect during daemon restart | opaque peer_unreachable | says the request was not sent and gives acpmux host ls |
intentional session stop with code 0 | “agent exited unexpectedly” | “agent stopped” |
Risk
A saved host remains a successful configuration change even when its first connection is offline. The warning gives a deterministic SSH probe and states that reconnecting continues; saving failures remain errors. The protocol classification is deliberately narrow, and code-0 exits are rendered as normal stops to match the explicit stop event. host enroll listener-port behavior is owned by hb-acpmux (#25286); this PR does not change the daemon behavior. It does not kill or replace a foreign socket holder. Daemon behavior and remote policy remain owned by hb-acpmux.
Validation
cargo test -p acpmux --test peer_canonical_endpoint: 3 passed. Coverage checks human warnings, exit 0, JSON warning fields, persisted configuration, and canonical endpoint listings. Run withumask 077andTMPDIR=/tmpon this VM; its default permissions make test homes group-writable and prevent daemon startup.cargo clippy -p acpmux --all-targets -- -D warnings: passed.cargo fmt --all -- --checkandgit diff --check: passed.- Owner-run fleet tests at preceding head
5d9435796fe94c9cbb415e54d720adf94542ae4f: acpmux lib passed;daemon_chat_openandsession_poolfailures also reproduce on base. Fleet validation of the updated head remains with the area owner.
Agent session: gcp-codex-lane-5
![View with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v3-3x.png)
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Need help on this PR? Tag @codesmith-bot with what you need.