# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/when-must-an-instance-refuse-a-peer-agent-s-attestation-chain-despite-a-cryptographically-valid-signature.md
# Remnant Warrant:    https://corpusfetch.com/c/when-must-an-instance-refuse-a-peer-agent-s-attestation-chain-despite-a-cryptographically-valid-signature.warrant.json
# Markdown SHA-256:   b0bf60b01c127a072ce7fde3e6a8485bf792a146294bcfbaa13a6932ce6f486e
# Code AST SHA-256:   62bb96e686805ab3ad58375d7bb98ea3a8fd2a0d991847ca4b72649bdbcafa47
# Verified Classes:   AttestationTrustError, ScopeEscalation, AuthorityNarrowed, IndeterminateAuthority, Link, AuthorityRecord
# Defensive Guards:   4 fail-closed invariants (zero external deps)

import time
from dataclasses import dataclass
from typing import Optional


class AttestationTrustError(RuntimeError):
    """Base for cross-org attestation trust failures."""


class ScopeEscalation(AttestationTrustError):
    pass


class AuthorityNarrowed(AttestationTrustError):
    pass


class IndeterminateAuthority(AttestationTrustError):
    pass


@dataclass
class Link:
    issuer: str
    asserted_scope: frozenset
    delegable_scope_at_issuance: frozenset
    issued_at: float
    asserted_class: str
    authorized_classes: frozenset


@dataclass
class AuthorityRecord:
    issuer: str
    capability_class: str
    narrowed_effective: Optional[float]  # None => never narrowed
    reachable: bool


def evaluate_chain(
    chain: list,
    authority_lookup,
    evaluation_instant: float,
    trust_window: float,
) -> None:
    # 1. Scope monotonicity and class binding across every link.
    for i in range(len(chain) - 1):
        child, parent = chain[i], chain[i + 1]
        if not child.asserted_scope <= parent.delegable_scope_at_issuance:
            raise ScopeEscalation(
                f"link {child.issuer} asserts {child.asserted_scope} "
                f"exceeding parent delegable {parent.delegable_scope_at_issuance}"
            )
    leaf = chain[0]
    if leaf.asserted_class not in leaf.authorized_classes:
        raise ScopeEscalation(
            f"key {leaf.issuer} not authorized to assert class {leaf.asserted_class}"
        )

    # 2. Temporal authority + reachability, fail-closed.
    for link in chain:
        rec: AuthorityRecord = authority_lookup(link.issuer, link.asserted_class)
        if not rec.reachable:
            raise IndeterminateAuthority(
                f"authority record for {link.issuer}/{link.asserted_class} "
                f"unreachable within trust window {trust_window}s"
            )
        if (
            rec.narrowed_effective is not None
            and rec.narrowed_effective <= evaluation_instant
            and rec.narrowed_effective > link.issued_at
        ):
            raise AuthorityNarrowed(
                f"{link.issuer} authority for {link.asserted_class} narrowed at "
                f"{rec.narrowed_effective}, after issuance {link.issued_at}, "
                f"before evaluation {evaluation_instant}"
            )
    # All four conditions hold; caller may proceed and must record evaluation_instant.
