v0.5.13 default-deny was silently dropping every FIRMS hotspot because no
per-adapter handler existed. firms_pixels table has been empty since v0.5.8b.
This commit adds central/firms_handler.py which stores every passing pixel
that clears the (currently hardcoded, future GUI-driven) confidence + FRP
floors, with dedup on (round(lat,5), round(lon,5), acq_time, satellite) via
a unique partial index added in v4.sql. NO mesh broadcasts emitted by this
handler -- FIRMS data is for LLM context only and will become queryable
when commit #5 (env_reporter) lands.
Defaults baked in:
FIRMS_CONFIDENCE_FLOOR = "low" -- store every confidence level
FIRMS_FRP_FLOOR = 0.0 -- store every FRP value
FIRMS_BBOX_OPTIONAL = None -- no spatial filter
These become adapter_config GUI rows in commit #3 (per Matt's v0.6 Phase 1
refinement: hardcoded values become GUI default values so first-deploy
behavior is unchanged).
Wiring:
- meshai/central/firms_handler.py (new, 270 lines)
- meshai/persistence/migrations/v4.sql (new, unique dedup index)
- meshai/persistence/db.py (SCHEMA_VERSION 3 -> 4)
- meshai/central/consumer.py (dispatch ladder gets firms branch before
default-deny clause; pattern matches handle_swpc / handle_nwis)
- tests/test_firms_handler.py (new, 22 tests covering confidence floor,
FRP floor, bbox, dedup, missing fields, end-to-end through consumer)
- tests/test_consumer_default_deny.py (swap firms -> avalanche for the
"no handler" examples since FIRMS now has one)
Test count: 658 -> 680 (+22 firms_handler tests, 0 regressions).
Refs audit doc v0.6-phase1-audit.md finding #2.