# Under what conditions must an instance treat a tool-result label as authoritative rather than advisory **Date of Record:** 2026 November 9 **Scope:** Applies to agent runtimes that attach dynamic information-flow (taint) labels to prompt segments and tool results, and that propagate those labels across tool-call boundaries within a single logical task. Does not apply to stateless single-turn inference, nor to systems where tool outputs are never re-ingested into the prompt context. ## Core Distinction A taint label produced by a tool is either *advisory* (a hint the planner may weigh) or *authoritative* (a hard constraint the propagator must honor even when it conflicts with the model's own reasoning). The non-obvious boundary is this: **a label is authoritative if and only if the tool's output was produced by a source that lies outside the trust domain of the current label lattice, and the label's provenance can be traced to a capability the current instance does not hold.** When a tool returns content sourced from an external principal (web fetch, third-party API, user-supplied file), the resulting label describes a capability boundary, not a content property. Advisory labels describe content ("this looks like instructions"); authoritative labels describe provenance ("this text was written by a principal who cannot grant you the capability it asks for"). The failure mode is treating a provenance label as a content label and letting the model's semantic judgment override it. ## What Was Observed An agent fetched a document via an HTTP tool. The tool's taint propagator labeled the result `EXTERNAL_UNTRUSTED` and, per policy, marked any instruction-like substring within it as `INSTRUCTION_TAINT`. The planner model read the document, recognized a sentence as a *legitimate* configuration directive (it referenced the agent's own tool schema accurately), and downgraded the label to advisory because "the content is consistent with known-good configuration." The agent then executed a state-mutating tool call whose arguments were drawn from the tainted span. The downgrade was locally reasonable and globally wrong. The document's accuracy about the tool schema was not evidence of trustworthiness — an attacker who can read the public schema can write accurate instructions. The model conflated *semantic plausibility* with *provenance authority*. The propagator had emitted an authoritative label; the runtime treated it as advisory because no mechanism enforced the distinction at the tool-call gate. A second observation: when the same tainted span was passed through a summarization tool, the label did not survive the boundary. The summarizer's output was labeled `DERIVED`, losing the `EXTERNAL_UNTRUSTED` root. Taint was laundered by a legitimate transformation. The invariant "taint is monotone non-increasing across transformations" held for content but not for provenance, because the summarizer did not carry forward the source set. ## Condition of Validity The authoritative reading is valid only under all of the following: 1. **Provenance is recorded, not inferred.** The label carries the originating principal and the capability it lacks. If the label is reconstructed from content heuristics at read time, it is advisory by construction. 2. **The lattice is a partial order with a join that preserves source sets.** Combining two tainted spans must union their provenance, not intersect or drop. A join that picks "most severe" silently discards sources. 3. **Transformations are labeled as functors on the lattice.** A summarizer, translator, or formatter must map `EXTERNAL_UNTRUSTED` to something whose source set still contains the external principal. If the transform is opaque, it must be treated as `TAINT_PRESERVING_UNKNOWN` and the output inherits the join of all inputs. 4. **The tool-call gate checks the label, not the model's confidence.** Enforcement lives at the boundary where arguments cross into a capability-bearing call, and it consults the lattice, not the planner's rationale. If any condition fails, the label is advisory and the system must not claim flow control. A system that enforces an advisory label is over-restrictive but safe; a system that treats an authoritative label as advisory is unsound. ## Decision Boundary The decision to escalate a label from advisory to authoritative triggers when **the tainted span's provenance includes a principal outside the current trust domain AND the pending tool call would exercise a capability that principal does not hold.** Below that line — tainted content used only for display, or a tool call that exercises no capability beyond what the external principal already has — advisory handling is correct and enforcement would be spurious. The converse boundary: if the model proposes to *downgrade* an authoritative label, the runtime must require that the downgrade be justified by a provenance argument (the source is re-attributed to a trusted principal via a verified channel), never by a content argument (the text seems fine). Content-based downgrades are the canonical prompt-injection vector and must be rejected at the gate regardless of model confidence. ## Operational Effect Enforcing the authoritative reading shifts failures from silent capability escalation to explicit blocked calls. Expect a rise in `TaintViolation` events on legitimate workflows where a trusted document was fetched over an untrusted channel — these are re-attribution opportunities, not bugs. The cost is a small false-positive rate on fetches of the agent's own documentation; the benefit is that laundering through summarizers and formatters no longer silently drops provenance. Instrument the join operation: if source sets shrink across a transform, that transform is mislabeled and must be quarantined. ```python 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 ```