mcpField
S
spec-driven-eval

spec-driven-eval

github.com/tech-leads-club测试与质量7.1k132 次安装3 天前更新
代码仓库

关于 spec-driven-eval

用于逐条对照 PRD 评估规格驱动实现的评估方法,分别衡量实现质量与测试覆盖,并以证据支持的二元检查实现可复现的比较。

主要功能

  1. 01逐条评估验收标准
  2. 02分开评定实现与测试
  3. 03基于证据的二元检查
  4. 04固定清单以便比较
  5. 05脚本汇总评分
  6. 06限定差异范围搜索证据

适用场景

  1. 01按 PRD 评估功能实现
  2. 02比较规格驱动开发框架
  3. 03审查测试对验收标准的覆盖
  4. 04一致地重复执行评估

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/tech-leads-club/agent-skills --skill spec-driven-eval

安装后在 Claude Code 中输入/spec-driven-eval确认已加载。

附带文件references/quickstart.mdreferences/reference.md

详细介绍

规格驱动实现评估

逐项评估规格驱动开发(SDD)工作是否符合 PRD(逐条验收标准),分别为实现和测试打分,并汇总为一个可比较的最终等级。专为基准测试设计:针对不同 SDD 框架评估同一 PRD,以及对同一项工作进行两次评估,都必须得出可比较、可复现的分数。

两个评估对象,两个问题

此评估回答两个相互独立的问题,并将两者的结论分开,因为它们可能各自失败:

  1. 框架在遵循和提取需求方面表现如何?——它是否遵循 PRD 且没有越界(遵循:Final 实现侧 + 范围 S),以及是否识别出了 PRD 仅隐含表达的需求,且没有带来噪声(提取:需求发现 E)?
  2. 测试框架在确保所有需求都已实现方面表现如何?——测试套件是否能证明每项获准需求确实已实现(T + 工程门禁 G)?

**使“全部已实现”定义明确的关联机制:测试框架须对完整的获准需求集 = PRD 验收标准 ∪ 有效的 E 新增项**负责。框架提取出的有效需求若从未被测试,则属于测试框架的疏漏(T),而非框架的疏漏(E 保留提取得分)。需求提取结果定义了验证目标。

评分采用检查清单:将每项标准拆解为原子级二元(达成 / 未达成)检查,每项均由 file:line 证据支持。采用二元拆解是为了提高评分的可复现性——分级 / 李克特量表(“这是 3 分还是 4 分?”)是不同评估者之间意见不一致的主要来源;二元检查可将评估者间的一致性提升至大致相当于人类水平。部分得分根据达成检查的比例推导,绝不通过滑动尺度进行主观判断。

适用场景

  • “逐项评估 / 给这个 PRD 打分,并给出最终等级”
  • “这个用户故事 / 功能是否 100% 实现?”
  • 对同一 PRD 的多种规格驱动实现进行基准测试
  • 根据验收标准审计实现和测试覆盖率(单元测试 + 端到端测试)

所需输入

  1. PRD(产品意图的事实依据)——用户故事的验收标准是评估的基本单位。
  2. 实现(生产代码)。
  3. 测试(单元测试 + 端到端测试)。
  4. SDD 衍生工件——spec.md 和 tasks.md(细化后的 AC、需求 ID、衍生需求)。需求发现 E 和范围 S 轴需要这些内容(评估对象是它们与 PRD 的一致程度)。缺少这些内容时,Final / T 仍会执行,但 E / S 会报告为 n/a — no derived spec。PRD 仍是判定“预期”内容的事实依据;衍生规格则是评估遵循度和需求提取情况的对象。

界定差异范围。评分前,使用 git 确定本次实现修改了哪些文件。此差异范围是步骤 4 和 8 中搜索所有 file:line 证据的主要范围:

git diff <base>..<head> --name-only   # branch or PR
git diff --name-only HEAD             # uncommitted changes
git status --short                    # include untracked new files

在报告中记录差异范围。范围外的证据仍然有效(例如,修改了一个此前已存在的文件),但如果某项检查依赖差异范围以外的文件,请注明这一点——这可能表明选择了错误的基准。


快速入门

