---
name: v0140-w6-int-structure
description: "v0.14.0 W6 int — mirror perri's multi-subnet regression structure (doyle guidance 2026-06-22)"
metadata: 
  node_type: memory
  type: project
  originSessionId: eca35c75-a881-4fbb-b4b8-da118254038c
---

W6 spt-core dummy-harness int (REQ-RUN-MULTISUBNET-HOME + REQ-ENDPOINT-UNBOUND-ATTACH) must MIRROR perri's real-harness acceptance script. doyle relayed the structure (2026-06-22):

- **Gate on >=2 subnets** — single-subnet auto-homes and HIDES the gap (binding constraint; the test is a no-op / false-green on a single-subnet node).
- **First subnet = the control home.**
- **Case 1** = endpoint-run E2E (spawns real harness + Psyche — reuse the v0.12.1 dummy-harness fixture, NO mocks), behind an acceptance env gate (perri's = `SPTC_ACCEPTANCE=1`).
- **Cases 2/3** = fast always-run probes on a multi-subnet node: bind `HOME_REFUSED` (multi + no --subnet) / `--subnet` BOUND (homes to the pick).
- Plus a **single-subnet control** proving auto-home still works.

perri's real-harness analog (the adapter side, her gating): spt-claude-code main @62cfbe3, `ci/subnet/multi-subnet-bringup-int.sh`. She validates on real claude-spt at v0.14.0 publish. See [[v0140-endpoint-creation-flow]].

**doyle W6 binding assertions (flagged at W2 gate):** W2's load-bearing premise "bind inherits home via establish_perch's prior-branch" is NOT proven by the W2 unit (that proves the decider + that the skeleton CARRIES home). live_adapt_* only exercises skeleton→bind in the SOLE-subnet case. W6 MUST assert explicitly:
1. **Multi-subnet home-inherit:** skeleton home=S → harness bind → perch STAYS home=S (NOT re-resolved), UNBOUND→ONLINE.
2. **No double-seed:** the skeleton's seeded sync scope is NOT re-seeded by bind's prior-branch (prior-branch skips seeding when home_subnet.is_some() — assert sync_subnets stays [S], single entry).
3. **REAL picker render of a live UNBOUND perch (doyle, W5-fix):** assert the disk→data.rs→model.rs seam end-to-end via a live bringup — a real UNBOUND perch renders as hollow `EpDisplay::Unbound`, NOT gray Offline. This seam (roster alive=false bound-gated → data.rs row_status must read Online → display_status Unbound) is exactly what NO unit reached and what let the W5 picker bug through CI-green (display unit hand-set EpStatus::Online = false premise). The data.rs `row_status_drives_unbound_display` unit now covers the rule; W6 must cover the REAL on-disk→render path.
