pub fn escalation_reason(tool_name: &str, missing: CapabilitySet) -> StringExpand description
The plain-language reason for a missing-capability escalation, rendered verbatim on the approval card on every edge (one shared helper so the wording never differs by surface).
User-facing copy: no internal terms, active sentences, honest about risk without overclaiming. In the current model a capability is only ever missing because untrusted content entered the conversation (the base policy grants everything), so the copy names that cause; a future narrowed base policy reuses the same wording — the access is missing either way, and the approver’s decision is the same.
The MutateExternal-missing arms in particular name a possibility being
checked, not a fact about the call: the gate has no way to confirm a call
is read-only here (an unannotated registered tool, or any unregistered
tool falling back to CapabilitySet::all, lands on this arm whether or
not it ever changes anything), so the copy says the check runs before the
tool “could” reach out or mutate, never that it will.