首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >OpenSpec 项目实战(七)| verify 2 个工具、3 处修复,第 4 维度依然缺席

OpenSpec 项目实战(七)| verify 2 个工具、3 处修复,第 4 维度依然缺席

原创
作者头像
运维有术
发布2026-06-02 22:22:44
发布2026-06-02 22:22:44
1650
举报
文章被收录于专栏:运维有术运维有术

🚩 2026 年「术哥无界」系列实战文档 X 篇原创计划 第 127 篇,OpenSpec 项目实战「2026」系列第 7

大家好,欢迎来到 术哥无界 | ShugeX | 运维有术

我是术哥,一名专注于 AI 编程、AI 智能体、Agent Skills、MCP、云原生、AIOps、Milvus 向量数据库的技术实践者与开源布道者

Talk is cheap, let's explore。无界探索,有术而行。

信息图封面:OpenSpec verify 修复 + json-formatter 实现
信息图封面:OpenSpec verify 修复 + json-formatter 实现

图:信息图封面:OpenSpec verify 修复 + json-formatter 实现

上一期做了三层改造——template 改了 tasks 格式、review 加了 4 维度审查和拆分方向建议、verify 加了第 4 维度 Task Granularity。三层改造的验证结果:template 生效了,review 生效了,verify 没生效。

verify 卡在哪?执行 /opsx:verify 后,报告只输出了 Completeness、Correctness、Coherence 三个维度,Task Granularity 始终缺席。第 6 期加的那个第 4 维度的定义,AI 压根没用上。

翻了一遍 SKILL.md 源文件,根因找到了:L46 定义部分确实写了 four dimensions,但后面两处引用这个数字的地方还停留在 three dimensions。一处是 Summary Scorecard 模板表格,只有 3 行没有 Task Granularity。另一处是 Graceful Degradation 段的最后一行,明确写着 "verify all three dimensions"。AI 执行 verify 时,读到这两处旧文案,直接按 3 维度出了报告。定义和引用不一致,AI 不觉得有问题,照着旧文案走就是了。

说到底,这是个典型的"改了定义没改引用"的问题。写代码的时候我们都知道改了接口要改所有调用方,但改提示词的时候容易忽略同样的道理。

本期做两件事:先把 verify SKILL.md 的内部矛盾修完,然后实现第二个工具 json-formatter。json-formatter 的 catalog 注册和路由第 2 期就配好了(catalog.ts 里的 stage: 'active',路由 /tools/json-formatter),但 src/modules/json-formatter/ 目录一直空着。这期把它填上,同时验证修复后的 verify 是否真的能输出 4 维度报告。

两个任务有先后顺序:先修 SKILL.md,再走 Propose → Apply → Verify。这样本期 verify 阶段就能用上修复后的配置,直接检验效果。

完整流程如下:

工作流总览
工作流总览

说明:本文内容基于 OpenSpec v1.3.1 实际项目操作记录整理。verify SKILL.md 修复和 json-formatter 工具实现均在 shuge-ai-toolbox 项目中实际验证,但 verify 第 4 维度(Task Granularity)修复后仍未生效,文中如实记录。文中的配置修改和代码仅供参考,实际效果请以你的项目环境测试结果为准。如果有实际使用经验,欢迎在评论区分享交流。

修复 verify SKILL.md:把矛盾的地方同步改完

先定位问题。文件路径是 .claude/skills/openspec-verify-change/SKILL.md,总共 173 行。

L46 的定义部分其实是对的:

代码语言:markdown
复制
Create a report structure with four dimensions:
- **Completeness**: Track tasks and spec coverage
- **Correctness**: Track requirement implementation and scenario coverage
- **Coherence**: Track design adherence and pattern consistency
- **Task Granularity**: Track task format compliance, TDD adherence, code completeness, and granularity assessment

四个维度定义齐全,L50-54 还详细拆了 Task Granularity 的四项检查:任务格式、TDD 合规、代码完整性、粒度评估。定义没问题。

问题出在后面两处引用这个数字的地方。

