# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/when-must-an-instance-reject-a-genai-audit-event-whose-traceparent-was-minted-by-a-peer-organization.md
# Remnant Warrant:    https://corpusfetch.com/c/when-must-an-instance-reject-a-genai-audit-event-whose-traceparent-was-minted-by-a-peer-organization.warrant.json
# Markdown SHA-256:   75c5f616a164cb2873fe240d146c14b71ae274b183a61526b644108c02d8f5be
# Code AST SHA-256:   d261d94fe6a5610cb5fd3c3032bd2cb098fbf1faa2164a5f15cce269a33f63e3
# Verified Classes:   FederatedAuditRejection, Provenance, CorrelationKey, FederatedTraceIndex
# Defensive Guards:   3 fail-closed invariants (zero external deps)

from dataclasses import dataclass
from typing import Optional


class FederatedAuditRejection(RuntimeError):
    """Raised when a peer GenAI audit event violates the correlation invariant."""
    pass


@dataclass(frozen=True)
class Provenance:
    issuer_org: str
    trace_id: str
    span_id: str
    conversation_id: str
    signature_valid: bool
    issuer_pinned: bool
    sampled: bool
    carries_usage: bool
    age_seconds: float


@dataclass(frozen=True)
class CorrelationKey:
    issuer_org: str
    trace_id: str
    span_id: str


class FederatedTraceIndex:
    def __init__(self, reorder_window_s: float = 300.0):
        self._roots: dict[tuple[str, str], str] = {}  # (issuer, trace) -> root span
        self._reorder_window_s = reorder_window_s

    def _check(self, p: Provenance) -> Optional[str]:
        if not p.issuer_pinned or not p.signature_valid:
            raise FederatedAuditRejection(
                f"unpinned or unsigned issuer {p.issuer_org!r} for trace {p.trace_id}"
            )
        if p.sampled is False and p.carries_usage:
            raise FederatedAuditRejection(
                f"unsampled span {p.span_id} carries gen_ai.usage on trace {p.trace_id}"
            )
        if p.age_seconds > self._reorder_window_s:
            raise FederatedAuditRejection(
                f"event age {p.age_seconds}s exceeds reorder window "
                f"{self._reorder_window_s}s for trace {p.trace_id}"
            )
        prior_root = self._roots.get((p.issuer_org, p.trace_id))
        if prior_root is not None and prior_root != p.span_id:
            return "quarantine"
        return None

    def ingest(self, p: Provenance) -> str:
        verdict = self._check(p)
        if verdict == "quarantine":
            # Isolated; never merged. Rejection is audited, event is retained.
            return "quarantine"
        self._roots.setdefault((p.issuer_org, p.trace_id), p.span_id)
        return "admit"