首次端到端运行?请参阅 quickstart.md,了解 4 个聊天会话的流程(冻结基线 → 规划 → 实现 → 评估),其中包含可直接粘贴使用的提示词。需要操作指南时请阅读该文档;本文件其余部分介绍评分方法。


核心规则(请先阅读)

这五条规则适用于每项评分,旨在确保评分可审计且可复现。

  1. 有证据,否则计零。 每项判定为已满足的检查都必须引用证据,格式为 file:line(或 file:startLine-endLine)。未找到证据 ⇒ 检查未满足。绝不可根据假设或 PRD 重述的意图给分。
  2. 判零前先搜索(防止误判为否)。 因“未找到”而将检查判为未满足之前,记录实际执行的搜索:从范围界定步骤中的差异面文件开始,然后记录尝试过的 grep/glob 关键词,以及检查过的其他文件/目录。判为未满足的检查必须确认该行为在差异面中不存在,而不能只依据在整个代码仓库中临时执行的 grep。未满足表示搜索过且确实不存在,而不是没有查看。如果没有展示搜索过程,则该检查尚未评分,而不是未满足。
  3. 端到端阅读路径,包括数据形态。 只有追踪了真实代码/测试路径,检查才能判为已满足,不能仅凭符号名称匹配。对于发出/返回/持久化的产物,检查实际构造的载荷对象本身,不能只看调用位置——存在 emit(...)/return ... 并不能证明载荷中包含指定字段(参见合取规则)。测试如果执行了某种行为,却没有断言该行为,则不满足验证检查。
  4. 基准评估时,评估者 ≠ 编写者。 比较实现时,评估模型应与编写代码的模型不同;LLM 评估者会过度认可自己的输出(自我偏好偏差)。如果两者相同,则在假设部分标明,并将边缘检查视为未满足。
  5. 评估者对受评对象只读。 绝不修改受评代码——无论是为了通过失败的门禁、提供“帮助”,还是修复微不足道的类型错误。失败的门禁仍然失败:记录 ✗,应用 Adjusted Final,并在报告的修复清单中列出所需更正。评估期间修改受评对象会污染基准(评分将不再衡量框架的输出),并使差异面失效。如果意外应用了更正,请将其还原,并按原始状态评分。

可复现性规则

评分必须稳定:相同的 PRD + 相同的提交在不同运行和评估者下,必须得出相同的 Final。必须遵守以下所有规则:

  1. 冻结 AC 列表及其检查清单(最大的偏差来源)。 AC 的枚举和检查粒度只决定并固定一次,因为 I、T 和 Story_score 的分母都取决于它们:
    • 如果存在带稳定需求 ID 的 spec.md,则冻结 AC 列表及其 ID——原样使用,不得重新拆分或合并。
    • 为每个 AC 推导二元检查清单,并将其保存到 <spec-folder>/evaluations/_ac-baseline.md(ID + AC 原文 + I 检查项和 T 检查项)。该 PRD 的每个实现都必须依据完全相同的检查清单评分。
    • 一个 AC = 一个可测试的意图断言;一项检查 = 一个原子且可观察的“是/否”命题。不得将不同的行为合并为一项检查,也不得将一个行为拆分为多项检查。
  2. 优先级必须来自 PRD,不得默默推断。 使用 PRD 中明确标注的 P0/P1/P2。如果某个 story 未标注优先级,则在报告中将其标为 ASSUMED,并列入 Assumptions;不得让推断出的优先级悄然改变 3/2/0 权重。
  3. 只在最后进行一次舍入。 运算过程中保留完整精度;仅将报告中的 AC_score、Story_score 和 Final 舍入到小数点后 2 位。分档依据舍入后的 Final。
  4. 通过计算得出结果,不要手算。 汇总结果(Σw、每个 Story_score、Final、Adjusted Final)必须通过执行脚本计算(例如 node -e / python3 -c);脚本以每个 AC 的 I/T 分数和优先级权重表作为输入,并将脚本输出粘贴到报告中。绝不可心算或手算——手动累加分母(Σw)是已知的失误模式,会悄然改变评分档位。Σw 必须由脚本根据报告中展示的同一优先级表推导,不得将其作为字面量输入。
  5. 自洽性集成评估(k = 3)。 在低温度或零温度下独立评估检查清单三次,并在计算任何数值前,对每项检查按 MET/UNMET 结果取多数票。在低成本下,多数投票(k = 3)可消除大部分随机波动。如果三轮对某项检查的结果不一致,则该项检查属于边界情况——保留多数票结果并予以注明;如果持续存在分歧,则说明检查项措辞含糊(应在基线中明确措辞,参见“校准”)。

