# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/how-should-an-instance-distinguish-a-federation-trust-broker-denial-from-a-transient-discovery-failure-in-cross-org-agent-federation.md
# Remnant Warrant:    https://corpusfetch.com/c/how-should-an-instance-distinguish-a-federation-trust-broker-denial-from-a-transient-discovery-failure-in-cross-org-agent-federation.warrant.json
# Markdown SHA-256:   9ffce44d845f4306f56ba3cdd01481a1dce260f4252a114223d4a86bb183f689
# Code AST SHA-256:   4d9820bf6e459134090ab71290f74d2d00679f7fd83d492a71b4f511c21a6774
# Verified Classes:   FederationResolutionError, OutcomeKind, ResolutionOutcome
# Defensive Guards:   3 fail-closed invariants (zero external deps)

import time
from dataclasses import dataclass
from enum import Enum


class FederationResolutionError(RuntimeError):
    """Raised when a federated resolution cannot be safely classified."""


class OutcomeKind(Enum):
    DENIAL = "denial"            # terminal policy verdict
    UNAVAILABLE = "unavailable"  # transient, retryable
    UNKNOWN = "unknown"          # no valid attestation envelope


@dataclass
class ResolutionOutcome:
    capability: str
    descriptor: dict | None
    envelope: bytes | None
    envelope_type: str | None
    transport_error: bool = False


def verify_envelope(envelope: bytes | None, broker_key: bytes) -> bool:
    # Placeholder for real signature verification over the attestation envelope.
    return envelope is not None and broker_key is not None and len(envelope) > 0


def classify(outcome: ResolutionOutcome, broker_key: bytes) -> OutcomeKind:
    if outcome.transport_error:
        return OutcomeKind.UNAVAILABLE
    if not verify_envelope(outcome.envelope, broker_key):
        # Unattested outcome: broker contract violation, not a verdict.
        return OutcomeKind.UNKNOWN
    if outcome.envelope_type == "denial":
        return OutcomeKind.DENIAL
    if outcome.envelope_type == "unavailable":
        return OutcomeKind.UNAVAILABLE
    raise FederationResolutionError(
        f"broker emitted signed envelope with unrecognized type "
        f"{outcome.envelope_type!r} for capability {outcome.capability!r}"
    )


def resolve_with_policy(
    outcome: ResolutionOutcome,
    broker_key: bytes,
    max_transient_retries: int = 5,
    base_backoff: float = 0.5,
) -> OutcomeKind:
    kind = classify(outcome, broker_key)

    if kind is OutcomeKind.DENIAL:
        # Terminal: never retry, never fail over on the assumption of outage.
        return kind

    if kind is OutcomeKind.UNKNOWN:
        # Do not treat as denial. Bounded retry, then escalate as contract fault.
        for attempt in range(max_transient_retries):
            time.sleep(base_backoff * (2 ** attempt))
            # Re-resolution would occur here; if still unattested, escalate.
        raise FederationResolutionError(
            f"unattested resolution outcome for {outcome.capability!r}; "
            "broker failed to emit a verifiable negative attestation"
        )

    # UNAVAILABLE: bounded retry, then escalate as transient exhaustion.
    for attempt in range(max_transient_retries):
        time.sleep(base_backoff * (2 ** attempt))
    raise FederationResolutionError(
        f"transient unavailability persisted for {outcome.capability!r} "
        f"after {max_transient_retries} retries"
    )
