- 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
104 lines
4.9 KiB
Markdown
104 lines
4.9 KiB
Markdown
# ADR-009: Feature-Gate Layout: `local` and the Composition Boundary
|
|
|
|
## Status
|
|
|
|
Accepted (2026-09-20, Phase 1; the wasm-clean default-crate invariant
|
|
is the alk* family posture, AGENTS.md convention 4). Amended
|
|
2026-09-21 (pre-decomposition): the vendor's `net` gate dissolves
|
|
under ADR-011's extraction amendment; the vendor is
|
|
wasm-clean by construction; features collapse to `local` +
|
|
`composed`; see §Amendment.
|
|
|
|
## Context
|
|
|
|
The default crate must compile to `wasm32-unknown-unknown` (the
|
|
alktty/alktunnels precedent; the wasm shape is a sandboxed
|
|
SOCKS5 consumer (pure byte framing, no local sockets needed
|
|
client-side; phase-0 OQ-SK-04's analysis). Two groups of
|
|
platform-specific or sibling-dependent code need gating:
|
|
|
|
1. **The crate's own local backends** (dial/listen/egress providers
|
|
touching real sockets, ADR-008's local variants).
|
|
2. **The composed providers** (the alktunnels-composed egress/accept
|
|
helpers, ADR-008's composed variants), which need the
|
|
alktunnels dependency.
|
|
|
|
The vendor originally contributed a third gate: its kernel-net
|
|
region was to ride a default-on `net` feature (POC #4's measured
|
|
shape, ~120 cfg lines across 5 files). ADR-011's 2026-09-21
|
|
amendment pins the vendor as *extraction*; the kernel-net region is
|
|
not copied, so that gate no longer exists (see §Amendment). POC #4's
|
|
gate map survives as the extraction recipe, not as in-tree cfg.
|
|
|
|
## Decision
|
|
|
|
- **The default crate is protocol-only and wasm-clean.** Module
|
|
placement per [overview.md](../overview.md): protocol, wire,
|
|
producer, consumer, vendor modules at the core; backend modules
|
|
feature-gated, never imported by the protocol layer.
|
|
- **The default build has no `net` feature**: the extracted vendor
|
|
contains zero kernel-net code, so the wasm-clean subset is the
|
|
whole crate; there is nothing to gate (ADR-011 §Amendment).
|
|
- **`local` (default-off)**: the crate's first-party local backends,
|
|
namely the TCP dial, the UDP egress socket, the BIND listener, and
|
|
the front doors (the consumer's ssh `-D` local exposure; the
|
|
producer's local backend). Brings `tokio/net` + `socket2` into the
|
|
graph. Non-wasm by design (enabling it on wasm is a build error,
|
|
the alktty posture).
|
|
- **`composed` (default-off)**: the composed providers over
|
|
alktunnels 0.2.0 (direct-op egress, bind-first listen accept),
|
|
the only feature that adds the alktunnels dependency. The
|
|
protocol layer never references alktunnels types; the composed
|
|
module does, injected at the assembly layer (ADR-004/ADR-008).
|
|
- **tokio stays `default-features = false`** with the wasm-clean
|
|
subset (`rt`, `sync`, `io-util`, `macros`, `time`); **never
|
|
`features = ["full"]`** (AGENTS.md convention 4); `net`-shaped
|
|
additions ride `local` alone.
|
|
|
|
## Amendment (2026-09-21, pre-decomposition: the vendor's `net` gate dissolves)
|
|
|
|
The original decision carried a third feature, `net`
|
|
(default-on), the vendored subset's kernel-net gate, with `local`
|
|
implying it. ADR-011's extraction amendment dissolves it:
|
|
|
|
- The vendor is an extraction of the `T`-generic inventory only; the
|
|
kernel-net region (`run_tcp_proxy`, `run_udp_proxy*`, the legacy
|
|
`Socks5Server`/`Incoming` API, `Socks5Datagram`'s kernel path, the
|
|
DNS-resolve helper, the net-only tests), the `socks4` module, and
|
|
the legacy `Config`/`Authentication` layer are not copied into the
|
|
tree; the extraction is wasm-clean by construction, with no
|
|
in-tree cfg gate.
|
|
- Features collapse to two: **`local`** (first-party socket
|
|
providers + front doors, ADR-008; brings `tokio/net` + `socket2`
|
|
into the graph itself) and **`composed`** (the alktunnels
|
|
providers). `local` no longer implies a separate `net` feature;
|
|
it is the sole gate for socket/platform I/O.
|
|
- POC #4's gate map survives as the *extraction recipe* (its
|
|
ungated inventory is what to copy), not as in-tree cfg.
|
|
- The wasm verification is a hard gate with no feature toggles:
|
|
`cargo check --target wasm32-unknown-unknown` and native
|
|
`--no-default-features` both compile the same complete crate.
|
|
|
|
## Consequences
|
|
|
|
- Wasm consumers (the sandboxed adapter story; a product input,
|
|
nothing waits on it) build the default crate clean; the protocol
|
|
substance *is* the wasm-relevant surface.
|
|
- The verification commands cover the gates: `cargo test` (default),
|
|
`cargo test --all-features`, and both wasm checks
|
|
(`cargo check/clippy --target wasm32-unknown-unknown`), the
|
|
structural guard for the invariant.
|
|
- The vendor's carried changes (BIND, `new_reply` publication) live
|
|
in the extracted region where they touch codecs/typestate; nothing
|
|
vendored is gated; the only feature-gated socket code is the
|
|
crate's own first-party `local` module.
|
|
|
|
## References
|
|
|
|
- OQ-SK-04 (resolved: the extracted-and-forked base; ADR-011/
|
|
ADR-013), OQ-SK-01/03/08
|
|
(the providers the features gate)
|
|
- POC #4 `poc-connect-wasm-findings.md` (the measured gate, now the
|
|
extraction recipe),
|
|
alktty's `local` feature (the posture precedent), alktunnels
|
|
ADR-004 + overview.md (the same feature split) |