# FIX session state review — 2026-10-06

Base: `3bd872ecd`. Session: `codex-review-state-1006`. Parallel agents reviewed
C++, JNI, Rust and pure Java; the root alone built and tested under the shared
host lease after memory/process checks. Builds used the external session root,
C++11 and bounded LTO; build parallelism was at most 16. Java targets Java 8 APIs
and tests run on JDK 21. No .NET or reserved C++ FIXP source was changed.

## Corrections

C++ and Rust scheduled initiators previously reset only live counters, or lost
the old schedule anchor while reconnecting. A new observed window now requests
a checked replay-store epoch reset at the next Logon and advertises 141=Y.
The request survives failed sends and lost acknowledgements until an admitted
peer Logon. Same-window continuation retains the acknowledged epoch. Admission
clears the pending request before optional replay I/O, so replay failure cannot
cause another reset. Store-reset failure leaves the prior frontier authoritative.
The schedule anchor remains logical-session state; this does not add a persisted
calendar anchor to a fresh process.

Classic C++ and both JNI initiator owners now carry that schedule state across
runner reconstruction. Explicit offline JNI reset clears the carry only after
its store reset succeeds. C++ NullStore/MemoryStore and JNI storeless teardown
now honor ResetOnDisconnect and admitted-peer ResetOnLogout. Failed dials,
local-only Logout and store faults preserve the existing policy. C++ memory
replay is cleared before counters change; failed clear faults and refuses reuse.
A C++ Logon watermark temporary now retains SeqNum width, accepting legitimate
789 values above 2^32 without truncating the reset-ack bound.

Rust FIXP multi-acceptor checks SOFH representability and actual send capacity
before storing or assigning sequence state. An oversized payload no longer
journals an unsendable message or needlessly retires the peer. Rejection leaves
the peer, sibling, journal and sequence available for a valid retry.

Pure Java TCP acceptors reject application sends after local Logout, before any
builder, send hook, sequence assignment or wire activity. Inbound Logon vetoes
now respect callback retirement after stop/restart, including hooks that throw.

Pure Java worker initiators serialize outbound encoding, sequence assignment,
replay access and transport order. Ordinary inbound parsing remains independent
of a blocked write. A separate replay-store monitor protects the inbound
checkpoint without retaining it across socket writes. Whole Logon and Logout
transitions hold outbound ownership, including Logon veto scratch and resets.
Nested Logon-hook sends use the existing bounded deferred-command mechanism.
Successful Logout closes application admission before terminal status publication,
including validation-triggered Logout. Builder, primitive order and cancel paths
check before encoding or invoking hooks.

Worker stop/restart retires the old reader/dial before activating a replacement.
A callback may request restart promptly and observe CONNECTING while old parsing
or handshaking unwinds. Journal and audit ownership survive until that boundary;
resetSeq refuses while the worker is retiring. Channel installation and connected
publication check the generation, and expected retirement is contained by the
worker boundary. Ordinary external stop retains its bounded join outside the
writer monitor. Existing callback tests now await worker activation while still
checking that retired frames and commands never reach the replacement; Java-driven
immediate assertions remain.

Pure Java also gains the same observed-window reset behavior, using a cold
schedule anchor lookup at initiating Logon. Daily, overnight, weekday, weekly and
DST windows retain the existing C++ anchor semantics. A non-stop session and an
acceptor retain their prior policy. Durable replay and counters reset together;
a lost acknowledgement repeats the scheduled reset, and an admitted one enables
same-window continuation.

## Reproduction

