---
name: m4-resume-state
description: spt-core M4 (spt-net) state — D2 pairing nearly done; D2-wire + D2f shipped CI-green 2026-06-03; next = D2g elevation-gated show-totp.
metadata: 
  node_type: memory
  type: project
  originSessionId: 336986a0-eb60-4ba0-9db8-8722184623fc
---

M4 (`spt-net` P2P transport) in progress on `dev-freeform`. M0–M3 complete. D0+D1 done (iroh =0.98.2 pinned, identity-bound endpoint == node pubkey, RelayPolicy, mDNS; spt-net = workspace's FIRST async crate, tokio).

**D2 pairing — done + CI-green (2026-06-03):**
- D2a–e crypto: TOTP seed, SPAKE2 + transcript binding (#12 REQ-HAZARD-PAIR-TRANSCRIPT-BIND), seed epoch+rotation (#10), subnet-global rate-limit (#11), TrustStore TOFU (REQ-PAIR-2). All in `crates/spt-net/src/net/pairing/`.
- **D2-wire** (`08c6c9b`): ceremony driver `pairing::wire` over `SPT_PAIR_ALPN`. 6-frame/3-RTT; responder `Announce{epoch}` prepended because `Initiator::start` bakes the responder-authoritative seed-epoch into msg_a and the joiner lacks it (the resolved Q2). Pubkeys from iroh-auth `conn.remote_id()`, never frame-claimed. Centralized rate-slot release (every admitted-but-failed ceremony charges backoff). REQ-PAIR-1 `[impl,unit]`.
- **D2f** (`452358d`): `pairing::rendezvous` pure `H(name‖TOTP-step)` token (TOTP-step = clock window, NOT seed epoch); seed transfer on join (`F7 Seed` → `SubnetStore::add_joined`, joiner becomes full member/seed-holder, idempotent re-pair); create-new-names-up-front. REQ-PAIR-4/5 `[impl,unit]`. int (relay rendezvous routing + two-host) deferred to D9; loopback dial-by-addr only (Q1).

**NEXT = D2g** (plan `M4-D2g-PLAN.md`, committed `72570d5`): elevation-gated `spt pair show-totp [--subnet|--create-new]`, LOCAL-only (no daemon needed). Real OS gate — Linux `libc::geteuid()==0`, Windows `windows`-crate TokenElevation, fail-safe to authenticator-app fallback; put `elevation.rs` in the `spt` binary (cli.rs has clap `Cmd` enum, no `pair` subcmd yet). REQ-PAIR-3 (code fetch from SubnetStore) + REQ-PAIR-6 (gate). **todlando agent available for admin-enabled testing on this machine.** After D2g, D2 COMPLETE → D3 subnet registry (REQ-INST-7,9..13 + #8 epoch-lease).

iroh API churns — grep the registry source `~/.cargo/registry/src/*/iroh-0.98.2/src/` rather than guess. CI gotcha: a new push CANCELS the prior in-flight run — watch latest sha only. See [[ci-traceability-gate]], [[windows-uac-binary-name-740]], [[cross-machine-test-rig]].
