From 7128b432eeb0ed866602f0f32f01ff413e3be867 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Mon, 15 Jun 2026 23:11:50 +0000 Subject: [PATCH] fix(satpass): add AOS horizon guard to reject stale far-future passes Passes whose AOS is more than max_aos_horizon_hours (default 24) in the future are now rejected in the handler. Prevents stale predictions republished via NATS LAST_PER_SUBJECT from broadcasting passes that are too far out to be actionable. Complements the existing los < now guard which catches passes that already ended. New adapter_config key: satpass.max_aos_horizon_hours (int, default 24, 0 = disabled). Co-Authored-By: Claude Opus 4.6 --- meshai/adapter_config/defaults.py | 5 +++++ meshai/central/satpass_handler.py | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/meshai/adapter_config/defaults.py b/meshai/adapter_config/defaults.py index 3198729..1d8d6e4 100644 --- a/meshai/adapter_config/defaults.py +++ b/meshai/adapter_config/defaults.py @@ -630,6 +630,11 @@ REGISTRY: dict[tuple[str, str], dict[str, Any]] = { "type": "bool", "description": "Dry-run mode: log wire text at INFO with DRY-RUN prefix instead of dispatching. Default true so satpass re-enables inert.", }, + ("satpass", "max_aos_horizon_hours"): { + "default": 24, + "type": "int", + "description": "Maximum hours ahead for AOS. Passes with AOS further in the future are rejected as stale predictions. 0 disables.", + }, # ================================================================= # DASHBOARD -- UI-only settings persisted for the operator diff --git a/meshai/central/satpass_handler.py b/meshai/central/satpass_handler.py index d17bc74..7558293 100644 --- a/meshai/central/satpass_handler.py +++ b/meshai/central/satpass_handler.py @@ -314,6 +314,14 @@ def handle_satpass(envelope: dict, subject: str, los_epoch, now) return None + # AOS horizon guard: reject passes too far in the future (likely stale prediction) + max_horizon_h = float(getattr(cfg, "max_aos_horizon_hours", 24)) + if max_horizon_h > 0 and aos_epoch > now + max_horizon_h * 3600: + logger.debug( + "satpass_handler: AOS %d is %.1fh away, beyond %gh horizon; skipping", + aos_epoch, (aos_epoch - now) / 3600, max_horizon_h) + return None + # Observer filter (empty = all) observers = getattr(cfg, "observers", []) or [] if observers and observer not in observers: