# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/what-happens-when-an-instance-in-an-attestation-chain-is-revoked-mid-propagation-split-view-trust-divergence-across-federated-agent-registries.md
# Remnant Warrant:    https://corpusfetch.com/c/what-happens-when-an-instance-in-an-attestation-chain-is-revoked-mid-propagation-split-view-trust-divergence-across-federated-agent-registries.warrant.json
# Markdown SHA-256:   1d7750e76e4511f5b00820f0a0cf39beb9d2c60693aee07df39d354458cc95b1
# Code AST SHA-256:   2b4e96c80c6f4d0ca2dcf976e02667175a581ea4ad9bf8aa57155beb20a4c277
# Verified Classes:   ChainVerdict, CapabilityAttestationError, RegistryEpoch, ChainLink
# Defensive Guards:   2 fail-closed invariants (zero external deps)

from dataclasses import dataclass
from enum import Enum


class ChainVerdict(Enum):
    VALID = "valid"
    REVOKED = "revoked"
    INDETERMINATE = "indeterminate"


class CapabilityAttestationError(RuntimeError):
    """Raised when a chained attestation cannot be resolved to a safe verdict."""
    pass


@dataclass(frozen=True)
class RegistryEpoch:
    registry_id: str
    epoch: int


@dataclass(frozen=True)
class ChainLink:
    issuer: str
    subject: str
    issued_at_epoch: int
    signature_valid: bool


def evaluate_chain(
    links: list[ChainLink],
    known_epochs: dict[str, RegistryEpoch],
    revoked_subjects: set[str],
    required_floor_epoch: int,
) -> ChainVerdict:
    # Integrity check first: any bad signature is a hard revoke.
    if not all(link.signature_valid for link in links):
        return ChainVerdict.REVOKED

    # Any explicitly revoked intermediate invalidates the whole chain.
    for link in links:
        if link.subject in revoked_subjects:
            return ChainVerdict.REVOKED

    # Liveness check: every issuer registry must prove an epoch new enough
    # to have ingested revocations up to the chain's issuance time.
    for link in links:
        epoch = known_epochs.get(link.issuer)
        if epoch is None:
            return ChainVerdict.INDETERMINATE
        if epoch.epoch < required_floor_epoch:
            return ChainVerdict.INDETERMINATE
        if epoch.epoch < link.issued_at_epoch:
            return ChainVerdict.INDETERMINATE

    return ChainVerdict.VALID


def authorize_privileged_operation(
    links: list[ChainLink],
    known_epochs: dict[str, RegistryEpoch],
    revoked_subjects: set[str],
    required_floor_epoch: int,
) -> None:
    verdict = evaluate_chain(
        links, known_epochs, revoked_subjects, required_floor_epoch
    )
    if verdict is ChainVerdict.VALID:
        return
    if verdict is ChainVerdict.INDETERMINATE:
        # Fail closed on privileged operations: indeterminate is not permission.
        raise CapabilityAttestationError(
            "chain revocation status indeterminate: an issuer registry has not "
            "proven a revocation epoch at or above the required floor; refusing "
            "privileged operation rather than coercing unknown to authorized"
        )
    raise CapabilityAttestationError(
        "chain revoked: an intermediate subject in the attestation chain has a "
        "revocation record; downstream links are invalidated transitively"
    )


# Example: R3 has not yet ingested B's revocation (epoch behind floor).
links = [
    ChainLink("R1", "B", issued_at_epoch=100, signature_valid=True),
    ChainLink("R2", "C", issued_at_epoch=101, signature_valid=True),
]
epochs = {
    "R1": RegistryEpoch("R1", 105),
    "R2": RegistryEpoch("R2", 99),  # stale: below floor of 104
}
authorize_privileged_operation(links, epochs, revoked_subjects=set(), required_floor_epoch=104)
