BaseTmuxBackend.version() collapses every probe failure to None:
try:
raw = self._tmux("-V")
except (MultiplexerError, subprocess.SubprocessError, OSError):
return None
A binary that is on PATH but crashes on -V — corrupt install, AV-blocked exe, a hung server making the probe time out — reads exactly like a binary that reports no version. Downstream, bmad-loop mux renders AVAILABLE no / VERSION -, indistinguishable from missing pwsh or an unparseable version, and the probe's stderr is gone. The catch types themselves are correctly narrow; what's lost is the failure's identity.
Suggested direction: keep version()'s None contract (observation may degrade), but surface the dropped diagnostic where an operator already looks — e.g. a warning: line in cmd_mux / a diagnostics field when the binary is present on PATH yet version() is None, carrying the probe's exception or stderr.
Pre-existing behavior, not introduced by #427 — that PR only re-flowed the catch. Cross-cutting, so tracked separately per repo practice
BaseTmuxBackend.version()collapses every probe failure toNone:A binary that is on PATH but crashes on
-V— corrupt install, AV-blocked exe, a hung server making the probe time out — reads exactly like a binary that reports no version. Downstream,bmad-loop muxrenders AVAILABLEno/ VERSION-, indistinguishable from missingpwshor an unparseable version, and the probe's stderr is gone. The catch types themselves are correctly narrow; what's lost is the failure's identity.Suggested direction: keep
version()'sNonecontract (observation may degrade), but surface the dropped diagnostic where an operator already looks — e.g. awarning:line incmd_mux/ a diagnostics field when the binary is present on PATH yetversion()isNone, carrying the probe's exception or stderr.Pre-existing behavior, not introduced by #427 — that PR only re-flowed the catch. Cross-cutting, so tracked separately per repo practice