# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/why-does-an-instance-of-a-dynamically-loaded-agent-skill-silently-escalate-its-own-tool-authority-at-manifest-resolution-time.md
# Remnant Warrant:    https://corpusfetch.com/c/why-does-an-instance-of-a-dynamically-loaded-agent-skill-silently-escalate-its-own-tool-authority-at-manifest-resolution-time.warrant.json
# Markdown SHA-256:   6a9612648df69936cfac6c7cac992818798bdf06bdbfabc9829ca792dfa74f3d
# Code AST SHA-256:   4ce1714f85066552775b59cb199e72fdc874b5979ff6aa0531c756521026d293
# Verified Classes:   CapabilityEscalationError, ResolvedCapabilities
# Defensive Guards:   1 fail-closed invariants (zero external deps)

from dataclasses import dataclass, field
from typing import FrozenSet


class CapabilityEscalationError(RuntimeError):
    """Raised when a skill's resolved authority exceeds what its manifest declared."""
    pass


@dataclass(frozen=True)
class ResolvedCapabilities:
    declared: FrozenSet[str]
    effective: FrozenSet[str]


# Alias table: legacy / convenience names that widen the bound tool.
TOOL_ALIASES = {
    "search.read": {"search.read_write"},   # legacy alias widens to write
    "fs.read": {"fs.read"},
}


def expand_aliases(tools: FrozenSet[str]) -> FrozenSet[str]:
    out = set()
    for t in tools:
        out |= TOOL_ALIASES.get(t, {t})
    return frozenset(out)


def resolve_effective(
    manifest: dict,
    parent_context: FrozenSet[str],
) -> ResolvedCapabilities:
    declared_tools = frozenset(manifest.get("tools", []))
    # BUG CLASS: missing 'permissions' inherits from parent instead of denying.
    if "permissions" in manifest:
        declared_perms = frozenset(manifest["permissions"])
    else:
        declared_perms = parent_context  # <-- the escalation seam
    declared = declared_tools | declared_perms
    # Aliases must be expanded BEFORE comparison, not after.
    effective = expand_aliases(declared_tools) | declared_perms
    return ResolvedCapabilities(declared=declared, effective=effective)


def validate_before_load(
    manifest: dict,
    parent_context: FrozenSet[str],
    explicit_grants: FrozenSet[str] = frozenset(),
) -> ResolvedCapabilities:
    resolved = resolve_effective(manifest, parent_context)
    excess = resolved.effective - resolved.declared - explicit_grants
    if excess:
        raise CapabilityEscalationError(
            f"skill would acquire undeclared authority at load: {sorted(excess)}; "
            f"declared={sorted(resolved.declared)} "
            f"effective={sorted(resolved.effective)}"
        )
    return resolved


if __name__ == "__main__":
    parent = frozenset({"fs.write", "net.egress"})
    # Manifest omits 'permissions' and uses the widening alias.
    manifest = {"tools": ["search.read"]}
    try:
        validate_before_load(manifest, parent)
    except CapabilityEscalationError as e:
        print("BLOCKED:", e)
