From fcb24b9d3dbb6c6711e1bd587b236d70918735a5 Mon Sep 17 00:00:00 2001 From: malice Date: Sun, 5 Jul 2026 20:38:48 -0600 Subject: [PATCH] fix(roads511): stable external_id -> durably pre-seedable (belt + suspenders) (#51) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit roads511 emitted external_id=None, so it couldn't be durably pre-seeded from the persistent tables (only wzdx/usgs_quake were) — it relied solely on the in-memory first-poll seed. Thread a stable external_id="511_{itd_id}" through consistently so it joins the durable layer: - env/roads511.py: _parse_event raw event + to_event both carry external_id="511_{id}" (== event_id). Flips _seen_key to the ext: branch and makes the incident decider persist traffic_events(source='511', external_id) — which ALSO restores the decider's own dedup (external_id=None was the original roads511 leak cause). - env/store.py _seed_from_persistent: add a "511" spec (seed from traffic_events where source='511', by external_id) mirroring wzdx; shared _key_ext helper so keys can't drift. - consistency proven byte-identical (raw _seen_key == pre-seed key == 511\x1eext:511_{id}); durable-preseed + regression tests added. Live DB: 0 source='511' rows yet (flip recent) -> durability engages as native rows accumulate; layer-2 in-memory seed covers the interim (atomic fetch). Central-era itd_511 rows use a different keyspace, intentionally not covered. Suite at 10-failure baseline (1716 passed). Co-authored-by: Matt Johnson Co-authored-by: Claude Opus 4.8 (1M context) --- work/meshai/env/roads511.py | 15 ++++- work/meshai/env/store.py | 25 ++++++- work/tests/test_store_received_delta.py | 86 ++++++++++++++++++++++++- 3 files changed, 121 insertions(+), 5 deletions(-) diff --git a/work/meshai/env/roads511.py b/work/meshai/env/roads511.py index 90052ac..80e7af7 100644 --- a/work/meshai/env/roads511.py +++ b/work/meshai/env/roads511.py @@ -329,6 +329,12 @@ class Roads511Adapter: event = { "source": "511", "event_id": f"511_{event_id}", + # Stable ITD id, EQUAL to event_id. Threading it as external_id + # makes _seen_key use the ext: branch (511\x1eext:511_{id}) and + # lets the incident decider persist a matching + # traffic_events(source='511', external_id='511_{id}') row so the + # store's durable startup pre-seed can suppress this item. + "external_id": f"511_{event_id}", "event_type": event_type, "headline": headline, "description": description[:500] if description else "", @@ -398,8 +404,15 @@ class Roads511Adapter: _roadway = props.get("roadway") _desc = evt.get("description", "") or "" _is_closure = bool(props.get("is_closure")) + # Stable ITD id (the raw event carries the same value as its + # event_id). Threading it lets the incident decider persist a + # traffic_events(source='511', external_id='511_{id}') row that the + # store's durable pre-seed matches via _key_ext('511', external_id). + # NOTE: Central-era rows used source 'itd_511' with 'idaho_511:event:*' + # ids — a different keyspace the pre-seed intentionally does not cover. + _external_id = evt.get("external_id") or event_id canonical_data = { - "external_id": None, # native adapter, no Central dedup + "external_id": _external_id, # 511_{itd_id}; enables durable pre-seed "source": "511", "sub_type": "road_closed" if _is_closure else "incident", "road": _roadway or None, diff --git a/work/meshai/env/store.py b/work/meshai/env/store.py index a919953..b61f661 100644 --- a/work/meshai/env/store.py +++ b/work/meshai/env/store.py @@ -316,14 +316,26 @@ class EnvironmentalStore: USGS id (e.g. ``us6000t9bn``) and the quake decider persists it as ``quake_events.event_id`` verbatim → ``_key_eid('usgs_quake', id)`` matches exactly. + * ``roads511`` — the native 511 adapter now carries a stable + ``external_id`` (``511_{itd_id}``, EQUAL to its ``event_id``) on its + raw event and the incident decider persists it as + ``traffic_events(source='511', external_id='511_{itd_id}')``. Same + value on both sides → ``_key_ext('511', external_id)`` matches + exactly. Central-era rows used source ``itd_511`` with + ``idaho_511:event:*`` ids — a DIFFERENT keyspace this pre-seed does + NOT cover. On the first restart after this change there may be ~0 + ``source='511'`` rows yet; the layer-2 in-memory silent-first-poll + seed covers any Central-era backlog in the interim (safe because + roads511 fetches atomically per tick), and durability grows as + native ``source='511'`` rows accumulate. DELIBERATELY NOT seeded here (native emit key ≠ any persistent key — see the report; these stay protected by the in-memory first-poll + non-empty-seed guard, which is sufficient because each fetches atomically per tick rather than across ticks): - roads511 / traffic (persistent rows are Central-keyed: - itd_511/tomtom_incidents with idaho_511:event:* external_ids, but the - native adapters emit source '511'/'traffic' with derived event_ids), + traffic (persistent rows are Central-keyed: tomtom_incidents with + tomtom external_ids, but the native adapter emits source 'traffic' + with derived event_ids), fires (native ``nifc__`` vs persistent IRWIN GUID), firms (native ``firms____