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:
@@ -36,6 +36,21 @@ Accepted
|
||||
> replace other peer-announced ops but never the serving side's own
|
||||
> registrations — the WS session's `op/register` handler gates on the
|
||||
> session fork.
|
||||
>
|
||||
> **Landed (2026-09-04, review 006 Unit 2+3):** the WS wiring this
|
||||
> note tracks is in — the hook forks the base registry per session,
|
||||
> registers the channel ops + openables + bootstrap discovery +
|
||||
> `op/register` on the fork, and dispatches over it; the session
|
||||
> retains its live `Arc<CallConnection>` in `WsSessions` (the hub's
|
||||
> reach-the-browser handle). §4's hub→browser call direction now has
|
||||
> its object: announced ops land in the connection overlay via
|
||||
> `op/register`, and the hub composes them through the connection
|
||||
> handle (gate:
|
||||
> `op_register_served_per_session_and_collision_is_already_exists`).
|
||||
> The `op/register` ACL posture on this surface: registered with
|
||||
> `AccessControl::default()` (the SRV-10 permissive-crate-default
|
||||
> precedent); deployments gate via a stricter `ChannelsPolicy`
|
||||
> passed through the hook (review 006 UP-02 decision).
|
||||
|
||||
## Status amendment (alkhttp port)
|
||||
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
## Status
|
||||
|
||||
Accepted (amended 2026-08-29 — the data-channel half of the WS path is
|
||||
deferred, not yet wired; see [OQ-05](../open-questions.md))
|
||||
deferred, not yet wired; see [OQ-05](../open-questions.md); amended
|
||||
2026-09-04 — the deferred wiring landed, review 006 Units 2–3)
|
||||
|
||||
## Context
|
||||
|
||||
@@ -106,6 +107,18 @@ On upgrade, the handler:
|
||||
> sessions (review-001, WS-03). The deferral and its rationale are
|
||||
> recorded in [OQ-05](../open-questions.md); the design above is the
|
||||
> contract the deferred wiring implements.
|
||||
>
|
||||
> **Wired (2026-09-04):** step 4 landed (review 006 Unit 2+3) in the
|
||||
> per-session-fork shape alkcall ADR-047 §4 amendment #2 decided: the
|
||||
> `install_channel_zero` hook forks the deployment's base registry,
|
||||
> registers the generic channel ops + the deployment's openables
|
||||
> (`HttpAdapter::with_ws_openable_alpns`, request-extension fallback)
|
||||
> + the bootstrap discovery set + `op/register` on the fork, and
|
||||
> dispatches over it. Openable set default: none (channel 0 only).
|
||||
> The session retains its live `Arc<CallConnection>` in `WsSessions`
|
||||
> (WS-26). Gates: the six e2e scenarios in
|
||||
> `tests/ws_upgrade_session.rs` + the `services/list-peers` announced-op
|
||||
> discovery gate (alkcall 0.3.1).
|
||||
|
||||
Everything ADR-048 says about dispatch — `call.requested` →
|
||||
`Dispatcher::dispatch_requested` with `AccessControl::check` gating,
|
||||
@@ -169,7 +182,7 @@ in-line channels session:
|
||||
- [websocket.md](../websocket.md) — the full WS session spec (its
|
||||
§"Data channels for browsers" carries the same v1-cut note)
|
||||
- [OQ-05](../open-questions.md) — the data-channel v1 cut deferral
|
||||
(status `deferred(scope)`; reopened when a browser consumer lands)
|
||||
(resolved 2026-09-04: the wiring landed, review 006 Units 2–3)
|
||||
- [ADR-048](048-websocket-native-session-not-gateway.md) — the native
|
||||
session (not gateway shape) decision this ADR amends (channel 0
|
||||
framing; upgrade path)
|
||||
|
||||
@@ -80,8 +80,8 @@ with their resolutions; new alkhttp OQs start at OQ-01.
|
||||
- **Origin**: review-001 finding WS-03 (`docs/reviews/001-initial-implementation-review.md`),
|
||||
[ADR-067](decisions/067-websocket-carries-channels.md),
|
||||
[ADR-048](decisions/048-websocket-native-session-not-gateway.md)
|
||||
- **Status**: deferred(scope: v1 cut — no browser consumer yet; reopened
|
||||
when one lands)
|
||||
- **Status**: resolved (2026-09-04 — review 006 Unit 2+3, `030c5ef`;
|
||||
upstream mechanisms in alkcall 0.3.0)
|
||||
- **Priority**: medium
|
||||
- **Question**: ADR-067 §"Data channels for browsers" promises
|
||||
browser-opened data channels (open ops on channel 0 → chunk
|
||||
@@ -96,25 +96,37 @@ with their resolutions; new alkhttp OQs start at OQ-01.
|
||||
deferred is the *wiring*: passing the deployment's openable-ALPN
|
||||
registrations and `ChannelLifecyclePolicy` through the WS upgrade
|
||||
path, plus a browser-opened-channel end-to-end test.
|
||||
- **Resolution**: (pending — v1 cut recorded 2026-08-29 in ADR-067 and
|
||||
ADR-048; the recently landed WS robustness work — idle-read timeout,
|
||||
session caps/eviction, pump consolidation — is the foundation the
|
||||
deferred work builds on. **2026-09-03**: the alkcall mechanisms this
|
||||
wiring composes on landed — alkcall review 004 Units 1–3: the
|
||||
per-session fork as dispatch registry (alkcall ADR-047 §4 amendment
|
||||
#2), the opt-in connect-side serving loop
|
||||
(`Dispatcher::serve_single_stream`), and the `op/register` bootstrap
|
||||
op (alkcall ADR-022 amendment 2026-09-03). **2026-09-04**: alkcall
|
||||
review 005 remediated the landed mechanisms (serving-loop
|
||||
concurrency, `op/register` collision policy, spec round-trip
|
||||
completeness) and alkcall 0.3.0 shipped them; alkhttp now consumes
|
||||
0.3. What remains here is alkhttp-side wiring only — alkhttp review
|
||||
003 Unit 2.)
|
||||
- **Resolution**: The wiring landed (2026-09-04, alkhttp review 006
|
||||
Unit 2+3): the `install_channel_zero` hook forks the deployment's
|
||||
base registry per session, registers the generic channel ops, the
|
||||
deployment's openable ALPNs (`HttpAdapter::with_ws_openable_alpns`,
|
||||
request-extension fallback), the bootstrap discovery set, and
|
||||
`op/register` (alkcall ADR-022 amendment), then dispatches over the
|
||||
fork — alkcall ADR-047 §4 amendment #2's per-session-fork shape.
|
||||
The session retains its live `Arc<CallConnection>` in `WsSessions`
|
||||
(evicted with the session). One premise of the original deferral
|
||||
was corrected along the way (review-003 WS-23): "reopened when a
|
||||
browser consumer lands" underestimated the consumer set — WS is
|
||||
also the native-client fallback behind hostile NAT/firewall, and a
|
||||
Rust WS consumer (the `test_support` client shape) is a legitimate
|
||||
first consumer. **OQ-04 does not block this wiring**; a browser
|
||||
consumer needs only binary-frame parsing + byte reassembly ahead of
|
||||
wasm-targeted alkcall. What the deferral rationale got right: the
|
||||
alkcall-side machinery was indeed complete — but two wiring
|
||||
blockers turned out to be design gaps (review-003 WS-24/WS-25),
|
||||
resolved upstream in alkcall 0.3.0 before the wiring could land.
|
||||
Gate coverage: the six e2e gates in `tests/ws_upgrade_session.rs`
|
||||
(open/discoverable/bytes round-trip, close + ledger decrement, cap
|
||||
denial, mid-open disconnect teardown, `TooLarge` demux resync,
|
||||
`op/register` + collision), plus the `services/list-peers`
|
||||
announced-op discovery gate (alkcall 0.3.1).
|
||||
- **Cross-references**: [ADR-067](decisions/067-websocket-carries-channels.md),
|
||||
[ADR-048](decisions/048-websocket-native-session-not-gateway.md),
|
||||
[websocket.md](websocket.md), tasks/websocket/review-001-ws-data-channel-decision.md,
|
||||
alkcall reviews 004–005 (`alkcall/docs/reviews/004-per-connection-dispatch-and-client-serving-review.md`,
|
||||
`alkcall/docs/reviews/005-serving-loop-concurrency-and-op-register-review.md`)
|
||||
`alkcall/docs/reviews/005-serving-loop-concurrency-and-op-register-review.md`),
|
||||
alkhttp review 003 (the drill-down), review 006 (the consequence
|
||||
review + remediation log)
|
||||
|
||||
## Resolved (ported)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
|
||||
## Status
|
||||
|
||||
Verified, open for remediation.
|
||||
Remediated (2026-09-04). WS-24/WS-25 resolved upstream (alkcall 0.3.0,
|
||||
review 006); WS-20/21/22/23/26/27 + UP-01 landed (review 006 Units
|
||||
2–3, `030c5ef`); Unit 4 docs landed with review 006 (OQ-05 resolved).
|
||||
The remediation log lives in
|
||||
[review 006](006-alkcall-0.3.0-consequence-review.md).
|
||||
|
||||
## Scope
|
||||
|
||||
@@ -447,17 +451,19 @@ Using `test_support::WsClient` (the Rust-native-consumer shape):
|
||||
5. `TooLarge` chunk on a data channel survives (demux resync) —
|
||||
already proven alkcall-side; assert it through the WS path.
|
||||
|
||||
## Unit 4 — spec reconciliation (docs)
|
||||
## Unit 4 — spec reconciliation (docs) — LANDED (2026-09-04, review 006)
|
||||
|
||||
- OQ-05 → resolved (or narrowed to the remaining piece), with the
|
||||
consumer-set reframe recorded (WS-23): browser + native fallback;
|
||||
OQ-04 not blocking.
|
||||
- OQ-05 → resolved, with the consumer-set reframe recorded (WS-23):
|
||||
browser + native fallback; OQ-04 not blocking.
|
||||
- ADR-067 v1-cut note and ADR-048 reconciliation note updated to the
|
||||
landed state; websocket.md §"Data channels for browsers" status
|
||||
block removed; the alknet-ADR-044 §5 pointer checked for staleness.
|
||||
block removed; the alknet-ADR-044 §5 pointer checked (not stale).
|
||||
- websocket.md gains the idle-knob deployment note for silent data
|
||||
channels (already true, just surfaced where a deployer reads).
|
||||
|
||||
Landed with review 006 Units 2–3; see review 006's remediation log
|
||||
for the landed shape and its verification.
|
||||
|
||||
---
|
||||
|
||||
## Verification log (this pass)
|
||||
|
||||
Reference in New Issue
Block a user