OpenSpec + Superpowers + Harness,然后我们加了工程师

之前有篇文章聊过工厂电气化的故事:1890 年代,工厂主把蒸汽机换成了电动机,但皮带、传动轴、厂房布局一概没动。三十年后,生产效率几乎原地踏步。真正的突破来自后来------工厂围绕电力从头设计,把工作流放在第一位,不再迁就原来的传动结构。

那篇文章讲的是平台层面:组织怎么架构 AI 原生应用,才算真的用上了新能力,而不只是贴了个新标签。

这篇文章也和这个相关,讲的是开发流程。当实现一个功能从几天缩短到几小时,团队的协作模型该怎么跟着变?规律是一样的:个人工作流加速了,但团队流程没有跟上,整个系统会把那个加速全部抵消掉。

用 OpenSpec + Superpowers + Harness 跑了多轮之后,我可以确认:个人层面的加速是成功的。原来需要 2-3 天的功能,现在几小时搞定。工作流知道"完成"是什么样的,我不用守着它跑。

然后有队友想用同一套流程。就在那时,我发现了新的瓶颈。


当 Apply 只需几小时,什么变了

单人场景下的体验:认真写 spec,跑 apply,最后验证。TDD、评估、重试都由 harness 处理,循环自己跑完,不需要我中途介入。

放到团队里,同样的加速带来了不同的问题。每个工程师都能在几小时内交付一个功能,同时在开发的功能自然就更多。这是好事。但并行开发的协作成本不会凭空消失。

瓶颈不再是实现速度,而是:

  • Spec 质量:Apply 的质量上限就是 spec 的质量。写了一个模糊但通过 eval 的 spec,出来的是一个"正确地做了错事"的功能。
  • PR 审查带宽:每个工程师每天都开 PR,谁来审?能审到什么程度?
  • 冲突发现时机:两个分支都动了同一个模块,冲突会在合并时才爆出来------除非你更早把这个挖出来。
  • 共享文件争用 :2-3 人时并行归档没什么问题。到了 4-6 人同时跑 archive,CLAUDE.mdREADME.md 就成了争用热点。
  • 架构一致性:模块边界谁来定?两个功能对同一个共享接口做出了互相矛盾的假设,怎么处理?

这些问题每一个都有解,但没有一个能靠个人工作流单独解决。个人工作流告诉 Claude 某个任务的"完成"是什么样。团队工作流要告诉团队某个功能的"完成"是什么样,还要在并行开发跑偏之前就把问题解决。


分支模型

最终落地的设计,按功能规模有两个分支。

flowchart TD Start([新话题]) --> Size{规模判断} Size -->|"2天内,单模块,无架构影响"| Small[feat/topic 分支] Size -->|"3天以上,或涉及架构,或跨模块"| Large[spec/topic 分支] Small --> SmallPR[开 draft PR] SmallPR --> Apply1[Apply: TDD, Eval] Apply1 --> Arch1[在分支上归档] Arch1 --> Ready[PR 可以审查了] Ready --> Merge1([合并到 Achieve]) Large --> PR1[PR1 Spec 审查] PR1 --> Spec{审核结果} Spec -->|否| Revise[修改 spec] Revise --> PR1 Spec -->|是| FeatBranch[从 main 拉 feat/topic] FeatBranch --> Apply2[Apply: TDD, Eval] Apply2 --> Arch2[在分支上归档] Arch2 --> PR2[PR2 实现审查] PR2 --> Merge2([合并到 Achieve])

拆成两个分支,是因为 spec 审查和代码审查本质上是两件事,风险级别也不同。

Spec 审查的风险更高:需求写错了,apply 会正确地交付错误的东西。而 harness 验证过之后的代码审查性质完全不同:CI 绿,eval 全通,没有未解决的 CRITICAL/HIGH。PR2 要判断的是 Claude 有没有实现 spec 的真实意图,不是把 harness 已经跑过的质量检查再手动走一遍。

触发大型功能轨道的条件(满足一条即可):

  • 涉及两个以上工程师活跃工作共用的接口
  • 需要团队对齐的架构决策
  • 预计 apply 时间 ≥ 3 天
  • 对现有 capability spec 的破坏性改动

Harness 验证后,PR 审查看什么:

