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 four children are separate defects on
separate call paths, but three of them are the same root cause and the fourth 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

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

No one assigned

    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