Skip to content

Latest commit

 

History

History
142 lines (96 loc) · 5.31 KB

File metadata and controls

142 lines (96 loc) · 5.31 KB

18. Settings、Policy 与托管配置

这篇讲什么

这一章解释 Claude Code 的设置从哪里来、按什么顺序叠加,以及为什么 policy / managed settings 会被单独当成一类源。

先给结论

Claude Code 的设置系统不是单文件配置,而是多来源合并系统。当前快照里至少存在:

  • user settings
  • project settings
  • local settings
  • flag settings
  • policy settings
  • plugin settings base

其中 policy settings 又不是单一文件,而是 remote managed settings、MDM、文件型 managed settings、HKCU 的“首个非空源优先”链路。

源码依据

Mermaid 图:settings 来源优先级图

flowchart TD
    A["plugin settings base"] --> B["userSettings"]
    B --> C["projectSettings"]
    C --> D["localSettings"]
    D --> E["flagSettings"]
    E --> F["policySettings"]
    F --> G["effective settings"]
    F --> H{"policy 来源"}
    H --> H1["remote managed"]
    H --> H2["MDM: HKLM / plist"]
    H --> H3["managed-settings.json + drop-ins"]
    H --> H4["HKCU"]
Loading

SETTING_SOURCES 的顺序不是装饰

src/utils/settings/constants.ts 里把来源顺序写成:

  • userSettings
  • projectSettings
  • localSettings
  • flagSettings
  • policySettings

注释直接说明 later sources override earlier ones。也就是说,settings merge 的语义不是推断出来的,而是常量层面就固定了。

policy settings 走的是“首个非空源优先”

src/utils/settings/settings.tspolicySettings 单独分支处理,并明确写明优先级:

  1. remote managed settings
  2. MDM (HKLM / macOS plist)
  3. managed-settings.json + managed-settings.d/*.json
  4. HKCU

这和普通 settings source 不同。普通源是 merge;policy 源是先选出“赢者”,再并入总配置。

managed settings 文件如何组织

loadManagedFileSettings() 说明:

  • 基础文件是 managed-settings.json
  • drop-in 目录是 managed-settings.d/
  • 基础文件先 merge
  • drop-in 文件按文件名字典序排序后覆盖

这是典型的系统级配置 drop-in 设计,和 systemd / sudoers 的管理习惯很像,方便多团队分别下发策略片段。

remote managed settings 为什么单独成体系

src/services/remoteManagedSettings/index.ts 说明这套服务具备:

  • 用户 eligibility 检查
  • OAuth / API key 两套认证头
  • checksum / sha256 级别的内容校验
  • 重试与轮询
  • 安全检查
  • fail-open 行为

其中最关键的是 fail-open。源码注释直接说明远程托管设置获取失败时不会阻断主流程,而是继续运行。

settings 合并不是简单覆盖

settingsMergeCustomizer() 表明:

  • 数组会 concat + dedupe
  • 普通对象走 lodash 深合并

同时 updateSettingsForSource() 又对写回做了额外规则:

  • 数组写回时直接替换
  • 显式 undefined 表示删除键
  • localSettings 写回后会异步加到 .gitignore

这说明“读取时的合并策略”和“写回时的编辑语义”是分开的。

可信源和非可信源的差别

同一个 settings.ts 里,像 hasSkipDangerousModePermissionPrompt()hasAutoModeOptIn()getUseAutoModeDuringPlan() 这类函数都会刻意排除 projectSettings,注释还直接提到 malicious project 风险。

这很重要。它说明 Claude Code 不认为所有 settings source 都同等可信。项目目录中的共享配置可以影响行为,但不能自动替用户接受高风险授权。

migration 的意义

src/migrations/ 目录中能看到大量“旧模型 / 旧选项迁移到新 setting”的脚本,例如:

  • 旧模型名迁移
  • 自动更新设置迁移
  • remote control 启动项迁移

这说明 settings 体系是长期演化的,Anthropic 预期用户配置会跨版本存活,因此必须维护迁移层。

对研究者的意义

这套 settings 系统体现出几个工程判断:

  • Claude Code 已经不是单机玩具配置,而是企业可治理配置。
  • policy 与 user/project/local 被明确区分。
  • 远程托管、MDM、本地 managed 文件被整合进统一策略层。
  • 某些高风险行为只接受“可信源”授权。

这一章的工作结论

Claude Code 的 settings 系统本质上是“多源 merge + 托管策略优先 + 可信边界控制”的配置治理系统,而不是一个普通的 settings.json 读取器。

延伸阅读