# FIXP response ownership and initiator lifecycle review — 2026-10-12

Session: `codex-review-initiator-1012`. This batch repairs recovery and lifecycle failures across C++, Rust, Java and .NET. Eight fix commits are backed up on the private session branch. The eight-fix candidate plus narrow coordination-note corrections is `82cc6b579f12142716ad87a600e0f0f068a0904e`, rebased without patch changes onto upstream `0eae8bab211815e057da636ba32a14161f349549`. The completed broad qualification below is supplemented by explicitly source-pinned integration checks. The final native integration gate completed successfully on that candidate. The final record commit changes no build or test inputs.

## Corrections

A runner consumes a peer's retransmission request before it writes the required reply. If the first reply write returned zero or an error, several implementations left the connection established without retaining an operation to retry. C++, Rust and Java now retire that connection on every incomplete required reply, including the first write. C++ multi-acceptors retire only the affected peer. Caller-owned application sends retain their zero-write retry behavior.

Rejected initiator establishment also left replay-store ownership and/or liveness active. The corresponding C++, Rust and Java rejection paths now release their owned resources while preserving rejected status and diagnostics. Java's transport remains caller-owned. Rejection fixtures cover reusable file locks and mapped-store ownership where supported.

The .NET initiator had equivalent required-response and rejected-ownership failures, and could overwrite a replacement connection's state after an application callback closed or reconfigured its owner. A lifecycle generation now prevents obsolete continuations from updating the replacement. Same-generation termination preserves the nested result and prevents a later FinishedReceiving write. Required-send failures retain outbound diagnostics. The supplemental correction covers incomplete finalization gap notifications, Terminate replies, and a TCP wrapper returning an obsolete outer result after a callback ran Init and Step. Its controls include partial-write diagnostics and nested ConfigError preservation.

JNI transcript handling exposed an integration regression from the earlier C++ admin-observation correction (`35fc3ee28`). C++ observation hooks intentionally see valid high Session Rejects before sequence admission; JNI treated that observation as typed admission. A JNI-local guard checks the already-advanced inbound frontier before publishing ORDER_REJECT. It preserves C++'s observation contract and does not queue discarded high administrative payloads: admitted Rejects 2 and 5 are typed; high Reject 4 is never typed, including after its gap closes. Tests cover both timestamp policies, both high-sequence paths, PossDup suppression and sequences above 2^32. This restores the existing JNI contract; it does not settle the separate upstream ruling about retaining high Session Reject payloads across providers.

Java worker shutdown could race with a required administrative reply: the reply reached the socket before the accepted inbound sequence reached memory and the replay store, then stop or close retained a frontier one message behind. Worker TestRequest and ResendRequest dispatch now holds the existing writer through the durable inbound checkpoint. Recovery callbacks stay outside that writer, and the normal tail avoids repeating an unchanged checkpoint. A separate concurrent-close path could deadlock when a callback owned the socket writer while a foreign closer waited for it. A duplicate close from that callback now returns so the original closer can finish; ordinary foreign duplicate callers still wait for completed teardown.

The eighth patch fixes a standalone Cargo export fixture that already used an out-of-checkout target but bypassed the required `build_path` helper. The correction preserves the actual temporary path. The exact failing build-root guard and the standalone Cargo lockfile regression then passed, with no lockfile-test skip. The prior owner released that file claim in `5a63b952f` before this correction.

## Before-and-after proof

| Fixture | Baseline | Corrected |
| --- | --- | --- |
| C++ response ownership, 148 exact cases | 86 failed, 62 passed | 148 passed; ASan/UBSan/leak run also passed |
| Rust response lifecycle, 52 cases | 28 failed, 24 passed | 52 passed |
| Java permanent new FIXP cases, 72 | 40 failed, 32 passed | 72 passed |
| Java before-only stalled-response probes, 32 | 32 passed, documenting the stalled established state | Probe excluded from permanent source |
| .NET initial recovery/callback cases, 48, plus native guard | 28 failed, 21 passed | 49 passed, no skips |
| .NET supplemental finalization, 36, plus native guard | 24 failed, 13 passed | Combined initial/supplemental plus guard: 85 passed, no skips |
| JNI transcript admission, 8, plus native guard | 2 failed, 7 passed | 9 passed, no skips |
| Java deterministic admin retirement/reset and concurrent-close proof, plus native guard | 7 failed, 6 passed | 13 passed, no skips |

