chore(central-ripout 2d-i): relocate the fire engine + renderer out of central/

Moves the last two live files out of the retired-Central folder. central/ is
now EMPTY and deleted entirely (incl. __init__.py).

- fire-fusion engine (ingest_hotspot_pixel + the growth/cluster/spotting
  engine) → env/fire_fusion.py, next to its sole consumer env/firms.py.
- wildfire text renderer (_render + its live helpers) → env/fire_render.py.

THE COUPLING RESOLVED: firms_handler._handle_pass_boundary had a LAZY import
inside a function body — `from meshai.central.wfigs_handler import _render` —
sitting on the live FIRMS fire-growth path. It is now a normal top-of-file
import (`from meshai.env.fire_render import _render`), visible and greppable.

PURE MOVE — no behavior change:
- The parity oracle (test_fire_refactor.py) PASSES UNCHANGED (only its import
  paths updated) — proving the fire wire output is byte-for-byte identical
  before and after. Fire alerts say exactly what they said.
- handle_firms / handle_wfigs (dead entrypoints, only caller was the deleted
  consumer.py) were KEPT and moved rather than dropped — the wording-cleanup
  PR removes them deliberately. "When unsure, keep."
- fire_render.py's geo-helper imports still point at central_normalizer — that
  file's split is a SEPARATE PR; carried the imports along, did not touch it.

Consumers + test import paths rewired. Full suite: 2059 passed, 0 failed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Matt Johnson 2026-07-17 22:27:08 +00:00
commit 1ffde64c3c
19 changed files with 97 additions and 72 deletions

View file

@ -1,8 +0,0 @@
"""Central connector package (v0.4) — historically consumed Central's NATS
JetStream firehose and normalized it into meshai pipeline Events. The NATS
consumer is retired (Central is gone); this package now only holds the
split-file modules still used by the native adapter paths (firms_handler,
wfigs_handler _render). The satellite pieces (satpass_handler, tle_handler,
pass_predictor) have moved to meshai.env.satellite, and the gauge-site
lookups have moved to meshai.env.gauge_sites they're feed-adapter support
code, not consumer leftovers."""

View file

