OpenSpec-practise

把静默失败堵死:OpenSpec v1.13.0 工作流实践

OpenSpec v1.12.0 与 v1.13.0 相继发布(2026-09),均无 breaking change。v1.13.0 的主题可以概括为一句话:archive 和 delta 解析器不再悄悄改掉或丢掉你写的内容。本文通过真实案例「订单列表查询」(order-list-query)演示升级后的完整工作流(Explore → Propose → Apply → Archive),并记录两个版本中对实践有实际影响的变化——包括 validate --report findings 首跑就在本仓库抓到 3 个真实问题。

一、两个版本的变化要点(实践视角)

v1.12.0:校验报告与有据规划

v1.13.0:delta 解析器与 archive 的健壮性

二、实践案例:order-list-query

2.1 Explore:新模板的第一次实战

按 v1.13 explore 模板走了一遍新的盘点路径:openspec list --specs 列出 7 个能力的需求计数,再对照双实现的路由表找缺口。剩余缺口四个:订单列表查询(小-中)、购物车清空接口(极小)、订单支付实现(大)、商品删除(中-大,涉库存引用)。

选定订单列表查询:GET /api/orders?userId= 返回订单历史——下单后「查看我的订单」是订单闭环的自然缺口;repo 层已有遍历能力,工作量可控;纯 ADDED 需求。

explore 阶段读代码时发现一个双实现差异:Python Order 模型没有 user_id 字段,而 Node 的订单对象一直携带 userId。这意味着按用户过滤的前提是先补齐模型——这个发现直接改变了 design 的内容。

2.2 Propose:新流程的 context 加载

按新 propose 模板第 2 步先跑 openspec context --json(返回权威 root 路径),确认后才读 config.yaml 的 context 字段作为规划约束。四个 artifacts:

2.3 Apply:同一坑第二次踩到

双实现落地各约 20 行。但 Node 集成测试首跑即失败:下单断言期望 201、实际 400(CART_EMPTY)——与 PR #11 修复的性能测试是同一个坑:dev 购物车端点固定 user_dev,测试却用别的 userId 下单。修正为 user_dev 视角的相对断言(记录前置订单数,断言 +2);多用户隔离断言放到 Python 侧——Python 购物车请求自带 userId,天然支持多用户 E2E。

这个重复踩坑本身值得记入实践账本:dev 服务器的 mock 身份模型(固定 user_dev)与测试的多用户意图存在结构性张力。unit 层测隔离(直连服务层)、integration 层测单用户闭环 + Python 侧补多用户,是当前架构下的合理分工。

测试结果:Node 18/18、Python 6/6 全绿。

2.4 validate –report findings:首跑抓到 3 个真实问题

收尾阶段用 v1.12 的新报告模式跑了一次主 specs 校验:

$ openspec validate --report findings --specs
spec/cart-management
  [WARNING] overview: Purpose section is too brief (less than 50 characters)
spec/payment
  [WARNING] overview: Purpose section is too brief (less than 50 characters)
spec/product-query
  [WARNING] overview: Purpose section is still a placeholder rather than
  a Purpose anyone wrote ...
Totals: 7 passed, 0 failed (7 items)

三个警告全部属实:cart/payment 的 Purpose 确实不足 50 字符;product-query 的 Purpose 还是 v1.5.0 实践归档时 CLI 写入的 TBD - created by archiving change ... 占位符,至今无人补写。逐一修复后 findings 清零。这正好完整验证了 v1.9.0(Purpose 格式)→ v1.11.0(占位符警告)→ v1.12.0(findings 报告)三个版本的演进闭环——工具逐版本补上的守护,在真实仓库里就是逐版本浮出的历史欠账。

2.5 Archive

openspec archive 一条命令完成合并(+1 added)与归档,产物为 openspec/changes/archive/2026-09-10-order-list-query/。归档后全量校验:无 active changes、7 specs 全部通过、findings 为空。

三、实践总结

3.1 v1.13.0 的价值是「消灭静默失败」

此前 delta 解析器的三个静默失败模式(*/+ 列表符不生效、重复 delta 段落只应用一份、fenced 空行被改写)共同点是:工具链报告成功,结果却是错的。这类失败比崩溃更危险——它污染的是”单一事实来源”本身。v1.13.0 把它们全部变成”要么生效、要么报错”。

3.2 工具守护的复利

从 v1.9.0 到 v1.13.0,五次升级在同一个点上持续加码:spec 的内容质量。Purpose 格式迁移 → 占位符警告 → findings 报告,每一层守护都在下一次实践中兑现了价值。SDD 的工具链价值不只是”生成更快”,更是”漂移更早被发现”。

3.3 遗留观察


本文基于 OpenSpec Practise 仓库的 order-list-query 实践(2026-09-10),完整产物见 openspec/changes/archive/2026-09-10-order-list-query/。