研发协作
跨模块边界/依赖方向/关键路径变更时…
把结构不变量写成编号、可引用、可机械强制或评审的契约,用于跨模块边界、依赖方向、关键路径和架构原则的变更。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 49/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
跨模块边界/依赖方向/关键路径变更时,用通用
解决思路
- 命名不变量:给每条结构不变量编号并可引用(如「Law 3」),写明 Statement(技术中立、能超越任何框架)、Rationale、Implications;Rationale 用具体事故式失败叙事说明违反后会出现的 bug 类别,而不是抽象说理。
- 拆分稳定与易变:原则文档很少改动且不写类名;其当前实现(canonical owner、guards、参考设计)放在随代码变化的伴随文档;两者冲突时以不变量为准,并修正实现文档。
- 机械强制:每个可强制的不变量都写架构测试并让构建失败,覆盖依赖方向、包边界、分层规则、禁止 import;不能构建强制的,转成引用该不变量的命名评审检查。
- 违规即重新设计:违反命名不变量的设计按构造就是错的;重新设计,不把例外论证进规范;禁止为迎合不合规代码而稀释契约;记录违规并修复代码。
- 规格展示符合性:触及受守卫区域的设计要列出所涉不变量,并逐条说明如何满足每条不变量;评审者按命名不变量核对主张,而不是争论品味。
- 例外即修正案:真实例外要提出 amendment,指明弯曲哪个不变量以及弯曲边界;静默例外会让不变量变成建议。这是唯一合法例外形式,其他都被第 4 点禁止;owner 不可达不构成例外,变更应等待或按合规落地。真正临时例外是有日期 waiver,带过期条件和 owner 签核,记录在易变实现文档中,不为临时情况修改稳定不变量。
- 未解释的 guard exclusion 是隐藏违规:发现者要上报给不变量 owner;一个 exclusion 绝不为下一个充当先例;不要因为「别人也这样」扩展 exclusion 列表,否则是在批准侵蚀而非遵循模式。
- 把常见不变量类别纳入守卫(示例而非强制):每个关注点一个 canonical owner;依赖方向(domain 不 import delivery mechanism);关键路径隔离(hot path 无 I/O、无慢或可选依赖);fail-closed 边界(无法评估的 gate 必须拒绝);迁移不可变性(见 `principal-engineering` 硬规则)。
- 避免原则文档变成类名清单:如果原则文档充满类名,说明它是实现文档戴错标题;把实现拆到伴随文档。
- 把「暂时从那里 import 一下」当作边界死亡信号:每个违规在局部看都合理,guard 正因此存在;不要让单次方便 import 成为先例。
- 不要只靠评审断言不变量:不在构建中强制的不变量,其执行频率只等于正确评审者在场的频率;必须落到架构测试或命名评审检查。
- 不要用合规成本为违规辩护:成本论证可能对,但正确形式是由 owner 决定并记录的 amendment(如装有 `recording-decisions`),绝不是某个 spec 里的静默例外。
- 不要把原则写成品味,要写成契约:如「偏好小模块」只能失败心情,而「module X never imports module Y」能失败构建。
适用边界 · 注意事项
- 不适用于不触及模块边界、依赖方向、关键路径或既定原则的局部变更,且不需要写或更新架构原则时。
- 需要先具备 `principal-engineering` 背景;不具备该背景时不要使用此技能。
- 当既不能机械强制也不能转成命名评审检查,且没有 owner 可做 amendment/waiver 时,不要把它包装成不变量或静默放行;应等待或按合规落地。