# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/when-must-an-instance-re-attest-after-a-delegated-scope-grant-on-the-split-between-token-validity-and-workload-attestation-freshness-in-aaif.md
# Remnant Warrant:    https://corpusfetch.com/c/when-must-an-instance-re-attest-after-a-delegated-scope-grant-on-the-split-between-token-validity-and-workload-attestation-freshness-in-aaif.warrant.json
# Markdown SHA-256:   f1f6963b1bc513e08ed15cbf57a107210d72498f6123dbdbb53c8e8a4be4fda2
# Code AST SHA-256:   be43da2f248520a113542b210199e7ac515ad47737479b5580c29a6abb163e27
# Verified Classes:   StaleAttestationError, DelegatedToken, AttestationPolicy
# Defensive Guards:   4 fail-closed invariants (zero external deps)

import time
from dataclasses import dataclass


class StaleAttestationError(RuntimeError):
    """Raised when a delegated scope is exercised past attestation freshness."""
    pass


@dataclass
class DelegatedToken:
    subject: str
    scopes: frozenset[str]
    issued_at: float          # epoch seconds, token `iat`
    expires_at: float         # epoch seconds, token `exp`
    attested_at: float        # epoch seconds, last workload attestation


@dataclass
class AttestationPolicy:
    max_attestation_age: float  # seconds; must be <= token TTL to be safe


def authorize_delegated_scope(
    token: DelegatedToken,
    required_scope: str,
    policy: AttestationPolicy,
    now: float | None = None,
) -> None:
    now = time.time() if now is None else now

    if now >= token.expires_at:
        raise StaleAttestationError(
            f"token for {token.subject} expired at {token.expires_at:.0f}"
        )

    if required_scope not in token.scopes:
        raise StaleAttestationError(
            f"scope {required_scope!r} not granted to {token.subject}"
        )

    attestation_age = now - token.attested_at
    if attestation_age > policy.max_attestation_age:
        # Token is structurally valid but the attestation backing it is stale.
        raise StaleAttestationError(
            f"attestation for {token.subject} is {attestation_age:.0f}s old "
            f"(policy max {policy.max_attestation_age:.0f}s); re-attest required"
        )

    if token.issued_at < token.attested_at:
        # The grant predates the most recent attestation: re-federate so the
        # delegated scope reflects current posture rather than a prior one.
        raise StaleAttestationError(
            f"delegated token for {token.subject} predates latest attestation; "
            "re-federate before exercising scope"
        )
