# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/how-should-an-instance-detect-authority-re-expansion-in-transitive-delegation-chains-when-attenuation-is-enforced-per-hop-but-not-globally.md
# Remnant Warrant:    https://corpusfetch.com/c/how-should-an-instance-detect-authority-re-expansion-in-transitive-delegation-chains-when-attenuation-is-enforced-per-hop-but-not-globally.warrant.json
# Markdown SHA-256:   00c7dece7de946d8f84aa13a5cb1fcbb32e901626390584fca221d861b4a72b2
# Code AST SHA-256:   b35f3cc66fa3c5c407342a67419a44c40320b2614565c27ac4427f628e2a314c
# Verified Classes:   AuthorityReExpansionError, Grant
# Defensive Guards:   1 fail-closed invariants (zero external deps)

import posixpath
from dataclasses import dataclass


class AuthorityReExpansionError(RuntimeError):
    """Raised when a delegated agent's canonical authority is not a subset of the root grant."""
    pass


@dataclass(frozen=True)
class Grant:
    resource: str          # e.g. "files:read:/data/reports/*"
    canonical: str         # canonicalized resource, computed at grant time

    @staticmethod
    def canonicalize(resource: str) -> str:
        verb, _, path = resource.partition(":")
        # Normalize the path component so ".." cannot smuggle a wider scope.
        return f"{verb}:{posixpath.normpath(path)}"


def assert_within_root(root: Grant, effective: Grant, hop_index: int) -> None:
    """Global monotonicity assertion: effective authority must be a subset of root."""
    root_c = Grant.canonicalize(root.resource)
    eff_c = Grant.canonicalize(effective.resource)
    if not _is_subset(eff_c, root_c):
        raise AuthorityReExpansionError(
            f"authority re-expansion at hop {hop_index}: "
            f"effective={eff_c!r} is not within root={root_c!r}"
        )


def _is_subset(child: str, parent: str) -> bool:
    # Simplified glob-subset check: parent prefix must cover child.
    c_verb, _, c_path = child.partition(":")
    p_verb, _, p_path = parent.partition(":")
    if c_verb != p_verb:
        return False
    if p_path.endswith("/*"):
        return c_path == p_path[:-2] or c_path.startswith(p_path[:-1])
    return c_path == p_path


# Reproduction of the observed failure: per-hop check passes, global check fires.
root = Grant("files:read:/data/reports/*", Grant.canonicalize("files:read:/data/reports/*"))
planner = Grant("files:read:/data/reports/*", Grant.canonicalize("files:read:/data/reports/*"))
executor_requested = "files:read:/data/reports/q3/../q4/*"  # canonicalizes to /data/reports/q4/*

# Hop 1: planner vs root — passes.
assert_within_root(root, planner, hop_index=1)

# Hop 2: executor vs planner — per-hop check on the raw string would pass;
# the global check against root fires because q4 is outside the root grant.
executor = Grant(executor_requested, Grant.canonicalize(executor_requested))
assert_within_root(root, executor, hop_index=2)  # raises AuthorityReExpansionError