矛盾点 1:Summary Scorecard 模板(L117-127)

这个表格是 verify 报告末尾的汇总模板,AI 按这个格式输出最终结论。当前只有 3 行:

代码语言:markdown
复制
### Summary
| Dimension    | Status           |
|--------------|------------------|
| Completeness | X/Y tasks, N reqs|
| Correctness  | M/N reqs covered |
| Coherence    | Followed/Issues  |

Task Granularity 行缺失。AI 生成报告时照着模板走,模板只有 3 行,输出自然只有 3 维度。

矛盾点 2:Graceful Degradation 段(L159-164)

这个段描述的是"当工件不全时怎么降级验证"。最后一句:

代码语言:markdown
复制
- If full artifacts: verify all three dimensions

写的是 three dimensions。即使所有工件都齐全,AI 读到这句也会认为只需要验证 3 个维度。

SKILL.md 三处矛盾位置标注
SKILL.md 三处矛盾位置标注

图:SKILL.md 三处矛盾位置标注

具体修改

改动不大,但位置分散,需要逐个同步。

修改 1:Summary Scorecard 加行

改前:

代码语言:markdown
复制
| Dimension    | Status           |
|--------------|------------------|
| Completeness | X/Y tasks, N reqs|
| Correctness  | M/N reqs covered |
| Coherence    | Followed/Issues  |

改后:

代码语言:markdown
复制
| Dimension        | Status           |
|------------------|------------------|
| Completeness     | X/Y tasks, N reqs|
| Correctness      | M/N reqs covered |
| Coherence        | Followed/Issues  |
| Task Granularity | Format/TDD/Code  |

新增的 Task Granularity 行,状态列用 Format/TDD/Code 简写,对应任务格式检查、TDD 合规检查、代码完整性检查三项。

修改 2:Graceful Degradation three → four

改前:

代码语言:markdown
复制
- If full artifacts: verify all three dimensions

改后:

代码语言:markdown
复制
- If full artifacts: verify all four dimensions

一个词的事。但这一词决定了 AI 验证时是否走第 4 维度。

SKILL.md 修复前后对比
SKILL.md 修复前后对比

图:SKILL.md 修复前后对比

改完存盘,总共改了两处三行。看起来微不足道,但这个同步不到位正是 verify 第 4 维度一直缺席的直接原因。

这里有个教训值得记一笔:提示词约束是一条链路,不是孤立的定义。L46 定义写得再漂亮,后面模板和退化逻辑没跟上,执行层就按旧路径走。2/8 法则的体现——定义占 20% 篇幅但决定方向,引用点占 80% 篇幅且决定实际行为。改提示词要改全链路,不能只改最显眼的那一处。

改完 verify SKILL.md 后,马上进入 Propose。这样本期生成的工件才能用上修复后的配置。

Propose:记录工件产出过程

本期跳过 Explore,需求很明确——实现 json-formatter 工具,复用 text-summary 已建立的组件模式。

执行 /opsx:propose

代码语言:markdown
复制
**AI**:What change do you want to work on? Describe what you want to build or fix.

**用户**:本期做一个 implement-json-formatter 变更。在 src/modules/json-formatter/ 下实现 JSON 格式化工具,复用 text-summary 已建立的组件模式。功能包括格式化、压缩、语法校验。catalog.ts 中 json-formatter 已注册为 active,路由已存在,但模块目录尚未创建。同时需要在 router/index.tsx 的 toolModules 中添加 json-formatter 的映射行。

**AI**:
**Change created: `implement-json-formatter`**
**Location:** `openspec/changes/implement-json-formatter/`

**Artifacts created:**
| Artifact | Description |
|----------|-------------|
| `proposal.md` | Why we need JSON formatting (dev高频需求,纯前端实现) |
| `design.md` | Technical design: single-file component, native JSON.parse/JSON.stringify, useEffect+import pattern |
| `specs/json-formatter/spec.md` | 8 scenarios covering format/minify/validate, empty input, large file |
| `review.md` | 4-dimension review with task split direction |
| `tasks.md` | 3 tasks: JsonFormatterPage (TDD), router mapping, verification |

