# Rust HA FileStoreSync handoff qualification — 2026-10-19

## Scope

Reconnect both named cases from
`private/rust/libhft-rust-pro-store/qualification/classic-store-gates/file_store.rs`
in `tests/private_file_sync_handoff.rs`:

- `configured_fixed_ha_file_sync_policy_survives_promotion_and_handoff`
- `configured_learned_ha_file_sync_policy_survives_binding_and_rebinding`

The real configured provider, HA wrappers and file store perform every normal
save, checkpoint and handoff. Production sources, OSS APIs and edition
discovery are unchanged. No public test hook is added.

## Worker adapter and retained assertions

The extracted fixture reached the dependency-private `HeldIdleWriter`, journal
and flusher pause control. Its replacement is an explicit subprocess-only
`pthread_create` fixture in `tests/support/file_store_writer_gate.c`. The test
arms only the next worker created by its current caller immediately before
promotion or learned binding. A bounded socket handshake confirms the actual
worker is held before its Rust entry point. The owner can still synchronously
write and sync; the background flusher cannot consume its queue.

This holds earlier than the historical observed-empty/pause seam. Journal
construction recovers the file and spawns its single flusher without waiting
for that worker to run. No test records are queued until after the handshake.
Held-state checks surround each snapshot. An unwind guard releases the worker
before store teardown; the normal path also confirms the gate clears after
primary release. Missing interception, timeouts and aborts fail qualification.

Public configured-store getters and the settings-derived pathname replace
obsolete concrete variant and inner-primary access. The four original policies
and two reuse cycles remain: `file` with FileStoreSync=Y/N, `sync-file`, and
`async-file`. Each synchronous snapshot must recover the exact application
payload, outbound frontier and inbound checkpoint before worker release.
Each asynchronous snapshot must equal the file bytes before the owner saved.
After release, reopening must recover the payload and inbound checkpoint on
both cycles. The wrapper is reused so a policy lost on promotion/rebinding
cannot pass.

The archived source review compares the original snapshot/handoff assertion
block with the adapter using rustfmt normalization, ignoring blank lines left
by removed gate statements. Only pathname/string adapters and added held-state
and diagnostic statements are removed for that comparison; payload and recovery
assertions remain. It also checks the two original names, policy order, reuse
count, public recovered-sequence assertion and absence of production changes.

## Negative controls and fixture ownership

Each case runs three exact subprocesses: the normal production provider, a
control that delegates a forced asynchronous request, and one that delegates a
forced synchronous request. Normal execution uses `ProStoreProvider` directly.
The controls alter only their public factory request before delegating to the
same provider. They must terminate with libtest assertion exit 101 and the
specific `SYNC_POLICY_NOT_DURABLE` or `ASYNC_OWNER_WROTE` diagnostic. A timeout,
native abort or unrelated assertion is refused as a control result.

Each feature configuration completes two normal children (16 snapshot cycles)
and four intended assertion failures. Exact-case child filters and those
expected failures are internal controls, not ignored/failed cases in the
complete parent suite. Raw child transcripts, outcomes and compiled fixture
libraries are retained separately.

The fixture compiles with C11, `-Wall -Wextra -Werror` and links pthread/libdl.
Ready, worker-release and child deadlines are bounded. The parent owns the
native source/library and every child's runtime subtree, including cleanup on
an assertion failure, child timeout or abrupt child exit.

## Qualification

Focused fixture source: `867ed33e6d23b37bdcaf686226ebf7a170a37df4`.
Complete qualification source: `bada10570164d58354e4be80c017b47582549d5e`,
based on published claim `d6ca0887d`. Only the two READMEs differ between the
focused and complete sources.

| Complete companion command | Counters enabled | Counters compiled out |
| --- | ---: | ---: |
| Library unit tests passed | 92 | 92 |
| Integration tests passed | 467 | 467 |
| **Total passed** | **559** | **559** |
| Failed / ignored / filtered | 0 / 0 / 0 | 0 / 0 / 0 |
| Normal snapshot cycles | 16 | 16 |
| Expected wrong-policy assertion failures | 4 | 4 |
| Strict companion all-target Clippy | pass | pass |
| Warnings-denied companion Rustdoc | pass | pass |

All six final commands and the focused two-case command return 0. This slice
adds exactly two integration tests to the prior 557-test checkpoint. The OSS
dependency still emits twelve generated FAST warnings; the strict Clippy result
here covers companion targets and is not an OSS warnings-clean claim.

Cargo uses `--locked`, the explicit development config, one job/test thread
and an out-of-tree session target. Scan holds the shared CPU lease and uses the
memory/process guard and command deadlines. BEELINK2 runs no heavy build.
All 361 selected source/configuration/documentation/fixture hashes match before
and after the complete run. Manifest SHA-256:
`166b8f1ea6d04e29627a1fba3bc5dcd23c06e8c74092db196c11dc7c93f9d2f7`.
Both qualified trees are clean afterward. Rustfmt and whitespace checks pass;
publication rechecks the qualified input hashes after rebasing.

## Retained evidence and limits

`~/archive/libhft/rust-file-sync-20261019/` retains source bundles/snapshot,
the exact adaptation patch, source review and assertion comparison, command
controller/guards, focused and full logs, child transcripts/outcomes/libraries,
toolchains, before/after hashes, totals and publication mapping. Its checksum
manifest and copies are verified on Scan and HP before scratch cleanup.

The two paused-writer FileStoreSync cases are now runnable. Other historical
fragments, including obsolete concrete store-selection assertions and private
replay counters, retain their own adapter work. This Linux worker-entry fixture
does not establish physical power-loss behavior or hardware performance, and
this checkpoint does not declare full Rust parity.
