Files
alksocks/docs/architecture/decisions/010-channel-capacity.md
T
glm-5.3-flash e196ed43e3 docs: remove em dashes from repo prose and forbid them going forward
- Rewrote em dash prose across the whole tree outside docs/reviews/
  (the historical reviews stay verbatim, matching the alktunnels and
  alktty precedent): src doc comments and inline comments (587),
  docs/architecture (319), docs/research + sdd_process (484), tests
  (361), tasks (899), fuzz (28), README/CHANGELOG/Cargo.toml (77),
  AGENTS.md (85), and the .opencode/agents prompts (109)
- Fenced content follows the precedent: comments, ASCII-diagram label
  separators, and template placeholders rewritten; wire data, JSON/BAST
  documents, byte diagrams, and transcripts survive verbatim; assert,
  expect, panic, error-display, and format message literals rewritten
  as prose; no code, fixture, or test data change
- src/rfc1928/LICENSE: the two dashes in alksocks' own provenance
  header rewritten; the MIT legal text untouched
- AGENTS.md adds Project Convention 18: no em dashes in prose; varied
  restructure, no spaced-hyphen substitutes, fenced prose rule, en
  dash numeric ranges exempt, docs/reviews/ exempt from the greps
- tasks/*.md frontmatter: the name values rewritten by the sweep are
  now quoted (a raw colon inside an unquoted YAML scalar parsed as
  null); taskgraph validate reports 37 tasks, no issues

Verification: cargo test; cargo clippy --all-targets -D warnings;
cargo fmt --check; cargo doc --no-deps; fuzz corpus replay
(cargo test --manifest-path fuzz/shared/Cargo.toml); wasm check and
clippy for wasm32-unknown-unknown with -D warnings; em dash grep over
the repo returns matches only in docs/reviews/ and the bast.md BAST
JSON data fence
2026-11-03 19:31:53 +00:00

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)