The C++ baseline's combined stdout/stderr interleaved one identity. The unchanged baseline binary was rerun with streams separated, verifying all 148 ordered identities; both logs are retained. Scratch Java instrumentation and probe classes were removed before production qualification.

## Completed qualification

C++ passed twelve existing relevant FIXP binaries in addition to the focused cases. Its official complete open-edition gate passed all 170 binaries, layering checks and simulator probes. Two multicast binaries explicitly skipped loopback packet delivery on this host; those skips are retained and do not establish packet-delivery coverage.

Both full Rust configurations, default and no-default-features, passed 2,063 cases across 36 executable/doc groups each, with one ignored doctest each. These runs used `RUST_TEST_THREADS=1` while a separate owner corrected an unrelated descriptor-reuse test race.

The local ten-stage qualification at `3884ccce3e4066c1c8e72372aaf7f40046d6175d` completed, including .NET development/open full suites, the final export scan and all-target Rust Clippy with warnings denied. The .NET development full suite passed 2,634 cases with two explicit skips: a hardware-dependent bypass NIC case and a pool case reserved for the separate two-thread execution. The open full suite passed 2,403 cases with the pool case skipped. Both separate pool executions passed all three cases; neither full execution required a retry. Open compilation used 144 public sources, excluded 67 private sources and passed six boundary refusal probes. All nine selected publication guards succeeded; conformance correctly reported PARTIAL because this selection was nine of 361 available stages.

The native-required Java qualification completed all thirteen stages: development/open builds, focused selections, default full suites, three special executions per edition, and the open boundary check.

| Java execution | Development | Open |
| --- | --- | --- |
| Focused selection | 475 passed, no skips | 471 passed, no skips |
| Full default suite | 6,852 passed, 3 skipped; 6,855 total | 6,381 passed, 3 skipped; 6,384 total |
| Mode-3 execution | 3 passed, no skips | 3 passed, no skips |
| Socket-idle execution | 12 passed, no skips | 12 passed, no skips |
| Telemetry-disabled execution | 3 passed, no skips | 3 passed, no skips |

Both full Java suites had zero failures/errors, and every identity from the original eight failures passed in both editions. The only full-suite skips were the three `HftTelemetryCountersDisabledTest` cases requiring `-Dlibhft.telemetryCounters=false`; all ran successfully in their matching dedicated executions. The open boundary check compiled 222 open sources without the 67 private sources. An earlier 302-case Java selection passed in managed-only mode and is not native coverage. The clean uninstrumented admin-retirement/concurrent-close selection also passed 173 cases with no skips.

The final Java verdict is `hp-java-corrected-frontier-inventory/complete.json`, SHA256 `db44fb0874464a944f9d3c638fe2466b1b8ef648d997159ca78d30221b067450`; `inventory-continuation/complete.json` records the adopted stages and completed continuation.

## Preserved failures and qualification limits

The original native-required Java development run completed 6,846 cases: 6,835 passed, eight failed and three telemetry-disabled cases skipped. Its failures were the JNI admission regression, five worker PossDup durable-frontier cases, one stopped-session provider parity case, and one steady-state allocation assertion. Sources, artifacts and failure identities remain preserved separately from corrected runs.

The allocation run placed JVM threads on isolated CPU 8. A controlled rerun on CPUs 0–7 passed both allocation cases and the native-required guard with identical source, compiled-class and native-library hashes. The two methods took 0.526 and 0.529 seconds; these are qualification timings, not engine latency measurements. Corrected full Java executions used that normal scheduling domain under both host CPU leases.

