审批
下面的模式描述对内置文件工具使用工作区访问,以包含具有相应读/写能力的会话授权目录。显式只读写入总是被拒绝;外部路径指未列出的路径。
每次副作用工具调用在执行前都会被分类:
- 风险:Read、Write、Privileged、Forbidden。
- 权限:Workspace、OutsideWorkspace、Network、PrivilegedEscalation。
- 授权:Once、Session、Persistent。
模式:
- Plan:没有内置 edit、write 或 bash。工作区读取自动执行。工作区外路径的读取、list、tree、glob、grep 和 search 询问操作者。启用 Skills 时,Skills 搜索目录(
skill/skills树)内的任何路径作为工作区读取自动执行。比较使用每个符号链接的最终目标。为 Plan 列出的外部工具保持 Write + Workspace,并且仍然经过审批。 - Default:Workspace Read 自动执行。写入、shell 和工作区外的路径询问操作者。
- Edit:内置
write和edit的工作区文件更改无需审查即放行。Shell、外部工具和工作区外的路径仍然询问。 - Review:内置
write和edit的工作区文件更改无需审查即放行,与 Edit 相同。另一个模型检查其余每个副作用调用(Codex guardian 风格),包括 bash、bash_start、bash_stop,以及工作区外路径的读取、list、tree、glob、grep、search、write 和 edit,还有外部 Write。工作区读取和 Skills 搜索目录仍然自动执行。会附上有界的记录摘录:最早和最新的用户回合作为授权锚点,放得下的其他用户回合,然后是最近的助手和工具证据。压缩摘要代表被折叠的用户回合。没有这些证据时,宿主询问操作者。之后的用户消息细化任务;状态问题不会撤销先前的授权。用户通过 question 工具给出的答案算作授权证据。审查者返回outcome(allow / deny / ask)、risk_level(low / medium / high)、user_authorization(low / medium / high)和rationale。Allow 会执行。Deny 变成模型可见的拒绝文本。Ask、对 Forbidden 的 allow,以及强制提示的 allow,都会回退到操作者。审查请求的瞬时失败按approvalRetry策略重试(默认五次,退避形状与模型轮次相同);仍然失败时宿主询问操作者。Review 不是授权,也不是完全放行。 - Audit:审查者和记录规则与 Review 相同,但工作区
write和edit也会被检查。它们不会自动放行。 - Full:限制在工作区内、策略允许的动作无需审查即放行。这包括分类保持 Write + Workspace 的任何已加载外部工具,不只是内置
write/edit。Forbidden、Privileged、工作区外和强制提示的调用从不完全自动放行。Session 和 Persistent 授权只适用于普通的 Workspace Read/Write 调用;每次分类后都会重新检查,不能绕过被提高的分类。
除非 config.json 中启用了 approvalModel,否则审查模型就是会话模型。该对象是 enabled、provider、model 和可选的 thinkingEffort。省略对象表示关闭。enabled: false 保留已存储的提供商、模型和档位但不使用,Review 和 Audit 跟随 /model 和工作思考档位。启用时,审查调用使用单独的客户端和该提供商的凭据。/model 和工作思考档位不适用。审查者使用已存储的档位;模型不提供的已存储档位回退到提供商默认值,与工作档位相同。审查用量不加到工作记录。缺少凭据、缺少目录模型,或已保存的开关指向目录中没有的模型,会失败,而不是回退到会话模型。/approval model 显示开关,打开或关闭它,或设置模型或 provider model 并打开它;已存储的档位保留。/approval thinking 循环已存储的档位或按名称设置一个并持久化它;它需要已存储或已启用的审批模型,但开关关闭时也能工作。/status 只在开关打开时增加 Approval model 和 Approval thinking 行。/status full 列出有效的重试策略。状态栏不会。
crystal run 可以用 --approval-model on|off、--approval-provider、--approval-model-id 和 --approval-thinking 为一个进程设置该开关。这些标志不写入 config.json。传入提供商或模型 id 会为该进程打开开关。--approval-model off 让任何已存储的名称和档位不被使用,并拒绝同一条命令上的提供商或模型 id。
旧配置值 autoedit、fullreview 和 full-review 仍然解析为 Edit 和 Audit。
外部工具作者可以在集合级把 approval 设为 inherit(默认)或 always,并按工具覆盖。操作者通过 config.json 中的 externalToolApproval 独立控制 Home 和 Project 工具的作者声明是否生效。默认是 Home author 和 Project host:安装在 ~/.crystal/tools 下信任作者声明,而工作区编写的声明保持在宿主策略下,除非操作者选择加入。有效的 always 对普通的、限制在工作区内的调用跳过提示和 Review。分类、schema 检查、凭据路径拒绝、路径围栏和其他执行安全下限仍然适用。工具更新继承该声明;没有内容哈希或绑定版本的信任授权。
不要把模式命名为 auto。这个词在审查和完全放行之间含糊。
调用自动放行时(策略、记住的授权或审查允许),shell 打印带 Title Case 字段的面板:Status、Reason、Risk 和 Authority,加上分类器摘要。审查允许还会打印 Outcome、审查 Risk、Authority 和理由。
持久授权存储在 ~/.crystal/permissions.json。现有授权仍然可读,但只在当前分类是没有 RequirePrompt 的 Workspace Read/Write 时适用。OutsideWorkspace、Network、Privileged、Forbidden、未知分类和 RequirePrompt 不能使用或创建可复用授权。它们的操作者允许只应用一次,与前端返回的范围无关。RequirePrompt 也阻止审查者 Allow 执行:Deny 仍然拒绝,而 Allow 和 Ask 到达操作者。无头前端拒绝任何这样的操作者提示。