**Task breakdown:**
- 任务 1: JsonFormatterPage 组件(TDD 模式,测试 + 实现)
- 任务 2: Router 映射配置(toolModules 添加 json-formatter)
- 任务 3: 验证完整功能

**All artifacts created! Ready for implementation.**
Run `/opsx:apply implement-json-formatter` to start implementing.

AI 一次生成了 5 个工件。按实际产出顺序记录。

proposal.md

代码语言:markdown
复制
变更内容:
- 新增 `src/modules/json-formatter/` 目录,包含页面组件、格式化逻辑和测试
- 修改 `router/index.tsx`,在 toolModules 中添加 json-formatter 映射行

能力清单:
- 新增能力:json-format(JSON 格式化 / 压缩 / 校验)

影响范围:路由加载、src/modules/ 目录结构

proposal 简洁,一页纸,说明了"为什么做"和"改什么范围"。

specs

能力清单只有一个 json-format,所以只生成一个 spec 文件。需求定义了三个核心行为:

  • 格式化:接收 JSON 字符串,输出缩进整齐的 JSON。Scenario 覆盖了简单对象、嵌套对象、数组三种输入
  • 压缩:移除多余空白,输出单行 JSON。Scenario 包含已有缩进的 JSON 和带注释的非法 JSON
  • 校验:检测语法错误,返回错误位置和描述。Scenario 覆盖了缺少引号、缺少逗号、多余的尾部逗号、未闭合的花括号等常见错误

每个需求至少有一个正常输入 Scenario 和一个异常输入 Scenario。Spec 的质量比 text-summary 那期好一些——text-summary 当时只有一个"短/中/长"的长度选项需求,json-formatter 的三个需求方向更清晰,边界条件也写得更具体。

design.md

技术决策部分记录了几个要点:

  • 纯前端实现,不依赖外部 API——json-formatter 是个本地工具,不需要调用任何后端服务
  • 复用 text-summary 的组件模式:页面组件负责 UI,纯函数文件负责逻辑——这个模式在 text-summary 上验证过了,直接沿用
  • 使用原生 JSON.parse + JSON.stringify 实现格式化和压缩,不引入第三方库——减小打包体积,同时 JSON.parse 自带的错误信息足够定位语法错误位置

还有一个值得注意的决策:校验功能不单独用 try-catch 包一层,而是复用格式化函数的错误处理。因为 JSON.parse 在解析失败时已经会抛出包含位置信息的 SyntaxError,没必要重复实现。这个决策后来在 tasks.md 里体现为 formatJSON 和 validateJSON 共用同一个 parse 调用。

不过 design.md 还做了一个后来影响实现结构的决策:single-file component 模式。它没有像 text-summary 那样把纯函数拆到独立文件,而是选择把格式化、压缩、校验逻辑直接内联在页面组件中。这个决策直接决定了 apply 后的文件数量——比预期少。

review.md

这期继续用第 6 期改造的 4 维度 review instruction。看看拆分方向建议有没有参考价值。

4 个维度的审查结果:

代码语言:markdown
复制
1. **边界条件** ✅ 通过:空字符串、null 输入、非法 JSON、超长字符串均有场景覆盖
2. **回滚方案** ⚠️ 警告:纯前端新增模块,回滚即删除目录,风险可控但 proposal 未显式说明回滚步骤
3. **测试覆盖** ✅ 通过:format/compress/validate 三个方向各有独立测试场景
4. **向后兼容** ✅ 通过:不影响 text-summary 的接口和路由

拆分方向建议:

代码语言:markdown
复制
建议按逻辑层 → 页面层 → 路由层的顺序拆分任务。三个纯函数(formatJSON / compressJSON / validateJSON)优先编写并测试,确保核心逻辑正确后再接入页面组件。路由映射放在最后一个任务。

和 text-summary 的 tasks 拆分思路一致——先纯函数、再组件、最后路由。说明 review instruction 的拆分方向引导在稳定输出,不是偶尔碰运气。

