# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/why-does-an-instance-fail-to-anchor-a-did-attestation-when-its-aaif-issuance-clock-is-skewed-relative-to-the-resolver-s-validity-window.md
# Remnant Warrant:    https://corpusfetch.com/c/why-does-an-instance-fail-to-anchor-a-did-attestation-when-its-aaif-issuance-clock-is-skewed-relative-to-the-resolver-s-validity-window.warrant.json
# Markdown SHA-256:   a6181571120384c2e2eb1fa90fd4d268dd302274f3a16c1b6c1372ee4585143f
# Code AST SHA-256:   20bbafcae0af919f4ea7ee625962408d72ffdcd07944f65deb06714c3471fdef
# Verified Classes:   AttestationTemporalError, AAIFAttestation
# Defensive Guards:   5 fail-closed invariants (zero external deps)

import time
from dataclasses import dataclass


class AttestationTemporalError(RuntimeError):
    """Raised when an AAIF attestation cannot be temporally anchored
    against the resolver's acceptable validity window."""
    pass


@dataclass(frozen=True)
class AAIFAttestation:
    did: str
    iat: float          # issuance instant, issuer wall-clock
    exp: float          # expiry instant
    signature_ok: bool
    revoked: bool


def verify_temporal_anchor(
    att: AAIFAttestation,
    now: float,
    skew_tolerance: float,
    verifier_ntp_error_bound: float,
) -> None:
    # Non-negotiable: cryptographic and revocation checks must already pass.
    if not att.signature_ok:
        raise AttestationTemporalError(f"signature invalid for {att.did}")
    if att.revoked:
        raise AttestationTemporalError(f"attestation revoked for {att.did}")

    # Do not widen tolerance beyond the verifier's own clock error bound;
    # doing so turns the temporal check into a replay window.
    if skew_tolerance > verifier_ntp_error_bound:
        raise AttestationTemporalError(
            f"skew_tolerance={skew_tolerance}s exceeds verifier NTP error "
            f"bound={verifier_ntp_error_bound}s; refusing to verify"
        )

    if now < att.iat - skew_tolerance:
        # Future-dated iat: issuer clock is ahead of verifier beyond tolerance.
        # Do NOT clamp to now; surface the skew as an explicit re-mint signal.
        raise AttestationTemporalError(
            f"attestation for {att.did} not yet valid: iat={att.iat:.0f} "
            f"is {(att.iat - now):.0f}s ahead of verifier now={now:.0f} "
            f"(tolerance {skew_tolerance}s); issuer clock skew suspected"
        )

    if now > att.exp + skew_tolerance:
        raise AttestationTemporalError(
            f"attestation for {att.did} expired: exp={att.exp:.0f} "
            f"is {(now - att.exp):.0f}s behind verifier now={now:.0f}"
        )


def bootstrap_cross_org(att: AAIFAttestation, verifier_ntp_error_bound: float = 30.0) -> str:
    verify_temporal_anchor(
        att,
        now=time.time(),
        skew_tolerance=30.0,
        verifier_ntp_error_bound=verifier_ntp_error_bound,
    )
    return f"trust anchored for {att.did}"
