docs(http): defer h3/WebTransport (ADR-044); browsers use WebSocket for v1
Working through the WebTransport implementation path surfaced a scope question distinct from the hedging-as-deferral anti-pattern ADR-038 was written to correct. Three findings drove the re-evaluation: 1. The browser bidirectional call-protocol path doesn't require WebTransport — WebSocket is full-duplex, EventEnvelope fits a WS binary message boundary cleanly, and the Dispatcher is stream- agnostic (ADR-012). What WebTransport gives over WebSocket (native multi-stream multiplexing, the ALPN-as-stream substrate) benefits the proxy use case, not the call protocol. 2. WebTransport is a draft standard (-07, not RFC) on an experimental Rust dependency stack (wtransport/h3 both self-describe as not production-ready). Either choice puts a draft protocol on the security surface of the first release. 3. The ALPN-stream-proxy (ADR-040) is speculative — its WASM parser consumers (browser SSH/SFTP/git clients) don't exist yet, and the downstream crates WebTransport deferral blocks (SSH, git, SFTP) expose their ALPNs natively over QUIC regardless. This is a scope decision (per ADR-009: a decision that 'genuinely doesn't need to be made yet because the use case isn't concrete'), not hedging. The reversal trigger is concrete: a real deployment needing the ALPN-stream-proxy. ADR-038 is superseded (its anti-pattern correction stands; its specific 'h3 in scope now' decision is reversed). ADR-040 and ADR-043 are parked, not superseded — their designs revive unchanged when WebTransport revives, with §2 (bidirectionality) and §3 (no-PeerId overlay) of ADR-043 transferring to WebSocket for v1. ADR-044 §5 also states the 'browser is not a peer' rationale that ADR-034 §4 closed without arguing: peer = addressable node in the call-protocol peer graph (stable PeerId, PeerRef::Specific-reachable, identity stable across reconnects), not 'any endpoint that exchanges calls during a live session.' A browser is the second but not the first (no stable crypto identity of its own, ephemeral, not addressable from other nodes). ADR-034 §4 and Assumption 2 are amended by reference. The wtransport-vs-hyperium dependency question is recorded (not resolved — WebTransport is deferred) in ADR-044 §'Research note' and webtransport.md so the revival doesn't re-derive it: wtransport probably isn't the right choice (axum-bridge friction — it owns its own HTTP serving path); the hyperium stack (h3 + h3-quinn + h3-webtransport) fits the axum integration better but its server-side WebTransport API needs verification before commitment. Reviewed by architecture-review subagent; all critical cross-reference issues (ADR-034 §5 stale 'in scope' assertion, ADR-036 Context listing h3 as implemented, webtransport.md Design Decisions table) resolved.
This commit is contained in:
@@ -1,10 +1,43 @@
|
||||
---
|
||||
status: draft
|
||||
last_updated: 2026-06-29
|
||||
status: deferred
|
||||
last_updated: 2026-06-30
|
||||
---
|
||||
|
||||
# WebTransport — the h3 ALPN handler
|
||||
|
||||
> **DEFERRED per [ADR-044](../../decisions/044-defer-webtransport-browsers-use-websocket.md).**
|
||||
> This spec is kept intact for revival. `h3`/WebTransport is not
|
||||
> implemented in the initial `alknet-http` release; the browser
|
||||
> bidirectional path uses WebSocket (see
|
||||
> [http-server.md](http-server.md) §"WebSocket browser path"). ADR-038
|
||||
> is superseded; ADR-040 and ADR-043 are parked (their decisions revive
|
||||
> unchanged when WebTransport revives). The reversal trigger is a
|
||||
> concrete deployment needing the ALPN-stream-proxy (a browser running
|
||||
> a WASM SSH/SFTP/git client to reach a non-call ALPN). Two transfers
|
||||
> apply during the deferment: ADR-043 §2 (call-protocol bidirectionality)
|
||||
> and §3 (the no-`PeerId` connection-local overlay) apply over WebSocket
|
||||
> unchanged; ADR-040 (the ALPN-stream-proxy) and ADR-043 §4 (the
|
||||
> non-call-ALPN substrate) do not — they require WebTransport's stream
|
||||
> model and revive with it.
|
||||
>
|
||||
> **Research note (for revival):** `wtransport` (v0.7.1, the reference
|
||||
> implementation read during initial research) is *probably not* the
|
||||
> right dependency choice at revival time, despite being a complete and
|
||||
> readable implementation. The load-bearing integration concern is that
|
||||
> the `h3` handler must route HTTP/3 requests through the same axum
|
||||
> `Router` as `h2`/`http/1.1` (ADR-036), and `wtransport` owns its own
|
||||
> HTTP serving path — bridging its request type into the `http::Request`
|
||||
> axum consumes is cross-ecosystem adapter work. The hyperium stack
|
||||
> (`h3` + `h3-quinn` + `h3-webtransport` + `h3-datagram`) operates at
|
||||
> the stream level and produces `http::Request` types natively, which is
|
||||
> a better fit for the axum integration — but its server-side
|
||||
> WebTransport API needs verification before commitment (the axum-bridge
|
||||
> feasibility is the load-bearing claim and is not yet confirmed against
|
||||
> actual crate APIs, only against READMEs and design philosophy). This
|
||||
> research is **not** run now (WebTransport is deferred); it is recorded
|
||||
> here so the revival does not re-derive the question from scratch. See
|
||||
> ADR-044 §"Research note (for revival)" for the cross-reference.
|
||||
|
||||
The `HttpAdapter` registration for the `h3` ALPN: HTTP/3 and
|
||||
WebTransport. WebTransport is a **bidirectional ALPN transport
|
||||
substrate** (ADR-043) — it carries ALPN protocols as bidirectional
|
||||
@@ -386,13 +419,19 @@ as a first-class transport.
|
||||
|
||||
## Design Decisions
|
||||
|
||||
> **Note:** This table reflects the design as written for revival. ADR-038
|
||||
> is **superseded by [ADR-044](../../decisions/044-defer-webtransport-browsers-use-websocket.md)**;
|
||||
> ADR-040 and ADR-043 are **parked** (implementation deferred per ADR-044).
|
||||
> The decisions revive unchanged when WebTransport revives — see the
|
||||
> header note and ADR-044 for the scope rationale and reversal trigger.
|
||||
|
||||
| Decision | ADR | Summary |
|
||||
|----------|-----|---------|
|
||||
| `h3`/WebTransport is first-class | [ADR-038](../../decisions/038-http3-and-webtransport-as-first-class.md) | In scope, not deferred; browser streaming uses QUIC streams |
|
||||
| WebTransport is a bidirectional ALPN transport substrate | [ADR-043](../../decisions/043-webtransport-bidirectional-alpn-substrate.md) | Carries ALPNs as bidirectional streams; call protocol is the first/canonical target (needs no WASM parser); both sides can initiate calls |
|
||||
| WebTransport ALPN-stream-proxy | [ADR-040](../../decisions/040-webtransport-alpn-stream-proxy.md) | The substrate's mechanism for non-call ALPNs (SSH, git, SFTP) — browser → WebTransport stream → target ALPN handler via WASM parser |
|
||||
| Browsers require X.509 | [ADR-027](../../decisions/027-tls-identity-redesign-acme-rawkey-decoupling.md) | `h3` needs X.509 (browser limitation) |
|
||||
| Browsers are not alknet peers | [ADR-034](../../decisions/034-outgoing-only-x509-and-three-peer-roles.md) | Bearer token, no `PeerId` |
|
||||
| ~~`h3`/WebTransport is first-class~~ | [ADR-038](../../decisions/038-http3-and-webtransport-as-first-class.md) | **Superseded by ADR-044** (scope deferral); originally "in scope, not deferred; browser streaming uses QUIC streams" |
|
||||
| WebTransport is a bidirectional ALPN transport substrate | [ADR-043](../../decisions/043-webtransport-bidirectional-alpn-substrate.md) | **Parked** per ADR-044. Carries ALPNs as bidirectional streams; call protocol is the first/canonical target (needs no WASM parser); both sides can initiate calls |
|
||||
| WebTransport ALPN-stream-proxy | [ADR-040](../../decisions/040-webtransport-alpn-stream-proxy.md) | **Parked** per ADR-044. The substrate's mechanism for non-call ALPNs (SSH, git, SFTP) — browser → WebTransport stream → target ALPN handler via WASM parser |
|
||||
| Browsers require X.509 | [ADR-027](../../decisions/027-tls-identity-redesign-acme-rawkey-decoupling.md) | `h3` needs X.509 (browser limitation; applies when WebTransport revives) |
|
||||
| Browsers are not alknet peers | [ADR-034](../../decisions/034-outgoing-only-x509-and-three-peer-roles.md) §4 (amended by ADR-044 §5) | Bearer token, no `PeerId` (rationale in ADR-044 §5) |
|
||||
| WebTransport streams → call protocol directly | [ADR-012](../../decisions/012-call-protocol-stream-model.md) | Stream-agnostic; WebTransport stream = QUIC bidirectional stream |
|
||||
| `BiStream` is a trait (WASM door) | [ADR-007](../../decisions/007-bistream-type-definition.md) | Browser implements `BiStream` over WebTransport stream; WASM parser speaks the protocol |
|
||||
| Stealth on h3 | [ADR-010](../../decisions/010-alpn-router-and-endpoint.md) | Unknown paths get the decoy |
|
||||
|
||||
Reference in New Issue
Block a user