# Classic FIX I/O and deadline progress review — 2026-10-12

Seven reproduced correctness and idle-CPU defects are corrected. The scoped
C++, Java, .NET and Rust qualifications pass in development and open editions.

The session `codex-review-progress-1012` uses isolated worktrees and
`LIBHFT_BUILD_ROOT`. The regression baseline starts at `ca11208ad`, with only
the new fixtures overlaid for each language. Builds and suites run serially
per host, using CPU leases and a check for foreign heavy jobs. Local parallelism
is capped at 16, HP at 4, and Scan at 8.

## Corrections

- C++: propagate a negative worker `StepOnce` result through the default
  `AcceptorThreadPool::Run`. A caller-supplied `RunWith` returning false still
  requests a clean stop.
- C++: preserve a failing port's result in `MultiPortAcceptor::StepOnce`, while
  stepping the other ports. Work reported by another port cannot cancel out
  the error, and two errors cannot turn the result into an unrecognized sum.
- Java: enforce a worker TLS initiator's Logon deadline while its reader is
  blocked waiting for the peer. Serialize the timeout with Logon admission and
  reject admission on a retired channel.
- Java: enforce the same worker's local Logout confirmation deadline when the
  peer remains silent. Preserve the existing stop and callback ownership.
- .NET: permit an idle poll when buffered bytes form an incomplete FIX frame.
  Complete or malformed input remains runnable; TLS read completion retains
  its existing wake. The extra parser call is confined to the idle-wait path.
- Rust: make `advance` and `step_read` stop on a closed transport before
  reporting a ready frame or processing the buffered tail. Preserve an earlier terminal error
  and allow a fresh reconnect to establish its own receive state.
- Rust: keep a peer's queued Logout response draining before retiring the
  managed connection. Each acceptor turn still services other peers. A
  positive LogoutTimeout retains its original deadline; zero retains the
  existing disabled-timeout meaning. Forced close and store faults retire
  immediately.

The Rust change concerns replies to an admitted peer Logout. It does not
change the application-requested Logout or failed-start policies being
reviewed separately.

## Results

The .NET tests-only baseline reproduced all six incomplete-frame cases:
59–60 owner-thread CPU ticks in each 600 ms interval, across TCP/TLS and
header/body/checksum splits. The two deliberate spinning controls and the
native-required check passed: 6 failures, 3 passes, no skips. The candidate
also checks completion of a 71-frame burst, which exceeds one receive-pass
budget, without waiting for the configured 1000 ms idle interval.

The corrected Java baseline reproduced only the two worker TLS deadlines:
2 failures, 8 passes, no errors or skips. Its original run had a fixture
configuration error (the TLS context's acceptor settings omitted the listener
port): 4 passes and 6 setup errors. Those reports are retained as setup errors,
not evidence of a runtime defect. Adding the explicit ephemeral port fixed
the fixture before the corrected baseline ran.

The Rust baseline reproduced five closed-receive failures, with the two
sticky-error and reconnect controls passing. Its peer-Logout selection
reproduced three failures, with the forced-close/store-fault control passing.
The failure assertions show the post-close sequence/store frontier advancing,
a ready frame being returned on a closed transport, premature acceptor
retirement, and the initiator losing its queued FIX bytes. Exact failing
identities and panic text are retained in `rust/scan/baseline-verified.json`.

The C++ baseline reproduced four failures with seven passing controls. A fatal
poll returned success after a second poll; multi-port results `(-1, -1)` became
`-2`, and `(-1, 1)` / `(1, -1)` became success. Both editions now pass all 11
focused cases and the full pool and multi-port registered executables. The
complete C++ gate contains 13 verified stages, with assertions enabled.

Java passes 75 cases in each edition, including the native-required check,
deadline, TLS, callback epoch, worker retirement and stop controls. Its fresh
JNI libraries use the corrected, C++-qualified headers at the normal build-root
locations. Each exact JUnit inventory has zero failures, errors or skips.

