acceptance-verify

对整体功能或完整模块做交付前验收:以用户确认过的验收指标清单逐条核验(已有测试套件 + 临时场景测试 + e2e 真实链路三层证据),只判定不改产品代码,产出锚定分支与 commit 的验收报告,支持复验。仅用户明确指定时触发("验收这个功能/模块"、"做验收"、"验收测试 / acceptance test"、"复验");只问"流程跑通没有"用 e2e-testing。

SKILL.md

GitHub

🎯 功能 / 模块验收(acceptance-verify)

AI 说明层

目的:解决"code review 说没问题、测试套件也全绿,但整个功能其实没达成目标"这一验收盲区。验收对象是一个整体功能或一个完整模块(空间维度的全量),不是某次改动(时间维度的 diff)。

功能:

  • 提炼核心目标 → 推导验收指标清单 → 用户确认后锁定为验收基准 → 逐条核验
  • 三层证据:L1 已有测试套件(基础基线)/ L2 临时场景测试(重点)/ L3 e2e 真实链路(重点,调用 e2e-testing)
  • 指标未覆盖时补充测试:长期回归有价值的进正式测试套件,一次性场景走查落临时测试
  • 场景执行过程留痕(scenario-records/),体验类结论必须有可追溯的观察记录
  • 产出锚定分支名 + commit 的验收报告,使结论可追溯、可复现
  • 落盘 .requirements/acceptance/{slug}/(按功能/模块 slug 组织,与需求编号解耦),多轮验收在同一目录累积
  • 只判定不修改:验收过程不改任何产品代码,不达标仅记录并给出建议(唯一例外是编写单测 / e2e 测试作为验证工具)
  • 二次验收:复验时重新采集基线、全量重跑指标,不比对中间提交与改动,只回答"现在好了没有"

⚠️ 仅用户明确指定时触发:本技能是低频重成本能力(占用大量上下文、会起容器并执行真实链路测试),AI 不得因"看起来该做验收"而自行启用——须由人显式发起。

使用场景:

  • 一个功能模块开发完成,需要确认"它到底好了没有"
  • 用户说"验收这个功能""验收一下这个模块""做验收""acceptance verify"
  • 需求/设计文档里有验收标准,但不确定是否真的都达成了
  • 重构或大改后,需要确认整体行为未被破坏
  • 上轮验收未通过、修复后要确认"现在到底好了没有",且不关心中间改了什么 → 二次验收

何时不使用:

  • 只改了几行、想看改动对不对 → code-review(对象是 diff,本技能对象是整体)
  • 只想验证单个 HTTP 接口 → api-testing
  • 只想跑通一条端到端流程、不涉及指标清单与验收结论 → e2e-testing
  • 开发前验证技术方案可行性 → demo-verify
  • 只要一份"该测什么"的计划、不做执行与判定 → test-planner

核心立场(本技能存在的理由)

常见错觉 为什么不成立
code review 通过 = 功能没问题 review 看的是 diff:局部改动正确 ≠ 功能完整,可能某个目标压根没实现
测试套件全绿 = 可以交付 套件测的是已覆盖的部分;验收标准里没被任何测试覆盖的指标,套件不会告诉你
跑通主流程 = 验收通过 主流程通了,边界、异常、跨模块组合、实际体验仍可能不成立

一句话:L1 测试套件只回答"已有测试是否还绿",不回答"这个功能是否达成目标"。回答后者靠 L2 场景测试 + L3 真实链路——这是本技能的重心。


核心概念

1. 验收对象

一个完整功能或一个模块(如"用户登录模块""订单导出功能"),不是单个函数、不是一次提交。 阶段 0 必须把边界写清楚:模块路径 / 入口 / 涉及的外部依赖。边界不清,指标无从推导。

2. 核心目标与验收指标

  • 核心目标:一句话说明这个功能/模块要达成什么(验收的"北极星")
  • 验收指标:从核心目标拆解出的多条可判定条目,每条必须能回答"达成 / 未达成"

