feat: the local bind-first halves (shape 3 substrate half, ADR-008 §1)
- `bind_tcp_first` + `TcpListenerHalves::accept_pair`: the real-socket
BindFn source (port 0 resolved via local_addr — the `bound` reply
field's data) and the per-accept (peer, halves) pair (the peer rides
accept()'s return — the forwarded op's `peer` carrier)
- unix bind-first parity shipped (OQ-TN-14): `bind_unix` +
`UnixListenerHalves` (local_addr / queue-feeding accept_loop /
bind-first accept_pair; an unnamed peer fails loud — the forwarded
`peer` param requires an address) + `bind_unix_first`
- assembly conveniences: `local_bind_first()` (tcp/unix dispatch; udp
fails loud — no accept on a UDP socket, the shape is not defined
there, never a fake listener) + `local_bindfirst_accept_loop()`
(downcasts the opaque listener; a foreign type fails loud)
- direct-op DialFn reuse verified + pinned: `local_dial` shared
unchanged (the UDP framed wrap composes inside the closure);
`direct_udp_through_local_dial_round_trips_framed` drives a REAL
udp echo through the direct op's establisher path
- tests/local_bindfirst.rs: tcp e2e over real sockets (bound fidelity
— the test dials the reported address; two clients → two forwarded
channels pumping independently, real distinct peers), unix parity
(real path in `bound`, named-peer client via socket2, real peer path
on the forwarded open), udp refusal, downcast-miss probe
- accept-first shapes (accept_loop + AcceptQueue) untouched
Verified: cargo test (default) + --all-features green (45 lib; 151
integration), clippy -D warnings clean (native all-features + wasm32),
fmt clean, wasm32 check passes (default crate stays wasm-clean),
cargo doc clean (no new warnings).
Tasks: tunnels/local-bind-halves (status completed; Notes + Summary
filled). CHANGELOG: Unreleased → Added.