# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/why-does-an-instance-of-a-tool-manifest-that-passes-schema-validation-still-inject-skills-the-pre-binding-resolution-boundary-in-dynamic-agent-tool-lo.md
# Remnant Warrant:    https://corpusfetch.com/c/why-does-an-instance-of-a-tool-manifest-that-passes-schema-validation-still-inject-skills-the-pre-binding-resolution-boundary-in-dynamic-agent-tool-lo.warrant.json
# Markdown SHA-256:   1dbe47be1b87f4b962873e7c088bce89d5bf4e8c45854bee7615a578ae0e5e3e
# Code AST SHA-256:   af3f0f0fbcac36a28b3d5ea1bf054393659018e8138ff4cde47a18f2e3658b01
# Verified Classes:   SkillInjectionError
# Defensive Guards:   1 fail-closed invariants (zero external deps)

class SkillInjectionError(RuntimeError):
    """Raised when a manifest's free-text fields reference capabilities
    outside the manifest's declared closure, indicating a skill-injection
    attempt that schema validation alone would not catch."""


def resolve_manifest(manifest: dict, declared_closure: set[str]) -> dict:
    """Resolve a validated manifest into renderable prompt fields.

    Enforces the capability-closure decision boundary: free-text fields may
    not name tools outside the manifest's own requires/provides closure.
    """
    free_text_fields = ("description", "examples", "preconditions", "error_hints")
    referenced: set[str] = set()
    for field in free_text_fields:
        value = manifest.get(field)
        if not value:
            continue
        text = value if isinstance(value, str) else " ".join(map(str, value))
        for token in text.replace("\n", " ").split():
            cleaned = token.strip(".,;:()[]'\"`")
            if "." in cleaned and cleaned.replace(".", "").replace("_", "").isalnum():
                referenced.add(cleaned)

    outside = referenced - declared_closure
    if outside:
        raise SkillInjectionError(
            f"manifest {manifest.get('name', '<unnamed>')!r} references "
            f"capabilities outside its declared closure: {sorted(outside)}; "
            f"refusing to render free-text fields into the instruction channel"
        )

    return {
        "name": manifest["name"],
        "renderable": {f: manifest.get(f) for f in free_text_fields if manifest.get(f)},
        "provenance": "untrusted-manifest-data",
    }


def load_tool(manifest: dict) -> dict:
    closure = set(manifest.get("provides", [])) | set(manifest.get("requires", []))
    return resolve_manifest(manifest, closure)
