• Measure real hibernate-to-completion time on the actual SBC/storage combination via a controlled, stationary test — the single biggest unknown in the current uncertainty budget (see Considerations).
• Find or create a genuine zero-speed/stationary wifi power-cycle baseline for the router (cold boot, not warm reassociation) to separate router reboot time from true neutral-section dead-time in future outage-duration analysis.
Apply the same multiple-trips treatment to any remaining candidates once repeated. The full-history analysis resolved RWB and found no corroborating Iver/Slough cluster: the two short Iver/Slough blips are separated geographically and remain rejected/low-priority. Only the unnamed ~51.485,-2.078 recurring candidate needs future repeat observations.
• Move the trigger condition from a fixed distance radius to time-to-section at current speed, once real hibernate-write timing is known (see Considerations, “Fixed radius vs time-to-section at speed”).
• NEW (found 2026-09-17): nothing restarts the hibernator after a reboot or crash. There is no systemd unit (system or user), no root cron entry, and nothing in john's crontab — the /2 * check-hibernate job is unrelated (it polls a note for an on-demand hibernate instruction). The script is started by hand. The consequence was visible in the 2026-08-17 incident: after the unclean power loss the machine came back with no neutral-section protection at all for 18m40s until manually restarted, passing any further sections unprotected. Deliberately NOT fixed with Restart=always — John does not want it running except on the train. His preferred approach, if this is ever picked up, is to let it always run but suppress itself by location (home, east of Paddington, or more than ~1 mile from the line). Design notes, the data available to build the corridor, and the pitfalls are in Considerations.
✓ RESOLVED 2026-09-17: the 2026-08-17 "SBC crashed rather than hibernating" incident was NOT a hibernator failure. Investigated from /home/john/hibernate-on-approach.log on pomelo. The log runs at its normal 5 s cadence and stops dead at 19:04:16 with no TRIGGER, no "hibernating" and no shutdown line, then resumes 18m40s later with a fresh starting — the signature of an unclean power loss, not a failed hibernate write. Hypothesis (b) was right: the last line reads nearest=Ruscombe / Twyford dist=10.70km armed=True — Maidenhead was still only a candidate that day and was not in the gazetteer, so the nearest section the hibernator knew of was 10.7 km away, far outside the 5 km radius. It was armed, polling and tracking correctly, and had no reason to act; three other hibernates succeeded normally that same evening. Already fixed by the 2026-09-05 promotion, now verified: the deployed gazetteer puts Maidenhead's westbound entry 2,046 m from where the machine died, well inside the radius, so the same journey today would trigger — with about 54 s of warning (first fix inside 5,000 m at 19:03:22, 4,868 m out, closing at ~52 m/s). Full detail in Findings.
⚠ Live bug (2026-08-17): SBC crashed rather than hibernating at the Maidenhead westbound drop. Second westbound observation of the Maidenhead candidate (c13 drop ~19:04:29–19:04:33+, ~51.515,-0.7385, matching the 2026-08-13 westbound drop at 51.5153,-0.7377). John reported the device crashed instead of completing a clean hibernate this time. Needs investigation: possibly the trigger fired too late for the write to finish (see Considerations, hibernate write time is still unmeasured), or the trigger wasn't armed for this point at all (same class of bug as the 2026-08-13 Twyford/Maidenhead mis-arm above) and the SBC just lost power uncleanly. Follow up once shell access to pomelo is available — check trigger logs for whether hibernate was attempted.
✓ 2026-09-05: Steventon/Milton gazetteer entry split into direction-aware brackets, per the proposal above. Replaced the single combined-midpoint row (51.6171,-1.2711) with two rows: eastbound entry (west-side boundary) 51.6169,-1.2654, and westbound entry (east-side boundary) 51.6182,-1.2729. Applied via sudo -u postgres psql on gravlax. Verified the deployed nearest_section query resolves each direction to its correct row. Royal Wootton Bassett still has only a westbound bracket (no eastbound data yet) so was left as a single point — not enough data for a direction-aware split there yet.
✓ 2026-09-05: Royal Wootton Bassett split into direction-aware brackets using a full-history wifi-drop analysis of all 44,033 location-db fixes (not just per-trip spot checks). This resolved the ‘eastbound entry still unknown’ gap noted above — clustering revealed the single approximate point (51.5416,-1.9045) sat between two tight, distinct clusters: eastbound entry 51.5475,-1.9296 (6-observation tight cluster, 42-64s, 2026-08-06 to 2026-09-02, within ~300m agreement) and westbound entry 51.5552,-1.9617 (7-observation tight cluster, 45-65s, 2026-08-03 to 2026-09-03, within ~150m agreement). Both are ~2-4km from the old single point. Applied via sudo -u postgres psql on gravlax; verified nearest_section resolves each test point correctly.
✓ 2026-09-05: Maidenhead promoted from candidate to confirmed and split into direction-aware brackets, using the same full-history wifi-drop analysis. Eastbound entry 51.5192,-0.7122 (9 observations, 2026-07-22 to 2026-09-02, 48-192s). Westbound entry 51.5100,-0.7537 (11 observations, 2026-07-13 to 2026-09-03, 40-84s). Both directions now well confirmed (20 total observations over ~2 months) — the previous westbound-confirmation gap is closed. Supersedes the single point 51.518,-0.724. Applied via sudo -u postgres psql on gravlax; verified nearest_section resolves correctly.
✓ 2026-09-05: Confirmed directly on pomelo, closing the 2026-07-30 unconfirmed-deploy item above. /home/john/bin/hibernate-on-approach.py was diffed byte-for-byte against the hibernate-on-approach repo and redeployed from it. Verified it is fully gazetteer-driven with no hardcoded Twyford/Maidenhead fallback list at all — that mechanism was removed entirely in the 2026-08-26 refactor, so the original concern (stale hardcoded list still live) cannot recur. Also verified passwordless sudo systemctl hibernate already works via the existing /etc/sudoers.d/50-john NOPASSWD:ALL rule, so the Running note prerequisites are fully satisfied.
✓ 2026-09-05: --help pointer added — hibernate-on-approach.py's argparse description now reads “Full docs: notes read hibernate-on-approach”. Deployed to ~/bin. Also fixed the two stale tests that were still asserting the old DB-with-static-fallback behavior (DEFAULT_NEUTRAL_SECTIONS, no-arg simulate_history) to match the current DB-only script — all 9 tests now pass (were 2 failing).
✓ 2026-09-05: Elizabeth line flag closed — checked location-db directly for the 2026-08-19 Whitechapel→Reading leg and the GWR leg from Reading. c13 never connects on either leg (saw GuestWL/VodafoneWiFi/mobile/#FreeStationWiFi instead, then a different SSID c9 near Bristol Parkway at 20:11), so there is no drop signal to assess and none of the established GWML detections could have fired that evening. See Findings for detail. The unexplained c9 SSID is a separate, low-priority loose end if it recurs.
✓ 2026-09-05: Aug 20 crash investigation closed from local logs. last -x shows pomelo remained in one continuous boot from 2026-08-19 08:00 through 2026-08-21 16:03, with no crash/reboot during the journey. /home/john/hibernate-on-approach.log shows four successful hibernate/resume cycles that morning (RWB 07:16, Steventon/Milton 07:39, old Ruscombe/Twyford 07:58, Airport Junction 08:09), followed by DB reconnects and continued monitoring. Conclusion: no computer crash occurred; the 2026-08-20 full-route c13 non-detection was not caused by a machine crash. The log also confirms the hibernator was still running the pre-2026-08-26 old trigger list at that time, which explains the obsolete section names in that historical log.
✓ 2026-09-05: Todo cleanup after full-history analysis and local-log review: removed superseded Steventon combined-row history, the old Ruscombe/Twyford trigger-move warning, and its duplicate deployment entry. The remaining open items are now physical measurements, Chipping Sodbury observations, the unresolved Aug 17 incident, and future candidate repeats.
• Geocode the unresolved WTT place names — probably the highest-value work available on this project. Only 63% of train_calls rows resolve to coordinates (937,996 of 1,494,642); the gap is junctions and passing points that are not stations (KENNET BRIDGE JN, HEATHROW AIRPORT JN and similar). That is why Airport Junction's nearest geocoded timetable point is 95 m away while Royal Wootton Bassett's is 14 km. Fixing it would put a booked passing time within a few hundred metres of every neutral section, which is what makes a timetable-driven trigger possible. Scope: 1,723 distinct unresolved names — tractable. John's suggestion (2026-09-17) is fuzzy matching, and yes it can be done in Postgres: pg_trgm 1.6 and fuzzystrmatch 1.1 are both available on gravlax, though not yet installed (CREATE EXTENSION). Match against the 2,606 uk-railway-stations rows and the wider naptan/geonames-GB sources already in the gazetteer. Expect to review the low-confidence matches by hand rather than trusting them — a junction wrongly matched to a similarly-named place elsewhere would put a phantom timing on the route.
• Method for the geocoding above, worked out 2026-09-17 — name similarity ALONE does not work. pg_trgm 1.6 and fuzzystrmatch 1.1 are now installed on gravlax's owntracks database (they were available but not created). Tested, and pure trigram matching fails badly: the best matches are similar-sounding places in entirely different parts of Britain — DIDCOT EAST JN → East Didsbury (Manchester), WOOTTON BASSETT JN → Wootton Wawen (Warwickshire), HEATHROW AIRPORT JN → Gatwick Airport. Matching against naptan (397,896 bus stops) is worse still; restricting to uk-railway-stations and stripping the JN/SDG suffixes helps but does not fix it.
• The missing ingredient is sequence context, and it is decisive. Every unresolved call sits between two resolved calls in the same journey, which bounds where it can be. Verified on WOOTTON BASSETT JN: across 40 journeys it appears only between SWINDON and CHIPPENHAM or BRISTOL PARKWAY, in both directions — which pins it to a few km of track and eliminates Wootton Wawen outright. Recipe: clean the name (strip JN, SDG, LC etc.), find the nearest resolved neighbours by seq within the journey, take their coordinates as a search region, fuzzy-match candidates within that region only, and score on name similarity plus geographic plausibility together. Review anything low-confidence by hand. Worth doing first for WOOTTON BASSETT JN specifically — that is the Royal Wootton Bassett neutral section, whose nearest geocoded timetable point is currently 14 km away at Kemble, the worst in the set.