Commit Graph
13 Commits
Author SHA1 Message Date
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