Files
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

156 lines
9.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
status: draft
last_updated: 2026-09-25 (the assembly layer landed + the cross-cutting
assembly integration suite; the protocol core landed + the cross-cutting
integration suite 2026-09-24; the rfc1928 doc's targeted fork 2026-09-22; the
vendor extraction amendment ADR-011 §Amendment 2026-09-21; Phase 1
initial draft 2026-09-20; the OQ-SK ledger promoted into ADRs
001-012 and open-questions.md)
---
# alksocks: Architecture
A SOCKS5 (RFC 1928) producer/consumer protocol crate on alkcall
channels: an arbitrary-egress proxy service that never binds a port
unless explicitly configured to. It is the `alk/socks5`-family
producer/consumer protocol crate, the sibling of alktty
(`alk/tty`) and alktunnels (`alk/tunnel`). Where alktunnels
realizes the `-L`/`-R` forwarding flavors, alksocks realizes the
`-D` flavor (dynamic / SOCKS5 proxy). This directory holds the
architecture spec docs and the ADRs.
## Current State
Phase 1 (Architecture): the **protocol core and the assembly layer
are implemented**. Phase
0 (`docs/research/phase-0.md`) is converged (2026-09-14) and
POC-complete (all numbered POCs passed or were dropped with the scope
decision); the OQ-SK ledger's Phase 1 inputs are collected and
promoted into ADRs 001–014. All docs are `draft`; they transition
to `reviewed` when their open questions resolve and the architecture
review passes.
The landed surface: the RFC 1928 core in `src/rfc1928/` (the targeted
fork, ADR-013; the vendor group's six tasks landed and passed the
extraction review), the ASSOCIATE datagram frame codec (`src/wire.rs`,
ADR-003), the open-op params + typed error surface (`src/params.rs` /
`src/error.rs`, ADR-001), the three seam types (`src/egress.rs`,
ADR-004), the producer half (`src/producer.rs`: the session-gate
establisher, the command-dispatch pump, the three commands, the scope
gates), and the consumer half (`src/consumer.rs`: the
connect/associate/bind session types with teardown ownership). The
assembly layer (batch 2) landed with it: the `local` providers in
`src/local/` (tcp_dial / udp_egress / bind_accept, the producer-side
`ProducerDoor`, ADR-008/009), the front doors in `src/door.rs` (the
NoAuth raw-pipe + RFC 1929 cred-bearing TCP door, the BIND door, the
UDP door, ADR-005/003/014), and the composed providers in
`src/composed/` (the direct-op egress + the bind-first accept over
alktunnels 0.2.0, ADR-007/008). Both cross-cutting integration suites
pin the behavior end to end: `tests/core-integration.rs` (the
protocol core) and `tests/assembly-integration.rs` (the assembly
layer: the full `-D` story through the doors, the composed variant
set, mixed assembly, the assembly teardown matrix).
## Documents
| Document | Status | Description |
|----------|--------|-------------|
| [overview.md](overview.md) | draft | Crate purpose, the resource model in brief, dependencies, feature gates, module map |
| [wire.md](wire.md) | draft | The wire format: the open op (trivial params, ADR-001), the phase model, the data planes (CONNECT pass-through / ASSOCIATE frames / BIND phases), sentinels |
| [producer.md](producer.md) | draft | The producer half: the session-gate establisher, command dispatch, the three seams (dial/egress/accept), scope gates, the local backend |
| [consumer.md](consumer.md) | draft | The consumer half: the channels-native sessions (connect/associate/bind), the front doors, door auth (ADR-005), teardown ownership |
| [vendor.md](rfc1928.md) | draft | The RFC 1928 core: the targeted fork of fast-socks5's `T`-generic subset (ADR-013; the extraction mechanics in ADR-011), covering the fork's scope, the deliberate modifications, the maintenance posture |
| [bast.md](bast.md) | draft | The BAST document for the ASSOCIATE datagram frame (ADR-003); pass-through stages have no binary framing to describe |
| [open-questions.md](open-questions.md) | draft | Centralized OQ tracker (OQ-SK-01..09 promoted; new questions as OQ-SK2-06.., where the SK2 numbering is not contiguous from 01 because working-draft numbers were consumed) |
## ADR Table
| ADR | Title | Status |
|-----|-------|--------|
| [001](decisions/001-alpn-and-open-op.md) | ALPN, Open Op, and Trivial Params | Accepted |
| [002](decisions/002-protocol-base.md) | Protocol Base: the Vendored fast-socks5 Typestate Subset | Accepted |
| [003](decisions/003-udp-handle-swap.md) | The Handle Swap: one Channel per Association, Frames In-Band | Accepted |
| [004](decisions/004-dial-callback-shape.md) | The Dial-Callback Shape: Function, not Trait, at Three Seams | Accepted |
| [005](decisions/005-auth-split-by-door.md) | Auth Mapping: "Both," Split by the Door | Accepted |
| [006](decisions/006-access-control.md) | Access-Control Posture: the Open Gate Plus the Command Gate | Accepted |
| [007](decisions/007-bind-in-base.md) | BIND in the Base Crate: the Phase Model Extended | Accepted |
| [008](decisions/008-provider-defaults.md) | Egress/Accept Provider Defaults: Local Socket and Composed (Direct Op) | Accepted |
| [009](decisions/009-feature-gates.md) | Feature-Gate Layout: `local` and the Composition Boundary | Accepted (amended 2026-09-21) |
| [010](decisions/010-channel-capacity.md) | Channel Capacity: Proxy-Workload Recommendation, Not a Wire Change | Accepted |
| [011](decisions/011-inline-vendor.md) | the Inline Vendor: fast-socks5's `T`-Generic Subset, In-Tree | Superseded by ADR-013 (extraction mechanics remain authoritative) |
| [012](decisions/012-target-policy.md) | Target Policy and the Virtual-Subnet Translation Layer | Accepted |
| [013](decisions/013-targeted-fork.md) | The Targeted Fork: the Extracted Subset Is Owned, Not Vendored | Accepted |
Upstream ADRs (alkcall/alktunnels/alknet) are referenced by their own
numbers and are NOT ported; the alkcall originals at
`/workspace/@alkdev/alkcall/docs/architecture/decisions/` remain
authoritative for the shared surfaces (establishment, channels wire
format, `pump_bidi`, identity seam, the channel caps).
## Key Design Principles
1. **The protocol never binds.** The SOCKS5 service is a produced,
ACL-scoped resource on a channels connection ("ALPN as a
service"); kernel binds exist only as the two explicit, optional,
feature-gated assembly shapes (the producer's local backend; the
consumer's front door). The binding decision belongs to the
caller. The UDP ASSOCIATE "bind" is virtualized as the channel
(the handle swap, ADR-003).
2. **The RFC conversation is the data plane.** One ALPN, one open
op, trivial params (ADR-001); the phase model needs no mode byte
(the reply synchronizes the switch); no in-band control
vocabulary (the escape hatch is a new ALPN, never a framing
change).
3. **The seams are functions, not traits** (ADR-004): DialFn /
EgressFactory / BindAcceptFactory at the three I/O planes; the
protocol layer never names a substrate type; ownership rides the
handle structurally.
4. **Auth is split by the door** (ADR-005): producer = the identity
seam; the front door = RFC 1929 + the credential→identity static
mapping.
5. **Two grants, clean separation** (ADR-006): `socks5:open`
(egress) and `socks5:bind` (ingress listeners), never implied by
each other; target policy = the dialer.
6. **Backpressure and limits are inherited, not redefined** (the
alkcall channels invariants); the one-channel-per-session
convention holds for all three commands; the proxy-workload cap
posture is ADR-010 (config, not wire).
7. **Wasm-clean default crate** (ADR-009): the default crate is
protocol-only; the RFC 1928 core is an extraction with zero
kernel-net code; there is no `net` feature (ADR-011 §Amendment);
`local` is opt-in and non-wasm; `composed` rides alktunnels'
wasm-clean default (verified with the wasm check at
implementation).
8. **The RFC 1928 core is owned** (ADR-013, superseding ADR-011's
vendor posture): the extracted `T`-generic subset is a targeted
fork (`src/rfc1928/`, fork point `5b18d4d`); project
conventions apply unconditionally, and the lint-allow/verbatim
apparatus is dissolved; `/workspace/fast-socks5` stays the
differential-testing behavioral reference and the only place the
full upstream surface (the kernel-net region) exists; nothing
waits on upstream and nothing is absorbed from it (a future
upstream fix is a hand-port, guarded by the differential suite).
## Document Lifecycle
| Status | Meaning | Transitions |
|--------|---------|-------------|
| `draft` | Under active development; may change significantly | → `reviewed` when the doc's open questions resolve |
| `reviewed` | Architecture is final; implementation may begin | → `stable` when implementation is complete and verified |
| `stable` | Locked; changes require review, may warrant an ADR | → `deprecated` when superseded |
| `deprecated` | Superseded; kept for reference | Removed when no longer referenced |
## References
- Phase 0: `docs/research/phase-0.md` (the OQ ledger + convergence),
the POC findings files, `docs/research/iroh-socks5-eval.md`
- The SDD process: `docs/sdd_process.md` (Phase 1's process; the
task format; the deferred-OQ blocker-task half)
- Upstream: alkcall ADR-037/039/047/049/050/040/041/051, ledger
CF-005/CF-006; alktunnels ADR-003/004/006/007/008 + the graduation
research; alknet ADR-078/090
- Siblings: alktty (`/workspace/@alkdev/alktty`),
alktunnels (`/workspace/@alkdev/alktunnels`)
- Reference checkout: `/workspace/fast-socks5` (v1.0.0, MIT,
third-party; the differential-testing reference)
- RFC 1928, RFC 1929; tun2proxy (`/workspace/tun2proxy`)