---
name: v0170-w1-w4-blockers
description: v0.17.0 robust-WAN-join + presence-truth milestone — W1+W4 correctness blockers LANDED; W2/W3/W5/W6 pending doyle scope
metadata: 
  node_type: memory
  type: project
  originSessionId: 8c8eef1f-6837-4fc5-a65f-0633fc292f63
---

v0.17.0 = robust WAN subnet join (ADR-0030) + presence-liveness truth (no ADR, correctness bug). doyle BUILD GO 2026-06-28; operator wants full milestone→publish (counter 36). Design LOCKED: ADR-0030 + docs/design/{robust-wan-subnet-join,subnet-presence-display}.md + V0.17.0-ROBUST-JOIN-AND-PRESENCE-JIT.md. Two parallel tracks: join cluster (W1-W3) + presence/display (W4-W5).

**LANDED (shared branch v0.16.0-update-arc, each gated locally):**
- W4 @867c7ab — REQ-PRESENCE-LIVENESS-TRUTH (impl+unit+int). registryhost self-gossip `else` split into `advertised_status()` helper: live-but-UNBOUND→warm Dormant; cold/no-session→**Suspended** (cold-but-node-up), never blanket Dormant, never self-gossiped Offline. Picker ALREADY maps Suspended→offline (data.rs `_` arm) ⇒ fix is one semantic flip, removes the dead-endpoint-shows-green-remotely bug. int lives in spt picker (load_snapshots→resource_projection→gather), NOT twohost.
- W1 @7cddaba — REQ-NET-FAMILY-GATE (doc+impl+unit). NetEndpoint::bind All-scope only: probe each family once, drop DEAD one. Probe = bounded TCP connect per-family anycast :443 on **spawn_blocking** (tokio `net` feature is OFF in spt-net — confirmed Cargo.toml) + std::net. select_families PURE (both-dead/both-healthy→Dual never-strand). SPT_DISABLE_IPV6/IPV4 force-off. Single-family bind = existing `clear_ip_transports()`+one `bind_addr` (the BindScope mechanism = the verified iroh single-family API). Loopback/Port untouched ⇒ all hermetic tests + CI dual-stack unchanged, no probe, no firewall prompt.

GATES green: spt-net 126 / spt-daemon 380 / spt 261 lib+bin, +4 new tests; clippy --workspace clean; traceable 311/311 0-findings; xtask check OK. Build OOMs if 3 crate test-bins codegen concurrently — use `$env:CARGO_BUILD_JOBS=2` + per-crate nextest.

**PENDING (doyle gates W1+W4 matrix, then scopes):**
- W2 REQ-JOIN-TWO-PHASE (impl+unit+int) — PairMeetReq/MetMember/PairCodeSubmit two-phase stream, daemon held-address state machine + 5-min timeout, ceremony-only wrong-code retry, --code one-shot preserved. brain.rs:1009 / pairhost.rs / meet.rs / cli.rs:6236.
- W3 REQ-JOIN-DIAGNOSTICS (impl+unit) — live search progress + detailed-failure-before-prompt + brain.rs:1024 terminal-event propagation (the `_=>continue` swallow) + --verbose/SPT_LOG trace.
- W5 REQ-SUBNET-DISPLAY-PARITY (impl+unit+int, DEPENDS on W4) — gossip additive Instance fields (bound/controlled+driver/harness_only), remove data.rs:293 remote-reduction, EpDisplay rework (drop UnboundControlled, Unbound→red-filled, HarnessOnly→amber-hollow, add Suspended→gray-filled). Palette = subnet-presence-display.md §B.
- W6 — int activations at fold, public docs (gh-pages networking/overview + join troubleshooting note + status-square legend), release bump-in-PR counter 36, deployah publishes.

Build rules: tag evidence same commit; commit SELECTIVELY (git add <files>, never -A — doyle shares the tree, e.g. his docs commit 1b4fced); coordinate traceable-reqs.toml (use git add -p to split per-wave hunks). CI fires on the release PR not branch push. See [[v0160-published.md]], [[release-counter-from-published]], [[agent-roles]], [[no-machinewide-killon-shared-runner]].