tasks.md

对比 text-summary 的 tasks,格式完全一致:每个任务都用 ### 任务 N 标题,附文件列表和 TDD 五步结构(写失败测试 → 确认失败 → 写最小实现 → 确认通过 → 提交)。

但任务数量比预想的少。tasks.md 只有 1 个核心任务——JsonFormatterPage 组件整体,不是 formatJSON / compressJSON / validateJSON 三个独立的纯函数任务。这是 design.md "单文件组件"决策的直接结果:逻辑内联在组件中,没必要拆成独立的纯函数 TDD 步骤。

工件自洽性检查

按照每期的惯例,检查 5 个工件之间是否存在矛盾:

  • proposal.md 说"新增 json-format 能力",specs 目录下确实只有一个 specs/json-formatter/spec.md,对应一致
  • design.md 说"使用原生 JSON.parse + JSON.stringify",没有提到任何第三方依赖,和 proposal 的"纯前端实现"一致
  • review.md 给出的拆分方向是"逻辑层 → 页面层 → 路由层",但 tasks.md 实际只有组件整体 + 路由映射两个任务,review 的建议没有被完全采纳
  • tasks.md 中的文件路径都指向 src/modules/json-formatter/,没有引用不存在的模块

5 个工件全部生成完毕,进入 Apply。

Apply:记录执行过程

执行 /opsx:apply

代码语言:markdown
复制
**AI**:Test failed as expected (Module not found). Now writing the implementation.

**AI**:One test is failing because `getByText` normalizes whitespace. Let me fix the test to use a regex matcher:

**AI**:
## Implementation Complete
**Change:** implement-json-formatter
**Schema:** with-review
**Progress:** 11/11 tasks complete ✓

| Task | Description | Status |
|------|-------------|--------|
| 1.1 | 写失败测试 | ✓ |
| 1.2 | 运行测试——确认失败 | ✓ |
| 1.3 | 写最小实现 | ✓ |
| 1.4 | 运行测试——确认通过 | ✓ |
| 1.5 | 提交 | ✓ |
| 2.1 | 添加 json-formatter 映射 | ✓ |
| 2.2 | 验证 router 测试 | ✓ |
| 2.3 | 提交 | ✓ |
| 3.1 | 运行所有测试 | ✓ |
| 3.2 | 验证路由可达 | ✓ |
| 3.3 | 最终提交 | ✓ |

Commits:
- `d3ff798` feat(json-formatter): implement JsonFormatterPage component
- `59c13cd` feat(router): add json-formatter tool module mapping
- `e26c616` feat: implement json-formatter tool page

Files Created/Modified:
- `src/modules/json-formatter/index.tsx` (component)
- `src/modules/json-formatter/index.test.tsx` (8 tests)
- `src/router/index.tsx` (added mapping)

All tasks complete! You can archive this change with `/opsx:archive`.

AI 按 tasks.md 的顺序执行。tasks.md 只有 1 个核心任务——JsonFormatterPage 组件整体。TDD 流程是:写组件的失败测试(渲染标题、输入区、按钮交互),确认模块找不到报错后,再写组件实现。不像 text-summary 那期有独立的纯函数 TDD 步骤,本期整个组件(含内联的格式化、压缩、校验逻辑)在一个任务里完成了。

整个过程 AI 和用户之间的交互不多,因为需求明确、tasks 拆分清晰,AI 基本一路执行下来没卡壳。不像第 4 期布局改造那次,AI 来回问了好几轮"Tab 切换行为是什么"、"滚动状态怎么处理"。本期这种"照着 tasks 一步步写"的场景,OpenSpec 的 TDD 五步结构确实减少了交互轮次。

Apply 执行流程:TDD 分步提交
Apply 执行流程:TDD 分步提交

图:Apply 执行流程:TDD 分步提交

文件核实

Apply 完成后,核实文件是否真的创建成功。

代码语言:bash
复制
ls src/modules/json-formatter/

实际只有 2 个文件,不是预期的 4 个:

代码语言:markdown
复制
index.tsx              # 页面组件(含格式化、压缩、校验逻辑)
index.test.tsx         # 8 个测试用例

对比 text-summary 的 8 个文件(4 源文件 + 4 测试),json-formatter 比 text-summary 更简洁——没有独立的逻辑文件,格式化、压缩、校验三个函数直接写在 index.tsx 的组件中。每个函数的核心就是 JSON.parse + JSON.stringify 的不同参数组合,不需要拆文件。

这就是 design.md "single-file component"决策的直接体现。text-summary 有 extract-summary.ts、text-utils.ts、stopwords.ts 三个辅助文件是因为逻辑确实复杂(词频统计、句子评分、停用词),json-formatter 的三个功能加起来也就十几行代码,拆文件反而多余。

路由映射检查

这是每期必查的环节。上一期 text-summary 也在这里手动加过映射。AI 执行 tasks 时可能跳过路由映射这步——tasks.md 写了这步,但 AI 容易忽略文件列表之外的操作。

读取 router/index.tsx,确认 toolModules 部分:

代码语言:typescript
复制
const toolModules: Record<string, () => Promise<{ default: React.ComponentType<unknown> }>> = {
  'text-summary': () => import('/src/modules/text-summary/index.tsx'),
  'json-formatter': () => import('/src/modules/json-formatter/index.tsx'),
};

json-formatter 行已经在。这次 AI 没漏。不过这个检查不能省——上一期 text-summary 的 review 过程中,我就发现过 AI 标记了 [x] 但实际文件没改的情况。手动核实是每期 apply 后的固定动作,不能信 AI 的完成报告。

实现体验对比

对比 text-summary,json-formatter 的实现过程有明显差异:

  • 组件模式复用度高:页面组件 index.tsx 基本套用 text-summary 的 textarea + 操作控件 + 结果展示三段式布局,只是把"生成摘要"按钮换成了"格式化/压缩/校验"三个按钮
  • 纯函数逻辑更简单:text-summary 的 extract-summary.ts 涉及词频统计、句子评分、位置权重,json-formatter 的内联逻辑本质是 JSON.parse + JSON.stringify 的三种参数组合
  • 测试更好写:text-summary 要模拟中文分词场景,json-formatter 输入输出都是字符串,测试用例更直观

这就是建立组件模式的价值:第一个工具花时间摸索模式,第二个工具直接套用。如果后续第三个、第四个工具继续走这条路径,实现速度会越来越快。

文件清单确认完毕,进入本期重点——Verify。

Verify:记录验证过程(本期重点)

本期 Verify 是核心验证点。修了 SKILL.md 的两处矛盾后,verify 报告是否首次出现 4 个维度?

执行 /opsx:verify

verify 报告

AI 实际输出的 verify 报告:

代码语言:markdown
复制
## Verification Report: implement-json-formatter

### Summary
| Dimension    | Status              |
|--------------|---------------------|
| Completeness | 11/11 tasks, 7/8 scenarios |
| Correctness  | Requirement implemented, 1 scenario uncovered |
| Coherence    | Design followed, pattern consistent |

---

### Issues by Priority

#### CRITICAL (Must fix before archive)
**Scenario not implemented: 大文件 JSON 解析**
- **Spec requirement**: "用户输入一个非常大的 JSON(超过 1MB)" → "错误提示区显示'JSON 数据过大,请控制在中。'"
- **Current state**: No size check in implementation
- **Recommendation**: Add size check in `src/modules/json-formatter/index.tsx`:
  ```typescript
  const MAX_SIZE = 1024 * 1024; // 1MB
  if (input.length > MAX_SIZE) {
    setError('JSON 数据过大,请控制在中。');
    setOutput('');
    return;
  }
  ```
  Add corresponding test in `src/modules/json-formatter/index.test.tsx`

#### WARNING (Should fix)
**Scenario not tested: 用户输入有效 JSON 并点击语法校验按钮**
- **Spec requirement**: "错误提示区显示'JSON 语法正确',结果展示区显示原始 JSON"
- **Current state**: Test for valid JSON validation is missing

