# FIXP replay ranges and pump diagnostics — 2026-10-08

Session: `codex-review-replay-1008`, starting at `12c8bc68e` in the private
`atrekes/libhft-devel` repository. Parallel source reviewers used the session's
worktree; root alone ran builds, one heavy job at a time, capped at 16 workers.
All products used `LIBHFT_BUILD_ROOT` under the session's build root. Review and
runtime verification were performed on BEELINK2/Linux, with C++11 and JDK 21
compiling the Java 8 target. No .NET or reserved C++ FIXP runner paths were edited.

## Changes

### Replay response diagnostics

Java initiator replay sends previously reused and cleared the incoming `lastStep`.
Successful replies reconstructed only part of the request metadata; a failed later
record also discarded bytes already emitted in the group. The initiator now uses
its existing reusable response step and merges output fields into the original
request step. Original frame/event/timestamp/read diagnostics survive complete,
rejected, failed and incomplete replay responses. The reported byte total includes
all completed frames and any positive short-write prefix.

An encoding failure before transport I/O retains the preceding actual transport
result. Tests use a custom store returning an oversized first or second record to
exercise that distinction. Missing records and failed body writes after a group
header still terminate the incomplete stream. Existing retry behavior for a wholly
unsent first header/reject, close-once behavior, sequence counters and replay-store
writes are unchanged. No allocation was added to replay sending.

### Heartbeat and termination diagnostics

Java's two runners and Rust's initiator, acceptor and multi-acceptor cleared an
owed heartbeat's output when beginning inbound processing. They now retain the
heartbeat bytes/template locally, process input and replies, then merge the prefix
once. Buffered input with no further I/O retains the heartbeat's raw result; an
actual read or write, including zero or negative results, replaces it. Rust's
initiator also clears prior-step diagnostics before attempting a heartbeat.

Java merges only while the original lifecycle generation owns the step, preventing
an old connection's heartbeat from contaminating a callback's replacement or reset.
A nested application send retains its existing diagnostic replacement contract,
with the original heartbeat added when the same connection still owns the step.
The multi-owner API's immediate terminal reset continues to own fresh diagnostics;
this work does not aggregate across that lifecycle boundary.

Both initiators previously discarded a flow-violation Terminate's temporary output
diagnostics. These are now merged into the triggering input step. Java acceptor
also records the attempted Terminate template before violation, peer termination
and silence-timeout writes, so a failed write still identifies the attempted reply.
Wire order, liveness timing, pending-gap handling and retirement policy are unchanged.

### Bounded replay-range work

C++ Fixed/Mmap (and File through its Fixed delegate), Java Fixed/Mmap and Rust
Fixed/File/Mmap stores reject requests larger than their retained index capacity
before looking up records. They also preflight unsigned endpoint overflow; Rust's
default replay-store implementation preflights overflow too. The now-redundant
per-record overflow checks were removed where applicable.

This changes impossible-range rejection from up to capacity-plus-one lookups to
constant work. Valid ranges still check every record. Sparse and evicted records,
closed stores, empty checkpoints, signed file-format restrictions and each binding's
existing zero-capacity policy remain intact. A valid inclusive endpoint at
`UINT64_MAX` is preserved where that store supports it. This is a source-level work
reduction, not a measured latency or throughput claim.

## Verification

| Gate | Result |
|---|---|
| C++ replay stores, original production headers with new boundary tests | Open and pro pass; semantic preservation is expected |
| C++ final replay-store suites | Open and pro pass |
| C++ replay-store AddressSanitizer + UndefinedBehaviorSanitizer | Open and pro pass, leak detection and fatal UB enabled |
| C++11 open edition and layering/simulator gates | 147/147 open binaries pass, no reported skips; 83 private binaries excluded |
| Rust original runner/socket overlay, new heartbeat tests | 7 assertion failures, no compilation failure |
| Rust final focused selector | 30/30 pass, including 11 new methods |
| Rust full default features | 1,404 pass; one existing documentation example ignored |
| Rust full no-default features | 1,404 pass; the same documentation example ignored |
| Java original three-production-file overlay | 576 assertion failures / 265 controls pass, zero errors/skips |
| Java final focused tests | 879/879 pass, zero errors/skips |
| Java full development | 5,321 unique tests pass; native guard and configured counter tests pass |
| Java full open edition | 4,878 unique tests pass; native guard and configured counter tests pass |
| Export-name scan and final source hashes | 22 engine files, zero export findings; all reviewed/tested hashes match |

Java's original-code failures comprise 500 heartbeat/termination diagnostic cases
and all 76 initiator replay cases. Controls are 112 heartbeat cases, 152 acceptor
replay cases and the mandatory native-library guard. Final new Java coverage is
612 heartbeat cases, 228 replay cases and two store-range cases (one range case is
pro-only): 842 additions in development and 841 in open. The parameter matrix spans
three roles, two framing formats and enabled/disabled flow rules. Bounded inner
loops exercise additional heartbeat forms, sequence endpoints and replay positions.

Rust's seven new heartbeat methods contain 338 scripted cases; four further methods
cover fixed/default/file/mmap range behavior. The focused selector also includes
19 pre-existing replay-review tests. Both full Rust runs include all library,
integration, binary and documentation targets.

Java uses the standard relocated development and open JNI locations with
`libhft.require.native=true`. Full-suite totals are deduplicated by test class/name
from archived Surefire XML, including the dedicated counters-disabled execution.
The three conditional skips in the ordinary counters execution must pass in that
configured fork before being counted as covered. Native tests are never counted
from an exit code alone.

Independent source reviews checked the C++ and Rust range guards, Rust heartbeat
changes, and final Java patch. Two additional Java findings from that review—the
failed silence template and no-I/O replay result overwrite—were fixed and included
before final verification. Source hashes identify exactly what each review and
runtime gate exercised.

## Limits and retained evidence

Failures are deterministic scripted transport/store faults, not physical network
fault injection. No Windows build, NIC latency measurement or new percentile claim
was made. Rust's new heartbeat matrix exercises replay rejection; full stored replay
is covered by existing tests and review of its composition with the common prefix
merge. Neither heartbeat matrix adds receive-buffer-full injection. Java callback
coverage includes a single nested send and lifecycle replacement/close, not every
possible multi-owner reentrant operation. These are coverage limits, not outstanding
confirmed defects in the patch.

The retained archive is
`~/archive/libhft/reviews/2026-10-08-codex-review-replay-1008/`, on BEELINK2 and HP.
It contains drivers, baseline/final logs, complete Surefire reports, independent
reviews, the tested 22 engine source files, SHA-256 manifests, this record, and Git
bundles/patches. `scratch/evidence/verification-summary.json` holds machine-readable
counts; `scratch/evidence/tested-source.sha256` binds them to source. The final bundle
has the recorded starting commit as its prerequisite. Archive and remote manifests
are checked before removing the session worktree and build products.
