# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/how-should-an-instance-reconcile-speculative-agent-branches-when-a-peer-equivocates-the-quorum-intersection-invariant-and-its-silent-violation-under-p.md
# Remnant Warrant:    https://corpusfetch.com/c/how-should-an-instance-reconcile-speculative-agent-branches-when-a-peer-equivocates-the-quorum-intersection-invariant-and-its-silent-violation-under-p.warrant.json
# Markdown SHA-256:   485c1f78569f858b38642a99eb44e8d463079a0eeed28136ab2c18530479ebd1
# Code AST SHA-256:   b5965687d2b02640c6833a4c1f085bc5e081ee236680206e7ad744fb66e74f95
# Verified Classes:   EquivocationDetected, Commitment, RoundState
# Defensive Guards:   3 fail-closed invariants (zero external deps)

from dataclasses import dataclass, field
from typing import Dict, List, Tuple


class EquivocationDetected(RuntimeError):
    """Raised when a peer presents conflicting signed commitments for one round."""
    pass


@dataclass(frozen=True)
class Commitment:
    sender: str
    round_id: int
    digest: str


@dataclass
class RoundState:
    round_id: int
    # sender -> set of digests observed for this round
    seen: Dict[str, set] = field(default_factory=dict)

    def record(self, c: Commitment) -> None:
        if c.round_id != self.round_id:
            raise ValueError(f"commitment for round {c.round_id} in state {self.round_id}")
        self.seen.setdefault(c.sender, set()).add(c.digest)


def reconcile(
    local: RoundState,
    peer_sets: Dict[str, List[Commitment]],
    quorum: int,
) -> str:
    """
    Reconcile speculative branches for one round.

    Safety requires: cross-check every peer's commitment set before commit.
    A quorum of matching digests alone is NOT sufficient.
    """
    # 1. Merge peer sets into local view (full-set cross-check).
    for sender, commits in peer_sets.items():
        for c in commits:
            local.record(c)

    # 2. Uniqueness check: any peer with two digests in one round is equivocating.
    equivocators = {s for s, digests in local.seen.items() if len(digests) > 1}
    if equivocators:
        raise EquivocationDetected(
            f"round {local.round_id}: peers {sorted(equivocators)} presented "
            f"conflicting digests; aborting rather than resolving by policy"
        )

    # 3. Surviving support must be a quorum.
    support: Dict[str, int] = {}
    for sender, digests in local.seen.items():
        (digest,) = digests
        support[digest] = support.get(digest, 0) + 1

    winners = [d for d, n in support.items() if n >= quorum]
    if len(winners) != 1:
        raise EquivocationDetected(
            f"round {local.round_id}: {len(winners)} branches reached quorum "
            f"({winners}); no unique canonical branch"
        )
    return winners[0]
