Network service after recovery v1
Finite clean-recovery schedule · 5 September 2026
On this page
Result
Ten checks exercise service through a new persistent owner after the earlier owner is fenced by delayed completion. The old owner completes and is joined before reopening. The test closes its listener, verifies that a mismatched policy cannot open the ledger, then creates a fresh owner and loopback listener.
The recovered owner starts with two committed claims and no sessions, queued work, outstanding write or prepared responses. Its source counter starts after the old owner's last allocated handle. New clients verify these outcomes:
- Replay of the formerly unacknowledged claim succeeds without a journal append.
- A fresh signed claim is admitted and adds one 221-byte record.
- Valid conflict evidence commits one 221-byte quarantine record.
- The quarantined claim is rejected without fencing the healthy writer.
- A claim using another slot still replays successfully without an append.
Five submitted operations after reopen produce three successful claim responses, one quarantine response and one rejection. Final state contains three claims and one quarantine; post-reopen growth is exactly 442 journal bytes. Sessions and the verification queue drain to zero. Existing owner and pressure schedules also pass.
Model and ownership boundary
Six stable checkpoints match the narrow Python owner model. They compare observed claim counts, prepared-response counts, submitted work, fencing, active sessions and queued work. Actual Rust client reads separately verify response status, exact payload fingerprints and stream closure. Rust assertions also check quarantine count and journal growth; those fields are not included in this model projection.
Successful recovery with two claims and abstract validation outcomes are explicit model inputs. Python does not prove disk recovery or cryptography. The Rust harness uses the real pinned-policy journal reopen and signature checks. Four changed observations detect resurrected queue work, duplicate replay accounting, rejection fencing and missing successful response preparation.
This is clean same-process owner shutdown with a new listener, not process death, old-listener backlog recovery, arbitrary power loss, or a stuck fsync. No new owner starts while the old thread can still mutate the journal. Recovery time, clock skew, automatic retry/backoff and public transport authentication remain outside this test.
Reproduce
SKEIN_NETWORK_RECOVERY=1 cargo run --locked --offline --features peer-recovery --example admission_isolated > outputs/network-recovery.json
python3 model/network_owner.py outputs/network-recovery.json
Captured results, comparison, regressions and source/binary manifest are retained under docs/results/network-recovery-v1*. Historical reports remain unchanged. Driver initialization is shared between initial startup and recovery; no new runtime dependency is added. Next: test bounded service across repeated recovery cycles and review the remaining scheduling gaps before introducing new commit lanes. No public admission or Fly deployment is enabled.
