# Transport and replay failure review — 2026-10-07

Worktree: `codex-review-transport-1007`; initial checkout `350e136ec`, rebased before
implementation onto `2fcba8583` (an unrelated internal installer record).
Parallel reviewers covered C++ transport waiting, Java replay-store failures,
and Rust required FIXP responses; root covered prepared-send ownership and
serialized every build/test under the shared host lease, with at most 16 workers.

## Confirmed defects and fixes

- C++ classic FIX initiator waited only for readability after a TLS read reported
  WANT_WRITE. A real connected socket and scripted retry direction reproduced
  a 300 ms delay despite immediate writability. The optional transport trait now
  selects writable interest; the same regression reports 0 ms, with idle-read
  parking and decrypted-buffer controls intact. This is a controlled readiness
  test, not a forced OpenSSL renegotiation or a throughput benchmark.
- C++ TxQueueTransport lacked ReadMsgOrEof, so the documented session decorator
  could not instantiate the EOF-aware receive API. The baseline compilation
  fails at that missing member. Forwarding preserves idle/data/FIN/error behavior;
  tests use a real socket pair through fix::Session, including missing-inner and
  closed-descriptor cases. Full queued runner/reconnect support is not claimed.
- C++ and Java FIXP preparation metadata could select a superseding or foreign
  frame, survive reinitialization, or refer to bytes overwritten by raw sendPayload.
  Both now bind each preparation to an owner and monotonic generation and refuse
  mismatched steps before consuming the current frame. Raw sends invalidate a
  preparation. C++ owners are allocated on construction/copy, not per send; copies,
  assignments, template specializations and placement-new address reuse are tested.
  Java also rechecks lifecycle, sequence/exhaustion and flow before transport I/O.
  In Java the old implementation emitted data before detecting sequence/lifecycle
  invalidation. Exact successful wire bytes and one sequence increment are checked
  in both SOFH formats. C++ public raw-buffer writers must discard preparations
  explicitly; normal runner prepare/store/send calls are synchronous.
- Java QuickFixFileStore reset published counters 1/1 and an empty in-memory index
  before fallible file operations. Injected failure left the object writable with
  an incorrect epoch. Publication now follows all reset I/O; failure closes the
  admission gate and keeps writer descriptors/locks until close. Both QuickFIX
  layouts have 12 total fault sites with publication/refusal/healthy controls
  (36 cases). This does not make multi-file disk reset atomic or promise rollback
  after truncation. Fault tests cover IOExceptions and same-JVM lock contention;
  partial writes, runtime exceptions and external contenders during a failed reset
  are not separately injected.
- Rust multi-peer FIXP handshake responses closed only positive short writes;
  zero/negative writes left an advanced peer active. Recovery-request failure in
  all three runners likewise left finalization waiting for a request never sent,
  with no queued retry. Every failed required response now retires the affected
  connection, leaving multi-peer siblings usable. Twenty new test functions cover
  40 SOFH scenarios: negative/zero/short/full writes, later refusal, replay through
  FinishedReceiving, and sibling activity. Existing result and transport-error
  information is preserved, and partial-write teardown is not repeated.

## Baselines

C++ idle readiness failed exactly at its <100 ms writable-wake assertion; queued
session compilation failed exactly at missing ReadMsgOrEof. The initial C++
prepared suite aborted on the first stale-step send assertion; later cases are
final regression coverage, not separately executed red-baseline claims.
Rust's required-response subset had 26 passing and 10 failing tests, no ignored.
Java's initial focused gate had 61 tests: 31 failures, no errors/skips (24 reset,
7 prepared-send); its JNI-required check passed. Later test strengthening aligned
foreign-step error metadata with C++/Rust, made stale headers identical, and added
a generation-exhaustion control; these are retained as final-test changes.

## Verification

Linux verification passed:
- C++11 open edition: 147/147 test binaries, zero reported skips, plus layering
  and simulator checks. That gate leaves out 83 private binaries; three private
  FIXP runner companions were separately compiled and passed with no skips.
- FIXP socket preparation and TX queue binaries passed AddressSanitizer plus
  UndefinedBehaviorSanitizer, with leak detection and fatal UB diagnostics.
- Java development: 3591 unique cases; Java open: 3149. Both have zero final
  failures, errors or skips. Native loading was required, with separately built
  development/open JNI libraries. The three counters-disabled cases initially
  skipped by the ordinary fork pass in their configured fork; final aggregation
  keys by class and case name. The new Java coverage is 36 reset cases plus nine
  socket test methods (including two-format subcases); the socket class totals 25.
- Rust default and no-default-features: 1324 passed each, no failures, one existing
  ignored builder documentation example per configuration. Each library subset
  passes 1176 tests; the totals also include integration/binary/doc tests.
- The focused C++ wait/queue suite passes, and the expanded prepared-send test
  executes 22 new scenario variants in the open-edition and sanitized runs.

All 16 changed engine files passed the export scan without findings. Source
hashes still match after the final rebase onto `d363816d0`; the incoming change
only added internal benchmark tooling/claims. Whitespace checks pass. No Windows
execution or optional Rust venue/service-pack feature suite is claimed.
The retained verification-summary.json gives the aggregate counts.

## Publication and evidence

Fix commits after rebase: Rust `b9516b032`, C++ transports `1683849ba`,
Java replay reset `16d224fc7`, prepared sends `d1e123cdf`.
Two session-branch push attempts received GitHub internal server errors; a later
retry succeeded before final publication.

Publication targets only private `atrekes/libhft-devel`, after fetch/rebase and
verification of exact engine source hashes. No .NET or reserved C++ FIXP runner,
flow, liveness or finalization source is changed. Independent reviews found no
blocking issue in reset publication/locks or preparation ownership/caller use.
No per-send heap allocation, lock or shared atomic is introduced. No general
latency or throughput claim is made beyond the controlled wait-direction timing.

Evidence is retained locally and on HP at
`~/archive/libhft/reviews/2026-10-07-codex-review-transport-1007/`: baseline and final
logs, JUnit reports, final source hashes, drivers, record, published patch and
review-history bundle. MANIFEST.sha256 is verified at both destinations before
the session worktree and build root are removed.
