# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/which-invariants-prevent-silent-capability-resurrection-across-federated-agent-trust-brokers-during-partial-revocation.md
# Remnant Warrant:    https://corpusfetch.com/c/which-invariants-prevent-silent-capability-resurrection-across-federated-agent-trust-brokers-during-partial-revocation.warrant.json
# Markdown SHA-256:   dd58e9098ad649b2638bd6d5b7b5ddd683b01125cd4caf8230f26f0cfed14a61
# Code AST SHA-256:   2fe462fd1107d7653429f976518f490df2f7aae81f98b6ca51c6f14ff62895b3
# Verified Classes:   CapabilityResurrectionError, EpochRegressionError
# Defensive Guards:   3 fail-closed invariants (zero external deps)

class CapabilityResurrectionError(RuntimeError):
    """Raised when a derived token's ancestor was revoked before the child's mint epoch."""


class EpochRegressionError(RuntimeError):
    """Raised when an authority's epoch counter regresses, invalidating monotonicity."""


def verify_lineage_liveness(
    token: dict,
    ancestor_epochs: dict[str, int],
    token_mint_epochs: dict[str, int],
) -> None:
    """
    Enforce the lineage liveness invariant across the full ancestor chain.

    token: {"id": str, "parent_id": str | None, "mint_epoch": int, ...}
    ancestor_epochs: capability_id -> current revocation epoch at origin
    token_mint_epochs: capability_id -> epoch observed at that token's mint time
    """
    chain = []
    cursor = token
    while cursor is not None:
        chain.append(cursor)
        parent_id = cursor.get("parent_id")
        cursor = None if parent_id is None else {"id": parent_id, "parent_id": None, "mint_epoch": token_mint_epochs.get(parent_id, -1)}

    # Walk from root to leaf; each child's mint epoch must be >= parent's revocation epoch.
    for i in range(len(chain) - 1, 0, -1):
        child = chain[i]
        parent = chain[i - 1]
        parent_revocation_epoch = ancestor_epochs.get(parent["id"])
        if parent_revocation_epoch is None:
            raise CapabilityResurrectionError(
                f"ancestor {parent['id']} has no known epoch; cannot prove liveness for {child['id']}"
            )
        if parent_revocation_epoch < 0:
            raise EpochRegressionError(
                f"ancestor {parent['id']} epoch regressed to {parent_revocation_epoch}"
            )
        if child["mint_epoch"] < parent_revocation_epoch:
            raise CapabilityResurrectionError(
                f"token {child['id']} minted at epoch {child['mint_epoch']} "
                f"but ancestor {parent['id']} revoked at epoch {parent_revocation_epoch}"
            )


def admit_request(token: dict, ancestor_epochs: dict[str, int], token_mint_epochs: dict[str, int]) -> bool:
    try:
        verify_lineage_liveness(token, ancestor_epochs, token_mint_epochs)
    except (CapabilityResurrectionError, EpochRegressionError):
        return False
    return True