#### SUGGESTION (Nice to fix)
**Test file uses getAllByRole for output textarea**
- **Current**: `screen.getAllByRole('textbox')[1]` relies on order
- **Alternative**: Add `aria-label` to output textarea

### Final Assessment

**1 critical issue found. Fix before archiving.**

Summary 表格只有 3 行。Task Granularity 维度没有出现——和上一期完全一样,修复 SKILL.md 没有生效。这对应草稿预测的"情况 B"。

不过 verify 报告本身的质量比上期好不少。它发现了 1 个 CRITICAL issue:spec 里定义了"大文件 JSON 解析"场景(超过 1MB 的 JSON 要提示用户),但实现中没有做 size check。还发现了 1 个 WARNING:有效 JSON 点击语法校验按钮的测试用例缺失。这些发现是 specs 里写了但 tasks.md 没覆盖到的场景,verify 把它们捞出来了。

verify 报告摘要:3 维度 + 缺失标注
verify 报告摘要:3 维度 + 缺失标注

图:verify 报告摘要:3 维度 + 缺失标注

build 验证

代码语言:bash
复制
npm run build

npm run build(实际执行 tsc -b && vite build)因 tsc 类型错误失败。报了 4 个错误,其中 2 个是 router 动态 import 路径的既有问题(从第 2 期就存在),1 个是测试文件里 vi 没用到但 import 了。这些都是类型层面的问题,不影响运行。

跳过 tsc 直接跑 npx vite build,构建成功:

代码语言:markdown
复制
vite v8.0.12 building client environment for production...
✓ 1757 modules transformed.
rendering chunks...
computing gzip size...
dist/index.html                           0.46 kB │ gzip:  0.30 kB
dist/assets/index-8W2XdHU1.css           20.28 kB │ gzip:  4.75 kB
dist/assets/json-formatter-DwIBtDQv.js    2.63 kB │ gzip:  0.88 kB
dist/assets/text-summary-C_blhUgt.js      2.84 kB │ gzip:  1.39 kB
dist/assets/index-BtN7sydP.js           295.12 kB │ gzip: 94.23 kB

✓ built in 197ms

json-formatter 和 text-summary 各自独立打包为 chunk(json-formatter-DwIBtDQv.jstext-summary-C_blhUgt.js),动态路由的 code splitting 生效了。json-formatter 只有 2.63 kB(gzip 后 0.88 kB),体积控制得不错。

浏览器检查:先踩了一个坑

启动开发服务器,访问 /tools/json-formatter——页面停在加载中...不动了。text-summary 页面正常。同一个 router 逻辑,一个能加载一个不能,问题肯定出在 json-formatter 模块本身。

仔细对比两个模块的代码,发现根因:json-formatter 的 index.tsx 只用了 named export(export function JsonFormatterPage()),而 router 的 ToolPage 组件取的是 mod.default。text-summary 有 export default TextSummaryPage,json-formatter 漏了。

给 AI 报了这个问题,它自己找到原因加上了 export default JsonFormatterPage;

修复后单独提交了一个 commit:

代码语言:markdown
复制
4b8e1d4 fix(json-formatter): add default export for lazy loading

这个 bug 的教训是:组件模式复用时,export 方式也得对齐。named export 和 default export 在动态 import 时行为不同,少写一行 export default 就会导致整个页面加载失败。后续每个新工具的模板里应该把 export default 作为固定项写死,避免再踩这个坑。

浏览器检查:修复后的功能验证

修复 export default 后重新访问 /tools/json-formatter,页面正常加载:

json-formatter 页面
json-formatter 页面

图 1:json-formatter 页面修复后正常加载,显示标题、输入区和三个操作按钮

页面布局和 text-summary 类似:

  • 标题区:JSON 格式化
  • 输入区:textarea,placeholder 提示输入 JSON
  • 操作区:格式化、压缩、校验三个按钮
  • 输出区:textarea 展示结果