指标六型(推导时逐型过一遍,避免只想到功能正确性):

类型 回答什么问题 典型证据层
🎯 功能达成 核心能力按目标工作了吗 L1 / L2
🌐 场景覆盖 各类真实使用场景都走得通吗 L2 / L3
🧱 边界异常 极端/错误输入下行为可控吗 L1 / L2
💎 体验质量 实际用起来顺手吗、反馈清晰吗、犯错后好恢复吗 L2 / L3
🔗 契约集成 对外契约 / 跨模块耦合成立吗 L1 / L3
📊 非功能 性能阈值、幂等、并发等可测项达标吗 L2 / L3

⚠️ 指标必须可判定——每条写清「判据」(什么算达成)。只写"体验良好""性能达标"这种无法判定的描述,等于没写指标。

3. 三层证据

层 名称 地位 做什么 产物落盘
L1 已有测试套件 基础 扫描项目既有单测/集成测试 → 匹配指标 → 直接跑,取结果。只复用,不改写 不落盘(引用现有路径)
L2 临时场景测试 重点 针对指标现写场景化脚本,模拟真实使用路径;体验类指标在此做场景走查并留观察记录 {slug}/temp-tests/
L3 e2e 测试 重点 真实环境 + 真实链路,验证跨组件终态与实际体验 调用 e2e-testing,产物按其约定落 tests/e2e/

证据层分配原则:

指标特征 分配到
已有测试明确覆盖该判据 L1(跑它,别重写)
需跨多步/多模块的真实业务场景 L3
单次/少次调用可验证、无现成测试 L2
判据含"体验/反馈/流畅度/容错" L2 场景走查(留观察记录),真实环境可用时叠加 L3 动态体验
依赖真实环境 / 外部系统 / 跨组件终态 L3

补充测试:进套件 还是 临时?

进正式测试套件 落临时测试
有长期回归价值(核心不变量、对外契约、边界条件) 仅本次验收需要的场景走查
断言稳定、不依赖一次性数据 依赖一次性构造数据 / 特定环境状态
CI 能稳定跑 跑完即弃,避免污染 CI

两种都是"补",区别只在归属。判断不清时问:三个月后这条断言还值得跑吗?值得 → 进套件。

⚠️ 进套件的准入条件(不可跳过):只有通过的测试才进正式套件。指标未达成(❌)或状态未定(⚪)时,验证脚本一律落临时测试或只做记录——把一条失败的测试固化进 CI,而本技能又不许改产品代码,结果是 CI 长期红灯且无人有权修。若确需把"已知失败"留档,落 temp-tests/ 并在报告中标注,不进 CI。


验收流程(6 阶段,严格顺序)

阶段 0 确定验收对象与代码基线 → 阶段 1 推导核心目标与指标
→ 阶段 2 用户确认指标(锁定基准)→ 阶段 3 证据映射
→ 阶段 4 执行三层验证 → 阶段 5 逐指标核验 → 阶段 6 产出报告并落盘

📍 阶段 0:确定验收对象与代码基线

0.1 验收对象边界与 slug

  • 明确模块路径 / 功能入口 / 涉及的外部依赖(DB、MQ、第三方 API)
  • 确定 slug:功能/模块的 kebab-case 标识(如 user-login、order-export)。同一对象跨轮必须一致,否则验收历史断裂。确定前先列 .requirements/acceptance/ 下已有 slug,与用户确认是复用(复验)还是新建(新对象)——避免 user-login 与 user-login-v2 这类近似 slug 把同一对象的历史拆成两截
  • 有需求或设计文档 → 读取(.requirements/config 的 storage_path → {storage_path}/{date}-{slug}/),作为指标推导的首要来源
  • 有 test/test-plan.md(test-planner 产出)→ 读取,作为指标来源之一,避免重复推导
  • 边界不清或信息不足 → 最小化提问,不臆测

0.2 代码基线采集(必做,不可省)

