# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/which-invariants-prevent-equivocation-in-byzantine-resilient-agent-registry-gossip-under-partial-synchrony.md
# Remnant Warrant:    https://corpusfetch.com/c/which-invariants-prevent-equivocation-in-byzantine-resilient-agent-registry-gossip-under-partial-synchrony.warrant.json
# Markdown SHA-256:   34772b5fbebbcf6322b1c55c85f801577353bfe89113015bb691066f119bc104
# Code AST SHA-256:   479b664d0810ab575e50d3c47c4624e63ebbde7cae55f4092d8865d4c4e8698e
# Verified Classes:   EpochUnconfirmedError, Certificate, RegistryView
# Defensive Guards:   5 fail-closed invariants (zero external deps)

from __future__ import annotations

from dataclasses import dataclass
from typing import Dict, FrozenSet, Tuple


class EpochUnconfirmedError(RuntimeError):
    """Raised when a capability certificate cannot be proven unique for its (agent, epoch)."""


@dataclass(frozen=True)
class Certificate:
    agent_id: str
    epoch: int
    capability_hash: str
    quorum_signers: FrozenSet[str]
    sequencer_ack: bool


class RegistryView:
    def __init__(self, quorum_size: int) -> None:
        self._quorum_size = quorum_size
        self._confirmed: Dict[str, Tuple[int, str]] = {}  # agent -> (epoch, cap_hash)

    def admit(self, cert: Certificate) -> None:
        if len(cert.quorum_signers) < self._quorum_size:
            raise EpochUnconfirmedError(
                f"agent={cert.agent_id} epoch={cert.epoch}: quorum too small "
                f"({len(cert.quorum_signers)}/{self._quorum_size})"
            )
        if not cert.sequencer_ack:
            raise EpochUnconfirmedError(
                f"agent={cert.agent_id} epoch={cert.epoch}: missing sequencer acknowledgement; "
                "cannot prove uniqueness, refusing to serve capability"
            )
        prior = self._confirmed.get(cert.agent_id)
        if prior is not None:
            prior_epoch, prior_hash = prior
            if cert.epoch < prior_epoch:
                raise EpochUnconfirmedError(
                    f"agent={cert.agent_id}: stale epoch {cert.epoch} < confirmed {prior_epoch}"
                )
            if cert.epoch == prior_epoch and cert.capability_hash != prior_hash:
                raise EpochUnconfirmedError(
                    f"agent={cert.agent_id} epoch={cert.epoch}: equivocation detected "
                    f"({cert.capability_hash!r} != {prior_hash!r})"
                )
        self._confirmed[cert.agent_id] = (cert.epoch, cert.capability_hash)

    def resolve(self, agent_id: str) -> str:
        if agent_id not in self._confirmed:
            raise EpochUnconfirmedError(f"agent={agent_id}: no confirmed capability in view")
        return self._confirmed[agent_id][1]
