fix(bin): bind tmux endpoint presence to exact session/window resolution - #2670
Open
KakkoiDev wants to merge 6 commits into
Open
fix(bin): bind tmux endpoint presence to exact session/window resolution#2670KakkoiDev wants to merge 6 commits into
KakkoiDev wants to merge 6 commits into
Conversation
bin/fm-backend.sh:837 probed a tmux endpoint with
`tmux display-message -p -t "$target" '#{pane_id}' >/dev/null 2>&1` and read
that exit status as "the endpoint exists". display-message is declared
CMD_FIND_CANFAIL, so an unresolvable -t never fails: it answers from the
client's active window, or expands to nothing when no client is attached, and
exits 0 either way. Every torn-down tmux endpoint therefore read as present,
including on the session-start fleet digest's per-task liveness line, where a
false present tells a supervisor a dead worker is still working.
The same probe also inherited tmux's window-name resolution, which matches by
fnmatch and by prefix, so a recorded `session:fm-x` could bind a live
`session:fm-x2`.
list-panes does fail on a target it cannot resolve, and asking it which window
it landed on makes the remaining name match exact: a recorded
session:window-name must come back as that same name. A pane id, window id, or
window index already resolves exactly, so its exit status alone is enough,
while a target naming no window at all (empty, or "session:") is refused
because tmux answers those from whatever window is current.
bin/fm-crew-state.sh:150 carried the byte-identical probe and now calls the
single owner. bin/fm-watch.sh reads panes only through capture-pane, which
does fail on an absent target, so it is unchanged.
Regression coverage fails on 733a504 and passes here:
tests/fm-tmux-agent-liveness.test.sh proves the predicate against real tmux
(absent window, gone session, prefix of a live name, live and absent pane ids,
and a record naming no window), and tests/fm-session-start.test.sh proves the
digest line itself reports dead for a gone window, a gone session, and a
prefix match. The tmux fakes in the suites that cross this predicate were
extended to answer list-panes the way tmux 3.7b does, and the real-tmux suites
now start their private servers with -f /dev/null so a host tmux.conf
after-new-session hook cannot rename the fixture session out from under them.
…mbiguous reads unreadable
…n liveness classifier
…dable, not missing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Root cause
fm_backend_target_exists(bin/fm-backend.sh) andfm_backend_tmux_agent_state(bin/backends/tmux.sh) resolved a recordedsession:windowendpoint using tmux's default fuzzy/prefix name matching instead of exact matching:tmux list-panes -t <session>:<window>andtmux list-windows -t <session>match a prefix of the session name, and the window-name comparison after inherited a similar prefix/glob laxness.fm_backend_tmux_agent_state), a false ALIVE is worse: it can suppress a legitimate relaunch, or (in the renamed-session case) risk authorizing a duplicate relaunch onto a live worktree.Fix
=exact-match prefix, relying on exit status alone rather than a name comparison against captured output.unreadable(protects a renamed-but-live agent from a duplicate relaunch), absent reportsmissing(safe to recover, since no live session holds that window).unreadable, notmissing, so a transient tmux glitch never licenses a duplicate relaunch.fm_backend_target_exists) intentionally does not re-probe on a renamed session: a renamed-but-live session reads dead there, which is documented in docs/tmux-backend.md as the safe direction for a passive read (false-dead only makes a supervisor look, never authorizes an action).Files:
bin/fm-backend.sh,bin/backends/tmux.sh,docs/tmux-backend.md,docs/verification/runtime-backends.md, plus colocated regression tests undertests/.Regression tests
Colocated tests fabricate a
state/<id>.metapointing at nonexistent tmux windows/sessions (dead-window-in-live-session and whole-session-gone cases) and assert dead/missing instead of the previous false ALIVE. Each new test fails on the pre-fix code and passes on this branch.Verification
Full no-mistakes pipeline run (review, test, document, lint) passed at head
51b38755; only the push step failed, due to the invoking machine's GitHub identity (KakkoiDev) lacking write access to kunchenguid/firstmate. Delivered manually via a personal fork per captain's instruction: pushedKakkoiDev:fm/fm-liveness-bug-r2, opening this PR against upstream.