mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-06-22 22:31:12 +00:00
[AZ-307] c6 FreshnessGate: active-conflict reject + stable-rear downgrade
Replaces the AZ-305 pass-through _evaluate_freshness hook with the production FreshnessGate. Loads tile_freshness_rules + sector classifications once at construction, builds an rtree index, and on every evaluate() either returns metadata unchanged (FRESH), stamps freshness_label=DOWNGRADED (stable_rear + stale), or raises FreshnessRejectionError carrying tile_id / age_seconds / classification / rule diagnostics (active_conflict + stale). Constructed inside PostgresFilesystemStore.from_config; the public storage_factory signature is preserved so AZ-305 unit tests still build the store with freshness_gate=None for the pass-through path. FDR schema bumped to v1.2.0: adds c6.freshness.rejected and c6.freshness.downgraded kinds (non-breaking; v1.1 readers route them opaquely). Operator CLI `python -m c6_tile_cache.freshness_gate explain` dry-runs the decision for a (lat, lon, capture_ts). Adjacent hygiene: c6_tile_cache.tools._dump_tile now passes os.environ to load_config (AZ-305 regression — load_config requires the env mapping). Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -127,6 +127,24 @@ KNOWN_PAYLOAD_KEYS: Final[dict[str, frozenset[str]]] = {
|
||||
# `message` is the rewrapped exception's str (truncated to keep the
|
||||
# record inline).
|
||||
"c6.write_failed": frozenset({"tile_id", "source", "reason", "error_class", "message"}),
|
||||
# AZ-307 / E-C6: emitted by the FreshnessGate on every reject decision
|
||||
# (active_conflict sector + tile_age > rule.max_age_seconds).
|
||||
# `tile_id` is the canonical UUIDv5; `age_seconds` is the integer-rounded
|
||||
# `(now - capture_timestamp).total_seconds()`; `classification` is the
|
||||
# `SectorClassification` enum value that drove the decision;
|
||||
# `rule_action` ("reject") and `rule_max_age_seconds` document which
|
||||
# rule fired so FDR consumers reproduce the decision without joining
|
||||
# back to `tile_freshness_rules`.
|
||||
"c6.freshness.rejected": frozenset(
|
||||
{"tile_id", "age_seconds", "classification", "rule_action", "rule_max_age_seconds"}
|
||||
),
|
||||
# AZ-307 / E-C6: emitted on every downgrade decision (stable_rear sector
|
||||
# — explicit or implicit-default — + tile_age > rule.max_age_seconds).
|
||||
# Same payload shape as `c6.freshness.rejected` so reject/downgrade
|
||||
# traces are line-for-line comparable. `rule_action` is "downgrade".
|
||||
"c6.freshness.downgraded": frozenset(
|
||||
{"tile_id", "age_seconds", "classification", "rule_action", "rule_max_age_seconds"}
|
||||
),
|
||||
}
|
||||
|
||||
KNOWN_KINDS: Final[frozenset[str]] = frozenset(KNOWN_PAYLOAD_KEYS.keys())
|
||||
|
||||
Reference in New Issue
Block a user