# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/in-what-scenarios-must-an-instance-refuse-delegation-in-aaif-credential-chains-the-attenuation-inversion-boundary-at-tool-scope-intersection.md
# Remnant Warrant:    https://corpusfetch.com/c/in-what-scenarios-must-an-instance-refuse-delegation-in-aaif-credential-chains-the-attenuation-inversion-boundary-at-tool-scope-intersection.warrant.json
# Markdown SHA-256:   2a0e8fe762c08b70d16b211572a009d77b7c4be6a683fd370c689bceca56adcc
# Code AST SHA-256:   4513b4945a54b7ab6aae63a05b715e35f5aeff14602f166b2f905500f8c7cc9f
# Verified Classes:   DelegationScopeConflict, Scope
# Defensive Guards:   1 fail-closed invariants (zero external deps)

from dataclasses import dataclass, field
from typing import FrozenSet


class DelegationScopeConflict(RuntimeError):
    """Raised when a delegated scope intersects to empty on an axis whose
    parent grant was non-empty. Must halt the chain; do not emit the token."""


@dataclass(frozen=True)
class Scope:
    tools: FrozenSet[str] = field(default_factory=frozenset)
    resources: FrozenSet[str] = field(default_factory=frozenset)


def attenuate(parent: Scope, requested: Scope) -> Scope:
    """Compute child authority as per-axis intersection of parent and request.

    Refuses (raises) if any axis that was non-empty in the parent becomes
    empty after intersection -- the attenuation-inversion boundary.
    """
    child = Scope(
        tools=parent.tools & requested.tools,
        resources=parent.resources & requested.resources,
    )

    for axis in ("tools", "resources"):
        parent_vals = getattr(parent, axis)
        child_vals = getattr(child, axis)
        if parent_vals and not child_vals:
            raise DelegationScopeConflict(
                f"attenuation inversion on axis '{axis}': "
                f"parent={sorted(parent_vals)} requested={sorted(getattr(requested, axis))} "
                f"-> intersection empty; refusing to mint delegated token"
            )

    return child


def mint_delegated_token(parent: Scope, requested: Scope) -> Scope:
    return attenuate(parent, requested)
