meshai/work/meshai
Matt Johnson 5654faf29d fix(pipeline): let wildfire_spotting skip the grouper (category-scoped)
wildfire_spotting is the most urgent signal in the system (a fire
throwing embers past its own containment line), but every fire event
carries a group_key (= event_id), so the Grouper held spotting for the
full grouper_window_seconds (60s live) before it could even reach the
dispatcher -- a ~60s latency FLOOR, and ~120s+ once FirePacer queuing
is added on top.

Add a module-level _NEVER_COALESCE_CATEGORIES frozenset and bypass the
coalescing window for the categories in it. Currently: wildfire_spotting
only.

This is safe because spotting is already rate-limited AT THE SOURCE: a
per-fire 1h cooldown (adapter_config.fires.spotting_cooldown_seconds,
default 3600, latched on fires.last_spotting_broadcast_at per irwin_id
in gating/firms.py) gates spotting DETECTION itself, so N active fires
yield at most N spotting alerts per hour. FirePacer (60s interval, with
head-of-line ordering for immediate severity) and the dispatcher's
per-(toggle, category, region) cooldown still apply downstream.

The bypass is scoped by CATEGORY, never by severity. Commit 85d48ce3
deliberately removed a severity == "immediate" bypass from this exact
spot because ALL fire events carry _severity_override="immediate", so a
severity bypass exempts the entire fire family from rate control. The
comment on the constant spells that out so it does not get re-added.

Tests: spotting with a group_key passes straight through; wildfire_growth
and wildfire_incident at immediate severity are STILL held (proving no
severity bypass crept back in); spotting with no group_key still passes
through. PR #129's test_immediate_severity_is_also_coalesced_no_bypass is
untouched and still passes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 16:36:49 +00:00
..
adapter_config feat(adapters): WZDx daily work-zone summary + FIRMS restart-safe cold-start (#108) 2026-07-09 19:13:17 -06:00
backends refactor: move source tree into work/, multi-stage Docker build, fix satpass 2026-06-16 03:40:31 +00:00
central fix(firms): repair the FIRMS fire-fusion Event contract (issues #117-#119) (#120) 2026-07-11 17:41:40 -06:00
cli chore: remove legacy TUI configurator; surface last config gap in GUI (#45) 2026-07-05 16:21:32 -06:00
commands feat(phase4a): peak_compass end-to-end + repair stale satpass test suite (#35) 2026-07-05 01:06:29 -06:00
dashboard MeshCore: channel provisioning, key sharing, location-based recommendations & transport-aware identity (#113) 2026-07-10 23:30:57 -06:00
data refactor: move source tree into work/, multi-stage Docker build, fix satpass 2026-06-16 03:40:31 +00:00
env fix(fires): wire FirePacer into the native fire broadcast path (#123) 2026-07-11 21:46:13 -06:00
notifications fix(pipeline): let wildfire_spotting skip the grouper (category-scoped) 2026-07-14 16:36:49 +00:00
persistence feat(context): durable SQLite-backed retention for MeshContext observations (#114) 2026-07-11 02:20:16 -06:00
scripts refactor: move source tree into work/, multi-stage Docker build, fix satpass 2026-06-16 03:40:31 +00:00
sources refactor: move source tree into work/, multi-stage Docker build, fix satpass 2026-06-16 03:40:31 +00:00
transport MeshCore: channel provisioning, key sharing, location-based recommendations & transport-aware identity (#113) 2026-07-10 23:30:57 -06:00
__init__.py refactor: move source tree into work/, multi-stage Docker build, fix satpass 2026-06-16 03:40:31 +00:00
__main__.py refactor: move source tree into work/, multi-stage Docker build, fix satpass 2026-06-16 03:40:31 +00:00
alert_engine.py Phase A — 4-section nav; move Scheduled Broadcasts + Danger Zones off Routing (#15) 2026-07-03 14:57:24 -06:00
central_normalizer.py refactor: move source tree into work/, multi-stage Docker build, fix satpass 2026-06-16 03:40:31 +00:00
chunker.py feat(reply): cap interactive LLM replies to 3 mesh packets (#7) 2026-07-02 16:49:10 -06:00
config.py MeshCore: channel provisioning, key sharing, location-based recommendations & transport-aware identity (#113) 2026-07-10 23:30:57 -06:00
config_loader.py feat(generic): config-driven REST/GeoJSON source adapter (ported from Central) (#78) 2026-07-07 00:20:02 -06:00
connector.py feat(send-queue): jittered pacing (default 2.2-2.6s) per radio instead of fixed 2.0s (#95) 2026-07-08 11:12:28 -06:00
context.py feat(context): durable SQLite-backed retention for MeshContext observations (#114) 2026-07-11 02:20:16 -06:00
coverage.py feat(coverage): widen adapter fetch scope to the enclosing box of coverage areas (#71) 2026-07-06 12:51:54 -06:00
coverage_area.py feat(region-routing): tag satpass events by observer coordinates so they region-route; add satpass to VALID_TOGGLES (#90) 2026-07-07 21:43:49 -06:00
geo.py refactor: move source tree into work/, multi-stage Docker build, fix satpass 2026-06-16 03:40:31 +00:00
history.py refactor: move source tree into work/, multi-stage Docker build, fix satpass 2026-06-16 03:40:31 +00:00
knowledge.py refactor: move source tree into work/, multi-stage Docker build, fix satpass 2026-06-16 03:40:31 +00:00
main.py fix(fires): wire FirePacer into the native fire broadcast path (#123) 2026-07-11 21:46:13 -06:00
memory.py refactor: move source tree into work/, multi-stage Docker build, fix satpass 2026-06-16 03:40:31 +00:00
mesh_data_store.py refactor(danger-zones): drop min_severity + position_max_age; table snow (grayed/inert) 2026-06-21 06:56:22 +00:00
mesh_health.py refactor: move source tree into work/, multi-stage Docker build, fix satpass 2026-06-16 03:40:31 +00:00
mesh_models.py refactor: move source tree into work/, multi-stage Docker build, fix satpass 2026-06-16 03:40:31 +00:00
mesh_reporter.py refactor: move source tree into work/, multi-stage Docker build, fix satpass 2026-06-16 03:40:31 +00:00
mesh_sources.py refactor: move source tree into work/, multi-stage Docker build, fix satpass 2026-06-16 03:40:31 +00:00
meshmonitor.py refactor: move source tree into work/, multi-stage Docker build, fix satpass 2026-06-16 03:40:31 +00:00
responder.py feat(transport): per-radio serialized+paced outbound send queue (#93) 2026-07-08 09:38:08 -06:00
router.py MeshCore: channel provisioning, key sharing, location-based recommendations & transport-aware identity (#113) 2026-07-10 23:30:57 -06:00
secrets_store.py feat(meshcore): route MeshCore cells to room servers (open rooms) (#110) 2026-07-09 22:14:42 -06:00
serial_ports.py fix(serial): detect passed-through /dev USB-serial nodes (container GUI detect) (#53) 2026-07-05 23:01:08 -06:00