v0.1.0 7deb448

remote-resilience.md RawHistoryFolder

Remote resilience

Remote attach starts with SSH bootstrap and then carries the vev session over authenticated UDP. The design is inspired by mosh's mobile-shell resilience, but vev uses its own protocol and is not compatible with mosh clients or servers.

The raw UDP AEAD key is never persisted by vev; the proxy registry stores only its SHA-256 ownership fingerprint. During bootstrap, the key briefly exists in memory in the proxy, the _udp-bootstrap relay, the client, and associated SSH/readiness I/O and string buffers. vev promptly clears reachable key buffers after handoff on a best-effort basis. Builds made with Go 1.26 and GOEXPERIMENT=runtimesecret additionally protect key-handling call trees with runtime/secret on linux/amd64 and linux/arm64; on unsupported platforms, runtime/secret calls the function directly. These protections do not cover globals, goroutines started by protected calls, copies retained by I/O implementations, or key material retained in cipher state.

Operational model

  • SSH bootstrap starts or finds the remote UDP endpoint.
  • UDP carries normal session traffic after bootstrap. The remote proxy binds a port in a fixed range, 61000-61023 by default; VEV_UDP_PORT_RANGE overrides it (a range, a single port, or 0 for a random ephemeral port).
  • Named sessions remain recoverable across daemon restarts; ephemeral sessions remain recoverable only while the daemon retains them.
  • VEV_REMOTE_TRANSPORT=stdio keeps all traffic inside SSH when direct UDP is blocked.

Recovery states

Resilience work uses these user-facing states:

State Meaning
connected a complete record or meaningful ACK progress is recent
degraded authenticated UDP packets still arrive, but complete-record or ACK progress is delayed
probing authenticated UDP packet contact is absent, so vev probes for path recovery
resuming a replacement transport is attaching to the same session
offline authenticated UDP contact remains absent; vev re-runs the SSH bootstrap and re-dials UDP with the resume token
expired the session or recovery window is no longer available

When a terminal is in raw mode, recovery messages appear as vev status text rather than as bytes written into the remote program's output stream.

VEV_REMOTE_TRANSPORT=stdio is the SSH-stdio fallback: it keeps the session inside authenticated SSH when UDP is blocked or unavailable. It remains available while UDP recovery is attempted.

UDP transport health diagnostics

At debug logging, UDP transport-health lines report only state, elapsed progress ages, and bounded transport counters; they do not include payloads, addresses, keys, or identities. For a real remote attempt, scripts/debug-remote-attach.sh --udp-health user@host stores redacted transport-health lines and Linux ss -u -m socket-memory counters, then prints the exact collected file paths.

Manual checks

Useful scenarios for validating resilience behavior:

  • block and unblock the configured UDP port range;
  • move between networks or change VPN state;
  • suspend and resume the client machine;
  • retry vev attach user@host:session for the same named session;
  • compare logs for UDP silence, probing, SSH bootstrap failure, proxy expiry, and missing sessions.

Keep hostnames, usernames, and local paths out of shared logs and screenshots.

source
1# Remote resilience
2
3Remote attach starts with SSH bootstrap and then carries the vev session over authenticated UDP. The design is inspired by mosh's mobile-shell resilience, but vev uses its own protocol and is not compatible with mosh clients or servers.
4
5The raw UDP AEAD key is never persisted by vev; the proxy registry stores only its SHA-256 ownership fingerprint. During bootstrap, the key briefly exists in memory in the proxy, the `_udp-bootstrap` relay, the client, and associated SSH/readiness I/O and string buffers. vev promptly clears reachable key buffers after handoff on a best-effort basis. Builds made with Go 1.26 and `GOEXPERIMENT=runtimesecret` additionally protect key-handling call trees with `runtime/secret` on linux/amd64 and linux/arm64; on unsupported platforms, `runtime/secret` calls the function directly. These protections do not cover globals, goroutines started by protected calls, copies retained by I/O implementations, or key material retained in cipher state.
6
7## Operational model
8
9- SSH bootstrap starts or finds the remote UDP endpoint.
10- UDP carries normal session traffic after bootstrap. The remote proxy binds a port in a fixed range, `61000-61023` by default; `VEV_UDP_PORT_RANGE` overrides it (a range, a single port, or `0` for a random ephemeral port).
11- Named sessions remain recoverable across daemon restarts; ephemeral sessions remain recoverable only while the daemon retains them.
12- `VEV_REMOTE_TRANSPORT=stdio` keeps all traffic inside SSH when direct UDP is blocked.
13
14## Recovery states
15
16Resilience work uses these user-facing states:
17
18| State | Meaning |
19| --- | --- |
20| `connected` | a complete record or meaningful ACK progress is recent |
21| `degraded` | authenticated UDP packets still arrive, but complete-record or ACK progress is delayed |
22| `probing` | authenticated UDP packet contact is absent, so vev probes for path recovery |
23| `resuming` | a replacement transport is attaching to the same session |
24| `offline` | authenticated UDP contact remains absent; vev re-runs the SSH bootstrap and re-dials UDP with the resume token |
25| `expired` | the session or recovery window is no longer available |
26
27When a terminal is in raw mode, recovery messages appear as vev status text rather than as bytes written into the remote program's output stream.
28
29`VEV_REMOTE_TRANSPORT=stdio` is the SSH-stdio fallback: it keeps the session inside authenticated SSH when UDP is blocked or unavailable. It remains available while UDP recovery is attempted.
30
31## UDP transport health diagnostics
32
33At debug logging, UDP transport-health lines report only state, elapsed progress ages, and bounded transport counters; they do not include payloads, addresses, keys, or identities. For a real remote attempt, `scripts/debug-remote-attach.sh --udp-health user@host` stores redacted transport-health lines and Linux `ss -u -m` socket-memory counters, then prints the exact collected file paths.
34
35## Manual checks
36
37Useful scenarios for validating resilience behavior:
38
39- block and unblock the configured UDP port range;
40- move between networks or change VPN state;
41- suspend and resume the client machine;
42- retry `vev attach user@host:session` for the same named session;
43- compare logs for UDP silence, probing, SSH bootstrap failure, proxy expiry, and missing sessions.
44
45Keep hostnames, usernames, and local paths out of shared logs and screenshots.

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 12

Tags 11

↑↓ moveenter openesc close