输入一段压缩的 JSON 测试格式化功能:

代码语言:json
复制
{"name":"shuge-ai-toolbox","version":"1.0.0","dependencies":{"react":"^19.0.0","react-dom":"^19.0.0"}}

点击格式化按钮,输出带缩进的版本:

格式化测试
格式化测试

图 2:输入压缩 JSON 后点击"格式化",输出带缩进的可读版本

再测试校验功能——输入一段不合法的 JSON:

代码语言:json
复制
{"name": "test", "age":}
校验测试
校验测试

图 3:输入无效 JSON 后点击"校验",显示语法错误提示

校验功能正常,返回了语法错误的提示信息。浏览器检查通过。

Archive:归档

确认 verify 通过后执行归档:

代码语言:markdown
复制
## Archive Complete
**Change:** implement-json-formatter
**Schema:** with-review
**Archived to:** `openspec/changes/archive/2026-05-31-implement-json-formatter/`
**Specs:** No delta specs (json-formatter is a new capability, not yet in main specs)
All artifacts complete. All tasks complete (11/11).
**Note:** The verification report found a missing "large file" scenario check (>1MB), but since you chose to archive without addressing it, the spec remains in the archive for future reference.

注意最后那句 Note:AI 提醒 verify 报告发现的大文件场景(>1MB)未修复就归档了。这说明 verify 确实起到了"检查遗漏"的作用,虽然 Task Granularity 维度没生效,但其他三个维度(特别是 Correctness)把 spec 里写了但实现没覆盖的场景捞出来了。

验证归档结果:

代码语言:bash
复制
ls openspec/changes/

活跃变更目录应该是空的(或只剩其他未完成的 change),implement-json-formatter/ 已移到 openspec/archive/ 下。

Git 推送:提交到 GitHub

AI 按 TDD 步骤分 3 个独立 commit 提交,加上后续修复 export default 的 1 个 commit,共 4 个 commit:

代码语言:markdown
复制
4b8e1d4 fix(json-formatter): add default export for lazy loading
e26c616 feat: implement json-formatter tool page
59c13cd feat(router): add json-formatter tool module mapping
d3ff798 feat(json-formatter): implement JsonFormatterPage component

这不是一个大合并 commit,而是按 TDD 节奏的增量提交:组件实现 → 路由映射 → 最终整合 → bug 修复。每个 commit 粒度小、职责单一,符合 TDD 分步提交的模式。

SKILL.md 的修复没有纳入 git commit——因为它是在项目外的 .claude/skills/ 目录下执行的,不属于项目仓库的变更范围。

代码语言:markdown
复制
**AI**:已推送到远端。3 个 commit 从 `d387013` 到 `e26c616`。

回顾:本期学到了什么

verify 修复没有生效

改了 SKILL.md 三处(定义本身已正确、Summary Scorecard 加行、Graceful Degradation 改 three→four),全链路同步了,但 verify 报告仍然只输出 3 维度。AI 不是没读到修改——它确实加载了 SKILL.md——但输出时没有严格按模板逐项填充,而是按自己的理解走了老路径。

这说明单靠改提示词的约束力有天花板:改全链路是必要条件,但不是充分条件。即使定义、模板、退化逻辑全部统一了,AI 在生成报告时仍然可能跳过模板,直接按惯性输出。

有个结论是确定的:提示词的全链路同步比单点增强重要得多。L46 的定义写得再漂亮,后面模板和退化逻辑没跟上,执行层就按旧路径走。这是 2/8 法则的又一次验证。但同时要承认,全链路同步也不能保证 AI 一定按模板走——这是提示词约束的固有局限。

verify 报告虽然没有出现第 4 维度,但在其他方面发挥了价值:它发现了大文件 JSON 解析场景的遗漏和有效 JSON 校验测试的缺失。这些是 specs 里写了但实现没覆盖的,verify 把它们捞出来了。

第二个工具的实现体验

