- Rewrote em dash prose across the whole tree outside docs/reviews/ (the historical reviews stay verbatim, matching the alktunnels and alktty precedent): src doc comments and inline comments (587), docs/architecture (319), docs/research + sdd_process (484), tests (361), tasks (899), fuzz (28), README/CHANGELOG/Cargo.toml (77), AGENTS.md (85), and the .opencode/agents prompts (109) - Fenced content follows the precedent: comments, ASCII-diagram label separators, and template placeholders rewritten; wire data, JSON/BAST documents, byte diagrams, and transcripts survive verbatim; assert, expect, panic, error-display, and format message literals rewritten as prose; no code, fixture, or test data change - src/rfc1928/LICENSE: the two dashes in alksocks' own provenance header rewritten; the MIT legal text untouched - AGENTS.md adds Project Convention 18: no em dashes in prose; varied restructure, no spaced-hyphen substitutes, fenced prose rule, en dash numeric ranges exempt, docs/reviews/ exempt from the greps - tasks/*.md frontmatter: the name values rewritten by the sweep are now quoted (a raw colon inside an unquoted YAML scalar parsed as null); taskgraph validate reports 37 tasks, no issues Verification: cargo test; cargo clippy --all-targets -D warnings; cargo fmt --check; cargo doc --no-deps; fuzz corpus replay (cargo test --manifest-path fuzz/shared/Cargo.toml); wasm check and clippy for wasm32-unknown-unknown with -D warnings; em dash grep over the repo returns matches only in docs/reviews/ and the bast.md BAST JSON data fence
281 lines
13 KiB
Markdown
281 lines
13 KiB
Markdown
---
|
|
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, so 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 | none (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) |