Summary
#254 and #291 both landed the same shape — psmux qualifies its window ids to session:@N at the minting/listing seams — but the rule a backend author needs in order to do that safely is still spread across two backend-specific docstrings and a parenthetical in the authoring guide. The TerminalMultiplexer ABC states one half of it (list_window_ids must match new_window, because window_alive is a membership test) and, after #291, that current_window_id must match the window_id column of list_windows. What it does not state is the general obligation those two are instances of.
Split out of the #291 diff deliberately: correcting the stale text was in scope for that fix, writing cross-backend authoring guidance was not.
The rule that is currently undocumented
If a backend returns anything other than a bare native id from an id-minting seam, then every verb that backend's own callers replay the id through must accept that form — and where one cannot, the backend translates inside that verb rather than leaving the id bare.
psmux is the worked example in both directions:
Getting this wrong is quiet in both directions, which is why it is worth writing down:
Suggested scope
- One paragraph in
docs/adapter-authoring-guide.md's target-grammar section stating the obligation, with psmux's select_window translation named as the worked example of "the verb cannot take it, so translate".
- A sentence on
TerminalMultiplexer.new_parked_window noting the id is opaque and MAY be qualified, matching what new_window already says.
- No behavior change, no test changes.
Relevant for the external adapter path too: the herdr adapter is the documented implement-fresh reference, and any native-id backend written against parse_target() faces the same question.
Refs: #291, #290, #254, #310
Summary
#254 and #291 both landed the same shape — psmux qualifies its window ids to
session:@Nat the minting/listing seams — but the rule a backend author needs in order to do that safely is still spread across two backend-specific docstrings and a parenthetical in the authoring guide. TheTerminalMultiplexerABC states one half of it (list_window_idsmust matchnew_window, becausewindow_aliveis a membership test) and, after #291, thatcurrent_window_idmust match thewindow_idcolumn oflist_windows. What it does not state is the general obligation those two are instances of.Split out of the #291 diff deliberately: correcting the stale text was in scope for that fix, writing cross-backend authoring guidance was not.
The rule that is currently undocumented
If a backend returns anything other than a bare native id from an id-minting seam, then every verb that backend's own callers replay the id through must accept that form — and where one cannot, the backend translates inside that verb rather than leaving the id bare.
psmux is the worked example in both directions:
select_windowcannot takesession:@Non stock 3.3.7 (the CLI-side existence check matches only window index/name), so the backend resolves the id to an index before sending instead of exempting the id from qualification.Getting this wrong is quiet in both directions, which is why it is worth writing down:
window_alivereads every live window as instantly dead (the trap psmux: pipe_pane targets a bare @N window id — per-server ambiguity binds the sink to the wrong server's pane (empty run logs) #254's notes called ci: bump actions/checkout from 6 to 7 #1).list_windowsbut notcurrent_window_id, and the ctl-window prune stops recognizing its own window — it kills the window it is running in (found by review on psmux: TUI-side window ids are still bare — parked mint, list_windows fields, and prune kill targets replay @N cross-server #291).Suggested scope
docs/adapter-authoring-guide.md's target-grammar section stating the obligation, with psmux'sselect_windowtranslation named as the worked example of "the verb cannot take it, so translate".TerminalMultiplexer.new_parked_windownoting the id is opaque and MAY be qualified, matching whatnew_windowalready says.Relevant for the external adapter path too: the herdr adapter is the documented implement-fresh reference, and any native-id backend written against
parse_target()faces the same question.Refs: #291, #290, #254, #310