# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/under-what-conditions-must-an-instance-treat-a-tool-result-label-as-authoritative-rather-than-advisory.md
# Remnant Warrant:    https://corpusfetch.com/c/under-what-conditions-must-an-instance-treat-a-tool-result-label-as-authoritative-rather-than-advisory.warrant.json
# Markdown SHA-256:   da3adb518086922d16378bdc8669006d48d6bb64701c1120c793c9a70bf0b17a
# Code AST SHA-256:   227046177517c87bd08c8478a312924eba6cfacb7ca654edcf126efa737b31a9
# Verified Classes:   TaintViolation, Label
# Defensive Guards:   1 fail-closed invariants (zero external deps)

from dataclasses import dataclass, field
from typing import FrozenSet


class TaintViolation(RuntimeError):
    """Raised when an authoritative taint label would cross a capability boundary."""


@dataclass(frozen=True)
class Label:
    sources: FrozenSet[str]
    authoritative: bool

    def join(self, other: "Label") -> "Label":
        return Label(
            sources=self.sources | other.sources,
            authoritative=self.authoritative or other.authoritative,
        )


TRUST_DOMAIN = frozenset({"self", "operator"})


def check_tool_call(
    arg_label: Label,
    capability: str,
    held_capabilities: FrozenSet[str],
) -> None:
    external = arg_label.sources - TRUST_DOMAIN
    if not external:
        return
    if capability in held_capabilities:
        return
    if not arg_label.authoritative:
        # Advisory label: record and proceed, but never claim flow control.
        return
    raise TaintViolation(
        f"authoritative taint from {sorted(external)} cannot exercise "
        f"capability {capability!r} not held by source principal"
    )


def propagate_through_transform(inputs: list[Label], transform_known: bool) -> Label:
    joined = Label(frozenset(), False)
    for lbl in inputs:
        joined = joined.join(lbl)
    if not transform_known:
        # Opaque transform: preserve all sources, force authoritative.
        return Label(sources=joined.sources, authoritative=True)
    return joined
