#302 / LMT7OBIT — read-only source RCA, hertz, 2026-09-16 CONCLUSION [INFERENCE] The strongest newly located candidate is per-subnet rendezvous endpoint lifecycle work monopolizing the shared two-worker NetHost runtime: synchronous Windows interface enumeration/gateway lookup and/or monitor callback deregistration in iroh dependencies. This fits rotation alignment and active_dial_tasks=0, but no worker stack or duration measurement identifies the actual blocking primitive. Source does NOT support blaming the already-offloaded family TCP probe, and supplies no deterministic 5–10-second blocker. 1. EXACT PATH, ORDER, BOUNDS NetHost::start creates worker_threads(2) at crates/spt-daemon/src/nethost.rs:1286–1290. It binds the main endpoint there (:1291–1303), launches meet rotation on runtime.handle() (:1372–1378), and runs the 25ms canary there (:1388–1395). Meet rotation is independently scheduled on TOTP PERIOD_SECS=30 (crates/spt-net/src/net/pairing/totp.rs:38), NOT on the registry pump's coincidentally equal 30s cadence. pairhost.rs:188–206 loads attached subnet names and spawns one listener task per subnet; :242–248 sleeps to the next TOTP boundary, aborts previous-window tasks, and preserves one-window overlap. Three attached subnets mean three newly constructed endpoints per window, with two windows logically overlapping. Abort does not synchronously join retired actors. Each task calls bind_rendezvous (crates/spt-net/src/net/pairing/meet.rs:125–141), which derives a SHA-256 identity and directly awaits NetEndpoint::bind_scoped. There is no bounded_block_on bridge or outer bind timeout in this path. endpoint.rs:245–253 performs TcpStream::connect_timeout INSIDE spawn_blocking; :183 sets1500ms per family. :272 joins v4/v6 probes concurrently. Production All scope repeats this for each bind; explicit force-off overrides skip probes, relay-disabled also skips. The spawn_blocking wait has no separate queue/whole-operation deadline, but awaiting it yields the worker. NET_FAMILY_GATE is emitted AFTER family choice (:347–358), not before the probe. Between that line and PAIR_MEET_UP: configure IP transports, relay and discovery; builder.bind().await (:360–421); bind_rendezvous returns; pairhost.rs:218–222 emits UP. Existing background actors can run AFTER UP. 2. ACTUAL SYNCHRONOUS DEPENDENCY BOUNDARIES Release Cargo.lock was read from tag v0.70.0 and pins iroh0.98.2, netwatch0.16.0, netdev0.42.0, portmapper0.16.0, and swarm-discovery git89a2200d54a4e3cab2f46cc75ebff49a1fb07614. This avoids accusing the unpatched registry swarm copy. Let R=C:/Users/decid/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f and G=C:/Users/decid/.cargo/git/checkouts/swarm-discovery-dcbf738e81529f91/89a2200. - R/iroh-0.98.2/src/socket.rs:866 creates portmapper; :906–912 binds transports; :997–1004 initializes QUIC/netmon; :1069–1080 spawns the socket actor. - R/netwatch-0.16.0/src/interfaces.rs:251–287, especially256: async State::new calls synchronous netdev interface enumeration before awaiting route lookup. R/netdev-0.42.0/src/os/windows/interface.rs:90–128 calls GetAdaptersAddresses(AF_UNSPEC), up to four calls for buffer growth, NO elapsed deadline/offload. IPv4-only QUIC binding does not narrow this AF_UNSPEC call. - R/portmapper-0.16.0/src/lib.rs:632–639 and733–760 perform synchronous ip_and_gateway BEFORE spawning protocol futures; :772–794 calls HomeRouter::new. R/netwatch-0.16.0/src/interfaces.rs:444–473 reaches the same synchronous interface enumeration. This actor work need not finish at the PAIR_MEET_UP instant. Protocol500ms/1s waits do NOT bound earlier gateway enumeration. Participation depends on runtime portmapper configuration; production All scope does not disable it as Loopback does. - R/netwatch-0.16.0/src/netmon/windows.rs:72–94 drops callback registrations synchronously. :127–143 and169–181 call CancelMibChangeNotify2 directly, without offload/timeout. Endpoint retirement can therefore run an OS callback-quiescence wait on its owning runtime. API's documented deadlock conditions are NOT evidence they occurred here; callbacks in this implementation use try_send. - UDP socket/options/bind and multicast initialization are also synchronous (netwatch src/udp.rs:724–761; G/src/socket.rs:94–161,228–265). iroh src/address_lookup/mdns.rs:506–517 selects IpClass::Auto independently of the QUIC bind-family gate. - mDNS captures Handle::current (iroh src/address_lookup/mdns.rs:280–298), and endpoint/netmon/portmapper actors spawn on the calling runtime. Moving a later DialPlan future does not relocate already spawned actors. Iroh Runtime is a task tracker/cancellation wrapper, not a dedicated thread pool (iroh src/runtime.rs:23–32,79–96). Negative evidence: WMI route lookup is already spawn_blocking (netwatch src/interfaces/windows.rs:29–46). Ordinary netwatch UDP destruction is spawn_blocking (src/udp.rs:862–873). Patched swarm DropGuard aborts rather than joining (G/src/lib.rs:494–497), and its old dead-updater retry loop is fixed. Long ASYNC waits alone cannot explain a stopped independent canary. No required shared application mutex between meet and rc was located. The demonstrated shared resource is the executor; both workers blocked, or a proven dependency preventing the other from progressing, can delay canary and established-stream servicing. Possible OS-global contention remains unmeasured. Secondary source hazard, not the leading 30s explanation: pairhost now_secs reads ceremony NTP synchronously. ntp.rs:139–167 holds OFFSET mutex while refreshing; :263–266 resolves DNS synchronously, :285–315 iterates addresses with1500ms socket timeouts. DNS/whole refresh lacks a total bound. However TTL is15minutes (:53), not every30s unless clock-step/forced invalidation intervenes. Do not present it as the observed rotation blocker without evidence. 3. HISTORICAL IPv6 / #30 / #174 DISTINCTIONS Named memory C:/Users/decid/.claude/projects/C--Users-decid-Documents-projects-spt-core/memory/broken-ipv6-poisons-iroh-discovery.md:12–18 measured dns.iroh.link TCP443 AAAA failure, A success, and immediate join recovery after adapter-wide IPv6 disable. It did NOT measure worker starvation. ADR0030:29 gates endpoint bind families; :41 deferred periodic reevaluation. v0.17.0 shipped the gate. The historical adapter-wide intervention is broader than IPv4-only QUIC binds; independent discovery/mDNS/enumeration paths remain distinct. #30 reports batches of long-lived all-peer dial failure, not a located blocking primitive: https://github.com/BigscreenVR/spt-bs-releases/issues/30#issuecomment-5125674180 . #174's strongest evidence is HFENDULEAM NIC-bounce wedge, brain restart ineffective, whole-daemon SAME-BINARY restart effective: https://github.com/BigscreenVR/spt-bs-releases/issues/174#issuecomment-5227486794 . Later correction says ENLYZEAM recovered on its same pre-flap binder without a local profile-change event: https://github.com/BigscreenVR/spt-bs-releases/issues/174#issuecomment-5320033507 . Neither establishes today's periodic canary mechanism. FALSIFIER / W2c SHAPE Capture both spt-broker-net worker stacks DURING a stale-canary interval, joined to monotonic begin/end stamps around interface enumeration, portmapper gateway lookup, callback cancellation, endpoint bind/retirement and NTP refresh. If these finish outside the peak or the workers are freely servicing unrelated work, this specific synchronous-lifecycle candidate is falsified. A pending async probe/QUIC timeout alone is not confirmation. Preserve the original canary and simultaneous real rc ACK/echo while doing any controlled experiment; no resident experiment was performed here. Seam B as written in .spt/preserved/302/REMEDY-DESIGN.md:10 quarantines outgoing dial/connect/prove, then hands successful connections to serving before register_conn. That does NOT cover meet endpoint bind/background actors/destruction. If stacks confirm this candidate, remedy the proven blocking OS boundary off-runtime with bounded admission, or isolate the COMPLETE pre-trust meet endpoint lifecycle on a bounded separate executor (creation, descendant actors and retirement), keeping main serving/canary unchanged. Merely moving a wrapper future or increasing workers is not isolation. Test unchanged three-subnet rotation and remote+local rc; global resource contention can defeat executor-only isolation. Do NOT select 'cache/offload family probe' as the fix: it is already offloaded and precedes NET_FAMILY_GATE. Caching might reduce redundant probes but is not evidence-backed relief of the observed post-UP worker stall. No product edits, build, test, process attach, remote configuration change, or lifecycle action in this RCA. Evidence is source plus the authorized180-sample ENLYZEAM series and ball-b's correlation; root remains a candidate pending the worker-stack/duration discriminator.