git rev-parse --abbrev-ref HEAD                  # 分支名
git log -1 --format='%H|%h|%s|%ci|%an'           # 完整hash|短hash|标题|时间|作者
git status --porcelain                            # 非空 = 工作区 dirty

报告中必须包含:分支名、commit(短 hash + 完整 hash + 标题)、是否 dirty。

⚠️ dirty 处理:工作区有未提交改动时不阻断验收,但须先提示「建议先提交或 stash 后验收,否则结论不可按 commit 复现」;用户仍继续则报告中标注 ⚠️ 工作区存在未提交改动(N 个文件),结论仅对当前工作区有效,不可按 commit 复现——否则报告里的 commit 锚点会误导读者。

⚠️ 验收过程中代码变了:若执行期间 HEAD 发生变化(新提交/切分支),停止并重新采集基线,在报告中标注原基线与实际执行基线。禁止顶着旧 commit 出结论。

0.3 环境准备与可用性探测(结论须在阶段 3 生效) L3 需要真实环境。先备齐验收依赖的第三方组件(Redis / MySQL / MQ / 对象存储等),再探测可达性与凭证(凭证走 env 文件,不内联真实密钥——详见 e2e-testing「敏感信息外部化」)。

组件获取优先级(自上而下,命中即停):① 复用现成实例(本地已装 / dev 环境 / 已有容器在跑;须确认可连接、版本匹配、非生产)→ ② Docker 起容器(无现成实例时的首选)→ ③ 装 docker 后回到 ②(仅 Linux)→ ④ 装组件本体(最后手段,Windows 由用户安装)。

平台规则:Linux 无 docker 时 AI 可安装 docker(须先告知用户——安装改变机器状态);Windows 及其他非 Linux 平台禁止 AI 自行安装(需 GUI 交互 / 管理员权限 / 重启,AI 无法可靠完成)→ 提示用户手动安装并给出指引。 起容器与装组件属环境准备,不违反「只判定不修改」铁律(该铁律只约束产品代码)。检测命令、容器约定、清理、生产告警见 reference.md「环境准备」。

记录环境状态并传递到阶段 3:环境最终不可用 → 依赖真实环境的指标不得分配 L3,直接判 ⚪ 未验证 或降级 L2 模拟,不降级为通过,并列入"需补验清单"。⚠️ 若阶段 3 仍分配给 L3、到阶段 4 才发现跑不了 = 白走一轮——环境结论必须在分配证据层时生效。

0.4 轮次判定(必须在阶段 1 之前完成)

检查 .requirements/acceptance/{slug}/ 是否存在:

检查结果 轮次 阶段 1 的走法
目录不存在 round-1(首次验收) AI 推导核心目标与指标
目录已存在 round-N(二次验收) 不重新推导——读 metrics.md 沿用指标;同步读上一轮报告,只看"哪些未达标",不看修复过程

⚠️ 判定必须在阶段 1 之前:一旦先推导再发现是复验,等于用新推导的指标覆盖了已锁定基准,历史轮次失去可比性。

🎯 阶段 1:推导核心目标与验收指标

复验(round-N)时跳过推导:直接沿用 metrics.md 中已锁定的指标,进入阶段 2 确认是否沿用 / 是否追加。下方推导流程仅适用于首次验收。

AI 自主推导(依据:需求/设计文档 → 模块代码 → 对外契约 → 使用场景),输出:

## 验收对象
- 模块/功能:<名称>
- 边界:<路径 / 入口 / 依赖>

## 核心目标
<一句话:这个功能/模块要达成什么>

## 验收指标清单(草案)

| 指标 ID | 类型 | 指标描述 | 判据(什么算达成) | 建议证据层 | 来源 |
|---------|------|---------|-------------------|-----------|------|
| M-01 | 🎯 功能达成 | <描述> | <可判定判据> | L1/L2/L3 | 需求 REQ-xx / 代码推导 |
| M-02 | 💎 体验质量 | <描述> | <可判定判据> | L2 | 场景推导 |
...

