Skip to content

(remote): probe tmux and inotifywait and gate affordances by tier (#218) - #425

Merged
devsuitup merged 2 commits into
mainfrom
feat/218-probe-tier-gates
Oct 3, 2026
Merged

devsuitup merged 2 commits into
mainfrom
feat/218-probe-tier-gates

Conversation

@devsuitup

@devsuitup devsuitup commented Oct 3, 2026 •

Copy link
Copy Markdown
Owner

Second slice of #218 (items 1 and 2 of the remaining scope; items 3 and 4 stay open). Refs #218.

What changed

  • Probe. PROBE_COMMAND is its own ssh command (LIST_COMMAND is not widened): command -v tmux and command -v inotifywait, answered as two booleans. transport.probeTools(alias) goes through the same run() as the other calls (same ssh binary, BatchMode, ConnectTimeout, no new spawn site), with a 15 s timeout and a 1 KiB output cap, and throws on a non-zero exit or any output other than the two lines.
  • Schedule. The indexer probes at the end of a successful host refresh, at most every 6 h while both tools are present and every 30 min while one is missing (so an install is noticed); a failure is retried after 30 min, keeps the previous answer and never fails the refresh. Reconnect re-arms it. A changed answer notifies the renderer.
  • Profile. computeHostProfile takes tools (true / false / null) and returns blocked and tools. tmux === true makes attach available on an idle host; tmux === false makes it unavailable even when a descriptor names a pane (attach runs a bare tmux over the same non-interactive ssh). Unknown never withholds anything.
  • Gates. Attach: attachBlockReason keeps the three-failure fallback (it wins) and adds the tmux reason; the row opens its transcript and the tooltip gives the reason. Send a prompt: sendBlockReason disables the button with the inject reason on a host that was read. New session: the disabled button's title now gives the launch tier's reason. The host tooltip says when only the periodic pull runs (no inotifywait). Stop is untouched.

Tests

New: remote-transport-probe, remote-index-probe, annotate-remote-tier-gates, dom-sidebar-remote-tier-gates, and additions to remote-host-profile. Each was run red before the code (missing function / property). The probe command is also run through a real sh with command -v answered by shell functions. annotate-remote-attachable-local-status.test.js only gained the new sendBlockReason parameter in its function factory.

Mutations, 26 in all (two more for the missing-tool re-probe delay), one per guard, each killed: tmux-false reason, tmux-true availability, attachBlockReason tmux branch and its precedence against the failure fallback, sendBlockReason blocked guard, tool-flag normalisation, parseProbe line count and value strictness, probe timeout, exit code, output cap, ssh options, probe interval, retry delay, keep-on-failure, change notification, re-arm on reconnect, alias pruning, missing probeTools, remoteSendBlocked in main.js, send handler guard, disabled button, inotifywait line, launch reason title. Two survived the first test set (change notification, transport without probeTools) and got an assertion each.

task check: exit 0 (3091 + 119 passing). One earlier run failed git-changes-runner-real-git (leaf symlink to a file), which passes alone and on the rerun.

Not verified

  • No real host: the probe was run through a local sh, not over ssh. command -v over a non-interactive ssh on a host whose login shell is not POSIX (fish) is untested.
  • Inject is gated per host (some live session reports a socket), not per session: a session without its own socket on a host where another has one is still offered Send.
  • Stop has no gate and no mutation: it is pinned by tests that it carries none.

Changelog

One line under Unreleased, Changed.

…ssion by tier

A remote host's affordances were decided row by row from descriptors, so a
host without tmux still offered attach and an idle host with tmux read as
missing it. One light ssh per host, at the first successful refresh and
then every six hours, now reports whether tmux and inotifywait are
installed; a failed probe leaves the profile unknown. Attach is withheld
while tmux is known missing, Send a prompt is disabled with the inject
reason, and the new-session button states the launch tier's reason. Stop
is untouched.

Refs #218
@devsuitup

Copy link
Copy Markdown
Owner Author

Reviewing dab589b (adversarial review in progress).

@devsuitup devsuitup left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adversarial review at dab589b: 0 blocking. PROBE_COMMAND is a constant passed as a separate argv element through the same run() (BatchMode, no local shell). The parser accepts exactly two name=0|1 lines. A banner, a non-POSIX shell or an oversized output leaves the host unknown, which never withholds. Withholding attach on tmux=false is correct: attach runs a bare tmux over the same non-interactive ssh. The probe piggybacks on refreshHost, serialised per host and rate-limited. All 6 mutations replayed were killed. Being fixed: a false answer is kept for 6 h, so it now re-probes at the 30 min interval, plus a CHANGELOG wording fix.

A false answer was kept for six hours, so attach stayed withheld long
after tmux was installed. A host with a missing tool is now asked again
after 30 minutes; one with both present keeps the six-hour interval.

Refs #218

@devsuitup devsuitup left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-review at 6058d62 (delta from dab589b): 0 blocking. The interval stays 6 h only when the probe succeeded and both tools are present. A missing tool or a failed probe re-asks after 30 min, and both mutations are killed. CHANGELOG wording fixed.

@devsuitup
devsuitup merged commit 90464ad into main Oct 3, 2026
16 of 17 checks passed
@devsuitup
devsuitup deleted the feat/218-probe-tier-gates branch October 3, 2026 08:10
@devsuitup devsuitup mentioned this pull request Oct 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant