--- status: draft last_updated: 2026-09-28 (OQ-SK2-09 recorded — the UDP door's peer-pin posture; option 2 landed in 0.1.0, option 3 deferred; OQ-SK2-06's trigger ownership checked — genuinely external; the OQ-SK ledger OQ-SK-01..09 promoted 2026-09-20; new questions continue as OQ-SK2-06..) --- # alksocks — Open Questions Centralized tracker. The Phase 0 OQ ledger (`docs/research/ phase-0.md`, OQ-SK-01..09) is promoted here with statuses current as of the Phase 1 spec; new Phase 1 questions continue the OQ-SK2 numbering (SK2 = the architecture-set ledger, distinct from the Phase 0 ledger's OQ-SK- prefix, which stays historical). Note: the SK2 numbering is not contiguous from 01 — OQ-SK2-01..05 were consumed in working drafts before the first committed set; the sequence starts at the numbers in use. Format per `docs/sdd_process.md`. ## Theme 1: Wire format and phases ### OQ-SK-01: Producer dial policy — what dials the target? - **Origin**: [phase-0.md](../research/phase-0.md) (OQ-SK-01) - **Status**: resolved — [ADR-004](decisions/004-dial-callback-shape.md) (the shape), [ADR-008](decisions/008-provider-defaults.md) (the provider set) - **Priority**: high - **Resolution**: 2026-09-20 (Phase 1). The dialer-trait-vs-callback half closed on the POC evidence (function-not-trait at three seams — DialFn/EgressFactory/BindAcceptFactory, boxed halves, ownership rides the handle). The provider-default half: the base crate ships local-socket providers (`local`) and composed providers (`composed`, the alktunnels direct op); no implicit dialer — registration always takes the callbacks explicitly. - **Cross-references**: OQ-SK-03, OQ-SK-08, ADR-004, ADR-008 ### OQ-SK-03: UDP ASSOCIATE without binding - **Origin**: [phase-0.md](../research/phase-0.md) (OQ-SK-03) - **Status**: resolved — [ADR-003](decisions/003-udp-handle-swap.md) - **Priority**: high - **Resolution**: 2026-09-20 (Phase 1; baseline settled 2026-09-13, POC #2 validated 2026-09-14). The handle swap: one channel per association; `{addr, data}` frames in-band (`[len: u16 BE]` over the RFC 1928 address encoding); association lifetime = channel lifetime; RFC codec at front doors only; sentinel BND.ADDR in-band. The datagram framing (the one-way door) is now decided with empirical ground under it (open cost measured ~0.8 ms; LRU + dedup pinned by test). - **Cross-references**: OQ-SK-01, ADR-003, ADR-008 ### OQ-SK-08: BIND — the accept-side command - **Origin**: [phase-0.md](../research/phase-0.md) (OQ-SK-08) - **Status**: resolved — [ADR-007](decisions/007-bind-in-base.md) - **Priority**: high - **Resolution**: 2026-09-20 (Phase 1; POC #5 validated 2026-09-15). BIND ships in the base crate, phase-model style; the accept variants: local listener (default, faithful), composed (alktunnels bind-first listen + forwarded op — vanilla-fidelity since the graduation), wrapper-aware (in-band default). The establishment bound covers only the open-op round trip; the accept wait lives in the teardown-governed pump phase. - **Cross-references**: OQ-SK-01, ADR-004, ADR-006, ADR-007 ## Theme 2: Crate architecture ### OQ-SK-02: Auth mapping — identity seam vs in-band SOCKS auth - **Origin**: [phase-0.md](../research/phase-0.md) (OQ-SK-02) - **Status**: resolved — [ADR-005](decisions/005-auth-split-by-door.md) - **Priority**: medium - **Resolution**: 2026-09-20 (Phase 1; the posture settled 2026-09-13). "Both," split by the door: producer = identity seam (in-band NoAuth no-op); front door = RFC 1929 + static credential→identity config mapping. The door's credential→ identity mapping shape (the Phase 0 residue): static config in v1; a pluggable lookup remains an additive extension if a deployment needs dynamic resolution. - **Cross-references**: ADR-005, ADR-006 ### OQ-SK-04: fast-socks5 wasm posture - **Origin**: [phase-0.md](../research/phase-0.md) (OQ-SK-04) - **Status**: resolved — [ADR-011](decisions/011-inline-vendor.md) (the extraction mechanics), [ADR-013](decisions/ 013-targeted-fork.md) (the ownership posture) - **Priority**: high - **Resolution**: 2026-09-20 (Phase 0's final resolution, promoted; amended 2026-09-21 by ADR-011 §Amendment; superseded as a posture 2026-09-22 by ADR-013). The extracted region is a **targeted fork**: the `T`-generic subset in-tree with zero kernel-net code (wasm-clean by construction, no `net` feature); two carried changes (BIND, `new_reply` publication); fork point = the tree as of the extraction-review commit (`5b18d4d`), module `src/rfc1928/`; differential testing against `/workspace/fast-socks5` (behavioral reference — the cheap upstream-fix path closes; a future upstream fix is a hand-port, guarded by the suite). - **Cross-references**: ADR-002, ADR-009, ADR-011, ADR-013 ### OQ-SK-07: POC register - **Origin**: [phase-0.md](../research/phase-0.md) (OQ-SK-07) - **Status**: resolved — the register is closed (process artifact, not a design question) - **Priority**: low - **Resolution**: 2026-09-14 (Phase 0). All POCs resolved: #1, #2, #4, #5 passed; #3 dropped (transferred to alknet with OQ-SK-06). Findings live in `docs/research/` (the findings files are the artifacts); numbering is historical (do not renumber). Full register: phase-0 §OQ-SK-07. - **Cross-references**: OQ-SK-06 ### OQ-SK-09: Channel capacity for proxy workloads (the 256 default) - **Origin**: [phase-0.md](../research/phase-0.md) (OQ-SK-09) - **Status**: resolved — [ADR-010](decisions/010-channel-capacity.md) - **Priority**: medium - **Resolution**: 2026-09-20 (Phase 1). No wire change (rejected permanently); assembly-layer config is the mechanism; the crate docs carry the proxy-workload recommendation with the memory arithmetic; in-channel port multiplexing rejected (the rationale + the revisit trigger recorded — the additive escape is a new multiplexed ALPN). - **Cross-references**: OQ-SK2-08, ADR-010 ## Theme 3: Policy and composition ### OQ-SK-05: Target policy and egress scoping - **Origin**: [phase-0.md](../research/phase-0.md) (OQ-SK-05) - **Status**: resolved — [ADR-006](decisions/006-access-control.md) (the gate posture), [ADR-012](decisions/012-target-policy.md) (target policy + the virtual-subnet layer) - **Priority**: high - **Resolution**: 2026-09-20 (Phase 1). No allowlist hook in v1 (the dialer-refuses shape); domain targets pass through unresolved (egress-owned resolution); the virtual-subnet translation layer is assembly-layer policy over the dial callback (no crate feature in v1; a helper may be added additively if a deployment materializes). - **Cross-references**: OQ-SK2-07, ADR-006, ADR-008, ADR-012 ### OQ-SK-06: noq client support - **Origin**: [phase-0.md](../research/phase-0.md) (OQ-SK-06) - **Status**: resolved — transferred to the alknet rewrite (the 2026-09-14 scope decision) - **Priority**: low - **Resolution**: 2026-09-14 (Phase 0). The quinn/noq `AsyncUdpSocket` client wrapper is alknet's ancestor-shaped component (ADR-090 + the quinn-proxy POC live there); it neither produces nor consumes channels. This crate's client story is the channels-native sessions (POC-validated) — complete without it. - **Cross-references**: ADR-002 (the base), phase-0 §Scope ### OQ-SK2-06: The sandboxed-wasm-consumer adapter story - **Origin**: [overview.md](overview.md) (the wasm posture's product input; phase-0 OQ-SK-04's retrospective) - **Status**: deferred(scope) - **Door type**: two-way - **Priority**: low - **Impacts**: how much wasm surface to exercise in the default crate (a product/docs input). Blocks nothing in the protocol design — the wasm-clean invariant (ADR-009) holds regardless. - **Blocked on**: a concrete sandboxed-adapter use case — a TS/Python (or other) adapter embedding the alksocks consumer session in a wasm runtime. Tracker task id: `architecture/oq-sk2-06-wasm-adapter-story` (`tasks/architecture/oq-sk2-06-wasm-adapter-story.md`). - **Trigger ownership (checked 2026-09-28)**: the trigger is genuinely external — no planned suite-internal surface (alktty, alktunnels, alkcall) needs a sandboxed alksocks consumer, and the `alknodes` assembly concept carries no named wasm-adapter plan. Nothing suite-side waits on this OQ, and this OQ waits on nothing suite-side (the adapter's substrate — the wasm-clean default crate — is complete and continuously gate-verified; a downstream glue crate can embed it today with zero further alksocks work). The Schrödinger-bind check (both sides deferring to each other forever) came up empty; the OQ stays an unowned external trigger by verified default. Re-check the ownership claim if a product surface names a sandboxed adapter — the amendment then converts this to an owned dependency. - **Resolution**: Not yet decidable. The use case isn't concrete yet — the adapter story is a product input whose shape would tell us whether the wasm consumer needs surface beyond the channels-native session (e.g. bindings ergonomics). The architecture decision (wasm-clean default, ADR-009) is already made and does not depend on this. - **Cross-references**: ADR-009, ADR-011 ### OQ-SK2-07: Virtual-subnet translation-layer helper - **Origin**: [phase-0.md](../research/phase-0.md) (OQ-SK-05's 2026-09-14 proposal; ADR-012's resolution) - **Status**: deferred(scope) - **Door type**: two-way - **Priority**: low - **Impacts**: nothing in the crate — the seams already support the translation layer (the dial callback, ADR-004/ADR-012). This tracks whether a *translation-table helper* should graduate into the crate if a deployment materializes with concrete needs. - **Blocked on**: a concrete deployment wanting identity-scoped virtual subnets (the tun2proxy virtual-network prior art to check at that point). Tracker task id: `architecture/oq-sk2-07-virtual-subnet-helper` (`tasks/architecture/oq-sk2-07-virtual-subnet-helper.md`). - **Resolution**: Not yet decidable. The use case isn't concrete — the mechanism is assembly-layer policy today (ADR-012), and a crate-level helper would need real deployment requirements to shape (subnet sizing, per-identity tables, hub exposure). - **Cross-references**: ADR-004, ADR-006, ADR-012, OQ-SK2-08 ## Theme 4: Documentation tuning ### OQ-SK2-08: The recommended proxy-workload cap figure - **Origin**: [overview.md](overview.md) §Open Questions; ADR-010's docs-level residue - **Status**: open - **Priority**: low - **Resolution**: ADR-010 pinned the posture (config, not wire; documented recommendation with memory arithmetic). The concrete recommended figure (e.g. "raise per-connection to 4096, per- identity to 1024" or similar) is a docs tuning note to pin during implementation when real workload numbers exist. - **Cross-references**: OQ-SK-09, ADR-010 ### OQ-SK2-09: The UDP door's peer-pin posture (the option-3 residual) - **Origin**: review 003 S-1 (the accepted-uncovered posture note) → the pre-publish session's escalation (2026-09-28): the residual is a real deployment concern (NAT is common), and the RFC's own drop rule was unimplemented - **Status**: partially resolved — option 2 landed in 0.1.0 (commit `31fb11c`); option 3 deferred (below) - **Door type**: two-way (additive; the current shape is RFC-faithful) - **Priority**: low (post-fix: the common cases are covered) - **The posture after option 2**: the door pins the client's source **IP** on the first parsed datagram and sends replies to the **latest-seen port** from that IP (the NAT port-rebind case keeps receiving); datagrams from other source IPs are dropped (RFC 1928's MUST, previously unimplemented — the spoof primitive shrank from any-source to same-IP off-path). The **remaining residual**: a full client IP change mid-association (a NAT *address* rebind) stops receiving replies — the RFC's expected-peer posture (the RFC pins the expected IP per association too). - **Option 3 (the complete fix, deferred)**: per-ASSOCIATE relay sockets spawned by the TCP door, with the expected peer IP derived from the TCP control connection's remote address (the RFC's "acquire from the SOCKS server" reading) — RFC-faithful end to end and kills the same-IP spoof residual too. Deferred because it restructures the doors' client-correlation story (currently the loose assembly-layer wiring seam) and needs its own ADR — not buildable speculatively without a deployment that actually spells the wildcard bind *and* suffers address-level rebinds. - **Blocked on**: a concrete wildcard-bind deployment with address-level client mobility (QUIC connection migration is the likely driver — the channels association survives transport migration while a pinned IP does not). - **Cross-references**: review 003 S-1, ADR-003 (the handle swap), ADR-014 (the doors own the accept-path defense), OQ-SK-03 ## Deferred / Blocked (index) | OQ | Status | Blocked on | Tracker task | |----|--------|------------|--------------| | OQ-SK2-06 | deferred(scope) | a concrete sandboxed-adapter use case | `architecture/oq-sk2-06-wasm-adapter-story` | | OQ-SK2-07 | deferred(scope) | a concrete virtual-subnet deployment | `architecture/oq-sk2-07-virtual-subnet-helper` | | OQ-SK2-09 | partially resolved (option 3 deferred) | a wildcard-bind deployment with address-level client mobility | — (the posture is recorded here; a tracker task spawns with the deployment driver) | ## References - Phase 0 ledger: `docs/research/phase-0.md` §Open Questions (OQ-SK-01..09 — the full reasoning trails live there) - The SDD process: `docs/sdd_process.md` (the OQ format; the deferred-OQ blocker-task half)