# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/when-must-an-instance-refuse-a-federated-task-before-policy-negotiation-completes.md
# Remnant Warrant:    https://corpusfetch.com/c/when-must-an-instance-refuse-a-federated-task-before-policy-negotiation-completes.warrant.json
# Markdown SHA-256:   205a324e5e8bbf4d4a26127797d3869dd8315e392b31a00485f4dde0b70b0a0a
# Code AST SHA-256:   9e3c47dbf47c625444ca3b0db6d8971b7529770525fbb02ba683fcb25082f787
# Verified Classes:   FederationPolicyUnresolved, Advertisement, CachedNegotiation
# Defensive Guards:   1 fail-closed invariants (zero external deps)

from dataclasses import dataclass
from typing import Optional


class FederationPolicyUnresolved(RuntimeError):
    """Raised when a task would be routed to a peer capability whose policy
    digest has not been negotiated and no unexpired cached result exists."""
    pass


@dataclass(frozen=True)
class Advertisement:
    peer_id: str
    capability_id: str
    negotiation_epoch: int
    policy_digest: str


@dataclass(frozen=True)
class CachedNegotiation:
    policy_digest: str
    expires_at: float


def authorize_route(
    ad: Advertisement,
    accepted_digests: set[str],
    cache: Optional[CachedNegotiation],
    now: float,
    task_requires_policy: bool,
) -> str:
    """Return the policy digest under which the task may be routed.
    Raises FederationPolicyUnresolved if the capability is advertised but
    not yet authorized for this task's policy obligations."""
    if not task_requires_policy:
        # No policy obligation: advertisement alone is sufficient authority.
        return ad.policy_digest

    if ad.policy_digest in accepted_digests:
        return ad.policy_digest

    if cache is not None and cache.expires_at > now:
        return cache.policy_digest

    # Advertised but unauthorized: refuse before dispatch, do not retry
    # as a transport error.
    raise FederationPolicyUnresolved(
        f"capability {ad.capability_id!r} on peer {ad.peer_id!r} "
        f"epoch {ad.negotiation_epoch} advertised digest {ad.policy_digest!r} "
        f"is not in the accepted policy set and has no live cached "
        f"negotiation result; holding task pending policy resolution"
    )
