The mechanical half of the posture change: src/vendor/ ->
src/rfc1928/ (module alksocks::rfc1928), tests/vendor-differential.rs
-> tests/rfc1928-differential.rs (git mv — history preserved).
- Fork point pinned: the tree as of 5b18d4d (the extraction review's
gate commit); provenance permanent in the module docs and the
extended LICENSE notice (upstream MIT preserved, fork-point +
post-fork modification statement added — extend, never replace)
- The lint-allow posture dissolved: all module-level #[allow]s
removed and the suppressed smells fixed (u8::max_value() ->
u8::MAX, needless lifetimes elided, match_like_matches_macro
applied, io::Error::new(Other) -> io::Error::other, the
AuthMethod::new self-taking signature renamed
into_starting_state, the F-4 ToSocketAddrs string re-worded — it
no longer names the cut resolve_dns(), the unused ready! macro
and dead AuthenticationMethod::from_u8 removed, the upstream
commented-out async-std note folded into the impl doc)
- Module docs rewritten: ownership statement (project conventions
apply unconditionally), extraction provenance (ADR-011) +
ownership (ADR-013) + maintenance posture (behavioral reference,
hand-port path)
- Differential suite survives the rename untouched (32 tests pin
bytes, not upstream text)
Verification: cargo test (38+32 green), cargo clippy --all-targets
-D warnings, cargo fmt --check, cargo check/clippy
--target wasm32-unknown-unknown, cargo test --all-features, cargo
doc --no-deps — all pass.
7.6 KiB
ADR-013: The Targeted Fork — fast-socks5's T-Generic Subset Is Owned, Not Vendored
Status
Accepted (2026-09-22, post-extraction-review; supersedes the ADR-011 maintenance posture — ADR-011 stays for the extraction mechanics and the cut table; the ADR-011 §Amendment is subsumed here)
Context
ADR-011 pinned the inline-vendor posture as extraction (the
T-generic subset copied in-tree, kernel-net region not copied; the
net gate dissolving), and the vendor group — five implementation
tasks plus the review gate — landed it in commits 57b107b..5b18d4d,
with the review (tasks/implementation/ review-vendor-extraction.md) as the fidelity gate: the file-by-file
diff vs /workspace/fast-socks5 v1.0.0 categorizes every hunk, and
every review criterion passed.
The review also made the maintenance posture's cost visible. The tree is now permanently diverged from upstream in five categories:
- The extraction cut — the kernel-net region,
socks4, the legacyConfig/Authenticationlayer,Socks5Datagram, the convenience dialers, the DNS helper: gone. - The carried changes — BIND's reply surface, the published
new_reply. - The panic translations —
ReplyError::from_u8(the review's F-1),use_password_auth,reply_error's parse. - The error-pruning adjustments — anyhow/log/async-trait out,
error variants pruned,
MissingTargetAddradded. - The lint-allow posture — module-level
#[allow]s preserving upstream style (u8::max_value(), needless lifetimes,match_like_matches_macro,io_other_error,wrong_self_ convention, the F-4 verbatim string) to keep the diff mechanical.
Category 5 exists solely to keep categories 1–4 reconcilable by a line-based diff. But a future re-base against an upstream release was never going to be a clean mechanical diff again — it was always going to be manual reconciliation across all five categories. The vendor posture's maintenance apparatus (verbatim preservation, the lint allows, the re-vendor/adjustment-list discipline) pays a permanent tax to serve a re-base path that would never be used.
The "vendor" framing also produced a real defect: the review's
F-1 (ReplyError::from_u8's upstream unreachable!() arm kept
verbatim — wire-reachable, a misbehaving peer could panic the
consumer task) escaped precisely because the vendor posture
maintained a second, weaker instruction set ("verbatim + adjustments
list" instead of "project conventions, unconditionally"). The
fidelity-vs-conventions tension is structural to the vendor framing;
the review caught the escape, but the seam itself was the vendor
framing's.
The fork point is now — post-review, post-F-1 — the cleanest line
the tree will ever present: the extraction provenance is in git
history (57b107b..5b18d4d), the review is the recorded fidelity
gate, and the five divergence categories are documented in ADR-011,
vendor.md, and the review task. "The tree as of the review commit
(5b18d4d) is the fork point" is a trivially defensible line.
Decision
- The extracted region is a targeted fork, fully owned by this crate. The "vendor" framing is retired: there is no upstream tree to stay reconcilable with, no re-vendor, no adjustment-list apparatus, no second instruction set. Project conventions (the AGENTS.md set) apply unconditionally to the forked code.
- The fork point is the tree as of commit
5b18d4d(the extraction review's gate commit). The extraction provenance is carried in git history (57b107b..5b18d4d), the module docs, and the extended LICENSE notice; the review task is the recorded fidelity gate. - Module naming: the forked core is
src/rfc1928/, re-exported asalksocks::rfc1928. "vendor" names an ownership relation (now gone); "socks5" would stutter with the crate name (alksocks::socks5) and collide with the future module structure (the producer/consumer/adapter layers are also SOCKS5-shaped).rfc1928names what the module is — the RFC 1928 wire vocabulary and the state machines — permanent and collision-free. - The lint-allow posture dissolves. The module-level
#[allow]s and the "verbatim lint posture" module-doc paragraphs are removed; the suppressed smells are fixed per project conventions:u8::max_value()→u8::MAX, needless lifetimes elided,match_like_matches_macroapplied,io::Error::new(Other)→io::Error::other,wrong_self_conventionfixed onAuthMethod:: new(self, ..), the F-4 string re-worded (it no longer names a cut function), and the#[allow(dead_code)]onAuthenticationMethodswept with actual usage. Upstream's commented-out dead code stays dropped (F-2). - The license mechanics: MIT permits sublicensing, so modifications after the fork point are this project's under the crate license (MIT OR Apache-2.0, per Cargo.toml). The bundled notice is extended, not replaced: upstream MIT text + copyright (the notice-preservation obligation, perpetual) + a fork-point statement + the modification note.
- The reference checkout survives as a behavioral reference.
/workspace/fast-socks5stays for differential testing of RFC edge cases; the differential suite (tests/rfc1928-differential.rs) pins bytes, not upstream text, so it survives the rename untouched. Textual-diff discipline is retired; behavioral differential testing is retained. - The cut table is re-read as the not-forked inventory — the map of what to hand-port if a future need surfaces (e.g. the kernel-net region for a standalone vanilla-server example). The hand-port path replaces the re-vendor path: port against the reference checkout, adapt to the crate's conventions, and let the suite guard it.
- The honest cost: the cheap upstream-fix path closes. A future fast-socks5 fix (a reply-code mapping correction, a codec fix) arrives as a hand-port against the reference checkout, not a diff absorb. Risk is assessed low — fast-socks5 is a quiet project, and the extracted surface is the well-trodden RFC 1928 path.
Consequences
- Positive: one instruction set (project conventions, unconditionally); the lint-allow tax and the adjustment-list apparatus dissolve; smells are fixed at the only cost that matters — a one-time cleanup verified by the existing suite. The F-1 seam class (conventions-vs-fidelity gaps) is closed structurally.
- Positive: the module name is stable for the crate's future
(no
alksocks::socks5stutter, nosocks5::producercollision pressure). - Negative (accepted): the cheap upstream-fix path closes — a future upstream fix is a hand-port against the reference checkout, guarded by the differential suite. Assessed low-risk (quiet upstream, well-trodden RFC surface).
- Neutral: the differential suite survives the rename untouched
(it pins bytes, not upstream text).
/workspace/fast-socks5keeps its role as the behavioral reference; the only thing it loses is being the target of a line-based diff. - Neutral: the fork-point line (
5b18d4d) is recorded in git history, the module docs, and the extended LICENSE notice; the extraction provenance (the ADR-011 trail) remains readable.
References
- ADR-011 (the extraction mechanics, the cut table, the carried
changes — the mechanics remain authoritative), ADR-002 (the
protocol base), ADR-009 (feature gates, no
netfeature) tasks/implementation/review-vendor-extraction.md(the fidelity gate + F-1),docs/architecture/rfc1928.md(the owned-core spec)/workspace/fast-socks5(v1.0.0, MIT — the behavioral reference for differential testing)