SDD下OpenSpec规约冲突问题

7 阅读6分钟

在 SDD(Spec-Driven Development)模式下,像 OpenSpec 这类框架把“规约 / spec”放在开发前面,本质上是把很多原本在代码层暴露的问题,前移到规约层。多人并行开发时,冲突不会消失,只是从“代码冲突为主”变成了:

冲突类型典型表现本质
需求语义冲突两个人对同一条业务规则理解不同规约语义不一致
边界冲突A 改订单状态流转,B 改退款规则,最终相互影响领域边界未切清
接口冲突前后端或服务间对字段、枚举、错误码理解不一致契约未冻结
版本冲突某成员按旧 spec 开发,另一成员已更新 spec规约版本漂移
优先级冲突一个组员追求快速上线,另一个坚持规约完整性团队治理问题
合并冲突多人同时改同一份 spec 文档/同一模块协作机制不足

为什么 SDD 下冲突反而更“显眼”

因为在普通开发里,很多分歧会等到联调、测试、线上问题才暴露;而在 SDD 下,大家先围绕 spec 工作,所以冲突更早被看见。

这其实是好事。 早暴露的冲突,比晚暴露的 bug 成本低得多。

你可以把它理解为:

  • 传统方式:冲突主要在代码合并阶段爆发
  • SDD 方式:冲突主要在规约评审阶段爆发

前者改代码成本高,后者改文档和设计成本低。

多人并行时,规约会受到哪些具体影响

1. 同一规约被多人修改,容易出现“语义撕裂”

比如一个支付模块 spec,A 把“支付失败可重试”写进异常处理,B 又在风控章节里写“失败后必须重新发起申请”。这两条都看起来合理,但放在一起就是冲突。

问题不在格式,而在于:

  • 谁是最终裁决口径
  • 哪条规则优先
  • 场景是不是被拆分清楚

2. 规约粒度不合适,会放大团队摩擦

如果 spec 写得太大、太集中,所有人都改同一个文件,就会频繁冲突。 如果 spec 写得太碎,又可能丢失全局一致性。

所以 SDD 下最关键的是分层规约,通常要拆成:

  • 产品/业务总规约
  • 领域规约
  • 模块规约
  • 接口契约
  • 实现约束 / ADR

这样每个人改自己的层,冲突会少很多。

3. 并行开发会让“规约先行”变成“规约追赶实现”

团队初期最常见的问题是:

  1. 大家先写了一版 spec
  2. 开发过程中发现现实更复杂
  3. 某些人直接改代码,不及时回写 spec
  4. 结果代码是真的,spec 变成假的

这比没有 spec 更危险,因为团队会误以为“我们是对齐的”。

所以在 SDD 里,真正需要防的是:

spec 名义上是单一事实来源,实际上代码才是事实来源。

会遇到哪些典型冲突场景

场景一:多人同时改同一个业务流程

例如“下单-支付-发货-退款”流程,订单组、支付组、客服组都可能改。

这时冲突往往不是 Git 冲突,而是:

  • 状态机是否一致
  • 事件顺序是否一致
  • 回滚逻辑是否一致
  • 异常补偿责任归属是否一致

场景二:一个人改领域模型,另一个人改接口

A 在 spec 里把 status 拆成 payment_statusfulfillment_status; B 还在按旧接口返回单一 status

最后会出现:

  • 文档能解释
  • 代码能运行
  • 系统却不能一致演化

场景三:跨团队协作时,局部最优破坏全局一致

每个小组都觉得自己“只是加一个字段 / 一个例外规则”,但累计起来,规约会越来越脏,出现:

  • 特例过多
  • 命名不统一
  • 错误码风格不一致
  • 状态流转无法闭合

这在 OpenSpec 这类强调规约驱动的框架里尤其明显,因为 spec 本身就是协作核心。

怎么把冲突控制住

核心不是“避免冲突”,而是让冲突可见、可裁决、可追溯

一、把 spec 分成“稳定层”和“易变层”

建议这样分:

层级内容变更频率管理方式
稳定层核心术语、领域边界、主流程、核心状态机严格评审,少数人维护
易变层参数、策略、边界条件、灰度规则模块 owner 维护
契约层API、事件、字段、错误码变更必须通知依赖方
实现层技术选型、代码组织、任务拆解开发组自主管理

这样多人并行时,不是所有人都去改“总规约”。

二、明确 owner 机制

一份 spec 如果没有 owner,就一定会失控。

建议至少定义:

  • 业务 owner:负责业务语义正确
  • 技术 owner:负责可实现性和架构一致
  • 接口 owner:负责契约稳定
  • 模块 owner:负责具体子域

多人都能提变更,但必须有人有最终裁决权

三、使用“变更提案”而不是直接改主规约

不要让所有人直接改主 spec。 更好的做法是:

  1. 先提 spec change
  2. 描述背景、影响范围、兼容性
  3. 评审通过后再合入主规约
  4. 再驱动代码开发

这相当于把代码里的 PR 流程,前移到规约层。

四、把依赖关系显式化

每次改 spec,都要回答 4 个问题:

  1. 影响哪些模块?
  2. 影响哪些接口?
  3. 是否破坏兼容性?
  4. 是否需要迁移策略?

如果这些不写清楚,多人并行开发一定会踩坑。

五、对规约做版本化

spec 不能只是一个文档,它需要像代码一样管理:

  • 有版本号
  • 有变更记录
  • 有弃用策略
  • 有兼容说明

否则团队里一定有人按旧版本开发。

六、让“测试用例/验收用例”绑定规约

最有效的方法之一,是把规约变成可验证对象,例如:

  • 每条关键规则配验收样例
  • 每个接口契约有 contract test
  • 每个状态机有示例路径和反例路径

这样争议不再停留在“我觉得”,而是落到“是否满足规约例子”。

一个很实际的判断标准

如果一个团队在 SDD/OpenSpec 下并行开发,出现下面这些现象,说明规约治理有问题:

  • spec 经常在开发完成后补写
  • 同一个概念在不同文档里名字不一样
  • 接口字段反复变
  • 联调时才发现核心规则不一致
  • 大家都在问“以哪个文档为准”
  • 出问题时只能去读代码确认真实逻辑

如果出现这些,说明团队并不是“Spec-Driven”,而只是“Spec-Decorated”。

结论

简要说:

  1. 会影响规约,也一定会有冲突。

  2. 但这不是 SDD/OpenSpec 的缺点,而是它把冲突提前暴露了。

  3. 真正的问题不在“多人并行”,而在于:

    1. 规约有没有分层
    2. 是否有 owner
    3. 变更是否走评审
    4. 契约是否版本化
    5. spec 是否能被测试和执行验证
  4. 做得好,SDD 会让多人协作比传统方式更稳;做不好,spec 会迅速变成新的混乱源。