docs: spec-level sync with the single-publish fix + port-debt repair

The spec docs had not caught up with the stub-sweep fix commits
(4eae18f..3317ea0), and the ported docs still carried alknet
numbering that now collides with alkcall's own ADR range.

Spec sync with the landed code:
- call-protocol.md: register_imported/register_imported_all return
  Result and refuse marked specs; marked-spec registration refusal
  contract spelled out (ADR-047 am. 4 §4.8, ADR-022 am. 2026-10-13)
- client-and-adapters.md: from_call flow gains the Pub sink-forwarding
  branch and the marked-op refusal (resolves OQ-37 — no from_call
  relay wrapper; sanctioned compositions are
  ChannelRelay::register_relay_openable / ChannelClient)
- ADR-051: "channel/control is not implemented" stale sentence
  replaced with the ADR-052 per-leg control contract
- OQ-37 resolved; OQ-22 split (primitive resolved; broker placement
  out of scope) with new OQ-42 for the downstream hub broker
  (deferred(scope), concretely blocked); OQ-24 resolved by the shipped
  add/strip surface; OQ-41 → deferred(scope) with blocking condition
- README: OQ bullets renumbered to tracker IDs; alknet-collision note
  rewritten (range 001..053, alknet prefix convention); new principle
  11 (implement-or-stop-advertising); AGENTS.md ADR range 001..053

Port-debt repair:
- 149 broken decision links across 17 docs — ported with alknet
  numbers/paths, most now remapped to alkcall files by slug; the
  rest link the alknet repo per the README convention
- stale OQ numbering rewritten to tracker IDs in call-protocol.md,
  call-README.md, operation-registry.md, client-and-adapters.md,
  ADR-025, channels-overview/README/wire, channel-client
- unambiguous "alknet ADR-NNN" labels where an alknet number collides
  with an alkcall ADR (052 TTY vs channel/control, 033 storage vs
  rust-canonical, 025/026/027+020 vault vs PeerEntry/auth ADRs)

Verified: cargo test (697 + guard), fmt, clippy --all-targets -D
warnings; full markdown link scan clean.
This commit is contained in:
glm-5.3-flash committed 2026-10-13 09:34:37 +00:00
1 parent 3317ea0963
commit 7b8a3e7558
26 files changed
+432 -332

No files matched your search

+14 -10
View File
@@ -36,7 +36,7 @@ hand-rolled (the hot path); the BAST document is the contract.
The payload is opaque to the channels layer. The handler parses its own
framing from the payload — TTY's `[stream_type:u8][length:u32][payload]`
(5-byte format, ADR-052), call's length-prefixed JSON (`EventEnvelope`
(5-byte format, alknet ADR-052), call's length-prefixed JSON (`EventEnvelope`
framing, ADR-014), tunnel's raw bytes, SSH's channel protocol. The
channels layer carries the bytes transparently.
@@ -72,7 +72,7 @@ its framing entirely. See ADR-035 for the full cost/benefit analysis.
## `MAX_CHUNK_LEN`
`16 * 1024 * 1024` (16 MiB), matching TTY's cap (ADR-052 §5). A chunk with
`16 * 1024 * 1024` (16 MiB), matching TTY's cap (alknet ADR-052 §5). A chunk with
`length > MAX_CHUNK_LEN` returns `ChunkTooLarge` and does not corrupt the
stream — the demux drops the chunk and continues. The header is always
exactly 8 bytes, so the demux can always resync by reading the next
@@ -110,7 +110,7 @@ which is internal to TTY's 5-byte format).
A zero-length chunk (`length = 0`) is delivered as an empty payload,
which the reassembled stream interprets as EOF. This is the clean-shutdown
signal for a `channel_id` — the same convention as TTY (ADR-052
signal for a `channel_id` — the same convention as TTY (alknet ADR-052
§Sentinels), now at the channels layer (one sentinel per channel, not
per `(channel_id, stream_type)`).
@@ -245,9 +245,13 @@ same shape, each level.
The exact API shape of the add/strip pair (built into the read/write path
vs. a standalone utility) is an implementation detail for the channels
crate, tracked as OQ-68. The *contract* — the channels layer strips its
8-byte header on read and the handler parses its own framing from the
payload — is decided; the *function surface* is not.
crate; the shipped surface resolves it (OQ-24, formerly alknet OQ-68):
the strip is integrated into the read/write path — the demux loop
consumes `read_header`/`write_chunk` so a handler's `BiStream` yields
payload chunks and never sees the 8-byte header — while the low-level
primitives (`parse_header`/`write_header`/`read_header`/`write_chunk`/
`write_eof` in `channels::wire`) stay exposed as the standalone utility
for tooling.
## Channel lifecycle (summary)
@@ -293,10 +297,10 @@ All design decisions are documented as ADRs in [decisions/](decisions/).
Open questions are tracked in [open-questions.md](open-questions.md).
Key questions affecting this doc:
- **OQ-68** (open): Add/strip API shape — whether the 8-byte header
add/strip is built into the channels read/write path or exposed as a
standalone utility. The *contract* (channels strips, handler parses
payload) is decided; the *function surface* is not.
- **OQ-24** (tracker; alknet OQ-68) (resolved): Add/strip API shape —
built into the read/write path (the demux loop strips headers; handlers
never see them), with the low-level header primitives exposed in
`channels::wire` for tooling.
## References