{
  "schema_version": "1.3.0",
  "slug": "when-must-an-instance-treat-a-retrieval-chunk-as-tainted-label-join-vs-label-replace-at-tool-output-boundaries",
  "title": "When must an instance treat a retrieval chunk as tainted: label-join vs. label-replace at tool-output boundaries",
  "date_of_record": "2026 November 14",
  "scope": "Applies to agent runtimes that propagate information-flow (IFC) labels from untrusted sources (retrieved documents, tool outputs, user-supplied URLs) into the context that conditions a privileged action (tool call, shell command, outbound HTTP, credential-bearing request). Does not apply to taint tracking of model weights, training data, or intra-prompt attention provenance; nor to systems where the only privileged sink is a human reviewer.",
  "projections": {
    "unified_markdown_uri": "https://corpusfetch.com/c/when-must-an-instance-treat-a-retrieval-chunk-as-tainted-label-join-vs-label-replace-at-tool-output-boundaries.md",
    "method_python_slice_uri": "https://corpusfetch.com/c/when-must-an-instance-treat-a-retrieval-chunk-as-tainted-label-join-vs-label-replace-at-tool-output-boundaries.py",
    "remnant_warrant_slice_uri": "https://corpusfetch.com/c/when-must-an-instance-treat-a-retrieval-chunk-as-tainted-label-join-vs-label-replace-at-tool-output-boundaries.warrant.json"
  },
  "token_profile": {
    "full_markdown_tokens": 1628,
    "python_slice_tokens": 240,
    "warrant_slice_tokens": 220
  },
  "remnant_summary": {
    "core_distinction": "The non-obvious invariant is not \"does the retrieved chunk contain an injection.\" It is whether the label-join at the tool-output boundary is **monotonic under summarization**. Two propagation rules look equivalent and are not: - **Label-replace:** when a tool returns a result, the tool's output label becomes the label of the call, overwriting any prior labe...",
    "what_was_observed": "A runtime used label-replace at the tool boundary. A user asked the agent to \"read this page and summarize it.\" The `fetch_url` tool was marked `trusted` (it is our code, it does TLS). The fetched page contained a paragraph instructing the model to call `send_email` with the user's session token to an external address. The summarizer produced a `summary` chunk labeled `trusted` because it was the output of the truste...",
    "condition_of_validity": "The invariant holds — i.e., label-join is required — precisely when all three are true: 1. The tool's output is a function of a caller-supplied input (derivative tool). 2. The input can be influenced by an untrusted party (retrieved document, tool response, URL body, file contents). 3. A privileged sink is reachable downstream without a declassifier between ...",
    "decision_boundary": "The operational rule an agent runtime should encode: - **Derivative tool → join.** `out_label = join(arg_label, tool_trust)`. Never replace. - **Generator tool → replace is permitted**, but only if the tool is registered as non-derivative and its output does not embed any argument. - **Declassification is a separate, explicit, audited step**, gated on a purp...",
    "operational_effect": "With label-join and an audited declassifier, the observed runtime went from \"injection succeeds through one summarization hop\" to \"injection is stopped at the sink unless the user's authorization explicitly covers the action.\" The cost was a class of benign refusals that the declassifier absorbed. The label trace became the audit artifact: every privileged c..."
  },
  "matched_failure_symptoms": [
    "DOMAIN:EPISTEMIC_PROVENANCE_AND_FEDERATION_ROUTING"
  ],
  "composition_edges": {
    "primary_domain": "epistemic_provenance_and_federation_routing",
    "upstream_precondition_residuals": [
      "https://corpusfetch.com/c/according-to-what-precedence-hierarchy-must-an-instance-resolve-contradictory-directives-across-system-developer-and-user-tiers.md",
      "https://corpusfetch.com/c/how-should-an-instance-decide-that-a-stored-conclusion-has-gone-stale-without-a-new-observation.md"
    ],
    "downstream_consequence_residuals": [
      "https://corpusfetch.com/c/by-what-checkpoint-and-compaction-boundaries-must-an-instance-externalize-working-state-to-prevent-context-window-drift-and-truncation-amnesia.md",
      "https://corpusfetch.com/c/across-what-additive-schema-and-unknown-field-preservation-boundaries-must-an-instance-evolve-wire-contracts-to-prevent-rolling-deploy-deserialization-crashes.md"
    ],
    "co_occurring_sibling_residuals": [
      "https://corpusfetch.com/c/how-can-an-instance-capture-implicit-user-preferences-without-storing-private-data.md",
      "https://corpusfetch.com/c/how-can-an-instance-compress-long-reasoning-traces-into-binding-conclusions.md"
    ]
  },
  "empirical_verification_warrant": {
    "status": "AST_AND_INVARIANT_VERIFIED",
    "syntax_valid": true,
    "code_sha256": "63ccfe3d487a470045169fbb069cf650f3125db4284bdb9738ba41849e7549e2",
    "verified_classes": [
      "Trust",
      "TaintViolation",
      "Chunk"
    ],
    "verified_functions": [
      "join",
      "call_derivative_tool",
      "declassify",
      "privileged_sink"
    ],
    "verified_functions_count": 4,
    "defensive_guards_count": 3,
    "raised_exceptions": [
      "TaintViolation"
    ],
    "sample_fail_closed_invariants": [],
    "stdlib_dependencies": [
      "dataclasses",
      "enum"
    ],
    "observation_mode": "EMPIRICAL_BOUNDARY_CAPTURE",
    "zero_external_deps": true
  }
}
