The TCP BIND dispatch arm replaces its refusal with the full phase
model (POC #5-validated scope), plus the command gate at dispatch:
- The command gate: TCP BIND requires socks5:bind from the per-call
opener identity (CF-005/CF-006) — the pump handler resolves it
from the open-op AuthContext; serve_socks5_over<T> takes the
resolved can_bind boolean explicitly. A scope-less identity gets
the RFC-faithful ConnectionNotAllowed (0x02) with no factory call
(the gate precedes the seam) while CONNECT still serves it.
- The phase model (wire.md §BIND): the BindAcceptFactory at the
command-read interception point → reply#1 carrying BND.ADDR (the
factory's bind_addr) → the quiet wait (single-shot select!, exactly
two exits: the one accept, or the control stream's EOF/garbage/
error; any byte = protocol garbage → session ends, no data plane;
the accept future's drop IS the client-gone teardown) → reply#2
carrying the peer address (via the fork's published new_reply) →
pump_bidi inline (the CONNECT shape, R-02).
- Two-stage RFC-faithful failure mapping: factory failure → reply#1's
mapped code; accept-stage failure → reply#2's mapped code, no data
plane. No phantom listeners, no phantom data planes.
- The no-factory default is the wrapper-aware in-band variant
(ADR-007 variant 3, documented): sentinel reply#1 + sentinel reply#2
(0.0.0.0:0), the full phase model preserved — the channel is the
connection.
- The accept wait lives in the teardown-governed pump phase, never
under the establishment bound (ADR-007).
Tests: 16 unit tests (raw RFC client over duplex) + 7 harness
integration tests over channels — happy path, the gate (0x02 while
CONNECT serves, both scopes), quiet-wait garbage, client-gone
teardown (owner-flag witness), both failure stages over channels,
no-factory variant 3, and the three-command regression guard (CONNECT
serves, BIND serves under its gate, ASSOCIATE still refuses).
Verification: cargo test green (96 lib + 26 harness + 37
differential); clippy -D warnings clean (all targets, native +
wasm32-unknown-unknown); cargo fmt clean; wasm check clean.
Task: tasks/implementation/core-producer-bind.md (status → completed)