Complete the ADR-011 §Amendment (extraction, not wholesale-copy-plus- gate) across every doc that stated the pre-amendment posture: - ADR-011: add the two extraction-recipe exclusions the amendment missed (the socks4 module — upstream's separate default-off cargo feature, out of RFC 1928 scope; the legacy Config/Authentication auth layer — ungated but consumed only by the cut region) and the dependency-surface adjustments (log -> tracing, anyhow dropped, async-trait dropped with its legacy-layer uses) - ADR-009: amend — the vendor's net gate dissolves; features collapse to local + composed; local carries tokio/net + socket2 itself - vendor.md: replace the contradictory old "four carried changes" section with the two-change reading + extraction-time adjustments; extend the cut table (socks4 row, legacy auth layer) - overview.md: dependency diagram + feature table drop the net feature; module map reflects two carried changes - README.md: principles 7/8 + doc/ADR tables updated - ADR-002/012, open-questions.md (OQ-SK-04), phase-0.md current-state sections, AGENTS.md conventions 4/17 + stale wasm-caveat sentence, POC findings posture notes: aligned with the extraction Verification: repo-wide grep for stale "four carried"/default-on net/ implies-net statements returns only amendment-context matches; extraction recipe re-verified against POC #4's gate map and the fast-socks5 v1.0.0 source (async-trait usage confined to the cut legacy layer; AuthMethod<T> traits are native async-fn-in-trait).
126 lines
7.5 KiB
Markdown
126 lines
7.5 KiB
Markdown
---
|
||
status: draft
|
||
last_updated: 2026-09-21 (the vendor extraction amendment — ADR-011
|
||
§Amendment, ADR-009 §Amendment; 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) — initial draft. 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–012. All docs are `draft` — they transition
|
||
to `reviewed` when their open questions resolve and the architecture
|
||
review passes. `src/` does not exist yet; implementation follows the
|
||
decomposition phase.
|
||
|
||
## 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](vendor.md) | draft | The inline vendor: the extracted fast-socks5 subset's scope (extraction, not wholesale copy), the two carried changes, 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 | Accepted (amended 2026-09-21) |
|
||
| [012](decisions/012-target-policy.md) | Target Policy and the Virtual-Subnet Translation Layer | 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 vendor 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 vendor is first-class** (ADR-011): the `T`-generic subset
|
||
extracted in-tree with two carried changes (BIND, `new_reply`);
|
||
`/workspace/fast-socks5` stays the differential-testing reference
|
||
and the only place the full upstream surface (the kernel-net
|
||
region) exists; nothing waits on upstream.
|
||
|
||
## 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`) |