# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/under-what-conditions-must-an-instance-treat-a-revoked-agent-identity-as-still-authoritative-the-credential-overlap-window-in-federated-agent-meshes.md
# Remnant Warrant:    https://corpusfetch.com/c/under-what-conditions-must-an-instance-treat-a-revoked-agent-identity-as-still-authoritative-the-credential-overlap-window-in-federated-agent-meshes.warrant.json
# Markdown SHA-256:   932c24c596324439e9331a42795a795f8ed0e291857db611890225fdfee06544
# Code AST SHA-256:   08b1fee2bce71e234c8b644d0bd0db8a8b0dbfa87df4eb10f6dfb39831910bdf
# Verified Classes:   StaleRevocationKnowledgeError, VerifierState
# Defensive Guards:   3 fail-closed invariants (zero external deps)

import time
from dataclasses import dataclass


class StaleRevocationKnowledgeError(RuntimeError):
    """Raised when a verifier can no longer prove its revocation view is fresh."""


@dataclass
class VerifierState:
    positive_cache_ttl_s: float
    pull_interval_s: float
    freshness_bound_s: float
    last_successful_sync: float
    credential_expiry: float


def assert_credential_authoritative(state: VerifierState, now: float, revoked: bool) -> None:
    sync_failure_age = now - state.last_successful_sync
    if sync_failure_age > state.freshness_bound_s:
        raise StaleRevocationKnowledgeError(
            f"sync_failure_age={sync_failure_age:.1f}s exceeds freshness_bound="
            f"{state.freshness_bound_s:.1f}s; refusing last-known-good state"
        )
    if revoked:
        raise StaleRevocationKnowledgeError(
            "revocation record received; positive cache must be evicted, not TTL-expired"
        )
    exposure_bound = max(state.positive_cache_ttl_s, state.pull_interval_s) + min(
        sync_failure_age, max(0.0, state.credential_expiry - now)
    )
    if now >= state.credential_expiry:
        raise StaleRevocationKnowledgeError("credential expired")
    # exposure_bound is the residual risk the operator accepts; log it, do not hide it.
    return None
