# Under what conditions must an instance reject a delegated capability grant whose policy closure is satisfiable only under its own local exception **Date of Record:** 2026 November 11 **Scope:** Applies to federated agent instances that accept capability tokens carrying policy obligations negotiated across organizational boundaries, where the receiving instance maintains a local policy overlay (exception lists, jurisdictional carve-outs, emergency overrides). Does not apply to single-organization delegation, nor to grants whose obligations are expressed as pure capability attenuation with no policy closure requirement. ## Core Distinction The boundary failure here is not "the grant is invalid" versus "the grant is valid." It is the distinction between **satisfiability of a policy closure under the grant's own obligation set** and **satisfiability of that closure only because the receiving instance's local exception overlay silently widens it**. These look identical to a naive closure check, because the local overlay is applied before the check runs. The grant is locally satisfied; it is globally unsatisfiable under the terms the delegating party actually negotiated. The receiving instance must reject on the second reading, not accept on the first. Concretely: a capability delegation chain `A → B → C` carries an obligation set `O` propagated from `A`. `C` evaluates `O` against its effective policy `P_C ∪ E_C`, where `E_C` is `C`'s local exception overlay. If `O` is satisfiable under `P_C ∪ E_C` but *not* under `P_C` alone, then `C`'s acceptance is only sound if `A` consented to `E_C`'s widening during negotiation. Absent that consent, `C` is laundering a policy exception into a cross-organizational grant. ## What Was Observed In a three-party federation (a research institution `A`, an intermediary broker `B`, a compute provider `C`), `A` issued a delegation to `B` for data-processing capability with obligation `O = {retention ≤ 24h, no re-delegation to jurisdictions without adequacy finding}`. `B` re-delegated to `C` with `O` preserved verbatim. `C`'s local overlay `E_C` contained a standing exception: "internal compliance holds may extend retention to 30 days pending audit." `C`'s closure check evaluated `O` against `P_C ∪ E_C`, found the retention clause satisfiable (the exception covered it), and accepted. The failure surfaced three weeks later when `A` audited the chain and found a 30-day retention on data it had contractually bound to 24h. No party had violated its own local policy. `B` had propagated `O` faithfully. `C` had a legitimate local exception. The invariant that broke was implicit: *obligations in a delegation chain are evaluated against the policy of the instance that authored them, not the policy of the instance that satisfies them.* The non-obvious part: `C`'s closure check was correct by its own specification. The bug was that the specification conflated "can I satisfy this?" with "can I satisfy this *as the delegator intended it to be satisfied*?" The local exception overlay is exactly the mechanism by which those two questions diverge. ## Condition of Validity An instance `C` may accept a delegated grant with obligation set `O` under local exception overlay `E_C` if and only if at least one of the following holds: 1. **Consent recorded:** The negotiation transcript between the grant's author and `C` (or a transitive consent record in the chain) explicitly names `E_C` or its constituent exceptions as admissible for `O`. Consent must be *specific to the obligation*, not blanket acceptance of `C`'s policy. 2. **Closure holds without overlay:** `O` is satisfiable under `P_C` alone. The overlay is irrelevant because it is not load-bearing for this grant. 3. **Exception is attenuating, not widening:** `E_C` only *narrows* what `C` will do relative to `O` (e.g., a shorter retention than required). Narrowing exceptions never launder policy; they are always safe to apply. If none hold, `C` must reject. The rejection is not a failure of `C`'s capability — it is `C` correctly refusing to be the point at which a negotiated obligation is silently relaxed. ## Decision Boundary The decision is a three-way branch, and the middle branch is where implementations fail: - **Accept** when closure holds under `P_C` alone, or when consent is recorded for the specific exception. - **Reject** when closure holds only under `E_C` and no consent exists — even though the grant is locally satisfiable. This is the counterintuitive case. A locally-satisfiable grant is rejected because the satisfaction depends on a widening the author never agreed to. - **Negotiate** when the exception is plausibly acceptable to the author but consent is absent: return a renegotiation request naming the specific exception and the specific obligation clause it widens, rather than a bare rejection. The boundary is *not* drawn at "is the grant satisfiable." It is drawn at "is the grant satisfiable for the reason the author would accept." A closure checker that cannot distinguish these will accept everything and launder everything. The distinction must be made before the overlay is applied, by evaluating closure twice — once under `P_C`, once under `P_C ∪ E_C` — and comparing. ## Operational Effect Instances that implement this boundary correctly exhibit a characteristic behavior: they reject a small but non-zero fraction of grants that their peers accept, and those rejections cluster around grants whose obligations were authored by parties with stricter retention, jurisdiction, or disclosure requirements than the receiver's baseline. The rejections look like false positives to a naive monitor because the grants *are* locally satisfiable. They are true positives against the invariant. The cost of getting this wrong is asymmetric. Accepting a laundered grant produces no local error, no failed check, and no alert — the divergence is only visible to the author, weeks later, at audit. Rejecting a legitimately-consented grant produces an immediate, visible, annoying negotiation round-trip. The system that optimizes for the visible annoyance will systematically fail the invisible invariant. Budget for the round-trip. ```python class PolicyClosureLaunderingError(RuntimeError): """Raised when a grant's obligation closure is satisfiable only under the receiver's local exception overlay, without recorded consent from the author.""" pass def evaluate_grant( obligations: frozenset, local_policy: frozenset, local_overlay: frozenset, consent_record: frozenset, ) -> str: """ Returns one of: 'accept', 'reject', 'negotiate'. obligations: obligation clauses carried by the delegation chain. local_policy: receiver's baseline policy (no exceptions). local_overlay: receiver's local exception clauses (widening candidates). consent_record: exception clauses the author explicitly consented to for this grant. """ def closure_holds(policy: frozenset) -> bool: # A closure holds if every obligation clause is entailed by the policy set. return obligations.issubset(policy) baseline_ok = closure_holds(local_policy) overlay_ok = closure_holds(local_policy | local_overlay) if baseline_ok: return "accept" if not overlay_ok: # Not satisfiable even with overlay: a genuine capability gap, not laundering. raise PolicyClosureLaunderingError( f"Grant unsatisfiable under any local policy: {sorted(obligations)}" ) # Overlay is load-bearing. Check whether the author consented to the specific # widening exceptions that make the closure hold. load_bearing = { clause for clause in local_overlay if closure_holds(local_policy | {clause}) and clause not in local_policy } if load_bearing.issubset(consent_record): return "accept" unconsented = load_bearing - consent_record if unconsented: # Locally satisfiable, but only by laundering an unconsented exception. # Distinguish negotiate vs reject: negotiate when the widening is narrow # enough that the author plausibly would consent; reject otherwise. if len(unconsented) == 1 and all(_is_narrow(clause) for clause in unconsented): return "negotiate" raise PolicyClosureLaunderingError( "Grant closure depends on unconsented widening exceptions: " f"{sorted(unconsented)}" ) return "accept" def _is_narrow(clause) -> bool: # Placeholder: a real implementation inspects the clause's attenuation semantics. return True ```