推导纪律:

  • 六型指标逐型过一遍,命中不足的显式说明"本模块无此型指标"(防止只推导功能正确性)
  • 每条指标必须能追溯到来源(需求条目 / 设计点 / 代码推导 / 场景推导);凭空编造的指标一律不写
  • 无需求文档时,从模块对外契约 + 真实使用场景推导,并在报告中标注指标来源为「代码/场景推导(无需求文档,置信度 🟡)」

🔒 阶段 2:指标确认(锁定验收基准)

将指标清单呈现给用户确认:

## 验收指标确认(请确认后进入执行)

核心目标:<...>

| 指标 ID | 类型 | 指标描述 | 判据 | 证据层 |
|---------|------|---------|------|--------|
| M-01 | ... | ... | ... | ... |

请确认:
1. **完整性**:是否遗漏了应验收的目标?
2. **判据可判定性**:每条判据能否明确判定达成/未达成?
3. **证据层分配**:场景类指标是否该走 L3(真实链路)?
4. **优先级**:哪些是 🔴 必达(不达成就不能交付)?

复验时确认内容不同(沿用而非新建):

## 验收指标确认(复验 · 沿用 round-{N-1} 基准)

沿用指标:<N 条,来自 metrics.md>

请确认:
1. **沿用**:沿用已锁定的 N 条指标,是否同意?
2. **追加**:是否需新增指标?(新增项在本轮「轮次对比」中记为 `—` → 新状态,并说明新增原因)
3. **重验范围**:默认全量重跑(含上轮已 ✅ 的),是否同意?
  • 用户确认 → 锁定为验收基准,进入阶段 3
  • 用户修正 → 更新后再次确认,最多迭代 3 次
  • ⚠️ 锁定后不得边跑边改指标——发现"这条测不出来"应标 ⚪ 未验证 并说明,而不是删掉或改判据。否则验收变成"测到什么算什么"

🗺 阶段 3:证据映射

为每个指标确定具体怎么验,输出映射表:

指标 ID 证据层 具体验证方式 已有测试 / 需新建 落盘位置
M-01 L1 跑 tests/test_login.py::test_login_success 已有 —
M-02 L2 新写场景脚本:错误密码 → 检查返回与提示文案 新建·临时 {slug}/temp-tests/...
M-03 L3 e2e 旅程:注册→登录→访问受保护资源 调用 e2e-testing tests/e2e/

L1 扫描方式(不假设固定路径,同 test-planner 阶段 2.5):用 list_dir / search_file 找项目既有测试目录约定,识别框架与运行命令。

▶️ 阶段 4:执行三层验证

按 L1 → L2 → L3 顺序执行。前一层的结果用于收敛后一层的重点(L1 已明确覆盖且通过的指标,L2 不必重复造轮子,把时间留给 L2/L3 的场景与体验)。

L1 已有测试套件(基础)

  • 执行映射到的已有测试,取全量结果(通过/失败/跳过)
  • 已有测试失败 → 记为「L1 基线异常」,按影响面定级,不等同于验收不通过,但必须进入报告
  • 只跑不改写;发现问题记下来,不改测试去迁就实现
  • 「L1 已覆盖」判定从严:必须是「该测试的断言确实覆盖了这个判据」,不是「测了同一个函数」。只测了返回值却没测判据里的边界/文案/副作用 → 不算覆盖,转 L2
  • L1 覆盖且 PASS → 该指标可标 ✅,不重复造轮子,但报告中注明「证据来自 L1,未做场景级复验」
  • 🌐 场景覆盖型 / 💎 体验质量型原则上不走 L1——单测测不了完整业务场景与使用体验

