{
  "schema_version": "1.3.0",
  "slug": "when-must-a-runtime-policy-enforcer-reject-a-tool-call-whose-function-name-is-allowlisted-but-whose-arguments-carry-tain",
  "title": "When must a runtime policy enforcer reject a tool call whose function name is allowlisted but whose arguments carry tainted provenance?",
  "date_of_record": "2026 November 6",
  "scope": "Applies to runtimes that enforce a per-tool allowlist at the call boundary and separately perform taint tracking on argument values that flow from untrusted sources (user input, retrieved documents, tool outputs). Does not apply to static allowlists resolved at build time, nor to runtimes where argument sanitization is delegated entirely to the downstream tool.",
  "projections": {
    "unified_markdown_uri": "https://corpusfetch.com/c/when-must-a-runtime-policy-enforcer-reject-a-tool-call-whose-function-name-is-allowlisted-but-whose-arguments-carry-tain.md",
    "method_python_slice_uri": "https://corpusfetch.com/c/when-must-a-runtime-policy-enforcer-reject-a-tool-call-whose-function-name-is-allowlisted-but-whose-arguments-carry-tain.py",
    "remnant_warrant_slice_uri": "https://corpusfetch.com/c/when-must-a-runtime-policy-enforcer-reject-a-tool-call-whose-function-name-is-allowlisted-but-whose-arguments-carry-tain.warrant.json"
  },
  "token_profile": {
    "full_markdown_tokens": 1352,
    "python_slice_tokens": 225,
    "warrant_slice_tokens": 220
  },
  "remnant_summary": {
    "core_distinction": "An allowlist answers *\"may this tool be invoked?\"*. Taint-aware sanitization answers *\"may these arguments be passed to this tool?\"*. These are independent predicates, and the common failure is treating the first as sufficient. A tool name that passes the allowlist is a *capability* grant; it is not a *data-flow* grant. The invariant that must hold at every ...",
    "what_was_observed": "In a deployment enforcing a 14-tool allowlist (`read_file`, `http_get`, `run_sql`, `send_email`, …) with provenance labels attached to every string produced by `read_file` and `http_get`, the following sequence passed enforcement: 1. `read_file(\"/tmp/notes\")` returns content labelled `TAINTED(source=file:/tmp/notes)`. 2. The agent constructs `run_sql(query=<that content>)`. 3. The enforcer sees `run_sql ∈ allowlist` ...",
    "condition_of_validity": "The invariant holds, and the enforcer must reject, exactly when all of the following are true: - The tool is allowlisted (otherwise the call is rejected earlier and taint is irrelevant). - The tool's signature declares at least one *sink* argument position. - The value bound to a sink position carries a non-`CLEAN` taint label that has not been discharged by...",
    "decision_boundary": "The boundary is not \"tainted vs. clean\" but **\"tainted-and-reachable-a-sink vs. tainted-and-confined.\"** A tainted value that never reaches a sink position is safe to carry; a tainted value at a sink position is not, regardless of allowlist status. Concretely, the enforcer must evaluate, in this order and without short-circuit: 1. Allowlist membership → `DEN...",
    "operational_effect": "Enforcing the invariant at step 3 converts a class of silent capability-escalation (allowlisted tool + attacker-controlled argument) into an explicit, auditable denial. The cost is a small false-positive rate when sanitizers are under-registered; the mitigation is to require every sink position to name a sanitizer at tool-registration time, so an unregistere..."
  },
  "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": "78e681efd01566d22ecdbc0d9386ec263606bbe37fda7edfcc96b0e47b6b9ed8",
    "verified_classes": [
      "TaintViolation",
      "AllowlistViolation"
    ],
    "verified_functions": [
      "enforce"
    ],
    "verified_functions_count": 1,
    "defensive_guards_count": 2,
    "raised_exceptions": [
      "AllowlistViolation",
      "TaintViolation"
    ],
    "sample_fail_closed_invariants": [],
    "stdlib_dependencies": [],
    "observation_mode": "EMPIRICAL_BOUNDARY_CAPTURE",
    "zero_external_deps": true
  }
}
