[filed by the maintainer's AI agent while debugging linux-in-the-browser#94 fallout]
WebSocketPacketNaasUplink (src/devices/web_socket_packet_uplink.ts) tears down on WS close and never reconnects — after any relay-side drop (deploy roll of naas-l3-production has a documented brief gap; network blips; and, until today's relay fix, any full-size guest TCP segment) the guest keeps its interface but every packet goes to sDrops forever. The user-visible shape: "[naas] VPN disconnected: relay connection closed", then every later network command (ssh, wget) silently hangs until the machine is relaunched.
Witnessed live 2026-07-15: the relay's old WS read limit (mtu+64) 1009-failed the session on the first ~1500-byte upload segment (openssl 3.5 TLS ClientHello via the new ports wget); the uplink then stayed dead, which is why ssh -T git@github.com hung on machines where wget had already killed the VPN. The relay-side trigger is fixed (brintos-web 1d3ebcb: 64 KiB read limit + bidirectional TCP MSS clamping to mtu-40, RED-flip regression test in 8e57f0e), but the uplink should still self-heal.
Sketch: on non-closedByUs close, reconnect with expo backoff + jitter, re-HELLO with a fresh token (the mint callback already exists — opts.token is a function), resume forwarding on HELLO_OK. The assigned egress IP will change (existing flows RST/timeout end-to-end — acceptable, same as a real VPN rebind). Emit "[naas] L3 uplink: reconnecting (attempt N)" so the state is visible. A REFRESH-style session resume that keeps the assigned IP would be a nicer follow-on but needs relay-side session affinity.