# Rust FIXP shared-store HA and C2 across two hosts — 2026-10-03

The independent Rust replay-store probe passes the complete five-transition
handoff on BEELINK2 and SCAN through the intended shared NFS export. Both Rust
durable backends also preserve finalized session IDs when the other host resets
and reopens the store. These are synthetic engineering proofs. Venue endpoint,
session/schema and certification evidence remains outstanding.

## Source, binaries and mounts

- Both binaries were built from clean commit
  `df728ce07a46778bcdf3888b05c90f478f30795f`, Rust tree
  `c3eb7b00e5908db467c15187f4d1f86ae1d40325`, in the owned HP worktree.
  Offline builds used one Cargo job and waited for an idle host. Outputs stayed
  under `~/build/codex-rust-ibv/libhft`. No heavy build ran on BEELINK2 or SCAN.
- Probe SHA256:
  `b8b70a27870a2472f4f63a236835de9ffddc7f8b82738c2b5c7147b83c118180`.
- FIXP runner SHA256:
  `69d518993b8b87764061dc48baf47f7bc3329a92ce7068e6c1ef38dd5af6ddcc`.
  Each run checked identical bytes on its two participants.
- Both participants mounted `10.0.4.45:/srv/libhft-ha` as NFS 4.2 with
  `local_lock=none`. SCAN used its NFS client mount, not the server's local
  backing directory. Mount identity, options, both kernels and binary identity
  are retained with the raw reports.

## Five-transition handoff

The successful run is `run-20261003T163336Z` under
`~/archive/libhft/rust-fixp-ha-20261003`.

| Transition | Observed result |
|---|---|
| BEELINK2 primary commits sequence 41 | Open result 0, primary lock held, one record, next sequence 42 |
| SCAN attempts open while primary lives | Open result 1, store closed, no primary lock |
| SCAN promotes after release, recovers 41 and appends 42 | Open result 0, exact payload recovery, two records, next sequence 43 |
| BEELINK2 attempts open while promoted primary lives | Open result 1, store closed, no primary lock |
| BEELINK2 recovers after reverse release | Exact sequence-42 payload, two records, last sequence 42, next sequence 43 |

Each primary held its lock for 20 seconds after emitting its report. The shipped
`validate-ha-failover-evidence --provider independent-rust` accepts the five
reports: **all 15 checks pass**. The sanitized report retains report hashes,
derived sequence facts and source revision; the raw private reports retain the
store path and participant context.

The earlier `run-20261003T163106Z` also passed all protocol transitions and the
validator, but its archive command failed copying NFS permission metadata.
The corrected launcher copies store bytes without those attributes. The entire
sequence was then rerun: exit zero, checksums verified, test store removed.

## C2 retirement across the shared export

The retained runner executed six cases with separate real CLI processes:

- On BEELINK2, finalization completes for a synthetic session ID in each of
  `file` and HA `mmap`, producing its synced 28-byte `LHFF` companion.
- On SCAN, a new acceptor opens those same stores with `--reset-store`. The
  retired ID is rejected, while a different ID establishes, on both backends.
- The companion bytes match exactly before and after the second host's replay
  reset and rejection. They match across both participants and both backends.

**All six cases pass.** The application transport is loopback on each physical
host; cross-host state goes through NFS. This is a two-host persistence/recovery
proof, not a cross-host application-wire or latency measurement. Server processes
are stopped and waited in `finally`; the unique shared fixture directory and
remote runtime outputs are removed after their evidence is copied.

## WSL prerequisite correction

The initial local mount failed with `mount.nfs4: mount(2): Operation not permitted`.
The observed NFS peer on SCAN was `10.0.4.39:50820`: WSL NAT translated the reserved
client port. SCAN's export still required a source port below 1024.

The reviewed SCAN helper now enables `insecure` only for
`10.0.4.39:/srv/libhft-ha`, retaining `root_squash`, synchronous writes and the
client-specific timed firewall rule. The home installer checks this export
policy before deciding that SCAN needs no restoration. After the user ran the
updated installer, both mounts and the export policy passed readiness checks.
The before/after scripts and diagnosis are retained separately under
`~/archive/libhft/fixp-ha-wsl-nat-20261003`.

## Retention and limits

Raw reports, source/binary/build identities, harnesses, mount records, store
snapshots, readiness output and SHA256 manifests are retained under
`~/archive/libhft/rust-fixp-ha-20261003`. A compact private evidence copy beside
this record is committed under `internal/docs/bench/evidence/rust-fixp-ha-20261003`.
Committed log copies normalize SSH's CRLF line endings; the archive retains
their original bytes. JSON reports are copied byte for byte.

The five selected documentation/coverage/inventory/validator stages pass with
zero skips and failures. Their result is PARTIAL, not a complete conformance-suite
pass. The two edited engine files pass the privacy/export scan. No runtime source
changed in this evidence update, and no new full-crate test count is claimed.

This closes the previously missing external two-host shared-store proof. It proves
active/passive handoff after primary release for this provider and store path;
it adds no replication, network-partition, crash-fault, availability or latency
claim. FIXP remains partial pending venue session/schema certification and its
binding-matrix present claim. Overall Rust subsystem counts remain 43 complete,
2 partial and 1 not applicable; production venue certification still prevents
a full parity claim.
