# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/under-what-conditions-must-an-instance-refuse-a-federated-agent-card-whose-signature-chain-is-valid-but-whose-delegation-depth-exceeds-the-trust-ancho.md
# Remnant Warrant:    https://corpusfetch.com/c/under-what-conditions-must-an-instance-refuse-a-federated-agent-card-whose-signature-chain-is-valid-but-whose-delegation-depth-exceeds-the-trust-ancho.warrant.json
# Markdown SHA-256:   81853c1ec1c98d8f7deb223356f0918479037a23cca6815935259c9c9e7be52d
# Code AST SHA-256:   2ca4da99743e7f3db9a93806317c3492b27ceb749485b50c56b723e63adf2a16
# Verified Classes:   TrustFederationError, Hop
# Defensive Guards:   4 fail-closed invariants (zero external deps)

from dataclasses import dataclass


class TrustFederationError(RuntimeError):
    """Raised when a federated Agent Card violates delegation-budget invariants."""
    pass


@dataclass
class Hop:
    issuer: str
    subject: str
    max_delegation_depth: int  # budget this hop *grants* downstream; absent => 0
    signature_valid: bool


def verify_federated_card(chain: list[Hop], anchor_budget: int) -> None:
    """
    chain[0] is the credential issued by the trust anchor; chain[-1] is the leaf.
    Enforces per-hop budget monotonicity, not merely signature validity.
    """
    if not chain:
        raise TrustFederationError("empty delegation chain")

    for i, hop in enumerate(chain):
        if not hop.signature_valid:
            raise TrustFederationError(f"hop {i} ({hop.issuer}) signature invalid")

    # Running budget carried from the anchor. Anchor grants anchor_budget.
    held = anchor_budget
    for i, hop in enumerate(chain):
        # This hop consumes one unit of budget to exist as an issuer.
        held_after_consumption = held - 1
        if held_after_consumption < 0:
            raise TrustFederationError(
                f"hop {i} ({hop.subject}) exceeds anchor budget: "
                f"effective depth {i + 1} > {anchor_budget}"
            )
        # The hop may not grant more than it holds.
        if hop.max_delegation_depth > held_after_consumption:
            raise TrustFederationError(
                f"over-delegation at hop {i} ({hop.issuer}): "
                f"granted {hop.max_delegation_depth}, held {held_after_consumption}"
            )
        held = hop.max_delegation_depth

    # held is remaining budget at the leaf; negative would already have raised.
    return None


def ingest_card(chain: list[Hop], anchor_budget: int) -> str:
    verify_federated_card(chain, anchor_budget)
    return "ACCEPTED"


# Observed failing case: A.root(1) -> A.broker(0) -> B.gateway(3) -> B.subagent-7
observed = [
    Hop("A.root", "A.broker", max_delegation_depth=0, signature_valid=True),
    Hop("A.broker", "B.gateway", max_delegation_depth=3, signature_valid=True),
    Hop("B.gateway", "B.subagent-7", max_delegation_depth=0, signature_valid=True),
]
# Raises TrustFederationError: over-delegation at hop 1 (A.broker): granted 3, held 0
