docs: correct WS framing claims from spike; add implementation plan

Spike against alkcall source resolved ADR-067 assumptions:
- write_chunk issues header+payload as separate write_alls; channel
  0's write_frame issues prefix+body separately — a logical write can
  surface as multiple chunks, so the WS adapter must parse outgoing
  chunk boundaries (byte-stream treatment both directions), not assume
  write-per-chunk or message-per-chunk
- MAX_CHUNK_LEN is 16 MiB; the WS path needs a practical message cap
  with oversized chunks split across messages
- install_channel_zero + run_loop_single_stream confirmed as the exact
  server-side seam; EOF/teardown invariants already specified by
  alkcall (REQ-CH-01/02)

Corrections applied to websocket.md, ADR-067, OQ-01.

docs/plans/implementation.md: scoped plan guiding task decomposition —
spike findings, 4-phase build order, OQ dispositions, task conventions.
This commit is contained in:
2026-08-28 05:55:03 +00:00
parent 320ea87b08
commit eaf1a203bc
4 changed files with 160 additions and 24 deletions
@@ -46,18 +46,23 @@ in the alknet design). The path is an axum route on the `HttpAdapter`
router, subject to the same reserved-path collision rule as any
default-surface route ([ADR-046](046-assembly-layer-custom-http-routes.md)).
### Framing: the WS message boundary carries chunks, not envelopes
### Framing: the chunk header is the boundary, not the WS message
The alknet design's "one `EventEnvelope` = one binary WS message, no
length prefix" framing is **superseded**. The WS message boundary now
carries channels chunks; the call protocol's envelopes ride inside
channel 0 as length-prefixed JSON (alkcall ADR-014 frame format), the
same as any other in-line channels transport.
length prefix" framing is **superseded**. The WS binary message stream
is treated as a byte stream; the 8-byte chunk header is the only
framing. Call-protocol envelopes ride inside channel 0 as
length-prefixed JSON (alkcall ADR-014 frame format), the same as any
other in-line channels transport. A chunk may span WS messages and a
WS message may carry chunk fragments (in practice the write path
usually produces one chunk per message, but nothing may depend on
it — channel 0's frame writer issues two writes, prefix then body,
which can surface as two chunks).
Layering on the wire, for a call frame over WS:
```
WS binary message
WS binary message(s) — byte stream
└── chunk header [channel_id: u32 BE][length: u32 BE] (8 bytes)
└── payload = frame [len: u32 BE][EventEnvelope JSON] (channel 0)
```