docs(review 006 Unit 4): spec reconciliation — OQ-05 resolved, WS data-channel docs to the landed state

- OQ-05: deferred → resolved (2026-09-04, review 006 Unit 2+3); the
  consumer-set reframe recorded (WS is also the native-client fallback
  behind hostile NAT/firewall; OQ-04 does not block the wiring).
- ADR-067: status amendment + the v1-cut blockquote gains the Wired
  (2026-09-04) note — per-session-fork shape, openable surface, gates.
- ADR-048: landed-state amendment — §4's hub→browser direction has its
  object (op/register → connection overlay, hub composes via the
  retained Arc<CallConnection>); the op/register ACL posture (UP-02,
  SRV-10 precedent) recorded.
- websocket.md: the step-7 deferral note and the §"Data channels for
  browsers" status block removed (the section now documents the landed
  surface: with_ws_openable_alpns, the OpenableAlpns fallback, cap
  policy, discovery, gates); idle-knob deployment note for silent data
  channels (semantics unchanged; the 60 s default bites more often —
  set None at assembly for long-lived interactive channels).
- Review 003 status → remediated (all findings closed; log in review
  006); its Unit-4 section marked landed.
- alknet-ADR-044 §5 pointer checked: not stale.

Verification: cargo test 454 / 0; --all-features 582 / 0; clippy
(both) clean; fmt clean; doc clean.
This commit is contained in:
2026-09-04 16:17:11 +00:00
parent 2053420f7d
commit 64fa10be31
5 changed files with 100 additions and 33 deletions
+29 -8
View File
@@ -1,6 +1,6 @@
---
status: draft
last_updated: 2026-08-30
last_updated: 2026-09-04
---
# WebSocket — the Browser Bidirectional Path (Channels over WS)
@@ -89,8 +89,12 @@ route on `HttpAdapter`'s router. The handler:
7. Data channels (1..N) route per the deployment's openable-ALPN
registrations; the browser opens them via the per-ALPN open ops on
channel 0 (alkcall ADR-047), the same mechanism any consumer uses.
*(Deferred wiring, v1 cut — see [OQ-05](open-questions.md);
step 6, channel 0, is all v1 implements.)*
Wired 2026-09-04 (review 006 Unit 2+3): the hook registers the
deployment's openables — `HttpAdapter::with_ws_openable_alpns`
(default: none) or the `OpenableAlpns` request-extension fallback —
plus the generic channel ops, the bootstrap discovery set, and
`op/register`, on the per-session fork (alkcall ADR-047 §4
amendment #2).
The **default upgrade path is `/alk/channels`** (was `/alknet/call` in
the alknet design). The path must not collide with the reserved
@@ -209,6 +213,17 @@ strict**:
the same deployment posture as `from_wss`'s drop monitor
([ADR-070](decisions/070-from-wss-consumer-adapter.md)): the idle
knob bounds *demux parking*, not app liveness.
- **Data channels sharpen this knob's bite** (surfaced with the
data-channel wiring, review 006): a silent-but-alive *data channel*
(an idle SSH-style session, an open-but-quiet tunnel) forwards no
chunks, so the deadline runs out and the whole WS session is evicted
with `1001` — exactly the same semantics as before the wiring
(this is not a new rule), but the 60 s default now hits more often
because sessions live longer and carry quiet channels. A deployment
serving long-lived interactive channels should set
`with_ws_idle_timeout(None)` at assembly and lean on the same levers
as above; the idle knob remains a demux-parking bound, not an
application keepalive.
- Layered note (the WS-13/FWD-15 interaction recorded here): the
*HTTP* SSE path (`/subscribe`) sends server-side keep-alive comment
frames every 15 s — see
@@ -243,11 +258,6 @@ before ACL). This is alkcall ADR-017's model; see also
### Data channels for browsers
> **Status (2026-08-29):** decided design, deferred wiring — the v1 WS
> path installs channel 0 only; browser data-channel opens are not yet
> wired (review-001, WS-03; [OQ-05](open-questions.md)). The mechanism
> below is the contract the deferred wiring implements.
A browser opens a data channel exactly as any channels consumer:
1. Calls the per-ALPN open op on channel 0
@@ -264,6 +274,17 @@ This is what makes the WASM-SSH-client-in-a-browser use case (the one
that motivated the alknet WebTransport track) workable over WS: the
SSH byte stream rides a data channel.
The openable set is declared with `HttpAdapter::with_ws_openable_alpns`
(each `OpenableAlpn { spec, open_handler }`; the ALPN-specific handlers
stay in the ALPN crates — alkhttp ferries the registrations), with the
`OpenableAlpns` request-extension fallback for bare-registry/custom
upgrade routes. Cap policy is the `ChannelsPolicy` extension (one
instance consulted by both the open wrappers and the demux teardown).
Peer-announced ops (`op/register`) land in the connection-local
overlay; discovery: `services/list` (the session's own surface) and
`services/list-peers` (peer-announced ops, alkcall 0.3.1). E2E gates
for the whole flow live in `tests/ws_upgrade_session.rs`.
### Bidirectionality
The WS channels session inherits both protocols' native