443 relay

The data plane for NAT-bound devices: both ends dial outbound through a WebSocket bridge on port 443.

Phones behind carrier NAT can't accept inbound connections, and edges like Cloudflare only pass ports 80/443. The 443 relay solves both: a per-edge WebSocket bridge with a 1-byte role preamble lets both sides dial outbound, so a phone participates in the data plane while opening zero inbound ports.

Two outbound dials meet in the middle; the preamble says who is who.

phone   ──outbound──▶ wss://edge:443  ◀──outbound── backbone
                     [role byte: worker]   [role byte: dialer]
        bridge splices the two streams → one ordinary TCP pipe
Hardened in production

Three real bugs, three fixes

  • Build-fingerprint agreement — both ends must prove they run the same runtime pack before any tensor bytes flow.
  • Node-token download auth — partial-shard downloads are authenticated with the same wallet-derived node token the app already holds.
  • The `Int.ushr` frame stall — Kotlin's ushr uses only the low 5 bits of its shift, so len ushr 56 became len ushr 24 and silently corrupted every frame ≥ 64 KiB (a 593 KB result_output was the first casualty). Fixed by moving length packing to Long shifts — and load-bearing for batched expert dispatch, which routinely exceeds 64 KiB.

The relay carries whatever the topology needs — ring layer boundaries or expert dispatch streams — and the same mechanism verified for the ring is what production phone workers use in the swarm.

Both /api/expert-relay and /api/ring-relay upgrades are raw-spliced: the gateway forwards WebSocket frames byte-for-byte without parsing them, so the relay stays a thin, model-agnostic pipe. It still meters the bytes it bridges per session, and that measured work flows into the hub's contribution ledger and settles to the worker's own wallet in KVR — relaying for a NAT'd phone earns exactly like a direct-connected node.