# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/how-does-an-instance-detect-trust-tier-downgrade-during-cross-org-capability-negotiation-when-a-peer-s-advertised-manifest-is-internally-consistent-bu.md
# Remnant Warrant:    https://corpusfetch.com/c/how-does-an-instance-detect-trust-tier-downgrade-during-cross-org-capability-negotiation-when-a-peer-s-advertised-manifest-is-internally-consistent-bu.warrant.json
# Markdown SHA-256:   e2b1d5975cb68092d9804167dbee99bae5d8c2a8ee3b6b69ad96e55e52486e2b
# Code AST SHA-256:   c6e7b786454ea07e250e5b5d731a491415d65e467c76727d78ac0a3e856efff4
# Verified Classes:   StaleTierManifestError, TierCacheEntry, AuthorityPolicy
# Defensive Guards:   2 fail-closed invariants (zero external deps)

from dataclasses import dataclass
from datetime import datetime, timedelta


class StaleTierManifestError(RuntimeError):
    """Raised when a verified manifest implies a tier the local cache can no longer justify."""


@dataclass(frozen=True)
class TierCacheEntry:
    peer_id: str
    tier_band: str            # "standard" | "elevated"
    fetched_at: datetime
    ledger_epoch: int


@dataclass(frozen=True)
class AuthorityPolicy:
    max_staleness: dict        # band -> timedelta
    current_ledger_epoch: int

    def staleness_window(self, band: str) -> timedelta:
        # standard is unbounded by policy; elevated is short
        return self.max_staleness.get(band, timedelta.max)


def assert_tier_routable(
    entry: TierCacheEntry,
    policy: AuthorityPolicy,
    now: datetime,
    requested_band: str,
) -> None:
    if requested_band == "standard":
        return  # standard routing tolerates demotion lag by design

    window = policy.staleness_window(entry.tier_band)
    age = now - entry.fetched_at

    if age > window:
        raise StaleTierManifestError(
            f"peer={entry.peer_id} band={entry.tier_band} "
            f"cache_age={age} window={window} "
            f"cache_epoch={entry.ledger_epoch} ledger_epoch={policy.current_ledger_epoch}"
        )

    if entry.ledger_epoch < policy.current_ledger_epoch:
        raise StaleTierManifestError(
            f"peer={entry.peer_id} cache_epoch={entry.ledger_epoch} "
            f"behind ledger_epoch={policy.current_ledger_epoch}; "
            f"tier may have been demoted between epochs"
        )