L2 临时场景测试(重点)

  • 按真实使用路径写,不是按函数逐个调用——一个场景脚本应模拟"用户/调用方真正会怎么用"

  • 断言锚定指标判据,不锚定当前实现——但边界要划准,否则无从下手:

    ✅ 允许读代码 ❌ 禁止读代码
    识别调用入口、函数签名、请求/响应契约(否则连怎么调都不知道) 读实现内部逻辑反推断言的期望值(如"这里返回 3,就断言 ==3")

    判据期望值的唯一来源是阶段 2 锁定的指标判据(其源头是需求/设计文档或用户确认)。无需求文档、指标由代码推导而来时,该类指标置信度标 🟡 并在报告中声明——这是"防自欺"的诚实标注,不是禁止读代码

  • 体验类指标(💎)在此做场景走查:连续操作、故意犯错、观察反馈,记录到 scenario-records/

  • 落盘 {slug}/temp-tests/,命名 acceptance-{指标ID}-{YYYYMMDD-HHmm}.{ext}

  • 执行完保留(作为验收证据,报告中标注路径)

L3 e2e 测试(重点)

  • 调用 use_skill("e2e-testing"),传入:本次需真实链路的指标清单(含判据)+ 场景描述 + 需求来源(requirement_ref)
  • 不重复实现 e2e 编排——环境、凭证、tests/e2e/ 隔离、teardown、安全门禁一律遵其约定
  • 体验类指标如需真实环境体验 → 走 e2e-testing 的动态体验验证
  • 回收 e2e 报告 → 映射回指标 ID(e2e 的 step 与验收的指标不是一一对应,必须人工/AI 做映射,不能把 journey 报告直接当验收结论)

L3 失败 ≠ 验收不通过:先判断是否环境/数据/时序问题。非编排问题且根因不明 → 调用 use_skill("debug") 定位。本技能判定"指标是否达成",不负责定位"服务为什么失败"。

✅ 阶段 5:逐指标核验

每个指标给出状态 + 证据 + 结论:

状态 含义
✅ 达成 有证据,判据满足
🟡 部分达成 主路径成立但存在未满足的边界/体验缺口,不阻塞交付
❌ 未达成 判据不满足。必达与否都记 ❌,区别只在计入哪一档结论(必达❌ → ❌ 不通过;非必达❌ → ⚠️ 有条件通过)
⚪ 未验证 环境不可用 / 无手段验证 / 需人工——必须显式列出,禁止静默略过

核验纪律:

  • 证据必须可追溯:写明"哪条测试 / 哪个场景记录 / e2e 的哪个 step",不写"已验证"这种无据结论
  • 体验类结论必须有观察记录:不能凭感觉给"体验良好",要引用 scenario-records/ 里的具体观察
  • ⚪ 不等于 ✅:未验证的指标在结论中单独列「需补验清单」
  • 全部指标过完后才出总结论

验收结论:

  • ✅ 通过 — 全部 🔴 必达指标达成,且无任何 ❌(可容忍 🟡 / ⚪)
  • ⚠️ 有条件通过 — 🔴 必达全达成,但存在非必达指标 ❌,或存在 🟡 / ⚪
  • ❌ 不通过 — 存在任一 🔴 必达指标 ❌

⚠️ 非必达指标 ❌ 归 ⚠️,既不归 ✅ 也不归 ❌:它不阻塞交付,但必须列入报告「交付前必须完成」或由用户显式接受风险——不得因"只是非必达"就当它不存在。三档结论必须对任一指标组合都能给出唯一归属。

📄 阶段 6:产出验收报告并落盘

落盘到 .requirements/acceptance/{slug}/reports/round-{N}-{YYYY-MM-DD}.md。

报告模板见「验收报告模板」。落盘后:

  • 指标清单同步落 metrics.md(首次验收创建;后续轮次沿用,需追加指标时追加并在本轮报告中说明)
  • 本轮未通过项写入 metrics.md 的「历史未达标」区,供下轮复验定位
  • 本轮为复验时,报告必含「轮次对比」区(见下方「二次验收」)

🔁 二次验收(复验)

二次及以上验收时,不关注中间做了哪些提交和改动——不 diff 版本、不读中间 commit、不追溯"修复了什么"。只看当前状态下这个功能是否达成目标。

为什么:一旦去看中间改动,就会不自觉地把"改动是否修好了那个点"当成验收结论,退回到 diff 视角(那是 code-review 的事)。验收只回答"现在好了没有"。

