Commit Graph
25 Commits
Author SHA1 Message Date
glm-5.3-flash 2ae489a205 vendor: the client session — Socks5Stream<S>::use_stream path
Extract the T-generic client session from fast-socks5 v1.0.0's
client.rs into src/vendor/client.rs (ADR-011 §Amendment extraction,
vendor.md cut table row 2): Socks5Stream<S> with use_stream (the
greeting, method-choice read, password sub-handshake, request
encoder, reply reader, socket accessors), the AsyncRead/AsyncWrite
impls, and the pruned Config (skip_auth only).

- typed MissingTargetAddr variant replaces upstream's
  anyhow::Error::msg(...).into() at client.rs:285 (the one SocksError
  addition; the client.rs:528 Other(anyhow!) site went with the cut
  Socks5Datagram)
- use_password_auth's unreachable!() is an error return (upstream's
  None-arm message; convention 2), and the sub-negotiation reply's
  version byte is now checked (was only a dropped debug!)
- write -> write_all in request_header (clippy unused_io_amount;
  byte-identical on a healthy stream)
- cut (not copied): Socks5Datagram, the Socks5Stream<TcpStream>
  convenience impl (connect*/connect_raw), Config::connect_timeout
- 14 first-party duplex tests vs raw-byte mock servers (uncorrelated
  from the vendored server typestate): both handshakes, 0xff
  refusal, version mismatch, domain/IP request forms, the full
  failure-code table, UDP-ASSOCIATE zero fallback, skip_auth,
  io-impl copy, socket accessors
- mod.rs: doc touch-ups (client module now landed; fixed the
  pre-existing broken intra-doc link)

Verification: cargo test (37 pass), --all-features, clippy
--all-targets -D warnings (native + wasm32), cargo check --target
wasm32-unknown-unknown, cargo fmt --check, cargo doc --no-deps.
2026-09-21 14:15:59 +00:00
glm-5.3-flash 9ba63fd239 vendor: the server typestate — Socks5ServerProtocol + new_reply publication
Extract the explicit typestate from fast-socks5 v1.0.0's server.rs
into src/vendor/server.rs (ADR-011 §Amendment extraction, vendor.md
cut table row 1): the states module, Socks5ServerProtocol<T, S>,
the auth machinery (AuthMethod/AuthMethodSuccessState, the
NoAuthentication/PasswordAuthentication impls, auth_method_enums! +
StandardAuthentication), negotiate_auth/read_command/reply_success/
reply_error, transfer/wait_on_tcp, try_notify!, ErrorContext<T>,
SocksServerError (landed early by the wire-vocabulary task).

- carried change #2: new_reply is pub (byte-identity tested — v4
  10-byte / v6 22-byte forms + the reply-code table)
- extraction adjustments: log calls dropped (unused bindings
  renamed), reply_error's parse().unwrap() replaced with a
  compile-time const, auth_method_enums! de-exported to
  pub(crate) use, no anyhow/async-trait
- cut (not copied): the legacy Socks5Server/Incoming/Socks5Socket,
  Config<A>/Authentication layer, DnsResolveHelper, the run_* +
  udp kernel-net handlers, the net-only test module
- 12 first-party duplex tests: full no-auth round-trip, version
  mismatch, 0xff method refusal, 0x07 unknown-command reply, both
  reply forms byte-exact, password accept/reject

Verification: cargo test (25 pass), --all-features, clippy
--all-targets -D warnings (native + wasm32), cargo check --target
wasm32-unknown-unknown, cargo fmt --check, cargo doc.
2026-09-21 14:01:06 +00:00
glm-5.3-flash 7497b79c05 vendor: the wire vocabulary — consts, commands, codecs, errors, macros
Extract fast-socks5 v1.0.0's non-net lib.rs region into
src/vendor/mod.rs (scaffolding-pinned root; the task's lib.rs target
name corrected — a second root file would conflict, see task Notes):
consts, Socks5Command (as_u8/from_u8 made pub), AuthenticationMethod,
SocksError pruned to the extracted region's consumers (no anyhow/
Redaction/InvalidHeader/ReplySocks4Error/ArgumentInputError), the
Result alias, ReplyError codec, UdpHeaderError + new_udp_header/
parse_udp_request. util/target_addr.rs gains TargetAddr/AddrError
(minus resolve_dns + its two variants)/ToTargetAddr/Addr/read_address;
util/stream.rs gains the read_exact!/ready! macros (de-exported to
pub(crate) use) + ConnectError + to_reply_error. SocksServerError
lands verbatim in server.rs early — SocksError's #[from] needs it
before the typestate task. 16 first-party codec tests (round-trips,
mapping tables, garbage-RSV/unknown-ATYP); no sockets, no env_logger.
Newer-clippy style lints allowed at module level in vendored files
(verbatim diff posture, rationale recorded).