| Boundary | Baseline result |
|---|---|
| Java acceptor post-Logout and Logon callback retirement | 30 failing cases |
| Java concurrent application/reader outbound ownership | 12 failing cases |
| Java reader and delayed-dial retirement | 5 failing cases |
| Java live peer reset and concurrent application | 6 failing cases, 18 existing controls pass |
| Java nested Logon callback and validation Logout admission | 12 failing cases, 24 existing controls pass |
| Java scheduled epochs | 7 failing cases, 3 controls pass |
| C++ schedule/reconnect and 64-bit Logon | 34 and 11 failed assertions in the extended baseline |
| C++ non-durable teardown reset | 42 failed assertions across 32 reset/retention scenarios |
| JNI schedule reconstruction | 15 failed assertions across both owners |
| JNI storeless reset policy after schedule fix | 4 failed assertions |
| Rust schedule epoch and FIXP capacity | 6 failing cases and 1 control |
| Rust admitted reset followed by replay send failure | 1 failing case |

The final C++ teardown fixture adds two failed-clear controls. Java lifecycle
coverage adds actual audit/journal lifetime through a held reader and runtime
reset refusal. The final schedule fixture adds cold anchor math controls.

All baseline logs and source snapshots/patches are retained. Early JNI fixture
runs lacked the required storeless persistence setting or aborted before all
assertions; the corrected full baseline is separately named. A parameterized
JUnit method-filter invocation ran no tests; the full-class baseline supersedes
it. The first worker retirement candidate passed its new cases but failed three
old immediate-restart assertions; their asynchronous worker expectations were
corrected while retaining wire and sequence checks.

## Verification

C++ development: 23 regression binaries pass, including real sockets, durable
stores, schedule/teardown policies, 64-bit Logon and TLS backpressure. The full
open-edition gate passes 147/147 binaries with zero reported skips, plus layering
and simulator checks. Four JNI unit variants (development/open, TLS off/on) pass.

Rust default and no-default-feature configurations each pass 1277 cases, with
zero failures and one intentionally ignored builders.rs documentation example.
The admitted-reset/replay-failure regression is included in both final runs.

Java development: 3362 unique cases pass, with zero final failures/errors/skips.
The initial full ordinary run passed 3354, failed two old lifecycle fixtures and
intentionally skipped the three counters-disabled cases. The corrected two tests
then passed, as did the remaining configured event-driven/counters-disabled forks.
Production source did not change between these runs. The transport fixture now
checks cold refusal separately from a real admitted socket write failure and
subsequent explicit reset/reconnect. The acceptor fixture waits for the retired
worker itself, asserts no late hook/store/reply, and admits a replacement HA Logon.
Initial and completion XML reports are retained; results are combined by unique
class/test identity rather than hiding the original failures.

Java open edition: 2920 unique cases pass, with zero final failures/errors/skips.
The open native library was rebuilt with HFTJAVA_PRO=0 and native loading was
required for both editions. The final Java rebase changed no tested engine
source; 53 ownership/lifecycle/schedule regressions then passed again.

The focused Java state gate passes 134 cases in each of three configured forks,
including TLS small-buffer backpressure. All final native/Rust source hashes were
unchanged by rebase; frozen Java hashes are retained for the final publication
check. Export scan covers 23 changed engine files with zero findings; whitespace
check passes.

The Java-driven single-owner path does not acquire the worker writer or replay
monitors. Schedule bookkeeping is cold and FIXP preflight is a constant-time
bounds check. This pass makes no measured latency-speedup claim. The TLS
small-buffer burst remains the liveness gate for worker serialization; its
reader must keep draining during blocked writes.

## Publication and evidence

C++: `6badca93a`; Rust: `013372380`; JNI: `bab2585e8`.
Pure Java: `13657da43`.
Published only to private `atrekes/libhft-devel`; main stays linear. Before the
native/Rust push, fetch/rebase, exact source-hash comparison, focused C++/JNI
reruns and both Rust regression configurations passed.

Evidence destination:
`~/archive/libhft/reviews/2026-10-06-codex-review-state-1006/` on BEELINK2 and HP.
The archive retains baseline/final logs and reports, driver scripts, source
manifests, the published patch, this record and a review-history Git bundle
(including superseded candidate checkpoints; requires base `3bd872ecd`). Every
retained file is covered by `MANIFEST.sha256`. The session worktree, build root and scratch are removed
after publication and verified mirroring.