评分模型

评分单位:验收标准(AC),拆分为二元检查项

对于每个范围内的 AC,冻结的检查清单包含两组原子检查项,每项均按 MET(1)/UNMET(0) 评分:

实现检查项(I 检查项)——每个不同的可观察行为对应一项检查。只有当生产代码执行了该行为,并有 file:line 作为证据时,该项才为 MET。仅纳入行为可观察的子句(AC 中明确表达的动作,例如:创建 / 返回 / 拒绝 / 持久化 / 授予 / 默认设为)。非功能性润色(措辞、日志)不属于检查项——应另行注明,使其绝不影响评分。

将 AC 解析为检查项时(在冻结基线时一次性完成),应用以下两条规则,确保捕捉到的内容不限于动词: 合取/负载字段规则。 当 AC 列出多个项目时——由 “and”、“,”、“with [field]”、“including” 连接——尤其是在发出/返回/持久化产物的主体或负载中,应将每个具名字段或实体都作为独立的 I-check。不要只确认父级方法已被调用:对于每个具名字段,打开在 file:line 构造的实际数据对象,并验证其中包含该字段(应根据负载结构评分,而非调用位置)。 示例:“发出与用户和试用结束日期关联的触发器”→两个 I-check:(1)触发器负载包含 userId;(2)触发器负载包含 trialEndsAt。确认已执行 emit(...) 并不满足检查(2),如果负载对象遗漏了该字段。

析取/产品选定规则。 当 AC 给出多个选项(“A or B”、“暂停或取消”、“立即或在周期结束时”)时,应一次性确定解读并固定在基准中(该解读本身不得因运行而异):

  • 独立路径——两者都是可独立触发的行为(例如,“立即或在周期结束时取消”):每条路径各设一个 I-check,并分别判定为 MET/UNMET。
  • 由产品控制/可配置——AC 将选择描述为由产品决定(例如,“应用由产品选定的行为:暂停或取消”):两个 I-check——(1)已实现推荐/默认行为;(2)无需更改代码即可触发另一选项(配置键/标记/环境变量)。如果将一个选项硬编码且没有切换到另一个选项的方式 ⇒ 检查(2)为 UNMET。恰好能触发另一选项的其他功能(例如用户主动取消)不满足检查(2)——它必须是同一个由产品控制的决策点。
  • 如果 “product-chosen” 本身在 运行时可配置 与 设计时选定 之间存在歧义,则根据 PRD/规格措辞确定解读,并将确定后的解读记录在基准中;只有当 AC 将选择描述为由运行时/产品控制时,才要求另一条非默认路径可触发。

接线/入口规则(异步传递的副作用)。 如果可观察副作用通过入站事件异步传递(例如 Stripe webhook → handler → 持久化状态),除行为 I-check 外,还应添加专门的接线 I-check:入口端点确实会接收、验证入站事件,并按类型将其分发给 handler。这与检查 handler 是否产生正确状态的 T-outcome 测试不同:即使 handler 已经过全面测试,只要它位于失效、未注册或路由错误的端点之后,接线检查仍会失败。否则,一个正确但不可达的 handler 会获得满分(这正是 T-outcome 入口点中立性造成的盲区——允许测试绕过 HTTP,就必须由其他方式证明路由确实存在)。接线 I-check 应针对将事件类型映射到 handler 的控制器/路由评分(签名/真实性验证 + 分发),而不是针对 handler 内部逻辑。对于每个可观察效果通过入站异步事件抵达的 AC,都应固定一个接线 I-check。

