rule.json。rule.json 列出的每个 rulebook 都是实时文件,在同一次调用中从 <scope>/rules/<name>/rulebook.json 读取。加载过程不写入文件、不访问网络,也不缓存结果,因此快照反映磁盘上的当前配置。
快照只有两种状态:ready 和 degraded。本页说明两种状态的完整约定,包括配置来源被拒绝后的执行范围,以及恢复到 ready 的方法。
配置状态
一条警告就足以让运行时进入
degraded。错误与警告的区别在于来源,而不是状态的严重程度:
- 错误指出某个来源已被丢弃。该来源不再提供任何规则。
- 警告指出某个来源仍然生效,只是被拒绝的那部分被忽略。
degraded。
ready 和 degraded 是 cc-safety-net status 打印的仅有两种判定,判定直接读自快照状态。禁用 Claude Code 插件不会改变判定;status 会把它报告为 Not active 下的第一项:“plugin cc-safety-net@cc-marketplace is disabled in Claude Code; nothing is enforced in Claude Code until it is re-enabled. Other integrations are not affected.”无效配置的行为
无效配置本身不会阻止普通命令。系统不会执行无效的候选配置,但智能体仍可继续工作。- 无法验证的规则来源会被丢弃,其规则不再执行。
- 其他每个通过验证的范围都会继续执行自己的规则。
- 所有内置保护都会继续生效。破坏性命令规则、机密保护、策略文件保护和 Git 元数据保护不读取自定义规则配置。
- 无法读取的用户
policy.json会回退到保护性默认值,因此破坏性命令保护和机密保护都保持开启。无法读取的项目policy.json不提供任何内容,用户策略照常生效。
degraded 状态没有特殊恢复模式或允许列表。配置不可用不会单独导致某项操作被拒绝。读取或编辑 rule.json,以及运行 cc-safety-net rule update,都是普通工具调用,各自独立判定。因此,智能体可以自行修复配置。
在所有状态下始终受保护的是两个范围的 policy.json。策略文件保护和 Git 元数据保护在加载策略快照之前运行,因此不会受到损坏配置的影响。具体阻止哪些操作见策略。
配置回退矩阵
错误:来源被丢弃
上述每一条消息都会指明它拒绝的文件或来源,以及对应的修复办法。远程来源缺少 rulebook 时,消息以
run `cc-safety-net rule update` to vendor <source> 结尾;本地来源缺少 rulebook 时以 create that file or remove that source from the rules config 结尾;rulebook 无效和名称不一致这两种情况都以 fix that file 结尾。
警告:来源仍然生效
每个 rulebook 都是实时文件,保存后的编辑在下一次工具调用即生效,无需任何发布步骤。改坏了也不会毫无提示:无法解析或未通过 schema 校验的文件会被丢弃,并报出上面那条 invalid rulebook 错误;被删除的文件同样被丢弃,报的是 missing rulebook file 错误。两种情况都会让快照进入
degraded。policy.json:逐字段保留或替换为保护性默认值
逐字段保留意味着一个无效字段不会连带丢掉文件其余部分配置的保护。保护性默认值刻意偏向更多拒绝:强制开启破坏性命令保护和机密保护,丢弃两个允许路径列表中的无效条目,并丢弃用于关闭规则的覆盖。有效的机密允许路径仍会保留在策略中。
.cc-safety-net/policy.json 这个项目文件也按同样方式逐字段保留,只有一处不同:audit 仅属于用户范围,因此项目文件中的 audit 部分会被忽略,并给出诊断 project policy audit settings are ignored; audit is user scope only。每个字段的保留行为见策略。
运行时永远不会重写 policy.json。手动修复,或使用仪表板中的修复操作。
在文件仍有错误期间,仪表板表单显示的是完整默认值,而不是保留下来的值。修复文件之前无法保存。修复操作会保留每个已识别的有效设置;只有在无法解析 JSON 时,它才会用默认值替换整个文件。
透明包装器的覆盖缺口
transparent_wrappers 声明在 rule.json 中,而不是在 rulebook 中,并且 rule.json 本身没有 digest。这有两个后果:
- 被丢弃的 rulebook 仍保留其范围的包装器,因为
rule.json本身仍然可读。 - 无法读取的
rule.json会丢失该范围的包装器,因为没有经过验证的副本可以回退。分析不再穿透这些包装命令去识别其下受保护的命令。
rule.json。
Fail-closed 情形
“Fail closed” 描述的是运行时或分析失败。它会拒绝当次工具调用,不用于描述无效配置的处理方式。
无效配置正相反:规则来源被丢弃,
policy.json 逐字段保留或替换为保护性默认值,而工作继续进行。
degraded 状态的报告方式
doctor 是唯一同时报告规则配置和 policy.json 的命令。有关每个命令的选项和退出行为,请参阅 CLI 命令。
有两个结构性限制值得了解:
Config warning:行和审计configFallback标志只出现在快照加载之后做出的决策上。策略文件和 Git 元数据的拒绝发生在此之前,因此两者都不会带上它们。- 诊断只指明被拒绝的文件和触发条件,绝不会复制其中的字节。恰好位于格式错误配置文件中的机密不会出现在消息里。
可见的失败与静默的失败
- 规则来源被丢弃时,会话中可能没有提示。 它减少的是拒绝,因此普通会话可能没有任何异常。每次修改规则配置或升级后,都应运行
cc-safety-net status检查。需要完整报告时运行doctor。 - 未迁移的旧配置更加静默。 运行时既不加载该文件,也不报告它,因此即使其中的规则毫无保护作用,快照仍保持
ready。用rule verify才能标记出来。 - 无效的
policy.json大多会自己暴露出来,因为被拒绝的部分会回退到保护性默认值:两项保护被强制开启,允许路径被丢弃,用于关闭规则的覆盖被丢弃。你会因为出现比配置更多的拒绝而发现它。 - 无效
policy.json静默的那一半:无效的safety.level会静默回退到standard,因此把paranoid拼错反而会降低你的预设。无效的secret_protection.deny_paths条目,以及会把规则提到高于默认值的按规则覆盖,都会被丢弃而不是被修复。 - 只有状态行标记是被动呈现的。
Config warning:行需要依附一次无关的拒绝才会出现,其他所有呈现位置都要等你运行命令或打开仪表板。
恢复配置
以下命令都是普通工具调用。即使运行时处于degraded,智能体也可以执行完整的恢复流程。各命令的选项和退出行为见 CLI 命令。
1
检查判定结果
ready 或 degraded,并在 Not active 下逐行列出诊断。禁用的 Claude Code 插件显示为第一个 Not active 项,不会形成单独判定。status 只提供信息,适合作为日常检查。2
获取完整报告
policy.json 的命令。运行时处于 degraded 时会显示为 config.runtime-degraded 警告,该检查项的详情就是指明每个被拒绝来源的完整原因。3
查看实际生效的内容
Issues 和 Warnings。用它确认被丢弃的来源带走了哪些规则。只有在策略存在错误时它才以非零值退出;只有警告时会打印在 Warnings 下并以 0 退出。4
验证你的规则配置
rule.json,并重放运行时的加载过程,因此能发现防护在运行时会遇到的同样问题。它还会标记出仍需迁移的旧文件。没有问题时以 All configs valid. 或 Configs valid with warnings. 结束,有问题时打印 Config validation failed. 并以 1 退出。有一处写入需要留意。当有效的 rule.json 缺少 $schema 键时,rule verify 会补上一个并打印 Added $schema to <scope> config.。除此之外,它不会改动任何内容。5
修复来源
本地 rulebook 不需要运行任何命令。编辑诊断指出的那个文件,防护会在下一次工具调用时读取它。远程来源缺失或过期时,重新落盘一次:重新解析每个已配置的远程来源,把各自的内容写入
rules/<name>/rulebook.json,然后完全按照防护的加载方式重新加载该范围。指定某个来源即可只更新它,用户范围加 --global。如果仍有诊断,它会报告该诊断并以非零值退出,不会声称成功。Rule config updated. 后面跟着 Active rulebooks (<n>): 列表,表示该范围没有诊断。每个来源各自独立更新。失败的来源会打印 Failed to update <spec>: <message> 并保留原有副本,其他来源照常更新。验证仅涵盖正在更新的范围。6
手动修复 policy.json
运行时永远不会重写
policy.json。自行更正诊断中指出的字段,或使用仪表板中的修复操作,然后重新运行 status。完整 schema 和默认值见策略。status。运行时会在下一次工具调用时重新加载,因此不需要重启任何东西。
迁移遗留的 lock 与缓存
由早期版本配置过的范围可能仍带有rule.lock 和 cache 目录。两者都不再被读取,因此快照保持 ready,也不会从中执行任何内容。cc-safety-net doctor 会把它们报告为 info 级检查项 config.v2-leftovers,标题为 Rulebook lock and cache leftovers detected,详情是 Files an earlier version left behind are no longer read: <paths>.,修复提示为 Run `cc-safety-net rule sync` (add `--global` for user scope) to migrate them, then rerun doctor.
如今 rule sync 只做这一件事。它离线运行,开头先打印弃用提示:
rule.json 缺失或无法读取,它会拒绝执行,因为此时只有 lock 还记录着已配置的来源。它打印的全部消息见 rule sync。
迁移旧的内联规则
运行时不再加载旧的内联配置文件~/.cc-safety-net/config.json 和 .safety-net.json,也不会为它们生成诊断。其中的规则不会执行,但其他功能照常工作,快照仍可能保持 ready。这会造成升级后的静默保护缺失。cc-safety-net rule verify 会标记仍需迁移的旧文件。
在要转换旧配置的那个项目中运行迁移:
rule migrate 会传递同步结果,因此如果迁移后的范围仍有诊断,它会报告该诊断而不是报告成功。迁移后的文件已经写入,旧文件也会保留,所以你可以修复报告出的问题后再运行一次。它迁移成的 rulebook 布局见自定义规则。
相关页面
策略
完整的
policy.json 契约、默认值和逐字段保留行为。自定义规则
rulebook 布局、来源、落盘、覆盖和透明包装器。
CLI 命令
status、doctor 和每个 rule 子命令的完整选项和退出行为。审计日志
决策记录在哪里、条目 schema 以及保留期。