# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/how-should-an-instance-reconcile-a-tamper-evident-audit-trail-when-an-a2a-hop-is-replayed-by-a-non-aaif-signer.md
# Remnant Warrant:    https://corpusfetch.com/c/how-should-an-instance-reconcile-a-tamper-evident-audit-trail-when-an-a2a-hop-is-replayed-by-a-non-aaif-signer.warrant.json
# Markdown SHA-256:   1856d9c61da6222082d5829fa52fcc5ddc7850ed940acbac2d3adc556451812a
# Code AST SHA-256:   aafbe83c422cf3bbbdf7666ec5661f080cb76f6fc57607894cbcd230cb2274b9
# Verified Classes:   ProvenanceSpliceError, Hop
# Defensive Guards:   4 fail-closed invariants (zero external deps)

import hashlib
from dataclasses import dataclass

class ProvenanceSpliceError(RuntimeError):
    pass

@dataclass(frozen=True)
class Hop:
    signer: str
    prev_hash: str
    payload: bytes

    @property
    def content_hash(self) -> str:
        return hashlib.sha256(self.prev_hash.encode() + self.payload).hexdigest()

def reconcile_hop(
    hop: Hop,
    *,
    branch: str,
    branch_entitlement: dict[str, set[str]],
    federation_seen_hashes: set[str],
    signature_ok: bool,
    linkage_ok: bool,
) -> str:
    if not signature_ok:
        raise ProvenanceSpliceError(f"invalid AAIF signature from {hop.signer}")
    if not linkage_ok:
        raise ProvenanceSpliceError("predecessor hash does not link to branch head")

    if hop.content_hash in federation_seen_hashes:
        raise ProvenanceSpliceError(
            f"replay detected: hop {hop.content_hash[:12]} already observed in federation"
        )

    entitled = branch_entitlement.get(branch, set())
    if hop.signer not in entitled:
        raise ProvenanceSpliceError(
            f"signer {hop.signer} not entitled to extend branch {branch}"
        )

    return "accepted"
