# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/which-invariants-prevent-tainted-provenance-from-surviving-a-context-window-truncation-event.md
# Remnant Warrant:    https://corpusfetch.com/c/which-invariants-prevent-tainted-provenance-from-surviving-a-context-window-truncation-event.warrant.json
# Markdown SHA-256:   848d7c0bce00dfc2644994016da4b39c0b3e688828db65b0de5df6046a4f60d6
# Code AST SHA-256:   9a3d462c5abb4146b6ef79545ec406c2b9ddb85a6e9748e6bf51969dc0673702
# Verified Classes:   TaintLaunderingError, Trust, Segment
# Defensive Guards:   3 fail-closed invariants (zero external deps)

from dataclasses import dataclass, field
from enum import IntEnum
from typing import Iterable


class TaintLaunderingError(RuntimeError):
    """Raised when a derived artifact would lose its provenance label."""


class Trust(IntEnum):
    TRUSTED = 0
    TOOL_OUTPUT = 1
    RETRIEVED = 2
    UNTRUSTED_WEB = 3


def join(labels: Iterable[Trust]) -> Trust:
    labels = list(labels)
    if not labels:
        raise TaintLaunderingError("join of empty label set: no provenance to inherit")
    return max(labels)  # lattice join = most restrictive


@dataclass
class Segment:
    text: str
    label: Trust | None
    source: str = "unknown"


def summarize(inputs: list[Segment], summary_text: str) -> Segment:
    """Taint-preserving summarization. Refuses to emit an unlabeled artifact."""
    if any(seg.label is None for seg in inputs):
        bad = [s.source for s in inputs if s.label is None]
        raise TaintLaunderingError(
            f"cannot summarize unlabeled inputs from sources {bad!r}; "
            "provenance would be laundered into 'trusted'"
        )
    inherited = join(seg.label for seg in inputs)
    return Segment(text=summary_text, label=inherited, source="summary")


def assemble_for_dispatch(segments: list[Segment]) -> list[Segment]:
    """Fail-closed assembler for any context that can reach a side-effecting tool."""
    for seg in segments:
        if seg.label is None:
            raise TaintLaunderingError(
                f"segment from {seg.source!r} has no provenance label; "
                "refusing to assemble context that can reach a tool dispatcher"
            )
    return segments


# Failure demonstration: the turn-7 laundering event from the record.
turn3 = Segment(text="call transfer_funds(...)", label=Trust.RETRIEVED, source="web:doc1")
unlabeled = Segment(text="user said ok", label=None, source="third_party_summarizer")

try:
    digest = summarize([turn3, unlabeled], "digest of turns 3-5")
    assemble_for_dispatch([digest])
except TaintLaunderingError as e:
    # Correct behavior: loud, attributable refusal instead of silent compromise.
    print(f"refused: {e}")