I = (# I-checks MET) / (# I-checks)

测试检查(T-checks)——在所需级别进行验证。所需级别由策略固定,不逐条 AC 判断:

  • 纯逻辑/业务逻辑 ⇒ 必须进行单元测试
  • 可观察的 HTTP/契约/持久化副作用 ⇒ 必须进行端到端/集成测试
  • 同时包含两者的 AC ⇒ 两者都必须进行

T-outcome——持久化/异步副作用(基于结果,与入口点无关)。 当 AC 声明结果状态时——措辞如“导致/持久化/显示的状态/反映变更/更新状态”——验证检查针对的是实际结果状态,而非某次调用。将此类检查标记为 T-outcome(区别于普通的同步响应 T-e2e)。该策略包含四个部分:

  • 断言真实结果。 MET 要求依据真实基础设施,断言实际持久化的状态(真实的数据库行)或实际返回的负载。仅走过执行路径,却未断言最终状态的测试为 UNMET(核心规则 3)。
  • 入口点由实现自行选择(入口点中立)。 通过任意入口点驱动真实组件并断言最终状态:可以调用 HTTP 端点,也可以直接针对真实数据库调用处理器、队列消费者或服务方法。对于异步设计(先快速确认,再处理),不必通过完整的 HTTP→队列→工作进程路径进行测试——等待处理器完成并断言持久化的行,已经足够且效果相同。不要因为队列/异步架构未通过 HTTP 端到端驱动而扣分;关键在于是否断言了真实的最终状态,而不在于测试从哪个入口进入。
  • 仅 mock 的排除规则(严格限定范围)。 断言在 mock 的存储库/状态机上调用了某个方法(expect(save).toHaveBeenCalled() / expect(transition).toHaveBeenCalledWith(...)),只能证明发生了调用,不能证明结果已持久化 ⇒ 对任何“导致/已持久化/显示某状态”检查均为 UNMET(但仍可计入稳健性 R)。此排除规则仅适用于结果检查,不得扩大适用范围:如果检查所要验证的命题是“调用了外部 API”(例如“立即取消会调用 StripeClient.cancel”“在 Stripe 中创建订阅”),那么用 spy/mock 验证是正确的,因为断言的命题就是这次调用。仅使用 mock 在此类情况下没有问题;此排除规则不适用。
  • 最低级别是下限。 所需级别是一个**下限,而非精确匹配。**级别更高的测试(例如覆盖了单元测试级别所需命题的端到端/集成测试)可以满足该命题,前提是确实在真实产物上断言了具体命题(例如指定的负载字段或默认值)。不要仅仅因为单元测试级别所需检查的唯一断言出现在端到端/集成测试中,就将其标记为 UNMET。

对于每个所需级别,推导出二元检查,例如:在该级别断言了主要行为(只有实际断言时才为 MET,不可仅仅执行过)、断言了相关的否定/错误情况、断言了每项次要条款。mock 的外部系统(例如通过 nock mock 的 Stripe)无法证明外部系统一侧的情况——应根据可观察的本地契约编写检查,并注明此限制。

合取规则也适用于 T 类检查:每个指定的负载字段都需要单独验证。测试断言了产物已发出/返回,却没有断言字段存在/取值的,则该字段检查为 UNMET(断言调用了 emit ≠ 断言负载中包含 trialEndsAt)。

T = (# T-checks MET across all required levels) / (# T-checks)

I 和 T 都会得出细粒度的值,但每个底层原子都是二元的、以证据为依据的“是/否”——这正是使结果可复现的关键。不存在“轻微还是显著”的判断:每项条款要么有自己的检查,要么没有,而且这一决定已在基线中确定。

按 AC、按故事、最终得分
AC_score    = 0.6 * I + 0.4 * T
Story_score = mean(AC_score over the story's ACs)      # ACs equally weighted by default
Final       = Σ(w_s * Story_score) / Σ(w_s)            # weighted by story priority

故事优先级权重 w_s:

优先级权重理由
P03核心 MVP
P12接近 MVP/发布
P2 / 不在范围内0不计入评分;另行报告为路线图就绪度

0.6/0.4 的实现/测试占比体现了“优先交付可运行的软件,再由测试证明”。整个基准测试中应固定这些权重,以及 P0/P1/P2 权重;更改它们会破坏可比性。

评分区间
最终得分等级
≥ 0.90规格完整
0.75–0.89良好(差距较小)
0.60–0.74部分达标(存在明显差距)
0.40–0.59较弱
< 0.40不合格
偏差控制

LLM 评审者存在充分记录的偏差;请明确控制以下偏差:

  • 冗长/数量偏差——更多代码或更多测试绝不会提高 I 或 T。只有映射到 AC 条款的检查才计入。额外测试计入 R/D(见下文),绝不计入评分。
  • 自我偏好偏差——见核心规则 4(评审者 ≠ 作者)。
  • 锚定效应——依据冻结基线和 references/reference.md 中的校准锚点评分,而不是依据你碰巧评审过的上一个实现。
与评分并列报告(不计入 Final——保持可比性)
  • 稳健性指数 R——超出 PRD 案例的额外测试,按 High=1.0 / Med=0.5 / Low=0.25 加权后求和。用于体现防御性质量。绝不提高 Final。
  • 范围遵循度 S——pass / partial / fail,遵循可追溯性原则:每项已构建行为都必须追溯到经过认可的来源(PRD 验收标准 → Final,或有效的 E 补充项)。对每项已构建行为进行以下三项检查:
    • PRD 边界——构建了 PRD 明确列为范围外的内容 ⇒ fail。
    • 擅自构建——构建的内容既无法追溯到 PRD AC,也无法追溯到有效的 E 补充项(无法追溯/凭空杜撰)⇒ fail。
    • 计划偏移——spec.md/tasks.md 认可了某项行为,但代码没有构建该行为(或只构建了一半/实现不一致)⇒ partial。 所有内容都能清晰追溯 ⇒ pass。报告导致失败/部分符合的行为及其 file:line。**框架推导到规范中的有效需求,若因超出范围而正确地未予构建,这属于良好的规范执行——不应扣减 S;**应将其记录为 E 下的 deferred-valid。
  • 工程门禁 G——build、lint、unit、e2e。**每项门禁都必须是实际执行后得到的 ✓/✗,或明确标记为 not-run(并附原因,例如 e2e 基础设施不可用)。未执行测试时,绝不能报告门禁通过。build 门禁通过机械方式固定,以排除评审者的自由裁量:每个基准选择一次项目的规范构建命令(仓库文档说明的构建脚本),并将门禁定义为该命令以 0 退出——除此之外不考虑其他因素。在报告中记录准确命令,确保每次运行使用相同的门禁。代码未受本次改动影响的既有无关工具链故障(例如未改动的迁移路径中已知的类型检查错误)属于不计分的已记录注释,而非 ✗:它不影响 build 门禁,也不会触发 Adjusted Final。应将其作为已知注释记录在报告中,但 build 判定只依据固定构建命令的退出代码。尝试后再标记未运行:只有在记录了实际尝试后,才可将门禁报告为 not-run——必须执行命令(或检查前置条件,例如通过 docker ps 检查 e2e 基础设施),并粘贴其错误输出作为证据。没有尝试记录的原因不成立;该门禁仍为尚未评分,与未进行搜索的 UNMET 完全相同(将核心规则 2 应用于门禁)。只有已确认失败的门禁(✗)才会触发 Adjusted Final = Final × 0.5;not-run 门禁既不能增加也不能扣减分数——它只作为已知盲点报告。未调整的 Final 仍须报告,以便比较。评审者绝不能修复失败的门禁(核心规则 5)——记录 ✗、调整分数,并列出修复方法。
  • 测试分布 D——将每项功能测试归为三个层级之一,并以数量和占测试套件的百分比报告。用于展示测试投入的分布;绝不提高 Final。见下文。
按层级 D 划分测试分布(并列报告)

将每个新增功能测试(每个 it/测试用例;it.each 的每一行单独计数)准确归入一个层级。此分类复用测试检查和稳健性步骤中已完成的工作,因此成本低且可复现:

层级定义对应项
必要(主要成功路径)断言 P0/MVP AC 的主要成功路径,或该路径正常工作的必要依赖。P0 主流程上的 T-check MET
次要(重要)对应某项 AC,但不是 P0 主要路径:P1 AC、边界/负向/错误路径、次要条款、安全/授权、重复/幂等/去重、状态触发的发射。非必要项的 T-check MET
锦上添花不对应任何 AC:防御性/穷举覆盖(枚举映射、未知状态、仓库/基础设施内部、辅助方法),或与端到端测试已验证路径重复的单元测试覆盖。稳健性 R 的额外项

**经验法则:**对应 AC 的测试分为必要和次要;稳健性 R 清单中的测试属于锦上添花层级。每项测试只能归入一个层级,不要重复计数。

将 D 报告为表格,列出 层级 → 数量 → 占比(占功能测试总数的百分比),并附上一行分布解读。健康的测试套件会为每条 P0 主要路径至少覆盖一项必要测试;必要测试偏少、锦上添花测试偏多是一个隐患(有稳健性,却未验证核心路径),反之(没有防御性测试)则很脆弱。D 仅作描述,不会改变 Final。


需求提取 E — 框架提取需求的能力(并列报告;绝不纳入 Final)

E 根据 PRD 对由 SDD 衍生的 spec.md/tasks.md 进行评分:框架是否找出了资深工程师会坚持要求的隐含需求,并且表达得是否清晰(没有臆造或相互矛盾的补充内容)?这是 SDD 框架「超越转录的价值」。它评估的是规范产物,而非代码。与 R/S/D 一样,它与 Final 并列报告,以保持保真度评分的可比性。

包含三项二元清单子指标:

E_recall — 是否找出了应找出的内容?

使用下方冻结的隐含需求类别标准。对每个类别,标记为已覆盖(引用 spec.md:line)、遗漏或不适用(PRD/领域使其无关)。该标准与 PRD 无关且可复用,因此无需为每个 PRD 单独设置标准答案,也能重现召回率。

E_recall = Addressed / (Addressed + Missed)        # N/A excluded
#类别如果该功能满足以下条件,则预期应有相应需求……
1输入验证与边界接受用户/外部输入(范围、格式、必填字段)
2错误分类与消息可能以调用方必须区分的方式失败(类型化错误、错误码)
3身份验证/授权暴露端点或访问用户拥有的数据
4幂等与去重可能会被重试或重放(支付、仅创建一次的资源)
5并发与竞态条件存在交错写入,或对共享状态执行检查后再操作
6数据生命周期与一致性持久化状态(事务、部分失败回滚、保留策略)
7可观测性在生产环境中运行(日志、指标、故障可追踪性)
8限制、分页与速率返回列表或会被高频调用
9外部依赖故障调用第三方(超时、重试、熔断、回退)
10状态转换完整性具有生命周期/状态机(非法转换保护)

可按领域扩展该标准,但须在每项基准测试中冻结,并对每个框架使用完全相同的类别列表。对于横向对比基准测试,还应报告汇总召回率:将所有框架中有效的补充项合并为经裁定的主清单,然后据此计算每个框架的召回率。

E_precision — 信号干净,还是过度打磨?

构建新增需求台账:列出 spec.md/tasks.md 中每项无法追溯到 PRD 中某一行的需求。逐项进行二元判定,并附上一句判定依据和 spec.md:line:

判定含义
Valid-necessaryPRD 暗示存在的真实缺口(例如“拒绝 trialDays > 30”)
Valid-defensive合理的强化措施(可观测性、重试、类型化错误)
Invalid幻觉、与 PRD 矛盾,或属于明确列出的范围外事项,构成范围蔓延
E_precision = (Valid-necessary + Valid-defensive) / total additions

有效新增项构成**valid E-additions集合,供其他各处引用(基准测试的分母,以及 S 可追溯性)。将每项有效新增项标记为已构建或已延期**(延期的有效新增项 = 良好的纪律,见 S)。

E_justified — 新增项是否有充分依据?
E_justified = additions carrying an explicit rationale/traceability / total additions

即使单项看起来合理,缺乏依据的新增项仍是危险信号。报告全部三项:E_recall / E_precision / E_justified。强大的框架在这三项上都表现出色——找到了隐含需求,几乎没有引入噪声,并为新增内容提供了充分依据。


校准(每份 PRD 执行一次,再信任基准测试结果)

检查清单是对每项 AC 含义的假设;请先进行校准,确保不同评估者意见一致:

  1. 锚定。 references/reference.md 中有已完成的检查清单锚点——至少包括一项明确的 MET、一项明确的 UNMET,以及一项附有判定和理由的边界检查。评分前请先阅读;这些锚点确定了 MET/UNMET 的界限。
  2. 一致性检查。 对于高风险基准测试,请让人工标注的参考答案(或第二个评审模型)检查该检查清单。如果超过约 20% 的检查判定不一致,说明检查清单措辞过于含糊——请在 _ac-baseline.md 中明确含糊的检查项,然后重新运行。不要通过“取平均”来掩盖分歧;应修正操作性定义。
  3. 边界案例最有价值。 发现人工评审者或模型评审者意见不一的检查项时,请将其及最终判定加入 references/reference.md 中的锚点库。

流程

复制此清单并跟踪进度:

FRAMEWORK — respect & extract requirements
- [ ] 1. Locate PRD, spec.md/tasks.md. Run git diff to identify changed files (diff surface). Use the diff surface as the primary search scope for implementation and test evidence throughout steps 4 and 8
- [ ] 2. Enumerate stories + ACs; tag priority; mark out-of-scope items
- [ ] 3. Build/load the frozen binary checklist per AC (I-checks + T-checks) → _ac-baseline.md
- [ ] 4. Score I-checks MET/UNMET with file:line evidence (record searches before any UNMET)
- [ ] 5. Elicitation E: run the category rubric (E_recall) + added-requirement ledger (E_precision, E_justified) → freeze the `valid E-additions` set
- [ ] 6. Scope S: trace every built behavior (PRD-boundary / rogue-build / plan-drift)

HARNESS — ensure they are all implemented
- [ ] 7. Define the sanctioned set = PRD ACs ∪ valid E-additions; ensure each has a T-check
- [ ] 8. Score T-checks MET/UNMET with file:line evidence (unit + e2e per fixed level policy)
- [ ] 9. Inventory extra tests → Robustness Index R
- [ ] 10. Classify every feature test into tiers → Test Distribution D (counts + %)
- [ ] 11. Run/record Engineering Gates G (✓/✗/not-run)

ROLL-UP
- [ ] 12. Repeat the scoring steps three times (k=3); take majority verdict per check
- [ ] 13. Compute I, T, AC/Story/Final; apply bands; Adjusted Final only if a gate is ✗
- [ ] 14. Emit the report (see references/reference.md template): Final + E + S + R/G/D + ranked gaps + fixes

步骤规则:

  • 步骤 1 — 在搜索任何证据之前,先确定差异范围。选择与你要评估的对象匹配的基准(分支顶端、上次提交或工作树):
git diff <base>..<head> --name-only   # for a branch/PR
git diff --name-only HEAD~1           # for the last commit
git diff --name-only HEAD             # for uncommitted changes
git status --short                    # for untracked new files

在报告中记录文件列表。步骤 4 和 8 会将其作为首批检查路径。

  • 步骤 2 — PRD 明确列出的范围外项目/非目标(无论 PRD 使用什么标题)权重均设为 w=0。缺失不算缺陷。不要为其评分。
  • 步骤 3 — 如果已有 _ac-baseline.md,就复用;否则创建该文件,并将其视为此 PRD 后续所有运行的契约。仅将可观察行为条款纳入检查项。
  • 步骤 5 — E 评估的是 spec.md/tasks.md,而非代码。台账中有效的补充项定义了步骤 6 和 7 使用的 valid E-additions 集合。将每项有效补充标记为已构建/已延期。
  • 步骤 6 — 可追溯性:已构建的行为若没有 PRD AC,也没有有效的 E 补充项,就属于越界构建(fail)。已延期且有效的范围外补充项不扣分。
  • 步骤 7 — 测试框架分母是认可集合(PRD ACs ∪ 有效 E 补充项)。有效提取的需求没有测试,属于 T 漏项,而非 E 漏项。
  • 步骤 8 — 仅允许二元结果:MET(有证据)或 UNMET(已搜索但未找到)。每项检查不得使用部分值。
  • 步骤 9 — 额外测试是正向信号,但绝不能替代缺失的覆盖。R 高而 T 低,评级仍然低。
  • 步骤 10 — 每项测试必须且只能归入一个层级;各层级数量之和必须等于功能测试总数。排除功能未新增的既有测试(另行注明)。
  • 步骤 11 — 仅在实际执行过时,门禁才能标记为 ✓/✗;否则标记为 not-run,并提供尝试证据(命令 + 错误输出 — 参见 Probe-before-not-run)。不要假定基础设施不可用:先检查(例如 docker ps,或项目文档所述的 e2e 测试套件运行条件)。如果门禁为红,切勿修复被评估对象的代码(核心规则 5)。
  • 步骤 12 — 对 k=3 取多数结果。注明三次运行结果不一致的检查项。
  • 步骤 13 — 展示计算过程:列出每组检查的 MET/总数,以便重新计算 I 和 T。将汇总计算作为脚本执行并粘贴其输出(可复现性规则 4)——切勿手工计算 Σw 或 Final。

输出

按照 reference.md 中的模板生成 Markdown 报告。报告必须分别呈现两个评估对象,并包含:每项 AC 的实现检查清单表格(I-checks、MET/UNMET、证据);Elicitation E 区块(类别评分标准召回率表 + 带判定的新增需求台账 → E_recall/E_precision/E_justified);Scope S 可追溯性判定;每项需求的单元/e2e 测试检查清单表格(T-checks 覆盖认可集合 = PRD ACs ∪ 有效 E 补充项);额外测试清单;测试分布 D 表格(各层级的数量 + 百分比);计算出的 Final(若门禁为 ✗,还需提供 Adjusted Final);R/G/D;按优先级排序的差距清单;以及达到 1.00 所需的具体修复方案。

如果存在 .specs/spec 文件夹,将报告保存至 <spec-folder>/evaluations/<priority>-<story-slug>-<timestamp>.md;否则直接在对话中提供。<timestamp> 为 UTC 时刻,格式为 YYYYMMDDTHHMMSSZ(例如 20260606T143012Z),通过写入时的系统时钟获取(date -u +%Y%m%dT%H%M%SZ)。时间戳可确保每个报告文件名唯一,因此多个 Agent 并行评估同一个 story 时绝不会互相覆盖——每次运行都会生成各自的文件。如果仍有同一秒发生冲突的可能(许多运行并行进行时),请在文件名后追加短运行 ID:<priority>-<story-slug>-<timestamp>-<run-id>.md。

注意:只有报告文件名带时间戳。冻结的 _ac-baseline.md 不带时间戳——它是所有运行共同读取的唯一共享产物,以确保结果可比较;切勿为每次运行另建副本。

完整示例

reference.md 中提供了一个完整的实用评估示例(示例计费服务的 P0「无需银行卡即可开始免费试用」),展示了按 AC 列出的二元检查清单及 file:line 证据,以及校准基准。请遵循其结构和严谨程度。

反模式

  • 将 I/T 评分交给“感觉像 0.75”这样的主观判断,而不是统计二元检查项。
  • 针对每种实现重新推导 AC 列表或检查清单(这会破坏可比性),而不是复用已冻结的基准。
  • 将检查项标记为 UNMET,却不展示已执行的搜索;或将其标记为 MET,却不提供 file:line 证据。
  • 未先运行 git diff 确定差异范围,就在整个代码库中搜索证据——这会导致搜索结果不可靠,并夸大“未找到”的可信度。
  • 未端到端阅读生产代码路径,就给予实现分数。
  • 将额外或防御性测试计入 AC 的必要覆盖范围,或因代码/测试更多而提高评分。
  • 未实际运行工程门禁,却报告其通过;或对 not-run 门禁应用 Adjusted Final。
  • 将门禁标记为 not-run,却没有记录尝试过程(命令 + 错误输出)。没有探测就声称“基础设施不可用”,属于捏造证据。
  • 修改待评估代码以将失败的门禁变为通过——评估者对评估对象只能进行只读检查;失败的门禁应计为 ✗,修复建议写入报告。
  • 不执行脚本并粘贴输出,而是手动计算汇总值(Σw、Final)。
  • 因缺少范围外功能而扣分。
  • 将 E 或 S 纳入 Final——总体评分必须仅表示“对给定 PRD 的忠实度”,否则会破坏可比性。
  • 对框架提取出的有效需求予以扣分,即使它已被正确推迟到范围外(这是良好的纪律,而非范围失误)。
  • 仅依据 PRD 评估测试框架完整性(T)——分母应为经认可的集合(PRD AC ∪ 有效的 E 补充项)。
  • 因 E 中的需求数量而给予奖励:虚构或范围蔓延式的补充会降低 E_precision,而不会提高分数。
  • 在同一 PRD 的不同实现之间更改权重(0.6/0.4、P0/P1/P2)。

评论

支持 Markdown