检查项 来源
CI 全绿(单元 + 集成 + E2E)? CI 面板
所有 eval 组达到阈值? eval-log.md
CRITICAL/HIGH 全部解决? 最终评估器输出
PR 描述和 spec 意图对得上? proposal.md

不要逐行做代码审查。Harness + CI 才是主要的质量关卡,正确性判断比人工检查更可靠。人类在 PR 上带来的是 spec 保真度的判断:Claude 实现的是我们真正想要的,还是只是我们字面上写的东西?


并行开发,不在合并时踩雷

分布式开发里最麻烦的冲突,不是 git 里的 merge conflict。是在两周并行工作结束后才浮出来的设计冲突------你发现工程师 A 的功能依赖的接口,已经被工程师 B 改掉了。

解法:把冲突的暴露点从合并时提前到 propose 时

/opsx:propose <topic-B> 执行期间:

bash 复制代码
→ 读取 openspec/specs/(所有现有 capability spec)
→ git branch -r | grep 'feat/\|spec/'(列出活跃分支)
→ 读取每个活跃分支的 proposal.md
→ 在 design.md 的 Dependencies 部分写下:
    "depends on: topic-A(需要 auth 接口稳定后才能 apply)"
    "conflicts with: 未检测到"

这不是什么复杂的依赖分析工具,就是个阅读任务。Claude 把活跃分支和现有 spec 读一遍,声明它看到了什么。如果 topic-B 依赖的接口还在 topic-A 里改,这个依赖在 apply 开始之前就是可见的,不用等跑完之后才发现。

B 依赖 A 的接口时:A 的 spec PR 必须先合并,B 才能进 apply。不是"无法并行化"------是"接口确定之后,并行实现才能开始"。

两类冲突,处理方式不同:

代码冲突 是正常 git 工作。Rebase 解决就行。

设计分歧 走一个决策树:实现细节的分歧交给评估器仲裁(哪种方案在 spec 下得分高就用哪个),架构层面的设计决策写进 design.md Alternatives 部分留作团队同步,需求理解有歧义的退回 explore 重写。规律是:让冲突可见,让决策显式,把它写下来。Spec 在积累决策。后来的工程师------以及之后跑的 Claude apply------都从这些积累的上下文里读取。


四层 Achieve 关卡

Apply 完成 ≠ Achievement。Harness 告诉你代码对了,Achieve 告诉你功能可以发布了。

flowchart LR S([Apply 完成]) --> A[本地关卡] A -->|通过| B[CI关卡] A -->|失败| FA[修复 eval] FA --> A B -->|通过| C[PR关卡] B -->|失败| FB[修复 CI] FB --> B C -->|通过| D[归档关卡] C -->|失败| FC[处理审查] FC --> C D -->|通过| E([Achieve]) D -->|未完成| FD[补全归档] FD --> D

集成测试是故意放在 CI 里跑的。本地环境通常没有完整的服务栈------外部 API、多容器编排、有状态的数据库,这些维护起来成本太高,不值得。CI 有完整环境,就在那跑。这是明确的取舍。

一个值得关注的方向:在开发阶段就给每个 PR 提供类生产的隔离沙箱。Signadot 在这个方向专门发力------他们的重点就是开发侧,coding agent 提交变更,需要一个隔离环境来验证。这和第二层的缺口直接对应:如果每个分支都有沙箱,集成测试就能在循环里更早跑,不用等到 CI。值得作为进一步收紧 achieve 关卡的方向探索。

PR 打后如果 CI 失败:工程师把失败日志粘给 Claude,Claude 在 feature 分支上修,展示 diff,工程师审完批准,Claude 再提交推送。不是完全的重新 apply------只针对这个具体的失败。Git 历史保持干净。


集成层

四层关卡定义了"完成"是什么样。集成层的目标是让这一切对团队其他人可见------不需要任何人手动更新 ticket。

设计这一层有三个核心目标:

  1. 可见性 --- PM 不用开口问,就能看到一个 ticket 处于 OpenSpec 的哪个阶段
  2. 自动化 --- JIRA 状态自动更新,零人工操作
  3. DoD 强制执行 --- eval 没过、CI 没绿、归档没完,ticket 关不了

