# Admission, recovery and replay payload review — 2026-10-08

Session `codex-review-admission-1008` started from `2f14dfb64` in its own locked worktree. Parallel reviewers covered classic C++, Java and Rust admission/recovery; root covered C++ FIXP payload storage and owned every build. Heavy jobs used the shared host lease, one at a time, with at most 16 compiler workers and outputs under the session build root. No .NET source or reserved C++ liveness/flow/finalization policy was edited.

## Findings and corrections

### C++ administrative observation

The first high-sequence ResendRequest and Logout passed validation and were acted upon without calling the administrative observation hook. Equivalent messages arriving during an already pending gap did call it. Both first-high branches now notify the observer once, after validation and before the administrative action. Unseen lower inbound sequence numbers remain unacknowledged. The hook retains its existing observation-only contract; no new callback reentrancy guarantee is introduced.

The 57-case regression covers FAST/SAFE/TEST, low and expected sequence numbers, first-high and pending-high paths, invalid CompID/BeginString controls, and locally initiated Logout confirmation. It checks callback metadata, the state visible during the callback, resulting recovery/frontier state and wire responses. The original header fails exactly six cases: two first-high message kinds in three modes. The other 51 pass.

### C++ FIXP payload storage

All three runner roles framed the caller's application payload before saving that payload for replay. When the input shared the runner's public send buffer, SOFH encoding could move or overwrite the original source bytes. The initial wire frame was correct, but both durable-before-send and memory-after-send paths saved different bytes.

All six Save sites now read the encoded frame's payload, whose bounds were checked by the successful encoder. Sequence consumption, failure retirement, and the documented caller-payload pointer in outbound diagnostics remain unchanged. The fix adds pointer arithmetic, with no extra copy or allocation.

The 84-case matrix covers three roles, two framing formats, two storage orders and seven placements: overlap on either side, exact header reservation, disjoint storage inside the send buffer, and external input. The original headers produce 48 stored-payload mismatches while all wire comparisons pass; the 36 remaining placements are controls. Final checks also cover sequence progression, replay retrieval, diagnostic pointer compatibility and an inactive sibling's untouched state. This is not a claim of a live sibling traffic test or crash-durability testing.

### Java rejected-frame recovery

Nonterminal validation rejects could consume and checkpoint an expected sequence without requesting the next missing chunk. Parsed validation rejects could also leave an already buffered application stranded when they closed its gap. Both the ordinary owner and TCP acceptors now continue recovery after a consumed reject, preserving Reject-first wire order, store/transport failure guards and callback retirement checks.

The TCP acceptor also lacked the ordinary owner's deferred-admin check at the start of the next inbound message. After a rejected replay closed the gap before a retained high TestRequest, a subsequent higher application could remain buffered without a Heartbeat response or new request. TCP now resolves that already admitted administrative boundary before processing the next frame, with retirement/fault guards. Existing parsed-reject deferred reply timing is preserved; basic-validity rejects retain their existing immediate resolution behavior.

The 196 new cases span transcript, worker initiator, single TCP acceptor and multiplexed TCP acceptor; seven rejection causes; repeated chunk endpoints, final buffered application delivery, high/low non-consuming controls, deferred reply timing, next-higher-frame progress and stop from the Reject callback. Existing checkpoint-failure and recovery regression classes accompany them. These tests use memory stores and do not themselves inject durable checkpoint faults.

### Rust recovered administrative checkpoint

Resolving an already observed high administrative message advanced the live inbound number past that message without persisting the new frontier. For example, high TestRequest 5 followed by GapFill 2→5 left live next=6 but stored next=5. Restart could request the already consumed administrative number again.

The resolution now checks the store checkpoint before a deferred Heartbeat or further recovery request. A refused checkpoint takes the existing store-fault path, retiring unsent batches and preventing those follow-up writes. Buffered application handling and gap fills that already overshoot the boundary keep their existing single-checkpoint paths.

Six new test methods cover 69 combinations, including restoration from the store, refusal and write ordering, ordinary replay versus GapFill, chunking, later high applications, buffered/unretained application controls and deferred replies after rejection. Three methods fail on the original production source and three controls pass. Original test methods stop at their first failing assertion; this is not evidence that all 69 combinations executed against the old code.

## Verification

| Gate | Result |
|---|---|
| C++ full administrative callback suite and ASan/UBSan | Pass; 57 new cases |
| C++ full FIXP send-failure suite and ASan/UBSan | Pass; 84 new cases |
| C++11 open edition, layering and simulator gates | 147 selected, 147 ran, 147 pass; zero reported skips; 83 private binaries excluded |
| Private C++ FIXP suites | 8 binaries pass; zero reported skips |
| Java original production with new regressions | 13 assertion failures, 51 expected socket read timeouts, 132 controls pass; native loading guard also passes |
| Java final focused recovery/checkpoint suite, required JNI | 413 pass; zero failures/errors/skips |
| Java full development / open editions, rebuilt required JNI | 5,837 development / 5,394 open unique cases pass; zero failures/errors/skips |
| Rust default / no-default features | 1,421 pass in each; one existing documentation example ignored in each |
| Rebuilt .NET native FIXP and loading guard | 56 pass; zero failures/skips (development native library) |

Sanitizers enable leak detection and fatal undefined behavior. Java uses JDK 21 with the Java 8 target and standard relocated native paths. Complete Surefire reports determine pass/fail/skip counts; configured counters-disabled forks are included, and skipped native tests are never counted as passes. Rust's existing ignored documentation example is reported separately. The private C++ gate is the eight FIXP binaries, not every private binary excluded by the open gate.

Intermediate harness failures are retained: the first C++ observer fixture needed a default constructor for the protocol's fallback application, and the baseline-result recognizer needed to recognize that fixture's diagnostic spelling. Neither was a production failure. The first Java matrix used duplicate tag 112 in a TestRequest, which the existing policy accepts. Its 24 failing/error rows were corrected to a NewOrderSingle with repeated tag 38, matching existing validation coverage; the other 172 new cases and 217 surrounding controls already passed. Production was unchanged by either fixture correction.

Independent reviewers checked the production changes and regression coverage. All nine engine files pass the public-export content scan, and whitespace checks pass. The exact nine engine source files are bound by `tested-source.sha256`. No Windows, exchange NIC, or latency benchmark was run; no measured latency gain is claimed. The review does not establish new policy for validation or observation of other high administrative message types that are deferred or dropped by existing code.

## Publication and retained evidence

The code commits are `472d25e51` (Rust checkpoint), `e9d8d7ee6` (C++ observation), `bebb60e84` (C++ replay payload) and `302555618` (Java recovery). Publication targets only private `atrekes/libhft-devel`: fetch/rebase, inspect incoming changes and outgoing commits, and verify the exact tested source hashes before pushing. The main checkout is updated with `pull --ff-only`. Only this session's claim block is removed.

Evidence is retained at `~/archive/libhft/reviews/2026-10-08-codex-review-admission-1008-recovery/` locally and on HP: original/final logs, test reports, source snapshots/hashes, reproduction scripts, independent reviews, final patch and Git history bundle. Both copies' manifests are verified before removing the session worktree, build outputs and scratch.