The first new permanent Java fixture run recorded 171 passes and two FileStore lock errors. Reset-enabled stop controls tried reopening a file before closing the session that intentionally still owned it. The fixture correction asserts the stopped frontier first, closes the session, then reopens the store for durable inspection. The clean 173-case run passed without changing the runtime candidate or replacing the successful deterministic before-and-after proof.

The first corrected full wrapper stopped after all twelve development socket-idle cases passed because its prepared inventory counted six methods without multiplying by two providers. That failed wrapper and successful XML are unchanged. A fresh continuation verified all twelve method/provider identities, native-required properties, matching XML/log totals and Maven exit zero, then copied the five completed development stage snapshots without rerunning them. A separate driver changed only the expected socket count from six to twelve and completed the remaining eight telemetry/open/boundary stages. No engine or test source changed for that inventory correction. Runtime failures, fixture ownership errors and wrapper inventory errors remain separate evidence; they are not erased or recounted as test passes.

An earlier sixteen-stage integration attempt was cancelled in its initial resource wait before any command executed. The later twenty-stage attempt at `31efdf32` completed only its architecture build and was stopped during the next resource wait before any test executed. Both attempts retain their original plans, logs and cancellation receipts.

## Source lineage and final import gate

The eight fixes were qualified through source-pinned runs and then rebased, unchanged, onto successive upstream commits. The consolidated integration candidate is `c1e4e2107cc4dc08595d3f22b681594eb4642d2f`, on `15bd9353500e138d368f6b9061ff0a52a5d39dd2`. Range-diff verifies all eight patches are identical in candidate `4a3774c51e5c78b383de63ed5c5616fc98643a0b`, on `684c492fdca2d27ae7ef49591c523a70c244af34`. Rebased commits are backed up on the private session branch.

The retained HP C++ input inventory contains 1,335 files matching local `3884ccce3`, and all 307 tracked C++ benchmark files match that HP base. Inspection of 167 generated open dependency files found no repository dependency outside `engine/cpp`. At `976664f2`, all 1,121 non-Chronicle inputs in the frozen HP Java context remained byte-identical. Broad HP Java qualification used base `d95d4afd42ffd0ae8449bc75db10f366ae3b48c6` plus the archived reviewed patch and file hashes. That exact 24-file source snapshot was archived before the owned HP checkout was normalized to clean c1. Input comparisons establish equivalence at those pins; they do not imply execution of later changed inputs.

The original local 25-stage integration run at c1 completed eleven stages: the three C++ controls and, in each Rust feature configuration, ownership 105, initiator 35, session 429 and Clippy. All cases passed with no ignores. It was stopped with exit143 in the resource wait before the first .NET native build, to move remaining work to HP. Its cancellation receipt retains the eleven-stage prefix; the original run is incomplete. Only its two Clippy stages are adopted into the final integration aggregate.

HP then executed the 23 non-Clippy stages. Its first thirteen stages passed. Development .NET test execution also succeeded, with 371 passes and one expected Linux SO_REUSEPORT skip, but the wrapper stopped because its plan expected 369 passes. The missing two were existing development-only partial-class facts, `Quickfix_store_mode_async_file_and_mmap_are_distinct` and `Explicit_mmap_store_durability_is_parsed_alongside_FileStoreSync`. Independent source and prior-full inventory review establishes exactly 372 identities, equal to the actual TRX. The open inventory remains 359. The original failed plan, result, raw inventory, TRX and failure record are unchanged. Since the validator stopped before writing the stage14 checkout receipt, the continuation explicitly records that absence and rechecks the clean c1 source and native/managed artifacts.

