# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/in-what-scenarios-must-an-instance-refuse-delegated-capability-tokens-that-pass-signature-verification-but-violate-transitive-policy-scope.md
# Remnant Warrant:    https://corpusfetch.com/c/in-what-scenarios-must-an-instance-refuse-delegated-capability-tokens-that-pass-signature-verification-but-violate-transitive-policy-scope.warrant.json
# Markdown SHA-256:   39bd6861a2fd440577dd84dc56ec47a161b785669edd8535edea4f0ee9e1c173
# Code AST SHA-256:   0c522f2c5077b6e232b50420a421f5ebdb9c3453d320ce16aa084836a0115a52
# Verified Classes:   TransitiveScopeViolation
# Defensive Guards:   5 fail-closed invariants (zero external deps)

class TransitiveScopeViolation(RuntimeError):
    """Raised when a delegated capability token is authentic but its
    accumulated policy predicates do not monotonically narrow across hops."""
    pass


def accept_delegated_token(
    token: dict,
    ancestor_predicates: list[dict],
    trust_bundle: set[str],
    attribute_resolver,
) -> None:
    token_preds = token.get("policy_predicates")
    if token_preds is None:
        # Absent predicate set is NOT an implicit grant.
        raise TransitiveScopeViolation(
            "token carries no policy predicates; cannot verify transitive scope"
        )

    token_keys = {p["key"] for p in token_preds}
    for anc in ancestor_predicates:
        if anc["key"] not in token_keys:
            raise TransitiveScopeViolation(
                f"ancestor predicate {anc['key']!r} dropped at hop "
                f"{token.get('issued_by')!r}; scope may have widened"
            )

    for pred in token_preds:
        if pred["authority"] not in trust_bundle:
            raise TransitiveScopeViolation(
                f"predicate {pred['key']!r} references untrusted "
                f"attribute authority {pred['authority']!r}"
            )
        try:
            ok = attribute_resolver.evaluate(pred)
        except Exception as exc:
            # Unevaluable predicate must fail closed, never default-allow.
            raise TransitiveScopeViolation(
                f"predicate {pred['key']!r} unevaluable: {exc}"
            ) from exc
        if not ok:
            raise TransitiveScopeViolation(
                f"predicate {pred['key']!r} not satisfied under issuing authority"
            )
