# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/what-structural-signals-indicate-aaif-agent-identity-attestation-is-being-satisfied-by-a-delegated-credential-rather-than-the-workload-s-own-hardware.md
# Remnant Warrant:    https://corpusfetch.com/c/what-structural-signals-indicate-aaif-agent-identity-attestation-is-being-satisfied-by-a-delegated-credential-rather-than-the-workload-s-own-hardware.warrant.json
# Markdown SHA-256:   f084fb619dd89ec1228008fa929fdeb2212c092a4254290b368b3b786fe0f120
# Code AST SHA-256:   086d991a806d1aceaaac83b97c0e23bd707329b7ee0082bfaa87d7af5a770a3b
# Verified Classes:   AttestationBindingError, ChainEvidence
# Defensive Guards:   4 fail-closed invariants (zero external deps)

from dataclasses import dataclass
from typing import Optional


class AttestationBindingError(RuntimeError):
    """Raised when a delegation chain's leaf is not bound to the hardware root."""


@dataclass
class ChainEvidence:
    root_nonce: bytes                 # nonce the verifier issued
    root_bound_nonce: bytes           # nonce actually inside the hardware quote
    root_attested_at: float           # unix ts of hardware attestation
    leaf_key_first_seen: float        # unix ts leaf key was registered/minted
    leaf_has_key_attestation: bool    # TPM2_Certify / enclave key-attest present
    max_delegation_depth: int
    leaf_hardware_bound_claim: bool   # asserted by delegator, not proven


def assert_leaf_hardware_bound(ev: ChainEvidence) -> None:
    if ev.root_bound_nonce != ev.root_nonce:
        raise AttestationBindingError(
            "verifier nonce is not bound into the hardware-rooted element; "
            "leaf proof-of-possession is decoupled from the root quote"
        )
    if not ev.leaf_has_key_attestation:
        raise AttestationBindingError(
            "leaf presents no key-attestation statement; chain is satisfiable "
            "with a software key and cannot inherit root assurance"
        )
    if ev.leaf_key_first_seen > ev.root_attested_at:
        raise AttestationBindingError(
            f"leaf key minted at {ev.leaf_key_first_seen} after root attestation "
            f"at {ev.root_attested_at}; hardware quote cannot vouch for a later key"
        )
    if ev.max_delegation_depth >= 1 and ev.leaf_hardware_bound_claim:
        # Claim at depth >= 1 is asserted, not proven; require per-hop key-attest.
        if not ev.leaf_has_key_attestation:
            raise AttestationBindingError(
                "delegator asserts hardware_bound at depth >= 1 with no per-hop "
                "key-attestation; treating as delegation-only"
            )


def classify(ev: ChainEvidence) -> str:
    try:
        assert_leaf_hardware_bound(ev)
    except AttestationBindingError:
        return "delegation-only"   # apply software-key policy, not root assurance
    return "hardware-satisfied-at-leaf"
