Commit Graph
46 Commits
Author SHA1 Message Date
glm-5.3-flash db051dd068 release: v0.3.1 — the dependency-patch (alkcall 0.10.1 / alktunnels 0.4.1)
- alkcall 0.10.0 -> 0.10.1: the adoption-window ordering fix (review
  013, routed from alkgit's wave-2 gate) — install+park-drain is one
  atomic section in the channels demux; the fix surface is private
  upstream, no change on this crate's paths (relevant in principle to
  the bind-first adopt flow)
- alktunnels 0.4.0 -> 0.4.1: the dependency-patch ride, no
  API/wire change
- fuzz/shared harness alkcall pin bumped in lockstep
- doc pins: AGENTS.md convention 11, README (rides paragraph),
  overview.md dependency tree + feature table; CHANGELOG 0.3.1 entry

Verification: cargo test (145 passed), cargo test --all-features
(638 passed), fuzz corpus replay green, clippy (all-targets +
wasm32-unknown-unknown) -D warnings clean, cargo fmt --check clean,
wasm check green, cargo doc clean, publish dry-run clean
2026-10-22 06:33:12 +00:00
glm-5.3-flash f56b44589c release: v0.3.0 — the dependency-major (alkcall 0.10.0 / alktunnels 0.4.0)
- alkcall 0.9.0 -> 0.10.0 (the gateway ownership-seam release): the
  GatewayDispatch ownership-provider threading + the loud unwired-spine
  default are not on this crate's paths (no gateway module use; registry
  dispatch on the native wire untouched). Zero API/wire change here.
- alktunnels 0.3.0 -> 0.4.0 (its dependency-major ride): no alktunnels
  API/wire change; the composed providers see none of it.
- fuzz/shared: the harness's own alkcall pin bumped in lockstep (its
  ChannelOpenError construction makes a drifting pin a duplicate-type
  compile failure, not silent drift) — the only bump contact.
- Docs: CHANGELOG 0.3.0 entry, README version blurb (alktunnels style),
  AGENTS.md pin update, deps tree in overview.md.
- Minor-not-patch for the established reason: semver-incompatible
  dependency bumps + this crate's public ChannelOpenError re-exports
  (SocksOpenError::Open/open_ref) are semver-visible downstream.

Verification: cargo test (default 145 unit + suites green), --features
local, --all-features (171 unit + all suites), clippy --all-targets
--all-features -D warnings, fmt --check, wasm32-unknown-unknown check +
clippy, fuzz corpus replay 3/3, publish --dry-run clean.
2026-10-19 03:53:47 +00:00
glm-5.3-flash 9ed3e8c83d release: v0.2.0 — the dependency-major (alkcall 0.9.0 / alktunnels 0.3.0)
- Cargo.toml: alkcall 0.8.1 -> 0.9.0 (crates.io, the stub-sweep
  release) and alktunnels 0.2.1 -> 0.3.0 (its dependency-major ride);
  0.1.0 -> 0.2.0 (semver-incompatible dep bumps + public alkcall
  re-exports -> minor, matching the alktunnels 0.2.1 -> 0.3.0 ride)
- fuzz/shared/Cargo.toml: alkcall 0.9.0 (one alkcall version across
  the path graph)
- No code change: zero contact with the 0.9.0 breaking surface (no
  marked-pub registration, no control-handle subscription, no
  resource enumerator use, no generic op/register announcements;
  Establishment::default() is the only Establishment contact, in the
  session gate)
- CHANGELOG: 0.2.0 section + compare links
- README: the 0.2.0 note
- docs/architecture/overview.md: dep tree + feature table alkcall
  0.9.0 / alktunnels 0.3.0
- AGENTS.md: alkcall refs — v0.8.x/0.8.0 pin -> v0.9.x/0.9.0

Verification: cargo test (145 default / 171 all-features), fuzz/shared
corpus replay (3/3), clippy --all-targets -D warnings (native +
wasm32-unknown-unknown), fmt --check, wasm32 check, cargo doc, and
cargo publish --dry-run --allow-dirty all green
2026-10-14 05:33:44 +00:00
glm-5.3-flash 3127e0231a release: v0.1.0 — the initial release
- CHANGELOG: the 0.1.0 entry finalized for publish — the alkcall
  0.8.1 / alktunnels 0.2.1 bumps and the fuzzing adoption folded in
  (the crate is unpublished, so no separate hardening cut — the
  alktunnels 0.2.1 precedent only applies post-publish); the fuzz/
  workspace bullet added (three targets, 129 seeds, corpus-replay
  gate, campaigns clean)
- README: the Version 0.1 note aligned (alkcall 0.8.1 — the
  duplicate-adopt fix is directly relevant to the consumer open/adopt
  paths; alktunnels 0.2.1; the fuzz posture noted)
- docs/architecture/overview.md: dep tree 0.8.1 / 0.2.1

Verification: cargo test (376 default / 638 all-features), fuzz/shared
corpus replay (3 pass), clippy --all-targets -D warnings (default,
all-features, wasm32-unknown-unknown), fmt --check, doc, wasm32 check,
and cargo publish --dry-run --allow-dirty all green (64 packaged
files — fuzz/, docs/research|reviews|plans/, tasks/, .opencode/,
AGENTS.md all excluded)
2026-09-28 11:31:27 +00:00
glm-5.3-flash 08a3694464 fuzz: adopt fuzzing (wave 1) + alkcall 0.8.1 / alktunnels 0.2.1 bumps
Adopt the alk*/fuzzing posture (alkcall 0.8.1 + alktunnels 0.2.1
precedent) before the v0.1 publish — the cheapest moment this crate
will ever have for it:

- alkcall 0.8.1 + alktunnels 0.2.1: the duplicate-adopt/open fix is
  directly relevant to this crate's consumer open/adopt paths
- fuzz/ workspace (the sibling layout): nightly-pinned subtree, stable
  fuzz/shared library (corpus replay = the fuzz gate), detached runner,
  JSON dict, deterministic seed generator; 129 committed seeds
- three wave-1 targets over already-pub APIs: datagram_codec (the
  ASSOCIATE frame codec — the alkcall-fuzz-doc-assigned downstream
  target), rfc1928_codec (the forked RFC 1928 core's handshake state
  machines, both protocol directions), params_parse (the wire-stable
  open-op surface)
