From d305ce65d73dd6e7f26812988af9764d1860fe6f Mon Sep 17 00:00:00 2001 From: "Matt Johnson (via Claude)" Date: Sun, 7 Jun 2026 16:57:21 +0000 Subject: [PATCH] feat(dispatcher): bypass cooldown for immediate-severity events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Events with severity=immediate skip the per-toggle cooldown check entirely — they are already rate-controlled by source handler change detection. Also set cooldown_seconds default to 0 (disabled). Co-Authored-By: Claude Opus 4.6 --- meshai/config.py | 2 +- meshai/notifications/pipeline/dispatcher.py | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/meshai/config.py b/meshai/config.py index 0e69f50..00faedc 100644 --- a/meshai/config.py +++ b/meshai/config.py @@ -543,7 +543,7 @@ class NotificationToggle: severity_channels: dict = field(default_factory=dict) # v0.5.2: staleness drop + per-toggle cooldown (Matt's spam fix) freshness_seconds: int = 600 # drop events older than this at dispatcher entrance - cooldown_seconds: int = 300 # per (toggle, category, region) throttle window + cooldown_seconds: int = 0 # per (toggle, category, region) throttle window; 0 = disabled # per-channel delivery config (mirrors NotificationRuleConfig channel fields) broadcast_channel: Optional[int] = None node_ids: list = field(default_factory=list) diff --git a/meshai/notifications/pipeline/dispatcher.py b/meshai/notifications/pipeline/dispatcher.py index f56b640..4d2e177 100644 --- a/meshai/notifications/pipeline/dispatcher.py +++ b/meshai/notifications/pipeline/dispatcher.py @@ -358,7 +358,12 @@ class Dispatcher: return # ---------- Section 2 — per-toggle cooldown ---------- - cooldown_s = int(getattr(tog, "cooldown_seconds", 300) or 0) + # Immediate-severity events bypass cooldown entirely — they are + # already rate-controlled by source handler change detection. + if getattr(event, "severity", None) == "immediate": + cooldown_s = 0 + else: + cooldown_s = int(getattr(tog, "cooldown_seconds", 300) or 0) if cooldown_s > 0: suffix = (event.data or {}).get("_cooldown_suffix", "") region_key = event.region or "*"