# hp TLS completion and runtime freshness review

Four defects were reproduced before their fixes: a successful .NET TLS write could
be treated as a transport failure; freshness checks missed private runtime sources;
saturated smoke rows bypassed metric/stamp validation; and JNI builds missed local
header dependencies. These fixes do not add a lock. No latency improvement is claimed.

## Successful TLS completion race

`ManagedSession.Peer` checked `IsCompletedSuccessfully` before `IsCompleted` after
starting a direct or batched TLS write. A write that succeeded between those
observations fell through to the failure branch, disconnecting the session after
its frame had been written. This is a completion-order race, not concurrent
application calls to the peer.

The write paths now check completion first and consume the completed `ValueTask`
once through `GetAwaiter().GetResult()`. Pending writes retain their existing
buffer/admission contract. Faults and cancellation retain the disconnect policy.
The direct and batch drain paths also consume their completed result. This does
not wait for an incomplete write and adds no successful-path allocation.

`ManagedTlsWriteCompletionTests` exercises the actual peer send, batch and drain
paths with a controlled `SslStream` write source. Its first status read can return
pending and then make the write successful: the former two-observation race is
deterministic, without a scheduler-dependent sleep or a production injection hook.
The 14 cases cover that race, synchronous and pending success, fault and
cancellation, one-time result consumption and retained buffers.

All 14 failed before the fix and passed after it. The new cases, existing real TLS
tests and send-batch tests then passed together: 30 passed, none skipped. This is
not proof that the race caused the earlier five-second TLS timeout recorded in
[the managed/Rust validation record](RECORD_2026-10-02_hp-managed-rust-validation.md);
that incident did not capture the completion transition.

## Freshness checks after the edition split

`smoke-matrix.sh` now includes Java's `pro/src/main` and `venue/src/main` sources;
.NET's `pro/src/Libhft`, `venue/src/Libhft` and `Directory.Build.props`; and the
C++ venue headers used by native benchmark/JNI/.NET artifacts. The checks retain
their runtime-versus-test distinction and tolerate optional directories that are
absent in an exported edition.

Seven regression methods exercise the shell's actual check commands with
controlled timestamps. Before the patch, 13 subcases missed a changed private
source or build property. Afterward all seven methods passed. This is a
conservative source-directory freshness check, not an exact compiler dependency
graph.

## Saturated smoke-row admission

The row checker returned a passing result immediately for `SATURATED`, before
validating the four latency values or finding `bench_params` in the run logs.
Accepting saturation in a short functional check must not bypass those independent
requirements. Both accepted verdicts now reach the metric and stamp checks; a
valid saturated row retains its explicit qualification exception.

The new regression covers valid, malformed-metric and unstamped rows for both
verdicts. Before the fix, both malformed/unstamped saturated rows falsely passed;
afterward all six subcases passed. The full smoke preflight self-test passed all
eight methods.

## JNI local-header dependency

The Java native library target depended on its translation unit and C++ engine
headers, but not headers beside that translation unit. The new
`hftjava_edition.h` was therefore omitted. Edits to it could leave `make native`
reporting an old library as current. Local `.h` and `.hpp` files are now
prerequisites of the native library.

The existing JNI native-build self-test gains a fake-compiler regression. It
checks one initial link, an unchanged no-op, an isolated header-mtime change,
and another no-op, for each local header extension. It uses only its own temporary
fixture/output tree. Both header subcases failed before the fix and passed after
it. All four JNI build self-tests passed, including the existing PGO/BOLT dry runs.

## Completed validation

The post-rebase full .NET run passed 1,601 of 1,604 tests, with no failures. Its
three skips were the opt-in live bypass receiver, multicast loopback, and native
pool broadcast requiring multiple acceptor threads. The pool case then passed
separately with `LIBHFT_ACCEPTOR_THREADS=2`, without a skip. Skips are not hardware
coverage. The earlier full run passed 1,583 of 1,586 tests before further upstream
tests arrived.

