From 8af23eeee009be864b10535c56d3e1ec7eafd55c Mon Sep 17 00:00:00 2001 From: "glm-5.3-flash" Date: Mon, 28 Sep 2026 09:17:04 +0000 Subject: [PATCH] docs: OQ-SK2-09 (the UDP door's peer-pin posture) + OQ-SK2-06's trigger-ownership check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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. --- CHANGELOG.md | 16 +++-- docs/architecture/open-questions.md | 62 +++++++++++++++++-- docs/architecture/overview.md | 18 ++++-- .../oq-sk2-06-wasm-adapter-story.md | 6 ++ 4 files changed, 85 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64fb2b6..a5d8140 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,12 +65,16 @@ providers). constructor twins — the cred-bearing front door's re-origination). - **The `local` feature (ADR-008/009)** — the socket-backed seam providers (`tcp_dial` / `udp_egress` / `bind_accept` — the explicit - bind decisions), plus both doors: the consumer-side front doors - (`FrontDoor` — the NoAuth raw pipe + the RFC 1929 cred-bearing - door with the credential→identity mapping, ADR-005; - `UdpFrontDoor` — one association per bound relay socket, the RFC - codec at the door boundary only) and the producer-side listener - (`ProducerDoor` — vanilla clients dial it, each accepted + bind decisions, resolving via the non-blocking + `tokio::net::lookup_host` resolver), plus both doors: the + consumer-side front doors (`FrontDoor` — the NoAuth raw pipe + the + RFC 1929 cred-bearing door with the credential→identity mapping, + ADR-005; `UdpFrontDoor` — one association per bound relay socket, + the RFC codec at the door boundary only, the peer-pin posture: the + client's source IP pins on the first parsed datagram, replies + follow the latest-seen port from that IP, foreign-IP datagrams are + dropped per RFC 1928's MUST — OQ-SK2-09) and the producer-side + listener (`ProducerDoor` — vanilla clients dial it, each accepted connection is served via `serve_socks5_over`; the ADR-014 idle-first-byte window + max-sessions cap knobs). - **The `composed` feature (ADR-008/009)** — the alktunnels 0.2.0 diff --git a/docs/architecture/open-questions.md b/docs/architecture/open-questions.md index 1e9bad7..1686285 100644 --- a/docs/architecture/open-questions.md +++ b/docs/architecture/open-questions.md @@ -1,8 +1,10 @@ --- status: draft -last_updated: 2026-09-22 (OQ-SK-04's resolution updated to the -targeted-fork posture — ADR-013; the OQ-SK ledger OQ-SK-01..09 -promoted 2026-09-20; new questions continue as OQ-SK2-06..) +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 @@ -165,10 +167,24 @@ sequence starts at the numbers in use. Format per - **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 - adapter embedding the consumer session). Tracker task id: +- **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 @@ -214,12 +230,48 @@ sequence starts at the numbers in use. Format per 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 diff --git a/docs/architecture/overview.md b/docs/architecture/overview.md index edc44d0..5a72032 100644 --- a/docs/architecture/overview.md +++ b/docs/architecture/overview.md @@ -1,10 +1,11 @@ --- status: draft -last_updated: 2026-09-24 (ADR-014 indexed — the idle-timeout posture; -the targeted fork — ADR-013, the module is `src/rfc1928/`; the vendor -extraction amendment — no `net` feature — 2026-09-21; Phase 1 initial -draft 2026-09-20 — the OQ-SK ledger promoted into ADRs 001-012 and -open-questions.md) +last_updated: 2026-09-28 (OQ-SK2-09 indexed — the UDP door's peer-pin +posture; OQ-SK2-06's trigger ownership checked; ADR-014 indexed — +the idle-timeout posture; the targeted fork — ADR-013, the module is +`src/rfc1928/`; the vendor extraction amendment — no `net` feature — +2026-09-21; Phase 1 initial draft 2026-09-20 — the OQ-SK ledger +promoted into ADRs 001-012 and open-questions.md) --- # alksocks — Overview @@ -225,9 +226,14 @@ Open questions are tracked in [open-questions.md](open-questions.md). Key questions affecting this document: - **OQ-SK2-06**: sandboxed-wasm-consumer adapter story (deferred(scope) - — a product input, nothing waits on it) + — a product input, nothing waits on it; the trigger is external by + verified default) - **OQ-SK2-08**: recommended proxy-workload cap figure (open — a docs tuning note; ADR-010 pins the posture) +- **OQ-SK2-09**: the UDP door's peer-pin posture (option 2 — the + same-IP lock + reply-port refresh — landed in 0.1.0; option 3, the + control-conn-derived expected peer, deferred on a concrete + wildcard-bind deployment) ## References diff --git a/tasks/architecture/oq-sk2-06-wasm-adapter-story.md b/tasks/architecture/oq-sk2-06-wasm-adapter-story.md index d2309e5..44ee494 100644 --- a/tasks/architecture/oq-sk2-06-wasm-adapter-story.md +++ b/tasks/architecture/oq-sk2-06-wasm-adapter-story.md @@ -21,6 +21,12 @@ deferred-oq]` per `docs/sdd_process.md` §Deferred OQs. exists — a TS/Python (or other) adapter embedding the alksocks consumer session in a wasm runtime. +**Trigger ownership (checked 2026-09-28)**: external by verified +default — no planned suite-internal surface names a sandboxed +alksocks consumer (see the OQ's "Trigger ownership" bullet for the +check). If a product surface later names one, convert this tracker +to an owned dependency in the same round. + ## Work When the condition arrives: