Parent: #28
Remaining scope from #30, split out because #46 (the multi-pairing fan-out fix) closed #30 by its own Fixes #30 keyword even though this part wasn't built yet.
relay:use capability
Gates who may ask an ordinary, opted-in node to relay for them -- scope kind node, token required, same rationale class as webrtc:signal/room:member: using a volunteer's bandwidth/connectivity has a real receiver-side cost. A dedicated hub deployment (wire-mesh-node/cloudflare-hub) can reasonably stay open to anyone gossiped, the way it works today; an ordinary opted-in node can require this token before accepting relay requests from strangers. Blocked by #102: enforcing this needs relay-hub.ts restructured to consume manage-request frames alongside relay frames, which it doesn't do today (it drops them outright).
Client-side no-relay opt-out -- confirmed already done, no further work needed
? direct-only: bool on relay-connect-frame was tried during #46 and reverted -- it has no coherent hub-side meaning, since relay-hub only ever receives relay-connect once the sender has already decided to relay. The real decision point is upstream: whether sendManageRequest's own targetDevice-triggered relay-routing path gets called at all.
Confirmed by reading the actual shipped code (mesh-session.ts's sendManageRequest, room-client.ts's sendRoomMessage/requestToJoin): targetDevice is optional throughout, and targetDevice !== undefined is the sole trigger for relay wrapping (ensureRelayPairing + transmit(frame, true)). A caller that omits it gets transmit(frame, false) -- always direct, never relay. room-client.ts's own doc comment already states this plainly ("omit it for a session that already is the direct connection"). This is exactly the opt-out described here, delivered as a natural consequence of #32's own API design, not a separate feature that still needs building.
This issue's own remaining scope is therefore just the relay:use capability above, blocked by #102.
Full detail: the plan file's section B, and #30's own now-superseded body.
Parent: #28
Remaining scope from #30, split out because #46 (the multi-pairing fan-out fix) closed #30 by its own
Fixes #30keyword even though this part wasn't built yet.relay:use capability
Gates who may ask an ordinary, opted-in node to relay for them -- scope kind
node, token required, same rationale class aswebrtc:signal/room:member: using a volunteer's bandwidth/connectivity has a real receiver-side cost. A dedicated hub deployment (wire-mesh-node/cloudflare-hub) can reasonably stay open to anyone gossiped, the way it works today; an ordinary opted-in node can require this token before accepting relay requests from strangers. Blocked by #102: enforcing this needsrelay-hub.tsrestructured to consume manage-request frames alongside relay frames, which it doesn't do today (it drops them outright).Client-side no-relay opt-out -- confirmed already done, no further work needed
? direct-only: boolonrelay-connect-framewas tried during #46 and reverted -- it has no coherent hub-side meaning, sincerelay-hubonly ever receivesrelay-connectonce the sender has already decided to relay. The real decision point is upstream: whethersendManageRequest's owntargetDevice-triggered relay-routing path gets called at all.Confirmed by reading the actual shipped code (
mesh-session.ts'ssendManageRequest,room-client.ts'ssendRoomMessage/requestToJoin):targetDeviceis optional throughout, andtargetDevice !== undefinedis the sole trigger for relay wrapping (ensureRelayPairing+transmit(frame, true)). A caller that omits it getstransmit(frame, false)-- always direct, never relay.room-client.ts's own doc comment already states this plainly ("omit it for a session that already is the direct connection"). This is exactly the opt-out described here, delivered as a natural consequence of #32's own API design, not a separate feature that still needs building.This issue's own remaining scope is therefore just the relay:use capability above, blocked by #102.
Full detail: the plan file's section B, and #30's own now-superseded body.