Skip to content

psmux: the client-verb probes aim their -t at an unguarded session name, and read the attached count with a substitutable target #671

Description

@dracic

Two residuals in how the psmux leaf aims its display-message probes. Both predate #659 and #670 — that change only made the second one load-bearing in a new direction. Same function family as #669 (which is about a probe with no -t at all); these two are about a -t that is present but wrong.

1. A :-bearing session name goes straight into -t <session>

_client_left (src/bmad_loop/adapters/psmux_backend.py:851) and switch_client's gate read both take current_session() and pass it to _attached_clients, which spawns:

display-message -p -t <session> '#{session_attached}'

Nothing guards the name. current_return_target refuses exactly this shape a few lines up, and says why: the grammar cannot carry it — a:b parses as session a, window b, and ":@N" parses sessionless. So a session named foo:bar makes the probe read a different thing entirely, or fail; the count then degrades and the verdict with it.

The #221 rule already exists in this module (_qualified_window_id, current_return_target); the client-verb probes are the callers that never got it. A if not session or ":" in session: return False at the two entry points, or the guard folded into _attached_clients, would match the module's own convention.

Reachability is the honest caveat: control-session names this seam mints never contain :. An operator-created session, or a future naming scheme, is what makes this reachable — which is why the sibling call sites guard rather than assume.

2. The attached-count read uses -t <session>, not the exact-match form

_attached_clients reads with a plain -t <session>. The module docstring already records what that costs elsewhere: "a -t read naming a session whose own server is gone can be answered by a different server, so a wrong True is reachable when a same-named session exists on a foreign one."

Under the old delta that residual was mostly harmless — it took two successful reads of the same session with the first nonzero to manufacture a drop. Since #670 the count is also read in the nonzero direction, as the gate that vouches for a switch-client -t whose rc was 0. A foreign server's nonzero count would therefore vouch for a switch that moved nobody: a vacuous True, which tui.launch.return_attached_client turns into RETURNED and a cleared return option.

The narrowing options, in increasing strictness:

  • read with the seam's exact-match token (={session}) so a dead server cannot be substituted for;
  • treat a failed read as ungated rather than as zero, so the verdict degrades to False instead of borrowing a stranger's count — this is already the behaviour, but it is implicit in _attached_clients returning None, not stated at the gate;
  • scope the count to our own client (#{client_tty} / -c) instead of the session-wide total, which also addresses the "the attached client may belong to another terminal" case. That is a design change, not a patch.

Both items came out of the review rounds on #670 and were deliberately left out of it: neither is caused by the verdict-source change, and the second one only becomes interesting because of it.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Robustness, enhancement, tests, or docs worth schedulingarea:adaptersCoding-CLI adapters and profilesarea: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