做法:用 opsx CLI 作为集成层。每个阶段命令(opsx exploreopsx proposeopsx applyopsx archive)在内部的 post-step 里调用 jira_hook.py。Jenkins 是纯粹的执行者,跑 opsx 命令。JIRA 集成逻辑在 opsx 里,不在 Jenkinsfile 里。

这样做的好处:集成逻辑可以在本地测试,开发和 CI 行为一致,而且具备容错性------JIRA API 报错不是致命错误。JIRA 挂了,build 照样跑。

JIRA 状态映射

flowchart LR E([Exploring]) -->|opsx propose| P([Proposing]) P -->|"PR1 开启,仅大型功能轨道"| SR([Spec Review]) SR -->|spec 合并| AP P -->|"opsx apply,小型功能轨道"| AP([Applying]) AP -->|PR 开启| IR([In Review]) IR -->|"DoD 通过,opsx archive"| Done([Done]) IR -->|DoD 未通过| Blocked([Blocked]) Blocked -->|修复并重新归档| IR classDef phase fill:#90EE90,stroke:#333,stroke-width:2px,color:#006400 classDef done fill:#E6E6FA,stroke:#333,stroke-width:2px,color:#00008B classDef blocked fill:#FFB6C1,stroke:#DC143C,stroke-width:2px,color:#000000 class E,P,SR,AP,IR phase class Done done class Blocked blocked

.meta.yaml 里的 jira_key 是可选字段,没有这个字段所有 hook 静默跳过。两个方向都支持:PM 先建 ticket,或者工程师先开 explore、后面再补关联。

Jenkins:每个阶段在哪里跑

