You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Child of #288. Same root cause as #228 — psmux reports execution, not effect — but a different call path and a different consumer, so it does not fit under that issue's title or scope.
#228 is about the shell trailer: switch-client -t "$ret" || switch-client -l cannot reach its fallback because the first command exits 0. This is about the Python seam: TerminalMultiplexer.switch_client / detach_client return a boolean that tui.launch.return_attached_client consumes to decide whether to clear RETURN_OPTION. On psmux that boolean is vacuously True.
Verified in the psmux source at v3.3.7 (the version available() admits)
switch-client (src/main.rs, the "switch-client" | "switchc" arm): every flag is folded into a command string and the arm ends in
cmd.push('\n');send_control(cmd)?;returnOk(());
send_control returns Ok on the TCP round-trip, so ? propagates only a transport error. No form carries a server reply — -t included. Exit 0 whether or not any client moved.
detach-client (same file, the "detach-client" | "detach" arm): the only nonzero exit is an unreachable session server —
ifsend_control(server_cmd).is_err(){eprintln!("psmux: no session '{}'", session_for_routing);
std::process::exit(1);}returnOk(());
— so it succeeds with zero clients attached. It also promotes a flag-less invocation to detach-all, which is what the backend issues:
let effective_all = detach_all || (t_target.is_none() && shell_cmd.is_none());
Post-tag: current main gives switch-client a response path (send_control_with_response), but only for -t. The -l fallback stays exit-0-regardless, and detach-client is unchanged — the arm is identical between v3.3.7 and 33ea109.
Why nothing is broken today
Latent, not live. psmux's per-window option channel is inert (#310), so return_attached_client reads an empty RETURN_OPTION and answers False before reaching either verb. The moment #310 / #315 revives that channel, this becomes reachable: the parked-return path will consume a True that means nothing, clear the return option, and report a hand-back that never happened — reintroducing #227's exact symptom on the platform the psmux backend exists for.
Impact when live
sweep._return_after_decisions journals sweep-returned-after-decisions, prints "✓ decisions recorded", and sets prompting = False — while the human is still attached and the client never moved. Every later decision then defers through the unattended path.
Observe effect instead of trusting the exit code — e.g. compare list-clients before/after, at the cost of an extra round-trip on a path that runs once per decisions phase.
Accept and contain — keep the vacuous True but make return_attached_client verify the option was actually consumed. Weakest, but backend-agnostic.
Nothing is actionable until #310 lands; filing now so the reviver of that channel inherits the constraint rather than rediscovering it.
Context
Surfaced by the review of #227 / PR #316, which widened detach_client from None to bool and made the tmux path honest (smoke-measured: detach-client exits 1 with no current client when nothing is attached, 0 with a client). The psmux divergence is recorded in the backend's degradation ledger there; this issue is its tracker.
Child of #288. Same root cause as #228 — psmux reports execution, not effect — but a different call path and a different consumer, so it does not fit under that issue's title or scope.
#228 is about the shell trailer:
switch-client -t "$ret" || switch-client -lcannot reach its fallback because the first command exits 0. This is about the Python seam:TerminalMultiplexer.switch_client/detach_clientreturn a boolean thattui.launch.return_attached_clientconsumes to decide whether to clearRETURN_OPTION. On psmux that boolean is vacuouslyTrue.Verified in the psmux source at v3.3.7 (the version
available()admits)switch-client(src/main.rs, the"switch-client" | "switchc"arm): every flag is folded into a command string and the arm ends insend_controlreturnsOkon the TCP round-trip, so?propagates only a transport error. No form carries a server reply —-tincluded. Exit 0 whether or not any client moved.detach-client(same file, the"detach-client" | "detach"arm): the only nonzero exit is an unreachable session server —— so it succeeds with zero clients attached. It also promotes a flag-less invocation to detach-all, which is what the backend issues:
Post-tag: current
maingivesswitch-clienta response path (send_control_with_response), but only for-t. The-lfallback stays exit-0-regardless, anddetach-clientis unchanged — the arm is identical betweenv3.3.7and33ea109.Why nothing is broken today
Latent, not live. psmux's per-window option channel is inert (#310), so
return_attached_clientreads an emptyRETURN_OPTIONand answersFalsebefore reaching either verb. The moment #310 / #315 revives that channel, this becomes reachable: the parked-return path will consume aTruethat means nothing, clear the return option, and report a hand-back that never happened — reintroducing #227's exact symptom on the platform the psmux backend exists for.Impact when live
sweep._return_after_decisionsjournalssweep-returned-after-decisions, prints "✓ decisions recorded", and setsprompting = False— while the human is still attached and the client never moved. Every later decision then defers through the unattended path.Candidate directions
Trueon builds that cannot report effect.list-clientsbefore/after, at the cost of an extra round-trip on a path that runs once per decisions phase.Truebut makereturn_attached_clientverify the option was actually consumed. Weakest, but backend-agnostic.Nothing is actionable until #310 lands; filing now so the reviver of that channel inherits the constraint rather than rediscovering it.
Context
Surfaced by the review of #227 / PR #316, which widened
detach_clientfromNonetobooland made the tmux path honest (smoke-measured:detach-clientexits 1 withno current clientwhen nothing is attached, 0 with a client). The psmux divergence is recorded in the backend's degradation ledger there; this issue is its tracker.Refs: #288, #228, #222, #310, #315, #227