| Rust edition | Closed receive | Peer Logout | Session | Initiator | Acceptor |
| --- | ---: | ---: | ---: | ---: | ---: |
| Development | 7 | 4 | 442 | 37 | 47 |
| Open | 7 | 4 | 428 | 31 | 38 |

All Rust selections passed with zero failures or ignored cases. The 11 focused
cases also appear in the session/owner totals; they are not additional unique
coverage. Exact listed and executed inventories match.

.NET passes all 114 selected cases in each edition, with exact discovery/TRX
identity equality and zero failures or skips. The selection covers idle polling,
TLS read/write completion, stop behavior, Logon SendingTime and latency checks,
Logout admission, QuickFIX writer ownership and the required native library.
All six partial-frame cases record zero owner-thread CPU ticks in 600 ms in
each edition; the same-host TCP/TLS spinning controls record 59 and 60 ticks.
Every partial-frame case also delivers its completed 71-frame burst within
the fixture's 300 ms bound under a 1000 ms idle poll. This is a measured park
and wake result, not a claim of zero CPU use at finer clock resolution.

This is a scoped correctness and idle-CPU qualification, not a throughput
benchmark or a full repository test run.

## Evidence

The completed evidence is retained under
`~/archive/libhft/reviews/2026-10-12-codex-review-progress-1012/`, including raw
TRX/JUnit output, exact test inventories, compiler commands, baseline failures,
candidate passes, source/artifact hashes and the upstream integration audit.

The local .NET baseline uses SDK 8.0.423/runtime 8.0.29 and GCC 15/C++17 for
the native-required library at its normal build-root path. No native library
is relocated with an ad hoc build flag.

- C++: `cpp/evidence-progress-hp` and
  `cpp/final-progress-evidence-audit.json`; HP GCC 14.2.1/C++11/O1/LTO1,
  `-UNDEBUG`, j4. All 1,274 candidate C++ inputs match the integrated local tree.
- Java: `evidence/hp-java-deadline-baseline-port`, candidate raw reports and
  `java/final-deadline-evidence-audit.json`. The audit verifies 4,914 copied
  evidence files, both exact 75-case inventories, and actual required JNI
  paths/hashes. Of 2,170 conservative input pins, 2,169 match the integrated
  tree. The sole difference, `cross_binding_api_inventory.py`, changes a static
  .NET suppression-pattern check and is used by neither Maven nor the native
  makefile; the Java results do not qualify that tool change.
- Rust: `rust/scan`, `rust/QUALIFICATION.md` and
  `rust/local-scan-source-equivalence.json`; Scan Rust/Cargo 1.92.0,
  default features, test debug information disabled, j8, one test thread.
  All 848 Rust/shared-fixture/dictionary/tool input hashes match locally.
  This default Rust build has no C++/JNI/.NET native engine-library dependency.
- .NET: `dotnet/hp-candidate-evidence-26c841a0`, including both raw TRX reports,
  discovery inventories, CPU observations in `tests.log` and six successful
  build/discovery/test stages. HP uses explicit SDK 8.0.131, runtime 8.0.31,
  GCC 14.2.1/C++17 and j4. Both editions force a fresh native build at the normal
  build-root path and use fresh managed outputs; the test copy must match the
  native artifact hash. All 1,823 C++/.NET source pins match the local candidate.

Local integration at `26c841a00` imports the upstream .NET SendingTime/Logout
correction (`9fd67df1d`) and managed QuickFIX writer ownership (`10c31016b`).
Their regression classes are included in the passing .NET candidate. These
imports change none of the qualified C++/Java/Rust runtime or test inputs.
The final upstream import, `d640e3c55`, adds a separate benchmark driver and
its evidence; it changes none of these qualified inputs. The archived
`integrated-inputs-after-rebase.json` records the final source equivalence.
Local C++ and .NET candidate waits were canceled before any compiler or test
launched; the preserved cancellation receipts are not test results.