explorepropose 在本地跑------这两步是和 Claude 的交互式对话。apply 可以在 Jenkins 上跑(feat/* 分支),也可以本地跑。archive 在合并后的 Jenkins 上跑,负责执行 DoD 检查。

groovy 复制代码
stage('apply') {
  when { branch 'feat/*' }
  steps { sh 'opsx apply $TOPIC' }
}
stage('test') {
  steps {
    sh 'make test'   // 单元 + 集成
    sh 'make e2e'    // E2E(CD 流水线)
  }
}
stage('archive') {
  when { branch 'main' }
  steps { sh 'opsx archive $TOPIC' }
}

TOPIC 从分支名自动推导(feat/auth-refactorauth-refactor)。

归档时的 DoD 强制执行

opsx archive 把 ticket 推到 Done 之前,会跑四项检查:

检查项 通过条件
eval-log.md 无 CRITICAL 或 HIGH
CI 状态 构建通过
PR 状态 已合并到 main
归档文件 pitfalls.md 存在 + spec.md 状态为 DONE

任何一项没过,ticket 进 Blocked,附上哪项检查失败的说明,exit 1,Jenkins stage 报红。MEDIUM 和 LOW 只是警告。

结果是:JIRA 里到达 Done 的 ticket,意味着 harness 验过代码,CI 通过了,人工审查批了,知识也归档了。不是有人填完的检查清单------是自动跑的关卡。


工程师现在做什么

Harness 改变了个人的工作循环,团队工作流改变了工程师的角色。

Apply 自动处理 TDD、评估、重试,工程师的时间从执行转向判断。

之前 之后
实现是核心工作 Spec 撰写是核心工作
高级工程师 = 编码最快的人 高级工程师 = Spec 写得最准 + 最有架构判断力的人
瓶颈 = 实现速度 瓶颈 = PR 审查带宽 + Spec 质量
一个功能需要 2-3 天 一个功能只需几小时,更多功能同时推进

Spec 撰写是最有价值的工作。 三十分钟精准的 spec,能换来三小时干净的 apply。模糊的 spec 产出通过 eval 但偏离意图的代码------技术上正确,做的是错误的事。工程师成了需求翻译官:把产品意图转化为 Claude 能精确执行的 SHALL 语句。

Spec 保真审查取代代码审查。 到了 PR,要问的问题变成:

  • Claude 实现的是 spec 的意图,还是只是字面上写的内容?
  • Eval 通过是因为 spec 写得好,还是因为它太模糊根本无法失败?
  • 边缘情况有没有在 spec 里明确写出来,还是被悄悄遗漏了?

架构判断仍然属于人。 谁来写 spec/arch-<name>?谁来拆解子话题?谁来定义模块边界?谁来决定接口契约的样子?这些需要对系统走向的理解,Claude 没法替代。这需要真正想过系统演进的工程师,不是只看着当前状态的人。

工程师的工作变成了:决定做什么,定义完成是什么样,验证 AI 真的做对了。头和尾。中间自己跑。


扩展到三人以上

2-3 人时,共享文件几乎不构成问题。4-6 人同时跑并行 archive 时,CLAUDE.mdopenspec/specs/README.mdopenspec/config.yaml 就成了合并冲突的来源。

解法:archive 只碰 per-capability 的文件。

bash 复制代码
CLAUDE.md                  ← 短小稳定的索引,archive 时不更新
openspec/specs/README.md   ← 只在新建 capability 时更新(在 spec PR 里,不在 archive 时)
openspec/config.yaml       ← 通过专用 chore PR 修改,不绑定到功能开发

openspec/specs/<capability>/spec.md      ← 每次归档该 capability 时更新
openspec/specs/<capability>/pitfalls.md  ← 每次归档该 capability 时更新

不同 capability = 不同文件 = 并行 archive 永不冲突。六个工程师同时归档,互不影响。

CLAUDE.md 变成了一个短小稳定的索引:

markdown 复制代码
## Capability Pitfalls
apply 时读取对应文件:
- auth: openspec/specs/auth/pitfalls.md
- payment: openspec/specs/payment/pitfalls.md
- notifications: openspec/specs/notifications/pitfalls.md

## 全局 Pitfalls
[仅跨模块的 pitfall,保持 5 条以内]

绝大多数 pitfall 有 capability 归属,archive 时直接写进 per-capability 文件。Global 部分增长缓慢。这是防止 CLAUDE.md 越来越臃肿的关键------臃肿的 CLAUDE.md 会让长期项目越来越难维护。


乘数效应

个人 AI 工具给了一个工程师生产力乘数。实现循环缩短了,瓶颈转移了。

围绕新瓶颈重组的团队,可以在这个乘数上再叠一个乘数。不是因为 AI 做了更多事,而是因为工程师的时间真正集中到了杠杆最高的地方:spec 的精准度,架构的一致性,以及随着每次 archive 持续积累的 openspec/specs/ 知识库。

风险在工作流不对。Spec 写得一团糟还在快速 apply,会快速产出错误的东西。Harness 能捕获实现错误,抓不住 spec 错误。那是工程师的工作,需要有意识地投入。

做对了:团队交付更多,知识随每次 archive 不断积累,真正需要人类判断的工作------决定做什么、定义完成是什么、验证它真的发生了------才是工程师时间真正去的地方。

一个工程师用这套工具栈,可能看到 10x 生产力提升。把工作流做对的团队,能在这个 10x 上再叠一层乘数。做错了,加速反而会帮倒忙。


参考资料

本系列:

本篇设计文档:


这套方法论还没完成。也不会完成。这依然是重点所在。

相关推荐
明航咨询—张老师7 小时前
告别文档堆砌,CMMI V3.0 如何让敏捷开发真正落地
敏捷开发·devops·数据驱动·cmmi v3.0
猴哥聊项目管理3 天前
研发管理软件推荐清单:如何搭建一套高效的DevOps研发效能平台?
信息可视化·研发效能·项目管理·敏捷开发·devops·研发工具选型·研发工具
2401_853087889 天前
企业私有代码仓库建设:高可用、备份恢复与灾备方案复盘
敏捷开发·devops·源代码管理
2401_8530878810 天前
历史知识库平滑迁移:全量数据迁移、格式兼容与低切换成本方案
敏捷开发·devops
wanghao66645513 天前
ACP敏捷项目管理中的风险燃尽图:让风险一目了然敏捷实践 · 风险管理 · 可视化
敏捷开发
MESMarketing16 天前
互动分享 | Shift-Left实践落地
功能测试·测试工具·自动化·自动驾驶·敏捷开发
TYKJ02322 天前
Day3、我在生产环境踩过的5个网络配置坑(每一个都差点背锅)
网络协议·敏捷开发
SamDeepThinking23 天前
批评下属不如当场展示解决方案
后端·程序员·团队管理
SamDeepThinking23 天前
打造高效团队的四个关键动作
java·后端·团队管理