三层,而非一层。
SpecScore 分层校验,最廉价、最确定的优先。代码检查器是确定性的 — 快速、免费,每次提交都运行。AI 审查是概率性的 — 更深入,消耗 token,能捕获代码检查器够不着的东西。人的判断是第三层: 前两层无法弥合的缝隙仍然需要人 — 因为目前还没有工具能可靠地弥合它们。 这两个自动层是互补的,而非冗余的:代码检查器捕获 AI 无法佐证的问题,AI 捕获代码检查器够不着的问题。
每个校验器检查什么。
Layer 1
CLI 代码检查器
deterministic每次运行结果相同,不用 LLM,零成本。如果在这里通过了,那就是事实 — 而非意见。
$ specscore lint apply-discount.md ✓ R1 has acceptance criteria ✓ R2 has acceptance criteria ✗ R3 no acceptance criteria ✗ link "Related Feature: discount-tiers" not found ✗ section "Open Questions" missing 3 problems exit 1
- 引用完整性 — 链接可解析、ID 唯一
- 结构约定 — 必需的章节、frontmatter 的形态
- 状态卫生与索引漂移
- slug 冲突
- 元数据字段上的前缀合法性(例如
Related Ideas:)
Layer 2
AI 审查与评分
non-deterministic像人类审查者那样按含义阅读 — 也和人一样,并非完全可重复。
> /score apply-discount.md Grade: B — ready with edits AC-2 vague trigger — name the actor and event AC-3 no error path for an expired code prose reads clean; criteria need tightening
- 验收标准是否写成可验证的 Given/When/Then
- 单个工件内部的一致性
- 含糊或占位性的内容
- 对人类审查者而言的可读性
- 作者可操作、标注了严重级别的反馈
- A–F 的就绪度评级
它们捕获不到什么。
没有哪个校验器是魔法。下面就是每一个止步之处 — 好让你清楚地知道,哪里仍然需要你自己的判断来完成工作。
Layer 1
CLI 代码检查器
- 跨深层级的隐式矛盾
- 规格与代码之间的漂移 (随着
specstudio:recap上线而改善) - 验收标准在语义上的正确性
- 一个名称是否真的讲得通
- 这些需求是否解决了所陈述的问题
Layer 2
AI 审查与评分
捕获并不稳定- 完全的逐次可重现性 — 在容差范围内裁决可能会变化
- 没有显式交叉检查时,大型树中跨工件的矛盾
- 需求是否真正解决了问题 — 能标出明显的缺口,会漏掉特定领域的缺口
- 从底层 LLM 继承而来的偏见
- 以绝对的把握保证语义正确性
- 任何评分细则没有纳入权重的东西
- 1
代码检查器够到这里
结构、引用、卫生。廉价又确定 — 但对含义视而不见。
- 2
AI 够到这里
含义、清晰度、单个工件内部的一致性。更深入 — 但是概率性的,在大型树上较弱。
- 3
仍然要靠你
对整个系统的贯穿式判断 — 这是目前没有工具能可靠完成的工作,所以仍然需要一位人类审查者。
两个工具都救不了你的那种情形
想象一棵真实而深的规格树。功能 A 要求 X。功能 B 要求Y。功能 C 要求 Z。然后功能 D 悄悄要求了某个与 B 矛盾的东西 — 但只在 A 同时生效时才矛盾。代码检查器看到的是四份合法、彼此链接良好的文档,于是通过了。 AI 审查器逐个阅读工件,没有理由把这四份一起加载进来,从而注意到这种三方交互。
这两层都无法可靠地捕获它 — 我们也不会假装不是这样。正是这一类矛盾,才是第三层存在的理由。SpecScore 的职责是把这棵树做得足够易于导航, 让一位审查缝隙的人能够找到冲突 — 开放问题沿层级向上传播、相关需求只需一次查询即达 — 而不是声称某个工具已经替你找到了它。