mirror of
https://github.com/zvx-echo6/meshai.git
synced 2026-06-10 17:04:45 +02:00
First family of the v0.5.7 NATS-and-categories campaign (Matt review of Central v0.10.0 meshai_integration_guide.md). Weather lands first because the NWS NATS pattern is already legal; the other five families need invalid mid-subject > rewrites that will ship per-family.
FIX 1 -- NWS NATS pattern validated. _subjects_for("nws", "us.id") -> ["central.wx.alert.us.id.>"]. The wildcard token > sits at the tail only (token index -1), so the subject is a legal NATS multi-level wildcard. No code change. Live introspection confirmed in-container.
FIX 2 -- NWS HTML strip in mesh composer. Per Central guide Surprise 3, data["description"] and data["instruction"] arrive as raw HTML (<p>, <br>, <strong>, , —, ...). Until now the composer fed event.title / event.summary straight to LoRa, so any future title/summary populated from those fields would have leaked literal markup onto the wire.
Added strip_html_tags(text) -> str in meshai/notifications/renderers/composer.py. Block-level tags (br, p, div, li, tr, h1-h6) become a single space so adjacent paragraphs do not fuse; all other tags are removed; HTML entities are decoded via html.unescape; whitespace is collapsed. Applied in _primary_identifier (title and summary paths) and _region_segment BEFORE byte-budget truncation, so the 150 B cap counts real glyphs, not markup. Universal (not NWS-gated) since strip is a no-op on plain text -- protects against future adapters that surface raw HTML too.
FIX 3 -- ALERT_CATEGORIES weather audit. Cross-referenced ALERT_CATEGORIES{toggle="weather"} against meshai/env/nws.py:_derive_category() emission set:
nws.py emits: weather_warning, weather_watch, weather_advisory, weather_statement
registry weather: weather_warning, weather_watch, weather_advisory, weather_statement
Parity. No additions, no removals. The v0.5.2 stream_* migration to the seismic family (USGS hydro under the GUI Geohazards tab) is already reflected; weather is clean at 4 entries. Added a comment block above the weather section pointing at test_alert_categories_weather_complete which now enforces this parity going forward -- if a new branch is added to _derive_category(), the test fails and forces a matching registry entry.
Tests
-----
PYTHONPATH=. pytest -q: 345 passed (was 328; +17 new in tests/test_weather_v057.py).
- strip_html_tags: simple tags, br/paragraph -> space, entity decode (& —), nested/attrs, plain-text no-op, empty input, whitespace collapse.
- compose_mesh_message integration: HTML in title scrubbed; HTML in summary fallback scrubbed; 150 B budget still holds.
- Weather parity: reflection-based scan of NWSAlertsAdapter._derive_category() vs registry; both must match.
- Required-fields check on the four weather entries.
Safe-mode preserved (master off, all family toggles off, all adapters native, central disabled). No live toggle flipped. Not tagging yet -- v0.5.7 tag waits until all families ship.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|---|---|---|
| .. | ||
| test_adapter_avalanche.py | ||
| test_adapter_ducting.py | ||
| test_adapter_fires.py | ||
| test_adapter_firms.py | ||
| test_adapter_nws.py | ||
| test_adapter_roads511.py | ||
| test_adapter_swpc.py | ||
| test_adapter_traffic.py | ||
| test_adapter_usgs.py | ||
| test_adapter_usgs_quake.py | ||
| test_central_consumer.py | ||
| test_central_region_routing.py | ||
| test_central_sub_adapter_routing.py | ||
| test_channel_rendering.py | ||
| test_config_loader.py | ||
| test_config_source_field.py | ||
| test_dashboard_config_save.py | ||
| test_notification_toggles.py | ||
| test_pipeline_digest.py | ||
| test_pipeline_grouper.py | ||
| test_pipeline_inhibitor_grouper.py | ||
| test_pipeline_scheduler.py | ||
| test_pipeline_skeleton.py | ||
| test_pipeline_toggle_filter.py | ||
| test_renderers.py | ||
| test_save_section_secret_preserve.py | ||
| test_v052_dispatcher.py | ||
| test_weather_v057.py | ||