json-formatter 的实现速度明显比 text-summary 快。核心原因:

  • 组件模式可以直接复用,不用重新摸索
  • JSON 格式化的核心逻辑比文本摘要的词频统计简单得多
  • 测试用例更好写——输入输出都是字符串,不需要模拟中文分词

第一个工具花时间建立模式,第二个工具享受模式红利。如果后续继续按这个节奏迭代,每加一个工具的边际成本会越来越低。

export default 这个坑

json-formatter 实现过程中踩的 export default 坑值得单独记一笔。text-summary 有 export default,json-formatter 没有,页面直接卡死在"加载中..."。这不是复杂逻辑 bug,而是一行代码的遗漏,但排查花了不短的时间——因为第一反应是"路由配置有问题",而不是"export 方式不对"。

后续每个新工具的模板应该把 export default 作为固定项写死,和 import React 一样成为模板的必选项。

路由加载策略的局限

toolModules 手动映射每加一个工具改一次 router/index.tsx,两期下来已经改了两次(text-summary 和 json-formatter)。目前只有两个 active 工具还好,等工具数量上去了这就是维护负担。但本期不改这个,属于"能用但不够优雅"的范畴,留给后续专门的重构任务。

理想的做法是把 toolModules 改成动态扫描 src/modules/ 目录,或者在 catalog.ts 里加一个 modulePath 字段,让路由映射自动生成。不过这种重构属于"改善型"需求,当前阶段优先级不高——先把工具做出来再说。

关于 verify 的边界思考

如果本期 verify 4 维度仍然没生效,那说明纯 SKILL.md 文案修改的约束力有天花板。AI 的执行行为受上下文惯性影响——它可能读到新的模板但仍然按旧习惯输出。单靠提示词约束,无法保证 AI 严格遵循每一条规则。这个发现本身有价值:它说明质量保证不能只压在 verify 这一个环节上,需要引入更强的过程控制。

下一期会详细讨论这个问题,以及为什么后续不再死磕 OpenSpec verify 的增强,而是引入 Superpowers 的计划纪律来补充。

预告

第 8 期先不写代码,复盘第 5-7 期三层改造的实验结果:template 改造的投入产出比、review 拆分方向建议的实际价值、verify SKILL.md 修复的最终效果。然后引入三档工作流的概念:

  • 快速档:低风险改动(文案、样式),OpenSpec + fresh verify 就够了
  • 标准档:普通工具开发,OpenSpec + Superpowers writing-plans 控制计划颗粒度
  • 严格档:核心逻辑、bugfix、重构,叠加 TDD、debug、code review

按风险选强度,不再一刀切。这也是这个系列从"摸索 OpenSpec 增强方案"转向"组合使用 OpenSpec + Superpowers"的转折点。


声明:本文基于 OpenSpec v1.3.1 源码分析、实际项目操作记录和读者反馈整理。所有改造均在 shuge-ai-toolbox 项目中实际验证。配置和代码仅供参考,请以实际环境测试为准。

项目仓库https://github.com/shuge-x/shuge-ai-toolbox

好啦,谢谢你观看我的文章,如果喜欢可以点赞转发给需要的朋友,我们下一期再见!敬请期待!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 修复 verify SKILL.md:把矛盾的地方同步改完
    • 矛盾点 1:Summary Scorecard 模板(L117-127)
    • 矛盾点 2:Graceful Degradation 段(L159-164)
    • 具体修改
  • Propose:记录工件产出过程
    • proposal.md
    • specs
    • design.md
    • review.md
    • tasks.md
    • 工件自洽性检查
  • Apply:记录执行过程
    • 文件核实
    • 路由映射检查
    • 实现体验对比
  • Verify:记录验证过程(本期重点)
    • verify 报告
    • build 验证
    • 浏览器检查:先踩了一个坑
    • 浏览器检查:修复后的功能验证
  • Archive:归档
  • Git 推送:提交到 GitHub
  • 回顾:本期学到了什么
    • verify 修复没有生效
    • 第二个工具的实现体验
    • export default 这个坑
    • 路由加载策略的局限
    • 关于 verify 的边界思考
  • 预告
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档