A fresh continuation validates the thirteen original successful stage receipts and independently revalidates stage14, then executes only original rows15–23. Its complete receipt covers those nine fresh stages only. The final aggregate is explicit: HP13 + revalidated14 + fresh9, plus the two adopted local Clippy stages. It does not relabel either original run as completed. The corrected canonical inventory changes only the development total370→372, Passed369→371 and SessionSettingsQuickFixTests class36→38.

| Consolidated integration portion | Coverage |
| --- | --- |
| C++ configuration build, architecture and schedule | Three stages; shared table27 rows/162 value-boundary probes |
| Rust default and no-default-features | Ownership105, initiator 35 and session 429 each; required empty-buffer recovery controls; Clippy warnings denied |
| .NET native builds and reuse-port units, both editions | Forced native builds at normal paths; TLS0/TLS1 outcomes retained |
| .NET selected/pool executions | Development371P1S, open358P1S; separate pool3P each |
| Java builds and selected executions, both editions | Forced JNI builds, exact414 cases each, zero skips, native guards |
| Publication/configuration guards and export scan | Thirteen selected conformance stages and engine export scan |

The remaining-nine continuation completed successfully. The independently validated aggregate is `evidence/composite-c1-verified/composite.json`, SHA256 `725be3bdc6c45498a79f11d823c7d65fef88ebec97c5a3fa030d610bdb1c1b17`, with 453 pinned evidence inputs. All thirteen selected guards ran; nested tests had zero skips, including the standalone Cargo lockfile case. Export scanned 50 engine files with zero findings. Original local plan SHA256 `0a28f727853b0dd4981edf121a155de98b301afca6b382384111a86140d4c972`; HP original manifest `5592cfb7b27d49b1d6b35651d54fe54af6673e37fca61a0bd6fbc582accdfa41`; remaining-nine manifest `6731302c990b55aa419a2def77884caaf8e1eb11fb5906e3dcc2a3304e771c65`. Evidence directories retain original cancellations and inventory failure alongside separate continuation receipts.

Later upstream imports include Java numeric-floor/schedule rulings and the shared table reader (`f1f4206ee`); .NET Pure local-clock timestamp checks (`498372155`, `ea555357b`); bounded .NET replay payload reads and store metadata (`9611ac185` and follow-ups); Rust config range alignment (`dae075f33`); and the four-reader table guard (`684c492fd`). At `4a3774c51e5c78b383de63ed5c5616fc98643a0b`, both new Clippy configurations passed with warnings denied (`local-post-import-clippy2-4a3774c5/complete.json`, SHA256 `869e3b779b887046b0bd3cb5758d0636034eee5504a055d8ad9f8a6bfc4f564d`).

The corresponding functional import execution passed Rust configuration41/network5/connect-lifecycle17 in each feature configuration (126 total), .NET development300 and .NET open270, all without failures or skips. Its wrappers stopped twice on accounting errors; the executions and failures are preserved separately:

- Three initial Rust cases printed diagnostics between their names and a standalone `ok`. The original single-line parser counted38 instead of41. Independent exact-name review and a corrected serial parser verified all41 raw outcomes. The parser rejects unfinished cases, orphan outcomes, failures and explicit skips; eleven scratch parser controls passed.
- The later open .NET selection expected295 because it mistakenly included25 development-only `ManagedSessionResetEpochTests` mmap rows. `MmapStoreRowAttribute` supplies no row when the open edition excludes the durable-store provider. All25 file-store rows exist and passed; the other selected classes also match. Exactly270 applicable case identities passed, with no skipped cases.

Qualification is an explicit eight-stage prefix: revalidated original Rust configuration stage, six successful continuation stages, and separately revalidated open .NET stage. Neither failed wrapper is presented as a completed full run. Their unexecuted Java/guard/export suffix is not credited. The separate prefix qualification receipt is `evidence/import-prefix8-verified/qualification.json`, SHA256 `2d4c218eb2a238154cd765c79621d8a299dd82911d01f1a30c80b241c9eb57db`. The .NET prefix includes native QuickFIX/configuration coverage using its recorded c1-built libraries; it is not a pure-managed-only run or execution with the later native libraries. The remaining Java config checks are included in the later rebuilt-native selection below.