- one diagnostic: DatagramReader::retained_bytes() (the decoder-state
  bound's assertion target, the alktunnels retained_bytes() posture)
- docs/research/fuzzing.md: the scoped plan + implementation log;
  AGENTS.md gains the corpus-replay verification line
- campaigns: 3 × 10-min detached runs exited 0 (datagram ~1.9M execs,
  rfc1928 ~2.0M, params ~3.1M; oom/timeout/crash 0/0/0 on all 33 fork
  jobs per target; coverage saturated on both codec targets). No crate
  bugs; three harness-model defects found + fixed (2 pre-campaign by
  corpus replay, 2 campaign-found, crash inputs promoted as seeds 900/
  901): the len==0 well-framed decode partition, the fieldless-struct
  serde-seq form, the BadAtyp re-frame arm, the short-domain count-walk
  gate
- wave 2 (session_pumps stateful target) deferred to post-0.1 — the
  byte-level targets carry the attacker-reachable load for the publish

Verification: cargo test (15 suites ok, default + all-features), clippy
(all-targets + wasm + fuzz/shared), fmt, cargo doc, publish --dry-run,
corpus replay 129 seeds green, cargo fuzz build clean.

Refs: alkcall docs/research/fuzzing.md (§7.9 posture), alktunnels
docs/research/fuzzing.md; docs/research/fuzzing.md (this crate's copy)
2026-09-28 11:18:08 +00:00
glm-5.3-flash 8af23eeee0 docs: OQ-SK2-09 (the UDP door's peer-pin posture) + OQ-SK2-06's trigger-ownership check
- OQ-SK2-09 recorded: option 2 (the same-IP lock + reply-port
  refresh + the RFC drop rule) landed in 0.1.0 (31fb11c); option 3
  (the control-conn-derived expected peer — the complete fix)
  deferred on a concrete wildcard-bind deployment with address-level
  client mobility (QUIC migration is the likely driver); the
  deferred-index row added
- OQ-SK2-06: the trigger ownership checked (2026-09-28) — genuinely
  external by verified default (no suite-internal surface names a
  sandboxed alksocks consumer; the substrate is complete and
  gate-verified, nothing waits on nothing); the Schrödinger-bind
  check recorded in the OQ + the tracker task
- overview.md: the OQ index updated (SK2-09 added, SK2-06's
  ownership noted); the door bullet in the CHANGELOG carries the
  peer-pin posture + the async resolver note

Verification: cargo test + --all-features (15 suites each), clippy
--all-targets --all-features -D warnings clean, fmt clean, wasm check
clean, doc 0 warnings.
2026-09-28 09:17:04 +00:00
glm-5.3-flash 13c6209b07 review-003: the residue round's dispositions recorded — the review resolved 2026-09-27 10:54:45 +00:00
glm-5.3-flash d51ea8a262 review-003: fix the frontmatter's invalid YAML — the plain-scalar colons broke the parse 2026-09-27 10:21:57 +00:00
glm-5.3-flash 2db05172ef review-003: the assembly-layer full review — F-1/F-2 fixed, the residue dispositioned
- Review 003 written (docs/reviews/003-assembly-layer-implementation-
  review.md): the batch-2 assembly layer post-landing, the review-002
  template — correctness/security/smells/coverage over the five
  batch-2 modules + the batch-2 consumer/producer diff surface.
  Baseline: 375 default / 620 all-features green, clippy/fmt/doc
  clean, both wasm checks clean, publish dry-run completes,
  llvm-cov 93.68% lines / 91.01% functions.

- F-1 (major, fixed): the cred-bearing door swallowed every in-band
  refusal's mapped reply code (the CONNECT/BIND session-open errors
  and the accept-stage Err were bare closes) — a vanilla client got
  no reply where ADR-007 pins a reply-code-shaped refusal. Fixed with
  a write_refusal_reply helper (the door's boundary codec, RFC
  placeholder BND.ADDR) at all three sites, pinned by
  cred_door_in_band_refusal_surfaces_the_reply_code.

- F-2 (major, fixed): UdpFrontDoor::serve_on returned Ok(()) on a
  fatal relay-socket I/O failure against its own doc contract —
  the Io exit now surfaces as Err; the idle/association/session
  exits stay clean.

- Findings recorded, not fixed (the release-polish round's residue):
  D-1 (associate_with_token 0% covered), D-2 (the composed-egress
  failure matrix), D-3 (the io-kind refusal-table arms), S-1 (the
  UDP door's learned client address), N-1..N-8 (doc lines, posture
  notes, coverage residue).

Verification: cargo test (375) + --all-features (620) green,
clippy --all-targets --all-features -D warnings clean, fmt --check
clean, doc --no-deps clean, both wasm checks clean, publish
dry-run completes.
2026-09-26 11:14:04 +00:00
glm-5.3-flash 04c76e3a41 review: the batch-2 gate closed — the assembly layer verified, R-1/R-2 fixed
Review checkpoint closing batch 2 (the assembly layer). The gate
opens: the never-binds posture, seam contracts, door fidelity, the
bind-first graduation, feature-gate hygiene, and POC fidelity all
verify clean; two findings were corrected in the review change.

Findings corrected:

- R-1 (major): the UDP front door's in-band decode created a fresh
  DatagramReader per call and kept only the first frame of a batch —
  POC #2's first-cut bug (reader state must persist across calls;
  batched datagrams were silently dropped, mid-frame EOF was silent).
  Fix: an owning InbandBridge (persistent reader + pending queue +
  fail-loud mid-frame EOF, the AssociateSession shape) threaded
  through the channel->socket pump; pinned by three bridge unit
  tests (which fail against the per-call reader) and an end-to-end
  doubled-echo door-udp test.
- R-2 (convention 2): seven non-test expects -> typed errors —
  DoorBuildError (both door builders' .build() is now Result),
  ProducerDoorBuildError/ProducerDoorError (the bind decision is
  serve's typed error), the composed table invariant as an egress
  error, register_forwarded_serving -> Result (the alkcall
  diagnostic surfaced), TokenClientError (wrap on a spent client).
  New error types re-exported; test call sites updated.
- R-3/R-4 (doc residues): producer.md's local-backend section
  described a channel pipe — the landed ProducerDoor serves
  serve_socks5_over on the accepted socket directly;
  associate_with_token's doc (the TCP door refuses ASSOCIATE, never
  calls it); SessionOwner's doc (the accept uses SyncHalves/
  OwnedWrite).

Verification: cargo test (default) green; cargo test --all-features
green; cargo clippy --all-targets [--all-features] -- -D warnings
clean; cargo fmt --check clean; both wasm checks clean (default +
composed); local-on-wasm fails at mio as designed; cargo doc
--no-deps clean.

Task: tasks/implementation/review-assembly-layer.md (status:
completed; the batch-2 gate opens release polish).
2026-09-26 08:24:32 +00:00
glm-5.3-flash 1addedfdd0 assembly: the cross-cutting integration suite + docs sync (batch 2 closes)
- tests/assembly-integration.rs (7 tests, local + composed): the full
  -D story (vanilla cred-bearing client -> TCP door + UDP door ->
  producer w/ local providers -> real echo targets; CONNECT + BIND +
  ASSOCIATE live, one-command-per-connection, teardown + fresh
  sessions), the composed story (direct_egress + bindfirst_accept +
  real TCP dial; all three commands; the lazy-table dial-count
  witness), mixed assembly (channels-native + door clients on one
  registration; composed seams beside native sessions), the assembly
  teardown matrix (UDP-door idle bound; channel reaped; fresh
  association after), the producer door driving all three commands,
  and the -D domain-target pin (resolution at the producer's seam,
  ADR-012).
- Fix the drift the suite surfaced: ComposedEgress::next_reply ended
  fresh (never-opened-table) associations at birth — the ended-relay
  Err now fires only once a tunnel existed and every relay ended; the
  fresh table parks (the readiness contract). Regression-pinned in
  tests/composed-egress.rs (fresh_association_parks_before_any_
  tunnel_is_opened).
- Harness: the composed-accept machinery single-sourced into
  tests/harness.rs (the composed suites' shapes + the five-gate
  composed identity); composed-accept.rs consumes the shared shapes.
- Docs sync: README Current State (the assembly layer landed; both
  suites named), lib.rs crate docs (the assembly-layer paragraph),
  consumer.md (the TokenClient door-only contract + the
  one-command-per-connection posture reconciled).
- Task assembly-integration-suite: completed; Notes + Summary filled
  (the local-on-wasm failure observed: mio's unsupported-wasm error).

Verification: cargo test (375), cargo test --all-features (615),
clippy --all-targets -D warnings (default + all-features), fmt --check,
doc --no-deps (0 warnings), both wasm checks (default + composed),
local-on-wasm fails as designed.
2026-09-25 23:03:13 +00:00
glm-5.3-flash 431920ddef review: the fix-round gate closed — every review-002 finding verified, batch 2 opens
The closing checkpoint (tasks/implementation/review-fix-round-002.md):
each review-002 finding verified closed against the landed tree, the
full verification sweep green, conventions re-swept, and the gate
condition (ADR-014 accepted, no major finding) holds.

Per-finding verification (all nine checklist points):
- C-1: the take-guard verified — a second await_inbound returns the
  spent shape Ok(None), the re-read structurally impossible (the plane
  owns the stream); pinned by the double-read + reply1-twice tests.
  D-1's one-reader decision recorded (option (a), BindReply1 cut).
- C-3 closed: the builder's explicit bind_policy is the substrate-free
  gate; the presence reading is only the backward-compat default; the
  pump handler's identity-derived gate byte-identical.
- D-2 closed: the full builder chain through .register(...) serves all
  three commands end to end (RegisterMode::ProducerBuilder + the
  integration test, identity witness asserted).
- N-1/N-4 coherent: the cut list gone (zero references), keep-notes
  current, the Refused vocabulary honest at all five sites + the
  harness's minimal producer, wire untouched, provenance extended.
- D-3 resolved (declare side): the channel:open_failed ErrorDefinition
  declared, schema pinned drift-free against the typed parse table.
- N-8 re-run: 96.30% regions / 97.28% lines; every named line covered;
  the residual attributed (accept_bi log arm, fork accepted-uncovered,
  test panic-guards) — no new load-bearing gaps.
- N-5/N-6 verified: the shared module compiles into both crates via
  the crate-root mount + extern-crate-self alias; open_and_negotiate
  single-sources the teardown-at-birth prologue.
- C-2 decided: ADR-014 accepted (option 1 — teardown-governed phases),
  the spec lines carry the posture.
- Cross-cutting sweep green: test 375 green (+ all-features, local,
  composed), clippy -D warnings clean, fmt clean, doc clean, both wasm
  checks clean, publish dry-run completes; no unwrap/expect/panic in
  non-test code (mechanically attributed across src/); no local/
  composed code exists (the batch boundary holds).

One gate-round finding, F-1 (minor), fixed in this change: the
review-numbering collision — "review 002 R-1/R-2/R-4" cited the
batch-1 gate review's findings (tasks/implementation/
review-protocol-core.md) under a name that now means the general
review; reworded to "the gate review's R-N" at all six sites
(producer.rs, consumer.rs, egress.rs, the review doc). Review 002
marked resolved; the next general review doc is 003-*.

Verification: cargo test (375 green), --all-features + --features
local/composed green, clippy --all-targets -D warnings clean, fmt
--check clean, doc clean, both wasm checks clean, publish dry-run
completes, llvm-cov 96.30% regions / 97.28% lines attributed.
2026-09-25 04:02:16 +00:00
glm-5.3-flash 986bd13ce7 adr-014: the idle-timeout posture — teardown-governed phases, no protocol-layer idle bound
- ADR-014 accepted (review 002 C-2): the pre-command handshake, the
  BIND quiet wait, and the association lifetime are all
  teardown-governed; the protocol layer never times out (option 1)
- the BIND relationship recorded as same regime (ADR-007 decided one
  phase's ends by designing BIND; ADR-014 records the inherited
  resolution — one principle, not two)
- the doors' accept-path obligations recorded pre-batch-2 (accept-stage
  idle bound, per-credential/per-peer caps, accept-queue bounds);
  revisitable additively (an optional producer-side idle seam would
  be config, not wire)
- spec lines carry the decided posture: wire.md (association-lifetime
  bullet, no-in-band-control bullet, preamble, frontmatter);
  producer.md (the open handler, the local-backend section, decision
  table, frontmatter); overview.md ADR index
- one upstream-fidelity correction: upstream's dial timeout maps to
  0x06 (TTL expired), not 0x01 as the review sketch suggested
- open-questions.md unchanged (C-2 was never tracked there)

Verification: cargo test green (357 passed), clippy -D warnings clean,
fmt clean, cargo doc clean, wasm check + clippy (wasm32) clean
2026-09-24 19:16:30 +00:00
glm-5.3-flash 68d5be36a0 rfc1928: the keep-or-cut sweep + the honest refusal vocabulary (review-002 N-1, N-4)
- N-1 cut: auth_method_enums! (macro + generated StandardAuthentication/
  StandardAuthenticationStarted/allow_no_auth), skip_auth_this_is_not_
  rfc_compliant, CheckResult's Option/Result impls (bool stays) — the
  producer-replaced machinery; ADR-013's no-speculative-surface posture
- N-1 keep-notes made current: ConnectError (hand-port companion; the
  fired trigger + keep disposition recorded in stream.rs),
  transfer/wait_on_tcp (differential-suite-consumed), Bug (upstream-
  verbatim, display intact)
- N-4: new SocksServerError::Refused(&'static str) — the honest log
  vocabulary for the five in-stream policy refusal sites (the BIND
  command gate + dial/egress/bind-factory/bind-accept seams) and the
  harness's minimal producer; wire bytes untouched (Bug keeps its
  display; AuthenticationRejected stays the typestate's auth-reject)
- Provenance extended, not replaced (convention 17): server.rs module
  doc's owned-changes paragraph + rfc1928.md's owned-code post-fork
  changes list + last_updated
- Differential :103 comment reworded to the RFC's ordering rationale;
  AuthMethod doc updated for the macro cut
- Tests: refusal-site session-error asserts moved to Refused, the
  mapping-table loop grew the variant, a display/shape test pins it

Verified: cargo test (356 green incl. --all-features), clippy/fmt/doc
clean, both wasm checks clean.
2026-09-24 18:20:31 +00:00
glm-5.3-flash ff81f2d27b producer: the explicit bind-policy gate + the builder-register pin (review-002 C-3, D-2, S-1, N-2)
- C-3: Socks5ProducerBuilder.bind_policy(bool) — the substrate-free
  entry's explicit BIND gate, defaulting to the accept seam's
  presence; seam presence is never the sole gate
- D-2: RegisterMode::ProducerBuilder + an integration test wiring the
  full builder through .register(...) serving all three commands
- S-1: run_datagram_stage's doc names the hot-Ok(None) residual
- N-2: wire.md §UDP ASSOCIATE carries the inline-send backpressure line

Verified: cargo test (352 green), clippy/fmt/doc clean, wasm checks clean.
2026-09-24 18:04:55 +00:00
glm-5.3-flash 53739b20cb consumer: the BIND reply#2 re-entry guard + session hygiene (review-002 C-1, D-1, N-6, S-2)
- C-1: BindSession::await_inbound is take-guarded — the first read
  takes the session's stream; the returned BindDataPlane owns it (the
  TakenInner pairing posture; the session stays the teardown owner),
  so a second call returns the family's spent shape Ok(None) and can
  never re-read the live data plane. A failed read restores the inner
  (the phase is only consumed on success; the producer ends the
  session on every post-reply#1 failure exit, so a re-call EOFs —
  never a live data-plane re-read either way). Pinned by the
  double-await_inbound integration test (the spent shape + the
  data-plane bytes asserted untouched) and the spent-BIND unit test.
- D-1: one normative reply#2 reader (option a) — the session's
  await_inbound; BindReply1::await_inbound is cut and reply1() is
  documented as a view (bind_addr + raw_mut), matching its actual
  usage; the reply1()-twice re-entry path is closed (pinned by the
  view test).
- N-6: the three session constructors' prologues collapsed into one
  private open_and_negotiate helper (teardown-at-birth in one place);
  zero behavior change.
- S-2: the EOF-propagation doc line on all three reap sites (the
  dropped teardown_channel handle is deliberate — the graceful shape;
  clear_all aborts instead).
- BindDataPlane is un-lifetimed (owns the stream); into_inner returns
  the owned Socks5Stream<BiStream>; docs synced (module + session
  docs, consumer.md §The BIND client).

Verification: cargo test 352 green (all-features too), clippy
-D warnings clean, fmt clean, cargo doc clean, both wasm checks clean.
2026-09-24 11:58:55 +00:00
glm-5.3-flash 6d14d35a54 tasks: decompose the review-002 fix round — eight dependency-ordered tasks
The general review (docs/reviews/002-protocol-core-implementation-review.md)
decomposed into the fix-round group, grouped so no session carries
both a code-fix vertical and the test sweep:

- fix-bind-reply2-reentry: C-1 (the BIND reply#2 re-entry guard) +
  D-1 (the reader decision) + N-6 (the constructor prologue
  helper) + S-2 (the reap doc line) — one consumer session
- fix-producer-gate-policy: C-3 (the explicit BIND gate input) +
  D-2 (the register/builder coverage) + S-1/N-2 (the stage doc
  lines) — one producer session
- fix-rfc1928-posture: N-1 (the keep-or-cut pass) + N-4 (the honest
  refusal vocabulary) — one fork posture session
- fix-hygiene-residue: D-3 (the ErrorDefinition declaration) +
  N-3 (the unreachable let-else) + N-9 (the is_mid_frame note)
- fix-coverage-residue: N-8's attributed line list — tests only,
  after the code fixes (final shapes)
- fix-test-helper-consolidation: N-5 — after the coverage round
- architecture/adr-014-idle-timeout-posture: C-2 — the ADR-sized
  decision, independent, before the doors exist
- review-fix-round-002: the closing checkpoint; the batch-2 gate

The review doc's disposition table now names the landed tasks.
N-7 is recorded-only (the review's own recommendation).
2026-09-24 11:18:21 +00:00
glm-5.3-flash d612d7f7f2 review 003: the protocol-core implementation reviewed — correctness/security/smells/coverage
General review of the landed batch-1 protocol core (docs/reviews/
002-protocol-core-implementation-review.md), complementing the
narrow fidelity review: correctness hazards, security posture,
dead surface, and cargo-llvm-cov attribution, cross-checked against
alkcall 0.8.0 and the sibling crates.

Two majors:
- C-1: BindSession::await_inbound (and BindReply1::await_inbound)
  is re-entrant with no spent-marker — a second call re-reads the
  live data plane as reply#2, silently corrupting the pipe. Fix
  sketched: inner.take() (the session's own None-arm posture) +
  tests.
- C-2: no timeout surface on the pre-command RFC handshake or the
  association (bounded memory, unbounded time; the alkcall
  establishment bound covers only the open op). A decision to make
  before batch 2's doors route vanilla clients through the same
  phases; sketched as an ADR-level choice, not a core defect.

Minors: C-3 (the substrate-free can_bind gate conflates
factory-wired with allowed), D-1 (BindReply1::await_inbound is
spec'd, 0% covered, never called — the two-reader ambiguity), D-2
(Socks5Producer::register + the builder's egress/accept setters
unexercised — the spec'd assembly shape has no test), D-3
(error_schemas declared vec![] while params.rs's doc claims the
ADR-049/ADR-016 contract; alktty declares it), S-1 (the stage's
Ok(None) defense is livelock-safe but rate-unbounded — posture
note), N-1 (review 001's keep-or-cut triggers fired:
StandardAuthentication/skip_auth_this_is_not_rfc_compliant/
CheckResult impls are cut candidates; ConnectError/transfer/
wait_on_tcp stay as hand-port-map companions; Bug is now consumed).

Coverage (94.52% regions / 95.55% lines): the load-bearing gaps
attributed in N-8 — the two untested split surfaces, ASSOCIATE
into_inner's Ok arm, the datagram stage's three failure exits
(ReplyFrameRejected/EgressEnded/Io), read_reply2's version arm,
plus single-arm cosmetics.

Verified: cargo test 348 green; --all-features green; clippy
--all-targets -D warnings clean; fmt --check clean; cargo doc
--no-deps clean; both wasm checks clean; cargo publish --dry-run
completes; cargo llvm-cov 94.52/94.67/95.55 (regions/functions/
lines). No code changed in this review — findings documented for
the fix decomposition.
2026-09-24 10:35:33 +00:00
glm-5.3-flash 16b21e3447 review 002: the protocol core reviewed — readiness-contract hardening + two convention fixes
The batch-1 gate review (tasks/implementation/review-protocol-core.md):
all eight criteria examined (seam contracts, wire fidelity, access
control, teardown/lifecycle, conventions, wasm, POC fidelity, docs
sync); the gate to batch 2 opens. Findings R-1/R-2 were corrected in
the review change; R-3..R-5 are doc residues fixed in the same change;
R-6 is accepted with rationale.

- R-1 (major): the datagram stage's Ok(None) re-park is unsafe against
  a zero-yield egress — a next_reply that is a pure instantly-ready
  Ok(None) with no await wins every select! poll and livelocks the
  stage on a current-thread runtime (empirically reproduced; the
  landed unit test's mutex masked the hazard at its lock's yield
  boundary; multi-thread survives). Fix: the Ok(None) handler yields
  before re-parking; a pinning unit test drives the strictest
  zero-yield violator.
- R-2: the two into_inner expect()s (consumer sessions) become typed
  Result<_, SpentSessionError> — convention 2's no-panic rule; spent-
  session unit tests pin the shape; test call sites updated.
- R-3/R-4/R-5: doc residues — stale task-time phrasings in
  egress.rs/producer.rs, producer.md's register() sketch reconciled
  to the landed signature, the establishment-bound test doc reworded
  to what the substrate-free probe actually pins.
- R-6 (accepted): the wasm gate rides a transitive getrandom/wasm_js
  feature unification (alkcall -> jsonschema/referencing -> ahash) —
  verified compiling clean today; noted for OQ-SK2-06.

Verified: cargo test 348 green; --all-features green; clippy
--all-targets -D warnings clean; fmt --check clean; both wasm checks
clean (from a clean wasm target dir); cargo doc --no-deps clean.
The bind-only-identity reconciliation from the integration session
was independently verified as correct (ADR-006 as landed; the suite
pins it). Batch boundary holds: no local/composed code exists.
2026-09-24 09:13:08 +00:00
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
glm-5.3-flash d530eae5c4 wire: the ASSOCIATE datagram frame codec — frame + DatagramReader (ADR-003)
- frame(addr, payload): [len: u16 BE][addr + data] over
  TargetAddr::to_be_bytes() + payload; the joint bound enforced at
  frame time (checked_add; 65507 + 255-char domain = 65766 > 65535 →
  Oversize) with addr_encoding_len exposed (7 v4 / 19 v6 / 259 max
  domain) and MAX_INNER_LEN pinned
- DatagramReader: incremental reassembly across chunk boundaries
  (split frames, batched frames, partial headers), infallible,
  returning per-frame Results; the addr sub-layout decoded by hand
  (ATYP-keyed, UTF-8-validated) with typed decode errors —
  BadAtyp / ShortAddress / DomainNotUtf8 / EmptyFrame — so the
  producer stage fails the association loud on protocol garbage
  (udp_undecodable_frame_ends_association, POC #2)
- module docs state the framing-once invariant (the egress speaks
  inner bytes; this layer owns the single length prefix — the
  double-framing bug class POC #2 caught), the F-2 invariant at
  payload level (a zero-length payload is a legal empty datagram,
  never EOF; wire len == 0 is unreachable garbage), and the EOF
  layering (the channels-level sentinel, outside the codec)
- doc-sync: wire.md + bast.md residue corrected — "len == 0 is a
  legal empty datagram" replaced with the payload-level F-2
  statement (len == 0 unreachable since addr >= 7 bytes)
- lib.rs re-exports frame, DatagramReader, addr_encoding_len,
  MAX_INNER_LEN, WireError (convention 15)

Verification: cargo test (58 lib + 37 differential), clippy
--all-targets -- -D warnings, fmt --check, doc --no-deps, and both
wasm checks (check + clippy on wasm32-unknown-unknown) — all clean.
2026-09-23 15:02:24 +00:00
glm-5.3-flash 7bd5d6a7e7 review 001 remediation: the forked core's findings resolved
Batch 1 (F-1 + N-1 + S-2 + N-4):
- reply_success/reply_error write replies with write_all (partial-write
  hazard closed; the err_when-chaining idiom suppresses
  clippy::unused_io_amount — reproduced fresh via a five-variant probe)
- rfc1928.md's write_all bullet records both conversions and the real
  rule (replies are single-shot, all-or-nothing) + the lint blind spot
- reject's doc names the 0xff vocabulary choice (RFC 1929 needs only
  non-0x00); Addr::Domain's deliberating comment pinned

Batch 2 (coverage: L-1 + L-2 + L-3 + S-1):
- client v6 request encoding pinned (22 bytes, ATYP=4, slice bounds)
- Socks5Stream::shutdown() EOF/BrokenPipe propagation pinned
- wait_on_tcp's io-error arm + SocksServerError::to_reply_error's full
  mapping table + read_command's command-phase version mismatch covered
- S-1: read_address's 1-byte-field bound documented; decode-side
  255/256 boundary pinned both faces

Batch 3 (posture notes: C-1, C-2, N-2, N-3 — decided keep-with-note):
- ConnectError: hand-port map's companion (cut if the producer layer
  lands without consuming it); StandardAuthentication: ADR-005
  auth-split is the anticipated consumer; CheckResult same shape
- tracing: the fork's declared logging seam, noted in Cargo.toml

Coverage 92.63% → 93.09% regions / 95.40% → 96.07% lines; the named
gaps closed, the remainder is accepted-uncovered with disposition.
Review doc carries the re-verification + resolution record.

Verification: cargo test (39 lib + 37 differential), clippy
(all-targets + wasm32) -D warnings, fmt, doc, wasm check, MSRV 1.88,
publish dry-run — all green.
2026-09-23 06:25:27 +00:00
glm-5.3-flash 4bd25c093e review: rfc1928 post-fork full review — 001
Security + code-smell + coverage review of the targeted fork as owned
code (the extraction review was narrow; this is the full pass).

Findings: 1 major (F-1: reply_success/reply_error write replies with
.write() — a partial-write hazard invisible to clippy's
unused_io_amount under the err_when-chaining idiom, executable-probe
verified; rfc1928.md's write_all rationale is false for these sites),
7 minors (2 security-posture notes, 2 extraction leftovers, 3
coverage gaps), 4 observations. No critical findings.

Verification: 38+32 tests, clippy (all-targets + wasm32) -D warnings,
fmt, doc, wasm check, publish dry-run, MSRV 1.88 native+wasm — all
green. Coverage 92.63% regions / 95.40% lines (cargo-llvm-cov); gaps
attributed per finding. Differential suite's 15 upstream citations
spot-checked against the v1.0.0 reference checkout — all accurate.
2026-09-23 05:46:04 +00:00
glm-5.3-flash f8c34444fb rfc1928: the targeted fork — rename + convention pass (ADR-013)
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.
2026-09-22 12:41:30 +00:00
glm-5.3-flash 001aac1fd5 docs: the targeted fork — ADR-013, the RFC 1928 core is owned
ADR-013 supersedes ADR-011's maintenance posture (not its mechanics):
the extracted T-generic subset is fully owned code, the vendor
framing is retired. Module renamed src/vendor/ -> src/rfc1928/
(naming decided in the ADR: 'vendor' names an ownership relation
now gone; 'socks5' would stutter and collide with the future
producer/consumer layers). Fork point = the tree as of the
extraction-review commit (5b18d4d); provenance stays permanent
(module docs + the extended LICENSE notice).

- ADR-013: fork posture, license mechanics (notice extended, not
  replaced; post-fork modifications under the crate license),
  hand-port replaces re-vendor, lint-allow posture dissolved
- ADR-011 marked Superseded (extraction mechanics remain
  authoritative); ADR-002 references re-pointed
- vendor.md -> rfc1928.md rewritten as the owned-core spec (the cut
  table re-read as the hand-port map)
- spec sweep: README index (ADR-013 row, doc table, principle 8),
  overview (module map, deps, ADR table), producer/consumer/wire/
  bast reference vocabulary, open-questions OQ-SK-04 resolution,
  AGENTS.md conventions 4/17 + verification note + context bullet,
  Cargo.toml description

Verification: cargo doc --no-deps clean; no stale vendor.md/src-vendor
references outside the ADR-011 historical text.
2026-09-22 12:33:36 +00:00
glm-5.3-flash 5b18d4d292 review: vendor extraction — gate opens; F-1 panic arm fixed
The extraction review against vendor.md's cut table, ADR-011
§Amendment, and AGENTS.md conventions. All five file diffs vs the
fast-socks5 v1.0.0 reference checkout read hunk-by-hunk and
categorized (cut / carried changes / adjustments / provenance /
tests); wasm, clippy, fmt, doc all green; RFC 1928 spot-checks
(reply form, method order, UDP zero fallback, domain cap, FRAG
split) independently verified against the RFC text.

F-1 (critical, resolved here): ReplyError::from_u8 kept upstream's
unreachable!("ReplyError code unsupported.") arm while being
wire-reachable — Socks5Stream::read_request_reply feeds the raw
reply byte from the wire into it, and RFC 1928 §6 marks 0x09-0xFF
unassigned, so a misbehaving peer would panic the consumer task.
Unassigned codes now map to GeneralFailure (the RFC's catch-all),
pinned by a new test, and the panic-translation adjustment is
recorded in vendor.md's adjustment list (with the Config-Default
and write_all notes) in the same change.

Findings F-2..F-4 (dead commented code dropped with its region;
Cargo.toml feature-layout comments; the preserved resolve_dns error
string) reviewed and accepted. Review task file carries the full
record; the gate to the downstream task groups is open.

Verified: cargo test (38 + 32), cargo test --all-features, clippy
--all-targets and --target wasm32-unknown-unknown (-D warnings),
cargo check --target wasm32-unknown-unknown, cargo fmt --check,
cargo doc --no-deps.
2026-09-22 11:01:55 +00:00
glm-5.3-flash b0cfc26065 docs: pin the vendor scope as extraction — the net gate dissolves
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).
2026-09-21 03:15:04 +00:00
glm-5.3-flash 9587670138 docs: Phase 1 architecture — specs, ADRs 001-012, open-questions tracker
- docs/architecture/: README index, overview, wire, producer,
  consumer, vendor, bast specs + open-questions.md (the OQ-SK-01..09
  ledger promoted; new questions as OQ-SK2-06..)
- ADRs 001-012: ALPN/op/params, protocol base, the handle swap,
  the dial-callback shape, auth split by the door, access control
  (open gate + BIND command gate), BIND in base, provider defaults,
  feature gates, channel capacity, the inline vendor, target policy
- deferred OQs (SK2-06, SK2-07) with tracker tasks in
  tasks/architecture/ per the sdd_process deferred-OQ protocol
- review pass applied: frame-length joint bound (65766 corner),
  accept_no_auth vs skip_auth corrected against fast-socks5 source,
  composed-feature wasm posture, cross-reference fixes

Verified: cross-references (all ADR/OQ refs resolve), doc sizes
under split threshold, Phase 0 fidelity spot-checks
2026-09-20 18:41:56 +00:00
glm-5.3-flash 3044abe296 docs: consolidate phase-0 — current-state form, one statement per decision
The Phase 0 doc had accumulated stratified updates (each revision layered
on top of the prior text), leaving duplicated statements, superseded
reasoning presented as live, and a few internal conflicts. This rewrite
is a consolidation only — no decisions changed:

- Each OQ opens with a status line; resolved content stated as settled
  fact; superseded reasoning retained only where it carries Phase 1 ADR
  weight (e.g. OQ-SK-04's decision tree as the reasoning trail).
- The inline-vendor decision now stated once (OQ-SK-04 + the Convergence
  Layering bullet) instead of ~10 restatements; stale 'file the upstream
  ask' residue removed (Convergence protocol-base bullet).
- The component-3 transfer to alknet stated once in §Vision; the noq
  section is background-only; OQ-SK-06 compressed to its resolution.
- OQ-SK-01/03's duplicated direct-op update merged into its OQ;
  OQ-SK-08's superseded sequencing consistently framed as the retired
  POC workaround against alktunnels 0.1.0.
- Checklist: OQ-SK-03/06/07 and the POC box checked to match their own
  text; 'RFC-refused in both POCs' corrected (fast-socks5 refuses BIND;
  POC #5 implemented it).
- Preserved: all external anchors cross-referenced by the findings files
  (§OQ-SK-07 register + numbering, §Prior art's run_udp_proxy_custom
  caveat, OQ-SK-04's decision record, the Convergence Layering bullet),
  every ADR/API/file:line reference, POC numbers, and measurement
  figures. Restored on audit: the 65507 u16-suffices rationale,
  skip_auth_this_is_not_rfc_compliant, lib.rs:91, the wasm-resolver
  interaction note.

Verified: anchor audit against all cross-referencing docs (no dangling
references), content-loss audit vs the prior version (no unsuperseded
fact dropped), fast-socks5 v1.0.0 spot-checks (TCPBind refusal sites,
wait_on_tcp:1195, private new_reply, typestate methods — all true).
2026-09-20 11:45:32 +00:00
glm-5.3-flash cced3b2b85 docs: correct fast-socks5 posture — third-party upstream, inline vendor decided
The ownership premise ('we own fast-socks5') was wrong — it is
third-party upstream and has not been forked. The corrected posture
resolves OQ-SK-04: inline vendor. The wrapper's needs exceed the wasm
gate regardless (BIND absent upstream — POC #5 proved the wrapper
drives it; the run_udp_proxy_custom bind seam; private new_reply), so
carrying the T-generic subset (~120 cfg lines, POC #4-verified) pays
for itself independent of the adapter story.

AGENTS.md:
- convention 17 rewritten: 'Upstream: alkcall is ours to shape;
  fast-socks5 is inlined' — the ownership split stated plainly, the
  inline vendor + its four carried changes named, the courtesy PR
  kept optional/never-waited-on, the vendor point (v1.0.0) noted
- convention 4: wasm posture note updated to the resolved vendor
- prior-art entry: fast-socks5 marked third-party/NOT ours

phase-0.md:
- OQ-SK-04 RESOLVED (2026-09-20): resolution note headers the OQ (the
  two settling facts: wrong ownership premise; needs exceed the gate);
  decision tree retained as reasoning trail with both legs annotated
  (Case 2's premise falsified by the BIND need); the root question
  reframed as retrospective; checklist item checked
- §Prior art fast-socks5: header + run_udp_proxy_custom caveat
  reworded from 'fileable ask' to in-tree change
- settled-foundations wasm caveat resolved; survey + checklist
  prior-art entries marked; 'What Phase 0 could NOT answer' wasm item
  struck as resolved; convergence Layering bullet now enumerates the
  four in-tree carried changes; upstream-asks bullet: fast-socks5
  items are no longer asks

poc-connect-wasm-findings.md / poc-bind-findings.md /
iroh-socks5-eval.md: 'we own it' ask sections corrected to
in-tree-vendor changes (dangling fragment from an earlier edit also
fixed); ledger item 3 annotated

Verified: fast-socks5 upstream still 1.0.0, no net feature, BIND
refused (lib.rs:384-386/server.rs:813-816) — the needs-are-real facts
stand. Docs-only change; no build surface affected.
2026-09-20 09:59:12 +00:00
glm-5.3-flash cb553ea033 docs: record the upstream graduation landing (alkcall 0.8.0, alktunnels 0.2.0)
The ask ledger's two alktunnels items landed 2026-09-18/20 — superseded
in shape, not implemented as posed. The graduation (alktunnels
tunnels-graduation.md -> ADRs 007/008) adopted the ssh
forwarded-tcpip-shaped alternative over the per-ask carriers.

phase-0.md:
- settled-foundations: establishment gains the reply-projection note
  (ADR-049 amendment 3); the relay/hub note records the in-tree
  ChannelRelay/HubLegTemplate (ADR-051); identity-seam note marked
  current at 0.8.0
- OQ-SK-01: Option A updated — the direct op (channels/tunnel/direct,
  ADR-007) is the dynamic-target channel; POC #5's scope-gate +
  ADR-007 rationale point the same way (separation lives at the ACL)
- OQ-SK-03: composed egress's vehicle is open_direct +
  Substrate::Udp; the ~0.8 ms measurement carries over; the stale
  POC-candidate hunch paragraph updated
- OQ-SK-08: the landed note — ask #1 dissolved (bind-first establisher;
  the real bound rides the open reply; POC #5's open-rides-the-accept
  workaround + the 10s-bound finding retire), ask #2 landed at the
  wire's native moment (forwarded op's {listen, substrate, peer}
  params), correlation token per ADR-008 Amendment 1
- convergence: egress seam composes against 0.2.0; the upstream-asks
  bullet records the landing per crate; the BIND hand-off bullet notes
  variant 2 is now fully vanilla-fidelity
- checklist OQ-SK-08 item + POC #5 register entry point at the landed
  note

poc-bind-findings.md: ledger statuses appended (superseded in shape;
evidence stands as the alktunnels-0.1.0 record)

AGENTS.md: alkcall pin 0.7.1 -> 0.8.0 (reply projection noted);
architecture context: alktunnels v0.2.0 entry added, alkcall 0.8.0
surface listed

Verified against the repos: alkcall 0.8.0 changelog (U-1/U-2/ADR-051),
alktunnels 0.2.0 changelog + ADR-007/008 + exports
(bindfirst_establisher producer.rs:641, register_tunnel_bindfirst_
openable :924), fast-socks5 still 1.0.0 with no net feature (the
courtesy tail). Docs-only change; no build surface affected.
2026-09-20 09:49:08 +00:00
glm-5.3-flash cb4d58a2bf docs: POC #5 (channels-native SOCKS5 BIND) findings
POC #5 run 2026-09-15 (alksocks-bind-poc, standalone, 9 tests) —
OQ-SK-08 POC-validated; the POC register (OQ-SK-07) is closed.

- The BIND phase model extends end to end on one channel: request →
  reply#1 (BND.ADDR) → quiet wait → one inbound accept → reply#2
  (peer) → pump_bidi pass-through (0 B overhead, like CONNECT)
- Both accept variants implemented: local (real TcpListener, faithful
  RFC) + composed (alktunnels listen-tunnel — per-listener ACL for
  free, hub-relayable)
- The address-first-vs-accept-first deadlock resolved in shape:
  reply#1 first, the tunnel open rides the accept future
- The socks5:bind scope gate distinguishes ingress from egress
  (RFC-faithful ConnectionNotAllowed refusal; CONNECT unaffected)
- Vanilla front door re-validated for the BIND conversation (raw pipe,
  zero translation); CONNECT + ASSOCIATE regression-guarded on the
  same registration — the RFC 1928 command surface is complete
- fast-socks5: zero BIND ask (typestate-driven; reply_success carries
  reply#1); courtesy ask: publish the private new_reply encoder
- alktunnels ask ledger pinned at two items for the one-version bump:
  (1) listen-addr inspection without consuming an accept, (2) accepted
  handles carrying peer metadata — both POC-evidenced, both additive

Verification: cargo test (9/9), clippy --all-targets -D warnings,
fmt --check clean in alksocks-bind-poc.
2026-09-15 06:09:35 +00:00
glm-5.3-flash aac63d17fc docs: phase-0 consistency pass — POC register + client-wrapper transfer residue
- OQ-SK-07: add a POC register table (one-place accounting of all five
  numbered POCs: #1/#2/#4 passed, #3 dropped, #5 pending); mark the
  priority order as historical; note numbering must not be renumbered
- §Vision: fix the components 1+2 layout sentence now that component 3
  transferred; keep the transfer reasoning
- alknet-client ancestor section: replace the stale 'this crate's
  client half rehomes that work' sentence with a historical note (the
  rehoming is alknet's, per the 2026-09-14 scope decision)
- noq prior-art section + OQ-SK-06: add transfer banners so ~25 lines
  of transferred research are not read as live scope
- OQ-SK-02: spell out what the 'yes / planes-don't-compare /
  probably-not' shorthand maps to
- OQ-SK-04: note the component-3 transfer does not change the wasm
  decision inputs
- OQ-SK-07 #3: rewrite the ambiguous 'at the time of the decision'
  parenthetical as before/after
- Survey list: mark noq and iroh entries as alknet-facing background
- Convergence checklist: uncheck the POC item (BIND POC still pending)
  and explain the checkbox semantics

Verified against the repo: findings files, POC crates
(alksocks-connect-poc 8 tests, alksocks-udp-poc 11 tests,
alksocks-fs5-wasm-poc exists), upstream line refs (fast-socks5
lib.rs:384-386 / server.rs:813-816 / 1195, noq runtime/mod.rs:44 /
endpoint.rs:162, alktunnels producer.rs:207,392), op name
channels/socks5/sub in both POC crates.

Verification: docs-only change; no build/test surface affected.
2026-09-15 04:07:42 +00:00
glm-5.3-flash 601afa3922 docs: BIND use case found (OQ-SK-08, POC #5) + capacity OQ-SK-09
Post-POC #2 findings review: a real BIND use case and mechanism
surfaced, plus a channel-capacity analysis for proxy workloads.

- OQ-SK-08: fast-socks5 parses but refuses TCPBind — the wrapper owns
  the whole shape (zero upstream ask). Phase-model extension: reply#1
  (BND.ADDR) -> quiet wait -> one inbound accept -> reply#2 (peer) ->
  raw pass-through; iroh-socks5's channels-native BIND is convergent
  precedent. Accept variants mirror OQ-SK-03's egress variants:
  feature-gated local listener (faithful RFC) vs composed alktunnels
  listen-tunnel (needs a listen-addr-inspection ask) vs wrapper-aware
  only. Security note: BIND is inbound egress — SOCKS5_OPEN_SCOPE must
  distinguish it from CONNECT/ASSOCIATE.
- OQ-SK-09: 256-channel default vs proxy fan-out; wire change
  rejected, assembly-layer config + documented proxy-workload
  recommendation is the mechanism; in-channel port multiplexing
  ([port:u16] per chunk) considered and rejected (re-opens OQ-SK-03's
  demux-vs-phase trade, breaks 0-B pass-through, AGENTS.md #10).
- OQ-SK-05 addendum: virtual address space / identity-scoped subnets
  adoptable with no wire change — DST.ADDR/BND.ADDR translation via
  the dial callback; hub exposure via terminate-and-re-produce.
- POC #5 (BIND, both accept variants, vanilla front-door test) added
  to OQ-SK-07; checklist + convergence updated; upstream-asks list
  pinned (fast-socks5: net gate + UDP bind seam; alktunnels:
  listen-addr inspection).

Verification: docs-only change (phase-0.md).
2026-09-15 03:28:15 +00:00
glm-5.3-flash 6c71c0e5d2 docs: Phase 0 converged — scope pinned to socks+channels, recommended approach written
- Scope resolution: the quinn/noq AsyncUdpSocket client wrapper
  (component 3) transfers to the alknet rewrite (its ancestor work —
  ADR-090, quinn-proxy POC — lives there; it consumes no channels and
  has no consumers planned here). OQ-SK-06 and would-be POC #3 go
  with it. alksocks = the producer/consumer pair only.
- Convergence section added (Phase 0's output for the Architect): the
  validated approach pieces (fast-socks5 typestate driven directly for
  both commands, the handle-swap wire shape, DialFn + EgressFactory
  egress seam, "both" auth split by the door, alktty/alktunnels
  layering, vendored-subset fork posture) and the list of Phase 1 ADR
  decisions with their collected inputs (datagram framing, demux vs
  phase, params/ALPN, scope convention, door mapping, wasm posture).
- Checklist: OQ-SK-06 resolved-by-transfer; POC list complete (#1/#2/#4
  passed, #3 dropped); convergence checked off.
2026-09-14 11:07:57 +00:00
glm-5.3-flash c77c28c28e docs: POC #2 (channels-native UDP ASSOCIATE) findings
- alksocks-udp-poc (/workspace/alksocks-udp-poc/): 11 tests pass,
  clippy -D warnings + fmt clean; the handle-swap baseline validated
  end to end (one channel per association, [len][addr+data] frames
  in-band, RSV/FRAG only at front doors, channel EOF = association
  lifetime, per-datagram addressing without a flow table)
- Both egress variants implemented behind the EgressFactory callback;
  composed per-destination alktunnels udp-tunnel open cost measured at
  ~0.8 ms mean (N=20, in-process loopback) — comfortable for DNS +
  browsing
- Front-door RFC-codec composition confirmed (RFC UDP header codec at
  the vanilla boundary only); CONNECT regression-guarded on the same
  registration
- Load-bearing API findings for Phase 1: the select!-driven stage's
  egress readiness contract (Pending-when-idle; readable() not
  writable(); closed queues end, never spin) and the length framing
  applied exactly once by the wire layer (egress returns inner bytes)

Verification: cargo test (11 pass), cargo clippy --all-targets -- -D
warnings, cargo fmt --check, cargo doc --no-deps (all clean in the
POC crate); phase-0.md OQ-SK-03/07 statuses updated.
2026-09-14 11:03:24 +00:00
glm-5.3-flash 921aaf3a9a docs: qualify the 256-channel figure — default policy knob, not a wire limit
channel_id is u32 on the wire (~4B ids, monotonic counter, ADR-040);
256 is the default per-connection max_channels (memory bound, 256x1MiB
reassembly buffers) and the default per-identity DoS cap (ADR-041) —
both configurable without a wire change. AGENTS.md convention 10 and
the OQ-SK-03 composed-egress note now carry the qualifier.
2026-09-13 16:54:02 +00:00
glm-5.3-flash 4730672f10 docs: OQ-SK-02 direction settled — "both" auth, split by the door
- endgame story makes both mechanisms real: consumer binds the produced
  SOCKS5 resource locally (optional front door, ssh -D shape without
  the forced bind) and points tun2proxy at it
- producer side: identity seam only (CF-005/CF-006); a password there
  is moot against the ACL system — in-band conversation runs NoAuth
- consumer front door: owns RFC 1929 where vanilla clients need it
  (tun2proxy/curl user:pass), maps accepted credentials to the channel
  identity it opens the producer with; the SOCKS password never crosses
  the channel as a SOCKS password
- replace-or-second-gate sub-question dissolves: the mechanisms occupy
  different planes (door-local creds vs channel-level identity)
- remaining for Phase 1: credential->identity mapping shape; producer-
  side local backend door surface; AuthMethod trait vs door-owned check
2026-09-13 16:15:57 +00:00
glm-5.3-flash c3ccba4d59 docs: OQ-SK-03 handle swap — the relay handle is the channel itself
- the ASSOCIATE reply's BND.ADDR/BND.PORT is a relay handle, not a
  destination (per-datagram destinations ride the datagram header);
  swapping "tell the client about a UDP port" for "tell the client
  about the UDP tunnel" preserves every RFC property: one channel per
  association, {addr, data} frames in-band, channel EOF = association
  lifetime, optional front-door binds on either side
- sentinel-address hunch superseded: no virtualized relay address is
  ever needed on the in-band path; BND.ADDR there is pure
  RFC-compatibility surface
- producer egress has two variants, both dial-callback policy (OQ-SK-01
  shape): local UdpSocket (no flow table, native-only) or composed
  per-target alktunnels udp-tunnels (lazy destination->tunnel table;
  flow table reborn as channel handles; per-target ACL for free —
  dissolves most of OQ-SK-05 for the composed path)
- no upstream ask: alktunnels' connected-udp substrate is correct as-is
  for per-target composition; an unconnected-egress resource would be
  SOCKS5 again (circular)
- POC #2 baseline settled: sketch both egress variants behind the dial
  callback, measure per-destination open cost of the composed variant
2026-09-13 16:01:32 +00:00
glm-5.3-flash cf5432209a docs: iroh-socks5 evaluated — not the base, but OQ-SK-03 prior art
- new docs/research/iroh-socks5-eval.md: full source review of
  iroh-socks5 0.5.0 (github.com/mattgeddes/iroh-socks5, MIT OR
  Apache-2.0) — quality verified, structural sibling of the alksocks
  shape, but iroh-coupled (no generic-T seam) with an RFC subset, so
  fast-socks5 stays the protocol base (POC #1/#4 conclusions stand)
- phase-0: prior-art section for iroh-socks5; OQ-SK-03 updated with its
  UDP design as the POC #2 baseline (framed {addr, data} in-band
  datagrams, RFC header codec at front doors only, no producer-side
  flow table, control-EOF association lifetime, FRAG != 0 refused)
2026-09-13 14:58:41 +00:00
glm-5.3-flash 7c6bc65618 docs: POC #1 (channels-native CONNECT) + POC #4 (fs5 wasm fork) findings
- POC #1 passed (alksocks-connect-poc, 8 tests + curl front-door
  example): BiStream-as-T genericity, register_openable_with_
  establisher fit, pump_bidi data plane, typed session refusal,
  RFC reply-code dial-refusal mapping, vanilla-client front door.
  Structural resolution: the dial belongs at the command-read
  interception point (target is unknowable at open time); the
  establisher is the session gate. OQ-SK-01/02 shapes resolved
  empirically.
- POC #4 passed (fs5-wasm-poc, kept at /workspace/alksocks-fs5-wasm-poc):
  the fork is genuinely minimal — ~120 lines of #[cfg] insertions
  gate kernel-net behind a default-on 'net' feature; the wasm-clean
  subset compiles for wasm32-unknown-unknown (--no-default-features)
  and still completes a full RFC 1928 CONNECT conversation. OQ-SK-04
  reduces to the adapter-story question.
- Corrected the run_udp_proxy_custom prior-art claim: it binds a
  kernel socket unconditionally (relay closure + reply IP only);
  the channels path drives the typestate directly. Fileable ask.
- Findings: docs/research/poc-connect-wasm-findings.md
2026-09-13 14:38:22 +00:00
glm-5.3-flash a628715106 docs: OQ-SK-04 restructured as the conditional decision tree it is
The root question is 'does wasm make sense for alksocks?', not 'how
do we get wasm': Case 1 (wasm wanted) -> fork-first, PR as courtesy,
carry regardless; Case 2 (wasm unwanted) -> plain dependency on the
router.rs native path, no fork (the alkhttp precedent, strictly
better when its premise holds). Decision inputs written: (a) is
there a planned sandboxed (wasm) consumer of the SOCKS5 service,
(b) is the fork genuinely minimal (POC #4 checks). Fork-first is a
conditional preference, not a general one — do not carry a fork for
an invariant's sake. AGENTS.md conventions 4/17 aligned.
2026-09-12 11:00:56 +00:00
glm-5.3-flash 766e489f99 docs: three-component split; fork-first (vendor-and-vet) posture; consumer-side bind
- phase-0 vision: components split — (1) producer half (expose the
  SOCKS5 service over channels), (2) consumer half (consume it,
  optionally bind it locally — the ssh -D front door + tun2proxy
  path), (3) standalone SOCKS client wrapper for quinn/noq that must
  work with any RFC 1928 server (iroh relay/peer IP-leak motivation,
  alknet ADR-090 generalized); the earlier docs conflated the
  consumer-side bind with the producer-side local backend
- principle 6: the vpn-like endgame — tunnel a produced SOCKS5
  resource to a local port, point tun2proxy (--proxy socks5://
  natively) at it; verified tun2proxy src/args.rs
- OQ-SK-04 resolved as fork-first: 'fork' = vendor-and-vet inline in
  the crate (minimal diff, feature-gate native-net), PR upstream as
  courtesy, never wait on approval; wasm-drop (alkhttp precedent) is
  the escape hatch, not the plan
- AGENTS.md conventions 4/9/17 aligned (fork-first, binds on either
  side, wasm posture)
2026-09-12 10:21:29 +00:00
glm-5.3-flash 216a5e965e docs: phase-0 — UDP phase model vs alktty-style demux; fork-vs-reimplement collapses onto OQ-SK-04
- OQ-SK-03: RFC 1928 control/data never interleave (fast-socks5
  wait_on_tcp treats post-reply control bytes as garbage), so the
  alktty 5-stream demux solves a problem SOCKS5 doesn't have; phase
  model (pass-through CONNECT, len-prefixed datagrams post-reply)
  subsumes it; the demux's real advantage is an additive in-band
  stream-type vocabulary — noted as the honest one-way-door fork
- OQ-SK-04: no structural fork needed for the channels surface
  (router.rs interception shape covers CONNECT; run_udp_proxy_custom
  + reply_success + the pure UDP codec cover ASSOCIATE); the
  fork/wrap/reimplement decision is driven entirely by the wasm
  feature-gating outcome; full fork documented as least attractive
2026-09-12 09:46:05 +00:00
glm-5.3-flash 4c641ea9c0 docs: repo init — gitignore, AGENTS.md, Phase 0 draft
- .gitignore (target/, node_modules/, .worktrees/, Cargo.lock)
- AGENTS.md: project conventions adapted from alktunnels for the
  SOCKS5 wrapper crate (no-forced-binding posture, fast-socks5
  genericity, producer/consumer vocabulary, upstream-asks rule,
  verification commands with the wasm caveat for OQ-SK-04)
- docs/research/phase-0.md: Phase 0 draft — vision, prior art
  (fast-socks5 surface, alktunnels -D conclusion, alknet ADR-090
  client, noq trait-shape divergence), open questions OQ-SK-01..07,
  POC candidates, convergence checklist
- sdd_process.md: package name fixed (alkcall -> alksocks)
2026-09-12 09:19:54 +00:00
glm-5.3-flash 169aa47790 init 2026-09-12 07:01:39 +00:00