Finding
ConnectionTrace.sessionHeldSuffix/1 is a declared Swift/Kotlin byte contract, but native formatting disagrees at millisecond values that land on a tenth-second half-tie.
Machine-readable native reproduction:
| millis |
Swift |
Kotlin |
| 50 |
after 0.0s |
after 0.1s |
| 150 |
after 0.2s |
after 0.2s |
| 250 |
after 0.2s |
after 0.3s |
The fresh differential pilot therefore fails session_held_half_tie at 50 ms. This is not harness normalization noise: Swift calls Foundation String(format: "%.1f", ...); Android calls Java/Kotlin "%.1f".format(...), and the native runtimes select different half-tie results.
Reachability and impact
The helper is public on both platforms and is used by both live disconnect emitters:
- Swift
BLEManager appends it to connect down (uptime ends...) while Connection Test Mode is active.
- Android
WhoopBleClient appends it to the corresponding live log line.
This changes diagnostic text by 0.1 seconds only; it does not affect reconnect behavior, storage, or user health data. Severity is bounded P2 parity contract / P3-low operational. Exact half-ties are possible because both callsites derive integer milliseconds, although typical sessions last much longer.
RED / acceptance
Add mirrored public tests for at least 50, 150, and 250 ms and require byte-identical output under an explicit canonical rounding policy. Preserve existing contracts:
- negative millis => empty suffix (unknown session start)
- zero =>
after 0.0s
- ordinary 432/6800/120000 ms outputs unchanged
- locale remains fixed to a decimal point
The parity harness must then pass the complete curated Readout corpus without an exemption or output normalization.
Provenance / routing
The helper originated in upstream PR ryanbr#1023 for issue ryanbr#1020. That PR tested ordinary tenth-second values but not half-ties. Duplicate searches across open/closed issues and PRs in both ryanbr/noop and bhelm/noop found no existing rounding report or fix.
Fix routing: upstream-only production PR against ryanbr/noop; do not patch production only in the fork.
Finding
ConnectionTrace.sessionHeldSuffix/1is a declared Swift/Kotlin byte contract, but native formatting disagrees at millisecond values that land on a tenth-second half-tie.Machine-readable native reproduction:
after 0.0safter 0.1safter 0.2safter 0.2safter 0.2safter 0.3sThe fresh differential pilot therefore fails
session_held_half_tieat 50 ms. This is not harness normalization noise: Swift calls FoundationString(format: "%.1f", ...); Android calls Java/Kotlin"%.1f".format(...), and the native runtimes select different half-tie results.Reachability and impact
The helper is public on both platforms and is used by both live disconnect emitters:
BLEManagerappends it toconnect down (uptime ends...)while Connection Test Mode is active.WhoopBleClientappends it to the corresponding live log line.This changes diagnostic text by 0.1 seconds only; it does not affect reconnect behavior, storage, or user health data. Severity is bounded P2 parity contract / P3-low operational. Exact half-ties are possible because both callsites derive integer milliseconds, although typical sessions last much longer.
RED / acceptance
Add mirrored public tests for at least 50, 150, and 250 ms and require byte-identical output under an explicit canonical rounding policy. Preserve existing contracts:
after 0.0sThe parity harness must then pass the complete curated Readout corpus without an exemption or output normalization.
Provenance / routing
The helper originated in upstream PR ryanbr#1023 for issue ryanbr#1020. That PR tested ordinary tenth-second values but not half-ties. Duplicate searches across open/closed issues and PRs in both
ryanbr/noopandbhelm/noopfound no existing rounding report or fix.Fix routing: upstream-only production PR against
ryanbr/noop; do not patch production only in the fork.