# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/how-does-an-instance-detect-a-rotated-did-controller-key-that-still-verifies-under-a-cached-federation-trust-anchor.md
# Remnant Warrant:    https://corpusfetch.com/c/how-does-an-instance-detect-a-rotated-did-controller-key-that-still-verifies-under-a-cached-federation-trust-anchor.warrant.json
# Markdown SHA-256:   1b8a559da7c1aa80264b848066ae915b30a01e332c3ccb1478ad8ab6423ca160
# Code AST SHA-256:   f5a6a9bd2befda191c3b022b0f544eb4220f1929be05804d174a64406b4cbe32
# Verified Classes:   TrustAnchorDivergenceError, AnchorVersionUnavailable, DIDDocumentVersion, CachedAnchor
# Defensive Guards:   4 fail-closed invariants (zero external deps)

from dataclasses import dataclass
from datetime import datetime, timedelta

CLOCK_SKEW_TOLERANCE = timedelta(minutes=5)


class TrustAnchorDivergenceError(RuntimeError):
    """Raised when a cached anchor and the resolved document disagree on key material."""
    pass


class AnchorVersionUnavailable(TrustAnchorDivergenceError):
    """The document version in force at issuanceDate has been pruned."""
    pass


@dataclass(frozen=True)
class DIDDocumentVersion:
    version_id: str
    valid_from: datetime
    valid_until: datetime | None
    key_fragments: frozenset[str]


@dataclass(frozen=True)
class CachedAnchor:
    did: str
    controller: str
    version_id: str
    key_fragments: frozenset[str]


def select_key_version(
    cached: CachedAnchor,
    history: list[DIDDocumentVersion],
    issuance_date: datetime,
) -> DIDDocumentVersion:
    """Pick the document version authorized at issuanceDate, never the cached one blindly."""
    if cached.did != cached.did.lower():
        raise TrustAnchorDivergenceError(f"anchor DID not normalized: {cached.did}")

    target = issuance_date - CLOCK_SKEW_TOLERANCE
    for version in history:
        if version.valid_from <= target and (
            version.valid_until is None or target <= version.valid_until
        ):
            if version.version_id != cached.version_id:
                # Cache diverged from history: this is the silent-rotation case.
                raise TrustAnchorDivergenceError(
                    f"anchor {cached.did} cached at {cached.version_id} "
                    f"but issuance falls in {version.version_id}"
                )
            return version

    raise AnchorVersionUnavailable(
        f"no document version for {cached.did} covers issuance {issuance_date.isoformat()}"
    )


def verify_credential(cached: CachedAnchor, history: list[DIDDocumentVersion],
                      issuance_date: datetime, signing_fragment: str) -> bool:
    version = select_key_version(cached, history, issuance_date)
    if signing_fragment not in version.key_fragments:
        raise TrustAnchorDivergenceError(
            f"fragment {signing_fragment} not authorized in {version.version_id}"
        )
    return True