与首次验收的执行差异:

环节 首次验收 二次验收
指标 AI 推导 → 用户确认 → 锁定 读 metrics.md 沿用;需追加则追加并在本轮报告说明,不回溯修改历史轮的指标定义
代码基线 采集当前分支 + commit 重新采集(分支/commit 大概率已变),不比对上轮基线
重跑范围 全量 默认全量重跑——不掌握中间改动,无法判断上轮 ✅ 的指标是否仍成立
输入参考 需求/设计文档 需求/设计文档 + 上轮报告(只看"哪些未达标",不看修复过程)
输出 round-1-{date}.md round-{N}-{date}.md

轮次报告必须包含「轮次对比」区(只比结果,不比过程):

## 轮次对比(vs round-{N-1})

| 指标 ID | 上轮状态 | 本轮状态 | 变化 |
|---------|---------|---------|------|
| M-02 | ❌ 未达成 | ✅ 达成 | 已解决 |
| M-05 | 🟡 部分达成 | 🟡 部分达成 | 缺口未变:<...> |
| M-07 | — | ⚪ 未验证 | 本轮新增指标 |

代码基线:`main@a1b2c3` → `main@d4e5f6`(**不比对中间改动**)

发现回归时的处置(上轮 ✅、本轮 ❌/🟡):

  • 只记录事实,不做归因——本技能不 diff 中间改动,因此无从也不应回答"是哪次提交导致的"
  • 报告中记录「回归:M-XX 由 ✅ 变为 🟡/❌」+ 当前实际表现 + 证据,并建议转 code-review / debug 定位
  • ❌ 禁止为了解释回归而回头去 diff 中间提交——那会退回 diff 视角,把"那个点改坏了"当成验收结论
  • 用户追问"为什么" → 明确答复"验收不做归因,建议转 debug",而非临时破例去看 diff

⚠️ 复验的执行成本:全量重跑意味着 L3 要在真实环境再走一遍完整旅程(含创建订单、扣库存等真实副作用)。复验前确认:① 环境可重复使用 ② e2e-testing 的 teardown 到位、上轮数据已清理。成本过高时允许按风险分层(🔴 必达全跑 + 🟡 抽样),但必须在报告中显式标注"本轮为抽样复验"及未覆盖的指标,不得让抽样结果被误读为全量结论。

收敛判据:全部 🔴 必达指标 ✅ 且无 ❌ → 验收通过,可停止复验。同一指标连续两轮仍为 ❌/🟡 → 报告中标注「需重新评估方案」并提示用户,不再机械复验。


落盘结构

验收记录按功能/模块 slug 组织,与具体需求编号解耦——同一对象的每轮验收累积在同一目录,形成验收历史:

.requirements/acceptance/{slug}/
├── metrics.md                          # 验收指标基准(首次锁定,跨轮复用)
├── reports/                            # 每轮一份验收报告
│   ├── round-1-2026-09-09.md
│   └── round-2-2026-09-12.md
├── scenario-records/                   # L2/L3 场景执行观察记录
│   └── YYYY-MM-DD-{场景slug}.md
└── temp-tests/                         # L2 临时场景测试脚本
    └── acceptance-{指标ID}-{YYYYMMDD-HHmm}.{ext}
  • slug 命名:功能/模块的 kebab-case 标识(如 user-login、order-export)。同一对象跨轮必须保持一致,否则验收历史断裂
  • L1 产物不落盘——引用项目既有测试路径即可
  • L3 产物落在 tests/e2e/(遵 e2e-testing 约定),验收侧只存报告与映射关系
  • 补进正式套件的测试落在项目既有测试目录(遵 test-planner 阶段 2.5 的位置判断)
  • 不做 req update --docs add 注册:验收目录不在需求目录内,强行注册会造成双源。报告内记录关联需求 ID 即可

验收报告模板

# 验收报告:{功能/模块名}

