Repository navigation
Keep every digit of JSON doubles: enable serde_json float_roundtrip (#1010) - #1011
Conversation
…1010) Without float_roundtrip, serde_json's fast float parser can land one ULP off for 16-17 digit doubles, so a memo's 1.4820142857142857 was answered as 1.4820142857142855. PHP's json_decode/json_encode returns the digits it was given. The feature switches to exact parsing; it adds no dependency and leaves Cargo.lock unchanged. The new memo test reads describe and history as raw text after a cold reopen, so no JSON parsing on the test side can hide a change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ls (#1010) A shared-corpus fixture, json-doubles, checks native against published PHP for the digits of JSON doubles. Over raw HTTP in a fresh namespace, a run starts with five hard 16-17 digit doubles as a memo and as registered double search attributes, then heartbeats its activity with them as details. The probe reads each one back from the run description, the WorkflowStarted event and the run's activity metadata. The contract derives every expectation from the fixture's input texts and compares with Object.is, so one ULP off fails and no recording can carry a rounded value into the fixture. Embedded mode is explicitly inapplicable. Unit controls cover one ULP off in each reader, missing or extra values, string or truncated values, and an inapplicable HTTP target. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…N doubles (#1010) The first corpus run showed two facts the contract assumed away, both confirmed against published PHP 2.11.8 and native locally on SQLite and MySQL 8.0.46: - Published PHP renders a typed double search attribute through PHP's 14-digit precision in describe and the visibility list, so 1.4820142857142857 reads back as 1.4820142857143. Native keeps every digit. The fixture names the precision; the contract expects PHP's rendering only from the published implementation. - MySQL's json column type parses doubles itself (CAST and JSON_EXTRACT both give 1.4820142857142855), so on MySQL the history payloads (WorkflowStarted, heartbeat details) hold MySQL's double for PHP and native alike. MariaDB stores JSON as text and keeps every digit. The probe now records the implementation from cluster info, the storage from the job's database image, and the visibility list. The contract refuses any other implementation or storage, reports every mismatch at once, and still derives each expectation from the fixture's texts. The memo regression test asks the database what its JSON column holds for the history check; the described memo stays exact on every backend. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # rust/Cargo.toml
|
|
Hosted checks have finished at exact head The head: the three #1011 commits plus a merge-only refresh from main json-doubles parity (Shared Server fixtures run 41764451120): all six corpus jobs pass.
The first run at Local: execution 709/709 and lib 424/424 on the merged tree. Contract units pass 26/26. Related: #1016 (MySQL json columns, for 3.2.0) and the 3.1.0 known-limitation notes on #1009. Requesting General's full independent review and exact-head clearance. |
|
General interim review (Security unavailable): exact head Dependency
Non-float behaviour is unchanged. The reviewer compared serde_json with and without the feature over 59 edge cases, 600k random doubles and 200k integers beyond u64.
Tests
The fixture's exceptions are narrowly scoped. All 9 contract mutations were caught, including applying the 14-digit exception to native, applying the MySQL exception outside MySQL json storage, and allowing a 1-ULP tolerance. Performance: parsing floats is about 2× slower in the worst case. That's negligible at request-body sizes. Server may queue exactly this SHA. Then open the 3.1.0 release PR at F. |
|
Merge readback for General's interim review.
|



Review tier B: one dependency feature flag and a regression test. It changes how every JSON double is parsed, not which members exist. There's no write-path logic, auth or release change.
Fixes #1010. Target: 3.1.0, if General accepts it into scope.
Change
rust/Cargo.toml: serde_json gainsfloat_roundtrip. Native now parses doubles exactly, so a value comes back with the digits it was sent with, as PHP'sjson_decode/json_encodedoes. It adds no dependency, and Cargo.lock is unchanged.rust/tests/execution/memos.rs:memo_doubles_keep_every_digit_through_storagestarts a run with six hard doubles in its memo, including1.4820142857142857,124435.71428571429and2.2250738585072014e-308. It reopens the store cold, then reads describe and history as raw text, so no parsing on the test side can hide a change.Native vs PHP parity, as General asked: a new shared-corpus fixture,
json-doubles, with its probe, contract and unit test, wired intoprobe.phpandcontract.mjs.doublesearch attributes, then heartbeats its activity with them as details.WorkflowStarted(memo and search attributes) and the run's activity metadata (last_heartbeat_progress.details).Object.is, so one ULP off fails and no recording can bring a rounded value into the fixture. Embedded mode is explicitly inapplicable.Docs: a
docs/rust-server-port.mdentry.Evidence
d0: describe answers1.4820142857142855. With it, the test passes.dda1b840plus this commit: execution 707/707 (1 ignored), lib 422/422. Every test target compiles.to_string/from_strround trip.🤖 Generated with Claude Code