docs(remote): describe parked route behavior
- commit
- ab24f6251c40d4e69f911c8e5917d06ea2492930
- author
- brice · · 2026-08-25 13:35 UTC
- parent
- 4ef812d
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
2 files · +24 -4
M AGENTS.md +1 -1
| @@ -64,7 +64,7 @@ Before touching daemon teardown paths, read the lock-ordering notes at the top o | |||
| 64 | 64 | Wire payload types/codecs live in `internal/ports/frame.go` and `internal/ports/wire.go`. Connection framing lives in `internal/adapters/ipc/transport.go`. | |
| 65 | 65 | ||
| 66 | 66 | - IPC frames on a connection are 4-byte big-endian length, 1 type byte, then payload. | |
| 67 | - | - Client message types occupy `1–13` (`MsgOutputResetRequest` is `13`) and `15` (`MsgRemotePreviewRequest`); server types occupy `16–23` (`MsgNavigationAction` is `23`) and `25–30` (`MsgAttachTarget`, `MsgRemotePreviewResponse`, `MsgCommittedRouteIdentity`, `MsgRecentRouteSnapshot`, `MsgNavigateRecentRoute`, and `MsgRouteNavigationFailure`). Types `14` and `24` remain reserved. | |
| 67 | + | - Client message types occupy `1–13`, `15`, `32–33`, and `35` (`MsgParkedRouteRequest`); server types occupy `16–23`, `25–31`, `34`, and `36` (`MsgParkedRouteResponse`). Types `14` and `24` remain reserved. | |
| 68 | 68 | - Version negotiation requires strict equality. | |
| 69 | 69 | - `Hello.Version` and `CommandRequest.Version` must stay first so their version peekers work. | |
| 70 | 70 | - Bump `ProtocolVersion` for any message layout change. | |
| @@ -64,7 +64,7 @@ Before touching daemon teardown paths, read the lock-ordering notes at the top o | |||||
| 64 | Wire payload types/codecs live in `internal/ports/frame.go` and `internal/ports/wire.go`. Connection framing lives in `internal/adapters/ipc/transport.go`. | 64 | Wire payload types/codecs live in `internal/ports/frame.go` and `internal/ports/wire.go`. Connection framing lives in `internal/adapters/ipc/transport.go`. | ||
| 65 | 65 | ||||
| 66 | - IPC frames on a connection are 4-byte big-endian length, 1 type byte, then payload. | 66 | - IPC frames on a connection are 4-byte big-endian length, 1 type byte, then payload. | ||
| 67 | - | - Client message types occupy `1–13` (`MsgOutputResetRequest` is `13`) and `15` (`MsgRemotePreviewRequest`); server types occupy `16–23` (`MsgNavigationAction` is `23`) and `25–30` (`MsgAttachTarget`, `MsgRemotePreviewResponse`, `MsgCommittedRouteIdentity`, `MsgRecentRouteSnapshot`, `MsgNavigateRecentRoute`, and `MsgRouteNavigationFailure`). Types `14` and `24` remain reserved. | 67 | + | - Client message types occupy `1–13`, `15`, `32–33`, and `35` (`MsgParkedRouteRequest`); server types occupy `16–23`, `25–31`, `34`, and `36` (`MsgParkedRouteResponse`). Types `14` and `24` remain reserved. |
| 68 | - Version negotiation requires strict equality. | 68 | - Version negotiation requires strict equality. | ||
| 69 | - `Hello.Version` and `CommandRequest.Version` must stay first so their version peekers work. | 69 | - `Hello.Version` and `CommandRequest.Version` must stay first so their version peekers work. | ||
| 70 | - Bump `ProtocolVersion` for any message layout change. | 70 | - Bump `ProtocolVersion` for any message layout change. | ||
M docs/remote-resilience.md +23 -3
| @@ -47,9 +47,26 @@ exact lifecycle target; the client confirms it with its remembered stable tab | |||
| 47 | 47 | cursor while holding raw input. The daemon either commits the fenced attachment | |
| 48 | 48 | transition and publishes the committed identity before the rebased full paint, | |
| 49 | 49 | or sends a typed pre-commit rejection and leaves the source attachment usable. | |
| 50 | - | No hostname, label, DNS result, or SSH alias authorizes reuse. Stopped, | |
| 51 | - | explicit-tab, cross-origin, and remote-to-remote selections retain direct | |
| 52 | - | close-and-dial handoff. | |
| 50 | + | No hostname, label, DNS result, or SSH alias authorizes reuse. Stopped and | |
| 51 | + | cross-origin targets outside the hybrid UDP flow retain direct close-and-dial | |
| 52 | + | handoff. | |
| 53 | + | ||
| 54 | + | A UDP attachment opening the hybrid home picker keeps its authenticated remote | |
| 55 | + | transport parked while a transient local connection renders the picker. The | |
| 56 | + | remote daemon suspends that attachment's rendered output only after a | |
| 57 | + | lease-bound prepare handshake, so the picker has sole terminal ownership and | |
| 58 | + | the client does not acknowledge screen updates it did not display. Terminal- | |
| 59 | + | external one-shot effects generated while parked, such as OSC 52 clipboard | |
| 60 | + | writes, are intentionally suppressed and are not replayed after Back or a | |
| 61 | + | switch; applying them later could affect a different terminal owner. Back | |
| 62 | + | resumes the parked attachment's current VT state with a full paint. Selecting a | |
| 63 | + | live or stopped session from the exact same configured endpoint sends the | |
| 64 | + | structured lifecycle/tab target over the parked transport; the serving daemon | |
| 65 | + | revalidates it and switches or restores with its persisted working directory | |
| 66 | + | and daemon-owned environment. Different endpoints and SSH stdio routes close | |
| 67 | + | and dial normally. While any switch takes longer than the short display | |
| 68 | + | threshold, the client overlays an animated switching or starting toast until | |
| 69 | + | the destination's authoritative output is flushed. | |
| 53 | 70 | ||
| 54 | 71 | ## Durable record compatibility | |
| 55 | 72 | ||
| @@ -82,6 +99,9 @@ picker selection changes. | |||
| 82 | 99 | - Each command request has a 10-second deadline for its result. A timeout | |
| 83 | 100 | abandons only that request; it does not complete a later request with a stale | |
| 84 | 101 | result. | |
| 102 | + | - Each parked-route control response and its required full paint have separate | |
| 103 | + | 15-second client deadlines. A parked lease expires after 15 minutes and | |
| 104 | + | closes only its exact retained transport generation. | |
| 85 | 105 | - Shared PTY content geometry follows the latest valid, non-superseded attach, | |
| 86 | 106 | resume, or resize claim. A later attachment can therefore replace the current | |
| 87 | 107 | shared geometry; if the winning attachment detaches, the most recently | |
| @@ -47,9 +47,26 @@ exact lifecycle target; the client confirms it with its remembered stable tab | |||||
| 47 | cursor while holding raw input. The daemon either commits the fenced attachment | 47 | cursor while holding raw input. The daemon either commits the fenced attachment | ||
| 48 | transition and publishes the committed identity before the rebased full paint, | 48 | transition and publishes the committed identity before the rebased full paint, | ||
| 49 | or sends a typed pre-commit rejection and leaves the source attachment usable. | 49 | or sends a typed pre-commit rejection and leaves the source attachment usable. | ||
| 50 | - | No hostname, label, DNS result, or SSH alias authorizes reuse. Stopped, | 50 | + | No hostname, label, DNS result, or SSH alias authorizes reuse. Stopped and |
| 51 | - | explicit-tab, cross-origin, and remote-to-remote selections retain direct | 51 | + | cross-origin targets outside the hybrid UDP flow retain direct close-and-dial |
| 52 | - | close-and-dial handoff. | 52 | + | handoff. |
| 53 | + | ||||
| 54 | + | A UDP attachment opening the hybrid home picker keeps its authenticated remote | |||
| 55 | + | transport parked while a transient local connection renders the picker. The | |||
| 56 | + | remote daemon suspends that attachment's rendered output only after a | |||
| 57 | + | lease-bound prepare handshake, so the picker has sole terminal ownership and | |||
| 58 | + | the client does not acknowledge screen updates it did not display. Terminal- | |||
| 59 | + | external one-shot effects generated while parked, such as OSC 52 clipboard | |||
| 60 | + | writes, are intentionally suppressed and are not replayed after Back or a | |||
| 61 | + | switch; applying them later could affect a different terminal owner. Back | |||
| 62 | + | resumes the parked attachment's current VT state with a full paint. Selecting a | |||
| 63 | + | live or stopped session from the exact same configured endpoint sends the | |||
| 64 | + | structured lifecycle/tab target over the parked transport; the serving daemon | |||
| 65 | + | revalidates it and switches or restores with its persisted working directory | |||
| 66 | + | and daemon-owned environment. Different endpoints and SSH stdio routes close | |||
| 67 | + | and dial normally. While any switch takes longer than the short display | |||
| 68 | + | threshold, the client overlays an animated switching or starting toast until | |||
| 69 | + | the destination's authoritative output is flushed. | |||
| 53 | 70 | ||||
| 54 | ## Durable record compatibility | 71 | ## Durable record compatibility | ||
| 55 | 72 | ||||
| @@ -82,6 +99,9 @@ picker selection changes. | |||||
| 82 | - Each command request has a 10-second deadline for its result. A timeout | 99 | - Each command request has a 10-second deadline for its result. A timeout | ||
| 83 | abandons only that request; it does not complete a later request with a stale | 100 | abandons only that request; it does not complete a later request with a stale | ||
| 84 | result. | 101 | result. | ||
| 102 | + | - Each parked-route control response and its required full paint have separate | |||
| 103 | + | 15-second client deadlines. A parked lease expires after 15 minutes and | |||
| 104 | + | closes only its exact retained transport generation. | |||
| 85 | - Shared PTY content geometry follows the latest valid, non-superseded attach, | 105 | - Shared PTY content geometry follows the latest valid, non-superseded attach, | ||
| 86 | resume, or resize claim. A later attachment can therefore replace the current | 106 | resume, or resize claim. A later attachment can therefore replace the current | ||
| 87 | shared geometry; if the winning attachment detaches, the most recently | 107 | shared geometry; if the winning attachment detaches, the most recently | ||