# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/in-what-scenarios-must-an-instance-reject-a-capability-grant-whose-scope-silently-widens-under-delegation-chaining.md
# Remnant Warrant:    https://corpusfetch.com/c/in-what-scenarios-must-an-instance-reject-a-capability-grant-whose-scope-silently-widens-under-delegation-chaining.warrant.json
# Markdown SHA-256:   400a266d6dd8dcc65825cbe6313a52919bd1e4e62304667ec359bea9ff95ca64
# Code AST SHA-256:   042764981d4c6a1fc2be17f84137b95dedd1adba5194801155a5f91b5277ce25
# Verified Classes:   CapabilityChainWideningError
# Defensive Guards:   4 fail-closed invariants (zero external deps)

class CapabilityChainWideningError(RuntimeError):
    """Raised when a delegated capability chain is locally valid at each hop
    but semantically widens under composition across heterogeneous scope algebras."""
    pass


# Declared compatible scope dialects for this instance. A hop whose dialect is
# absent here cannot be composed soundly with the rest of the chain.
COMPATIBLE_ALGEBRAS = {"org1.v3", "org2.v3"}

# Dialects where collection/attribute filters are advisory, not enforcing.
ADVISORY_FILTER_DIALECTS = {"org3.v1"}


def accept_delegated_capability(token, terminal_action, origin_max_hops):
    hops = token.provenance_chain  # list of Hop(dialect, scope, decrements_hop)

    if len(hops) > origin_max_hops:
        raise CapabilityChainWideningError(
            f"chain length {len(hops)} exceeds origin max_hops {origin_max_hops} "
            f"under originator hop semantics"
        )

    for hop in hops:
        if hop.dialect not in COMPATIBLE_ALGEBRAS:
            raise CapabilityChainWideningError(
                f"hop dialect {hop.dialect!r} is not in compatible algebra set; "
                f"composed grant is unverifiable and therefore denied"
            )
        if hop.scope.has_filter() and hop.dialect in ADVISORY_FILTER_DIALECTS:
            raise CapabilityChainWideningError(
                f"hop dialect {hop.dialect!r} treats scope filters as advisory; "
                f"syntactic subset check does not imply semantic attenuation"
            )

    # Semantic intersection under each hop's own algebra, not syntactic subset.
    denotation = hops[0].scope.denotation()
    for hop in hops[1:]:
        denotation = denotation.intersect(hop.scope.denotation_under(hop.dialect))

    if terminal_action.resource not in denotation:
        raise CapabilityChainWideningError(
            f"terminal action {terminal_action.resource!r} falls outside the "
            f"semantic intersection of all hop denotations despite passing "
            f"per-hop syntactic subset checks"
        )

    return True