Verification: cargo test (16 pass) + --all-features; clippy
--all-targets -D warnings (native + wasm32); cargo check
--target wasm32-unknown-unknown; cargo fmt --check; cargo doc.
Negative sweeps: no anyhow/log/tokio::net/socket2/tokio-stream/
async-trait under src/vendor/; no #[macro_export]; resolve_dns and
the pruned error variants absent.
2026-09-21 13:13:56 +00:00
glm-5.3-flash 57b107bdf0 vendor: crate scaffolding — Cargo.toml, lib.rs, vendor skeleton, license notice
- Cargo.toml: alksocks 0.1.0 in the sibling posture (alktunnels-style
  exclude/keywords/description); empty `local` + `composed` features
  declared (ADR-009 §Amendment — populated by their modules' tasks);
  deps = tokio wasm-clean subset (rt/sync/io-util/macros/time),
  tracing, thiserror; full tokio dev-deps. No alkcall, no net-shaped
  deps (the producer/consumer tasks pin alkcall 0.8.0).
- src/lib.rs: forbid(unsafe_code), crate docs (never-binds posture,
  vendor provenance, architecture pointer), `pub mod vendor;`.
- src/vendor/: skeleton preserving upstream fast-socks5 v1.0.0 file
  names for mechanical per-file diffs — mod.rs (provenance doc +
  server/client/util declarations), five stubs for the extraction
  tasks; socks4/ cut per ADR-011 §Amendment.
- src/vendor/LICENSE: upstream MIT text + v1.0.0 attribution header,
  referenced from the vendor module doc (ADR-011's license
  obligation; upstream has no per-file headers).
- tasks/implementation/vendor-crate-scaffolding.md: completed
  (checkboxes, notes, summary).

Verification: cargo test; clippy --all-targets -- -D warnings;
fmt --check; cargo check + clippy --target wasm32-unknown-unknown
with -D warnings — all clean; wasm gate green from birth.
2026-09-21 11:46:21 +00:00
glm-5.3-flash 2cc010cf2b tasks: decompose the vendor group — six dependency-ordered tasks
The inline vendor (vendor.md, ADR-011 §Amendment) is the root of the
crate's dependency graph; this decomposes it before any downstream
group (params/wire/producer/consumer/doors).

- vendor-crate-scaffolding: Cargo.toml (wasm-clean tokio subset, no
  alkcall yet), lib.rs, vendor/ skeleton, bundled MIT notice
- vendor-wire-vocabulary: consts, codecs, errors, macros — with the
  extraction-boundary pins (error-variant pruning, pub command
  codecs, macro de-exporting)
- vendor-server-typestate: Socks5ServerProtocol + the new_reply
  publication (carried change #2); BIND's driving is producer-group
  work, the vendor carries only the surface
- vendor-client-session: Socks5Stream::use_stream path + the
  AsyncRead/AsyncWrite impls; Config pruned (connect_timeout cut);
  tests against a raw-byte mock server so it runs parallel with the
  typestate task
- vendor-differential-tests: RFC edge-case suite over duplex streams,
  pinning upstream behavior per vendor.md's differential posture
- review-vendor-extraction: the gate before downstream groups —
  file-by-file diff vs /workspace/fast-socks5 must contain only
  cut/carried-change/adjustment hunks

Graph validated: all dependency ids resolve, no cycles; topological
order scaffolding → wire → (typestate ∥ client) → tests → review.
2026-09-21 11:39:12 +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