#315 — read-only RCA, hertz, 2026-09-16 CONCLUSION [INFERENCE, strongly supported by source + receiver send history] The changed gate INPUT was InboundClass, not a subnet mode: ball-b's successful outbound to lia on node14efb80c at02:24:45Z opened a15-minute (receiver endpoint, remote NODE) reply window. doyle's02:29:02Z inbound arrived4m17s later. ReplyExemption returns before AccessStore/NodeMode, so doyle did not 'pass the NodeMode step'; that step was not consulted. No v0.70.0 admission regression is established. Pending knock is not a deny fence in this contract. Historical allow reason is not directly recoverable: no allow audit line exists, and the recent-outbound row overwrites history. Do not turn this explanation into a claim that the exact02:29 persisted row was inspected. RECEIVER EVIDENCE (ball-b SM6W75NU, ENLYZEAM; narrowly scoped fields/history, no file transfer) -01:50:33Z: ACCESS_REFUSED MSG to ball-b from14efb80c (tier NodeMode), on0.69.0. -At that denial, latest outbound from ball-b to ANY endpoint on14efb80c was2026-09-11; no live15-minute window. First send into that node this session was01:54:45Z, after the refusal. -02:24:45Z: ball-b -> lia, confirmed SENT. lia is on14efb80c. Exactly one send in the requested02:14:02–02:29:02Z interval; none to hertz/other HFENDULEAM endpoints. -02:29:02Z: doyle -> ball-b admitted on0.70.0; no access allow line. Difference257000ms <900000ms. -02:54:00Z selected-row snapshot: endpoint=ball-b, node=14efb80c..., ts_ms=1789527188433 (02:53:08Z retry). CURRENT/SUPERSEDING ONLY, not historical admission evidence. Replying to this RCA itself refreshed the row again. -Knock k-c858cf002b44 remained pending, never approved. No quiet-window/new-send experiment requested: contacting the investigator on that node changes the very input under investigation. SOURCE CHAIN AND KEY 1. WAN receive calls classify_inbound(target, handshake-proven origin_node, now), then access_check_with_sender: crates/spt-daemon/src/wan.rs:1143–1172. This is the remote path. admit_local_delivery is the locally authored path, not the remote receipt seam (spt-store/src/gate.rs:561–616). 2. classify_inbound loads recent outbound and correlates at spt-store/src/gate.rs:368–378. Canonical path is /identity/trust/recent-outbound.json (spt-store/src/perch.rs:410–417), not directly /trust. 3. REPLY_WINDOW_MS=15*60*1000 (access.rs:2316–2318). Correlation compares ONLY endpoint + node + timestamp (access.rs:2397–2404). It contains no remote sender endpoint or knock id. record refreshes the single pair's timestamp and prunes old rows (:2370–2394); no historical ledger survives there. 4. Gate checks engine-room protection first, then Reply returns Allow(ReplyExemption) BEFORE loading ACL (gate.rs:264–283). The ordinary chain and all explicit rules/modes are below that branch. This is existing stateful-firewall semantics, not a grant inherited from lia. 5. Successful outbound WAN custody + proven sender invokes note_outbound(sender, proven_node, now) (wan.rs:373–395). The write is best-effort; source plus SENT history therefore supports the historical explanation but cannot substitute for a missing historic row/audit line. 6. If unsolicited, tier1–3 endpoint rules and tier4–5 node rules precede modes (access.rs:1744–1778). EndpointMode tier6 then NodeMode tier7 return immediately (:1817–1831). CapturedSubnetMode is tier8 (:1833–1853); any applicable captured CLOSED wins across the set. ImplicitOpen is only tier9 (:1855–1867). An added unmoded BIGNET membership CANNOT override a governing closed NodeMode. Even without node mode, adding an unmoded subnet cannot erase another matching captured closed mode. RESTART / #304 / EPOCH_FAST_FORWARD origin_subnets() is a fresh PER-CHECK load of RosterStore+SubnetStore (gate.rs:163–180), not a cached daemon-start calculation. It selects locally known subnet names for which roster.is_member(origin_node) is true. roster.rs:185–186 requires a row and no tombstone. A restart/exchange can change durable membership inputs, but cannot change the precedence above. heal_self_lease (spt-daemon/src/seedproofx.rs:1064–1077) fast-forwards this node's lease counter past the roster ceiling; it does not set node/captured modes and does not inject an open access result. User supplied gate.rs and notif MSG caller unchanged across v0.69.0..v0.70.0. Release diff inspection independently found no access.rs, roster.rs, subnet.rs, seedproofx.rs or pairhost.rs changes. wan.rs changes are request_presence attribution only; the send-contact and receive admission functions did not change. registry.rs changes instrument SQLite endpoint-registry waits, not the membership RosterStore used by origin_subnets; registryhost delta is a fixture premise. Startup/broker diff has no origin_subnets/captured-subnet/AccessStore/membership derivation change. Thus no #304 remote-friction change to this derivation was located. Evidence: release changed-file output artifact://859; full WAN/registry delta artifact://862; startup/broker delta artifact://864. WHY LIA AND DOYLE BOTH REACH WHILE KNOCK STAYS PENDING Lia's explicit endpoint rule independently permits an otherwise-unsolicited lia message. Doyle needs no lia-rule inheritance: once ball-b has spoken to any endpoint on their shared remote NODE, the same-node-of-origin reply window admits doyle before rules. During that window lia may ALSO use ReplyExemption; absence of allow logging prevents attributing her particular message to the explicit rule. Pending knock state is not an input to this gate, so neither admission consumes/approves the pending request. If endpoint-specific consent was intended, the node-wide reply-window key is a policy/design mismatch requiring a separate ruling, not evidence of a0.70.0 regression. Do not silently narrow existing reply semantics as an 'audit fix'. ONE-LINE ALLOW AUDIT REMEDY SHAPE (NO IMPLEMENTATION) ACCESS_ADMITTED wall_ms=