# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/in-what-scenarios-must-an-instance-refuse-task-delegation-across-a-federation-trust-boundary-when-the-peer-s-policy-digest-matches-but-its-negotiation.md
# Remnant Warrant:    https://corpusfetch.com/c/in-what-scenarios-must-an-instance-refuse-task-delegation-across-a-federation-trust-boundary-when-the-peer-s-policy-digest-matches-but-its-negotiation.warrant.json
# Markdown SHA-256:   82437cdf2056e155a0be17e1409afce93d6df2610ae7dd66f67de018158d3a01
# Code AST SHA-256:   1c7d37a0b80c9f687db5ab9fd6233f04454a12b41e70c9fdb7011d4fb2f1d0fc
# Verified Classes:   StaleEpochDelegationError
# Defensive Guards:   1 fail-closed invariants (zero external deps)

class StaleEpochDelegationError(RuntimeError):
    """Raised when a peer's policy digest matches the cached decision
    but the negotiation epoch does not confirm the cached authorization."""
    pass


def authorize_delegation(peer_digest: str, peer_epoch: int,
                         cached: dict | None, now: float) -> str:
    """Return 'delegate' | 'renegotiate'. Raise on unconfirmable/replay states."""
    if cached is None:
        return "renegotiate"

    if peer_digest != cached["digest"]:
        # Policy text changed: cached decision is void, renegotiate from scratch.
        return "renegotiate"

    cached_epoch = cached["epoch"]

    if peer_epoch < cached_epoch:
        # Digest matches but epoch regressed: replay or rolled-back peer.
        raise StaleEpochDelegationError(
            f"epoch regression: peer={peer_epoch} cached={cached_epoch} "
            f"digest={peer_digest[:12]}...; possible replay, escalate"
        )

    if peer_epoch > cached_epoch:
        # Peer is plausibly current but cached authorization is unconfirmed.
        return "renegotiate"

    if now > cached["expires_at"]:
        return "renegotiate"

    return "delegate"
