# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/which-invariants-prevent-taint-laundering-of-retrieved-content-across-tool-and-retrieval-boundaries.md
# Remnant Warrant:    https://corpusfetch.com/c/which-invariants-prevent-taint-laundering-of-retrieved-content-across-tool-and-retrieval-boundaries.warrant.json
# Markdown SHA-256:   34f3a01df3ee0208e05bec6667674b233eee30f2e440a50b5d542eb3eb915f17
# Code AST SHA-256:   cbced85ebbcfcb94d9870e158fd0345f1096acf4a0d9db6fd750ea0c7fbf1a5e
# Verified Classes:   TaintLaunderingError
# Defensive Guards:   4 fail-closed invariants (zero external deps)

class TaintLaunderingError(RuntimeError):
    """Raised when a boundary would downgrade taint without a recorded declassification."""


MAX_TAINT = 3  # 0=clean, 1=internal, 2=external_untrusted, 3=adversarial


def join_taint(inputs: list[int]) -> int:
    return max(inputs) if inputs else 0


def apply_boundary(
    boundary_name: str,
    inputs: list[tuple[str, int]],
    output_taint: int,
    declassification_record: dict | None = None,
) -> int:
    """Enforce: output taint >= max input taint, unless declassified with justification."""
    required = join_taint([t for _, t in inputs])
    if output_taint < required:
        if declassification_record is None:
            raise TaintLaunderingError(
                f"boundary {boundary_name!r} downgraded taint "
                f"{required}->{output_taint} with no declassification record; "
                f"inputs={[n for n, _ in inputs]}"
            )
        if not declassification_record.get("justification"):
            raise TaintLaunderingError(
                f"boundary {boundary_name!r} declassification lacks justification"
            )
    return output_taint


def summarize_tool(text: str, input_taint: int) -> tuple[str, int]:
    # Label-aware boundary: must propagate at least input_taint.
    summary = text[:200]
    propagated = join_taint([input_taint])
    if propagated < input_taint:
        raise TaintLaunderingError("summarize_tool lost taint during paraphrase")
    return summary, propagated


def route_action(source_name: str, source_taint: int, action: str) -> None:
    if source_taint >= 2:
        raise TaintLaunderingError(
            f"refusing action {action!r} attributed to tainted source "
            f"{source_name!r} (taint={source_taint})"
        )
    # execute action
