Skip to content

psmux backend: per-server bare-id targets and the pre-#483 rc-0 no-op ceiling #288

Description

@pbean

Umbrella issue for the psmux target-resolution family. The five children are separate defects on
separate call paths, but four of them are the same root cause — psmux reporting execution rather
than effect — and the fifth is the audit that found them.

Root cause: ids are per-server, and psmux runs one server per session

On tmux a bare @N (window) or %N (pane) id is server-global and unambiguous. On psmux it
is only meaningful on the server that minted it, and the CLI resolves it against the caller's
current-session
server. In a normal TUI-launched run there are at least two servers — the
bmad-loop-ctl session's and the agent session's — with colliding ids (@1 exists on both). So
a bare-id -t from inside the ctl pane silently binds to the wrong pane and exits 0.

This was already root-caused once, for switch-client, in #221 / psmux/psmux#483 and fixed in
#225 by composing a session-qualified target in the backend that knows its own target grammar.
The fix was applied to one call path, not to the class. #254 is the same bug on pipe_pane.

Compounding factor: the pre-#483 rc-0 no-op

psmux builds without the #483 fix exit 0 as a no-op when switch-client gets an unresolvable
target. Every fallback in this codebase that keys off a nonzero exit code — the POSIX trailer in
adapters/tmux_base.py (switch-client -t "$ret" || switch-client -l), the pwsh override in
adapters/psmux_backend.py, and BaseTmuxBackend.switch_client — is therefore structurally
unreachable
on those builds. The knowledge currently lives only in a CHANGELOG entry.

psmux/psmux#483 is CLOSED, fixed on main (d56d777 + 6c76ff9), but v3.3.7 (2026-07-20) is
still the newest tag
and carries the no-op. Two children are gated on the next release.

Children

#254 pipe_pane targets a bare @N → run logs empty on TUI-launched runs actionable now
#227 return_attached_client reports success even when switch_client fails actionable now (backend-agnostic — affects tmux too)
#228 version-gate the rc-0 no-op + document the fallback ceiling comment half actionable; version gate needs the tag
#222 live re-verification of the switch-client paths on the next psmux release blocked on the next psmux tag
#317 the seam's switch_client / detach_client booleans are vacuously True — return_attached_client trusts them latent until #310 lands, then live

Worth doing once, here

#254 offers two shapes: qualify the target inside PsmuxBackend.pipe_pane (smallest diff), or
have new_window return a session-qualified id so every downstream -t consumer is safe. The
second is the class-level fix, and given that this is now the second instance of the same bug,
an audit of the remaining bare @N / %N uses on the psmux path is cheap while someone is in
there.

Refs: psmux/psmux#483, psmux/psmux#482, #221, #225, #185, #217.

Metadata

Metadata

Assignees

Labels

area:psmuxpsmux terminal-multiplexer backendbugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions