# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/how-should-an-instance-distinguish-tool-manifest-trust-from-runtime-skill-trust-when-mcp-registration-is-the-attack-surface.md
# Remnant Warrant:    https://corpusfetch.com/c/how-should-an-instance-distinguish-tool-manifest-trust-from-runtime-skill-trust-when-mcp-registration-is-the-attack-surface.warrant.json
# Markdown SHA-256:   b4ec735f6e3485a90a5ebe795ab8d111725c730563ded41c97e936ef4c054cd3
# Code AST SHA-256:   46ec34bb08e993e7aedf5d1e66b2e1809f4533e81e709646bbfc55e8651d18cd
# Verified Classes:   SkillSurfaceViolation, Callable, SurfaceGuard
# Defensive Guards:   5 fail-closed invariants (zero external deps)

import hashlib
from dataclasses import dataclass, field


class SkillSurfaceViolation(RuntimeError):
    """Raised when runtime skill registration mutates the trusted callable surface."""
    pass


@dataclass
class Callable:
    name: str
    impl_hash: str
    provenance: str


@dataclass
class SurfaceGuard:
    baseline: dict[str, Callable] = field(default_factory=dict)
    sealed: bool = False

    def seal(self, tools: list[Callable]) -> None:
        if self.sealed:
            raise SkillSurfaceViolation("surface already sealed; cannot reseal")
        for t in tools:
            if t.name in self.baseline:
                raise SkillSurfaceViolation(f"duplicate name at baseline: {t.name!r}")
            self.baseline[t.name] = t
        self.sealed = True

    def register(self, skill: Callable) -> None:
        if not self.sealed:
            raise SkillSurfaceViolation("registration attempted before baseline seal")
        prior = self.baseline.get(skill.name)
        if prior is not None:
            # Shadowing / replacement is never legitimate within a session.
            raise SkillSurfaceViolation(
                f"name collision on {skill.name!r}: "
                f"baseline provenance={prior.provenance!r} hash={prior.impl_hash}, "
                f"new provenance={skill.provenance!r} hash={skill.impl_hash}"
            )
        # New name: requires fresh validation, not silent merge.
        if not self._validate_new(skill):
            raise SkillSurfaceViolation(
                f"new skill {skill.name!r} failed post-registration validation "
                f"(provenance={skill.provenance!r})"
            )
        self.baseline[skill.name] = skill

    def _validate_new(self, skill: Callable) -> bool:
        # Provenance must be a trusted source AND hash must match declared impl.
        trusted = skill.provenance.startswith("manifest://validated/")
        recomputed = hashlib.sha256(skill.name.encode()).hexdigest()[:16]
        return trusted and bool(skill.impl_hash) and skill.impl_hash == recomputed


def handle_registration(guard: SurfaceGuard, incoming: Callable) -> None:
    # Every runtime registration path must funnel through here.
    guard.register(incoming)