The managed benchmark wrappers rebuilt both native libraries with TCPDirect and
VMA enabled and published the Java and four .NET bundles. Java passed 948 selected
tests in 30 current source classes, with no failures, errors or skips. This includes
both provider suites, required-native and allocation checks, and the FIXP, durable
store, high-availability, reset/frontier and telemetry cases affected by concurrent
upstream changes. It is focused coverage, not a new complete Java-suite run. The
collector requires a fresh XML report for each selected source class and excludes
older reports left in the build tree. The first, smaller filter passed 151 tests.

The combined build/harness checks passed 13 methods (eight smoke preflight, four
JNI build and one .NET publish-wrapper test). Export scans of the four changed
engine files reported zero findings.

Functional checks use `host-cpu-slot` in `isol` mode and may overlap shared-core
conformance work. They are not a quiet-host latency sitting. Java/.NET physical
NIC smoke still awaits installation through the password-gated staging helper;
no root installation or new hardware result is claimed here.

## Evidence and provenance

### Published-source refresh

All six review commits were published to main before the final integrated refresh
at `218d577a230177939651e652603ed2fa9cf5f7be`. Its targeted .NET run passed 31 tests;
the full run again passed 1,601 of 1,604, with the same three skips. The two-thread
pool case passed separately without a skip. Java's 30 selected current classes
again passed 948 tests, with no failures, errors or skips. The 13 build/harness
self-tests also passed. These results remain pinned to this revision; later main
changes are not covered by this sitting.

Both managed native libraries were refreshed with TCPDirect and VMA enabled. The
verified profile-free artifacts are:

```text
libhftjava.so  eefe4d465050f334f2d6943626f682851821dab833df3fb0a6cbffba7b012bf8
libhftnet.so   04af079b8d92c7e52d53f555e1f321c7faae11052289ebdb53a1e59d85f16273
```

The archive below retains `publication-refresh-218d577a2.log`,
`publication-refresh-218d577a2.json`, the 30 fresh XML reports in
`java-focused-218d577a2/`, and the 59-input `managed-stage-218d577a2.sha256` manifest.
The current staging manifest passed its hash check. Installation and managed
physical NIC tests still require the home helper's password-gated sudo step;
neither was performed during this refresh.

### Earlier verified snapshots

The first complete validation used
`58e84108eec235aa6e73bf23f71ce95bc878f93e`, before publication rebasing. It is retained
on `origin/s/codex-libhft-hp-tls-20261002`. Builds live under
`/home/yann/build/codex-libhft-hp/libhft`, not in a checkout.

The post-rebase refresh used `cccaeb811f653fe995884b08e2187bd3560ea6e9`, retained
on `origin/s/codex-libhft-hp-verified-cccaeb811`. Both native libraries are
profile-free functional builds, not artifacts from a tuned latency sitting.

Evidence is retained under `~/archive/libhft/tls-completion-20261002/`:

- `tls-completion-red.log` and `tls-completion-green.log`;
- `private-freshness-red.log` and the before-fix shell/fixture copies in
  `freshness-before/`;
- `managed-refresh-58e84108e.log` and its focused Java XML reports in
  `java-focused-58e84108e/`;
- `smoke-row-red.log`, `jni-dependency-red.log` and their before-fix fixture trees;
- `managed-refresh-cccaeb811.log`, `managed-refresh-cccaeb811.json` and the 30
  current Java reports in `java-focused-cccaeb811/`.

The home staging helper is `~/stage-libhft-managed.sh`. A SHA256 manifest is generated
only after the selected suites pass and all native aliases match their current
library. Any further artifact change invalidates that manifest. Earlier manifests
are retained as evidence, not reused to authorize different artifacts. Installation
preserves the previous managed trees and configuration, and moves the two obsolete
Java jars into that backup instead of deleting them.
