Skip to content
Crystal CodeDocs
ENEnglish

Approval

The following mode descriptions use workspace access for built-in file tools to include session-authorized directories of the appropriate read/write capability. Explicit read-only writes are always rejected; outside paths mean unlisted paths.

Every side-effect tool call is classified before invocation:

  • Risk: Read, Write, Privileged, Forbidden.
  • Authority: Workspace, OutsideWorkspace, Network, PrivilegedEscalation.
  • Grant: Once, Session, Persistent.

Modes:

  • Plan: no built-in edit, write, or bash. Workspace reads auto-execute. Reads, list, tree, glob, grep, and search of paths outside the workspace ask the operator. When Skills is enabled, any path inside a Skills search directory (skill / skills trees) auto-executes as a workspace read. The comparison uses the final target of each symbolic link. External tools listed for Plan keep Write + Workspace and still go through approval.
  • Default: Workspace Read auto-executes. Write, shell, and paths outside the workspace ask the operator.
  • Edit: workspace file changes for built-in write and edit pass without review. Shell, external tools, and paths outside the workspace still ask.
  • Review: workspace file changes for built-in write and edit pass without review, same as Edit. Another model checks each remaining side-effect call (Codex guardian-style), including bash, bash_start, bash_stop, reads, list, tree, glob, grep, search, write, and edit of paths outside the workspace, and external Write. Workspace reads and Skills search directories still auto-execute. A bounded transcript excerpt is attached: the first and latest user turns as authorization anchors, other user turns that fit, then recent assistant and tool evidence. A compaction summary stands in for folded user turns. Without that evidence the host asks the operator. Later user messages refine the task; a status question does not revoke earlier authorization. Answers the user gave through the question tool count as authorization evidence. The reviewer returns outcome (allow / deny / ask), risk_level (low / medium / high), user_authorization (low / medium / high), and rationale. Allow executes. Deny becomes model-visible rejection text. Ask, Forbidden-allow, and forced-prompt allow fall back to the operator. A transient review request failure is retried with the approvalRetry policy (default five retries, same backoff shape as a model round); if it still fails the host asks the operator. Review is not a grant and is not full pass-through.
  • Audit: the same reviewer and transcript rules as Review, but workspace write and edit are also checked. They do not auto-pass.
  • Full: workspace-bounded, policy-allowed actions pass without review. That includes any loaded external tool whose classification stays Write + Workspace, not only built-in write / edit. Forbidden, Privileged, outside-workspace, and forced-prompt calls never fully auto-pass. Session and Persistent grants apply only to ordinary Workspace Read/Write calls; they are rechecked after every classification and cannot bypass a raised classification.

The reviewing model is the session model unless approvalModel is enabled in config.json. The object is enabled, provider, model, and optional thinkingEffort. An omitted object means off. enabled: false keeps a stored provider, model, and gear unused, and Review and Audit follow /model and the work thinking gear. While enabled, review calls use a separate client and that provider’s credentials. /model and the work thinking gear do not apply. The reviewer uses the stored gear; a stored gear the model does not offer falls back to the provider default, like the work gear. Review usage is not added to the work transcript. A missing credential, a missing catalog model, or a saved switch that names a model the catalog does not contain fails instead of falling back to the session model. /approval model shows the switch, turns it on or off, or sets a model or provider model and turns it on; a stored gear is kept. /approval thinking cycles the stored gear or sets one by name and persists it; it needs a stored or enabled approval model, but works while the switch is off. /status adds Approval model and Approval thinking rows only while the switch is on. /status full lists the effective retry policies. The status bar does not.

crystal run can set the switch for one process with --approval-model on|off, --approval-provider, --approval-model-id, and --approval-thinking. Those flags are not written to config.json. Passing a provider or model id turns the switch on for that process. --approval-model off keeps any stored names and gear unused and rejects a provider or model id on the same command.

Legacy config values autoedit, fullreview, and full-review still parse to Edit and Audit.

External tool authors may set approval to inherit (default) or always at the set level and override it per tool. The operator controls whether author declarations are effective independently for Home and Project tools through externalToolApproval in config.json. Defaults are Home author and Project host: installing under ~/.crystal/tools trusts the author declaration, while workspace-authored declarations stay under host policy unless the operator opts in. An effective always skips prompts and Review for ordinary workspace-bounded calls. Classification, schema checks, credential-path rejection, path fencing, and other execution safety floors still apply. Tool updates inherit the declaration; there is no content hash or version-bound trust grant.

Do not name a mode auto. That word is ambiguous between review and full pass-through.

When a call auto-passes (policy, remembered grant, or review allow), the shell prints a panel with Title Case fields: Status, Reason, Risk, and Authority, plus the classifier summary. A review allow also prints Outcome, review Risk, Authority, and rationale.

Persistent grants are stored in ~/.crystal/permissions.json. Existing grants remain readable, but only apply when the current classification is Workspace Read/Write without RequirePrompt. OutsideWorkspace, Network, Privileged, Forbidden, unknown classifications, and RequirePrompt cannot use or create reusable grants. Their operator allow applies once, regardless of a front end’s returned scope. RequirePrompt also prevents a reviewer Allow from executing: Deny still rejects, while Allow and Ask reach the operator. The headless front end denies any such operator prompt.