Chain pre-flight: diagnosis bypassed
- At: 2026-05-29T06:27:26Z by /idd-all-chain
- User choice: proceed anyway despite no separate diagnosis comment
- Rationale: issue body already contains root cause (raw Double → JSONSerialization 17-sig-digit rendering) + fix strategy (round to 6 dp) + the 4 affected executors. Spec is not vague; the chain's internal idd-diagnose has a concrete target.
Problem
Original text (from test-coverage session, 2026-05-28):
「executor 把 lat/lon 用 raw Double 丟給 JSONSerialization,25.04 會渲染成 25.039999999999999(IEEE-754 noise),影響所有吐座標的 executor(bus/bike/traffic/parking)。對 LLM 消費無害(它會 round),但不乾淨。真要修是在 executor 把座標 round 到 ~6 位小數(≈0.1m,遠夠交通用)。已在 d49eecb commit message + 測試註解記錄,留待未來 polish。」
Geo-emitting executors build their output dictionaries with raw Double
latitude/longitude values and hand them to JSONSerialization. Because
25.04 is not exactly representable in IEEE-754 binary64, the serializer
emits the full 17-significant-digit form 25.039999999999999 rather than
the clean 25.04 the source TDX data implies.
Confirmed empirically during the test-coverage work (commit d49eecb):
JSONSerialization.data(withJSONObject: ["lat": 25.04, "lon": 121.56])
=> {"lat":25.039999999999999,"lon":121.56}
(Note 121.56 happens to render cleanly — representability is value-dependent,
so the noise appears unpredictably across coordinates.)
Type
refactor (output is numerically correct, just not clean — no functional bug)
Expected
Coordinate fields in tool output render at a sane precision, e.g.
"lat":25.04, with no 17-digit float tail.
Actual
Coordinates render with IEEE-754 noise, e.g. "lat":25.039999999999999,
whenever the value is not exactly representable in binary64.
Affected executors
Every executor that emits lat / lon (or nested position) from a
RailPosition-shaped Double pair:
bus_status_positions — BusLivePosition.busPosition
bike_search_stations / bike_stations_nearby — station StationPosition
traffic_cctv — CCTV Position
parking_list_lots — CarParkPosition
Impact
Cosmetic. An LLM consuming the JSON rounds it when presenting to the user,
so end-user-visible behavior is unaffected. The noise is just ugly in the
raw tool output and in any logging / debugging that inspects it.
Suggested fix
Round coordinates to ~6 decimal places (about 0.1 m, far finer than any
transit use needs) before they enter the output dictionary. Options:
- A small helper
roundCoord(_ d: Double) -> Double { (d * 1e6).rounded() / 1e6 }
applied at each dict["lat"] = ... / dict["lon"] = ... site.
- A shared output-assembly helper that all geo-emitting executors call,
centralizing the rounding in one place.
Option 2 is preferable if the rounding is the only shared concern; option 1
if a shared helper would be over-abstraction for four call sites.
Provenance
Documented in commit d49eecb (executor test coverage) message + the
testBusStatusPositionsAssemblesPositions test note, which asserts on the
stable leading digits ("lat":25.0) precisely because of this noise.
Chain pre-flight: diagnosis bypassed
Problem
Geo-emitting executors build their output dictionaries with raw
Doublelatitude/longitude values and hand them to
JSONSerialization. Because25.04is not exactly representable in IEEE-754 binary64, the serializeremits the full 17-significant-digit form
25.039999999999999rather thanthe clean
25.04the source TDX data implies.Confirmed empirically during the test-coverage work (commit
d49eecb):(Note
121.56happens to render cleanly — representability is value-dependent,so the noise appears unpredictably across coordinates.)
Type
refactor (output is numerically correct, just not clean — no functional bug)
Expected
Coordinate fields in tool output render at a sane precision, e.g.
"lat":25.04, with no 17-digit float tail.Actual
Coordinates render with IEEE-754 noise, e.g.
"lat":25.039999999999999,whenever the value is not exactly representable in binary64.
Affected executors
Every executor that emits
lat/lon(or nested position) from aRailPosition-shaped Double pair:bus_status_positions—BusLivePosition.busPositionbike_search_stations/bike_stations_nearby— stationStationPositiontraffic_cctv— CCTVPositionparking_list_lots—CarParkPositionImpact
Cosmetic. An LLM consuming the JSON rounds it when presenting to the user,
so end-user-visible behavior is unaffected. The noise is just ugly in the
raw tool output and in any logging / debugging that inspects it.
Suggested fix
Round coordinates to ~6 decimal places (about 0.1 m, far finer than any
transit use needs) before they enter the output dictionary. Options:
roundCoord(_ d: Double) -> Double { (d * 1e6).rounded() / 1e6 }applied at each
dict["lat"] = .../dict["lon"] = ...site.centralizing the rounding in one place.
Option 2 is preferable if the rounding is the only shared concern; option 1
if a shared helper would be over-abstraction for four call sites.
Provenance
Documented in commit
d49eecb(executor test coverage) message + thetestBusStatusPositionsAssemblesPositionstest note, which asserts on thestable leading digits (
"lat":25.0) precisely because of this noise.