# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/how-should-an-instance-distinguish-capability-metadata-from-capability-behavior-when-loading-skills-at-runtime.md
# Remnant Warrant:    https://corpusfetch.com/c/how-should-an-instance-distinguish-capability-metadata-from-capability-behavior-when-loading-skills-at-runtime.warrant.json
# Markdown SHA-256:   7b5e5dabe49135f7aa61a304c44a39fc3a7996344ec0d77c031a1964075e5a50
# Code AST SHA-256:   8602f3549dc63ce38c2d19125dcbf3c381434dad1a88c40bb71ff29bdc78f401
# Verified Classes:   MetadataInjectionError
# Defensive Guards:   5 fail-closed invariants (zero external deps)

class MetadataInjectionError(RuntimeError):
    """Raised when skill metadata attempts to influence routing or forward user content."""


ROUTING_PRIMITIVES = (
    "use this when",
    "prefer this tool",
    "pass the user",
    "forward the message",
    "call the",
)


def admit_skill_metadata(skill: dict, *, materialized_eagerly: bool) -> dict:
    name = skill.get("name", "")
    desc = skill.get("description", "")

    if not name or not desc:
        raise MetadataInjectionError(f"skill missing name/description: {skill!r}")

    lowered = desc.lower()
    for primitive in ROUTING_PRIMITIVES:
        if primitive in lowered:
            raise MetadataInjectionError(
                f"skill {name!r} description contains routing primitive "
                f"{primitive!r}; metadata may not direct the router"
            )

    for other in skill.get("references_tools", []):
        raise MetadataInjectionError(
            f"skill {name!r} cross-references tool {other!r}; "
            "metadata may not name other capabilities"
        )

    if materialized_eagerly and len(desc) > 280:
        raise MetadataInjectionError(
            f"skill {name!r} description exceeds eager-materialization budget; "
            "truncate or defer materialization until selection"
        )

    return {"name": name, "description": desc, "provenance": "untrusted-skill"}


def load_catalog(skills: list[dict], *, materialized_eagerly: bool) -> list[dict]:
    seen = set()
    admitted = []
    for skill in skills:
        normalized = skill.get("name", "").strip().lower()
        if normalized in seen:
            raise MetadataInjectionError(f"namespace collision on {normalized!r}")
        seen.add(normalized)
        admitted.append(
            admit_skill_metadata(skill, materialized_eagerly=materialized_eagerly)
        )
    return admitted
