2bf682e2
docs: mux HOST starts the daemon it did not find; nothing else does
a73x 2026-08-28 19:53
Commit message
README.md
| Old | New | ||
|---|---|---|---|
| @@ -190,7 +190,13 @@ mux HOST # attach; Ctrl-\ d detaches, running it again reattaches | |||
| 190 | is safe to run every time — if one is already up it says so and exits 0. | 190 | is safe to run every time — if one is already up it says so and exits 0. |
| 191 | 191 | ||
| 192 | `mux HOST` runs `muxd endpoint` on HOST over ssh (finding a muxd in | 192 | `mux HOST` runs `muxd endpoint` on HOST over ssh (finding a muxd in |
| 193 | `~/.local/bin` even though ssh's non-login shell leaves it off PATH) — | 193 | `~/.local/bin` even though ssh's non-login shell leaves it off PATH). On a |
| 194 | box with no daemon that verb answers nothing, and `mux HOST` runs `muxd | ||
| 195 | start` there once, over the same ssh, before asking again — so the | ||
| 196 | `ssh HOST 'muxd start'` line above is optional after the first time. | ||
| 197 | Nothing else starts a daemon: the wall's per-host poll, `mux hosts`, every | ||
| 198 | reconnect and `mux --via 'ssh HOST muxd proxy'` all report the box | ||
| 199 | unreachable and leave it alone. Your | ||
| 194 | ssh config (aliases, ports, | 200 | ssh config (aliases, ports, |
| 195 | ProxyJump) all keeps working, since `mux` never parses HOST. That ssh | 201 | ProxyJump) all keeps working, since `mux` never parses HOST. That ssh |
| 196 | fetches the daemon's QUIC port and key once and the session moves onto | 202 | fetches the daemon's QUIC port and key once and the session moves onto |
docs/decisions.md
| Old | New | ||
|---|---|---|---|
| @@ -7357,3 +7357,22 @@ A slot is free only once its pump has RETURNED (`Tile.pump_done`): `present` | |||
| 7357 | alone hands a `*Tile` a returning thread is still reading to a new tile. Its | 7357 | alone hands a `*Tile` a returning thread is still reading to a new tile. Its |
| 7358 | doorbell pipe stays with it — never closed, so a fresh one per reuse leaks an | 7358 | doorbell pipe stays with it — never closed, so a fresh one per reuse leaks an |
| 7359 | fd pair — and `live` becomes the high-water mark, growth counted in `present`. | 7359 | fd pair — and `live` becomes the high-water mark, growth counted in `present`. |
| 7360 | |||
| 7361 | ## 2026-08-28 — a daemon starts when somebody asks, never from a read | ||
| 7362 | |||
| 7363 | `muxd endpoint` auto-started a daemon before answering, and the wall runs it | ||
| 7364 | over ssh once a second per listed host: a listed box with nothing on it got a | ||
| 7365 | daemon and a shell in session 0 from a READ, and a `muxd stop` typed there was | ||
| 7366 | undone a second later. `muxd proxy` had the same call. | ||
| 7367 | |||
| 7368 | Both now refuse an empty box. The ASK moves to the client, on the dial a user | ||
| 7369 | waited for — `mux HOST`'s entry, the picker's Enter — which runs `ssh HOST | ||
| 7370 | 'muxd start'` from the same `handoff.recipeFor` and reads the announce once | ||
| 7371 | more. `HandoffTarget.asked` carries that permission and gates the fallback | ||
| 7372 | line with it; `wallview.dial` spends it on the first attempt, so a start per | ||
| 7373 | backoff is unreachable. The local client's own `spawn.ensureForAttach` is | ||
| 7374 | unchanged. | ||
| 7375 | |||
| 7376 | The break, deliberate: an OLD client against a new remote no longer gets a | ||
| 7377 | daemon from a cold `mux HOST` — the user runs `ssh HOST 'muxd start'`, as | ||
| 7378 | README already said. `test/xversion.sh` has no cold-HOST probe. | ||