在 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. 并行开发会让“规约先行”变成“规约追赶实现”
团队初期最常见的问题是:
- 大家先写了一版 spec
- 开发过程中发现现实更复杂
- 某些人直接改代码,不及时回写 spec
- 结果代码是真的,spec 变成假的
这比没有 spec 更危险,因为团队会误以为“我们是对齐的”。
所以在 SDD 里,真正需要防的是:
spec 名义上是单一事实来源,实际上代码才是事实来源。
会遇到哪些典型冲突场景
场景一:多人同时改同一个业务流程
例如“下单-支付-发货-退款”流程,订单组、支付组、客服组都可能改。
这时冲突往往不是 Git 冲突,而是:
- 状态机是否一致
- 事件顺序是否一致
- 回滚逻辑是否一致
- 异常补偿责任归属是否一致
场景二:一个人改领域模型,另一个人改接口
A 在 spec 里把 status 拆成 payment_status 和 fulfillment_status; B 还在按旧接口返回单一 status。
最后会出现:
- 文档能解释
- 代码能运行
- 系统却不能一致演化
场景三:跨团队协作时,局部最优破坏全局一致
每个小组都觉得自己“只是加一个字段 / 一个例外规则”,但累计起来,规约会越来越脏,出现:
- 特例过多
- 命名不统一
- 错误码风格不一致
- 状态流转无法闭合
这在 OpenSpec 这类强调规约驱动的框架里尤其明显,因为 spec 本身就是协作核心。
怎么把冲突控制住
核心不是“避免冲突”,而是让冲突可见、可裁决、可追溯。
一、把 spec 分成“稳定层”和“易变层”
建议这样分:
| 层级 | 内容 | 变更频率 | 管理方式 |
|---|---|---|---|
| 稳定层 | 核心术语、领域边界、主流程、核心状态机 | 低 | 严格评审,少数人维护 |
| 易变层 | 参数、策略、边界条件、灰度规则 | 高 | 模块 owner 维护 |
| 契约层 | API、事件、字段、错误码 | 中 | 变更必须通知依赖方 |
| 实现层 | 技术选型、代码组织、任务拆解 | 高 | 开发组自主管理 |
这样多人并行时,不是所有人都去改“总规约”。
二、明确 owner 机制
一份 spec 如果没有 owner,就一定会失控。
建议至少定义:
- 业务 owner:负责业务语义正确
- 技术 owner:负责可实现性和架构一致
- 接口 owner:负责契约稳定
- 模块 owner:负责具体子域
多人都能提变更,但必须有人有最终裁决权。
三、使用“变更提案”而不是直接改主规约
不要让所有人直接改主 spec。 更好的做法是:
- 先提 spec change
- 描述背景、影响范围、兼容性
- 评审通过后再合入主规约
- 再驱动代码开发
这相当于把代码里的 PR 流程,前移到规约层。
四、把依赖关系显式化
每次改 spec,都要回答 4 个问题:
- 影响哪些模块?
- 影响哪些接口?
- 是否破坏兼容性?
- 是否需要迁移策略?
如果这些不写清楚,多人并行开发一定会踩坑。
五、对规约做版本化
spec 不能只是一个文档,它需要像代码一样管理:
- 有版本号
- 有变更记录
- 有弃用策略
- 有兼容说明
否则团队里一定有人按旧版本开发。
六、让“测试用例/验收用例”绑定规约
最有效的方法之一,是把规约变成可验证对象,例如:
- 每条关键规则配验收样例
- 每个接口契约有 contract test
- 每个状态机有示例路径和反例路径
这样争议不再停留在“我觉得”,而是落到“是否满足规约例子”。
一个很实际的判断标准
如果一个团队在 SDD/OpenSpec 下并行开发,出现下面这些现象,说明规约治理有问题:
- spec 经常在开发完成后补写
- 同一个概念在不同文档里名字不一样
- 接口字段反复变
- 联调时才发现核心规则不一致
- 大家都在问“以哪个文档为准”
- 出问题时只能去读代码确认真实逻辑
如果出现这些,说明团队并不是“Spec-Driven”,而只是“Spec-Decorated”。
结论
简要说:
-
会影响规约,也一定会有冲突。
-
但这不是 SDD/OpenSpec 的缺点,而是它把冲突提前暴露了。
-
真正的问题不在“多人并行”,而在于:
- 规约有没有分层
- 是否有 owner
- 变更是否走评审
- 契约是否版本化
- spec 是否能被测试和执行验证
-
做得好,SDD 会让多人协作比传统方式更稳;做不好,spec 会迅速变成新的混乱源。