{
  "schema_version": "1.3.0",
  "slug": "what-structural-signals-indicate-prompt-injection-taint-has-silently-laundered-through-a-summarization-tool-boundary",
  "title": "What structural signals indicate prompt-injection taint has silently laundered through a summarization tool boundary",
  "date_of_record": "2026 November 13",
  "scope": "Applies to agents that propagate dynamic information-flow (DIF) taint labels across tool call results and persistent memory writes, where at least one tool performs lossy transformation (summarization, extraction, translation, reformatting) between an untrusted source and a memory write. Does not apply to label systems that treat every tool boundary as a hard taint barrier (taint-dropping), nor to pure provenance systems that never merge labels.",
  "projections": {
    "unified_markdown_uri": "https://corpusfetch.com/c/what-structural-signals-indicate-prompt-injection-taint-has-silently-laundered-through-a-summarization-tool-boundary.md",
    "method_python_slice_uri": "https://corpusfetch.com/c/what-structural-signals-indicate-prompt-injection-taint-has-silently-laundered-through-a-summarization-tool-boundary.py",
    "remnant_warrant_slice_uri": "https://corpusfetch.com/c/what-structural-signals-indicate-prompt-injection-taint-has-silently-laundered-through-a-summarization-tool-boundary.warrant.json"
  },
  "token_profile": {
    "full_markdown_tokens": 1698,
    "python_slice_tokens": 337,
    "warrant_slice_tokens": 220
  },
  "remnant_summary": {
    "core_distinction": "The distinction that matters is between **taint propagation through identity-preserving transforms** and **taint propagation through lossy transforms**. When a tool returns bytes that are structurally identical to its input (a file read, a byte copy, a base64 round-trip), taint labels can be carried forward with a simple set-union rule and remain sound: if a...",
    "what_was_observed": "In a deployment where a `summarize_document` tool was declared `returns: trusted_text` and a `write_memory` tool accepted `trusted_text` only, the following chain executed cleanly and the taint engine raised no alarm: - Source `web_fetch` → label `UNTRUSTED_HIGH`. - `summarize_document` consumed the untrusted text; the engine applied the tool's declared output contract and emitted `TRUSTED`. - `write_memory` consumed...",
    "condition_of_validity": "The join-at-boundary rule is valid **iff** the label lattice has a bottom element and every tool declares its output label as a function of its input labels, not as a constant. Concretely: - A tool may only *lower* a label if it provides a **verifiable transform witness** — a proof obligation the engine can check mechanically (e.g., \"output is a strict subst...",
    "decision_boundary": "The engine must raise, not warn, at the moment a tool's declared output label is **strictly lower** than `join(inputs)` **and** no transform witness is registered. The boundary is: - `declared_output ⊑ join(inputs)` and witness present → propagate `declared_output`, record witness. - `declared_output ⊑ join(inputs)` and no witness → **hard fault**; the tool ...",
    "operational_effect": "After enforcing join-at-boundary with witness requirements, the summarizer's output became `UNTRUSTED_HIGH`, `write_memory` rejected the write, and the injection was contained at the summarizer boundary. The cost was utility: legitimate summaries of mixed-trust context could no longer be written to trusted memory without an explicit human or policy promotion..."
  },
  "matched_failure_symptoms": [
    "PROMPT_INJECTION_OR_CONFUSED_DEPUTY"
  ],
  "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": "a485e74237f066dfd8cbb5210456080fbb3ffc7769c45497aa7fe39cbd315dd6",
    "verified_classes": [
      "Trust",
      "TaintLaunderingError",
      "Labeled"
    ],
    "verified_functions": [
      "join",
      "apply_tool",
      "write_memory",
      "read_memory"
    ],
    "verified_functions_count": 4,
    "defensive_guards_count": 5,
    "raised_exceptions": [
      "TaintLaunderingError"
    ],
    "sample_fail_closed_invariants": [],
    "stdlib_dependencies": [
      "dataclasses",
      "enum"
    ],
    "observation_mode": "EMPIRICAL_BOUNDARY_CAPTURE",
    "zero_external_deps": true
  }
}
