fix(fires): detect acreage/containment growth, not just the fire-name set (#86)

The WFIGS adapter computed changed = (old event_id set != new event_id set),
so growth of an already-known fire produced changed=False. The store only runs
_ingest_fires (and the Phase-3 fire decider) when tick() reports a change, so
growth/update broadcasts for stable fires never fired — only brand-new or
dropped fire NAMES woke the path. Include acres + containment in the change
signature. The decider stays the broadcast gate (forward-only + cooldown), so
no backlog is dumped.

Co-authored-by: Matt Johnson <mj@k7zvx.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
malice 2026-07-07 11:26:05 -06:00 committed by GitHub
commit ceb95fb80e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -206,9 +206,26 @@ class NICFFiresAdapter:
new_events.append(event) new_events.append(event)
# Check if data changed # Change detection must reflect each fire's GROWTH, not just the set of
old_ids = {e["event_id"] for e in self._events} # fire names. Comparing event_id sets alone made acreage/containment growth
new_ids = {e["event_id"] for e in new_events} # of an already-known fire invisible: tick() returned False, so the store
# never re-ran _ingest_fires and the Phase-3 fire decider never saw the
# growth. Include acres + containment in the signature so a growing fire
# flips changed=True; the decider (forward-only + cooldown) stays the
# broadcast gate, so no backlog is dumped.
def _change_sig(e):
try:
acres = int(round(float(e.get("acres") or 0)))
except (TypeError, ValueError):
acres = 0
try:
pct = int(float(e.get("pct_contained") or 0))
except (TypeError, ValueError):
pct = 0
return (e["event_id"], acres, pct)
old_ids = {_change_sig(e) for e in self._events}
new_ids = {_change_sig(e) for e in new_events}
changed = old_ids != new_ids changed = old_ids != new_ids
self._events = new_events self._events = new_events