--- 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`)