Approval
Every side-effect tool call is classified before it runs.
| Axis | Values |
|---|---|
| Risk | Read, Write, Privileged, Forbidden |
| Authority | Workspace, OutsideWorkspace, Network, PrivilegedEscalation |
| Grant | Once, Session, Persistent |
| Mode | What passes | What still asks |
|---|---|---|
| Default | Workspace reads. With Skills on, any path in a Skills search directory | Writes, shell, and paths outside the workspace |
| Edit | Workspace changes from built-in write and edit |
Shell, external tools, and paths outside the workspace |
| Review | The same file changes as Edit. Skills search directories when Skills is on | Everything else is checked by another model. See below |
| Audit | Nothing extra. Workspace write and edit are checked too |
Same reviewer as Review |
| Full | Workspace-bounded, policy-allowed actions, including an external tool that stays Write + Workspace | Forbidden, Privileged, outside-workspace, and forced-prompt calls |
Do not name a mode auto. The word is ambiguous between review and full pass-through. /approval with no argument cycles Default, Edit, Review, Audit, and Full. /approval review and the other names set one mode and write it to config.json. Legacy values autoedit, fullreview, and full-review still parse.
Review
Section titled “Review”Review and Audit send each remaining side-effect call to another model. That includes bash, bash_start, bash_stop, reads and edits outside the workspace, and external Write.
The reviewer sees a bounded excerpt: the first and latest user turns, other user turns that fit, then recent assistant and tool evidence. A compaction summary stands in for folded turns. Without that evidence, the host asks you. Later user messages refine the task. A status question does not revoke earlier authorization. Answers from the question tool count as authorization.
| Outcome | Result |
|---|---|
| Allow | Runs the tool, unless the call is Forbidden or requires a forced prompt |
| Deny | Becomes rejection text the model can see |
| Ask, Forbidden-allow, forced-prompt allow | Falls back to you |
A transient reviewer failure is retried with approvalRetry (five times by default). If it still fails, you are asked. Review is not a grant and is not full pass-through.
The reviewer is the session model unless you turn on a separate approval model.
| Command | Effect |
|---|---|
/approval model |
Shows Approval model Off, or On <provider> <model>. A stored non-default gear is appended as · Think High |
/approval model on|off |
Saves the switch. A stored provider, model, and gear stay in place |
/approval model <model> |
Selects a catalog model, keeps the stored gear, and turns the switch on. <provider> <model> does the same across providers |
/approval thinking |
Cycles that model’s gear, or sets one by name, and saves it. Works while the switch is off |
The model must exist in providers.json. A missing credential or an unknown model is refused, and the previous setting stays. While the switch is on, Review and Audit call that model with its own credentials and stored gear. A stored gear the model does not offer falls back to the provider default. /approval thinking refuses off for a model that cannot disable thinking.
Tab completes /approval model from on, off, and the catalog, and /approval thinking from that model’s gears. /model and the work thinking gear do not change it. Compaction stays on the session model. While the switch is off, no separate client is created and Review and Audit follow /model. Finish the current turn before changing the approval model.
/status adds Approval model and Approval thinking rows only while the switch is on. /status full lists the effective retry and approvalRetry policies. The status bar does not.
When you are asked
Section titled “When you are asked”The overlay is a two-column grid: Status, Reason, Risk, Authority, and for review also Outcome and rationale.
| Key | Grant |
|---|---|
| Y, Enter, or 1 | Once |
| S or 2 | Session |
| A or 3 | Always (persistent) |
| N, Escape, or 4 | Deny |
Persistent grants are stored in ~/.crystal/permissions.json. Session and Always are offered only for ordinary Workspace Read/Write calls without a forced prompt. OutsideWorkspace, Network, Privileged, Forbidden, and forced prompts offer Once and Deny only. Session and Always keys are ignored.
Existing grants are checked against the current classification on every call. They cannot bypass an upgrade. A forced prompt still asks you after a reviewer Allow. Reviewer Deny rejects. crystal run denies any call that reaches this prompt.
Auto-pass cards
Section titled “Auto-pass cards”When a call auto-passes, the shell prints Status, Reason, Risk, Authority, and the classifier summary. A review allow also prints Outcome, the reviewer’s risk and authorization, and the rationale.
| Command | Hides or shows |
|---|---|
/verbose approvals |
Policy and grant cards |
/verbose review |
Review-allow cards, including Outcome and rationale |
Each stays on unless its field is false in config.json. Cards already printed follow their own switch. A saved verboseApprovals of false no longer hides review-allow cards. Asking you still uses the overlay.
Shell classification treats sudo, destructive filesystem commands, pipe-to-shell downloads, force-push, and credential-path writes as Forbidden or Privileged. Forbidden never fully auto-passes. Review and Audit may deny those calls or send them to you. Writes under .ssh, .gnupg, or ~/.crystal/credentials.json are Forbidden.