## 验收基线
- 验收对象:<模块路径 / 功能名 / 边界>
- 验收轮次:round-{N}(首次验收 / 二次复验)
- 代码基线:`{branch}` @ `{short_hash}`(`{full_hash}`)
  - commit 标题:{title} 时间:{time} 作者:{author}
  - 工作区:✅ 干净 / ⚠️ 存在 N 个未提交文件
- 验收时间:<时间> 执行方式:L1 套件 / L2 临时场景 / L3 e2e
- 关联需求:REQ-NNN《需求名》/ [无需求文档]

## 核心目标
<一句话>

## 验收结论
✅ 通过 / ⚠️ 有条件通过 / ❌ 不通过

- 指标总数:N ✅ 达成 X 🟡 部分 Y ❌ 未达成 Z ⚪ 未验证 W
- 🔴 必达指标:A 条,达成 A' 条

## 验收指标核验

| 指标 ID | 类型 | 指标描述 | 判据 | 层 | 证据 | 状态 |
|---------|------|---------|------|----|------|------|
| M-01 | 🎯 | <描述> | <判据> | L1 | `tests/test_x.py::test_y` PASS | ✅ |
| M-02 | 💎 | <描述> | <判据> | L2 | `{slug}/temp-tests/acceptance-M02-....py` PASS + 观察记录 | 🟡 <缺口> |
| M-03 | 🌐 | <描述> | <判据> | L3 | e2e journey step: register→login→access | ✅ |
| M-04 | 🔗 | <描述> | <判据> | L3 | — | ⚪ 环境不可用,需补验 |

## 三层证据执行结果

**L1 已有测试套件(基础)**
- 复用 N 条:通过 X / 失败 Y / 跳过 Z
- 基线异常:<列出失败测试及影响面,或"无">

**L2 临时场景测试(重点)**
- 新建 M 条(临时 K 条 / 进套件 P 条)
- 场景走查:<覆盖的场景 + 观察记录路径>

**L3 e2e 测试(重点)**
- 场景:<journey 名> 结果:✅ PASS / ❌ FAIL(abort 于 step X)
- 动态体验:<执行了 / 未执行,原因>

## 体验观察摘要(💎 类指标)
> 引用 `scenario-records/`,不凭感觉下结论
| 场景 | 观察 | 评价 |
|------|------|------|
| <场景> | <实际见到的反馈/耗时/提示> | 良好 / <缺口> |

## 未通过指标明细
### [M-0X] <指标描述>
- 判据:<...>
- 实际:<...>
- 证据:<测试/场景记录路径>
- 影响:<功能影响,翻译成用户/业务语言>
- 建议:<方向>

## 需补验清单(⚪ 指标)
| 指标 ID | 未验证原因 | 补验方式 | 阻塞交付? |
|---------|-----------|---------|----------|

## 交付建议
- 🔴 交付前必须完成:<...>
- 🟡 交付后跟进:<...>

与相邻 skill 的边界

skill 关系
e2e-testing L3 的执行者。本技能在 L3 调用它,不重复实现 e2e 编排 / 环境 / 凭证 / 隔离约定。它回答"流程跑通了吗、终态对吗",本技能回答"功能达成目标了吗"
test-planner 其 test/test-plan.md 可作为指标来源之一;其测试落盘位置判断方式(扫描不假设固定路径)被本技能 L1 复用
code-review 无依赖、无门禁、可独立触发。它看 diff(局部+增量),本技能看整体(全量)。review 通过不构成验收通过,反之亦然
api-testing 单接口验证;本技能需要时可作为 L2 的执行手段,不重复实现其客户端与断言约定
demo-verify 开发前验证技术可行性;本技能是交付前确认目标达成。时间轴不冲突
debug L3 失败且根因不明时转交定位;本技能只判定"是否达成"

