Files
alksocks/docs/architecture/README.md
T
glm-5.3-flash 1ad8d9d489 core: the cross-cutting integration suite + docs sync
The batch-1 closing task: nine cross-cutting integration tests
(tests/core-integration.rs) pinning the whole protocol core end to
end over the channels harness, plus the architecture-sync docs pass.

Tests:
- One registration, all three commands: CONNECT + ASSOCIATE + BIND
  interleaved live on the one channels/socks5/sub op; a teardown
  ends only its own session (mux/demux isolation) — the POC #2/#5
  regression guard, complete.
- Concurrency: nine concurrent mixed-command sessions (raw topology)
  and six through the typed consumer sessions (consumer-side
  topology) — the mux/demux pinned in both channel-id allocation
  directions; fresh round-trips after the burst; no channel leaks.
- Teardown matrix (wire.md §Sentinels and lifecycle): CONNECT
  half-close, ASSOCIATE EOF, BIND client-gone (a parked accept so
  the quiet-wait exit is deterministic) — each followed by fresh
  sessions of every command (no connection poisoning).
- Identity/scope matrix (ADR-006 end to end): open-only (CONNECT +
  ASSOCIATE serve, BIND refused 0x02 at the command gate), bind-only
  fail-closed at the open gate for all commands (the spec drift the
  task's phrasing carried, reconciled — ADR-006's open gate requires
  socks5:open unconditionally), both-scopes (everything, granted
  explicitly); the CF-006 witness asserted per row.
- The readiness contract re-pinned under concurrent load: a
  hot-Ok(None) egress across concurrent associations does not starve
  the datagram stage's channel branch.

Docs sync: README Current State ("the protocol core is implemented"
+ the landed inventory; the decomposition residue gone); consumer.md
§Wiring reconciled to the landed session signatures; ADR-006
§Consequences states the grant asymmetry explicitly; lib.rs crate
docs describe the landed surface.

Verification: cargo test 302 green; --all-features green; clippy
--all-targets -D warnings clean; fmt --check clean; both wasm checks
clean; cargo doc --no-deps clean. Batch boundary holds: no
local/composed code, the default crate is protocol-only.
2026-09-24 07:44:54 +00:00

147 lines
8.9 KiB
Markdown
Raw 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-24 (the protocol core landed + the cross-cutting
integration suite; 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 — 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 is 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–013. All docs are `draft` — they transition
to `reviewed` when their open questions resolve and the architecture
review passes.
The landed core (the protocol-only batch; no `local`/`composed` code
exists yet): 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
batch-1 cross-cutting integration suite (`tests/core-integration.rs`)
pins the core's whole behavior end to end; the `local` and
`composed` provider groups follow (batch 2).
## 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) — 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.. — the SK2 numbering is not contiguous from 01, 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, 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`)