# Java and Philadelphia callback spans and JVM placement — 2026-10-14

Two separately named adapters now declare the same tick span:
`libhft-java-callback-canonical` and `philadelphia-fast-callback-canonical`.
Both start after SDK serialization at the prepared send boundary and end at the
public application callback entry, before caller extraction. Java binds that callback
byte for byte to its original inbound frame and waits for the actual callback before
consuming its raw view. Callback failures abort the caller even when the SDK would
otherwise fail open. Neither adapter borrows a pre-parser receive timestamp.

Both SDKs are unchanged. Builders preserve their exact source/JAR/launcher hashes,
JVM options and explicit callback selection. Default observer launcher bytes remain
unchanged; existing default/eager/NIO installations and source capsules stay immutable.
The portable generation controller separately admits the two new engine identities.

## Actual qualification and placement

The first complete stripped-source generation passes 24 actual localhost pairs:
twelve per engine, with the 5/0/5 warmup sequence on all four flows. Java passes 28
capture/numeric controls and 71 changed-evidence refusals; Philadelphia passes 269
controls and 53 refusals. There are no skipped engine branches or SDK changes.

The unmodified NIO-only follow-up on HP separately completes its twelve functional
pairs and all four tiny physical fixture/wire checks. Its tiny medians remain in the
12–50 ms range, so the recorded screening guard stops before more full deadline
failures. The earlier default physical failure and SCAN queue cancellation remain
in their earlier seals. This NIO-only result receives no report promotion.

A bounded thread diagnostic first fails because `jcmd` is absent from PATH; its
partial pair and cleanup are retained. A second uses the installed JDK's absolute
`jcmd` path and completes a 200-sample pair with the complete fixture audit. It has
no timing grade because stack capture is instrumentation. Its observed thread CPUs
show the Java polling and SDK reader threads sharing CPU 8 despite the wider endpoint
mask; the JVM service threads also occupy that CPU. No NIC-cause inference is made.

The optional `--thread-placement split` profile places the Java server polling and
SDK threads on separate inherited CPUs, with JVM service threads on the remaining
endpoint CPUs. Philadelphia and both initiators use one foreground CPU and separate
JVM service CPUs. Cold `taskset` operations affect only this JVM's task inventory;
all masks are checked back from the kernel, retained in `jvm-placement.json` and
independently checked by the callback auditor. No optional JNI placement library is
introduced or moved.

This second generation again passes all 24 actual pairs and 297 capture/numeric
checks. Its Java/Philadelphia cold readers refuse 75/57 alterations, including
changed kernel-placement evidence. The two functional generations retain 960 primary
samples, 960 delays and 2,800 application frames per peer in total.

## Full quiet local collection

HP then completes twelve full pairs per engine under a high-priority quiet lease:
1,000 warmup cycles, 10,000 measured samples, three runs and 10,000/s on every flow.
All original bodies, full typed owner folds, measured administration, callback bindings
and per-thread placement checks pass. The 24 pairs retain 240,000 primary samples,
240,000 scheduler delays and 660,000 application frames per peer.

Every timing row remains **S4 diag**. Java misses achieved rate on all four flows;
NOS also misses percentile stability. Philadelphia misses rate on NOS, mixed and tick;
MD misses stability, and NOS also misses stability. Delays remain below the configured
interval at p99. No failed flow has a ratio or Stage 5 award. Physical callback collection
and current matched Java admission remain open.

Both original SDK-free full replays pass. Relocated cold replay reproduces every
quantile, true extremum and blocker exactly, without compilation or new socket pairs.
The selected source capsules remain byte/mode unchanged and contain no engine,
internal or Git tree. They are explicitly working inventories; none is relabelled
as a clean Git source pin.

The [immutable seal](evidence/java-callback-canonical-20261014/retention-seal.json)
binds 4,207 original inputs / 398,407,294 bytes; SHA-256
`18a96e95606ff90449495d385d0f95e062c468b090a2feea2b69e7098b4aaca8`.
It retains both generations, all full originals, both diagnostics, the NIO-only HP
follow-up, complete source selections, launch/compile/check receipts and exact cold
proofs. Runtime products and SDK jars are independently hash-bound in the separate
product archives.