@ -1,5 +1,15 @@
"""v0.7-fire-tracker-3 FIRMS handler -- storage + attribution + cluster + growth/halt/spotting.
Relocated from `meshai.central.firms_handler` during the Central ripout
(central/ handler retirement, chore/ripout-2d). ``ingest_hotspot_pixel`` is
the LIVE fire-fusion engine with one consumer: the native FIRMS adapter
(`meshai.env.firms` -> `_run_fusion`). ``handle_firms`` (the Central
NATS-envelope entrypoint) has no live production caller -- Central's
consumer that drove it is gone -- but it remains the parity-tested legacy
contract (see `tests/test_firms_handler.py`, `tests/test_firms_refactor.py`,
`tests/test_fire_tracker_phase1/2/3.py`) -- kept verbatim, not deleted, per
that coverage.
Pre-v0.6-1 the v0.5.13 default-deny gate at consumer._normalize() silently
dropped every `central.fire.hotspot.>` envelope because no per-adapter handler
existed (audit doc v0.6-phase1-audit.md finding #2). The `firms_pixels`
@ -70,6 +80,7 @@ from datetime import datetime, timezone
from typing import Any, Optional
from meshai.persistence import get_db
from meshai.env.fire_render import _render
logger = logging.getLogger(__name__)
@ -919,7 +930,6 @@ def _handle_pass_boundary(conn, *, irwin_id, pass_id, lat, lon,
if fire is None:
return None
from meshai.central.wfigs_handler import _render
movement = {"direction": drift_direction, "speed_mph": drift_mi_per_hour or 0.0}
normalized = dict(fire)
normalized["irwin_id"] = irwin_id
@ -948,7 +958,14 @@ def _handle_pass_boundary(conn, *, irwin_id, pass_id, lat, lon,
def _render_growth_wire(*, incident_name, direction, speed_mph,
lat, lon):
"""Per design doc section 4 + Phase 2 spec item 3."""
"""Per design doc section 4 + Phase 2 spec item 3.
NOTE: unreferenced (verified via repo-wide rg during the chore/ripout-2d
relocation -- zero callers in source or tests). `_handle_pass_boundary`
renders growth wires via the WFIGS `_render` instead. Left in place
(moved verbatim, not deleted) since dropping dead code is out of scope
for this pure-move PR.
"""
near_part = ""
try:
from meshai.central_normalizer import nearest_town

View file

@ -1,5 +1,15 @@
"""WFIGS handler: persistence-backed change-detection + wire renderer.
Relocated from `meshai.central.wfigs_handler` during the Central ripout
(central/ handler retirement, chore/ripout-2d). ``handle_wfigs`` has no live
production caller (Central's NATS consumer that drove it is gone), but it
remains the parity-tested legacy contract for the WFIGS wildfire wire format
(see `tests/test_fire_refactor.py`, `tests/test_wfigs_handler.py`) -- kept
verbatim, not deleted, per that oracle. ``_render`` IS live: it is imported
by `meshai.env.fire_fusion._handle_pass_boundary` on the FIRMS growth path
(`env/firms.py` -> `ingest_hotspot_pixel` -> ... -> `_handle_pass_boundary`
-> `_render`) to render the `wildfire_growth` wire.
v0.5.8b refactor: New: vs Update: decision now keys on `last_broadcast_at`,
not on row existence. Cold-start scenarios where the dispatcher drops the
broadcast (cold-start grace, stale filter, cooldown, dedup) leave the fires
@ -469,7 +479,7 @@ def _render(n: dict, *, prefix: str = "",
lines: list[str] = []
# Line 1: header
lines.append(f"🔥 {name} \u2014 {prefix}")
lines.append(f"🔥 {name} {prefix}")
# Line 2: size / containment with delta (plain text -- no bold markdown).
acres_str = f"{int(acres):,} ac" if acres is not None else "size unknown"

View file

@ -138,7 +138,7 @@ class FIRMSAdapter:
new_events = self._parse_csv(csv_data)
# Feed every fetched pixel into the SHARED source-agnostic fusion engine
# (central.firms_handler.ingest_hotspot_pixel): attribution + growth /
# (env.fire_fusion.ingest_hotspot_pixel): attribution + growth /
# spotting / halt. DB-level dedup (firms_pixels unique key) makes this
# idempotent across ticks, so re-fetched pixels never double-count.
# NEVER broadcasts raw hotspots -- only the fusion wires it returns.
@ -422,14 +422,14 @@ class FIRMSAdapter:
engine and collect the fire-fusion broadcasts.
Every parsed pixel is mapped to the canonical FIRMS schema and passed to
``central.firms_handler.ingest_hotspot_pixel`` -- the exact same engine
``env.fire_fusion.ingest_hotspot_pixel`` -- the exact same engine
the Central NATS handler drives. The engine INSERTs the pixel, runs
attribution, and runs the growth / spotting / halt fusion; it returns
ONLY fusion wires (never a raw-hotspot / cluster broadcast). DB-level
dedup makes re-fetched pixels no-ops, so nothing double-counts.
"""
try:
from meshai.central.firms_handler import (
from meshai.env.fire_fusion import (
ingest_hotspot_pixel, _parse_acq_epoch,
)
except Exception:

View file

@ -10,7 +10,7 @@ import time
import pytest
import meshai.notifications.clock as clock_mod
import meshai.central.wfigs_handler as wfigs_handler
import meshai.env.fire_render as wfigs_handler
_FROZEN_TS = 1_700_000_000.0

View file

@ -1,6 +1,6 @@
"""Step 3 fire age-gate tests (Step 5 verification, age-gate part).
Targets `meshai.central.wfigs_handler._fire_too_old_to_announce` and the
Targets `meshai.env.fire_render._fire_too_old_to_announce` and the
handler's "New"-path suppression behaviour.
The gate exists because MeshAI broadcast a 6-week-old, already-closed fire
@ -21,7 +21,7 @@ import time
import pytest
from meshai.central.wfigs_handler import _fire_too_old_to_announce
from meshai.env.fire_render import _fire_too_old_to_announce
_14D = 14 * 86400
@ -131,7 +131,7 @@ def test_handler_new_path_suppresses_old_fire():
"""Case (i): a brand-new fire whose declared_at is ~45d old is INSERTed
but the 'New' broadcast is suppressed (wire is None), and the New-path
category tag is NOT applied."""
from meshai.central.wfigs_handler import handle_wfigs
from meshai.env.fire_render import handle_wfigs
from meshai.persistence import get_db
now = int(time.time())
@ -154,7 +154,7 @@ def test_handler_new_path_suppresses_old_fire():
def test_handler_new_path_announces_recent_fire():
"""Case (i): a recent fire (~5d) DOES broadcast 'New' and tags
wildfire_declared."""
from meshai.central.wfigs_handler import handle_wfigs
from meshai.env.fire_render import handle_wfigs
now = int(time.time())
declared = now - _5D
@ -171,7 +171,7 @@ def test_handler_update_path_still_emits_for_old_fire():
"""An already-broadcast OLD fire that grows acreage still emits an
'Update' (Case (iii) is NOT gated -- genuine old-but-active fires keep
getting containment/acreage updates)."""
from meshai.central.wfigs_handler import handle_wfigs
from meshai.env.fire_render import handle_wfigs
from meshai.persistence import get_db
now = int(time.time())

View file

@ -23,7 +23,7 @@ import pytest
from meshai import central_normalizer as cn
from meshai.notifications.formatters._budget import budget_for
from meshai.central.wfigs_handler import (
from meshai.env.fire_render import (
_build_canonical,
_render as _wfigs_render,
handle_wfigs,
@ -55,7 +55,7 @@ def mem_db(monkeypatch, tmp_path):
except Exception:
pass
try:
from meshai.central import wfigs_handler as _wh
from meshai.env import fire_render as _wh
_wh._last_cleanup = 0
except Exception:
pass

View file

@ -81,7 +81,7 @@ def _envelope(*, lat, lon, acq_date="2026-06-06", acq_time="1200",
def test_pixel_within_radius_attributes_to_fire():
from meshai.central.firms_handler import handle_firms
from meshai.env.fire_fusion import handle_firms
from meshai.persistence import get_db
# Cache Peak Fire stub @ 42.118, -113.643.
@ -120,7 +120,7 @@ def test_pixel_within_radius_attributes_to_fire():
def test_centroid_recomputes_as_median_across_passes():
"""A second attributed pixel updates the centroid to the median, not
just the latest pixel's coords."""
from meshai.central.firms_handler import handle_firms
from meshai.env.fire_fusion import handle_firms
from meshai.persistence import get_db
_seed_fire(irwin_id="ID-TEST-002",
@ -157,7 +157,7 @@ def test_centroid_recomputes_as_median_across_passes():
def test_pixel_outside_radius_stays_unattributed():
from meshai.central.firms_handler import handle_firms
from meshai.env.fire_fusion import handle_firms
from meshai.persistence import get_db
_seed_fire(irwin_id="ID-TEST-003",
@ -196,7 +196,7 @@ def _hhmm(h, m=0):
def test_three_unattributed_pixels_fire_cluster_once():
from meshai.central.firms_handler import handle_firms
from meshai.env.fire_fusion import handle_firms
from meshai.persistence import get_db
# No fires seeded -- everything is unattributed.
@ -235,7 +235,7 @@ def test_three_unattributed_pixels_fire_cluster_once():
def test_fourth_pixel_in_same_cluster_does_not_refire():
from meshai.central.firms_handler import handle_firms
from meshai.env.fire_fusion import handle_firms
from meshai.persistence import get_db
base_lat, base_lon = 43.500, -114.500
@ -279,7 +279,7 @@ def test_fifth_pixel_after_time_window_can_form_new_cluster():
no nearby unstamped pixels to count, so it stays silent -- but if
we then ingest TWO more nearby pixels (also outside the original
window), we should fire a NEW cluster."""
from meshai.central.firms_handler import handle_firms
from meshai.env.fire_fusion import handle_firms
base_lat, base_lon = 43.500, -114.500
# First cluster at 12:00..12:20 -> fires + stamps all 3.
@ -321,7 +321,7 @@ def test_fifth_pixel_after_time_window_can_form_new_cluster():
def test_wfigs_first_sight_tags_wildfire_declared():
from meshai.central.wfigs_handler import handle_wfigs
from meshai.env.fire_render import handle_wfigs
normalized = {
"_kind": "wfigs_incident",
@ -351,7 +351,7 @@ def test_wfigs_first_sight_tags_wildfire_declared():
def test_wfigs_update_does_not_retag_wildfire_declared():
"""After a row exists AND has been broadcast, an acres-grew Update
must NOT carry the wildfire_declared category."""
from meshai.central.wfigs_handler import handle_wfigs
from meshai.env.fire_render import handle_wfigs
from meshai.persistence import get_db
# Pre-existing row that has already been broadcast.

View file

@ -73,7 +73,7 @@ def _envelope(*, lat, lon, acq_date="2026-06-06", acq_time="1200",
def test_two_pass_drift_emits_growth_with_direction_and_speed():
"""Pass 1 (N20 bucket A), pass 2 (N20 bucket B, ~6h later, centroid
1.0 mi N of pass 1). Drift should be ~1.0 mi N, broadcast must fire."""
from meshai.central.firms_handler import handle_firms
from meshai.env.fire_fusion import handle_firms
from meshai.persistence import get_db
_seed_fire(irwin_id="ID-GROWTH-001",
@ -139,7 +139,7 @@ def test_two_pass_drift_emits_growth_with_direction_and_speed():
def test_drift_below_threshold_does_not_emit_growth():
"""0.3 mi drift between consecutive passes -- below the 0.5 mi
default -- must NOT broadcast wildfire_growth."""
from meshai.central.firms_handler import handle_firms
from meshai.env.fire_fusion import handle_firms
from meshai.persistence import get_db
_seed_fire(irwin_id="ID-DRIFT-001",
@ -181,7 +181,7 @@ def test_drift_below_threshold_does_not_emit_growth():
def test_halt_detector_fires_once_after_12h_idle():
"""Fire with last_pass_at 14h ago + no new pixels in that fire
triggers halt on the next FIRMS pixel arrival (for any fire)."""
from meshai.central.firms_handler import handle_firms, _maybe_emit_halt
from meshai.env.fire_fusion import handle_firms, _maybe_emit_halt
from meshai.persistence import get_db
now_epoch = 1780768800 # 2026-06-06 18:00 UTC
@ -214,7 +214,7 @@ def test_halt_detector_fires_once_after_12h_idle():
def test_halt_detector_no_second_broadcast_for_same_fire():
"""Once halt_broadcast_at is stamped, the detector skips that fire."""
from meshai.central.firms_handler import _maybe_emit_halt
from meshai.env.fire_fusion import _maybe_emit_halt
from meshai.persistence import get_db
now_epoch = 1780768800
@ -238,7 +238,7 @@ def test_halt_eligibility_returns_after_new_pass_arrives():
"""A previously halted fire that receives a new pixel becomes eligible
for halt again if it goes idle a second time. The detector filter is
halt_broadcast_at IS NULL OR halt_broadcast_at < last_pass_at."""
from meshai.central.firms_handler import _maybe_emit_halt
from meshai.env.fire_fusion import _maybe_emit_halt
from meshai.persistence import get_db
now_epoch = 1780768800
@ -267,7 +267,7 @@ def test_halt_eligibility_returns_after_new_pass_arrives():
def test_bearing_and_direction_round_trip():
"""Bearing helper + 8-way mapping cover all cardinals/intercardinals."""
from meshai.central.firms_handler import _bearing, _direction_8
from meshai.env.fire_fusion import _bearing, _direction_8
# Source point.
s_lat, s_lon = 42.0, -114.0
# Each cardinal/intercardinal direction we test by walking ~1 mi.
@ -289,7 +289,7 @@ def test_bearing_and_direction_round_trip():
def test_direction_8_boundary_cases():
from meshai.central.firms_handler import _direction_8
from meshai.env.fire_fusion import _direction_8
# Bearings on the boundary -- check the +22.5 offset rounds correctly.
assert _direction_8(0.0) == "N"
assert _direction_8(22.4) == "N"
@ -339,7 +339,7 @@ def test_pass_row_aggregates_match_member_pixels():
"""5 pixels attributed in the same pass yield ONE fire_passes row
with pixel_count=5, total_frp = sum, pass_started_at = min(acq),
pass_ended_at = max(acq), centroid = median."""
from meshai.central.firms_handler import handle_firms
from meshai.env.fire_fusion import handle_firms
from meshai.persistence import get_db
_seed_fire(irwin_id="ID-AGG-001",

View file

@ -71,7 +71,7 @@ def test_pass_close_stamps_perimeter_geojson():
"""Pass A: 6 pixels in a hex around the seeded center. First pixel
of pass B triggers boundary close -> perimeter_geojson written for
pass A as a closed GeoJSON Polygon."""
from meshai.central.firms_handler import handle_firms
from meshai.env.fire_fusion import handle_firms
from meshai.persistence import get_db
center_lat, center_lon = 42.500, -114.500
@ -121,7 +121,7 @@ def _seed_pass_a_hex_then_close(*, irwin_id, center_lat, center_lon,
start_now=1780747200):
"""Helper: seed a fire + 6 hex-vertex pass A pixels. Caller follows up
with a pass B pixel to trigger boundary close + perimeter write."""
from meshai.central.firms_handler import handle_firms
from meshai.env.fire_fusion import handle_firms
_seed_fire(irwin_id=irwin_id, lat=center_lat, lon=center_lon,
name=irwin_id)
for i in range(6):
@ -138,7 +138,7 @@ def _seed_pass_a_hex_then_close(*, irwin_id, center_lat, center_lon,
def test_pixel_2mi_ne_of_perimeter_emits_spotting():
"""Pass B pixel 2 mi NE of pass A's perimeter centroid fires
wildfire_spotting with the correct distance + direction."""
from meshai.central.firms_handler import handle_firms
from meshai.env.fire_fusion import handle_firms
from meshai.persistence import get_db
center_lat, center_lon = 43.000, -115.000
@ -188,7 +188,7 @@ def test_pixel_2mi_ne_of_perimeter_emits_spotting():
def test_pixel_inside_perimeter_no_spotting():
from meshai.central.firms_handler import handle_firms
from meshai.env.fire_fusion import handle_firms
center_lat, center_lon = 43.500, -114.500
_seed_pass_a_hex_then_close(irwin_id="ID-SPOT-003",
@ -223,7 +223,7 @@ def test_pixel_inside_perimeter_no_spotting():
def test_second_spotting_within_cooldown_suppressed():
from meshai.central.firms_handler import handle_firms
from meshai.env.fire_fusion import handle_firms
center_lat, center_lon = 44.000, -116.000
_seed_pass_a_hex_then_close(irwin_id="ID-SPOT-004",
@ -257,7 +257,7 @@ def test_second_spotting_within_cooldown_suppressed():
def test_spotting_refires_after_cooldown():
from meshai.central.firms_handler import handle_firms
from meshai.env.fire_fusion import handle_firms
center_lat, center_lon = 44.500, -116.500
_seed_pass_a_hex_then_close(irwin_id="ID-SPOT-005",
@ -286,7 +286,7 @@ def test_spotting_refires_after_cooldown():
def test_convex_hull_basic():
from meshai.central.firms_handler import _convex_hull
from meshai.env.fire_fusion import _convex_hull
pts = [(0, 0), (1, 0), (1, 1), (0, 1), (0.5, 0.5)]
hull = _convex_hull(pts)
assert (0.5, 0.5) not in hull
@ -294,7 +294,7 @@ def test_convex_hull_basic():
def test_point_in_polygon_basic():
from meshai.central.firms_handler import _point_in_polygon
from meshai.env.fire_fusion import _point_in_polygon
square = [(0, 0), (0, 10), (10, 10), (10, 0)] # (lat, lon)
assert _point_in_polygon((5, 5), square) is True
assert _point_in_polygon((15, 5), square) is False
@ -303,7 +303,7 @@ def test_point_in_polygon_basic():
def test_geojson_round_trip_via_hull():
"""Hull -> GeoJSON -> parse -> ring shape sane."""
from meshai.central.firms_handler import _convex_hull, _hull_to_geojson
from meshai.env.fire_fusion import _convex_hull, _hull_to_geojson
hull = _convex_hull([(0, 0), (1, 0), (0, 1), (1, 1)])
raw = _hull_to_geojson(hull)
parsed = json.loads(raw)

View file

@ -73,7 +73,7 @@ def _pixel(*, lat, lon, acq_date="2026-06-06", acq_time="1200",
def _feed(pixel, *, now, seed=False):
from meshai.central.firms_handler import ingest_hotspot_pixel
from meshai.env.fire_fusion import ingest_hotspot_pixel
return ingest_hotspot_pixel(pixel, now=now, seed=seed)

View file

@ -10,8 +10,8 @@ Envelope shape sourced from firms-investigation.md sampling (250 envelopes
"""
import pytest
from meshai.central import firms_handler
from meshai.central.firms_handler import handle_firms
from meshai.env import fire_fusion as firms_handler
from meshai.env.fire_fusion import handle_firms
from meshai.persistence import close_thread_connection, init_db
from meshai.persistence import db as persistence_db

View file

@ -100,7 +100,7 @@ def _offset_mi(lat, lon, north_mi, east_mi):
def _feed(pixel, *, now):
from meshai.central.firms_handler import ingest_hotspot_pixel
from meshai.env.fire_fusion import ingest_hotspot_pixel
return ingest_hotspot_pixel(pixel, now=now)
@ -407,7 +407,7 @@ _SUBJECT = "central.fire.hotspot.N20.high.us.id"
class TestCentralPathUnchanged:
def test_storage_only_pixel_still_stores_and_returns_none(self):
from meshai.central.firms_handler import handle_firms
from meshai.env.fire_fusion import handle_firms
from meshai.persistence import get_db
env = _envelope(lat=42.19664, lon=-113.70981)
out = handle_firms(env, subject=_SUBJECT, data={}, now=1780660000)
@ -427,7 +427,7 @@ class TestCentralPathUnchanged:
def test_central_growth_wire_and_stamps_identical(self):
"""The extracted core produces the SAME growth wire/stamps on the
Central envelope path that the inline handler did."""
from meshai.central.firms_handler import handle_firms
from meshai.env.fire_fusion import handle_firms
center_lat, center_lon = 42.0, -114.0
_seed_fire(irwin_id="ID-CG", lat=center_lat, lon=center_lon,
name="Pine Gulch")

View file

@ -119,7 +119,7 @@ _SUBJECT = "central.fire.hotspot.N20.high.us.id"
def _drive_two_pass_growth(irwin_id, center_lat, center_lon):
"""Seed a fire + pass A (5 px) + first pass-B pixel 1 mi N. Returns the
(wire, data) from the boundary pixel that fires wildfire_growth."""
from meshai.central.firms_handler import handle_firms
from meshai.env.fire_fusion import handle_firms
_seed_fire(irwin_id=irwin_id, lat=center_lat, lon=center_lon, name="Pine Gulch")
for i in range(5):
env = _envelope(lat=center_lat + 0.0001 * i,
@ -136,7 +136,7 @@ def _drive_two_pass_growth(irwin_id, center_lat, center_lon):
def _seed_pass_a_hex_then_close(irwin_id, center_lat, center_lon,
start_now=1780747200):
from meshai.central.firms_handler import handle_firms
from meshai.env.fire_fusion import handle_firms
_seed_fire(irwin_id=irwin_id, lat=center_lat, lon=center_lon, name=irwin_id)
for i in range(6):
angle = i * math.pi / 3
@ -156,7 +156,7 @@ def _offset_mi(lat, lon, north_mi, east_mi):
def _drive_spotting(irwin_id, center_lat, center_lon, now=1780768800):
"""Seed hex pass A + closed perimeter, then a pass-B pixel 2 mi NE that
fires wildfire_spotting. Returns (wire, data)."""
from meshai.central.firms_handler import handle_firms
from meshai.env.fire_fusion import handle_firms
_seed_pass_a_hex_then_close(irwin_id, center_lat, center_lon)
sp_lat, sp_lon = _offset_mi(center_lat, center_lon,
north_mi=2.0 / math.sqrt(2),
@ -354,7 +354,7 @@ class TestFormatterGolden:
_clear_cache()
def test_halt_wire_golden(self, monkeypatch):
from meshai.central.firms_handler import _maybe_emit_halt
from meshai.env.fire_fusion import _maybe_emit_halt
from meshai.persistence import get_db
_cutover(monkeypatch, "wildfire_halted")
try:
@ -416,7 +416,7 @@ class TestNotCutoverLegacyVerbatim:
assert "_on_broadcast_committed" not in data
def test_halt_eager_latch_stamped(self, _no_cutover):
from meshai.central.firms_handler import _maybe_emit_halt
from meshai.env.fire_fusion import _maybe_emit_halt
from meshai.persistence import get_db
now = 1780768800
_seed_stale_fire("ID-HN", now_epoch=now, idle_hours=14)
@ -439,7 +439,7 @@ class TestNotCutoverLegacyVerbatim:
class TestClusterBelowThreshold:
def test_maybe_emit_cluster_below_threshold_returns_none(self):
from meshai.central.firms_handler import _maybe_emit_cluster
from meshai.env.fire_fusion import _maybe_emit_cluster
from meshai.persistence import get_db
data = {}
# No pixels in firms_pixels -> the cluster query finds < min_pixels

View file

@ -3,6 +3,13 @@ must be importable without error after the budget shim refactor.
This guards against a broken import chain (e.g. circular imports or a bad
re-export in the shim) that would silently break all handlers.
chore/ripout-2d: the last two central/ handlers (firms_handler.py,
wfigs_handler.py) relocated to meshai/env/fire_fusion.py + fire_render.py
(central/ has no *_handler.py left -- the fusion engine's only consumer is
the native env/firms.py adapter). The glob below now also covers those two
explicitly so this guard still exercises the relocated live import chain;
it keeps globbing central/ too in case a future handler lands back there.
"""
import glob
@ -11,17 +18,16 @@ import os
def _handler_modules():
"""Collect meshai.central.*_handler module names by globbing the source tree."""
pattern = os.path.join(
"""Collect handler-ish module names: meshai.central.*_handler (glob) +
the fire-fusion modules relocated out of central/ during the ripout."""
central_pattern = os.path.join(
os.path.dirname(__file__),
"..", "meshai", "central", "*_handler.py",
)
paths = sorted(glob.glob(pattern))
assert paths, "No *_handler.py files found — check the glob path"
modules = []
for p in paths:
name = os.path.basename(p)[:-3] # strip .py
modules.append(f"meshai.central.{name}")
central_paths = sorted(glob.glob(central_pattern))
modules = [f"meshai.central.{os.path.basename(p)[:-3]}" for p in central_paths]
modules += ["meshai.env.fire_fusion", "meshai.env.fire_render"]
assert modules, "No handler-ish modules found — check the glob path"
return modules

View file

@ -279,7 +279,7 @@ def test_fires_has_tombstoned_at_column():
def test_wfigs_tombstone_stamps_column():
"""A tombstone envelope sets fires.tombstoned_at."""
from meshai.central.wfigs_handler import handle_wfigs
from meshai.env.fire_render import handle_wfigs
conn = get_db()
# Seed an active fire row.
irwin = "TOMB-1"

View file

@ -23,7 +23,7 @@ import time
import pytest
from meshai.central.wfigs_handler import handle_wfigs
from meshai.env.fire_render import handle_wfigs
from meshai.notifications.env_reporter import EnvReporter
from meshai.persistence import get_db

View file

@ -169,7 +169,7 @@ def test_dedup_suffix_lets_updates_pass_and_repeats_dedup():
def test_wfigs_handler_stamps_dedup_suffix():
from meshai.central.wfigs_handler import _attach_commit_handles
from meshai.env.fire_render import _attach_commit_handles
data = {}
_attach_commit_handles(data, irwin_id="{X}", acres=42.0,
contained_pct=15, event_log_row_id=None)

View file

@ -20,7 +20,7 @@ import time
import pytest
from meshai import central_normalizer as cn
from meshai.central.wfigs_handler import (
from meshai.env.fire_render import (
WFIGS_BROADCAST_COOLDOWN_S,
handle_wfigs,
_render as _wfigs_render,
@ -47,7 +47,7 @@ def mem_db(monkeypatch, tmp_path):
pass
# Reset the stale-fire cleanup throttle so it runs deterministically.
try:
from meshai.central import wfigs_handler as _wh
from meshai.env import fire_render as _wh
_wh._last_cleanup = 0
except Exception:
pass