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 <noreply@anthropic.com>
This commit is contained in:
Ubuntu 2026-06-15 23:11:50 +00:00
commit 7128b432ee
2 changed files with 13 additions and 0 deletions

View file

@ -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

View file

@ -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: