meshai/tests
K7ZVX a491684861 fix(central): v0.4 C.3.1 -- preserve secret refs in save_section + deliver_policy=NEW (no backlog flood)
Fixes the two real bugs C.3 surfaced when flipping usgs_quake to central.

BUG #1 -- GUI save dropped ${VAR} secret refs (config_loader.save_section).
  before: A GUI PUT round-trips the *interpolated* secret value (GET returns the
          resolved key string, e.g. the real TomTom key). save_section's
          check_secrets saw a literal string at a SECRET_FIELDS path, didn't
          recognize it as a ref, and DROPPED it -- losing the on-disk
          ${TOMTOM_API_KEY} placeholder. C.3's flip PUT stripped TomTom's key.
  after:  check_secrets now reads the raw on-disk value (pre-interpolation) for
          each secret field and decides three ways:
            on-disk ${VAR} and new == resolved(VAR)  -> keep the ${VAR} ref
            on-disk ${VAR} and new != resolved(VAR)  -> intentional change, store it
            no on-disk ${VAR} ref                    -> reject (never write a raw
                                                        secret to a domain file)
          ${VAR} resolution mirrors load: os.environ first, then /data/secrets/.env.
          The common case (GUI re-saves unchanged config) now preserves the
          placeholder instead of dropping it.

BUG #2 -- CentralConsumer replayed the entire retained backlog on first flip.
  before: js.subscribe(...) with no config -> default deliver_policy=all. Fine
          for quake (682 msgs) but would flood the bus with ~330k traffic_flow
          messages on first flip.
  after:  consumer_config() -> ConsumerConfig(deliver_policy=DeliverPolicy.NEW):
          only messages published AFTER consumer creation. meshai won't see the
          backlog on first flip -- acceptable, Central is a live firehose for
          current events. (NOT geo-filtering -- that's a Central-side issue filed
          separately for the Central project.)

Files: meshai/config_loader.py (save_section secret preservation),
meshai/central/consumer.py (consumer_config() + deliver_policy=NEW),
tests/test_save_section_secret_preserve.py (new),
tests/test_central_consumer.py (deliver_policy assertion).

Verification:
- (A) py_compile clean on config_loader.py + consumer.py.
- (C) pytest -q: 276 passed (272 + 4 new -- preserve-unchanged-ref,
  changed-value-written, no-placeholder-still-rejects, deliver_policy=NEW).
  The C.2.1 strip test still passes (no placeholder -> reject).
- (D) In-prod (rebuilt): GET+PUT /api/config/environmental round-trip ->
  {"saved":true}; on-disk traffic.api_key stayed '${TOMTOM_API_KEY}'
  (SECRET_REF_PRESERVED: True), not the literal key; disk restored to baseline.
  consumer_config().deliver_policy == DeliverPolicy.NEW in the built image.

Follow-up for D rollout: the durable 'meshai-v04-central_quake_' created during
C.3 was made with deliver_policy=all; re-flipping a domain may need that stale
durable deleted on the Central NATS server first (config mismatch on re-subscribe).

D rollout (remaining domains) is now safe: GUI flips preserve secret refs and
new subscriptions don't replay huge backlogs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 04:55:20 +00:00
..
test_adapter_avalanche.py feat(notifications): Phase 2.10 avalanche adapter pipeline integration 2026-05-27 23:08:24 +00:00
test_adapter_ducting.py feat(notifications): Phase 2.13 ducting adapter threshold-crossing emission (severity-tiered, Option C) 2026-05-28 00:01:40 +00:00
test_adapter_fires.py feat(notifications): Phase 2.11 NIFC fires adapter pipeline integration 2026-05-27 23:33:48 +00:00
test_adapter_firms.py feat(env): Phase 2.6 FIRMS adapter emits Events to pipeline bus 2026-05-15 05:23:00 +00:00
test_adapter_nws.py feat(notifications): Phase 2.6 NWS adapter pipeline integration 2026-05-15 04:47:31 +00:00
test_adapter_roads511.py feat(notifications): Phase 2.8 roads511 adapter pipeline integration 2026-05-27 21:18:21 +00:00
test_adapter_swpc.py feat(notifications): Phase 2.12 SWPC space weather adapter + dedup fix 2026-05-27 23:41:30 +00:00
test_adapter_traffic.py feat(notifications): Phase 2.7 traffic adapter pipeline integration 2026-05-27 19:17:27 +00:00
test_adapter_usgs.py feat(notifications): Phase 2.9 usgs water adapter pipeline integration 2026-05-27 21:58:13 +00:00
test_adapter_usgs_quake.py feat(notifications): Phase 2.14 USGS earthquake adapter (new) -- closes Rule 16 Seismic standalone path 2026-05-28 00:10:39 +00:00
test_central_consumer.py fix(central): v0.4 C.3.1 -- preserve secret refs in save_section + deliver_policy=NEW (no backlog flood) 2026-05-28 04:55:20 +00:00
test_channel_rendering.py feat(notifications): Phase 2.5b per-channel-type renderers 2026-05-15 04:25:44 +00:00
test_config_loader.py fix(notifications): Phase 2.16.1 unblock pipeline -- grouper flush + rules coercion + toggle warning 2026-05-28 00:36:13 +00:00
test_config_source_field.py feat(central): v0.4 C.1 Central connector backend (no-op until adapter source flipped) 2026-05-28 02:28:19 +00:00
test_dashboard_config_save.py fix(dashboard): v0.4 C.2.1 -- route PUT /config to multi-file save_section (Rule 17 persistence unblocked) 2026-05-28 03:17:30 +00:00
test_pipeline_digest.py fix(notifications): inject llm_backend into build_pipeline 2026-05-15 03:08:31 +00:00
test_pipeline_grouper.py fix(notifications): Phase 2.16.1 unblock pipeline -- grouper flush + rules coercion + toggle warning 2026-05-28 00:36:13 +00:00
test_pipeline_inhibitor_grouper.py fix(notifications): Phase 2.16.1 unblock pipeline -- grouper flush + rules coercion + toggle warning 2026-05-28 00:36:13 +00:00
test_pipeline_scheduler.py feat(notifications): Phase 2.5a channel interface unification 2026-05-15 03:45:27 +00:00
test_pipeline_skeleton.py feat(notifications): Phase 2.5a channel interface unification 2026-05-15 03:45:27 +00:00
test_pipeline_toggle_filter.py fix(notifications): inject llm_backend into build_pipeline 2026-05-15 03:08:31 +00:00
test_renderers.py feat(notifications): Phase 2.5b per-channel-type renderers 2026-05-15 04:25:44 +00:00
test_save_section_secret_preserve.py fix(central): v0.4 C.3.1 -- preserve secret refs in save_section + deliver_policy=NEW (no backlog flood) 2026-05-28 04:55:20 +00:00