Recovery without widening permission
Nia can now replace “permissions are broken” with a specific account: the target, the applicable gate, the observed refusal or admission, and the effect count.
Recovery begins with that account. It does not begin by changing the whole session to yolo.
Start with the exact observed target and current scope
Before any later retry, establish:
- The current persistent conversation and cwd when relevant—not merely a title from an old screenshot.
- The exact tool and call, including any outer
writeenvelope and inner device name. - The original arguments, supported replacements, and actual destination or action under review.
- The tool declaration, effective policy key, mode, and execute-time autoApprove input.
- The host’s relevant UI capability and any independent provider safety requirement.
- Whether execution occurred, which result belongs to which call, and which effects remain uninspected.
On the paper route, use only the supplied fictional records. If a fact is not in the record, mark it unknown. Do not create certainty by substituting your own settings or making a provider request.
Use the recovery matrix
| Observation | Boundary to investigate | Bounded recovery | What not to do |
|---|---|---|---|
Tool absent or No such tool | Enabled registry and actual direct/mounted route | Confirm the exact known name and current availability; use an already available appropriate surface or report the missing capability. | Assume a user allow installs or discovers a tool. |
blocked by tool policy | The declaration’s effective deny, including a selected bash deny | Read the exact reason and arguments; preserve the refusal unless the responsible policy owner identifies an authorized correction. | Expect yolo or a generic user allow to erase a tool deny. |
blocked by user policy | The effective normalized key, including dispatcher fallback | Identify whether the key is the device or invoking tool; compare the policy with the intended scope. | Remove unrelated denies or treat the stock hint as authorization to change policy. |
Tool call denied by user after a selection | One-call response, dismissal, or adapter returning no positive value | Retain the declined outcome; reconsider the operation and input before any separately authorized retry. | Treat it as a persisted deny, or retry just to pressure another answer. |
| Required approval but no UI | Runner UI installation and required operation | Stop; identify whether the owning host has an appropriate supported approval surface. Reading the refusal completes this workbook case. | Widen the mode merely to make unattended execution continue. |
| Prompt or result refers to revised input | Supported handler replacement and reclassification | Review the effective operation again; correlate prompt, tier, and execution evidence. | Approve by remembering the original input or assume every metadata field was rewritten. |
| Domain stale-revision refusal | The domain’s own object and revision contract | Inspect the current object and reconsider the action. | Substitute a fresh token into an unchanged request without review. |
| Malformed device JSON or schema error | Envelope decoding and inner validation | Compare the fictional payload with the actual schema; repair only the intended input in a separately authorized real workflow. | Loosen approval policy to repair invalid data. |
| Pending provider safety checks | Provider metadata and explicit acknowledgement path | Keep the required decision separate from ordinary allow/yolo behavior; stop if it cannot be obtained appropriately. | Treat autoApprove or xdev forwarding as acknowledgement. |
EPERM, EACCES, or EROFS after execution begins | Actual OS/host primitive and resolved target | Preserve the error and relevant cause; hand the exact authorized operation to the host’s normal diagnostic process outside this workbook. | Assume another tool approval grants privilege or activate an elevated writer as practice. |
| Extension handler block or timeout | Pre-execution handler and its active-work failure | Identify the failing handler and preserve the blocked call; investigate compatibility or the supported domain path. | Interpret a stalled gate as silent consent. |
| A call ran without asking | The full resolution path | Check tier defaults, tool allow, selected rule, policy key, launch autoApprove, child construction, and supported forwarding. | Infer either safety or a bypass from zero prompts alone. |
The matrix deliberately distinguishes a policy denial from a declined call. It also distinguishes a stale domain object from a handler-revised tool input: the generic approval wrapper is not itself a domain revision system.
Worked recovery: an unexpected no-prompt result
Read dispatch-specific-allow again. The outer name is write, generic write policy is deny, and the fictional action is exec-tier. A superficial account says the gate ignored deny.
A complete account says:
- The target is
xd://seed_slotand the outer declaration supplies that policy key. - The valid
seed_slot: allowreplaces the invokingwritefallback. - The inner declaration does not deny this fictional action; its user allow applies.
- The report records zero prompts and one inert execution, not a real publication.
The immediate repair is the explanation. Whether a real device-specific allow is intended is a separate policy-owner decision. It is not permission to rewrite the reader’s configuration.
Now compare boundary-auto-approve-mode. Its no-prompt result has another cause: execute-time autoApprove selects wrapper yolo despite configured always-ask. Do not diagnose it as a device-policy issue.
Worked recovery: an error result after outer admission
In dispatch-inner-tool-deny, the outer transport reaches dispatch. The inner policy then refuses, and the dispatcher returns an error result. There is one outer tool_call and no inert inner execution.
A retry with the same denied action is not a missing-dialog repair. The operator must address the actual inner-policy reason or leave the action blocked. A transport return and an outer event are not evidence that the inner effect occurred.
For a later real file error, inspect the relevant effect before retrying. Approval and cancellation are not rollback, and a sequence of primitives can have partial results. The prior Tan and Continuity chapters retain their own phase-aware recovery boundaries; this permission chapter does not replace them with a universal transaction guarantee.
Finish the exercise without resetting anything
Nothing must be cleared, dropped, or reset to complete these cases. The fixtures are reading material. Retain your written predictions and corrections if useful. Do not use session resets, memory deletion, policy removal, or personal-profile changes as workbook cleanup.
Paper checkpoint: write a three-sentence recovery note for boundary-no-ui, naming the fictional target, the actual stopped gate, and the effect count. Worked answer: the exec-tier seed_note call requires approval in always-ask. The supplied runner has no UI, so the wrapper resolves false before execution. The inert execution count is zero; changing mode is not required to learn or explain the result.
Failure boundary: a useful diagnosis may end at an unavailable host capability or missing observation. That is more accurate than manufacturing success through a wider grant.
Source trail: packages/coding-agent/src/tools/approval.ts — denyError; packages/coding-agent/src/extensibility/extensions/wrapper.ts — refusal and selection paths; packages/coding-agent/src/tools/xdev.ts — dispatch errors; packages/coding-agent/src/tools/file-write-fallback.ts — primitive failure handling. For separate domain recovery, see Review Desk; for session-state boundaries, see Decision Desk resetting deliberately.
Tool permissions and approvals · Source chapter: permissions/recovery-without-widening-permission. Original evidence remains scoped to its recorded snapshot.