Upstream `8e73c7f16` adds benchmark sources and retained evidence. Five public benchmark Python transitions affect the toolchain-resolver guard's scanned inputs; they require final-source guard coverage but do not change selected engine/runtime inputs. The exact source assessment enumerates the imports and their build/test consumers.

Upstream `b3a19f824` then changes requested listener reuse-port behavior in C++: TLS listeners retain/apply the request, unavailable platforms refuse it, and TCPDirect refuses unsupported sharing. The TLS and TCPDirect objects gain members, so JNI and hftnet require rebuilding despite unchanged exported C ABI declarations. The prior four qualified native libraries were copied and hash-verified into retained evidence before replacement. No Windows or VMA execution is claimed by this review.

Upstream `0eae8bab2` also enables .NET native TLS acceptors to honor the option, with actual shared-bind controls for both single- and multi-session native listeners. The final native gate at `82cc6b579` completed all25 stages. Six development and five open C++ binaries passed (TCPDirect fake support is pro-only), including all148 response-ownership cases in each edition, changed transport controls and reconnect control. Both JNI/hftnet editions were freshly compiled at their normal output paths, with loaded/copy hashes checked.

Java's exact189 cases per edition all passed with zero skips. These combine the previously unexecuted151 configuration checks with TLS, loopback, transcript admission, close/observer/stopped-read controls. The .NET native selections each passed44 cases with one explicitly expected Linux skip: `The_setting_refuses_the_start_where_the_option_cannot_be_set`, reason `Linux has SO_REUSEPORT`. The new actual native TLS shared-bind case passed. Both native reuse fixtures ran TLS0/TLS1; only TLS0 reports the two expected unavailable-TLS-listener diagnostics per edition. The TLS1 variants exercised shared TLS binds.

All four selected guards passed: shared numeric ranges, option matrix, tool-path rules and documentation facts. Conformance reported PARTIAL with exit2 because4 of362 available stages were selected; this is not a full conformance-suite pass. Nested guard inventories contain no skips. The final engine export scan exited0 with no findings. The complete receipt is `evidence/hp-native-331-82cc6b57/complete.json`, SHA256 `7a75115215009cde5a475dedaa3780af2bcc54418bc73aad45d7b2fa5335f131`. The frozen plan is `1e6503fb55507db24d07dd7d457145711c03579cce707939d0e3b5712bd233ab`, runner `e23912b5794a9e7ad817aa23c04628dbfa025090e0e1566bf9f6f3e8a87e7075`. Adding the private record and resolving coordination notes changes none of these selected inputs; the final manifest verifies that exact boundary.


## Evidence handling

Exact source hashes, named-case inventories, command vectors, native hashes, raw logs and XML/TRX reports are retained in session evidence, including every skip and its explicit supplement. The final archive destination is `~/archive/libhft/reviews/2026-10-12-codex-review-initiator-1012/final`; its qualification manifest and history bundle retain the tested and published revisions separately. HP C++/JNI qualification uses GCC 14, C++11, four compile jobs and one LTO job. hftnet uses its normal GCC 14 C++17/OpenSSL Makefile flags without an LTO claim. Earlier local C++ integration controls used GCC 15, C++11 and one LTO job, with at most sixteen make jobs. The final local supplements run Rust Clippy and publication tooling. Each host admits one heavy job through CPU-slot coordination and an additional process/memory check. Builds use `LIBHFT_BUILD_ROOT`; JNI and hftnet retain their normal native paths and native-required guards.

No engine latency benchmark or Windows validation is claimed. The changes repair recovery/lifecycle stalls and preserve diagnostics; the JNI guard adds a bounded sequence check only for Session Reject observation. Publication must retain the distinction between executed coverage, input equivalence, source inspection and intentionally skipped cases.
