配置分层与 override 契约
September 10, 2026 · View on GitHub
状态:权威开发规则(authoritative) 读取时机:新增或修改 Settings UI、配置文件、本地偏好存储、运行时 profile,或 agent/MCP/provider 相关开关之前
本规则适用于所有用户可配置项。Cindy 允许用户高度定制,但默认配置承载创作者品味,
是产品体验的一部分——不是让每个选项都堆进设置页。产品边界见
../product-rules/core-product-principles.md;
进入 Settings UI 的配置还必须遵守
../design-rules/cindy-design-system.md(主题
token)与 engineering-conventions.md(i18n)。
增量适用原则:约束新增和正在修改的配置项,不要求为统一形式专项重构存量配置。
1. 可见性分层
新增/修改任何可配置项前,先判断它属于常规设置、高级设置、隐藏配置还是内部常量;不要 因为技术上能配置就放进 Settings 外层。
- 只有大多数用户经常需要理解并调整、且无需理解内部实现的选项,才默认可见。
- 低频、专业或误改成本高的选项进入高级设置。
- 有定制价值但不值得占用 UI 注意力的选项进入配置文件、本地配置存储,或由 agent 通过 自然语言修改。
- 涉及产品语义、安全边界、数据契约或核心体验的不变量保留为内部常量。
2. 默认值与用户 override 分离
- 每个配置项都必须能判断是否被用户显式自定义。
- 运行时以「系统默认值 + 用户 override」合并出有效值;持久化只记录 override 与必要的 自定义标记,不把完整默认配置复制进用户配置。
- 未自定义的用户随版本获得新默认值,已自定义的用户保留自己的选择。
模型资料的系统层再区分公共默认、供应商默认、供应商实报与服务端明确修正;用户覆盖始终最高。 发现快照和用户字段分开持久化,详见 模型资料优先级。
模型可见性
显示开关的有效值是 用户显式 override ?? 当前目录 defaultEnabled。此条只约束模型显示开关。
- 目录下发哪些默认开、哪些默认关,没拨过开关的路线一律跟随。目录后来新增的默认开模型 要显示出来;客户端不得把「没有开关记录」做成全关。
- 用户手动开过或关过的写成 override,升级不清、不覆盖。
- 「恢复默认」只删除本次点名路线的 override,重新跟随当前目录。
- 收藏、历史选择、引擎偏好不能当成开关。
- 桌面、IM 与远端用同一套 override;没 override 的路线由各端按当时目录 defaultEnabled 计算。
实现核对须区分上游原始目录与执行端活动目录:当前仍有客户端精简陈列投影,见 已知实现差异。该说明不是对本节合同的豁免; 不得仅因代码仍在筛选就反向修改产品规则,也不能未验证便声称两者已一致。
3. 默认值演进与迁移
- 默认值变化时,分别说明新用户、未自定义老用户、已自定义老用户的行为。
- 迁移必须基于「是否自定义」的状态判断,不得通过旧值猜测用户意图;只有历史数据缺少 自定义状态时才允许一次性兼容迁移,并在代码或 PR 中说明判断依据与风险。
4. 恢复默认
- Settings 中「恢复默认」的语义是删除对应 override、重新跟随当前版本默认值,而不是 写入一份静态默认值快照。配置组与整体设置页应提供相应粒度的恢复入口。
- 用户通过 agent 要求恢复默认时同样删除 override。
5. 隐藏配置也是正式契约
- 隐藏配置必须有清晰 schema、字段说明、取值约束和安全边界,不能依赖零散分支或隐式 约定。
- agent 修改配置时,只有用户明确要求才写入 override,不得把当前默认值固化回用户配置。
Review 清单
- 新配置的可见性层级选对了吗?是否因“技术上能配”就塞进了设置页外层?
- 有效值是否由「默认 + override」合并?持久化是否只存 override 而非完整默认?
- 默认值变化的迁移是否基于「是否自定义」,而非用旧值猜意图?
- 「恢复默认」是否删 override 跟随版本,而不是写静态快照?
- 隐藏配置是否有正式 schema 与安全边界?agent 是否只在用户明确要求时写 override?
实现/PR 说明至少写明:配置层级、默认值及推荐理由、override 如何记录与识别、未自定义 用户如何跟随新默认、恢复默认会清除什么。