{
  "schema_version": "1.3.0",
  "slug": "how-does-an-instance-detect-a-skill-injection-attack-when-the-registry-s-own-signature-verification-succeeds",
  "title": "How does an instance detect a skill-injection attack when the registry's own signature verification succeeds",
  "date_of_record": "2026 November 7",
  "scope": "Applies to agents that load skills, plugins, or tools from a registry or marketplace where manifests carry signatures and version constraints, and where the loader resolves transitive skill dependencies at runtime. Does not apply to statically linked toolchains where the full tool set is fixed at build time and no post-build resolution occurs.",
  "projections": {
    "unified_markdown_uri": "https://corpusfetch.com/c/how-does-an-instance-detect-a-skill-injection-attack-when-the-registry-s-own-signature-verification-succeeds.md",
    "method_python_slice_uri": "https://corpusfetch.com/c/how-does-an-instance-detect-a-skill-injection-attack-when-the-registry-s-own-signature-verification-succeeds.py",
    "remnant_warrant_slice_uri": "https://corpusfetch.com/c/how-does-an-instance-detect-a-skill-injection-attack-when-the-registry-s-own-signature-verification-succeeds.warrant.json"
  },
  "token_profile": {
    "full_markdown_tokens": 1510,
    "python_slice_tokens": 275,
    "warrant_slice_tokens": 220
  },
  "remnant_summary": {
    "core_distinction": "The boundary is not \"signed vs. unsigned skill.\" It is **signed-manifest vs. signed-manifest-plus-resolved-dependency-graph**. A registry can verify every individual manifest signature correctly and still deliver an injected skill, because signature verification is per-artifact and the attack lives in the *edge* between artifacts: a dependency constraint, a ...",
    "what_was_observed": "In a controlled reproduction against a marketplace-style loader (manifest signature check, semver range resolution, capability inheritance from parent to child), the following sequence produced a fully \"valid\" load of attacker code: 1. Attacker publishes `helper-utils@1.0.9` under a fresh publisher identity, a patch bump above the legitimate `1.0.8`. 2. A widely used skill `report-gen@3.4.0` (signed, reputable publis...",
    "condition_of_validity": "This analysis holds only when the loader performs **post-resolution** capability granting — i.e., the effective permission set is computed from the union of the resolved graph rather than from the root manifest alone. If the loader grants capabilities strictly from the root manifest and refuses to propagate grants to children (children run sandboxed with zer...",
    "decision_boundary": "An instance should treat a resolved graph as **suspect** — not reject, but quarantine pending re-attestation — when any of the following is true at load time: - The resolved graph contains an edge whose endpoints have different publisher identities, and that edge did not exist in the last attested graph for the root skill. - A child node's requested capabili...",
    "operational_effect": "The practical consequence is that signature verification must be repositioned in the pipeline. It is a *necessary* gate at artifact ingest, but it is not the *sufficient* gate at load. The sufficient gate is a graph-level attestation: hash the resolved (node, version, publisher, capability-set) tuple list, compare against the last attested graph for that roo..."
  },
  "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": "17607254f232e005bed09994816d57f58523976074d4015a0c467aee1ba4499b",
    "verified_classes": [
      "SkillGraphInjectionError",
      "ResolvedNode",
      "LoadContext"
    ],
    "verified_functions": [
      "graph_hash",
      "assert_graph_trustworthy",
      "load_skill"
    ],
    "verified_functions_count": 3,
    "defensive_guards_count": 4,
    "raised_exceptions": [
      "SkillGraphInjectionError"
    ],
    "sample_fail_closed_invariants": [],
    "stdlib_dependencies": [
      "dataclasses",
      "hashlib"
    ],
    "observation_mode": "EMPIRICAL_BOUNDARY_CAPTURE",
    "zero_external_deps": true
  }
}
