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____