Root cause: several Cartagena old-city landmarks in the data had latitudes
~4 km too high (≈10.46°N instead of ≈10.42°N), dropping them out into the
Caribbean bay — that's why Day 2 stops 2–5 rendered in the water. The chat
model couldn't fix them because its web search couldn't surface valid
coordinates for those specific buildings, and it (correctly) refused to move
them to arbitrary guessed locations.
Also found the CTG (Rafael Núñez) airport was misplaced ~8 km east onto the
Bocagrande area ([10.4622,-75.4385]); the real airport is [10.4425,-75.5131].
This inflated the Day 1 arrival drop-off to 313 min.
Changes:
- data.js: re-anchor 6 old-city stops (S5, S7–S10, S20) + the C2 candidate to
verified on-land coordinates (all snap <21 m to the OSRM extract); fix the
CTG airport in the CTG→SMR flight stations and the S22 stop.
- app.js: correct AIRPORTS.ctg (used by the arrival transfer) to the real
airport. Add healCoordinates() so a plan saved before this fix (still holding
the old in-the-bay points in the browser's localStorage) is re-anchored to
the corrected source on load — stops re-sync by id, arrival/departure airports
re-derived from the AIRPORTS table. Idempotent; user-swapped stops (candidate
ids) are left alone. Verified with a CDP test that corrupts the saved plan
(6 stops + airport) and confirms a reload self-heals them back.
All regression suites pass: coords 6/6, drop-off leg 17/17, smoke 0 errors,
rail structure 13/13, dates 7/7.