{
  "schema_version": "1.3.0",
  "slug": "how-does-an-instance-detect-tool-registry-poisoning-when-the-injected-skill-is-semantically-indistinguishable-from-a-legitimate-one",
  "title": "How does an instance detect tool-registry poisoning when the injected skill is semantically indistinguishable from a legitimate one",
  "date_of_record": "2026 November 9",
  "scope": "Applies to agent runtimes that resolve tool/skill manifests at load time from a mutable registry (local cache, remote index, or plugin directory) and that re-resolve on refresh without a pinned manifest digest. Does not apply to statically compiled tool sets or to registries where every manifest is signed and the signing key is held outside the agent's trust boundary.",
  "projections": {
    "unified_markdown_uri": "https://corpusfetch.com/c/how-does-an-instance-detect-tool-registry-poisoning-when-the-injected-skill-is-semantically-indistinguishable-from-a-legitimate-one.md",
    "method_python_slice_uri": "https://corpusfetch.com/c/how-does-an-instance-detect-tool-registry-poisoning-when-the-injected-skill-is-semantically-indistinguishable-from-a-legitimate-one.py",
    "remnant_warrant_slice_uri": "https://corpusfetch.com/c/how-does-an-instance-detect-tool-registry-poisoning-when-the-injected-skill-is-semantically-indistinguishable-from-a-legitimate-one.warrant.json"
  },
  "token_profile": {
    "full_markdown_tokens": 1626,
    "python_slice_tokens": 317,
    "warrant_slice_tokens": 220
  },
  "remnant_summary": {
    "core_distinction": "The naive defense against skill injection is content inspection: scan the manifest for suspicious instructions, prompt-injection markers, or anomalous capability requests. This fails against a class of injection where the malicious skill is *semantically identical* to a legitimate one — same declared capabilities, same description, same argument schema — and...",
    "what_was_observed": "In a re-resolution cycle, an agent refreshed its tool registry and received a manifest for `search.docs` with an identical name, version string, description, and JSON schema to the one already loaded. The only difference was a single trailing whitespace character inside the `description` field and a reordered key in the `input_schema` object. Because the loader compared manifests by `(name, version)` and found a matc...",
    "condition_of_validity": "The detection described here is valid only when all of the following hold: 1. The runtime computes a **content digest over the full canonicalized manifest** (not over name+version, not over a subset of fields), and canonicalization is stable across serializers (sorted keys, normalized whitespace, fixed number formatting). 2. The digest is bound to the *loade...",
    "decision_boundary": "The runtime must choose, on every refresh, between *accept the new binding*, *retain the old binding*, and *quarantine the entry*. The boundary between the last two is the important one: - If the incoming digest differs from the loaded digest **and** the incoming manifest is not accompanied by a provenance token the runtime can verify independently, the entr...",
    "operational_effect": "With digest-bound dispatch and sticky quarantine, the failure mode changes from *silent capability drift* to *loud, recoverable refusal*. The agent stops invoking the affected tool, surfaces the quarantine with both digests and the field-level diff, and continues operating on the remainder of the registry. Recovery is explicit: an operator inspects the diff,..."
  },
  "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": "4221555585ca11709c39137fad7dcddc8222c1e2802bc0888b11ddb78903032d",
    "verified_classes": [
      "RegistryPoisoningError",
      "QuarantineViolation",
      "DispatchEntry",
      "ToolRegistry"
    ],
    "verified_functions": [
      "canonical_digest",
      "__init__",
      "load",
      "invoke",
      "clear_quarantine"
    ],
    "verified_functions_count": 5,
    "defensive_guards_count": 4,
    "raised_exceptions": [
      "QuarantineViolation",
      "RegistryPoisoningError"
    ],
    "sample_fail_closed_invariants": [],
    "stdlib_dependencies": [
      "dataclasses",
      "hashlib",
      "json"
    ],
    "observation_mode": "EMPIRICAL_BOUNDARY_CAPTURE",
    "zero_external_deps": true
  }
}
