"""Event semantics: backfill classification, release grouping, deterministic importance.""" from __future__ import annotations from datetime import UTC, datetime, timedelta from aiatlas.services.events import classify_backfill, group_key_for, importance_for NOW = datetime(2026, 9, 12, 12, 0, tzinfo=UTC) def test_backfill_rules() -> None: assert classify_backfill("NEW_MODEL", None, NOW) is False assert classify_backfill("NEW_MODEL", NOW - timedelta(days=1), NOW) is False # 1 day lag: news assert classify_backfill("NEW_MODEL", NOW - timedelta(days=4), NOW) is True # > 3 days: history being loaded assert classify_backfill("PRICE_CHANGED", None, NOW, is_first_run=True) is True # connector's first run = initial corpus assert classify_backfill("NEW_MODEL", None, NOW, entity_first_seen=NOW - timedelta(days=30)) is True assert classify_backfill("PRICE_CHANGED", None, NOW, entity_first_seen=NOW - timedelta(days=30)) is False # hint only applies to NEW_* assert classify_backfill("NEW_PAPER", datetime(2026, 9, 11), NOW) is False # naive datetimes are treated as UTC def test_group_key() -> None: assert group_key_for("NEW_MODEL", "model_x", datetime(2026, 5, 3, tzinfo=UTC), NOW) == "release:model_x:2026-05" assert group_key_for("RELEASE", "model_x", None, NOW) == "release:model_x:2026-09" assert group_key_for("PRICE_CHANGED", "model_x", None, NOW) is None assert group_key_for("RELEASE", None, None, NOW) is None def test_importance_matrix() -> None: assert importance_for("NEW_MODEL", "artifact") == 0 assert importance_for("NEW_MODEL_FAMILY", "model_family") == 1 assert importance_for("PROPERTY_CHANGED", "model") == 0 assert importance_for("NEW_MODEL", "model", org_model_count=5, tier=1) == 3 # frontier lab assert importance_for("NEW_MODEL", "model", org_model_count=1, tier=1) == 2 assert importance_for("NEW_MODEL", "model", org_model_count=1, openness="open-weights") == 3 assert importance_for("NEW_MODEL", "model", org_model_count=5, tier=3) == 1 # not frontier at tier 3, and a community source loses a point old, new = {"input_per_mtok": 10, "output_per_mtok": 30}, {"input_per_mtok": 5, "output_per_mtok": 30} assert importance_for("PRICE_CHANGED", "model", old, new) == 3 # -50 % assert importance_for("PRICE_CHANGED", "model", old, {"input_per_mtok": 7.5, "output_per_mtok": 30}) == 2 # -25 % assert importance_for("PRICE_CHANGED", "model", old, {"input_per_mtok": 9.5, "output_per_mtok": 30}) == 1 # -5 % assert importance_for("CONTEXT_CHANGED", "model", 200_000, 1_000_000) == 3 assert importance_for("CONTEXT_CHANGED", "model", 200_000, 400_000) == 2 assert importance_for("CONTEXT_CHANGED", "model", 200_000, 100_000) == 1 assert importance_for("DEPRECATION_ANNOUNCED", "model") == 3 and importance_for("RETIREMENT_ANNOUNCED", "model") == 3 assert importance_for("STATUS_CHANGED", "model", "active", "deprecated") == 3 and importance_for("STATUS_CHANGED", "model", "preview", "active") == 2 assert importance_for("OPENNESS_CHANGED", "model", "proprietary", "open-weights") == 3 assert importance_for("BENCHMARK_RESULT", "model", leader_change=True) == 2 and importance_for("BENCHMARK_RESULT", "model", default=1) == 1 assert importance_for("PRICE_CHANGED", "artifact", old, new) == 0