Auto mode 不是关掉确认:环境、$defaults 和人机卡点
很多人把 Auto mode 当成「全部免确认」。不是。它是把工具调用先丢给分类器:不可逆、破坏性、或明显出环境的动作仍会被拦。permissions.deny 和显式的 permissions.ask 在分类器之前就生效。
默认信任范围很窄:工作目录,以及当前仓库已配置的远程。往公司别的组织推代码、往团队云桶写文件,没写进环境前都会被当成越界。
字段和门槛会随版本变。下面以官方 Auto mode 配置页为准。对不上就跑 claude auto-mode config 和 claude --version。
先看要不要留人机卡点
Auto mode 默认允许往当前仓库的任意分支推,包括默认分支,以及开 PR。分支名本身像发布目标的除外,例如 production、release、gh-pages。强制推送、提交里带密钥、会经 CI 把密钥带出仓库的改动,仍会被拦。
想每次推送或开 PR 都问你,用 permissions.ask,不要只在聊天里说一句「先别推」:
{
"permissions": {
"ask": [
"Bash(git push *)",
"Bash(gh pr create *)"
]
}
}| 边界 | 机制 | Auto mode 里会怎样 |
|---|---|---|
| 先问再做 | permissions.ask | 匹配到就弹窗,分类器批不了 |
| 永远不做 | permissions.deny | 分类器看不到这次调用 |
| 只说这一次 | 对话里交代 | 压缩后可能丢,不适合当真约束 |
autoMode 写在哪
分类器会读会话加载的 CLAUDE.md。项目惯例可以写在那里,两边一起受影响。
跨项目的信任设施写在 autoMode:
| 作用域 | 文件 | 用途 |
|---|---|---|
| 个人 | ~/.claude/settings.json | 你自己信任的仓库、域名、桶 |
| 组织 | 托管设置 | 发给全员的底线 |
| 单次 | --settings 或 Agent SDK | 自动化临时覆盖 |
它不读项目里的 .claude/settings.json 和 .claude/settings.local.json。仓库或构建步骤不能借这两个文件塞 allow 规则。旧版本若把 autoMode 写在 local 文件里,迁到用户设置。
各作用域是叠加的。个人可以加 environment / allow / soft_deny / hard_deny,删不掉托管项。个人 allow 可以盖过组织 soft_deny。真正「不论意图都不许」的,放托管的 permissions.deny。
先配 environment
多数团队只需要这一项。条目是自然语言,不是正则。数组里写上字面量 "$defaults",才会保留内置槽位;省略等于整段换掉。
{
"autoMode": {
"environment": [
"$defaults",
"Source control: github.example.com/acme-corp and all repos under it",
"Trusted cloud buckets: s3://acme-build-artifacts",
"Trusted internal domains: *.corp.example.com",
"Key internal services: Jenkins at ci.example.com"
]
}
}保存后跑 claude auto-mode config 看生效结果。claude auto-mode defaults 打印内置规则。
常见写法包括:组织用途、源码托管、云厂商和桶、内网域名、CI 与制品库、私有包源、敏感数据位置与受众、生产命名空间、受保护的 IaC 范围。宿主机身份、容器出口白名单一类条目版本门槛更高,以当前 defaults 为准。
/auto-mode-setup 可按本项目的 CLAUDE.md、README、配置、远程,以及近期会话里出现过的主机和命令名起草环境项,写进 ~/.claude/settings.json。它读的是命令痕迹,不是你的聊天原文。需要 Pro / Max / Team,客户端还要够新;网页端和关了功能旗标的会话用不了。关掉命令和弹窗,用:
{
"skillOverrides": {
"auto-mode-setup": "off"
}
}allow、soft_deny、hard_deny
三份列表也都是散文规则。分类器内顺序:hard_deny → soft_deny → allow 例外 → 用户对「这一次动作」的明确意图。
「整理一下仓库」不算授权强制推送。「强制推送这个分支」才算。
任何一节省略 "$defaults",就丢掉那一节的全部内置规则。soft_deny 丢了会放开强制推送、curl | bash、生产部署、绕过 Auto mode 等默认软拦。hard_deny 丢了会放开内置的数据外泄规则。只改 environment 时,另外三节仍用默认。
{
"autoMode": {
"environment": ["$defaults", "Source control: github.example.com/acme-corp"],
"allow": ["$defaults", "Deploying to the staging namespace is allowed"],
"soft_deny": ["$defaults", "Never modify files under infra/terraform/prod/"],
"hard_deny": ["$defaults", "Never send repository contents to third-party code-review APIs"]
}
}不想打开文件,用 /permissions 的 Auto mode 页。改动落在用户设置。托管和 --settings 里的只读。
Shell 里若有很窄的 Bash(npm test) 一类 allow,默认仍可能在分类器前放行。要让 Auto mode 期间每条 Bash / PowerShell 都过分类器,设 "classifyAllShell": true。更稳,也更慢。
被拦了怎么办
打开 /permissions 的 Recently denied,按 r 标记重试。对话里展开完整工具调用,看它想碰哪里。
- 任务全程都要用的域名、包源、仓库主机:加进
environment - 以后都允许的模式:加
allow - 这一次你本来就想做:在下一句说清楚,再让它重试
多数会话里原因文案是固定的 Blocked by classifier。要拿精确 tool_input,挂 PermissionDenied 钩子。
重置个人定制:claude auto-mode reset。托管和 --settings 不受影响。
和记忆文件、钩子的分界,见 CLAUDE.md 管倾向,Hooks 才是铁律。MCP、Skills、Hooks 怎么叠,见 MCP、Skills、Hooks 怎么选。