ADR-013 supersedes ADR-011's maintenance posture (not its mechanics):
the extracted T-generic subset is fully owned code, the vendor
framing is retired. Module renamed src/vendor/ -> src/rfc1928/
(naming decided in the ADR: 'vendor' names an ownership relation
now gone; 'socks5' would stutter and collide with the future
producer/consumer layers). Fork point = the tree as of the
extraction-review commit (5b18d4d); provenance stays permanent
(module docs + the extended LICENSE notice).
- ADR-013: fork posture, license mechanics (notice extended, not
replaced; post-fork modifications under the crate license),
hand-port replaces re-vendor, lint-allow posture dissolved
- ADR-011 marked Superseded (extraction mechanics remain
authoritative); ADR-002 references re-pointed
- vendor.md -> rfc1928.md rewritten as the owned-core spec (the cut
table re-read as the hand-port map)
- spec sweep: README index (ADR-013 row, doc table, principle 8),
overview (module map, deps, ADR table), producer/consumer/wire/
bast reference vocabulary, open-questions OQ-SK-04 resolution,
AGENTS.md conventions 4/17 + verification note + context bullet,
Cargo.toml description
Verification: cargo doc --no-deps clean; no stale vendor.md/src-vendor
references outside the ADR-011 historical text.
3.1 KiB
ADR-010: Channel Capacity — Proxy-Workload Recommendation, Not a Wire Change
Status
Accepted (2026-09-20, Phase 1; the analysis is OQ-SK-09's, 2026-09-14)
Context
The 256-channel default cap (per-connection alkcall ADR-040;
per-identity ADR-041) is tight for a proxy workload: every proxied
flow is a channel (a browser or tun2proxy fan-out opens one
CONNECT channel per flow; composed UDP egress spends a downstream
channel per destination; BIND spends an accept resource per
listener). A proxy-shaped deployment will discover the cap in
production unless the crate documents the posture. The caps are
policy knobs — configurable without a wire change (the u32
channel-ID wire space is ~4 billion) — so the resolution is config
plus documentation, never wire.
Considered and rejected: in-channel port multiplexing (a
[port: u16][len][payload] per-chunk prefix) — it re-opens the
demux-vs-phase trade ADR-003 (the handle swap) resolved, breaks
the 0-B pass-through that lets the forked transfer drop in
unchanged, imposes chunk boundaries on a stream RFC 1928 treats as
unstructured, and violates the one-channel-per-SOCKS5-session
convention (AGENTS.md #10).
Decision
- No wire change — rejected permanently. The caps are policy knobs (alkcall ADR-040/041); the resolution is config.
- Assembly-layer config is the mechanism: a proxy-shaped deployment raises the per-connection/per-identity caps at registration; the default stays conservative for everyone else.
- Documented proxy-workload recommendation: the crate docs recommend a raised cap for proxy deployments, with the memory arithmetic — a session's memory is bounded + predictable (CONNECT/ ASSOCIATE are bounded-buffer pumps; BIND adds one listener + one accept), so the per-connection cap can rise safely relative to a general-purpose deployment. A concrete recommended figure is a docs-level tuning note, not an architecture constant.
- Defense-in-depth posture stays layered: ACL → per-connection cap → per-identity cap → dial/accept policy. Relaxing the caps leans on the rest. The per-identity DoS brake is arguably stronger here (each SOCKS5 session maps to real producer-side resources — a dial, a downstream channel, an accept listener); the per-connection memory bound is arguably weaker (the three command shapes are well-known and bounded).
- Revisit trigger (OQ-SK-09's): if a deployment hits a fixed upstream channel budget that config cannot raise, the additive escape is a new multiplexed ALPN — never a change to this ALPN's framing.
Consequences
- Deployments get the guidance before they hit the cap; no protocol surface changes.
- The rejected multiplexing proposal has a recorded rationale and a revisit trigger — the escape hatch is additive (new ALPN), never a framing change.
References
- OQ-SK-09 (the analysis), OQ-SK-03 (the demux-vs-phase trade the rejection leans on), OQ-SK-05 (the virtual-subnet idea that survives, recorded as OQ-SK2-07 in the tracker)
- alkcall ADR-040 (per-connection cap), ADR-041 (per-identity cap), ADR-034 (the channels wire format)