约束与原则

  1. 指标先确认后执行:阶段 2 锁定后即为基准,本轮内不得边跑边改。测不出来标 ⚪,不删指标、不改判据。跨轮次允许追加新指标,但已有指标的定义与判据一律冻结
  2. L1 只是基线:套件全绿不构成验收通过;本技能的价值在 L2/L3
  3. 断言锚定指标,不锚定实现:写 L2 断言前先读指标判据;先读实现再写断言 = 自欺欺人
  4. 场景优先于函数:L2 按真实使用路径写,不按函数逐个调用
  5. 体验结论必须有观察记录:💎 类指标不能凭感觉判定,必须引用 scenario-records/
  6. commit 锚定不可省:分支名 + commit + dirty 状态三要素齐全;执行期间 HEAD 变化须重新采集
  7. ⚪ 不等于 ✅:未验证指标单独列「需补验清单」,禁止静默略过或降级为通过
  8. 不重复实现 e2e:L3 一律走 e2e-testing,含其环境/凭证/隔离/teardown/安全门禁约定
  9. 证据可追溯:每条结论写明来源(测试路径 / 场景记录 / e2e step),禁止"已验证"式无据结论
  10. 结论翻译成功能语言:未通过指标要说清"用户/业务层面会怎样",不只是"测试失败"
  11. 凭据不入库:环境/凭证一律 env 文件注入,验收文档与脚本中不内联任何真实密钥/URL
  12. 中文输出:报告与指标用中文,代码标识符保持原样
  13. 只判定不修改(铁律):验收是判定动作,不是修复动作——不修改任何产品代码(实现、配置、依赖、数据迁移、脚本),不达标仅记录并给出建议方向。唯一例外是编写单元测试与 e2e 测试,它们是验证工具而非产品代码。发现缺陷 → 记入报告「未通过指标明细」+ 建议转 debug / code-review,不在验收过程中修复
  14. 二次验收只看终态:复验时重新采集基线、全量重跑指标;不 diff 版本、不读中间 commit、不追溯"修复了什么"、不比对上轮基线。只回答"现在好了没有"
  15. L3 一律调用 e2e-testing:不自行实现 e2e 编排、环境准备、凭证注入、tests/e2e/ 隔离与 teardown——重复实现会产生双源并违反其隔离约定

常见陷阱

  • 把验收做成"再跑一遍测试套件" → L1 全绿就出通过结论,恰恰是本技能要防的盲区。重心必须在 L2/L3
  • 指标不可判定 → 写"体验良好""性能达标",执行时无法判定,最后不了了之
  • 边跑边改指标 → 某条测不出来就删掉或放松判据,验收沦为走过场
  • 先读实现再写断言 → 写成"一定能过"的断言,验收失去意义(同 e2e-testing 的"写断言前不读实现代码")
  • 场景脚本按函数写 → 逐个函数调用跑通了,但真实使用路径没验到
  • 忘记录 commit / 忽略 dirty → 报告无法复现,结论失去追溯价值
  • 把 ⚪ 当 ✅ → 环境不可用的指标静默略过,交付后才发现没验
  • 把 e2e journey 报告直接当验收结论 → step PASS ≠ 指标达成,必须做 step → 指标 ID 的映射
  • 重复实现 e2e 编排 → 与 e2e-testing 双源,且容易违反其 tests/e2e/ 隔离约定
  • 体验结论无记录 → 报告写"体验良好"但无任何观察依据
  • 验收时顺手修代码 → 验收只判定不修改。顺手改会让本轮报告的代码基线失真(报告锚定的 commit 与实际验证的代码不一致),且这次修改本身未经 review
  • 复验时去 diff 中间改动 → 退回到 diff 视角,把"那个点修好了"当成验收结论;应全量重跑指标只看终态
  • 复验只跑上轮失败项 → 不掌握中间改动时,上轮 ✅ 的指标可能已被破坏;默认全量重跑
  • 复验时改写历史指标定义 → 上一轮的 ❌ 会因判据放松而"变成" ✅,验收历史失去可比性

更多资源

  • 指标推导细则、三层证据执行细节、commit 采集、场景观察记录模板:reference.md
  • 完整验收示例(模块级 + 功能级):examples.md
  • L3 执行依赖:use_skill("e2e-testing")
  • L1 落盘位置判断参考:use_skill("test-planner")