# Scalar value review, 2026-10-18

Session: `codex-review-values-1018`, thread
`01a0fcb1-4c4d-7380-bb51-0d6ed4a2b4d6`, on BEELINK2. The user requested continued
deep correctness and latency review, fixes, parallel review agents, and regular
publication. All changes use the session's worktree; builds use its external build
root, one host CPU lease, and at most 16 build/test workers.

## Scope and findings

Parallel read-only reviews covered C++ `FixUtils.h` and scalar decimal kernels;
Java `MessageView`, `ScaledDecimal`, and scalar builder methods; .NET
`ScaledDecimal`, `FixTimestamp`, and adjacent scalar conversions; and Rust wire,
compact, view, and kernel scalar conversions. Three defects were reproduced and
fixed. An independent agent reviewed the patches and test assumptions before the
baseline run. C++ and .NET have no production changes in this batch.

1. Java `MessageView.getDateTimeMillis` and `sendingTimeMillis` ignored trailing
   bytes whenever the first byte after seconds was not a dot. For example,
   `20260626-12:00:00Z` returned `1782475200000` instead of the malformed sentinel
   `Long.MIN_VALUE`. The parser now requires a dot whenever a suffix exists. Tests
   cover both accessors with lengths 18 through 21 and longer, alongside accepted
   fractions. Existing short fractions, truncation after milliseconds, and the
   documented day-range leniency remain covered.
2. Java `ScaledDecimal.parseScaled(ByteBuffer, ...)` dereferenced a null buffer
   for a positive length. Its byte-array and CharSequence counterparts returned
   `FAIL`. The ByteBuffer overload now performs the same null guard. Controls cover
   heap/direct and read-only buffers, absolute offsets, limit refusal, and
   preservation of position, limit, and mark.
3. Rust's public `wire::Clock` selected a 17-byte timestamp for FIX 4.0/4.1 but
   always wrote 21 bytes. An exactly sized buffer panicked; a larger buffer had
   four bytes after the returned end overwritten. The public `put_field_time`
   helper inherited this behavior. The legacy branch now copies only the 17-byte
   cached prefix. Tests cover exact output sizes, nonzero offsets, untouched
   surrounding bytes, inherited widths, cached seconds, clock rollback, and
   switches between FIX versions. Modern 21-byte output is checked separately.

The Rust legacy branch also avoids calculating and writing unused milliseconds.
No throughput or end-to-end latency improvement is claimed: this batch establishes
correctness and removes that work by inspection, without a timing benchmark.

## Qualification

Baseline source: `ee68c3d28c89f34c86231128a6d35996020210cc` (new tests,
production unchanged). Java ran 65 tests: 63 passed, exactly one assertion failure
for ignored timestamp suffixes and one null-buffer exception, zero skips. Rust's
new nine-test boundary suite had the expected six failures and three passing
modern-width controls.

Initial fixed source: `fec5f9c489a9a994bb33460b754aa7ad0a1da1ce`.

| Selected checks | Development | Open |
| --- | ---: | ---: |
| Java scalar/view/builder suites, including the required native-library guard | 65 passed | 65 passed |
| Rust wire, message codec, compact and scalar kernel unit tests | 65 passed | 65 passed |
| Rust clock bounds, decimal bounds and replay timestamp integration tests | 19 passed | 19 passed |

The `tuned-timestamp-pairs` feature also passed all nine clock-boundary tests.
Every fixed run had zero failures, errors, skips, or ignored tests. Java's native
library was built through the normal Maven lifecycle and its required-load guard
passed in both editions. Open and development output roots were separate.

The broader `fix40_time_dictionary` test initially still used the removed dictionary
location. Its owner published the repair during qualification. After all initial
checks passed, this branch integrated the reviewed upstream commit
`04d085c915a64936fca81e95cdf2c20903a4601c`. At rebased source
`c1da0e061380e522a6acbcef2db1542f636d71ca`, all four Rust integration suites
(clock bounds, decimal bounds, replay timestamps, and legacy timestamp dictionaries)
passed **44 tests per edition**, with zero failures or ignored tests. The six files
changed by this review remained byte-identical across the rebase. The incoming
Rust changes were dictionary fixture bindings and test/lint corrections, reviewed
before incorporation. This closes the initially excluded legacy-dictionary check.

The driver checks expected baseline failure names/counts, all nine selected Java
suite names, native-guard execution, result presence, and failure/skip totals. Raw
JUnit reports, Rust logs, stage commands and source identities are archived. These
are targeted checks, not a claim that the whole repository suite was run.

The final publication rebase added only unrelated internal benchmark material;
all `engine/` bytes remained identical to the rebased qualified source. Final
code commit before this record: `e892ae23a77ed40c4df502a9bd5752cfbf8b4685`.
Export scan of all six changed engine paths: zero findings. Whitespace check:
clean. No timing benchmark was performed.

## Boundaries

The existing scale-preserving decimal parsers' conservative top-88 signed-integer
refusal is documented and pinned by shared vectors; it was not treated as a newly
found defect. No confirmed steady-state allocation problem was found in the
reviewed scalar paths. No session/configuration/transport behavior is changed.

An adjacent .NET dictionary observation remains outside this qualified batch:
UTCDATEONLY currently checks eight digits without month/day bounds. Other
languages' dictionary coverage and the documented basic-format contract need a
separate parity review before changing the shared validation policy. This is an
unqualified observation, not a measured defect or a completed fix.

## Evidence

Raw evidence is retained outside Git under
`~/archive/libhft/reviews/2026-10-18-codex-review-values-1018`, with a `SHA256SUMS`
manifest. It includes the qualification drivers and reviewed patches, baseline and
fixed reports, source equivalence proofs, the review's Git commits in a bundle,
and the final record. The bundle requires its recorded base commit, which remains
in main's history. No raw captures or build outputs are committed to this repository.
