# Native .NET monotonic handler clock qualification

## Separate public delivery endpoint

The opt-in `libhft-dotnet-native-handler-canonical` producer uses a single
process-local monotonic `Stopwatch.GetTimestamp` domain with exact integer
nanosecond conversion. Tick starts immediately before the public flush of an
already serialized native send batch. Its end is stamped immediately after
public `NativeSession.PollMessage` returns, before constructing a managed
message view, matching a marker or extracting business fields. This is the
public polling handler delivery boundary; the SDK deliberately uses polling
rather than per-message reverse P/Invoke callbacks. RTT ends after the final
required parsing, extraction, sink folding and checks.

The original `libhft-dotnet-native` profile keeps its UTC/native receive
endpoint and identity. No SDK/native patch, implicit runtime switch or
historical promotion is made. The new compact flavour is
`dotnet-native+handler+complete-rtt` under the existing bounded-capture method.
The physical collector, independent reader and writer select this producer's
actual `samples.hftbrw` filename. Different raw filenames cannot supply its
proof. The writer verifies its public handler/transport/store identity and
requires complete cold report admission before reading samples or emitting
a cell. The default legacy Native profile remains unsupported by that writer.

## Actual qualification on both hosts

Both hosts build the 903-file stripped harness without an engine tree,
private tree or Git metadata. The build uses SDK 10.0.112, target net8.0 and
the existing matching SDK/native input; installed net8 runtime is 8.0.31.
MSBuild is limited to two jobs, with build servers/shared compilation off and
all outputs below the session build root. Each build has zero warnings and
zero errors. HP uses a high-priority `isol` lease and SCAN normal `isol`;
these functional diagnostics have no timing grade.

| Profile | Actual pairs per host | Independent corruption refusals per host |
|---|---:|---:|
| Original UTC receive | 12 | 73 |
| New monotonic handler | 12 | 97 |
| New handler with 2 ms boundary probe | 12 | 28 |

Across both hosts this is 72 actual pairs and 396 refusals, without skips.
Each profile completes all four flows with warmup 5, 0 and 5: 240 primary
samples, 240 delay samples and 1,000 application frames per peer per host.
Four independent C# owner/body vectors match the common specification.
Application capture contains only the first ten cycles and closes before
warmup; measured capture is zero.

The probe delays the actual inbound native observer path before public
polling delivery, then delays the required owner extraction. Its retained
checkpoints prove that RTT includes both regions and tick selects handler
entry before later extraction. Every raw sample exactly equals the selected
checkpoint difference. A wrong selected endpoint, altered raw/trace value,
missing trace, short delay, wrong probe or timing promotion is refused. Normal
runs have integer-zero probe, no trace and no per-sample trace allocations.

All 935 focused preflight, clock, runtime, compact writer, report gate,
comparison, queue and status controls pass with zero skips. The selected
source export has zero closure and scrub findings; this is source/functional
qualification, not a whole-harness release qualification.

## Immutable identities and retained correction

- Qualified source pin: `70c2c85ba4c5623504d64e9cca70f69145994386`.
- Complete source inventory SHA-256:
  `f9536ba865f16852b78657d2a912dc0314ba7ba585385b9223c72ecf8d8b4f53`.
- Driver DLL, identical on both hosts:
  `5162e8cd8eb9f36e461a8b6c0d76631d5bb2a638aa239c6842945413bcdc129b`.
- Existing native library:
  `91bdc88f8cd2d375262daafdc233ce2b16bc49e8fcae0789da12af999c737dc9`.
- Unpatched SDK content pin:
  `uncommitted-functional-source-26310f12584fd0f392af231da8c2ea10067f50bb337db118cc79a2895da54386`.

Every source and SDK byte/mode and the native library remain unchanged.
The final private wrapper initially replaced the executable's `.Bench`
suffix with `.dll` instead of appending `.dll`. This happened after all
36 pairs and 198 cold controls had already passed on each host. An independent
read-only finalizer verifies the original complete manifests, exit codes,
runtime hashes and source/SDK inventories and writes the final receipt.
No pair or cold replay is repeated. Original failed wrapper output remains.

Original source and working roots on both hosts:

- `~/.cache/libhft/fullbench-dotnet-native-handler-20261017-v1`
- `~/build/codex-fullbench/libhft/dotnet-native-handler-20261017-v1`

Fresh physical collection, report timing gates and a matched .NET peer
comparison remain open. The unchanged generic data-only installer and fixed
normal-user namespace entry support the new reviewed engine identity; no
new sudo registration or root-helper change is needed. No raw capture,
sample stream, runtime log or source tarball enters Git or a new archive.
