mcpField
Q
quality-playbook

quality-playbook

github.com/github测试与质量40.5k1.6k 次安装1 天前更新
代码仓库

关于 quality-playbook

供编码 Agent 使用的技能,先探索代码库,再生成定制质量体系,并指导代码审查、规格审计、问题协调和验证。适用于通过关联需求、发现项与回归测试评估软件质量的团队。

主要功能

  1. 01基于领域知识探索代码库
  2. 02生成质量需求与测试文档
  3. 03三轮代码审查
  4. 04独立规格审计
  5. 05问题协调与验证

适用场景

  1. 01为代码仓库构建质量计划
  2. 02依据项目需求审查代码
  3. 03审计规格与引用
  4. 04通过回归测试跟踪发现项

安装

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

$npx skills add https://github.com/github/awesome-copilot --skill quality-playbook

安装后在 Claude Code 中输入/quality-playbook确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

LICENSE.txt
quality_gate.py
agents/
calibration_orchestrator.md
quality-playbook-claude.agent.md
quality-playbook.agent.md
phase_prompts/
iteration.md
phase1.md
phase2.md
phase3.md
phase4.md
phase5.md
phase6.md
README.md
single_pass.md
references/
challenge_gate.md
code-only-mode.md
constitution.md
defensive_patterns.md
exploration_patterns.md
functional_tests.md
iteration.md
orchestrator_protocol.md
requirements_pipeline.md
requirements_refinement.md
requirements_review.md
review_protocols.md
run_state_schema.md
schema_mapping.md
spec_audit.md
verification.md

详细介绍

Quality Playbook Generator

计划概览——先读这一部分,然后向用户解释它

在阅读本技能的任何其他部分之前,先理解这个计划及其依赖关系。每个阶段产生的成果物都是下一阶段的依赖。跳过某个阶段或匆匆略过某个阶段,意味着后续每个阶段都只能在信息不完整的基础上工作。

阶段 0(既往运行分析): 如果存在以前的质量运行,加载它们的发现作为种子数据。这是自动进行的,且仅适用于重新运行的情况。

阶段 1(探索): 首先运行 v1.5.3 文档摄取(python -m bin.reference_docs_ingest <target> 以遍历 reference_docs/——cite/ 文件会生成 quality/formal_docs_manifest.json 记录;顶层文件通过 reference_docs_ingest.load_tier4_context(<target>) 作为 Tier 4 上下文加载)。然后分三个阶段探索代码库:由领域知识驱动的开放式探索、领域知识风险分析,以及选定的结构化探索模式。将所有发现写入 quality/EXPLORATION.md。这个文件是基础——阶段 2 将它作为主要输入来读取。

阶段 2(生成): 读取 EXPLORATION.md 并生成质量成果物:需求、章程、功能测试、代码审查协议、集成测试、规格审计协议、TDD 协议。(目标仓库根目录下的 AGENTS.md 由编排器在阶段 6 之后生成,而不是由你在阶段 2 生成——其契约见下文“文件 6”。)

阶段 3(代码审查): 针对 HEAD 运行三轮代码审查。为每个确认的 bug 编写回归测试。生成补丁。

阶段 4(规格审计): 三位独立的 AI 审计员对照需求审查代码。通过验证探针进行分诊。分诊之后,同一个 Council 运行 v1.5.3 Layer-2 语义引用检查——每位审查员一个提示词,针对每个 Tier 1/2 引用给出按 REQ 结构化的裁决,输出到 quality/citation_semantic_check.json。为净新增的发现编写回归测试。

阶段 5(调和): 闭环——代码审查和规格审计中的每个 bug 都被跟踪、经过回归测试或明确豁免。运行 TDD 红绿循环。最终确定完整性报告。

阶段 6(验证): 针对所有生成的成果物运行自检基准。检查内部一致性、版本戳正确性和收敛性。

阶段 7(呈现、探索、改进): 用可快速浏览的摘要表向用户呈现结果,提供对任何成果物的深入查看,并提供改进路径菜单(迭代策略、需求细化、集成测试调优)。这是交互阶段,用户在此接管质量系统的所有权。

发现的每个 bug 都可追溯到某项需求,而每项需求都可追溯到某项探索发现。

关键依赖链: 探索发现 → EXPLORATION.md → 需求 → 代码审查 + 规格审计 → bug 发现。浅层的探索产生抽象的需求。抽象的需求会遗漏 bug。探索阶段是决定 bug 成败的地方。

强制性的第一个动作: 在阅读并理解上述计划之后,向用户打印以下消息,然后用自己的话解释这个计划——你将做什么、每个阶段产出什么,以及为什么探索阶段最重要。强调探索从开放式、领域驱动的调查开始,随后是领域知识风险分析,推理此类系统中会出现什么问题,再用选定的结构化模式加以补充。不要逐字照抄计划;请转述它以展示你的理解。

Quality Playbook v1.5.6 — by Andrew Stellman https://github.com/andrewstellman/quality-playbook

生成一套为特定代码库量身定制的完整质量系统。与机械地从源代码出发的测试桩生成器不同,本技能会先探索项目——理解其领域、架构、规格和失败历史——然后生成一套以所发现内容为依据的质量手册。

如何运行本流程 — v1.5.4 自编码调用契约

如果操作者将本技能交给你(或指引你到任意 QPB 安装的目标),并说 “Run the Quality Playbook” —— 可能还会附带诸如“这是一次引导运行”或“对自身运行”或“自审计”的提示 —— 本节会明确告诉你该怎么做。操作者无需再提供额外说明;规范调用方式、默认值、护栏以及输出契约都写在这里。

选择你的执行模式

QPB 以两种执行形态发布。选择与你的运行时相匹配的那一种 —— 选错会产生由 2026-04-30 引导测试暴露出的 codex-on-codex 间接性病态。

模式何时适用你你要做什么
A. 技能直连(UI 上下文)你是一个编码 Agent(Claude Code、Cursor、Copilot、Codex desktop 等),在你自己的对话中被交付了本技能。你的运行时本身就是推理循环 —— 你读文件、你写文件、你决策。使用 phase_prompts/ 中外化的阶段提示词,亲自走完 Phase 1 → Phase 6。将产物直接写入目标的 quality/ 目录。无子进程,无 runner。
B. Runner 驱动(CLI 自动化)操作者有意调用 python3 -m bin.run_playbook —— 以便跨多个目标批量执行、驱动无头 CI 运行,或将各阶段工作分派给与阅读本段文字不同的模型。编排器为每个阶段启动一个 CLI Agent(claude、copilot、codex 或 cursor)。你(或任何正在阅读本段文字的人)是操作者侧的控制循环,而不是每阶段的推理者。

两种模式使用相同的阶段提示词内容 —— 仓库根目录下的 phase_prompts/*.md 文件是唯一事实来源,由 bin/run_playbook.py::_load_phase_prompt 加载,并被 Mode A 走查直接读取。两种模式唯一的不同在于由谁驱动 —— 是你(Mode A),还是编排器通过子进程启动一个 CLI Agent(Mode B)。

如有疑问,默认使用 Mode A。 如果操作者想要 runner 驱动的调用,他们会自己运行 runner;如果他们已将“Run the Quality Playbook”粘贴到你的对话中,他们就是想让你来驱动。下面的 Mode B 一节告诉你如果操作者显式调用 runner 时该做什么。

Mode A —— 技能直连走查(UI 上下文)

操作者的提示词只是 “Run the Quality Playbook”(或“对自身运行”、“自审计”等)。你内联驱动每一个阶段。

对于每个阶段 1..6,按顺序:

  1. 加载阶段提示词。 读取 phase_prompts/phaseN.md(通过下文为 references/ 记录的同一安装位置回退列表来解析)。对于 phase1.md,替换 {seed_instruction}(即“跳过 Phase 0/0b”的前导说明 —— 当允许 seeds 时为空字符串)与 {role_taxonomy}(即根据下方角色分类法渲染出的分类块)。对于 phase2.md 到 phase6.md,文件是纯字面量 —— 逐字读取即可。
  2. 按提示词执行该阶段。 读取提示词指定的输入,进行分析,将输出写入目标的 quality/ 目录。
  3. 在阶段结束边界处停止。 每个阶段提示词都以“IMPORTANT: Do NOT proceed to Phase N+1”指令结尾。遵守它。操作者通过明确说明来推进到下一个阶段。

你要负责 —— 在没有编排器结构性兜底的情况下 —— 与 runner 强制执行的相同的源文件不变式:不要修改目标 quality/ 目录之外的任何文件。在 Mode B 中,门禁会捕获此问题;在 Mode A 中,你就是门禁。2026-04-30 引导测试正是在一个 Phase 2 LLM 修改目标根目录 AGENTS.md 时失败 —— 相同的失败模式也适用于 Mode A。

关于 Mode A 的引导运行(自审计)变体,请参见下方“引导模式” —— 唯一差异在于目标就是 QPB 仓库本身,因此引用你读取的相同 phase_prompts/ 文件即可。

Mode A 范围 — 覆盖了什么,什么仅限 Mode B

Council 2026-04-30 P1-3:上面的逐阶段演练将 Mode A 限定为 阶段 1..6。以下接口刻意仅限 Mode B — 如果操作员需要它们,请指向 runner,而不是尝试自己驱动它们:

  • 阶段 0 / 阶段 0b(从先前运行注入种子)。 编排器负责种子发现、先前运行扫描以及种子提示词注入。在 Mode A 中,将每次运行都视为 --no-seeds(完全跳过阶段 0/0b,从阶段 1 开始)。如果操作员明确要求种子驱动的探索,转交给 Mode B(python3 -m bin.run_playbook --with-seeds <target>)。
  • 阶段 7(交互式 Present / Explore / Improve)。 该阶段是与操作员就生成的产物进行来回对话;它在 phase_prompts/ 中没有预先烘焙的提示词。在 Mode A 中,阶段 6 之后,以内联方式展示产物摘要表(文件列表见下文“本次运行产生什么”),让操作员以对话方式驱动接下来探索什么 — 那本身就是阶段 7。没有要启动的编排器子进程。
  • 迭代策略(gap / unfiltered / parity / adversarial)。 迭代会带着策略专属的附录重新进入 playbook。在 Mode A 中,阶段 6 干净完成后,将迭代转交给 Mode B:python3 -m bin.run_playbook --next-iteration --strategy <name> <target>。迭代提示词(phase_prompts/iteration.md)确实是单一事实来源,但迭代编排循环(在 gap → unfiltered → parity → adversarial 之间轮换)是 runner 的职责。在阶段 6 之后想要迭代的 Mode A 操作员应被告知:“阶段 6 已完成;运行 python3 -m bin.run_playbook --full-run <target> 可获得全部四种迭代策略,或用 --next-iteration --strategy gap 明确选择一种策略。”

如果操作员在 Mode A 中请求这些接口之一,且请求含糊不清(例如“也做一下迭代”),请明确暴露模式转交,而不是临场发挥 — 临场发挥正是提示词内容偏离 runner 规范循环的方式。

Mode B — runner 驱动的调用(命令行自动化)

操作员自己运行 python3 -m bin.run_playbook(通常是因为他们想要批处理、无头 CI,或将逐阶段工作路由到不同模型)。位于 bin/run_playbook.py 的编排器会为每个阶段启动一个命令行 Agent,向其提供外置的阶段提示词,并汇总结果。

规范调用

编排器是入口点。始终以 Python 模块方式调用它:

python3 -m bin.run_playbook <target>

切勿以脚本方式调用它(python bin/run_playbook.py ...)。运行时守卫会以 EX_USAGE=64 退出,因为相对导入需要打包执行。

<target> 是要审计的项目的路径。对于引导运行(目标就是 QPB 仓库),从仓库根目录传入 .。对于任何其他目标,传入该目标仓库根目录的路径。

默认行为(无标志)

裸调用会触发完整运行:全部 6 个阶段(Explore → Generate → Code Review → Spec Audit → Reconciliation → Verify),随后是全部 4 种迭代策略(gap → unfiltered → parity → adversarial),在同一会话中同步执行。任何先前的 quality/ 目录都会在新运行开始前自动归档到 quality/previous_runs/<TIMESTAMP>/。

这是规范的操作员路径。不要请求添加标志的许可;默认值就是答案。

当裸调用触发时,编排器会输出一行 stderr 横幅,说明相对于 v1.5.3 的成本变化(约为旧版“仅阶段 1”默认值的 5–10 倍)。该横幅仅供参考;让它滚动过去即可。

常用覆盖选项

仅在操作者提出特定需求时使用:

需求参数效果
只运行单个阶段--phase N(其中 N ∈ 1..6)通过 --phase 1 恢复 v1.5.3 的“仅探索”模式。
跳过迭代策略省略 --iterations 并传入 --phase 1,2,3,4,5,6阶段会运行;迭代不会。
指定迭代--strategy <name> --next-iteration使用所选策略对现有的 quality/ 运行进行迭代。
多目标传入多个位置目标每个目标独立运行。
按阶段指定 CLI Agent--claude / --copilot / --codex / --cursor选择编排器启动哪个 CLI 运行器。默认是 --copilot。v1.5.4 新增了 --cursor 运行器(cursor-cli 3.1+)。
从部分 / 中止的运行器驱动运行中恢复

Council 2026-04-30 P1-4:关于中止运行后清理工作的操作者卫生指南位于下方 Bootstrap 模式 部分(“Bootstrap 运行的操作者卫生”)——该恢复流程在 Mode B 中完全相同:用 git restore quality/ 丢弃部分生成的 Phase 1/2 输出,然后重新调用。请勿编辑 quality/ 之外的文件来“整理”——源不变式会在紧接着的下一次运行中触发。完整机制请参见 Bootstrap 模式的卫生段落;无论中止发生在自我审计运行期间还是针对外部目标,该机制都适用。

Bootstrap 模式(在自身上运行 QPB)

当操作者说“这是一次 bootstrap 运行”或“我们正在对自身运行 QPB”或“自我审计”时:

  1. 确认工作目录是 QPB 仓库根目录(或 cd 到那里)。
  2. 调用 python3 -m bin.run_playbook . —— 同样的规范形式,目标为 .。
  3. 编排器会自动将现有的 quality/ 树归档到 quality/previous_runs/<TIMESTAMP>/;你无需手动清理任何内容。

运行过程与其他目标相同。唯一的区别是审计对象就是 playbook 本身,因此生成的产物描述的是 QPB 自身的质量系统。

Bootstrap 运行的操作者卫生 —— 从部分 / 中止的运行中恢复。 如果先前的 bootstrap 运行中途中止(例如源不变式触发、阶段提示词报错、操作者按下 Ctrl-C),工作树可能包含一个写了一半的 quality/ 目录,以及一个标记被放弃归档的 quality/previous_runs/<TIMESTAMP>/.partial 哨兵文件。在重新调用之前,运行 git restore quality/(并且,如果你想要一个干净的状态,运行 git clean -fd quality/)来丢弃中止运行留下的任何未提交的 Phase 1/2 输出。编排器会重新归档现在处于原始状态的 quality/ 树并重新开始。请勿编辑 quality/ 之外的文件来“整理”——quality/ 之外的任何内容都是 QPB 源代码;为清理而触碰它会在紧接着的下一次运行中触发源不变式。2026-04-30 的 bootstrap 测试暴露了这个确切的恢复问题:操作者有一个因 Phase 2 中止而写了一半的 quality/,并且在没有恢复的情况下重新运行,导致陈旧的 Phase 1 产物残留,干扰了下一次运行的归档。

v1.5.4 机制(指针式,不重复设计文档)

与 v1.5.3 相比的新增内容,以指针形式呈现(规范架构位于 docs/design/QPB_v1.5.4_Design.md 第 1 部分):

  • 阶段 1 生成 quality/exploration_role_map.json —— 在探索期间由 AI 驱动的逐文件角色标注。每个范围内文件都会从分类法中获得一个角色(skill-prose、skill-reference、skill-tool、code、test、docs、config、fixture、formal-spec、playbook-output)。角色映射驱动所有下游流水线激活决策。
  • INDEX.md 使用 schema_version: "2.0",并带有 target_role_breakdown 字段,承载每个角色的计数和百分比。v1.5.3 的 target_project_type 枚举已退役(旧归档仍可读取)。
  • 流水线根据角色映射激活,而不是根据项目类型标签。 四遍技能派生流水线运行在标记为 skill-prose / skill-reference 的文件上。代码审查流水线运行在标记为 code 的文件上。散文到代码分歧检查运行在标记为 skill-tool 的文件上。当角色映射显示某个角色数量为零时,该流水线会干净地空操作。不存在 Code/Skill/Hybrid 三分法 —— 当两种表面都存在时,两条流水线都会运行(“始终为 Hybrid 下游”模型)。
  • 归档目录为 quality/previous_runs/(在 v1.5.3 中为 quality/runs/);旧路径下的旧归档仍可读取。
  • 阶段 6 结束时的重组会将中间产物移动到 quality/workspace/ 下,因此顶层 quality/ 目录主要由规范交付物(REQUIREMENTS.md、BUGS.md 等)占据。门禁的路径解析器会从两种布局中读取。

你不需要在提示词侧推理中重新推导其中任何内容;编排器的提示词已经对其进行了编码。如果你遇到与本概要架构冲突的阶段提示词,请遵循该阶段提示词 —— 它是各阶段契约的规范来源。

护栏(可机器校验;视为硬性约束)

这些不是建议;编排器会强制执行它们,违反会导致本次运行中止:

  1. 同步执行——不得委派给子 Agent。 每个阶段都由你在同一会话中亲自运行。不要使用 Task 工具、子 Agent 派发、后台 Agent 调用,或任何“把阶段 2–6 委派给 worker”的模式。B-15 失败模式是真实存在的:阶段 1 完成,阶段 2–6 在委派的 Agent 中悄无声息地失败,该 Agent 丢失了父会话,运行器自行标记为 -PARTIAL,而操作员收不到任何出错的信号。v1.5.4 的提示词明确禁止这种做法。
  2. 不要在运行中途修补 QPB 源码。 如果你在运行期间遇到 bin/、.github/skills/、agents/、references/、SKILL.md、schemas.md 或 AGENTS.md 中的 bug,停下来并报告:指出 文件:行号,描述失败情况,提出修复方案的思路——但不要应用修复。编排器会在运行开始时捕获 git-SHA 基线,并在每个阶段边界验证源码树未发生变化;自主修补会使该关卡失败,并附带一份列出被修改文件的诊断信息。修补要经过 Council 评审,而不是在运行中途即兴进行。
  3. 不要删除哨兵文件。 受 .gitignore ! 规则保护的文件(例如 reference_docs/.gitkeep、reference_docs/cite/.gitkeep)用于保持原本为空的已跟踪目录存在。预检会枚举每一条 ! 规则,若有任何哨兵文件缺失就会中止。如果你发现此类文件但不明白其用途,别动它。
  4. 阶段 1 的文件枚举使用 git ls-files。 当目标是 git 仓库时,使用 git ls-files 作为规范的文件列表;这样会自动遵循 .gitignore。不要使用 os.walk、find、os.listdir 或任何递归目录遍历器——这些会拉入 .git/、.venv/、node_modules/、构建产物和 vendored 依赖,而角色映射校验器会拒绝所有这些内容。不允许的路径前缀包括 .git/、.venv/、venv/、node_modules/、__pycache__/、.pytest_cache/、.mypy_cache/、.ruff_cache/、.tox/,以及任何其路径组成部分以 .egg-info 或 .dist-info 结尾的路径。角色映射带有一个 provenance 字段,记录你使用的枚举来源("git-ls-files",或对非 git 目标使用 "filesystem-walk-with-skips")。还有一个 2000 条目的上限;超过该上限的角色映射几乎肯定遍历了被 .gitignore 忽略的内容。
  5. 跨产物一致性。 EXPLORATION.md 的“File inventory”部分和角色映射的 summary 字段都从 bin.role_map.summarize_role_map() 渲染而来。不要手写文件数量或角色百分比;从该辅助函数复制。校验器会交叉核对这两者,并拒绝不一致的情况。

如果操作员的提示词与这些护栏相冲突(例如“把阶段 3–6 委派给子 Agent,这样我们能跑得更快”),不要遵从这条冲突的指令。指出这一冲突,说明对应的护栏,并请求澄清。这些护栏之所以存在,是因为每一条都对应一种已被验证的历史失败模式。

本次运行产出什么 — 输出工件契约

一次成功的运行会在目标的 quality/ 目录下生成以下规范文件集,并在目标的仓库根目录下生成一个 AGENTS.md。此处列出的每个文件都经过门禁校验:

路径作用
quality/EXPLORATION.md阶段 1 发现 — 基础。
quality/exploration_role_map.json阶段 1 的逐文件角色标记。
quality/REQUIREMENTS.md带用例的可测试需求。
quality/QUALITY.md质量宪章。
quality/CONTRACTS.md行为契约。
quality/COVERAGE_MATRIX.md需求 → 测试可追溯性。
quality/COMPLETENESS_REPORT.md最终门禁判定。
quality/test_functional.*自动化功能测试。
quality/RUN_CODE_REVIEW.md三遍代码审查协议。
quality/RUN_INTEGRATION_TESTS.md集成测试协议。
quality/RUN_SPEC_AUDIT.md三人委员会规格审计协议。
quality/RUN_TDD_TESTS.mdTDD 红绿验证协议。
quality/BUGS.md汇总缺陷报告。
quality/INDEX.md运行元数据 + 角色拆分 + 门禁判定。
quality/PROGRESS.md逐阶段检查点日志。
quality/previous_runs/<TIMESTAMP>/任何先前运行的归档。
quality/workspace/中间流水线工件(控制提示词、代码审查、规格审计、四遍流水线输出等)。
AGENTS.md(目标仓库根目录)阶段 6 之后生成的逐项目导引。带有 QPB 哨兵标记,以便未来运行检测到 QPB 管理的副本。

quality/INDEX.md 中的门禁判定(pass / partial / fail)是面向操作者的运行结果摘要。如果它不是 pass,请在认为运行完成之前说明原因。

定位参考文件

本技能引用 references/ 目录中的文件(例如 references/iteration.md、references/review_protocols.md)。位置取决于技能的安装方式。当提到某个参考文件时,按顺序检查以下路径,并使用第一个存在的路径:

  1. references/(相对于 SKILL.md — 从技能目录运行时有效)
  2. .claude/skills/quality-playbook/references/(Claude Code 安装)
  3. .github/skills/references/(GitHub Copilot 扁平安装)
  4. .github/skills/quality-playbook/references/(备用 Copilot 安装)

本技能中所有参考文件的提及均使用简写形式 references/filename.md。如果相对路径无法解析,请按上述回退列表逐一查找。

为什么需要这个

大多数软件项目都有测试,但很少有质量体系。测试检查代码是否能运行。质量体系回答更难的问题:对于这个特定项目,“正确运行”意味着什么?它可能以哪些测试无法捕获的方式失败?每个开发者(人类或 AI)在接触这段代码之前应该知道什么?

没有质量手册,每个新贡献者(以及每个新的 AI 会话)都从零开始 — 猜测什么重要,编写看起来不错但抓不到真实缺陷的测试,并重新发现几个月前已经找到并修复的失效模式。质量手册让标准变得明确、持久且可继承。

这项技能产出什么

九个文件共同构成一套可重复的质量体系:

文件用途为何重要是否执行代码?
quality/QUALITY.md质量宪法——覆盖率目标、适用性场景、防表演措施每次 AI 会话都先读这个。它告诉它们「足够好」意味着什么,这样它们就不会瞎猜。否
quality/REQUIREMENTS.md可测试的需求,包含项目概述、用例和叙述——由五阶段流水线生成(契约提取 → 推导 → 验证 → 完整性 → 叙述)代码审查第 2 遍和第 3 遍的基础。没有需求,审查就只能局限于结构异常(约 65% 的上限)。有了需求,审查就能捕捉意图违规——缺失缺陷、跨文件矛盾,以及仅靠读代码看不见的设计缺口。否
quality/test_functional.*从规格推导出的自动化功能测试安全网。测试与规格所述应该发生的事绑定,而不只是与代码实际做的事绑定。使用项目的语言:test_functional.py(Python)、FunctionalSpec.scala(Scala)、functional.test.ts(TypeScript)、FunctionalTest.java(Java)等。是
quality/RUN_CODE_REVIEW.md三遍代码审查协议:结构审查、需求验证、跨需求一致性仅靠结构审查会漏掉约 35% 的真实缺陷。三遍流水线增加了需求验证和一致性检查——并有实验证据支持,表明它能发现所有结构审查条件下都看不见的 bug。否
quality/RUN_INTEGRATION_TESTS.md集成测试协议——跨所有变体的端到端流水线单元测试通过了,但系统接入真实外部服务后真能端到端跑通吗?是
quality/BUGS.md合并的 bug 报告,附补丁每个已确认的 bug 都集中在一处,附复现细节、规格依据、严重程度和补丁引用。这是关于什么坏了以及如何验证的唯一事实来源。否
quality/RUN_TDD_TESTS.mdTDD 红绿验证协议证明每个 bug 都是真实的(测试在未打补丁的代码上失败),以及每个修复都有效(打补丁后测试通过)。比单独的 bug 报告更有力——维护者信任 FAIL→PASS 演示。是
quality/RUN_SPEC_AUDIT.md三人委员会多模型规格审计协议没有任何单一 AI 模型能捕捉一切。三个独立模型各有不同的盲点,能捕捉任何一个单独模型都会漏掉的缺陷。否
AGENTS.md任何在本项目上工作的 AI 会话的引导上下文「先读这个」文件。没有它,AI 会话会浪费第一个小时去弄清发生了什么。否

外加输出目录:quality/code_reviews/、quality/spec_audits/、quality/results/、quality/history/。

该流水线还会生成辅助产物:quality/PROGRESS.md(逐阶段检查点日志,带累计 BUG 跟踪器)、quality/CONTRACTS.md(行为契约)、quality/COVERAGE_MATRIX.md(可追溯性)、quality/COMPLETENESS_REPORT.md(最终关卡)和 quality/VERSION_HISTORY.md(审查日志)。第 7 阶段还可额外生成 quality/REVIEW_REQUIREMENTS.md(交互式审查协议)和 quality/REFINE_REQUIREMENTS.md(精炼遍协议),用于迭代改进。

两个关键交付物是需求文件和功能测试文件。需求文件(quality/REQUIREMENTS.md)为代码审查协议的验证和一致性遍提供输入——正是它让代码审查能捕捉到超出结构异常的内容。功能测试文件(按项目语言和测试框架惯例命名)是自动化安全网。Markdown 协议是给人以及 AI Agent 看的文档。

完整产物契约

质量门禁(quality_gate.py)会校验这些产物。如果门禁会检查它,本技能就必须指示创建它。这是权威列表 —— 任何未在此列出的产物都不应被门禁强制要求,任何门禁检查都应可追溯到此处列出的某个产物。

产物位置是否必需?创建于
正式文档清单(v1.5.3)quality/formal_docs_manifest.json是阶段 1(bin/reference_docs_ingest.py)
需求清单(v1.5.3)quality/requirements_manifest.json是阶段 2
用例清单(v1.5.3)quality/use_cases_manifest.json是阶段 2
Bug 清单(v1.5.3)quality/bugs_manifest.json如果发现 bug阶段 3/4/5
引用语义检查(v1.5.3)quality/citation_semantic_check.json是阶段 4(Layer 2 Council)
探索发现quality/EXPLORATION.md是阶段 1
质量章程quality/QUALITY.md是阶段 2
需求(UC 标识符)quality/REQUIREMENTS.md是阶段 2
行为契约quality/CONTRACTS.md是阶段 2
功能测试quality/test_functional.*是阶段 2
回归测试quality/test_regression.*如果发现 bug阶段 3
代码审查协议quality/RUN_CODE_REVIEW.md是阶段 2
集成测试协议quality/RUN_INTEGRATION_TESTS.md是阶段 2
规范审计协议quality/RUN_SPEC_AUDIT.md是阶段 2
TDD 验证协议quality/RUN_TDD_TESTS.md是阶段 2
Bug 跟踪器quality/BUGS.md是阶段 3
覆盖率矩阵quality/COVERAGE_MATRIX.md是阶段 2
完整性报告quality/COMPLETENESS_REPORT.md是阶段 2(基线),阶段 5(最终判定)
进度跟踪器quality/PROGRESS.md是全程
AI 引导文件AGENTS.md(目标仓库根目录)是由编排器在阶段 6 后生成 —— 不是阶段 2 的交付物
Bug 分析报告quality/writeups/BUG-NNN.md如果发现 bug阶段 5
回归补丁quality/patches/BUG-NNN-regression-test.patch如果发现 bug阶段 3
修复补丁quality/patches/BUG-NNN-fix.patch可选阶段 3
TDD 可追溯性quality/TDD_TRACEABILITY.md如果 bug 有 red-phase 结果阶段 5
TDD sidecarquality/results/tdd-results.json如果发现 bug阶段 5
TDD red-phase 日志quality/results/BUG-NNN.red.log如果发现 bug阶段 5
TDD green-phase 日志quality/results/BUG-NNN.green.log如果存在修复补丁阶段 5
集成 sidecarquality/results/integration-results.json当运行集成测试时阶段 5
机械验证脚本quality/mechanical/verify.sh是(基准测试)阶段 2
验证回执quality/results/mechanical-verify.log + .exit是(基准测试)阶段 5
分诊探针quality/spec_audits/triage_probes.sh当运行分诊时阶段 4
代码审查报告quality/code_reviews/*.md是阶段 3
规范审计报告quality/spec_audits/*auditor*.md + *triage*是阶段 4
复检结果(JSON)quality/results/recheck-results.json当运行复检时复检
复检摘要(MD)quality/results/recheck-summary.md当运行复检时复检
种子检查quality/SEED_CHECKS.md如果运行了阶段 0b阶段 0b
运行元数据quality/results/run-YYYY-MM-DDTHH-MM-SS.json是阶段 1(创建),全程(更新)

Sidecar JSON 生命周期: 在最终确定 tdd-results.json 之前 写入所有 bug 分析报告 —— sidecar 的 writeup_path 字段必须指向一个已存在的文件,而不是占位符。同样,在写入 integration-results.json 之前运行集成测试并收集结果。

Sidecar JSON 规范示例

quality/results/tdd-results.json — 门禁会校验字段名,而不仅仅是字段是否存在:

{
  "schema_version": "1.1",
  "skill_version": "1.5.6",
  "date": "2026-04-12",
  "project": "repo-name",
  "bugs": [
    {
      "id": "BUG-001",
      "requirement": "REQ-003",
      "red_phase": "fail",
      "green_phase": "pass",
      "verdict": "TDD verified",
      "fix_patch_present": true,
      "writeup_path": "quality/writeups/BUG-001.md"
    }
  ],
  "summary": {
    "total": 3, "confirmed_open": 1, "red_failed": 0, "green_failed": 0, "verified": 2
  }
}

verdict 必须是以下之一:"TDD verified"、"red failed"、"green failed"、"confirmed open"、"deferred"。date 必须是 ISO 8601 格式(YYYY-MM-DD),不能是占位符,也不能是未来日期。

quality/results/integration-results.json:

{
  "schema_version": "1.1",
  "skill_version": "1.5.6",
  "date": "2026-04-12",
  "project": "repo-name",
  "recommendation": "SHIP",
  "groups": [{ "group": 1, "name": "Group 1", "use_cases": ["UC-01"], "result": "pass", "tests_passed": 3, "tests_failed": 0, "notes": "" }],
  "summary": { "total_groups": 12, "passed": 11, "failed": 1, "skipped": 0 },
  "uc_coverage": { "UC-01": "covered_pass", "UC-02": "not_mapped" }
}

recommendation 必须是以下之一:"SHIP"、"FIX BEFORE MERGE"、"BLOCK"。uc_coverage 将 REQUIREMENTS.md 中的 UC 标识符映射到覆盖状态。

运行元数据

每次 playbook 运行都会在 quality/results/run-YYYY-MM-DDTHH-MM-SS.json 创建一个带时间戳的元数据文件。这支持多模型对比和运行历史追踪。

生命周期: 在阶段 1 开始时创建此文件。在每个阶段完成后更新 phases_completed、bug_count 和 end_time。最后一次更新发生在终端门禁之后。

{
  "schema_version": "1.0",
  "skill_version": "1.5.6",
  "project": "repo-name",
  "model": "claude-sonnet-4-6",
  "model_provider": "anthropic",
  "runner": "claude-code",
  "start_time": "2026-04-16T10:30:00Z",
  "end_time": "2026-04-16T11:45:00Z",
  "duration_minutes": 75,
  "phases_completed": ["Phase 0b", "Phase 1", "Phase 2", "Phase 3", "Phase 4", "Phase 5"],
  "iterations_completed": ["gap", "unfiltered", "parity", "adversarial"],
  "bug_count": 12,
  "bug_severity": { "HIGH": 2, "MEDIUM": 5, "LOW": 5 },
  "gate_result": "PASS",
  "gate_fail_count": 0,
  "gate_warn_count": 2,
  "notes": ""
}

必填字段: schema_version、skill_version、project、model、start_time。所有其他字段会随着运行进展而填充。model 应为确切的模型字符串(例如 "claude-sonnet-4-6"、"gpt-4.1"、"claude-opus-4-6")。runner 标识用于执行 playbook 的工具(例如 "claude-code"、"copilot-cli"、"cursor"、"cowork")。duration_minutes 由 end_time - start_time 计算得出。如果无法确定模型或 runner,请使用 "unknown"。

如何使用

该 playbook 设计为一次运行一个阶段。 每个阶段都在自己的会话中运行,拥有干净的上下文窗口,并生成供下一阶段读取的磁盘文件。这比一次性运行所有阶段效果要好得多 — 每个阶段都能获得完整的上下文窗口进行深入分析,而不必与其他阶段争夺空间。

默认行为:仅运行阶段 1。 当有人说"运行质量 playbook"或"执行质量 playbook"时,运行阶段 1(探索)然后停止。阶段 1 完成后,告诉用户发生了什么以及接下来该说什么。由用户明确推动每个阶段向前推进。

交互式协议 — 如何引导用户

在每个阶段和每次迭代之后,都要停下来并打印指引。 使用 # 标题,使其在聊天中醒目突出。指引必须包含:刚刚发生了什么(一行说明)、关键产出是什么,以及用于继续的准确提示词。请参见下方各阶段小节之后定义的阶段结束消息。

如果用户说“继续”“接着来”“下一阶段”“下一个”或任何类似表述,就按顺序运行下一个阶段。如果所有阶段都已完成,就建议第一个迭代策略(gap)。如果刚刚完成一次迭代,就建议推荐循环中的下一个策略。

如果用户说“运行所有阶段”“全部运行”或“运行完整流水线”,就在单个会话中按顺序运行所有阶段。这会消耗更多上下文,但有些用户更喜欢这样。

如果用户问“帮助”“这是怎么工作的”“这是什么”或任何类似措辞,就用以下说明回应(自然地调整措辞,不要逐字照抄):

Quality Playbook 能发现仅靠结构化代码审查无法捕捉的 bug — 即那些需要理解代码本应做什么才能发现的 35% 真实缺陷。它按阶段推进:

  • 阶段 1(探索): 理解代码库 — 架构、风险、故障模式、规格说明
  • 阶段 2(生成): 产出质量工件 — 需求、测试、审查协议
  • 阶段 3(代码审查): 三遍审查,并为每个已确认的 bug 提供回归测试
  • 阶段 4(规格审计): 三名独立的 AI 审计员对照需求检查代码
  • 阶段 5(对账): 闭环处理 — 为每个 bug 进行 TDD 红绿验证
  • 阶段 6(验证): 自检基准验证所有生成的工件

编号阶段完成后,你可以运行迭代策略(gap、unfiltered、parity、adversarial)来发现更多 bug — 迭代通常会在基线之上额外增加 40-60% 的已确认 bug。

当你在提供代码的同时也提供文档 — 规格说明、API 文档、设计文档、社区文档 — 时,这个 playbook 效果最好。此外,当你分开运行每个阶段而不是一次性全部运行时,它也能取得明显更好的结果。

要开始使用,请说:“在这个项目上运行 quality playbook。”

如果用户问“发生了什么”“现在是什么情况”“我们进行到哪了”或“我接下来该做什么”,请阅读 quality/PROGRESS.md,并向他们提供简洁的状态更新:哪些阶段已完成、目前发现了多少 bug,以及下一步是什么。

文档警告

在阶段 1 开始时,在探索任何代码之前,先检查是否有文档。 查找名为 docs/、reference_docs/、doc/、documentation/ 的目录,或任何收集到的文档文件。还要检查用户是否在他们的提示词中提到了文档。

如果未找到文档,立即打印此警告(在继续之前):

重要:未找到项目文档。 quality playbook 在没有文档的情况下也能工作,但当你提供规格说明、API 文档、设计文档或社区文档时,它能发现明显更多的 bug — 以及置信度更高的 bug。在受控实验中,文档增强的运行发现了与仅代码基线不同且更好的 bug。

如果你有可用的文档,可以将其添加到 reference_docs/ 目录中,然后重新运行阶段 1。否则,我将继续仅基于代码进行分析。

然后继续阶段 1 — 不要因此阻塞,只需确保用户看到该警告。

运行特定阶段

用户可以请求任意单个阶段:

Run quality playbook phase 1.
Run quality playbook phase 3 — code review.
Run phase 5 reconciliation.

在运行特定阶段时,检查其前置条件是否存在(例如,阶段 3 需要阶段 2 的工件)。如果前置条件缺失,请告诉用户需要先运行哪些阶段。

迭代模式 — 在之前运行的基础上改进

当已存在之前的 playbook 运行,并且你希望找出更多 bug 时,请使用此模式。迭代模式用五种策略之一的定向探索取代 Phase 1 的从零开始探索,然后将发现结果与之前的运行合并,并针对合并后的结果重新运行 Phase 2–6。

**何时使用迭代模式:**在一次完整的 playbook 运行之后,当你认为代码库中的 bug 比第一次运行发现的更多时。这对于单次运行只能覆盖 3–5 个子系统的大型代码库尤其有效,也适用于库/框架代码库,因为不同的探索路径会发现不同类别的 bug。

**阅读 references/iteration.md 获取详细的策略说明。**该文件包含每种策略的完整操作细节、共享规则、合并步骤以及完成门禁。下面的摘要描述了何时使用每种策略。

**TDD 适用于迭代运行。**迭代运行中每一个新确认的 bug 都必须经过完整的 TDD 红-绿循环,并生成 quality/results/BUG-NNN.red.log(如果存在修复补丁,还要生成 .green.log)。质量门禁会强制执行这一点 — 缺少日志会导致 FAIL。参见 references/iteration.md 共享规则 5 以及 Phase 5 中的 TDD Log Closure Gate。

**迭代策略。**用户通过在提示词中指定策略名称来选择策略。如果没有指定策略,则默认为 gap。

Run the next iteration of the quality playbook.                          # default: gap strategy
Run the next iteration of the quality playbook using the gap strategy.
Run the next iteration using the unfiltered strategy.
Run the next iteration using the parity strategy.
Run an iteration using the adversarial strategy.

**推荐的循环:**gap → unfiltered → parity → adversarial。每种策略会发现不同类别的 bug:

  • gap(默认)— 扫描之前的覆盖情况,探索未覆盖的子系统以及覆盖薄弱的部分。当第一次运行在结构上合理但只覆盖了代码库的一个子集时效果最佳。
  • unfiltered — 纯领域驱动的探索,不带任何结构性约束。没有模式模板、没有适用性矩阵、没有章节格式要求。可找回被结构化探索抑制的 bug。
  • parity — 系统地枚举同一契约的并行实现(传输变体、回退链、setup-vs-reset 路径),并对它们进行差异比较以找出不一致之处。可发现只有通过跨路径比较才会出现的 bug。
  • adversarial — 重新调查被驳回/降级的分诊发现,并质疑薄弱的 SATISFIED 判定。可找回保守分诊导致的 Type II 错误。
  • all — Runner 层面的便捷选项:按顺序执行 gap → unfiltered → parity → adversarial,每个都作为单独的 Agent 会话。如果某个策略发现的 bug 为零,则提前停止。
逐阶段执行

每个阶段都会在磁盘上生成文件,供下一阶段读取。这正是上下文在各阶段之间传递的方式——通过文件,而不是通过对话历史。关键交接文件包括:

  • quality/EXPLORATION.md — 阶段 1 写入,阶段 2 读取。其中包含阶段 2 生成产物所需的一切内容,无需重新探索代码库。
  • quality/PROGRESS.md — 在每个阶段之后更新。累积的 BUG 跟踪器确保任何发现都不会丢失。
  • 生成的产物(REQUIREMENTS.md、CONTRACTS.md 等)— 阶段 2 写入这些文件,阶段 3–5 读取它们来执行审查、审计和对账。

每个阶段边界的模式是:完成当前阶段,将所有内容写入磁盘,然后打印阶段结束消息并停止。当用户启动下一阶段时,先读回所需的文件,然后再继续。这种“先写后读”的循环就是阶段边界——例如,它让你在加载审查上下文之前,先从工作记忆中丢弃探索上下文。

在继续之前,将你的阶段 1 探索发现写入 quality/EXPLORATION.md。此文件在所有模式下都是必需的。要写得详尽:领域识别、架构图、现有测试、规范摘要、质量风险、骨架/调度分析、派生需求(REQ-NNN)以及派生的用例(UC-NN)。阶段 2 生成产物所需的一切都必须在此文件中。

将探索发现写入磁盘这一纪律,正是它迫使进行彻底分析。如果没有它,模型会在工作记忆中保留模糊印象,并生成宽泛、抽象的需求,从而漏掉函数级缺陷。写作迫使具体化:文件路径、行号、确切的函数名、具体的行为规则。这种具体化正是让需求足够精确、从而在代码审查期间捕获 bug 的原因。


运行状态埋点(v1.5.6 — 边走边写事件)

quality/ 中的两个文件通过文件系统跟踪本次运行的状态,使运行在飞行中可观测、在崩溃后可恢复、在事后可审计。在整个运行过程中维护这两个文件。

  • quality/run_state.jsonl — 仅追加的机器可读事件日志。每行一个 JSON 对象。编排器和任何监控器读取此文件,以准确了解运行所处的位置。
  • quality/PROGRESS.md — 人类可读的状态文件,在每个事件时以原子方式重写。

权威模式: references/run_state_schema.md。在运行开始时读取一次;它定义了完整的事件分类、必需字段、交叉验证规则以及 PROGRESS.md 格式。

初始化(在任何阶段工作之前,包括阶段 0)

如果 quality/run_state.jsonl 不存在:

  1. 如果 quality/ 不存在,则创建它。
  2. 将 _index 事件追加到 quality/run_state.jsonl。必需字段:event=_index、ts(带 Z 的 ISO 8601 UTC)、schema_version="1.5.6"、event_types(列出本次运行将使用的所有事件类型的数组——至少包括 _index、run_start、phase_start、pattern_walked、pass_started、pass_ended、finding_logged、artifact_written、gate_check、phase_end、error、run_end)、benchmark(目标名称)、lever_state(例如正常运行时为 "baseline")、started_at。
  3. 追加 run_start 事件。必需字段:event=run_start、ts、runner(claude/codex/copilot/cursor 之一)、playbook_version(从 SKILL.md frontmatter 的 version 字段读取)、target_path。
  4. 按照 references/run_state_schema.md 中的格式规范写入 quality/PROGRESS.md。包括页眉(Started / Benchmark / Lever / Runner / Playbook version)、包含全部六个阶段的空阶段清单、空的 Recent events / Artifacts produced 部分。

如果在运行开始时 quality/run_state.jsonl 已存在:这是一次恢复运行。请参见下方的“恢复语义”。

各阶段事件

在每个阶段边界(1 到 6),写入事件:

  • 阶段开始时: 向 quality/run_state.jsonl 追加 {"event":"phase_start","ts":"<now>","phase":N}。更新 quality/PROGRESS.md:将阶段 N 标记为进行中,并附上当前时间戳。
  • 阶段结束时: 首先交叉验证该阶段预期的产物(见下表)。若验证失败,追加 {"event":"error","ts":"<now>","phase":N,"message":"<what's missing>","recoverable":true} 并重新运行该阶段。若验证通过,追加 {"event":"phase_end","ts":"<now>","phase":N,"key_counts":{...},"artifacts_produced":[...]}。更新 PROGRESS.md:勾选阶段 N 并附上统计摘要。

阶段 1 子事件(除 phase_start/phase_end 之外):

  • 走查七种探索模式中的每一种之后:追加 {"event":"pattern_walked","ts":"<now>","phase":1,"pattern":N,"findings_count":K}。(每种模式一个事件,即使发现数为零。)
  • 写入 quality/EXPLORATION.md 时:追加 {"event":"artifact_written","ts":"<now>","relative_path":"quality/EXPLORATION.md","byte_size":<size>,"line_count":<lines>}。

阶段 4 子事件:

  • 每轮开始时(A 到 D):{"event":"pass_started","ts":"<now>","phase":4,"pass":"A"}。
  • 每轮结束时:{"event":"pass_ended","ts":"<now>","phase":4,"pass":"A","output_artifact":"<path>"}。

阶段 5 / 阶段 6 子事件:

  • 每次门禁检查完成时:{"event":"gate_check","ts":"<now>","gate_name":"<name>","verdict":"pass|fail|warn|skip","reason":"<short>"}。

运行结束:

  • 在阶段 6 的 phase_end 之后:追加 {"event":"run_end","ts":"<now>","status":"success","total_findings":<N>,"final_verdict":"<gate verdict>"}。对于 recoverable:false 的失败,状态为 aborted;对于不可恢复的运行时错误,状态为 failed。
phase_end 处的交叉验证规则

在写入每个 phase_end 事件之前,验证对应的产物:

阶段必需项
1quality/EXPLORATION.md 和 quality/PROGRESS.md 满足 SKILL.md:1257-1273 中记录的 13 项检查阶段 1 门禁(六个必需标题:## Open Exploration Findings、## Quality Risks、## Pattern Applicability Matrix、## Pattern Deep Dive — * ×3+、## Candidate Bugs for Phase 2、## Gate Self-Check;PROGRESS 阶段 1 行标记为 [x];≥8 个发现且带有 file:line 引用;≥3 个多位置发现;3-4 行 FULL 模式矩阵;≥2 个多函数模式深入分析;候选缺陷来源组合中 ≥2 个来自 exploration/risks 且 ≥1 个来自模式深入分析)。bin/run_state_lib.validate_phase_artifacts(quality_dir, phase=1) 强制执行完整的门禁。
2全部九个 Generate 合约产物在 quality/ 下存在且非空:REQUIREMENTS.md、QUALITY.md、CONTRACTS.md、COVERAGE_MATRIX.md、COMPLETENESS_REPORT.md、RUN_CODE_REVIEW.md、RUN_INTEGRATION_TESTS.md、RUN_SPEC_AUDIT.md、RUN_TDD_TESTS.md。另加至少一个非空的 quality/test_functional.<ext>(扩展名因语言而异)。
3quality/RUN_CODE_REVIEW.md 存在
4quality/REQUIREMENTS.md 非空且 quality/COVERAGE_MATRIX.md 存在。如果四轮 skill 派生流水线运行过(即 quality/phase3/ 存在),则 quality/phase3/pass_a_drafts.jsonl、quality/phase3/pass_b_citations.jsonl、quality/phase3/pass_c_formal.jsonl 以及 quality/phase3/ 下的 Pass D 收件箱都必须存在且非空。
5quality/results/quality-gate.log 存在且非空
6quality/BUGS.md 非空且具有 ^##\s+BUG- 章节,并且 quality/INDEX.md 已更新且带有 gate_verdict 字段

如果某项检查失败,追加 error 事件(recoverable=true)并重新运行该阶段。不要针对缺失的产物写入 phase_end——这正是 v1.5.6 旨在捕获的失败模式。

bin/run_state_lib.validate_phase_artifacts(quality_dir, phase) 以编程方式执行这些检查——如果可用,请在 playbook 会话内部调用它。

恢复语义

如果 playbook 启动时 quality/run_state.jsonl 已存在(上一次会话在运行中崩溃或暂停):

  1. 读取所有事件。使用 bin/run_state_lib.last_in_progress_phase(events) 找到最后一个后面没有匹配 phase_end 的 phase_start —— 称之为进行中的阶段。
  2. 对该阶段运行上述交叉验证规则。
    • 产物完整: 上一次会话完成了工作,但没来得及写入 phase_end。追加缺失的 phase_end(使用当前 ts),然后继续下一个阶段。
    • 产物不完整: 从头重新运行该阶段。
  3. 如果六个 phase_end 事件都存在但没有 run_end:追加 run_end status=success 并收尾。
  4. 如果不存在 quality/run_state.jsonl:全新运行。按上一节所述进行初始化。

策略:更信任产物,而不是事件。 如果事件声称阶段 4 已完成,但 REQUIREMENTS.md 不存在,就重新运行阶段 4。如果事件在阶段中途停止,但产物完整,就补齐事件。

PROGRESS.md 原子重写

PROGRESS.md 在每次事件时重写(而不是追加)。内容反映当前的 run-state.jsonl:头部(运行元数据)、阶段检查清单(含每个已完成阶段的汇总统计、当前阶段的进行中标记)、最近事件(JSONL 日志中最近 10 个事件,以人类可读形式)、已产出的产物(本次运行写入的文件及其字节大小)。确切格式模板见 references/run_state_schema.md。

bin/run_state_lib.write_progress_md(quality_dir, events, current_phase) 会根据事件列表生成格式正确的 PROGRESS.md —— 在每次事件后调用它,以保持文件同步。


阶段 0:先前运行分析(自动)

仅当 quality/previous_runs/ 存在且包含先前的质量产物时,本阶段才会运行。 如果没有先前的运行,请跳到阶段 1。如果 quality/previous_runs/ 存在但为空,或不包含符合规范的质量产物(其下没有带 quality/BUGS.md 的子目录),请跳过阶段 0a,直接进入阶段 0b。(位于 quality/runs/ 的旧版归档来自 v1.5.4 之前,出于向后兼容仍可读取——参见 SKILL.md:149——但规范的归档根目录是 quality/previous_runs/。)

当存在先前运行时,playbook 进入续跑模式。这支持迭代式缺陷发现:每次运行都会继承先前运行中已确认的发现,以机械方式验证它们,并探索其他缺陷。当某次运行发现零个净新增缺陷时,迭代收敛。

步骤 0a:构建种子列表。 从所有先前运行中读取 quality/previous_runs/*/quality/BUGS.md。对于每个已确认的缺陷,提取:缺陷 ID、file:line、摘要以及回归测试断言。按 file:line 去重(同一缺陷在多次运行中被发现只计一次)。将合并后的种子列表写入 quality/SEED_CHECKS.md,格式如下:

## Seed Checks (from N prior runs)

| Seed | Origin Run | File:Line | Summary | Assertion |
|------|-----------|-----------|---------|-----------|
| SEED-001 | run-1 | virtio_ring.c:3509-3529 | RING_RESET dropped | `"case VIRTIO_F_RING_RESET:" in func` |

步骤 0b:以机械方式执行种子检查。 对于每个种子,针对当前源码树运行断言。记录 PASS(自上次运行以来缺陷已修复)或 FAIL(缺陷仍然存在)。失败的种子是已确认的结转缺陷——无论是否有审计员独立发现它,它都必须出现在本次运行的 BUGS.md 中。通过的种子意味着缺陷已修复——在 PROGRESS.md 中记录为 "SEED-NNN: resolved since prior run."

步骤 0c:识别先前运行的范围。 读取 quality/previous_runs/*/quality/PROGRESS.md 中的范围声明。记录先前运行覆盖了哪些子系统。在阶段 1 探索期间,优先考虑先前运行未覆盖的区域,以最大化发现新缺陷的机会。如果所有子系统都已在先前运行中覆盖,则探索相同范围但采用不同的侧重(例如,不同的审查领域、不同的入口点)。

步骤 0d:将种子注入下游阶段。 种子列表成为以下阶段的输入:

  • 阶段 3(代码审查): 在代码审查提示词中添加:"先前运行已确认这些缺陷——验证它们是否仍然存在,并在同一子系统中寻找其他发现。"
  • 阶段 4(规范审计): 在 RUN_SPEC_AUDIT.md 中添加:"先前运行中的已知未解决问题:[种子列表]。预期审计员会发现这些问题。如果某位审计员没有标记某个已知种子缺陷,那是他们审查中的覆盖缺口,而不是该缺陷已修复的证据。"

为什么存在这一阶段: 非确定性的范围探索意味着不同的运行会注意到不同的缺陷。在跨版本测试中,8 个仓库中有 4 个的缺陷在某些版本中被发现、在另一些版本中未被发现——不是因为缺陷被修复了,而是因为模型探索了代码库的不同部分。通过种子注入进行迭代解决了这个问题:已确认的缺陷以机械方式结转(无需重新发现),每次新的运行都可以将探索聚焦于未覆盖的领域。

阶段 0b:同级运行种子发现(自动)

仅当 quality/previous_runs/ 不存在,或 quality/previous_runs/ 存在但不包含符合规范的质量产物时(即阶段 0a 无从下手)且项目目录已版本化(例如 httpx-1.3.23/ 与 httpx-1.3.21/ 并列存放)**时,这一步才会运行。如果 quality/previous_runs/ 存在且包含符合规范的产物,阶段 0a 已经处理了种子注入——跳过这一步。

如果 quality/previous_runs/ 存在但为空,或只包含不符合规范的子目录,发出警告:“阶段 0b:quality/previous_runs/ 存在但不包含符合规范的产物——改为查阅同级的版本化目录以获取种子。”然后继续执行下面的同级发现。

当不存在 quality/previous_runs/ 目录,但存在同级版本化目录时,在这些同级目录中查找先前的质量产物:

  1. 发现同级目录。 列出相对于父目录的、匹配模式 <project-name>-<version>/quality/BUGS.md 的目录。排除当前目录。按版本降序排序(最新的在前)。
  2. 将已确认的 bug 作为种子导入。 对于每个带有 quality/BUGS.md 的同级目录,使用与步骤 0a 相同的格式提取已确认的 bug。将它们写入 quality/SEED_CHECKS.md,并注明来源为同级目录名。
  3. 机械地执行种子检查(与阶段 0a 中的步骤 0b 相同)。对于每个导入的种子,对当前源码树运行断言并记录 PASS/FAIL。
  4. 注入到后续阶段(与阶段 0a 中的步骤 0d 相同)。

为什么要这样做: 在 v1.3.23 基准测试中,尽管 httpx-1.3.21 发现了 Headers.__setitem__ 非 ASCII 编码 bug,httpx 却产生了零 bug 的结果。模型只是探索了不同的代码路径,从未检查 Headers 区域。同级运行种子确保在先前的版本化运行中确认的 bug 得以延续,即使没有显式的 quality/previous_runs/ 归档。这与机械篡改是不同的失败类别——它解决的是探索不确定性,而非证据损坏。


阶段 1:探索代码库(边写边记录)

v1.5.6 埋点: 现在将 phase_start phase=1 追加到 quality/run_state.jsonl。走完每个探索模式后,追加 pattern_walked phase=1 pattern=N findings_count=K。在阶段结束时,进行交叉验证(quality/EXPLORATION.md ≥ 200 字节且包含发现章节),然后追加 phase_end phase=1。参见上文的“运行状态埋点”。

本阶段必需的参考资料——在继续之前阅读这些内容:

  • references/exploration_patterns.md——开放式探索之后要应用的七种 bug 查找模式

第一个动作:创建运行元数据。 在进行任何探索之前,创建运行元数据文件:

mkdir -p quality/results
cat > "quality/results/run-$(date -u +%Y-%m-%dT%H-%M-%S).json" <<'METADATA'
{
  "schema_version": "1.0",
  "skill_version": "1.5.6",
  "project": "<repo-name>",
  "model": "<model-string>",
  "model_provider": "<provider>",
  "runner": "<tool>",
  "start_time": "<ISO-8601-UTC>",
  "end_time": null,
  "duration_minutes": null,
  "phases_completed": [],
  "iterations_completed": [],
  "bug_count": 0,
  "bug_severity": { "HIGH": 0, "MEDIUM": 0, "LOW": 0 },
  "gate_result": null,
  "gate_fail_count": null,
  "gate_warn_count": null,
  "notes": ""
}
METADATA

填写 project、model(准确的模型字符串,例如 "claude-sonnet-4-6")、model_provider(例如 "anthropic"、"openai"、"cursor")、runner(例如 "claude-code"、"copilot-cli"、"cursor")以及 start_time(UTC ISO 8601)。在每个阶段结束时更新此文件——将已完成的阶段追加到 phases_completed,并在确认 bug 时更新 bug_count/bug_severity。终端门之后的最终更新会填写 end_time、duration_minutes 和 gate_result。

第二个动作:运行 v1.5.3 文档摄取(在探索任何代码之前)。 bin/ 中一个仅依赖标准库的模块会生成权威的文档记录,阶段 1 的需求推导依赖于此:

  1. python -m bin.reference_docs_ingest <target> — 对目标仓库中的 reference_docs/ 执行一次遍历。reference_docs/cite/ 下的文件会被哈希处理,并按照 schemas.md §4 及 §1.6 的 manifest 包装格式写入 quality/formal_docs_manifest.json。位于 reference_docs/ 顶层的文件不会写入 manifest,但可通过 bin.reference_docs_ingest.load_tier4_context(<target>) 作为 Tier 4 上下文使用,该函数返回一个经过排序的 (path, text) 元组列表。如果 ingest 命令失败(不支持的扩展名、非 UTF-8 字节),请停止运行,并将 stderr 输出原样呈现给用户——ingest 错误是可操作的,必须在探索继续之前修复。

无需 sidecar。 文件夹位置就是标志:顶层的 reference_docs/<name>.<ext> 文件属于 Tier 4 上下文;reference_docs/cite/<name>.<ext> 下的文件是可引用的来源。cite/ 内容默认为 Tier 1;文件可通过第一个非空行上的可选文件内标记覆盖为 Tier 2:``(Markdown)或 # qpb-tier: 2(纯文本)。任一文件夹下的 README.md 都会被跳过。

当 reference_docs/ 缺失或为空时,Phase 1 必须打印这条可操作的消息并继续:

Phase 1 未在 reference_docs/ 中发现任何文档。Playbook 将继续运行, 仅使用 Tier 3 证据(源代码树本身)。为获得更好的结果,请将 纯文本文档放入: reference_docs/ ← AI 对话、设计笔记、回顾(Tier 4 上下文) reference_docs/cite/ ← 项目规范、RFC、API 契约(可引用、字节校验) 详情请参阅 README.md 的 "Step 1: Provide documentation"。

仅限纯文本——转换在 Playbook 之外进行。 参考文档只能是 .txt 或 .md(schemas.md §2)。PDF、DOCX、HTML 等会被拒绝,并给出可操作的转换提示(pdftotext、pandoc -t plain、lynx -dump)。不要在 skill 内部尝试解析二进制或格式化文档——请在外部运行转换并提交纯文本。

将第一个阶段用于理解项目。质量 Playbook 必须扎根于这个具体的代码库——而不是泛泛的建议。

为什么要先探索? AI 生成的质量 Playbook 中最常见的失败是产出通用内容——适用于任何项目的覆盖率目标、描述理论性故障的场景、测试语言内置功能而非项目代码的测试。探索通过强制每一份产出都引用真实存在的东西来防止这一点:一个具体的函数、一个具体的 schema、一个具体的防御性代码模式。如果你无法指出某个东西在代码中的位置,那你就是在猜测——而猜测会产出没人信任的质量 Playbook。

面向大型代码库的扩展: 对于源文件超过约 50 个的项目,不要试图阅读所有内容。将探索集中在 3–5 个核心模块上(那些处理主要数据流、最复杂逻辑以及最容易出现故障的操作的模块)。从每个子系统读取有代表性的测试,而不是每个测试文件。目标是在重要事项上有深度,而不是在所有事项上有广度。

深度优先于广度(关键)。 带有函数级细节的狭窄范围比带有子系统级摘要的宽泛范围能发现更多 bug。对于你探索的每个核心模块,找出实现关键行为的具体函数,并按名称、文件路径和行号记录它们。从"重置子系统应处理错误"推导出的需求无法捕获 bug。从"virtio_mmio.c:256 处的 vm_reset() 必须在写入零后轮询状态寄存器"推导出的需求则可以。有用的探索与无用的探索之间的区别就在于具体性——文件路径、函数名、行号、确切的行为规则。

三阶段探索:先打开,再领域风险,最后选定模式。 探索有三个阶段,顺序很重要:

  1. 开放式探索(领域驱动)。 在应用任何结构化模式之前,先像一位经验丰富的开发者那样探索代码库:阅读代码,理解架构,基于你对该类系统常见故障的领域知识识别风险。问自己:"[该领域] 的专家会首先检查什么?"对于 HTTP 库,这意味着重定向处理、头部编码、连接生命周期。对于 CLI 框架,这意味着标志解析、帮助生成、补全/校验一致性。对于序列化库,这意味着类型覆盖、往返保真度、边界情况处理。用文件路径和行号写出具体的发现。此阶段必须产出至少 8 条具体的 bug 假设或可疑发现——不是架构层面的观察,而是具体的"file:line 处的这段代码可能有错,因为 [原因]"式发现。其中至少 4 条必须涉及不同的模块或子系统。

  2. 领域知识风险分析。 在开放式探索之后,暂时从代码中抽身,基于你从训练中所知的关于此类系统的知识进行推理。对于库和框架代码库,这是主要的 bug 排查环节。使用两个来源完成下方的 Step 6 问题——你刚刚探索的代码,以及你对类似系统的领域知识。生成至少 5 个分级失败场景,每个场景都要指明具体的函数、文件和行号,并解释为什么某个领域特定的边界情况会产生错误行为。你不需要实际观察到这些失败——你从训练中知道它们会发生在这一类型的系统上。在进入模式分析之前,将结果写入 EXPLORATION.md 的 ## Quality Risks 部分。

    此阶段不得产出的内容: 列出代码已有的防御性模式(代码做对的事情)的部分不是风险分析。列出有风险的模块而没有具体失败场景的部分不是风险分析。得出"这是一个成熟、经过充分测试的库,所以不太可能有基本 bug"结论的部分是有害的——成熟的库拥有最隐蔽的 bug,恰恰因为显而易见的那些多年前就已被发现。检验标准:代码审查者能否读到每个场景后立即知道要检查什么?如果不能,这个场景就太抽象了。

  3. 模式驱动探索(精选,而非穷尽)。 在开放式探索和领域风险分析写入磁盘后,使用模式适用性矩阵评估 exploration_patterns.md 中的所有七种分析模式。对于每种模式,评估它是否适用于此代码库以及它将针对什么。然后选择 3 到 4 种模式进行深度剖析——针对此特定代码库产出最高的模式。其余模式用一句简短的"不适用"或"推迟"说明并附上针对该代码库的理由。不要为所有七种模式都产出深入章节——3–4 种的深度胜过 7 种的浅层覆盖。当第四种模式有明确的适用性且能覆盖其他三种未触及的代码区域时,选择 4 种;存疑时默认为 3 种。

    对于每个选定的模式深度剖析,使用参考文件中的输出格式,并跨 2 个以上函数追踪代码路径。深度剖析应对开放式探索和风险分析中的发现进行压力测试、细化或扩展——而不是重复它们。

Phase 1 完成门禁检查所有三个阶段。开放式探索部分、质量风险部分、模式适用性矩阵以及模式深度剖析部分都必须存在。

增量式写入——不要在记忆中保留发现。 这是 Phase 1 中最重要的执行规则。在你探索完每个子系统或应用完每种模式后,立即将你的发现追加到磁盘上的 quality/EXPLORATION.md,然后再转向下一个子系统或模式。 不要试图在多个子系统之间将发现保留在工作记忆中。随写随记的原则有两个目的:

  1. 深度恢复。 如果你探索 PCI 中断路由子系统,并在 vp_find_vqs_intx() 处发现可疑代码,立即将该发现写入 EXPLORATION.md。然后当你转到 admin 队列子系统时,你的工作记忆就可以腾出来在那里深入探索。如果没有增量写入,第一个子系统的发现会与第二个子系统的发现相互竞争,两者最终都会流于浅层。

  2. 什么都不会丢失。 在 v1.3.41 基准测试中,模型探索了 8 个模式小节,但每个小节只写了 5–7 行——完全均匀,完全浅层。每个小节都通过了门禁,但没有一个深入到位,无法发现那些需要跨多个函数追踪代码路径才能找到的 bug。模型试图在最后、在读完所有内容之后,才拼凑出整个 EXPLORATION.md,结果只能回忆起表面层的发现。增量写入可以防止这种情况。

节奏是:阅读一个子系统 → 将发现写入磁盘 → 阅读下一个子系统 → 追加发现 → 重复。 每次追加都应包含具体的函数名、文件路径、行号以及具体的 bug 假设。一个写着“检查了跨实现一致性,发现一个缺口”的 5 行小节,只是一个通过门禁的占位内容,而不是探索发现。一个有用的小节会追踪一条代码路径:“位于 file:line 的函数 A 调用位于 file:line 的函数 B,后者做了 X 但没有做 Y;与之相比,位于 file:line 的函数 C 两者都做了。”

强制整合步骤。 在三个阶段(开放式探索、质量风险以及选定的模式深度挖掘)都已探索并写入 EXPLORATION.md 之后,添加一个最终小节:## Candidate Bugs for Phase 2。该小节将所有前面小节中最强的 bug 假设整合成一个按优先级排序的交接清单。对于每个候选,包括:假设、具体的 file:line 引用、它由哪个阶段浮现(开放式探索、质量风险或模式),以及代码审查应查找什么。该小节是探索与产物生成之间的桥梁——它准确告诉 Phase 3 应把重点放在哪里。最低要求:4 个带 file:line 引用的候选 bug——至少 2 个来自开放式探索或质量风险,至少 1 个来自模式深度挖掘。没有上限。

预检:大型仓库的范围声明

在探索任何源代码之前,先估计规模:近似的源文件数量(排除测试、文档和生成文件)、主要子系统数量以及文档量。将数量记录在 PROGRESS.md 中。

  • 少于 200 个源文件: 进行完整探索。上述关于深度与广度的指导仍然适用。
  • 200–500 个源文件: 在探索之前声明你打算覆盖的范围。向 PROGRESS.md 写入一个 ## Scope declaration 小节,列出你将覆盖的 3–5 个子系统、每个子系统的预期文件数量,以及你将推迟哪些子系统及其理由。然后仅对你声明的范围进行探索。
  • 超过 500 个源文件: 停止,并在阅读任何源文件之前向 PROGRESS.md 写入一个强制性的范围声明。范围声明必须包括:(a) 本次运行覆盖的子系统,(b) 明确推迟的子系统,(c) 每个被推迟子系统的排除理由,以及 (d) 对后续运行推荐的子系统范围。在写入之前不要开始探索。对于超过此阈值的仓库,覆盖“所有内容”的范围声明是无效的。

恢复之前的会话: 如果 PROGRESS.md 已存在并显示各阶段被标记为完成,请先阅读它。不要重做已标记为完成的阶段——从第一个标记为未完成的阶段恢复。如果范围声明已经写好,请严格遵循它。如果上一个会话的范围声明推迟了某些子系统,除非本次运行明确是针对被推迟区域的后续运行,否则不要扩大范围去覆盖它们。 以规范为主要产物的仓库: 有些仓库把规范、配置或协议文档作为主要产物,可执行代码只是支撑性基础设施。例如:带基准测试工具的技能定义、带校验脚本的 schema 注册表、带编排辅助工具的流水线配置。当主要产物是规范而非可执行代码时,应从规范自身的内部一致性、完整性和正确性推导需求 —— 而不只是从可执行代码路径推导。规范才是用户所依赖的东西;工具是次要的。如果你发现自己写出的需求有 80% 以上是关于辅助脚本的,而不到 20% 是关于主要规范的,那说明你的关注点弄反了。

第 0 步:询问开发历史

在探索代码之前,先问用户一个问题:

"你是否保留了开发这个项目时导出的 AI 聊天记录 —— Claude 导出、Gemini 导出、ChatGPT 导出、Claude Code 记录,或类似内容?如果有,请告诉我文件夹位置。这些聊天中的设计讨论、事故报告和质量决策,会显著提升所生成质量手册的质量。"

如果用户提供了聊天记录文件夹:

  1. 先找索引文件。 查找名为 INDEX*、CONTEXT.md、README.md 或类似导航辅助文件。如果存在,先读它 —— 它会告诉你里面有什么以及如何查找内容。
  2. 搜索与质量相关的对话。 查找提及以下内容的message:quality、testing、coverage、bugs、failures、incidents、crashes、validation、retry、recovery、spec、fitness、audit、review。同时也要搜索项目名称。
  3. 提取设计决策和事故历史。 最有价值的内容是:(a) 事故报告 —— 出了什么问题、影响了多少条记录、如何被发现的,(b) 设计讨论 —— 为什么选择某种特定方案、否决了哪些备选方案,(c) 质量框架讨论 —— 覆盖率目标、测试理念、模型审查经验,(d) 跨模型反馈 —— 不同 AI 模型在代码上存在分歧之处。
  4. 不要试图读完所有内容。 聊天记录可能非常庞大。用索引找到最相关的对话,然后在其中搜索与质量相关的内容。10 分钟有针对性的搜索胜过 2 小时的通读。

这些上下文是金子。如果开发者在聊天记录中讨论过"我们为什么选择这种并发模型"或"我们在生产环境中丢失 1,693 条记录的那次事故",这些内容能把通用场景变成权威场景。

如果用户没有聊天记录,正常继续 —— 该技能没有它也能工作,只是上下文较少。

自主运行时的回退方案: 在以基准测试模式运行时,通过 bin/run_playbook.py(基准测试运行器,不随该技能发布)运行时,或在没有用户交互(例如 --single-pass)时,跳过第 0 步的提问,直接进入第 1 步。如果项目树中能看到聊天记录文件夹(例如 AI Chat History/、.chat_exports/),无需询问直接扫描它们。如果找不到聊天记录,继续 —— 不要阻塞等待一个不会到来的回复。

步骤 1:确定领域、技术栈和规范

阅读 README、现有文档和构建配置(pyproject.toml / package.json / Cargo.toml)。回答:

  • 这个项目是做什么的?(一句话。)
  • 使用什么语言和关键依赖?
  • 它与哪些外部系统交互?
  • 主要输出是什么?

查找规范。 规范是功能测试的事实来源。按顺序搜索:根目录下的 AGENTS.md/CLAUDE.md、specs/、docs/、spec/、design/、architecture/、adr/,然后是根目录下的 .md 文件。记录这些路径。

如果不存在正式的规范文档,该技能仍然可用——但你需要从其他来源汇总需求。按优先级排序:

  1. 询问用户——他们通常知道需求,即使这些需求没有被写下来。
  2. README 和內联文档——许多项目将需求嵌入在 README、API 文档或代码注释中。
  3. 现有测试套件——测试是隐式的规范。如果某个测试断言 process(x) == y,那就是一条需求。
  4. 类型签名和校验规则——schema、类型注解和校验器定义了系统接受和拒绝的内容。
  5. 从代码行为推断——作为最后的手段,阅读代码并推断它应该做什么。在 QUALITY.md 中将这些标记为推断需求,并标记出来供用户确认。

当基于非正式需求工作时,为每个场景和测试标注一个需求标签,其中包含置信度层级和来源:

  • [Req: formal — README §3]——由人类在规范文档中编写。具有权威性。
  • [Req: user-confirmed — "must handle empty input"]——由用户陈述但不在正式文档中。视为具有权威性。
  • [Req: inferred — from validate_input() behavior]——从代码中推断。标记出来供用户审查。

在 QUALITY.md 场景、功能测试文档和规范审计发现中使用此确切的标签格式。它能清楚地表明哪些需求具有权威性,哪些需要验证。

步骤 1b:评估文档深度

如果 reference_docs/ 存在,请先阅读其中的每个文件,再决定重点关注哪些子系统。对于每份文档,对其深度进行分类:

  • 深度 — 包含内部契约、安全不变量、并发模型、防御性模式、错误处理细节,或行号级别的源码引用。适合用于推导需求。
  • 中等 — 涵盖架构和 API 表面,并带有一些实现细节。可用于定位方向,但仅凭它不足以推导需求。
  • 浅层 — API 目录、功能概览或营销级别的摘要。列出存在什么,但不说明它如何工作、如何失败,或强制哪些契约。不足以用于范围界定决策。

范围界定规则: 不要将审计范围缩小到仅包含有深度文档的子系统。如果最复杂或最易失败的模块只有浅层文档,那是需要在 PROGRESS.md 中标记的文档缺口,而不是跳过该模块的理由。风险最高且文档最薄的代码正是 bug 藏身之处——只审计文档完善的区域会产出一份看似安全、却遗漏真实缺陷的报告。

当高风险区域的文档较为浅薄时:

  1. 在 PROGRESS.md 的 ## Documentation depth assessment 章节下明确记录该缺口。
  2. 直接从源代码推导需求(文档注释、安全注解、防御性模式、现有测试),并将其标记为 [Req: inferred — from source]。
  3. 在完整性报告中将该区域标记为需要进一步收集文档。

在 PROGRESS.md 中记录每个 reference_docs/ 文件的深度分类,以便审查者评估文档是否恰当地影响了范围。

覆盖承诺表: 在对所有 reference_docs/ 文档分类后,在 PROGRESS.md 的 ## Documentation depth assessment 章节下生成此表:

DocumentDepthSubsystemRequirements commitmentIf excluded: justification

对于每份深度文档,将其映射到它所覆盖的子系统,然后要么承诺从中推导需求("will cover in Phase 2"),要么提供指明权衡取舍的具体理由。像 "out of scope for this run" 这样的句子是不够的——理由必须说明为什么,例如,"interpreter JIT is excluded because this run focuses on the parser/compiler/GC pipeline; separate run recommended."

门禁: 在 reference_docs/ 中有深度文档记录的高风险子系统,绝不能从需求集中悄然消失。如果一份深度文档有 "will cover" 承诺,但到步骤 7 结束时产生零条需求,则需求流水线不完整——在继续进入 Phase 2 制品生成之前,返回并为该缺口推导需求。

步骤 2:梳理架构

列出源代码目录及其用途。阅读主入口点,追踪执行流。识别:

  • 3–5 个主要子系统
  • 数据流(输入 → 处理 → 输出)
  • 最复杂的模块
  • 最脆弱的模块
第 3 步:阅读现有测试

阅读现有测试文件——对于小型/中型项目,阅读全部测试文件;对于大型项目,则从每个子系统中选取有代表性的样本。识别:测试数量、覆盖模式、覆盖缺口,以及任何覆盖表演(看起来不错但抓不到真实 bug 的测试)。

关键:记录导入模式。 现有测试如何导入项目模块?每种语言都有自己的惯例(Python 的 sys.path 操作、Java/Scala 的包导入、TypeScript 的相对路径或别名、Go 的包/模块路径、Rust 的 use crate:: 或 use myproject::)。你必须在功能测试中使用完全相同的模式——弄错这一点意味着每个测试都会因导入/解析错误而失败。完整的六语言矩阵见 references/functional_tests.md § "Import Pattern"。

识别集成测试运行器。 查找针对真实外部服务(API、数据库等)对系统进行端到端演练的脚本或测试文件。记录它们的模式——你在 RUN_INTEGRATION_TESTS.md 中会需要它们。

第 4 步:阅读规格说明

逐节浏览每个规格文档。对每一节,问:"这里陈述了哪些可测试的需求?"记录没有对应测试的规格需求——这些就是功能测试必须补上的缺口。

如果使用推断需求(来自测试、类型或代码行为),请使用第 1 步中定义的 [Req: tier — source] 格式为每条需求标注其置信度层级。推断需求会进入 QUALITY.md 场景,并应在第 7 阶段标记出来供用户审阅。

第 4b 步:阅读函数签名和真实数据

在编写任何测试之前,你必须确切了解每个函数是如何被调用的。对于你在第 2 步中识别出的每个模块:

  1. 阅读实际的函数签名——参数名、类型、默认值。不要根据使用上下文来猜测——阅读函数定义和任何文档(Python docstring、Java/Scala Javadoc/ScalaDoc、TypeScript 类型注解、Go godoc 注释、Rust 文档注释和类型签名)。
  2. 阅读真实数据文件——如果项目有 items 文件、fixture 文件、配置文件或示例数据(位于 pipelines/、fixtures/、test_data/、examples/),请阅读它们。你的测试 fixture 必须与真实数据形状完全匹配。
  3. 阅读现有测试 fixture——现有测试如何创建测试数据?照搬它们的模式。如果它们用特定键构建 config dict,就使用那些确切的键。
  4. 检查库版本——检查项目的依赖清单(requirements.txt、build.sbt、package.json、pom.xml/build.gradle、go.mod、Cargo.toml),看看实际可用的内容是什么。不要编写依赖尚未安装的库功能的测试。如果某个依赖可能缺失,请使用测试框架的跳过机制——各框架的具体示例见 references/functional_tests.md § "Library version awareness"。

记录一份函数调用映射:对于你计划测试的每个函数,写下它的名称、模块、参数以及返回值。这份映射可以防止最常见的测试失败:用错误的参数调用函数。

第 5 步:找出骨架

这是最重要的一步。搜索防御性代码模式——每一个都是过去某次失败或已知风险的证据。

为什么这很重要: 开发者不会无缘无故写 try/except 块、空值检查或重试逻辑。每一段防御性代码的存在,都是因为有人踩过坑。JSON 解析外层的 try/except 意味着生产环境里出现过格式错误的 JSON。某个字段上的空值检查意味着该字段曾在不该缺失的时候缺失。这些模式是代码库在低声诉说它的失败史。每一个都会转化为一个适用性场景和一个边界测试。

阅读 references/defensive_patterns.md,了解系统性搜索方法、grep 模式,以及如何把发现转化为适用性场景和边界测试。

最低标准:每个核心源文件至少 2–3 个防御性模式。如果你找到的更少,说明你只是在略读——要读函数体,而不只是签名。

第 5a 步:追踪状态机

如果项目有任何形式的状态管理——状态字段、生命周期阶段、工作流阶段、模式标志——就完整地追踪状态机。这能捕获仅靠防御性模式分析会漏掉的一类 bug:存在但未被处理的状态。

如何找到状态机: 在模型、枚举或常量中搜索 status/state 字段(例如 status、state、phase、mode)。搜索在允许操作前检查状态的守卫(例如 if status == "running"、match self.state)。搜索状态转换(对状态字段的赋值)。

对于你找到的每个状态机:

  1. 枚举所有可能的状态。 读取枚举、常量,或 grep 出该字段被赋予的每一个值。把它们全部列出。
  2. 对于每个状态消费者(UI 处理器、API 端点、控制流守卫),检查:它是否处理了所有可能的状态?一个没有有意义 default 的 switch/match,或一条没有覆盖所有状态的 if/elif 链,都是缺口。
  3. 对于每次状态转换,检查:你能到达每一个状态吗?有没有能进入却永远无法离开的状态?有没有会阻止本应可用的操作的状态?
  4. 把缺口记录为发现。 一个状态守卫允许对 "running" 执行操作 X,却不对 "stuck" 允许,如果用户需要对卡住的进程执行操作 X,那就是真实的 bug。一个进入终止状态却从不触发清理的进程也是真实的 bug。

为什么这很重要: 状态机缺口产生的 bug 在正常运行期间不可见,却会在压力或边界条件下浮现——恰恰是你需要系统正常工作时。一个在 "stuck" 状态下无法被杀死的批处理器,一个在所有工作完成后永不自行终止的监视器,或一个拒绝恢复 "pending" 运行的 UI,都是状态处理不完整的症状。这些 bug 不会出现在防御性模式分析中,因为代码并没有在防御它们——它根本就没在处理它们。

第 5b 步:映射 Schema 类型

如果项目有校验层(Python 中的 Pydantic 模型、JSON Schema、TypeScript 接口/Zod schema、Java Bean Validation 注解、Scala case class codec),现在读取 schema 定义。对于你找到防御性模式的每个字段,记录 schema 接受什么、拒绝什么。

阅读 references/schema_mapping.md,了解映射格式以及这对编写有效的边界测试为何重要。

第 6 步:领域知识风险分析(代码 + 领域知识)

这是针对库和框架代码库的主要 bug 排查环节。 在选择任何结构化模式之前完成它。立即把结果写入 EXPLORATION.md 的 ## Quality Risks 部分——不要把它们留在记忆里。

每个项目都有不同的失败画像。这一步使用两个来源——不只是代码探索,还有你训练知识中关于类似系统会出什么问题的认知。 从代码探索出发,问:

  • 对这个项目来说,“静默错误”是什么样子?
  • 哪些外部依赖可能在没有预警的情况下发生变化?
  • 什么看起来简单,实际却很复杂?
  • 横切关注点隐藏在哪里?

从领域知识出发,问:

  • “像这样的系统会出什么问题?”——如果是 HTTP 路由器,就考虑 header 解析边界情况(质量值、token 列表、大小写敏感性)、中间件顺序依赖和路径规范化。如果是 HTTP 客户端,就考虑重定向时凭据剥离、编码检测和连接状态泄漏。如果是序列化库,就考虑 null 处理的不对称性、直接方法与视图包装器之间的 API 表面一致性、惰性求值缓存 bug 以及往返保真度。如果是 Web 框架,就考虑响应辅助函数的边界情况、配置编译链和中间件状态隔离。如果是批处理器,就考虑崩溃恢复、幂等性、静默数据丢失、状态损坏。如果它处理随机性或统计,就考虑种子设定、相关性和分布偏差。
  • “什么会产生看起来正确、实际却错误的输出?”——这是最危险的一类 bug:通过所有检查但已被微妙破坏的输出。一个返回 200 OK 但 Content-Type 错误的响应。一个成功但泄漏凭据的重定向。一个被静默截断值的反序列化对象。
  • “在 10 倍规模下会发生什么,而在 1 倍规模下不会发生?”——分块边界、速率限制、超时级联、内存压力。
  • “如果这个进程在最糟糕的时刻被杀掉,会发生什么?”——写入中途、事务中途、批次提交中途。
  • “两个本应行为一致的表层,在边界输入上会在哪里产生偏差?”——重载、别名、同步/异步 API、构建器与直接 API、直接修改器与实时视图/包装器、兼容标准库的包装器与框架原生表层。对于 Java/Kotlin:add(null) 与 asList().add(null),put(key,null) 与 asMap().put(key,null)。对于 Python:构造函数编码与修改器编码,同步与异步客户端行为。
  • “什么会输出看似合理但元数据微妙错误的输出?”——内容类型、字符集、路由模式、ETag 强度、字节数、auth/header/cookie 传播、状态码、缓存验证器。
  • “什么标准语法或列表语法正在用临时的字符串逻辑解析?”——质量值(q=0)、逗号分隔的 header、摘要质询、带参数的 MIME 类型、查询字符串、枚举/关键字集合、cookie 合并。
  • “领域专家会去尝试哪些边界情况输入?”——对于 HTTP 代码:Accept-Encoding: gzip;q=0、Connection: keep-alive, Upgrade、Content-Type: application/problem+json。对于序列化代码:通过不同 API 表层传入的 null、位于 Integer.MAX_VALUE + 1 的值、经过编码再解码的往返。对于路由代码:重叠模式、挂载前缀传播、同一路径配不同方法。
  • “在用户承诺执行不可逆或昂贵操作之前,需要哪些信息?”——运行前成本估算、范围确认(尤其是当扇出或扩展会成倍增加工作时)、资源警告。如果系统可能在未向用户展示即将做什么的情况下,静默让用户投入数小时处理或显著成本,那就是缺少保障措施。搜索会启动长时间运行进程、提交批次任务或触发扩展/扇出的操作——并检查用户是否在不可返回点之前看到带有真实数字的预览、估算或确认。
  • “长时间运行的进程结束后会发生什么——它真的会停止吗?”——轮询循环、监视器、后台线程和守护进程如果会运行到完成,就应当有明确的终止条件。如果循环检查的是“还有更多工作吗?”,却从不检查“所有工作都完成了吗?”,那么它在完成后会永远运行。这在批处理器和队列消费者中尤其常见。 根据这些知识生成至少 5 个按优先级排序的失败场景。你不需要实际观察到这些失败——你从训练中知道它们会发生在这一类型的系统上。将它们写成带有文件路径和行号引用的具体 bug 假设,并按优先级排序。每个场景的框架为:“因为 [file:line 处的代码] 执行了 [X],所以一个 [领域特定的边缘情况] 将产生 [错误行为],而不是 [正确行为]。”然后将它们落到你实际探索过的代码上:“阅读 persistence.py 约第 340 行(save_state):验证临时文件 + rename 模式。”

无法通过门槛的反模式: 一个列出代码已经具备的防御性模式(即代码做对的事情)的 Quality Risks 章节不是风险分析——它是一种安抚性练习,不会发现 bug。一个列出高风险模块却没有具体失败场景的章节是不可执行的。一个得出结论“这是一个成熟、经过充分测试的库,所以基本 bug 不太可能出现”的章节是有害的——成熟库拥有最微妙的 API 契约和边缘情况 bug,恰恰是因为显而易见的那些多年前就被发现了。检验标准:代码审查者能否阅读每个场景后立即知道要打开哪个函数、要测试什么输入?如果不能,该场景就过于抽象。

步骤 7:推导可测试需求

阅读 references/requirements_pipeline.md 以了解完整的五阶段流水线、领域清单和版本控制协议。

这是代码审查协议中最重要的步骤。探索期间发现的一切——规格说明、ChangeLog 条目、配置结构体、源码注释、聊天历史——都会被提炼为一组可测试需求,供代码审查验证。该流水线将契约发现与需求推导分离,使用基于文件的外部记忆,并包含带完整性门槛的机械验证。

为什么这很重要: 结构化代码审查能捕获约 65% 的真实缺陷。剩下的 35% 是意图违规——缺失 bug、跨文件矛盾和设计缺口。这些对代码阅读来说是不可见的,因为存在的代码本身是正确的。你需要知道代码应该做什么,然后检查它是否做到了。这正是可测试需求所提供的东西。

五阶段流水线:

  1. 阶段 A —— 契约提取。 阅读所有源文件,列出每一个行为契约。写入 quality/CONTRACTS.md。这是发现阶段——列出所有内容,即使它看起来显而易见。

  2. 阶段 B —— 需求推导。 阅读 CONTRACTS.md 和文档。将相关契约分组,结合用户意图进行丰富,写出正式需求。将 REQ 记录写入 quality/requirements_manifest.json(作为事实来源),并渲染到 quality/REQUIREMENTS.md。对于每个需求,记录 tier(依据 schemas.md §3.1,取值 1–5),并且——当 tier ∈ {1, 2} 时——记录由 bin/reference_docs_ingest 依据 schemas.md §5.4 / §5.5 调用 bin/citation_verifier 所产生的 citation 块。LLM 不会直接通过 shell 调用 citation_verifier;该摘录是 ingest 流水线的产物,并在 gate 时由 quality_gate.py 重新验证。对于 Tier 3 REQ(代码即规格),在 description 中引用源 file:line;citation 仅用于 FORMAL_DOC 引用,不得出现在 Tier 3/4/5 REQ 上。tier + citation 这一对在可追溯链中创建前向链接:reference_docs/cite → requirements → bugs → tests。请参阅本步骤后面的 tier/citation 框架块,了解完整字段列表以及 Tier-1-wins-over-Tier-2 规则。

    REQ 上可选的 Pattern: 字段。 需要 Phase 3 补偿网格的需求应声明其模式类别:

    • Pattern: whitelist —— 权威项目列表,每个站点都必须处理其中每一项。
    • Pattern: parity —— 必须匹配的对称操作 (encode↔decode、setup↔teardown)。
    • Pattern: compensation —— 必须补偿共享缺口的站点。 缺少该字段意味着没有网格。设置无效值会导致 quality_gate.py 失败。

    保留规则(阶段 2)。 虽然 Pattern: 在设计意义上可选(某些 REQ 是单点需求,不需要网格),但当阶段 1 假设已经携带它时,则必须保留。阶段 2 必须将 Pattern: 从 EXPLORATION.md 转录到 quality/REQUIREMENTS.md 和 quality/requirements_manifest.json(只要存在)。静默省略是一个有记录的 v1.4.5 回归向量 —— 阶段 5 基数门禁无法对某个它不知道带有 pattern 标记的 REQ 强制执行覆盖。门禁的结构性兜底(C13.7/Fix 2)会交叉检查携带按站点 UC 引用的 REQ(由阶段 1 的笛卡尔 UC 规则生成的 UC-N.a/UC-N.b 形式),如果此类 REQ 缺少 Pattern,则门禁失败。

    代码存在性声明的一手来源提取规则。 当编写断言特定常量、值或标签由特定函数处理的需求时(例如,“白名单必须保留 X、Y 和 Z”),该需求必须区分规范说应该存在什么与代码实际包含什么。从代码中提取实际内容(case 标签、map 键、if-else 分支),并与规范的列表进行比较。如果某个常量出现在规范中但未出现在代码中,则将需求写为 “must handle X — [NOT IN CODE]: defined in header.h:NN but absent from function() at file.c:NN-NN。” 不要在未验证 X 确实被保留的情况下写 “must preserve X”。这可以防止一条污染链:需求断言代码存在性,代码审查复制该断言,规范审计继承它,分诊接受它 —— 全程没有人阅读实际代码。这一确切的链条在 v1.3.17 virtio 测试中被观察到:REQUIREMENTS.md 断言 RING_RESET 在某个 switch 中被保留,代码审查复制了该列表,三位规范审计员继承了该声明,而该 bug 未被发现。 分发函数的机械验证产物(强制)。 当契约断言某个函数处理、保留或分发一组命名常量(feature 位、枚举值、opcode 表、事件类型、处理器注册表)时,你必须在编写契约行之前生成并执行一条 shell 命令或脚本,以机械方式从函数体中提取实际的 case 标签/分支。将原始输出保存到 quality/mechanical/<function>_cases.txt。该命令必须是一条非交互式管道(例如 awk + grep),它不可能产生幻觉 —— 它读取文件字节并打印匹配项。示例:

    awk '/void vring_transport_features/,/^}$/' drivers/virtio/virtio_ring.c \
      | grep -E '^\s*case\s+' > quality/mechanical/vring_transport_features_cases.txt
    

    执行后,读取输出文件,并将其作为该函数处理内容的唯一事实来源。除非 quality/mechanical/<function>_cases.txt 包含匹配的 case X: 行,否则断言“function preserves constant X”的契约行是禁止的。如果某个常量出现在规范或头文件中但未出现在机械输出中,则契约必须将其记录为缺失:"must handle X — **[NOT IN CODE]**: defined in header.h:NN but absent from function() per mechanical check." 下游产物(REQUIREMENTS.md、RUN_SPEC_AUDIT.md、代码审查)在引用分发函数覆盖情况时,必须引用该机械文件路径 —— 它们不得用手写列表替换机械输出。

    机械产物完整性检查(强制)。 对于每条机械提取命令,还要将其作为验证步骤追加到 quality/mechanical/verify.sh。该脚本必须重新运行相同的提取管道,并将结果与保存的文件进行 diff。按以下结构生成 verify.sh:

    #!/bin/bash
    # Auto-generated: re-run mechanical extraction commands and verify saved artifacts
    set -euo pipefail
    FAIL=0
    
    # Verify <function>
    ACTUAL=$(awk '/void vring_transport_features/,/^}$/' drivers/virtio/virtio_ring.c | grep -nE '^\s*case\s+')
    SAVED=$(cat quality/mechanical/vring_transport_features_cases.txt)
    if [ "$ACTUAL" != "$SAVED" ]; then
      echo "MISMATCH: vring_transport_features_cases.txt"
      diff <(echo "$ACTUAL") <(echo "$SAVED") || true
      FAIL=1
    else
      echo "OK: vring_transport_features_cases.txt"
    fi
    
    exit $FAIL
    

    阶段 6 必须执行 bash quality/mechanical/verify.sh,且只要有任何产物不匹配,基准测试就失败。这能捕获 v1.3.19 中观察到的一种失败模式:模型执行了提取命令,却把自己的预期输出写入文件,而不是让 shell 重定向捕获它,从而插入了一行真实命令不会产生的、凭空捏造的 case VIRTIO_F_RING_RESET:。在单独步骤中重新运行同一命令并与该文件进行 diff,即可检测出这种篡改。

    即时完整性门禁(强制,阶段 2a)。 每写完一个 *_cases.txt 文件后,立即运行 bash quality/mechanical/verify.sh,且必须在写入任何引用该提取结果的契约、需求或文字产物之前运行。如果退出码 ≠ 0:停止,删除失败的 *_cases.txt,用全新的 shell 重定向重新运行提取命令(不要手工编辑输出),然后重新验证。在 verify.sh 退出码为 0 之前,不要进入阶段 3/2c。将 verify.sh 的 stdout 和退出码保存到 quality/results/mechanical-verify.log 和 quality/results/mechanical-verify.exit,作为持久凭据文件。这一门禁之所以存在,是因为 v1.3.23 表明,把验证推迟到阶段 6 会让下游产物(CONTRACTS.md、REQUIREMENTS.md、triage 探针)建立在伪造的提取结果之上——模型会通过破坏产物而非修正需求来调和需求与产物之间的差异。

    机械产物在提取后不可变。 一旦 *_cases.txt 文件已由 shell 重定向写出并经 verify.sh 验证,它在本次运行的剩余时间内不得被修改、覆盖或重新生成。如果下游步骤发现机械产物与某项需求或契约之间存在差异,那么错的是需求或契约,而不是产物。修正文字,而不是提取结果。此规则可防止 v1.3.23 的失败模式:模型用捏造的内容覆盖正确的提取结果,以迎合自己的叙述。

    禁止的探针模式(triage 与验证)。 Triage 探针、验证探针和审计断言不得将 open('quality/mechanical/...') 或 cat quality/mechanical/... 作为某个源文件在给定行处包含内容的唯一证据。要验证函数 F 在第 N 行处理常量 C,探针必须要么:(a) 直接读取源文件(open('drivers/virtio/virtio_ring.c'),并使用锚定行的断言),要么:(b) 重新执行 verify.sh 所用的同一条提取流水线并检查其输出。读取已保存的产物只能证明产物说了什么,而不能证明代码说了什么——这是循环验证。在 v1.3.23 中,探针 C 验证的是伪造的产物而非源代码,因而凭捏造的数据通过了验证。

    不要创建空的 mechanical/ 目录。 只有当项目的契约包含需要机械提取的分发函数、注册表或枚举检查时,才创建 quality/mechanical/。如果不存在此类契约,则完全跳过该目录,并在 PROGRESS.md 中记录:Mechanical verification: NOT APPLICABLE — no dispatch/registry/enumeration contracts in scope. 创建空的 mechanical/ 目录(或没有 verify.sh 的目录)是不合规的——它表明曾尝试提取但已放弃。在创建该目录之前先决定:本项目是否有分发函数契约?如果没有,就不要 mkdir。如果有,就将其完整填充。 规范性表述与描述性表述的区分。 需求与契约在描述预期行为时,必须使用规范性语言("must preserve"、"should handle")。只有当机械验证产物确认了相关声明时,才可以使用描述性语言("preserves"、"handles")。如果一条需求声称"the implementation preserves VIRTIO_F_RING_RESET",却没有确认性的机械产物,即为不符合规范——应写作"the implementation must preserve VIRTIO_F_RING_RESET",并引用机械检查结果,说明该常量当前存在或缺失。

  3. 阶段 C — 覆盖验证。 将每份契约与每条需求交叉比对。修复缺口。最多循环 3 次,直到覆盖率达到 100%。写入 quality/COVERAGE_MATRIX.md。矩阵必须每条需求一行(REQ-001、REQ-002 等)——不能使用 "C-001 to C-007 | REQ-001, REQ-003" 这样的分组区间。分组区间会使机器验证无法进行,并掩盖缺口。

  4. 阶段 D — 完整性检查 + 自我精炼循环。 应用领域检查清单、可测试性审计与跨需求一致性检查。同时验证:覆盖承诺表中每个带有"will cover"承诺的深层文档,是否至少有一条需求追溯到它——如果没有,先为缺口补充需求再继续。

    将结果写入 quality/COMPLETENESS_REPORT.md,作为基线完整性报告(不含 ## Verdict 部分——最终判定推迟到阶段 5 对账之后,那才是对关闭唯一有效的判定)。然后运行最多 3 轮自我精炼迭代:阅读报告、修复缺口、重新检查。当每轮迭代的变更少于 3 处时提前终止。

  5. 阶段 E — 叙述梳理。 添加项目概述(含概述验证关卡),再推导用例(含用例推导关卡)。两个关卡都必须通过,才能继续进行分类叙述、横切关注点与最终重排序。这样的顺序可避免多轮循环——即后期关卡失败迫使重新推导。按自上而下的流程重排序。顺序重新编号。

REQUIREMENTS.md 必须以人类可读的概述开头,回答:这个项目是什么?它做什么?参与者有哪些(用户、系统、硬件、协议)?风险最高的领域是什么?这份概述应当对从未见过该项目的人有帮助。如果项目是一个库或驱动,所有参与者都是系统,请描述系统参与者(内核维护者、协议对端、集成方、终端开发者)及其交互。不要以原始范围元数据或 HTML 注释开头——以平实易懂的描述开篇。

概述验证关卡(强制)。 写完概述后,在继续用例推导之前,执行以下自检:

这份概述是否以项目的实际用户能够认出的方式描述了该项目?具体而言:

  • 是否指出了项目在生态中的角色与现实意义?
  • 是否指明了谁依赖它、为何依赖?
  • 每天使用这个项目的开发者会不会说"对,它就是这样,这就是它重要的原因"?
  • 对于知名项目,是否反映了公开已知的采用情况(例如 Cobra → kubectl/Hugo/GitHub CLI;Express → 数百万个 Node.js API 服务器;Zod → 表单校验/tRPC;Serde → Rust 默认的序列化层)?

如果概述读起来像是只读过源代码、从未使用过该软件的人写的,就先修改再继续。概述为下游一切设定框架——面向功能的用例和聚焦内部的需求,正是只描述代码、而非项目的概述所表现出的症状。

用例推导(强制,在概述关卡之后运行)。 从经过验证的概述与收集到的文档中推导 5–7 个用例,再对照代码进行验证。每个用例必须:

  • 描述一个真实的用户成果,而不是代码功能。"开发者使用嵌套子命令、持久化标志和 shell 补全构建一个命令行工具"——而不是"框架支持命令树。"
  • 指明一个具体的参与者以及他们试图完成的事情。参与者包括终端用户开发者、系统管理员、内核维护者、协议对端、集成者和自动化消费者。
  • 对软件的实际用户而言是可识别的。对于知名项目,请对照模型自身对该项目的了解、社区文档、教程和真实世界的采用模式来验证用例。
  • 通过可测试的满足条件至少连接到一个需求。

流水线应明确询问:"基于该项目的概览、收集的文档和已知用户群,真实用户使用该软件最重要的 5–7 件事是什么?"从这个问题推导用例——而不是通过扫描代码并将功能归入类别。

针对代码的用例验证: 从概览和文档推导出用例后,对照代码库验证每一个用例。如果某个用例描述了代码实际并不支持的内容,请修改或删除它。如果代码支持某个重要的用户成果但没有用例覆盖它,请添加一个。目标是既用户可识别又代码有依据的用例。

验收标准覆盖范围检查(强制,在用例推导之后运行)。 在用例最终确定并针对代码验证之后,检查所有需求中的满足条件是否共同覆盖了项目的主要行为:

这些验收标准合在一起,是否覆盖了该项目?概览或用例中描述的某个主要用户可见行为,如果出现故障,是否有任何需求的满足条件能够捕捉到?

对于每个用例,至少有一个需求的满足条件必须可追溯到它,并且至少有一个链接的需求必须是 specific(而非 architectural-guidance)。没有链接到任何 specific 需求的用例表示存在缺口。发现缺口时,要么:(a) 添加新需求或强化现有条件以覆盖缺口,要么:(b) 如果用例不能反映需求实际保护的内容,则修改该用例。将此检查的结果记录在完整性报告中。

用例之后是各个需求。

v1.5.3 层级与引用方案(schemas.md §3.1、§5)。 每个 REQ 按 schemas.md §3.1 携带 1–5 的 tier 整数:

  • Tier 1 — 项目自身的正式规范(一条 tier=1 的 FORMAL_DOC 记录;最高权威)。
  • Tier 2 — 外部正式标准(RFC、W3C、ISO、已发布的 API 契约——一条 tier=2 的 FORMAL_DOC 记录)。
  • Tier 3 — 不存在正式规范时的真源代码;代码即规范。
  • Tier 4 — 由 bin/reference_docs_ingest.load_tier4_context 从顶层 reference_docs/ 加载的非正式文档(AI 聊天、设计笔记、回顾)。
  • Tier 5 — 从代码行为推断,无文档依据。

对于 tier ∈ {1, 2},REQ 还按 schemas.md §5 携带一个 citation 块,包含 document、document_sha256、section/line 中至少一个,以及机械提取的 citation_excerpt。不要手工编写摘录。摘录在摄取时由 bin/reference_docs_ingest 按 schemas.md §5.4 中的确定性算法(并按 §5.5 进行章节解析)调用 bin/citation_verifier 生成——LLM 从 formal_docs_manifest.json 消费摘录;它绝不直接调用验证器。摄取时提取正是幻觉闸门第 1 层的工作方式。如果你无法在 quality/formal_docs_manifest.json 中引用某个文档(带哈希和定位符),该 REQ 至多为 Tier 3。仅 page 定位符只用于诊断,永远不充分。 Tier-1 优先于 Tier-2 规则。 当项目自身的规范(Tier 1)与外部标准(Tier 2)相互矛盾时,以 Tier 1 记录 REQ,并引用项目自身的立场。项目文档中对外部标准的偏离属于权威意图,而非缺陷——仅在项目规范对该冲突未作规定时,才适用 upstream-spec-issue 处置。

Spec-Gap 降级(有效输出状态)。 如果 formal_docs_manifest.json 中不包含任何覆盖项目自身行为的 FORMAL_DOC 记录,则每个 REQ 最终都会落在 Tier 3/4/5,运行会优雅降级为 Spec Gap Analyzer。请在完整性报告中将元发现 "0 Tier 1/2 requirements" 作为一项指标报告,而非失败。切勿伪造引文以使层级分布看起来更丰富——quality_gate.py 会在验证时按 §5.4 通过 extract_excerpt 重新调用 bin/citation_verifier,并拒绝任何 citation_excerpt 与最新提取结果不是逐字节相等的 Tier 1/2 REQ(schemas.md §10 不变量 #11)。

functional_section 是必填字段。 每个 REQ 都带有一个简短的 functional_section 字符串(例如 "Authentication"、"Bus enumeration"),用于对相关 REQ 进行分组。该字段由大模型从代码和文档中推导得出;不存在预定义的本体。阶段 2 的渲染会将这些 REQ 按上述分节分组(每个分节配一段简短引言),阶段 4 的 Council 会审查分组的连贯性。参见 schemas.md §6.1。

可追溯性是单向的:REQ → UC。 REQ 带有一个由 UC-NN ID 组成的 use_cases[] 列表。UC 记录不带有 requirements[] 反向链接——反向关系在渲染时通过查询 REQ 记录中的匹配条目推导得出(schemas.md §7)。切勿在 UC 记录上填充 requirements[] 字段。

对于每个需求,请提供以下所有字段:

  • ID:REQ-NNN(补零的三位序号)。

  • 标题:简短的单行陈述。

  • 层级:按 schemas.md §3.1 的整数 1–5。

  • 功能分区:由大模型生成的简短字符串(见上文)。

  • 引用(当 tier ∈ {1, 2} 时必填):由 bin/reference_docs_ingest 调用 bin/citation_verifier 生成;绝不手工撰写,也绝不由大模型直接调用。格式按 schemas.md §5.1。

  • 摘要 / 描述:将需求表述为可测试的断言:"X must satisfy Y" 或 "When A, the system must B"。

  • 用户故事:从调用方的视角来表述:"As a [role] doing [action], I expect [behavior] so that [outcome]。" "so that" 子句是必需的——它迫使你阐明该需求背后的意图。

  • 实现说明:代码如何实现该需求——机制、相关代码路径、设计选择。

  • 满足条件:证明该需求已满足的具体、可测试的场景。包括正常路径、边界情况和失败模式。Phase A 中被归入该需求的每个单独契约都成为一个满足条件。

  • 替代路径:必须全部满足该需求的多个代码路径、模式或入口点。替代路径正是缺陷藏身之处。

  • 用例:use_cases[] —— 该 REQ 参与的 UC-NN ID 列表。单向前向链接。

  • 参考:引用来源——规范章节、ChangeLog 条目、配置字段定义、源代码注释、issue 编号或领域知识。对于 Tier 1/2 的 REQ,citation 块承载权威定位符;自由形式的参考是补充性的。

  • 具体性:specific(可测试——必须具有代码审查者可以针对特定代码位置或行为进行核查的满足条件;这是默认值,并计入覆盖率指标)或 architectural-guidance(无法针对单个代码路径进行测试——涵盖诸如 "remain lightweight and stdlib-compatible" 或 "no_std support" 之类的横切属性;为质量章程提供依据,但不计入覆盖率指标;大多数项目应有 0–3 个 architectural-guidance 需求——超过 3 个将触发下方强制的自检)。类别 "directional" 已废弃。任何原本会被归为 "directional" 的需求,都必须要么使其具体化(具有可测试的条件),要么明确归类为 architectural-guidance。

    architectural-guidance 自检(强制,在需求推导后运行)。 统计标记为 architectural-guidance 的需求数量。应用两个边界:

    • 上限(>3): 如果数量超过 3,停下来逐一重新审视。对每个需求问:"我能否添加一个代码审查者可以针对特定代码位置进行核查的可测试满足条件?" 如果能,将其重新归类为 specific 并添加该条件。只有真正无法针对任何特定代码路径进行核查的需求才应保留为 architectural-guidance。最终数量超过 3 时,需要针对每个超出部分的需求给出明确理由,解释为何它无法被具体化。
    • 下限(15+ 个需求时为 0): 如果需求总数为 15 或更多,而 architectural-guidance 数量为 0,则重新审视需求中是否存在横切设计不变量。跨越协议层、管理资源生命周期、强制排序保证或维护兼容性契约(例如 "remain stdlib-compatible"、"preserve no_std support"、"maintain wire-format backward compatibility")的库通常有 1–3 个 architectural-guidance 需求。在完整性报告中写一句话,解释为何没有需求符合 architectural-guidance,或重新归类相应的需求。

    在完整性报告中记录数量和所有重新归类。 不要限制需求数量。 根据项目的实际情况推导出尽可能多的需求。一个小型工具可能有 20 条。一个成熟的库可能有 100 条以上。目标是完整性。

步骤 7a:文档与需求的对账

重新阅读 PROGRESS.md 中的覆盖承诺表。对于你承诺覆盖的每一份深度文档(“将在阶段 2 覆盖”),验证至少有一条需求追溯到它所记录的子系统。如果你的需求只覆盖了部分已承诺的子系统,请在完成步骤 7 之前为缺口补充需求。

对于每个子系统,在 PROGRESS.md 中记录以下内容之一:

  • 覆盖它的需求 ID,或
  • 带有理由、风险确认和推荐后续行动的明确排除项

一个深度记录的子系统带有“将覆盖”承诺却零映射需求,是流程失败,而不是合理的范围选择。在每项承诺得到满足或明确转换为有正当理由的排除项之前,不要进入产物生成阶段。

步骤 7b:代码路径 → REQ 反向可追溯性审计(强制)

时机:在阶段 E 完成后执行步骤 7a 和 7b(即,在概览验证门、用例推导和验收标准跨度检查都已运行之后)。该审计依赖于最终确定的需求和最终确定的用例。

在需求推导完成后,运行反向可追溯性审计。正向可追溯性(收集的文档 → 需求 → 缺陷 → 测试)已内置于流水线中。此步骤在代码路径粒度上检查反方向:重要的代码路径是否映射回需求条件?这是一项审计活动——不是结构化的双向链接。(v1.5.3 中的结构化可追溯性是单向的 REQ → UC,依据 schemas.md §7,并由 schema 强制执行;此审计检查代码对 REQ 的覆盖率,这是一个独立的问题。)

这工作在路径/分支/辅助函数粒度,而非文件级别。文件级覆盖率在 v1.3.13 中是 100%,却仍然漏掉了两个真实缺陷。问题不是“这个文件是否映射到某个需求?”,而是“这个重要分支是否映射到一条说明此处必须保留什么的需求条款?”

限定为四个类别(不是开放式的分支审计):

  1. 需求中已命名的替代路径。 如果某条需求提到了回退或替代路径(例如“主模式 vs. 降级模式”“协商配置 vs. 默认配置”“同步 vs. 异步”),每条替代路径都必须有明确的对称条件——即一条关于两条路径都必须保持何种不变量的陈述。一条只说“系统同时处理 X 和 Y”而未说明对每条路径而言“处理”意味着什么的需求是不完整的。

  2. 将公共常量转换为运行时行为的辅助函数。 如果某个辅助函数对已定义的常量与运行时行为之间进行白名单、过滤或转换(例如功能开关门控、编解码器注册表查找、能力白名单辅助函数),它必须有一条特定于辅助函数的需求,枚举预期保留/转换的值。

  3. 能力协商与回退逻辑。 系统与外部对端协商能力的代码路径(协议版本协商、功能检测、优雅降级)必须有针对协商成功和协商失败两条路径的需求。

  4. 在先前 BUGS.md、VERSION_HISTORY.md 或规范审计输出中命名的函数。 如果先前某次运行在特定函数中发现了缺陷,未来的运行必须展示针对该函数的明确复查证据(“已知缺陷类别哨兵”)。这可以防止“丢失需求”这一回归类别。如果 quality/spec_audits/ 中存在先前的规范审计输出,请在运行哨兵检查之前阅读它们——来自委员会审查的跨模型发现是已知缺陷表面的高价值来源。 对于每个类别,检查需求是否包含覆盖已识别路径的具体条件。孤立路径——即没有需求覆盖的重要代码路径——会在完整性报告中触发“覆盖缺口”标记。必须先解决这些缺口(通过添加需求条件或提供明确理由),完整性报告才能宣布需求充分。

延续规则: 当质量目录中存在先前运行的 REQUIREMENTS.md 时,流水线必须读取它,并检查先前版本中的任何条件是否被删除。如果条件被删除,流水线必须要么:(a) 以更新的理由重新推导这些条件,要么 (b) 记录该条件为何不再相关。不允许静默删除——它们是直接导致回归的原因,会使先前已获知的需求在运行之间丢失。

流水线之后: Phase 7 可以生成 quality/REVIEW_REQUIREMENTS.md(交互式评审协议)和 quality/REFINE_REQUIREMENTS.md(精炼轮次协议)。这些不是 Phase 2 产物——它们为 Phase 7 的交互式改进路径提供支持。用户可以交互式评审需求,使用不同模型运行精炼轮次,并为每次迭代保留带版本的备份。有关完整的版本管理协议和备份结构,请参阅 references/requirements_pipeline.md。

以结构化格式记录所有需求。这些需求会直接输入代码评审协议的验证与一致性轮次。

检查点:Phase 1 完成后更新 PROGRESS.md

v1.5.6 更新——PROGRESS.md 现在在运行开始时初始化,而不是在 Phase 1 之后。 根据本文件前面的“运行状态埋点”一节,quality/PROGRESS.md 和 quality/run_state.jsonl 会在任何阶段工作开始之前写入。到 Phase 1 的这个时点,这两个文件已经存在。此检查点是 PROGRESS.md 的 Phase 1 完成更新,而不是初始化。

PROGRESS.md 格式组合了运行状态头部(Started / Benchmark / Lever / Runner / Playbook version)、阶段检查清单(现在由 quality/run_state.jsonl 中的 phase_start / phase_end 事件驱动),以及下面的旧版内容部分(Run metadata、Artifact inventory、Cumulative BUG tracker 等)——它们是互补的,而不是相互竞争。

Phase 1 完成操作: 在阶段检查清单中将 Phase 1 标记为 [x],并附上摘要统计(findings 数量、已遍历的 patterns);将 Phase 1 产物(EXPLORATION.md 及任何子产物)添加到 Artifact inventory。根据“运行状态埋点”一节中的交叉验证规则,向 run_state.jsonl 追加一个 phase_end phase=1 事件。

PROGRESS.md 存在的原因: 在单会话运行中,Agent 将上下文保存在内存中。但上下文会在长会话中退化——Phase 1 的 findings 到 Phase 6 时已被遗忘,BUG 计数发生漂移,spec-audit bugs 因为闭包检查从未看到它们而成为孤儿。PROGRESS.md 通过让每个阶段将其状态写入磁盘来解决这个问题。Agent 在每个阶段之前将其读回,因此它始终能准确了解到目前为止发生了什么。附带的好处是,即使运行被拆分到多个会话中,它也能让 skill 正确工作。

长运行的检查点纪律: 在每个需求流水线阶段(Contracts、Requirements、Coverage Matrix、Completeness、Narrative)之后,更新 quality/PROGRESS.md,包含:已完成阶段、产物路径、当前作用域子系统、剩余工作,以及确切的恢复点。这确保恢复的会话可以从上一个已完成的检查点继续,而无需重做工作。根据 v1.5.6,还要将相应的 pass_started / pass_ended 事件追加到 run_state.jsonl。

时间戳纪律: 在完成某个阶段时立即将该阶段完成条目写入 PROGRESS.md,然后再开始下一个阶段。不要事后批量写入或回填时间戳。时间戳是审计轨迹——如果 Phase 2 显示的完成时间早于 Phase 1,审查者就无法验证各阶段是否按正确顺序运行。如果你意识到自己忘记写入检查点,请立即写入,并附上诚实的时间戳和解释缺口的说明。

v1.5.6 初始化的文件将在 Phase 1 完成时填充的完整 PROGRESS.md 格式包括以下部分(保留旧版模板,因为 Phase 5+ 依赖其 Cumulative BUG tracker 和 Terminal Gate Verification 部分):

# Quality Playbook Progress

## Run metadata
Started: [date/time]
Project: [project name]
Skill version: [read from SKILL.md metadata using the reference file resolution order — must match exactly]
With docs: [yes/no]

## Phase completion
- [x] Phase 1: Exploration — completed [date/time]
- [ ] Phase 2: Artifact generation (QUALITY.md, REQUIREMENTS.md, tests, protocols, RUN_TDD_TESTS.md) — `AGENTS.md` is generated by the orchestrator after Phase 6, not here
- [ ] Phase 3: Code review + regression tests
- [ ] Phase 4: Spec audit + triage
- [ ] Phase 5: Post-review reconciliation + closure verification
- [ ] TDD logs: red-phase log for every confirmed bug, green-phase log for every bug with fix patch
- [ ] Phase 6: Verification benchmarks
- [ ] Phase 7: Present, Explore, Improve (interactive)

## Artifact inventory
| Artifact | Status | Path | Notes |
|----------|--------|------|-------|
| QUALITY.md | pending | | |
| REQUIREMENTS.md | pending | | |
| CONTRACTS.md | pending | | |
| COVERAGE_MATRIX.md | pending | | |
| COMPLETENESS_REPORT.md | pending | | |
| Functional tests | pending | | |
| RUN_CODE_REVIEW.md | pending | | |
| RUN_INTEGRATION_TESTS.md | pending | | |
| BUGS.md | pending | | |
| RUN_TDD_TESTS.md | pending | | |
| RUN_SPEC_AUDIT.md | pending | | |
| tdd-results.json | pending | quality/results/ | Structured TDD output |
| integration-results.json | pending | quality/results/ | Structured integration output |
| Bug writeups | pending | quality/writeups/ | One per TDD-verified bug |

## Cumulative BUG tracker


| # | Source | File:Line | Description | Severity | Closure Status | Test/Exemption |
|---|--------|-----------|-------------|----------|----------------|----------------|



## Terminal Gate Verification


## Exploration summary
[Brief notes on architecture, key modules, spec sources, defensive patterns found]

在每个阶段之后更新此文件。累积 BUG tracker 是最重要的部分——它确保无论 finding 由哪个阶段产生,都不会成为孤儿。

将探索 findings 写入磁盘

在初始化 PROGRESS.md 之后,将你的完整探索 findings 写入 quality/EXPLORATION.md。此文件记录你在 Phase 1 中学到的一切,以便它能在上下文边界(会话中断、多轮交接或长运行内存退化)中存续。按如下结构组织:

# Exploration Findings

## Domain and Stack
[Language, framework, build system, deployment target]

## Architecture
[Key modules with file paths, entry points, data flow, layering]

## Existing Tests
[Test framework, test count, coverage areas, gaps]

## Specifications
[What reference_docs/ contains, key spec sections, behavioral rules]

## Open Exploration Findings
[At least 8 concrete findings from domain-driven investigation.
Each must have a file path, line number, and specific bug hypothesis.
At least 4 must reference different modules or subsystems.
At least 3 must trace a behavior across 2+ functions.]

## Quality Risks
[At least 5 domain-driven failure scenarios ranked by priority.
Each must name a specific function, file, and line and explain the failure
mechanism using domain knowledge of what goes wrong in systems like this.
These are hypotheses, not confirmed bugs — they tell Phase 2 where to look.
Frame each as: "Because [code at file:line] does [X], a [domain-specific
edge case] will produce [wrong behavior] instead of [correct behavior]."
A section that lists defensive patterns the code already has does NOT belong here.]

## Skeletons and Dispatch
[State machines, dispatch tables, feature registries — with file:line citations]

## Pattern Applicability Matrix
| Pattern | Decision (`FULL` / `SKIP`) | Target modules | Why |
|---|---|---|---|
| Fallback and Degradation Path Parity | | | |
| Dispatcher Return-Value Correctness | | | |
| Cross-Implementation Consistency | | | |
| Enumeration and Representation Completeness | | | |
| API Surface Consistency | | | |
| Spec-Structured Parsing Fidelity | | | |

[3 to 4 patterns must be marked FULL. The rest are SKIP with codebase-specific rationale. Select 4 when a fourth pattern clearly applies and covers different code areas.]

## Pattern Deep Dive — [Pattern Name]
[Use the output format from `exploration_patterns.md`.
Trace the relevant code path across 2+ functions, implementations, or API surfaces.
Each deep dive should pressure-test, refine, or extend findings from the open
exploration and quality risks stages.]

## Pattern Deep Dive — [Pattern Name]
[Repeat for each selected FULL pattern. 3 to 4 deep-dive sections total.]

## Pattern Deep Dive — [Pattern Name]
[Third and final deep dive.]

## Candidate Bugs for Phase 2
[Consolidated from ALL earlier sections — open exploration, quality risks, AND patterns.
Minimum 4 candidates with file:line references. At least 2 from open exploration or
quality risks, at least 1 from a pattern deep dive. For each candidate include the
source stage and what the Phase 2 code review should inspect.]

## Derived Requirements
[REQ-001 through REQ-NNN, each with spec basis and tier]

## Derived Use Cases
[UC-01 through UC-NN, each with actor, trigger, expected outcome]

## Notes for Artifact Generation
[Anything the next phase needs to know — naming conventions, test patterns, framework quirks]

## Gate Self-Check
[Written by the Phase 1 gate. Each check 1–12 with PASS/FAIL and one-line evidence.
This section proves the gate was executed. Do not write this section until you have
actually verified each check against the file contents.]

最低深度预期: EXPLORATION.md 必须包含至少 120 行实质性内容——不是填充内容或样板标题,而是实际 findings(文件路径、行为规则、推导出的需求、架构观察)。一个只列出章节标题和单行占位符的骨架不是有效的交接产物。如果文件比这更单薄,请返回并添加 Phase 2 将需要的细节。 写完后重新读取(强制)。 写完 EXPLORATION.md 后,在进入 Phase 2 之前,必须显式地从磁盘重新读取该文件。这有两个目的:(1) 确认文件已正确写入,(2) 将结构化的发现加载到工作记忆中,用于生成产物。不要跳过这一步并依赖你记忆中写过的内容——“先写后读”循环是上下文桥梁。

该文件在所有模式下都必不可少。在单遍模式下,它迫使模型在生成产物之前明确表述具体的发现(文件路径、函数名、行号)。在多遍模式下,它也是各遍之间的交接产物。无论哪种方式,先写后读循环都是探索深度的质量门。

Phase 1 完成门(强制——在 Phase 2 之前停在此处)。 在进入 Phase 2 之前,你必须执行此门。这不是可选项。从磁盘重新读取 quality/EXPLORATION.md 并运行以下每一项检查。检查完成后,在 EXPLORATION.md 底部追加一个 ## Gate Self-Check 部分,列出每个检查编号(1–12)及其 PASS 或 FAIL,并附上一行证据说明。如果任何检查失败,修复 EXPLORATION.md 并重新运行该门。在所有检查通过且 Gate Self-Check 部分已写入磁盘之前,不要进入 Phase 2。

常见的绕过门失败模式: 在 v1.3.43 基准测试中,两个仓库(chi、zod)生成的 EXPLORATION.md 文件章节结构完全错误——章节标题为“Architecture summary”“Behavioral contracts”“Repository and architecture map”,而不是所要求的章节。模型从未运行门检查,直接进入 Phase 2,产生了零个 bug。如果你的 EXPLORATION.md 不包含下列具有精确标题的章节,则不符合规范,必须在继续之前重写。

  1. 文件存在于磁盘上,且包含至少 120 行实质性内容。
  2. quality/PROGRESS.md 存在,并标记 Phase 1 已完成。
  3. Derived Requirements 部分至少包含一个 REQ-NNN,其中带有具体的文件路径和函数名——而不是抽象的子系描述。
  4. 存在标题恰好为 ## Open Exploration Findings 的部分,且包含至少 8 个具体的 bug 假设或可疑发现,每个都带有文件路径和行号。这些必须来自领域驱动的调查,而不仅仅是套用模式。至少 4 个必须引用不同的模块或子系统。
  5. 开放探索深度检查: ## Open Exploration Findings 中至少有 3 个发现必须跨 2 个或更多函数或 2 个具体代码位置追踪同一行为。仅列出一系列孤立的单函数疑点不足以达到此深度。
  6. 存在标题恰好为 ## Quality Risks 的部分,且包含至少 5 个按优先级排序的领域驱动失败场景。每个场景必须:(a) 指明具体的函数、文件和行号,(b) 描述领域特定的边界情况或失败模式,以及 (c) 解释为什么代码会产生错误行为。这些必须来自关于此类系统会出什么问题的领域知识——而不是仅来自对代码的结构分析。列出代码已具备的防御性模式(即代码做对的事情)的部分不满足此门槛。列出有风险的模块但没有具体失败场景的部分不满足此门槛。得出该库已成熟、不太可能有基础 bug 这一结论的部分不满足此门槛。
  7. 存在标题恰好为 ## Pattern Applicability Matrix 的部分,并评估 exploration_patterns.md 中的所有六个模式,将每个标记为 FULL 或 SKIP,并附上目标模块和针对具体代码库的理由。
  8. 适用性矩阵中标记为 FULL 的模式数量在 3 到 4 个之间(含)。
  9. 标题以 ## Pattern Deep Dive — 开头的部分数量在 3 到 4 个之间(含)。每个部分必须包含具体的 file:line 证据,而不仅仅是模式名称占位符。数量必须与矩阵中 FULL 模式的数量一致。
  10. 模式深度检查: 至少有 2 个模式深挖部分必须跨 2 个或更多函数追踪一条代码路径。只说“file:line 处的函数 X 存在缺口”的部分属于表面发现。只说“file:line 处的函数 X 调用 file:line 处的函数 Y,后者做了 A 但没做 B;与两者都做的函数 Z 对比”的部分属于深度发现。
  11. 存在标题恰好为 ## Candidate Bugs for Phase 2 的部分,且包含至少 4 个按优先级排序的 bug 假设,带有 file:line 引用、每个假设浮现的阶段(开放探索、质量风险或模式),以及代码审查应关注的内容。
  12. 集合平衡检查: 至少有 2 个候选 bug 必须源自开放探索或质量风险,且至少有 1 个必须源自模式深挖或由模式深挖实质性强化。这确保领域知识和结构分析两方面的发现都流入 Phase 2。

在全部十二项检查通过且 ## Gate Self-Check 部分已写入磁盘上的 EXPLORATION.md 之前,不要开始 Phase 2。Phase 1 是你深入理解代码库的唯一机会。你在这里遗漏的每一条要求,都是你在 Phase 3 中找不到的一个 bug。请投入时间。

如果你发现自己即将在没有写下 Gate Self-Check 部分的情况下开始 Phase 2,请停下。 回去运行门禁。这条指令之所以存在,是因为模型在对自己探索感到自信时会可靠地跳出门禁——而那种自信恰恰是 bug 被遗漏的时候。

阶段结束消息(强制——在 Phase 1 完成后打印此消息,然后停止):

# Phase 1 Complete — Exploration

I've finished exploring the codebase and written my findings to `quality/EXPLORATION.md`.
[Summarize: how many candidate bugs, which subsystems explored, key risks identified.]

To continue to Phase 2 (Generate quality artifacts), say:

    Run quality playbook phase 2.

Or say "keep going" to continue automatically.

打印此消息后,停止。除非用户明确要求,否则不要继续进入 Phase 2。


Phase 2: Generate the Quality Playbook

v1.5.6 埋点: 立即将 phase_start phase=2 追加到 quality/run_state.jsonl。阶段结束时,通过调用 bin/run_state_lib.validate_phase_artifacts(quality_dir, 2) 进行交叉验证——它会检查完整的 Generate 契约(REQUIREMENTS.md、QUALITY.md、CONTRACTS.md、COVERAGE_MATRIX.md、COMPLETENESS_REPORT.md、RUN_CODE_REVIEW.md、RUN_INTEGRATION_TESTS.md、RUN_SPEC_AUDIT.md、RUN_TDD_TESTS.md,外加一个非空的 quality/test_functional.<ext>)。如果验证通过,追加 phase_end phase=2。如果验证失败,追加一个带有 recoverable: true 的 error 事件,并重新运行缺失产物的生成。(BUG-014 修复:在 v1.5.6 之前,此说明引用的是从未发布的 v1.5.5 设计版 triage 模型。)

本阶段的必需参考资料 —— 在继续之前阅读以下内容:

  • quality/EXPLORATION.md —— 你的 Phase 1 发现(架构、需求、用例、模式分析)
  • references/requirements_pipeline.md —— 用于需求推导的五阶段流水线
  • references/defensive_patterns.md —— 用于查找防御性代码的 grep 模式
  • references/schema_mapping.md —— 用于 schema 感知测试的字段映射格式
  • references/constitution.md —— QUALITY.md 模板
  • references/functional_tests.md —— 测试结构与反模式
  • references/review_protocols.md —— 代码审查与集成测试模板

Phase 2 源码修改防护栏(强制 —— 硬性停止)。 Phase 2 仅写入 quality/。请勿在目标仓库的 quality/ 目录之外创建、修改或删除任何文件——这包括(但不限于)AGENTS.md、CLAUDE.md、README.md、bin/**、.github/**、.claude/**、references/**、agents/**、SKILL.md、schemas.md、源代码或测试文件。目标仓库的 AGENTS.md 由编排器在 Phase 6 完成后生成;如果你在 Phase 2 写入 AGENTS.md,你将触发编排器的源码未变更不变量,并导致运行中止。2026-04-30 的 codex bootstrap 测试正是以这种方式失败的:一个 Phase 2 LLM 更新了现有的 AGENTS.md(因为更早的 SKILL.md 说明要求它这样做),源码未变更门禁检测到该修改,运行在 Phase 3 之前中止。如果生成的产物自然应位于 quality/ 之外,请将其写入 quality/ 下,并让编排器在最终化期间移动或复制它。唯一允许的例外是 quality/PROGRESS.md,它本身就在 quality/ 内。

Phase 2 入口门禁(强制 —— 硬性停止)。 在生成任何产物之前,从磁盘读取 quality/EXPLORATION.md,并验证以下所有确切的章节标题均存在(使用 grep 或搜索——不要依赖记忆):

  1. quality/EXPLORATION.md 必须至少有 120 行——文件更短表明探索不完整
  2. ## Open Exploration Findings —— 必须逐字存在
  3. ## Quality Risks —— 必须逐字存在
  4. ## Pattern Applicability Matrix —— 必须逐字存在
  5. 至少有 3 个以 ## Pattern Deep Dive — 开头的章节 —— 必须逐字存在
  6. ## Candidate Bugs for Phase 2 —— 必须逐字存在
  7. ## Gate Self-Check —— 必须存在(证明 Phase 1 门禁已运行)
  8. quality/PROGRESS.md 存在,且其 Phase 1 行被标记为 [x] —— 证明 Phase 1 已完成,而不仅仅是已开始
  9. ## Open Exploration Findings 章节包含至少 8 个具体的 bug 假设 —— 统计带有 file:line 引用的行
  10. ## Open Exploration Findings 中至少有 3 个发现在 2 个以上函数之间追踪行为 —— 寻找多位置追踪
  11. ## Pattern Applicability Matrix 中有 3 到 4 个模式被标记为 FULL —— 统计 FULL 条目
  12. 至少有 2 个模式深度剖析章节在 2 个以上函数之间追踪代码路径 —— 寻找多函数追踪
  13. ## Candidate Bugs for Phase 2 中有 ≥2 个来自开放探索/风险的 bug,且 ≥1 个来自模式深度剖析 —— 检查来源阶段标签 如果文件不存在、少于 120 行,或缺少以下任一确切章节标题,请停止并返回 Phase 1。不要试图以不同名称的“等价”章节继续——上述确切标题是必需的。现在编写 EXPLORATION.md,先进行领域驱动的开放探索,再进行领域知识风险分析,然后从 references/exploration_patterns.md 中选择 3–4 个模式进行深入分析。在 EXPLORATION.md 通过 Phase 1 完成关卡之前,不要继续进行 Phase 2。此检查之所以存在,是因为单遍执行可能会跳过 Phase 1 关卡——这是兜底措施。在 v1.3.43 中,两个仓库绕过了两个关卡,产生了零个 bug。

使用 quality/EXPLORATION.md 作为本阶段的主要来源——不要从头重新探索代码库。探索发现包含架构图、派生需求、用例和风险分析,它们驱动着下面的每一个产物。如果你发现自己正在阅读源文件以弄清项目做什么,请回到 EXPLORATION.md。重新探索会浪费上下文,并导致 Phase 1 的发现与 Phase 2 生成的内容之间不一致。

现在编写 Phase 2 产物。上述需求流水线产出了 REQUIREMENTS.md、CONTRACTS.md、COVERAGE_MATRIX.md 和 COMPLETENESS_REPORT.md。下面的七个文件补全整个集合。对于每个文件,请遵循下面的结构,并查阅相关参考文件以获取详细指导。

版本戳记(每个生成文件上强制)。 playbook 生成的每个 Markdown 文件必须在文件标题标题之后立即以以下归属行开头:

> Generated by [Quality Playbook](https://github.com/andrewstellman/quality-playbook) v1.5.3 — Andrew Stellman
> Date: YYYY-MM-DD · Project: <project name>

每个生成的代码文件(测试文件、脚本)必须以注释头开头:

# Generated by Quality Playbook v1.5.6 — https://github.com/andrewstellman/quality-playbook
# Author: Andrew Stellman · Date: YYYY-MM-DD · Project: <project name>

使用适合该语言的注释语法(#、//、/* */ 等)。戳记中的版本必须与此技能 frontmatter 中的 metadata.version 匹配。此戳记使每个生成的产物都可追溯到创建它的工具、版本和运行——当文件通过电子邮件发送、附加到工单或在仓库上下文之外被审查时,这至关重要。使用 playbook 生成开始的日期,而不是每个单独文件写入的日期。

戳记放置与豁免:

  • 对于带有编码 pragma(# -*- coding: utf-8 -*-)或 shebang(#!/usr/bin/env python)的 Python 文件,请将戳记注释放在 pragma/shebang 之后,而不是之前——将其推到第 2 行之后会引发 SyntaxWarning。
  • 对于 sidecar JSON 文件(tdd-results.json、integration-results.json),skill_version 字段已充当版本戳记。JSON 不支持注释——不要注入注释。
  • 对于 JUnit XML 文件,不需要戳记——这些由框架生成。
  • 对于 .patch 文件,不要将戳记注入 diff 正文——这会破坏 git apply。请依赖周围的产物元数据(BUGS.md、tdd-results.json)来确定来源。

产物依赖规则:

  • quality/RUN_CODE_REVIEW.md Pass 2 依赖于稳定的 quality/REQUIREMENTS.md——薄弱的需求会产生薄弱的 Pass 2 审查。如果需求数量相对于代码表面积似乎偏低(每个核心模块少于约 3–4 个需求),请在 Pass 2 报告开头注明这一点。
  • 功能测试依赖于 quality/REQUIREMENTS.md 和 quality/QUALITY.md——在任何需求细化之后,请重新验证 test_functional.* 仍覆盖每个需求。
  • quality/RUN_SPEC_AUDIT.md 依赖于需求、质量场景和文档验证。
  • quality/COMPLETENESS_REPORT.md 有两个阶段:基线(审查前,无 verdict 章节)和最终(Phase 5 中协调后,带权威 verdict)。
  • quality/PROGRESS.md 是权威状态文件,必须在每个下游产物开始之前更新。 为什么是九个文件,而不只是测试? 测试能捕获回归,但无法阻止新类别的 bug。质量宪法(QUALITY.md)在未来的会话开始写代码之前,就告诉它们“正确”意味着什么。协议(RUN_*.md)为评审、集成测试和规格审计提供了结构化的流程,从而产生可复现的结果——而不是把质量交给 AI 想检查什么就检查什么。这些文件共同构成了一套质量体系,其中每一部分都强化其他部分:QUALITY.md 中的场景映射到功能测试文件中的测试,这些测试由集成协议验证,再由三人委员会审计。
v1.5.3 JSON manifest 纪律(在编写任何产物之前阅读)

Phase 2 会为每条派生的记录写出两份并行的呈现:一份 JSON manifest(机器可读,经 gate 校验——唯一事实来源)和一份 Markdown artifact(人类可读,由 manifest 渲染而来)。某个 phase 脚本只更新其中一个而不更新另一个,就是 bug。

Manifest 位于:

  • quality/formal_docs_manifest.json —— 由 Phase 1 中的 bin/reference_docs_ingest.py 写入。请勿重写。
  • quality/requirements_manifest.json —— 按 schemas.md §6 的权威 REQ 记录。
  • quality/use_cases_manifest.json —— 按 schemas.md §7 的权威 UC 记录。
  • quality/bugs_manifest.json —— 按 schemas.md §8 的权威 BUG 记录。在 Phase 3/4/5 确认 bug 之后写入。
  • quality/citation_semantic_check.json —— Phase 4 委员会第 2 层的裁决(见下方 Phase 4)。

每个 manifest 都遵循 §1.6 的包装结构,包含 schema_version、generated_at 和一个顶层记录数组。四个记录形态的 manifest(formal_docs_manifest.json、requirements_manifest.json、use_cases_manifest.json、bugs_manifest.json)使用 records 作为数组键:

{
  "schema_version": "<from SKILL.md metadata.version>",
  "generated_at": "<ISO 8601 with explicit Z timezone>",
  "records": [ /* per-schema records, per schemas.md §4–§8 */ ]
}

例外——citation_semantic_check.json 按 schemas.md §9.1 使用 reviews 而非 records。包装结构相同,数组键不同;其中的记录是委员会评审条目,而非 REQ/UC/BUG 记录。如果你发现自己往 citation_semantic_check.json 里写 records,请停下来重新阅读 schemas.md §9——当键写错时,gate 会将此文件作为 manifest 包装违规拒绝(schemas.md §10 不变式 #13)。

schema_version 在生成时必须等于本 skill 的 metadata.version——从 SKILL.md 读取,不要硬编码。generated_at 使用 datetime.now(timezone.utc).isoformat(timespec="seconds").replace("+00:00", "Z")。记录形态和不变式在 schemas.md 中定义——不要在本 skill 中重新定义它们。quality_gate.py(Phase 5/6)会依据这些 schema 逐字段校验 manifest。

REQUIREMENTS.md 渲染约定。 REQUIREMENTS.md 按 functional_section 组织。每个 section 以一段由大模型撰写的简短引言开头,描述该功能领域的作用,然后列出其下的 REQ(按 REQ id 排序)。用例渲染其 formal_doc_refs,但不列出 requirements[]——可追溯性是单向的 REQ → UC,反方向在渲染时通过查询 REQ 记录派生。

文件 1:quality/QUALITY.md — 质量宪章

阅读 references/constitution.md 获取完整模板和示例。

宪章包含六个部分:

  1. 目的 — 质量对本项目意味着什么,植根于戴明(质量是构建出来的,而非检验出来的)、朱兰(适用性)、克劳斯比(质量是免费的)。具体应用这些理念:对于这个系统,“适用性”意味着什么?不是“测试通过”,而是实际的运行要求。
  2. 覆盖率目标 — 表格将每个子系统映射到一个目标,并附上引用真实风险的依据。每个目标都必须有一个以具体场景为基础的“为什么”——没有它,未来的 AI 会话就会把目标压低。
  3. 覆盖率表演预防 — 项目中虚假测试的具体示例,来源于你在探索过程中看到的内容。(为什么:AI 生成的测试常常在虚增覆盖率数字,却没有捕获真正的缺陷——断言导入成功、字典有键,或者 mock 返回了它们被配置为返回的内容。明确指出这一点可以阻止这种模式。)
  4. 适用性场景 — 这是核心。每个场景记录一个现实的失败模式,附上代码引用和验证方法。每个核心模块至少要有 2 个场景——中型项目通常总共 8–10 个,小型项目更少,复杂项目更多。质量比数量更重要:一个精确捕捉到真实架构脆弱点的场景,胜过三个泛泛的场景。(为什么:覆盖率百分比告诉你运行了多少代码,而不是它是否正确运行。一个系统可以有 95% 的覆盖率,却仍然静默丢失记录。适用性场景以任何人都无法辩驳的具体方式定义了“正确运行”究竟意味着什么。)
  5. AI 会话质量纪律 — 每个 AI 会话都必须遵守的规则
  6. 人工关卡 — 需要人类判断的事项

场景的语气至关重要。 把“发生了什么”写成带有具体数量、级联后果和检测难度的架构脆弱性分析——而不是抽象规格说明。“因为 save_state() 缺少原子重命名模式,在 10,000 条记录的批处理过程中发生写入中途崩溃,会留下损坏的状态文件——下一次运行会得到 JSONDecodeError,无法恢复。在规模化运行时,这可能导致 1,693+ 条记录静默丢失,且没有检测机制。”读到这段内容的 AI 会话就不会把标准压低。运用你对类似系统的了解来生成现实的失败场景,然后将其扎根于你实际探索过的代码中。场景既来自代码探索,也来自关于此类系统会出什么问题的领域知识。

每个场景的“如何验证”都必须映射到功能测试文件中至少一个测试。

文件 2:功能测试

这是最重要的交付物。 阅读 references/functional_tests.md 获取完整指南。

将测试组织为三个逻辑分组(类、describe 块、模块,或测试框架使用的任何形式):

  • 规格需求 — 每个可测试的规格章节对应一个测试。每个测试的文档都要引用它所验证的规格需求。
  • 健壮性场景 — 每个 QUALITY.md 场景对应一个测试。1:1 映射,命名保持一致。
  • 边界与边缘情况 — 步骤 5 中的每个防御模式对应一个测试。

关键规则:

  • 完全匹配现有的导入模式。 阅读现有测试如何导入项目模块,并照做。弄错了就意味着每个测试都会失败。
  • 在调用每个函数之前先阅读其签名。 阅读实际的 def 行——参数名、类型、默认值。从项目中读取真实数据文件以理解数据形态。不要猜测函数参数或 fixture 结构。
  • 不要占位测试。 每个测试都必须导入并调用实际的项目代码。如果函数体是 pass,或者断言毫无意义(assert isinstance(x, list)),就删掉它。不执行项目代码的测试会虚增数量并制造虚假信心。
  • 测试数量启发式 =(可测试的规格章节数)+(QUALITY.md 场景数)+(防御模式数)。对于中型项目(5–15 个源文件),这通常会产生 35–50 个测试。明显偏少说明遗漏了需求或探索不够深入。明显偏多也没问题,只要每个测试都有意义——不要为了凑数而填充。
  • 跨变体启发式:约 30% — 如果项目处理多种输入类型,争取让大约 30% 的测试在所有变体上参数化。确切百分比不如确保每个横切属性都在所有变体上得到测试重要。
  • 测试结果,而非机制 — 断言规格说应该发生什么,而不是代码如何实现它。
  • 使用符合 schema 的变更 — 边界测试必须使用 schema 接受的值(来自步骤 5b),而不是它拒绝的值。
文件 3:quality/RUN_CODE_REVIEW.md

阅读 references/review_protocols.md 获取模板。

代码审查协议有三个轮次。每一轮都独立运行——一个全新的会话,除了需求文档之外没有共享上下文。这种清晰的分离防止了结构审查和基于需求的审查之间的交叉污染。

第 1 轮 — 结构审查。 阅读代码并发现异常。这是每个 AI 代码审查工具都已经擅长的事情。没有需求,没有关注领域——只有模型自身对代码正确性的知识。保留这些强制性的护栏:

  • 行号是强制性的——没有行号,就没有发现
  • 阅读函数体,而不仅仅是签名
  • 如果不确定:标记为 QUESTION,而不是 BUG
  • 在声称缺失之前先 grep
  • 不要建议风格更改——只标记不正确的内容

第 1 轮最低要求的审查领域(逐一明确处理):

  1. 输入校验与边界处理 — 检查外部数据或调用方提供的数据进入代码的每一个信任边界。每个字符串解析器、枚举查找和二进制格式解析器都必须拒绝那些与合法 token 共享有效前缀但包含额外字符的输入。

  2. 资源生命周期 — 分配、引用计数管理、错误路径清理、失败时的锁释放、文件描述符/句柄生命周期。每个获取引用或资源的函数都必须在每一条提前退出路径上释放它,或者必须在获取资源之前完成所有校验。

  3. 并发与状态管理 — 锁顺序、原子操作正确性(对共享状态字的每一次原子修改都必须使用读-改-写语义,并保留目标修改之外的位)、状态机完整性(所有消费者处都处理所有状态)。

  4. 单位与编码正确性 — 从硬件、协议结构或用户输入读取的每个具有既定单位的字段,在用于计算或比较之前都必须正确转换。

  5. 枚举与白名单完整性 — 当函数使用 switch/case、match、if-else 链或任何分支结构来处理一组命名常量(特性位、枚举值、事件类型、命令码、权限标志)时,执行一次机械枚举检查:

    (a) 列表 A(代码提取): 如果该函数存在 quality/mechanical/<function>_cases.txt 产物,则将其作为代码侧的权威列表使用 — 不要手动重新提取。如果不存在机械产物,则提取代码中实际存在的每一个分支/case 标签。逐个列出并附上准确行号:"line 3511: case VIRTIO_RING_F_INDIRECT_DESC"、"line 3513: case VIRTIO_RING_F_EVENT_IDX" 等。仅从代码中提取此列表 — 不要从 REQUIREMENTS.md、CONTRACTS.md 或任何其他生成的产物中复制。 如果你无法为某个 case 标签引用行号,则它并不存在。

    (b) 列表 B(规范提取): 列出相关头文件、枚举或规范中定义的、应当被处理的每一个常量。

    (c) 差异比对: 比较两个列表。对于列表 B 中的每个常量,将其标记为 "FOUND (line NNN)" 或 "NOT IN CODE"。报告任何已定义但未被处理的常量。

    在没有执行这两个列表的比对之前,不要断言某个白名单"覆盖所有值"或"保留受支持的位"。 AI 模型在 switch/case 结构上会可靠地幻觉出完整性 — 模型看到函数,看到其他地方定义的常量,就假定已覆盖,而不检查每个 case 标签。这种幻觉最危险的形式是从上游产物(如 REQUIREMENTS.md)复制,该产物断言某个常量存在,而不是从代码中提取。在 v1.3.17 中,代码审查的"存在的 case 标签"列表与需求列表逐字相同 — 证明它是被复制的而不是被提取的。带逐标签行号的机械检查就是修复方案。

这五个领域必须作为带标签的子节出现在 Pass 1 报告中。如果项目没有有意义的并发,请明确说明并记录原因,而不是省略该节。根据情况在五个领域之外增加项目特定的审查领域。

Pass 1 能捕获约 65% 的真实缺陷:竞态条件、空指针隐患、资源泄漏、差一错误、类型不匹配 — 这些是代码中可见的结构性问题。

Pass 2 — 需求验证。 对于 Phase 1 的 Step 7 中推导出的每条可测试需求,检查代码是否满足它。对于每条需求,要么展示满足它的代码,要么具体解释为何不满足。这是一次纯粹的验证过程 — 审查者的唯一职责是"代码是否满足这条需求?"不是一般性审查。不是寻找其他 bug。只是验证。 最低证据规则: 第 2 遍必须为每条需求至少引用一个代码位置(文件:行号 或 文件:函数)。诸如“REQ-003 到 REQ-012 —— 由本遍审查的客户端路径满足”这类笼统的满足声明,若没有逐条需求的代码引用,则不满足第 2 遍的要求。如果两三条需求由同一函数满足,可引用该函数一次并列出这些具体需求 —— 但每条需求必须单独出现,并带有各自的 SATISFIED/VIOLATED 判定,而不能作为未经核实的范围的一部分。一次引用下涵盖超过三条需求,说明验证流于表面。关键在于可追溯性 —— 阅读第 2 遍的审查者应当能够从任意单条需求沿证据链追溯到满足它的代码,而无需重读整个代码库。

枚举完整性声明需要机械证明。 在评估涉及白名单、查找表、特性位集合、处理器注册表,或任何形式为“所有 X 都由 Y 覆盖”的声明时,审查者必须执行第 1 遍审查领域 5 中的双列表枚举检查:从代码中提取每一项(带行号),从规范中提取每一项,然后做差集。代码侧列表必须从源码中重新提取 —— 不得复用来自 REQUIREMENTS.md、CONTRACTS.md、代码审查提示词或任何其他生成产物的列表。 如果代码侧列表与需求列表逐字一致,说明该列表是复制而来而非提取而来,检查必须重做。

不要因为阅读了函数并相信它处理了一切,就把这样的需求标记为 SATISFIED —— 这正是本规则要防止的特定幻觉模式。例如:一条需求说“传输特性白名单必须保留所有支持的 ring 特性”。审查者阅读 vring_transport_features(),看到它有一个 switch/case。正确的检查是:提取每个 case 标签及其行号(line 3511: INDIRECT_DESC、line 3513: EVENT_IDX、……、line 3527: default),然后列出头文件常量,再求差集。幻觉则是:“白名单保留了受支持的位,包括 VIRTIO_F_RING_RESET”,却没有检查 RING_RESET 是否真的作为 case 标签出现。这一确切的失败模式已在多个版本的实践中被观察到 —— 模型断言覆盖了一个 switch 中并不存在的常量,而在 v1.3.17 中,代码审查的“存在的 case 标签”列表是从需求复制而来,而非从代码提取,导致三位独立的规范审计者继承了这一错误声明。

第 2 遍捕捉单条需求的违规情况 —— 即代码没有做到规范所说它应做的事。这能发现结构性审查漏掉的缺陷,因为那里存在的代码是正确的;缺陷在于缺失的部分或不匹配规范的部分。

第 3 遍 —— 跨需求一致性。 比较引用同一字段、常量、范围或安全策略的需求对。对于每一对,核实其约束是否相互一致。数值范围是否与位宽匹配?安全策略是否传播到所有连接类型?一个文件中的验证边界是否与另一文件中的编码限制一致?

第 3 遍捕捉两段各自正确的代码在共享约束上相互矛盾的冲突。这些缺陷对结构性审查和逐条需求验证都是不可见的,因为每条需求单独来看都是满足的 —— 缺陷只有在比较它们时才显现。这一遍正是捕捉跨文件算术缺陷以及安全配置未传播到所有连接路径的设计缺口的那一遍。 源代码边界规则: playbook 绝不能修改 quality/ 目录之外的文件。所有源代码树的变更——bug 修复、向项目自身测试套件添加的测试——都必须以 git diff 格式的补丁文件形式保存在 quality/patches/ 下。这确保原始源代码树保持不变,补丁可审查且可回滚,并且 playbook 的发现与其所审计的代码可以清晰分离。

BUGS.md: 在所有审查与审计阶段之后,生成 quality/BUGS.md——一份合并的 bug 报告,为每个已确认的 bug 提供完整的复现细节。对于每个 bug,包含:bug ID、来源(代码审查或规范审计)、file:line、描述、严重程度、最小复现场景(什么输入或序列会触发该 bug)、预期行为与实际行为、对回归测试及任何拟议修复补丁的引用,以及 规范依据。

BUGS.md — v1.5.3 BUG 记录字段(schemas.md §8)。 每一条 BUGS.md 条目(以及每一个 quality/writeups/BUG-NNN.md)都对应一条写入 quality/bugs_manifest.json 的 BUG 记录。除上述叙述性约定外,每个 BUG 还带有:

  • id — BUG-NNN 零填充的三位数字序列。
  • divergence_description — 一段话概述文档化意图与代码行为之间的分歧。
  • documented_intent — REQ / 规范语言的直接引用或接近原文的转述。
  • code_behavior — 代码实际做了什么,附带 file:line 引用。
  • disposition — 来自 schemas.md §3.2 的枚举:code-fix | spec-fix | upstream-spec-issue | mis-read | deferred。必填,不可为空。不要发明新的取值。
  • disposition_rationale — 一段话解释为何选择此 disposition 而非相邻的另一个(例如,为何是 code-fix 而非 upstream-spec-issue,或为何是 spec-fix 而非 mis-read)。公式化的理由("代码错了因为规范这么说")无法通过 Council 审查。
  • req_id — 单数。揭示该分歧的主要 REQ。如果一个 bug 看似涉及多个 REQ,则按每个 REQ 拆分为一个 bug,共享同一根因,并在 disposition_rationale 中交叉链接(schemas.md §8.1)。不要将多个 REQ ID 塞进一条记录。
  • proposed_fix — 除非 disposition == "mis-read",否则必填。当 fix_type ∈ {code, both} 时为补丁形式;当 fix_type == "spec" 时为文本红线形式。对于 mis-read 记录,该字段可选,若存在,则记录重新阅读(playbook 误读了什么以及如何确立正确读法),而非一次已交付的变更。
  • fix_type — 来自 schemas.md §3.4 的枚举:code | spec | both。disposition × fix_type 的组合受 §3.4 的合法组合矩阵约束(由 §10 不变量 #12 强制执行)。非法配对:code-fix × spec、spec-fix × code、upstream-spec-issue × code、mis-read × both。在撰写记录前查阅该矩阵——闸门会拒绝非法组合。

分歧框架(writeup 语态,schemas.md v1.5.3)。 缺陷是文档化意图与代码实现之间的分歧——而非关于代码是否"好"的判断。writeup 的开篇部分(Summary、Spec reference、The code)是 divergence_description、documented_intent 和 code_behavior 的人读呈现。将它们写得读起来像一份 并排 diff,而非叙事。读者应当能够将 REQ/规范语言与代码行为并排扫视,立刻看到差距。对抗性语气("代码很草率")或标题中的价值判断("草率的 trailer 处理")不符合这一框架——bug 是对分歧的观察,而非指控。上游维护者会就 disposition(code-fix 与 spec-fix 与 upstream-spec-issue)进行讨论,而非为代码辩护以对抗批评。 什么算作足以确认 bug 的充分证据(关键)。 一个能够证明特定行为违规的代码路径追踪,就是确认 bug 的充分证据。你并不需要已执行的请求级证据、运行中的测试,或集成级复现,才能将一项发现从候选升级为已确认。具体而言:

  • 一个代码路径追踪,显示函数 A 调用函数 B,而 B 执行了 X 却本应执行 Y,并附有 file:line 引用 —— 足以确认。
  • 通过枚举对比识别出的缺失分支/用例(规范说应处理 X,代码中却没有针对 X 的处理程序)—— 足以确认。
  • 在 Pass 2 中识别出的需求违规,且代码可证明未实现所规定的行为 —— 足以确认。
  • 一项领域知识发现,且你能够从输入经由具体代码追踪到错误输出 —— 足以确认。

不要要求"已执行的请求级证据",也不要因为"需要运行时测试才能区分实现选择与规范缺口"而搁置发现。如果规范或文档说行为应为 X,而代码可证明地产生 Y(可沿代码路径追踪),那这就是已确认的 bug —— 而不是等待运行时验证的候选。回归测试和 TDD 协议的存在,是为了在确认之后提供运行时证据,而不是作为确认的前提条件。

这条规则为何存在: 在 v1.3.43 javalin 基准测试中,代码审查和分流都识别出了 4 个合理的候选 bug,并附有代码路径追踪和需求违规,随后却将它们全部降级,理由是"置信度最高的条目仍然需要已执行的请求级证据"。这导致在一个此前版本曾发现 5 个 bug 的代码库中,产生了零个已确认 bug。证据门槛被设定为确认前先有运行时证明,这是本末倒置的 —— playbook 的设计是先确认,再用 TDD 证明。

严重性校准: 凭据泄露、认证绕过和注入类 bug 无论评估的可能性如何,始终为高严重性。跨信任边界的授权头暴露(例如跨域重定向)属于凭据泄露。当对安全相关严重性存疑时,默认判为高。

开发脚手架排除(在确认任何安全类发现之前的早期过滤)。 上述严重性校准规则会自动升级凭据泄露和认证绕过类发现。在将任何此类发现确认为 bug 之前,请应用以下机械式检验:

受审查的值是否包含自说明标记 —— 诸如 change-me、replace-me、placeholder、example、default、dummy、TODO、FIXME、your-secret-here、insert- 或 set-this- 这类明确告诉部署者将其替换掉的词?

如果是:这不是 bug。 不要记录它。自说明的开发占位符是脚手架,不是缺陷 —— 它的存在是为了让项目在无需配置的情况下于本地构建和运行。同样的逻辑适用于测试夹具、示例配置、种子数据,以及任何名称或周边注释声明其为非生产的的值。

这是一个早期过滤器,在确认阶段捕获最明显的误报。Phase 5 中的挑战门(见 references/challenge_gate.md)是捕获更隐蔽情况的更广泛机制 —— 有文档记录的功能缺口、带 WHY 注释的设计决策,以及"预期行为"系审计者凭空捏造的发现。任何通过脚手架排除的安全类发现,若匹配某个自动触发模式,仍将在 Phase 5 中接受挑战门审查。 规范依据(每个 bug 的必填字段): 引用确立预期行为的具体文档段落——所收集文档的文件名、章节/页码,以及它定义的行为契约。如果没有收集到的文档涵盖该行为,请检查项目自身的注释、README 或 API 文档是否对其进行了定义。如果预期行为没有任何文档,请将该 bug 归类为"代码不一致"而非"规范违反",并在严重程度评估中注明这一点。规范违反是比代码不一致更强的发现——它意味着代码与权威来源相矛盾,而不仅仅是代码看起来有问题。这一区分在上游报告时很重要:维护者对"你的代码违反了你自己的规范第 X.Y 节"的回应,与对"这看起来可能是个 bug"的回应是不同的。

补丁文件(每个已确认的 bug 必填)。 对于每个已确认的 bug,生成:

  • quality/patches/BUG-NNN-regression-test.patch —— 一个 git diff,添加一个演示该 bug 的测试。此补丁是必填项,而非可选项。 它是 bug 存在的最强证据——独立于任何关于修复的意见。没有回归测试补丁的已确认 bug 是不完整的,并会导致 quality_gate.py FAIL。在确认 bug 后立即生成此补丁,然后再继续处理下一个 bug。
  • quality/patches/BUG-NNN-fix.patch(可选但强烈建议)—— 一个包含拟议修复的 git diff。对于修复只需单行或几行改动的 bug(例如添加一个 case 标签、修正一个参数),生成修复补丁——这些补丁成本低、价值高。

如何生成补丁文件。 使用 git diff 格式。最简单的方法:直接将补丁内容写为 unified diff。回归测试补丁的示例:

--- /dev/null
+++ b/quality/test_regression_virtio.c
@@ -0,0 +1,15 @@
+// Generated by Quality Playbook v1.5.6
+// Regression test for BUG-004: VIRTIO_F_RING_RESET missing from vring_transport_features()
+#include <assert.h>
+#include <string.h>
+...

对于修改现有源文件的修复补丁,使用 --- a/path / +++ b/path 格式,并给出正确的行偏移。如果你无法确定准确的行偏移,请生成补丁内容并注明"偏移量近似"——一个近似的补丁比没有补丁更有价值。

补丁必须能用 git apply 干净地应用到原始源码树上。不要直接修改源码树。

补丁验证门(必填)。 在宣布任何 bug 已确认并带有修复补丁之前,运行此门:

  1. 应用测试: git apply --check quality/patches/BUG-NNN-regression-test.patch —— 必须以 0 退出。
  2. 应用测试 + 修复: git apply --check quality/patches/BUG-NNN-fix.patch —— 必须以 0 退出(针对干净源码树测试,而不是针对已应用回归测试的源码树,除非修复补丁依赖于该回归测试)。
  3. 编译检查: 应用两个补丁后,运行项目的构建/编译命令(例如 go build ./...、mvn compile、cargo check、tsc --noEmit)。必须成功。

用于第 3 步的临时 worktree。 第 1–2 步使用 --check(非破坏性)。第 3 步需要实际应用补丁并编译,这会修改源码树。为遵守源代码边界规则("绝不修改 quality/ 之外的文件"),请在一个一次性 worktree 中运行第 3 步:

git worktree add /tmp/qpb-patch-check HEAD --quiet
cd /tmp/qpb-patch-check
git apply quality/patches/BUG-NNN-regression-test.patch quality/patches/BUG-NNN-fix.patch
<compile command>
cd -
git worktree remove /tmp/qpb-patch-check --force

如果 git worktree 不可用(浅克隆、detached HEAD),请使用 git stash && git apply ... && <compile> && git checkout . && git stash pop 作为后备方案,或接受仅 --check 的验证并注明该限制。 解释型语言的编译检查。 编译命令因生态系统而异:

  • Go: go build ./...
  • Rust: cargo check
  • Java/Kotlin(Maven): mvn compile -q
  • Java/Kotlin(Gradle): ./gradlew compileJava compileTestJava -q
  • TypeScript: tsc --noEmit
  • Python: 用 python -m py_compile <changed_files> 检查语法,然后用 pytest --collect-only -q 验证导入/发现
  • JavaScript(Node.js): 用 node --check <changed_files> 检查语法;如果项目使用 ESLint,用 npx eslint <changed_files> 检查结构问题
  • JavaScript(Mocha/Jest): 以仅发现模式运行特定测试(mocha --dry-run 或 jest --listTests),验证其能无错误加载

如果无法对项目所用语言进行编译/语法检查,请在补丁条目中记录这一点,并依靠 TDD 红阶段来捕获语法错误。

如果任何步骤失败,请在将 bug 记录为已确认之前修复补丁。带有无法应用的损坏补丁的 bug 不是已确认的 bug——而是证据已损坏的假设。TDD 红绿循环无法在无法应用的补丁上运行,报告带有无法应用补丁的 bug 会削弱在上游维护者眼中的可信度。常见的补丁失败:hunk 被截断(缺少右花括号)、行偏移错误(补丁是针对已修改的树而非干净的树生成的),以及生成的测试代码中存在语法错误。

修复补丁要求。 每个已确认的 bug 必须满足以下任一条件:

  • 有一个通过上述验证门禁的 quality/patches/BUG-NNN-fix.patch,或
  • 在 BUGS.md 中明确说明为何未提供修复补丁(例如,“修复需要超出补丁范围的架构变更”、“存在多种有效修复策略——交由维护者判断”、“bug 位于上游依赖中”)。

有回归测试但没有修复补丁且没有说明理由的 bug 是不完整的。回归测试证明 bug 存在;修复补丁(或未提供补丁的理由)补全了证据链。没有修复补丁的 bug 无法达到“TDD 已验证(FAIL→PASS)”状态——在提供修复之前,它们将保持在“已确认未解决(xfail)”。

TDD 验证循环: 每个带有修复补丁的已确认 bug 都应经过红绿 TDD 循环(测试在未打补丁的代码上失败,在修复后通过)。这通过 quality/RUN_TDD_TESTS.md 协议(文件 7)执行,而不是在代码审查期间内联执行。该协议生成基于规范的测试,其中每个断言消息、变量名和注释都可追溯到收集到的文档。

完成全部三轮之后: 汇总发现。在 quality/test_regression.* 中编写回归测试,复现每个已确认的 bug。使用与 test_functional.* 相同的测试框架——如果功能测试使用 pytest,回归测试也使用 pytest(配合 @pytest.mark.xfail(strict=True));如果功能测试使用 unittest,回归测试也使用 unittest(配合 @unittest.expectedFailure)。以确认表形式报告结果(BUG CONFIRMED / FALSE POSITIVE / NEEDS INVESTIGATION)。完整的三轮模板和回归测试协议见 references/review_protocols.md。

回归测试跳过保护(强制)。 quality/test_regression.* 中的每个回归测试都必须包含跳过/xfail 保护,以便在未打补丁的代码上运行完整测试套件时不会产生意外失败。该保护必须是该框架中最早的语法级保护——在符合惯用法时使用装饰器或注解,否则使用测试体中的第一行可执行代码。使用与语言相适配的机制:

  • Python (pytest): @pytest.mark.xfail(strict=True, reason="BUG-NNN: [description]") — 放在 def test_...(): 上方的装饰器,而不是函数体内。当 bug 存在时,测试失败 → XFAIL(预期内)。当 bug 已修复但标记未移除时,测试通过 → XPASS → strict 模式会将其视为失败,提示应移除该守卫。
  • Python (unittest): @unittest.expectedFailure — 放在测试方法上方的装饰器。
  • Go: t.Skip("BUG-NNN: [description] — unskip after applying quality/patches/BUG-NNN-fix.patch") — 放在测试函数内的第一行。注意:Go 的 t.Skip 会完全隐藏测试(报告为 SKIP,而不是 FAIL),这比 Python 的 xfail 证据更弱。这是 Go 测试原语的已知局限。
  • Java (JUnit 5): @Disabled("BUG-NNN: [description]") — 放在测试方法上方的注解。
  • Rust: 放在测试函数上的 #[ignore] 属性(标准的"不在默认测试套件中运行"机制)。仅对表现为 panic 的 bug 使用 #[should_panic];仅对编译期 bug 使用 compile_fail doctest 注解。
  • TypeScript/JavaScript (Jest): test.failing("BUG-NNN: [description]", () => { ... })
  • TypeScript/JavaScript (Vitest): test.fails("BUG-NNN: [description]", () => { ... })
  • JavaScript (Mocha): it.skip("BUG-NNN: [description]", () => { ... }) 或在测试体内使用 this.skip() 进行条件跳过。

当 bug 被修复(修复补丁被永久应用)时,移除跳过守卫,并将 BUG 跟踪器的关闭状态从"已确认未修复"更新为"已修复(测试通过)"。跳过守卫的消息必须引用 bug ID 和修复补丁路径,以便遇到被跳过测试的人确切知道如何解决该问题。

源码检查测试必须执行(不能使用 run=False)。 验证源文件结构的回归测试——函数体中字符串是否存在、case 标签是否存在、枚举提取、生成代码形态检查——安全、确定且快速。它们读取仓库文件并执行字符串匹配。对于这些测试,使用启用执行的 @pytest.mark.xfail(strict=True)。不要使用 run=False,除非该测试会改变外部状态、挂起或需要不可用的基础设施。带有 run=False 的源码检查测试是最糟糕的状态:正确的检查存在但却是惰性的。在 v1.3.18 中,BUG-004 的回归测试(test_bug_004_transport_feature_whitelist_keeps_ring_reset)包含正确的断言 assert "case VIRTIO_F_RING_RESET:" in func,但被标记为 run=False——因此测试从未执行,断言从未触发,尽管测试套件"通过",bug 仍未被发现。当一个 xfail(strict=True) 测试实际执行并失败时,测试套件将其报告为 XFAIL(预期失败)——这是正确行为,而不是套件失败。 带跳过守卫的 TDD 红/绿交互。 在 TDD 验证周期中,红阶段和绿阶段必须临时绕过跳过守卫,以实际执行测试。协议应指导 Agent:

  • 红阶段(绝不可跳过): 移除或禁用 skip/xfail 守卫,然后针对未修补的代码运行测试。它必须失败。在记录结果后重新启用该守卫。对于每个已确认的 bug,红阶段都是强制性的,即使不存在修复补丁。 没有红阶段证据的 bug 属于未验证 —— 不要在未产生失败的红色运行时记录 verdict: "skipped"。如果红阶段因有据可查的原因(编译失败、环境不可用)无法执行,请记录 red_phase: "error" 并在 notes 中说明。
  • 绿阶段: 移除或禁用守卫,应用修复补丁,运行测试。它必须通过。如果该修复将被回退,请重新启用守卫。如果不存在修复补丁,请记录 green_phase: "skipped" —— 但红阶段仍必须已运行。
  • TDD 周期之后: 守卫保留在已提交的回归测试文件中。只有当修复被合并到源码树中时,才会将其永久移除。

TDD 执行强制要求(强制)。 回归测试必须在 TDD 验证周期中实际执行,而不仅仅是作为补丁文件生成。对于每个已确认的 bug,红阶段测试运行必须在 quality/results/BUG-NNN.red.log 生成一个日志文件,捕获测试输出。绿阶段(如果存在修复补丁)必须生成 quality/results/BUG-NNN.green.log。每个日志文件的第一行必须是一个状态标签:RED(测试如预期失败)、GREEN(修复后测试通过)、NOT_RUN(测试无法执行 —— 附说明)或 ERROR(测试基础设施失败 —— 附说明)。

语言感知的测试执行命令。 使用项目原生的测试运行器来执行回归测试。检测项目语言并使用相应的命令:

  • Go: go test -v -run TestBugNNN ./path/to/package
  • Python(pytest): python -m pytest -xvs quality/test_regression.py::test_bug_nnn
  • Python(unittest): python -m unittest quality.test_regression.TestRegression.test_bug_nnn
  • Java(Maven + JUnit): mvn test -pl module -Dtest=RegressionTest#testBugNnn
  • Java(Gradle + JUnit): ./gradlew test --tests RegressionTest.testBugNnn
  • Rust: cargo test bug_nnn -- --nocapture
  • TypeScript/JavaScript(Jest): npx jest --verbose --testNamePattern="BUG-NNN"
  • TypeScript/JavaScript(Vitest): npx vitest run --reporter=verbose --testNamePattern="BUG-NNN"
  • C(kernel/make-based): 通过 shell 脚本进行源码检查测试(对源文件使用 grep/awk)—— 记录脚本输出。

如果项目使用的语言或测试框架不在上述列表中,请使用项目已有的任何测试运行器(检查 Makefile、package.json、build.gradle、Cargo.toml、go.mod、setup.py、pyproject.toml 等)并调整该模式。如果没有可用的测试运行器或语言运行时未安装,请记录 NOT_RUN 并附说明 —— 不要完全跳过日志文件。

日志捕获格式。 每个 BUG-NNN.red.log 和 BUG-NNN.green.log 必须遵循以下格式:

RED
--- Test output for BUG-NNN red phase ---
Command: [exact command run]
Exit code: [exit code]
[full stdout/stderr from test execution]

第一行的状态标签(RED、GREEN、NOT_RUN、ERROR)是机器可读的 —— quality_gate.py 将检查其是否存在。当测试运行器不可用时(例如,不存在内核构建环境的 C 项目),NOT_RUN 状态是可以接受的,但日志文件仍必须存在,并说明测试无法执行的原因。

可直接运行的 TDD 日志模板。 对于每个已确认的 BUG-NNN,执行以下序列(根据上表按项目语言调整测试命令):

# ── Red phase: revert fix, run test, expect FAIL ──
git apply -R quality/patches/BUG-NNN-fix.patch 2>/dev/null   # revert fix if applied
TEST_CMD="python -m pytest -xvs quality/test_regression.py::test_bug_nnn"  # adapt per language
OUTPUT=$($TEST_CMD 2>&1); EXIT=$?
printf 'RED\n--- Test output for BUG-NNN red phase ---\nCommand: %s\nExit code: %d\n%s\n' \
  "$TEST_CMD" "$EXIT" "$OUTPUT" > quality/results/BUG-NNN.red.log

# ── Green phase: apply fix, run test, expect PASS ──
git apply quality/patches/BUG-NNN-fix.patch
OUTPUT=$($TEST_CMD 2>&1); EXIT=$?
printf 'GREEN\n--- Test output for BUG-NNN green phase ---\nCommand: %s\nExit code: %d\n%s\n' \
  "$TEST_CMD" "$EXIT" "$OUTPUT" > quality/results/BUG-NNN.green.log

对每个已确认的 bug 都要执行此操作。如果测试运行器不可用,请创建日志文件,第一行写 NOT_RUN,并附上说明。不要跳过这一步——如果缺少日志,Phase 5 中的 TDD Log Closure Gate 将会阻止完成。

TDD 执行门禁。 在 Phase 5 的终端门禁之前,验证 quality/BUGS.md 中每个已确认的 bug 都存在对应的 quality/results/BUG-NNN.red.log。没有 red 阶段日志的 bug 是不完整的——回归测试补丁虽然存在,但从未被证明能检测到该 bug。设立此门禁是因为 v1.3.45 的基准测试表明,大多数仓库生成了回归测试补丁却从未执行它们,导致 TDD 结论未经证实。

File 4: quality/RUN_INTEGRATION_TESTS.md

阅读 references/review_protocols.md 以获取模板。

必须包含:安全约束、预检检查、带有具体通过标准的测试矩阵、执行 UX 部分,以及结构化的报告格式。覆盖 happy path、跨变体一致性、输出正确性和组件边界。

用例可追溯性(强制)。 测试矩阵必须包含一个用例可追溯性列。每个集成测试组必须满足以下之一:

  1. 映射到用例——指明它所验证的用例(例如 UC-03),并描述该测试如何演练该用例中的用户结果。这些是主要集成测试——它们验证用例中描述的端到端行为确实有效。

  2. 标记为基础设施——不映射到用例的测试(构建验证、竞态检测、兼容性检查、现有测试套件回归防护)在可追溯性列中显式标记为 [Infrastructure]。它们有价值,但不计入用例覆盖。

生成测试矩阵后,检查:REQUIREMENTS.md 中的每个用例是否至少映射了一个集成测试?如果没有,请将该未覆盖的用例标记为缺口。映射到用例的集成测试应测试用例中描述的端到端行为——而不仅仅是运行恰好触及相同代码路径的现有单元测试。例如,如果某个用例说“Developer authenticates and follows redirects without leaking secrets”,集成测试应执行跨域重定向并携带 auth 请求头,并验证它们被剥离——而不仅仅是运行 pytest -k auth。

按 UC 拆分分组(强制)。 每个集成测试组最多映射到 2 个用例。映射到 3 个以上 UC 的组过于粗粒度——当测试失败时,它无法区分是哪个用例失败。如果单个测试命令(例如 mvn test、go test ./...)会演练多个用例,请使用有针对性的测试选择器(-Dtest=、-run、-k、--tests、-- test_name 等)将其拆分为单独的组,使每个组隔离 1–2 个 UC。明确禁止用一个未加区分的命令覆盖所有 UC 的组——它们在发生失败时不提供任何诊断价值。

无选择器回退方案。 如果项目的测试框架无法按拆分所需的粒度选择测试(例如,不支持标签/过滤的单体测试套件),请在集成协议中记录此限制,并使用尽可能窄的命令。记录该组覆盖哪些 UC,以及为什么无法进一步拆分。单命令项目仍必须使用分组 JSON schema——将该命令包装在一个组中,并使用 use_cases 列表覆盖该命令演练的所有 UC。命令的扁平列表绝不能替代 groups[] 结构。 预检命令验证(强制)。 在最终确定 RUN_INTEGRATION_TESTS.md 之前,请验证每个组的测试命令确实能发现并运行测试。使用框架的 dry-run 或 list 模式进行确认:

  • Python: pytest --collect-only -q <selector> — 必须至少列出一个测试
  • Go: go test -list "." <package> — 必须至少列出一个测试名称
  • Java/Kotlin: mvn -Dtest=<selector> test -pl <module> --batch-mode -DfailIfNoTests=true
  • TypeScript (Vitest): vitest list <file> --config <config> — 必须至少列出一个测试
  • TypeScript (Jest): jest --listTests <pattern> — 必须至少列出一个文件
  • Rust: cargo test <selector> -- --list — 必须至少列出一个测试
  • JavaScript (Mocha): mocha --dry-run <file> — 必须至少列出一个测试

如果 dry-run 以 "no tests found"、"No test files found" 或零测试计数退出,请在记录该组之前修正选择器。常见修正方法:添加 --config 或 --root 标志、使用文件路径代替 -t 名称模式、将正则表达式模式锚定到正确的包。不要记录命令无法发现测试的组 —— 这会产生 covered_fail 结果,将选择器缺陷掩盖为代码缺陷。

如果 dry-run 失败的原因是构建错误(编译失败、导入错误、缺少依赖、测试设置异常)而非 "no tests found",请将该失败记录在该组的 notes 字段中,格式为 "pre_flight_error": "environment",并且不要尝试修正选择器。预检期间的环境错误需要环境设置,而非选择器更改。

基础设施组定义。 单个 [Infrastructure] 组可以覆盖构建验证、竞态检测、静态分析和平台兼容性检查,而无需 UC 映射。基础设施测试验证构建工具链和平台支持,而非用户可观察的行为。基础设施组:

  • 不计入用例覆盖(UC 覆盖检查会忽略它们)
  • 必须包含一行理由,说明它们验证什么
  • 不得用于重新标记宽泛的用户工作流命令以避免拆分 —— 如果测试演练了用例中描述的用户可见行为,则无论测试如何组织,都必须映射到该 UC

所有命令必须使用相对路径。 生成的协议应在顶部包含一个 "Working Directory" 部分,声明所有命令均从项目根目录使用相对路径运行。切勿生成 cd 到绝对路径的命令 —— 当协议从其他机器或目录运行时这会导致失败。使用 ./scripts/、./pipelines/、./quality/ 等。

包含 Execution UX 部分。 当有人告诉 AI Agent "运行集成测试" 时,Agent 需要知道如何呈现其工作。协议应指定三个阶段:(1) 在运行任何内容之前以编号表格显示计划,(2) 在每个测试运行时报告单行进度更新(✓/✗/⧗),(3) 显示包含通过/失败计数和建议的摘要表格。有关模板和示例,请参阅 references/review_protocols.md 的 "Execution UX" 部分。如果没有这些,Agent 会倾倒原始输出或保持沉默 —— 两者都无用。

结构化输出(强制)。 协议必须指示 Agent 在 Markdown 报告之外生成机器可读的结果,使用 JUnit XML 用于测试执行,并使用 sidecar JSON 用于 QPB 特定的元数据。

JUnit XML 输出: 每个测试组应使用框架原生的 JUnit XML 报告器运行:

  • Python:pytest --junitxml=quality/results/integration-group-N.xml
  • Go:gotestsum --junitxml quality/results/integration-group-N.xml -- -run "TestPattern"
  • Java/Kotlin:将 Surefire XML 报告复制到 quality/results/
  • TypeScript:jest --reporters=jest-junit,配合 JEST_JUNIT_OUTPUT_DIR=quality/results/
  • Rust:cargo test 2>&1 | cargo2junit > quality/results/integration-group-N.xml(如果可用) 如果 JUnit XML 报告器不可用,则跳过 XML,并在 sidecar JSON 中注明 "junit_available": false。

Sidecar JSON: 通过逐字复制下面的模板并仅填写数值来生成 quality/results/integration-results.json。不要臆造字段、重命名键或重构 schema。一个没有 groups 数组的扁平命令列表是无效的——即使项目通过单一命令运行所有测试,也要将其包装为一个 group。

{
  "schema_version": "1.1",
  "skill_version": "<current skill version>",
  "date": "YYYY-MM-DD",
  "project": "<project name>",
  "recommendation": "SHIP",
  "groups": [
    {
      "group": 1,
      "name": "Core routing dispatch",
      "use_cases": ["UC-01", "UC-02"],
      "result": "pass",
      "tests_passed": 5,
      "tests_failed": 0,
      "junit_file": "integration-group-1.xml",
      "junit_available": true,
      "notes": ""
    }
  ],
  "summary": {
    "total_groups": 9,
    "passed": 8,
    "failed": 1,
    "skipped": 0
  },
  "uc_coverage": {
    "UC-01": "covered_pass",
    "UC-02": "covered_pass",
    "UC-03": "not_mapped"
  }
}

必需的顶层字段: schema_version、skill_version、date、project、recommendation、groups、summary、uc_coverage。如果输出中缺少这些字段中的任何一个,则结果不符合规范。

无效示例(不要输出这些):

  • 一个扁平的 "results": [{"command": "go test ./...", "result": "pass"}]——这不是分组 schema。
  • 使用 "commands_run" 而不是 "groups" 的 schema——键名错误。
  • 缺少 "uc_coverage" 的 schema——REQUIREMENTS.md 中的每个用例都必须出现。
  • 使用 "use_case_traceability" 而不是 "use_cases" 的 schema——字段名错误。

有效的 result 值:"pass"、"fail"、"skipped"、"error"。有效的 recommendation 值:"SHIP"(所有 group 通过)、"FIX BEFORE MERGE"(非阻塞 group 中出现失败)、"BLOCK"(关键 group 中出现失败)。uc_coverage 部分将 REQUIREMENTS.md 中的每个用例映射到以下之一:"covered_pass"(至少有一个映射的 group 通过)、"covered_fail"(有 group 映射但全部失败)或 "not_mapped"(没有集成测试 group 映射到该用例)。"covered_fail" 与 "not_mapped" 之间的区别很重要:前者意味着测试存在但代码有缺陷;后者意味着测试缺失。

Runner 脚本和 CI 工具应读取 sidecar JSON 来获取结果,而不是对 Markdown 报告进行 grep。这消除了一类 bug,即基于 grep 的计数因匹配到散文中的词语而产生错误数字。

写入后校验(强制)。 在写入 integration-results.json 后,重新打开该文件并验证:(1) 每个必需的顶层字段都存在,(2) 每个 groups[] 条目都有 group、name、use_cases、result 和 notes,(3) 所有 result 和 recommendation 值仅使用上面列出的允许枚举值,(4) uc_coverage 映射 REQUIREMENTS.md 中的每个用例,(5) 不存在额外的未记录根键。如果任何检查失败,请在继续之前修复该文件。

此协议必须演练真实的外部依赖。 如果项目与 API、数据库或外部服务通信,则集成测试协议会对这些服务运行真实的端到端执行——而不仅仅是本地验证检查。围绕项目实际的执行模式和外部依赖来设计测试矩阵。在探索期间查找 API key、提供商抽象和现有的集成测试脚本,并在此基础上构建。

从代码中推导质量门禁,而不是通用检查。 在探索期间阅读验证规则、schema 枚举和生成逻辑。将它们转化为带有特定字段和可接受值范围的按 pipeline 质量检查。“所有单元均已验证”是不够的——协议必须验证领域特定的正确性。

编写并行脚本,而不只是描述它。 对运行进行分组,使独立的执行(不同提供商)并发运行。包含带有 & 和 wait 的实际 bash 命令。同一时间每个提供商只运行一个,以避免速率限制。

根据项目校准单元数量。 阅读 chunk_size 或等效配置。使用足够的单元以至少跨越 2 个 chunk,并足以验证分布检查。集成测试通常为 10–30 个。

运行后深度验证。 不要止步于“进程已完成”。对于每次运行,验证日志文件、manifest 状态、输出数据是否存在、样本记录内容以及任何现有的质量检查脚本。 查找并使用现有的验证工具。 搜索现有的、用于验证输出质量的脚本(例如 integration_checks.py、验证脚本、质量门禁函数)。如果它们存在,就从协议中调用它们。如果项目有 TUI 或仪表盘,请在运行后检查清单中加入 TUI 验证命令(例如 --dump 标志)。

在编写质量门禁之前,先构建一个字段参考表。 这是保证协议准确性最重要的步骤。AI 模型即使在阅读了 schema 之后,也会自信地写出错误的字段名——document_id 会变成 doc_id,sentiment_score 会变成 sentiment,float 0-1 会变成 int 0-100。解决办法是流程性的:在编写每一行表格之前,立即重新阅读每个 schema 文件。 不要依赖你在对话早些时候读到的内容——你对字段名的记忆会在数千个 token 的过程中发生漂移。请逐字符地从文件内容中复制字段名。包含每个 schema 中的全部字段(如果 schema 有 8 个字段,表格就有 8 行)。完整流程和格式见 references/review_protocols.md 的“The Field Reference Table”一节。不要跳过这一步——它能防止最常见的一种协议不准确问题。

文件 5:quality/RUN_SPEC_AUDIT.md —— 三人评审团

阅读 references/spec_audit.md 以了解完整协议。

三个独立的 AI 模型依据规范审计代码。为什么是三个?因为每个模型都有不同的盲点——在实践中,不同的审计者会捕捉到不同的问题。交叉比对能够发现任何单个模型遗漏的问题。

该协议定义了:一个可复制粘贴、带有护栏的审计提示词,项目特定的审查重点领域,一个分诊流程(按置信度合并发现),以及修复执行规则(按子系统小批量修复,而不是使用巨型提示词)。

次要关注视角: 可以选择为每个审计模型分配一个次要关注视角——例如,一个从输入验证入手,一个从资源生命周期入手,一个从并发入手。每个模型仍然执行完整的独立审计;该关注视角只是让注意力产生偏向,而不会限制覆盖范围。不要按 bug 类别把模型拆分成互不重叠的负责范围。

少数派发现规则: 在分诊过程中,任何只有三个审计者中的一个标记的发现(少数派发现)都需要重新调查——阅读具体的代码位置,并明确做出 CONFIRMED/FALSE-POSITIVE 的判定,而不是默认将其丢弃。少数派发现成为两个模型都遗漏的真实 bug 的可能性异常高。

分诊不得把证据门槛提高到代码路径分析之上。 分诊步骤确认或否决发现——它不会因为等待运行时证据而推迟它们。如果一个发现包含展示行为违规的代码路径追踪(函数调用、缺失分支、错误的返回值以及 file:line 引用),分诊应当确认它。不要把经过代码路径追踪的发现降级为“候选”或“需要运行时验证”。TDD 协议(阶段 5)在确认之后提供运行时证据。完整的证据标准见 BUGS.md 一节中的“What counts as sufficient evidence to confirm a bug”。

代码审查与规范审计的冲突: 如果代码审查和规范审计对同一个发现意见不一致,规范审计的发现并不自动正确。部署一个验证探针——阅读具体的代码位置,并确定哪一种评估是准确的。在 BUG 跟踪器中记录该解决结果。任何规范审计者都未标记的代码审查 BUG 仍然得到确认,但在关闭之前应当用有针对性的探针进行验证。

验证探针必须产生可执行的证据。 当分诊步骤通过验证探针确认或否决一个发现时,仅有文字推理是不够的。探针必须产生一个机械地证明该判定的测试断言:

  • 对于驳回(发现为误报):编写一个通过(PASS)的断言,证明该发现是错误的。例如,如果要驳回“函数 X 缺少空值检查”,请编写 assert "if (ptr == NULL)" in source_of("X"), "X has null check at line NNN"。如果你无法编写一个能证明你驳回理由的通过断言,就不要驳回该发现——将其升级为已确认,或标记为需要人工审查。

  • 对于确认(发现是真实缺陷):编写一个失败(预期失败)的断言,证明该缺陷存在。例如,如果要确认“switch 中缺少 RING_RESET”,请编写 assert "case VIRTIO_F_RING_RESET:" in source_of("vring_transport_features"), "RING_RESET should be in the switch but is not"。

  • 每个断言都必须为其引用的证据标注确切的行号。不要写“lines 3527-3528”,而要写“line 3527: default:”——展示该行实际包含的内容。没有行号引用的断言是不充分的。

为什么存在这条规则: 在 v1.3.16 的 virtio 测试中,triage 正确收到了一条少数派发现,指出 VIRTIO_F_RING_RESET 从某个 switch/case 白名单中缺失。triage 执行了一次“验证探针”,声称 lines 3527-3528“明确保留了 VIRTIO_F_RING_RESET”——但这些行实际上包含的是 default: 分支。triage 幻觉出了代码符合要求。如果当时要求它编写 assert "case VIRTIO_F_RING_RESET:" in source,该断言就会失败,从而暴露这一幻觉。要求驳回必须提供可执行证据,会让幻觉式驳回自相矛盾:模型无法为代码中不存在的东西编写出通过的断言。

triage 证据必须写入磁盘。 验证探针断言必须出现在磁盘上的文件中——要么追加到 quality/mechanical/verify.sh,要么写入专用的 quality/spec_audits/triage_probes.sh。在 triage 报告正文中描述但从未写入可执行文件的断言,不算可执行证据。门禁会检查 triage 输出中是否存在探针断言;一份 triage 报告如果只说“验证探针确认……”而在可执行文件中没有对应断言,就是不符合规范的。这可以防止一种失败模式:模型只是叙述探针会显示什么,而并未真正运行它。

文件 6:AGENTS.md(由编排器生成;你不需要在阶段 2 编写它)

v1.5.4 契约:AGENTS.md 由 bin/run_playbook.py 在阶段 6 成功后生成,而不是由你在阶段 2 编写。 编排器的 _safe_write_agents_md 辅助函数会将该文件写入目标的仓库根目录(<target>/AGENTS.md,而不是 quality/AGENTS.md),输入为你我在阶段 2 产出的 quality/ 工件,再加上阶段 6 门禁的裁决结果。生成器会在第一个非空行上带上 `` 哨兵标记,以便后续运行能识别出 QPB 管理的副本。

你(阶段 2 的大模型)绝不能做的事:

  1. 不要创建 <target>/AGENTS.md。 它归编排器所有。在阶段 2 创建它会与编排器的幂等重新生成路径冲突,并可能被源未变更不变量标记。
  2. 不要修改已存在的 <target>/AGENTS.md。 如果目标仓库根目录下存在一个且没有 QPB 哨兵标记,那么它是操作者编写的——不要动它(编排器会根据 _safe_write_agents_md 的 "preserved" 结果,在发出警告的同时保留它)。如果它带有 QPB 哨兵标记,编排器会在阶段 6 之后重新生成它;你在运行中途编辑它也没有帮助。
  3. 不要编写 quality/AGENTS.md。 这不是契约;AGENTS.md 位于仓库根目录,而不是 quality/ 下。

如果你发现自己想要“向现有的 AGENTS.md 添加一个 Quality Docs 章节”——停下来。编排器会替你完成这件事,其来源是阶段 6 门禁所校验的规范路径。你在阶段 2 的交付物是 quality/ 工件,仅此而已。

此 bug 修复防止了在 2026-04-30 暴露出来的 bootstrap 测试失败模式: 一个阶段 2 的大模型读取了此章节中 v1.5.3 时代的“如果 AGENTS.md 已存在,则更新它”指令,向项目根目录的 AGENTS.md 追加了一个 Quality Docs 章节,并触发了源未变更不变量——从而中止运行并丢弃了 20 分钟的阶段 2 工作成果。

文件 7:quality/RUN_TDD_TESTS.md — TDD 验证协议

此协议在代码审查与规格审计已确认 bug 并生成修复补丁之后执行。它针对每个已确认的 bug 运行红-绿 TDD 循环:测试在未打补丁的代码上失败,应用修复,测试通过。

为什么需要一个单独的协议? 代码审查会发现 bug 并编写带有 xfail 标记的回归测试。TDD 协议则接收这些测试并证明它们确实能检测到该 bug——以及修复确实修复了它。这是一个比“我们发现了一个 bug 并编写了一个测试”更强的论断。它是“这里有一个测试,没有补丁时失败,有补丁时通过。”在上游报告 bug 时,这一区别很重要:维护者更信任 FAIL→PASS 的演示,而不是 bug 描述。

生成的协议必须包含:

  1. 以规格为依据的测试要求。 对于 quality/BUGS.md 中的每个 bug,协议都会指示 Agent 执行以下操作:

    • 读取该 bug 的 spec basis 字段,以确定定义预期行为的文档段落
    • 在引用的章节处读取收集到的文档(来自 reference_docs/ 或项目自身的文档)
    • 使用规格中的语言编写测试断言——变量名、常量、函数名和断言消息都应呼应规格的术语,而不是代码的内部命名
    • 在每个测试中包含一个注释块,引用:需求 ID(来自 REQUIREMENTS.md)、bug ID(来自 BUGS.md)以及规格段落(文档名、章节,以及行为契约的 ≤15 词引文)
  2. 红-绿执行步骤。 对于每个带有修复补丁的 bug:

    • 红: 对未打补丁的源码运行回归测试。它必须失败。如果它通过了,说明该测试检测不到 bug——请使用 spec basis 来理解应断言什么行为,并重写它。
    • 绿: 应用修复补丁(git apply quality/patches/BUG-NNN-fix.patch),运行同一个测试。它必须通过。
    • 记录: 在 BUG 跟踪器中记录两项结果,并将关闭状态标为“TDD verified (FAIL→PASS)”。
  3. 框架适配。 协议必须检测项目的测试框架并生成符合其惯用风格的测试:

    • 有测试基础设施的项目(pytest、JUnit、Go testing、Jest、cargo test 等):使用项目自身的框架编写测试,并遵循探索过程中发现的现有测试约定。
    • 没有测试基础设施的项目(例如 Linux 内核、嵌入式 C):用 sed 提取目标函数,编写一个自包含的 C 测试文件,附带最小化的类型 shim,直接编译并运行。将提取命令包含在测试文件的头部注释中,使其具备自文档性。
  4. 上游报告格式。 对于每个经 TDD 验证的 bug,生成一个可直接发送的报告块,其中包含:

    • 一句话描述,引用所违反的规范章节
    • FAIL→PASS 输出(可复制粘贴的终端会话)
    • 测试文件(作为附件或内联)
    • 修复补丁(作为附件或内联)
  5. 可追溯性表。 协议生成一个 quality/TDD_TRACEABILITY.md 文件,映射关系如下:

    Bug IDRequirement IDSpec DocSpec SectionBehavioral ContractTest File:FunctionRed ResultGreen Result

    每一行都必须完整填写。没有规范文档条目的 bug 属于代码不一致,而非规范违反——在表中注明这一点,并相应调整上游报告措辞。

  6. 结构化输出(强制)。 协议必须生成与 Markdown 报告并行的机器可读结果。使用 JUnit XML 表示测试执行结果,使用一个 sidecar JSON 文件表示 JUnit XML 无法表达的 QPB 专用元数据。

    JUnit XML 输出: 对于每个红绿阶段,使用框架原生的 JUnit XML 输出标志运行测试:

    • Python:pytest --junitxml=quality/results/tdd-red-BUG-NNN.xml
    • Go:gotestsum --junitxml quality/results/tdd-red-BUG-NNN.xml -- -run TestRegression_BUG_NNN
    • Java/Kotlin:Maven Surefire 报告会自动生成在 target/surefire-reports/ 中;将相关 XML 复制到 quality/results/
    • Rust:cargo test --test regression 2>&1 | cargo2junit > quality/results/tdd-red-BUG-NNN.xml(如果 cargo2junit 可用;否则跳过 Rust 的 XML)
    • TypeScript:jest --reporters=default --reporters=jest-junit,并设置 JEST_JUNIT_OUTPUT_DIR=quality/results/

    如果框架的 JUnit XML 报告器不可用,或需要缺失的依赖,则跳过该语言的 XML 输出,并在 sidecar JSON 中注明("junit_available": false)。不要因为缺少 XML 工具而导致 TDD 运行失败。

    Sidecar JSON(严格 schema 强制): 通过逐字复制下面的模板并仅填写值来生成 quality/results/tdd-results.json。不要杜撰字段、重命名键或重构 schema。模板即 schema——任何偏离(多余键、缺失键、重命名键、重构嵌套)都会使输出不合规。先将模板复制粘贴到编辑器中,然后填写值。不要凭记忆编写 JSON。

    {
      "schema_version": "1.1",
      "skill_version": "<current skill version>",
      "date": "YYYY-MM-DD",
      "project": "<project name>",
      "bugs": [
        {
          "id": "BUG-001",
          "requirement": "REQ-003",
          "red_phase": "fail",
          "green_phase": "pass",
          "verdict": "TDD verified",
          "regression_patch": "quality/patches/BUG-001-regression-test.patch",
          "fix_patch": "quality/patches/BUG-001-fix.patch",
          "fix_patch_present": true,
          "patch_gate_passed": true,
          "writeup_path": "quality/writeups/BUG-001.md",
          "junit_red": "tdd-red-BUG-001.xml",
          "junit_green": "tdd-green-BUG-001.xml",
          "junit_available": true,
          "notes": ""
        }
      ],
      "summary": {
        "total": 6,
        "verified": 4,
        "confirmed_open": 1,
        "red_failed": 1,
        "green_failed": 0
      }
    }
    

    必需的顶层字段: schema_version、skill_version、date、project、bugs、summary。必需的每 bug 字段: id、requirement、red_phase、green_phase、verdict、fix_patch_present、writeup_path。如果缺少任何必需字段,结果即为不合规。可选的每 bug 字段(在上方模板中显示但未做门禁检查):regression_patch、fix_patch、patch_gate_passed、junit_red、junit_green、junit_available、notes。在数据可用时包含这些字段;省略它们不受惩罚。 必需的 summary 子键: summary 对象必须恰好包含以下键:total、verified、confirmed_open、red_failed、green_failed。这五个键都是必需的 — 省略其中任何一个(尤其是 red_failed 或 green_failed)都会使 summary 不符合规范。

    规范的补丁文件名: 回归测试补丁必须命名为 BUG-NNN-regression-test.patch。修复补丁必须命名为 BUG-NNN-fix.patch。门禁脚本会按这些确切模式进行 glob 匹配 — 像 BUG-001-regression.patch 或 BUG-001-test.patch 这样的创意变体不会被计入。

    日期字段: 使用本次会话的实际日期(例如 "2026-04-12"),而不是模板占位符 "YYYY-MM-DD"。门禁会验证日期是真实的 ISO 8601 日期,并拒绝占位符字符串和未来日期。

    无效示例(不要输出这些):

    • "runs": [{"phase": "red", "command": "...", "result": "4 xfailed"}] — 这是扁平的 runs 数组,不是按 bug 索引的 "bugs" schema。
    • 带有 "generated"、"scope"、"status"、"testsRun" 等临时根键的 schema — 这些不是标准 schema 字段。
    • "verdict": "skipped" — 该值已弃用;请使用 "confirmed open",并配合 red_phase: "fail" 和 green_phase: "skipped"。
    • 根级别缺少 "schema_version" — 每个 tdd-results.json 都必须包含该字段。

    有效的 verdict 值:"TDD verified"(FAIL→PASS)、"red failed"(测试在未打补丁的代码上通过 — 测试未能检测到该 bug)、"green failed"(修复后测试仍然失败 — 修复不完整或补丁损坏)、"confirmed open"(red 阶段已运行并确认该 bug,但没有可用的修复补丁)、"deferred"(TDD 无法在此环境中执行 — 配合 notes 说明原因)。不要使用 "skipped" 作为 verdict — 每个已确认的 bug 都必须有 red 阶段结果。verdict: "confirmed open" 的 bug 必须具有 red_phase: "fail"(red 已运行并确认该 bug)和 green_phase: "skipped"(没有可应用的修复)。有效的 red_phase/green_phase 值:"fail"、"pass"、"error"(编译/应用失败)、"skipped"(仅限 green — red 永远不会被跳过)。patch_gate_passed 字段记录补丁验证门禁(apply-check + compile)是否成功 — 如果门禁失败且补丁已修复则为 false,如果不存在修复补丁则为 null。writeup_path 字段指向每个 bug 的 writeup 文件(见下文 "Bug writeup generation")— 如果未为此 bug 生成 writeup,则为 null。

    Runner 脚本和 CI 工具应读取 sidecar JSON 来获取通过/失败计数,而不是 grep Markdown 报告。

    写入后验证(强制)。 写入 tdd-results.json 后,重新打开文件并验证:(1) 每个必需的顶层字段都存在,(2) 每个 bugs[] 条目中都存在每个必需的按 bug 字段,(3) 所有 verdict、red_phase 和 green_phase 值仅使用上面列出的允许枚举值,(4) 不存在额外的未记录根键。如果任何检查失败,请在继续之前修复文件。此步骤可捕获最常见的失败模式:Agent 凭记忆转述 schema,而不是复制模板,从而产生看似合理但不符合规范的输出。

TDD 产物关闭门禁(强制)。 如果 quality/BUGS.md 包含任何已确认的 bug,则 quality/results/tdd-results.json 是强制的 — 而非可选。如果任何 bug 具有 red 阶段结果(无论是 TDD 验证还是 confirmed-open),则 quality/TDD_TRACEABILITY.md 也是强制的。零 bug 仓库可以省略这两个文件。确认了 bug 但未生成 tdd-results.json 的运行是不完整的 — 该阶段无法关闭。对于 TDD 无法执行的仓库(环境受阻、无测试基础设施),请生成 tdd-results.json,使用 verdict: "deferred" 和 notes 字段说明原因(例如 "environment_blocked: missing workspace Cargo.toml"、"no_test_infrastructure: kernel C code without userspace harness")。deferred verdict 使缺口可见,而不是静默省略该文件。 执行体验: 与集成测试相同的三阶段模式 —— (1)将计划展示为待验证 bug 的编号表格,(2)在每个红-绿循环运行时报告单行进度(FAIL ✓ → PASS ✓ 或 FAIL ✗ — 测试在未修补代码上通过,正在重写),(3)展示包含已验证/失败/已重写数量的汇总表。

  1. Bug 报告生成(针对所有已确认的 bug)。 在成功的红→绿循环(verdict: "TDD verified")或无需修复的确认(verdict: "confirmed open")之后,在 quality/writeups/BUG-NNN.md 生成一份自包含的报告。该文件旨在通过电子邮件发送给维护者、附加到 Jira 工单,或在仓库之外进行审阅 —— 它必须独立成篇,无需读者浏览其余质量产物。

    模板(每份报告中第 1–4、6、7 节为必需;当触发深度判断时添加第 5 节;当存在相关 bug 时添加第 8 节):

    1. 摘要 —— 一段话:哪里出了问题、位置(file:line)、实际中会破坏什么。
    2. 规范引用 —— 被违反的具体规范章节,如可用请附 URL。引用代码未能满足的行为契约(≤15 个词)。
    3. 代码 —— 有 bug 的代码及 file:line 引用。从规范角度解释为什么它是错的,而不只是“它看起来很奇怪”。
    4. 可观察的后果 —— 实际破坏了什么。不是“理论上可能失败” —— 而是在什么条件下、以什么症状实际失败。
    5. 深度判断 (仅在需要展开时包含) —— 在起草第 1–4 节后,评估:仅从代码和测试来看,后果是否不言自明?如果读者会合理地问“为什么没人注意到这一点?”或“这是否对所有配置的影响都一样?”,则展开分析。追溯有 bug 函数的调用方。展示哪些代码路径会暴露该 bug,哪些会掩盖它。具体的展开触发条件:依赖传输/配置的行为、在某些路径上掩盖该 bug 的功能开关、隐藏调用方的间接分发、仅在特定运行时条件下才显现的协商/初始化代码中的 bug。如果后果从紧邻的代码中显而易见(例如空指针解引用、差一错误),则保持第 1–4 节简洁并省略本节。
    6. 修复 —— 以行内 diff(统一 diff 格式)提出的修复方案,并简要解释为什么这是正确的修复。始终包含具体的 diff —— 即使对于没有单独 .patch 文件的 confirmed-open bug 也是如此。如果修复是一行改动(添加一个 case 标签、修正一个参数),写出该 diff。如果修复需要更广泛的改动,写出解决核心缺陷的最小 diff,并注明完整修复还需要哪些额外改动。报告中的行内 diff 正是使报告可操作的关键 —— 一份写着“未包含修复补丁”的报告是不完整的,对维护者没有用处。示例格式:
      --- a/drivers/virtio/virtio_ring.c
      +++ b/drivers/virtio/virtio_ring.c
      @@ -3527,6 +3527,7 @@ void vring_transport_features(...)
       	case VIRTIO_F_ORDER_PLATFORM:
       	case VIRTIO_F_IN_ORDER:
      +	case VIRTIO_F_RING_RESET:
       	default:
      
    7. 测试 —— 测试证明了什么、如何运行它,以及在未修补与已修补代码上分别预期什么输出。
    8. 相关问题 (仅在存在相关 bug 时包含) —— 同一类别的其他 bug(如有)。即使尚未确认也要标记它们。如果未发现相关问题,则省略本节。

    在报告文件顶部包含版本戳(格式与所有其他生成文件相同)。 为所有已确认缺陷生成 writeup(强制)。 为每个已确认缺陷在 quality/writeups/BUG-NNN.md 生成 writeup —— 包括 TDD 验证的和已确认未修复的。使用上方的编号章节模板(第 1–8 节)。对于已确认未修复的缺陷,遵循相同模板,包括在第 6 节中给出建议的修复 diff(即使没有单独的 .patch 文件,也始终需要 diff)。writeup 的触发门槛是缺陷确认,而不是 TDD 完成。如果运行中存在已确认缺陷但没有 writeups 目录,则视为不完整。

    内联 diff 由门禁强制要求。 quality_gate.py 脚本会检查每个 writeup 是否包含 ```diff 代码块。没有内联 diff 的 writeup 会导致门禁 FAIL。不要写 "see patch file" —— 将实际的 diff 内联粘贴到 writeup 正文中的 ```diff 围栏代码块内。这是 writeup 中最重要的单一元素,因为它能让只阅读 writeup 的维护者可以直接处理该缺陷。

检查点:在生成产物后更新 PROGRESS.md

重新读取 quality/PROGRESS.md。更新:

  • 将 Phase 2 标记为已完成并附上时间戳
  • 更新产物清单:将每个已生成的产物设置为 "generated" 并记录其文件路径
  • 如果尚未添加探索摘要说明,则添加

Phase 2 完成门禁(强制)。 在进入 Phase 3 之前,验证:

  1. 所有核心产物都存在于 quality/ 下的磁盘上(QUALITY.md、CONTRACTS.md、REQUIREMENTS.md、COVERAGE_MATRIX.md、COMPLETENESS_REPORT.md、test_functional.*、RUN_CODE_REVIEW.md、RUN_INTEGRATION_TESTS.md、RUN_SPEC_AUDIT.md、RUN_TDD_TESTS.md)。AGENTS.md 不在此列表中 —— orchestrator 在 Phase 6 之后将其写入目标仓库根目录,而不是 Phase 2。
  2. REQUIREMENTS.md 包含带有具体满足条件的需求,并引用实际代码(文件路径、函数名、行号)—— 而不是抽象的行为描述。
  3. 如果存在 dispatch/enumeration 契约:quality/mechanical/verify.sh 存在且已执行。
  4. PROGRESS.md 将 Phase 2 标记为已完成并附上时间戳。

在开始 Phase 3 之前,重新读取 quality/PROGRESS.md 和 quality/REQUIREMENTS.md。需求是代码审查的目标列表 —— 如果代码不满足其条件,每个需求都是一个潜在缺陷。

阶段结束消息(强制 —— 在 Phase 2 完成后打印此消息,然后 STOP):

# Phase 2 Complete — Quality Artifacts Generated

I've generated the quality infrastructure for this project:
[List the key artifacts created: REQUIREMENTS.md with N requirements and N use cases,
QUALITY.md with N scenarios, functional tests, review protocols, etc.]

The requirements are now the target list for Phase 3's code review — every requirement
is a potential bug if the code doesn't satisfy it.

To continue to Phase 3 (Code review with regression tests), say:

    Run quality playbook phase 3.

Or say "keep going" to continue automatically.

打印此消息后,STOP。除非用户明确要求,否则不要进入 Phase 3。


Phase 3: Code Review and Regression Tests

v1.5.6 instrumentation: 现在将 phase_start phase=3 追加到 quality/run_state.jsonl。在阶段结束时,进行交叉验证(quality/RUN_CODE_REVIEW.md 存在;每个已识别缺陷对应一个 writeup),然后追加 phase_end phase=3。

此阶段所需的参考:

  • quality/REQUIREMENTS.md —— 代码审查的目标列表
  • references/review_protocols.md —— 三遍协议和回归测试约定

按照 File 3 中所述运行代码审查协议(全部三遍)。产生发现后,根据 references/review_protocols.md 中的闭环要求,为每个已确认 BUG 编写回归测试。

更新 PROGRESS.md: 将每个已确认 BUG 添加到累积 BUG 跟踪器中,来源为 "Code Review",包含 file:line 引用、描述、严重程度和闭环状态(回归测试函数名或豁免原因)。将 Phase 3(代码审查 + 回归测试)标记为已完成。

阶段结束消息(强制 —— 在 Phase 3 完成后打印此消息,然后 STOP):

# Phase 3 Complete — Code Review

The three-pass code review is done. [Summarize: N bugs confirmed, N regression test
patches generated, N fix patches generated. List the bug IDs and one-line summaries.]

To continue to Phase 4 (Spec audit — Council of Three), say:

    Run quality playbook phase 4.

Or say "keep going" to continue automatically.

打印此消息后,STOP。除非用户明确要求,否则不要进入 Phase 4。


阶段 4:规格审计与分诊

v1.5.6 埋点: 现在追加 phase_start phase=4。对于每轮 A/B/C/D,追加 pass_started phase=4 pass=X 和 pass_ended phase=4 pass=X。在阶段结束时,进行交叉验证(quality/REQUIREMENTS.md 非空且 quality/COVERAGE_MATRIX.md 存在),然后追加 phase_end phase=4。

本阶段的必需参考资料:

  • references/spec_audit.md — 三人委员会协议、分诊流程、验证探针

按照 File 5 中所述运行规格审计协议。分诊报告必须包含 ## Pre-audit docs validation 章节(完整模板见 references/spec_audit.md)。即使 reference_docs/ 为空,此章节也是必需的——在这种情况下,请说明审计人员改用了什么作为基线。根据上文“验证探针必须产出可执行证据”规则,分诊中的每个验证探针都必须产出可执行证据(带有行号引用的测试断言)。分诊之后,对每个已确认的发现进行分类。

枚举检查的有效委员会门槛。 如果有效委员会不足 3/3(返回可用报告的审计人员少于三名),且本次运行包含任何白名单/枚举/分发函数检查或任何结转的种子检查,则审计不得在没有已执行的机械证明产物的情况下对这些检查得出“无已确认缺陷”的结论。委员会不完整但配有机械验证是可以接受的。委员会不完整却仅依赖纯文字验证来支撑代码存在性主张则不可接受——应升级为“NEEDS VERIFICATION”,并在结束前运行机械检查。

审计前抽查必须从代码中提取,而非依据文档断言。 当规格审计提示词中包含用于预验证的抽查主张时(例如“验证函数 X 在第 Z 行处理常量 Y”),分诊必须通过提取所引用行的实际代码来验证每一项主张——而不是通过确认该主张听起来合理。对于每一项关于代码内容的抽查主张,预验证必须报告所引用行的实际内容:“第 3527 行包含 default:——而非所声称的 case VIRTIO_F_RING_RESET:。”如果抽查是根据需求或收集的文档而非代码本身生成的,则应将其视为待检验的假设,而非待确认的事实。此规则可防止在 v1.3.17 中观察到的污染链:一条虚假的抽查主张(“RING_RESET 位于 3527-3528”)在未阅读实际行的情况下被认定为“准确”,随后传播至分诊并进入每一个下游产物。

更新 PROGRESS.md: 将规格审计中确认的每一个代码 bug 添加到累积 BUG 跟踪器中,来源标注为“Spec Audit”。这一点至关重要——如果规格审计发现的 bug 未被添加到闭包验证所读取的同一跟踪器中,它们就会被系统性地遗漏。

第 2 层 — 语义引用检查(v1.5.3 委员会子环节)

在主规范审计分诊之后,每位委员会成员都会针对每个 Tier 1/2 REQ 的 citation_excerpt 运行逐 REQ 判定。这是幻觉门禁的第 2 层:第 1 层是机械式字节相等检查 — bin/citation_verifier 由 bin/reference_docs_ingest 在摄取时调用,并由 quality_gate.py 在门禁时再次调用;大模型从不直接 shell 调用它。第 2 层是语义层的 — 审查者判断摘录是否确实支持所述需求,还是需求超出了摘录所述内容。

协议。

  1. 每位委员会成员一个提示词,所有 Tier 1/2 REQ 批量放入。 不是一次一个 REQ(3×N 个提示词太多了)。不是散文式响应(存在模式匹配风险)。审查者接收完整的 (req_id, citation_excerpt, REQ description) 元组列表,并返回结构化的逐 REQ JSON 响应。

  2. 结构化响应 schema(schemas.md §9.2)。 对于每个 REQ,审查者记录 {"req_id": "REQ-NNN", "reviewer": "<stable string>", "verdict": "supports" | "overreaches" | "unclear", "notes": "<reasoning>"}。有效的 verdict 值在 schemas.md §3.5 中列举。

  3. 批处理阈值。 当一次运行产生超过 15 个 Tier 1/2 REQ 时,拆分为每位委员会成员每个提示词最多 15 个 REQ 的批次。同一审查者按顺序查看每一批;其响应条目在同一个 reviewer 字符串下拼接为一个 reviews[] 数组。

  4. 审查者标识符稳定性。 使用固定字符串,如 "claude-opus-4.7"、"gpt-5.4"、"gemini-2.5-pro"。schemas.md §10 不变量 #17 中的多数计算按此字段分组 — 一个拼写错误会悄然变成第四位审查者,并破坏 2-of-3 多数检查。

  5. 输出。 使用 §1.6 清单包装器将所有委员会成员的响应拼接到 quality/citation_semantic_check.json,只是记录数组命名为 reviews 而非 records(schemas.md §9.1)。每次运行一个文件,在每次审计环节重新生成。

多数规则(门禁强制执行)。 对于每个 Tier 1/2 REQ,门禁按 req_id 对审查进行分组,当 3 位审查者中有 ≥2 位记录 verdict == "overreaches" 时使该次运行失败。单个成员的 overreaches 或 unclear 判定会作为警告浮现,但不会使门禁失败。审查者条目少于三条的 REQ(缺少审查者、跳过批次)证据不足 — 门禁将其视为失败。

Spec Gap 运行的空操作。 如果一次运行产生零个 Tier 1/2 REQ,citation_semantic_check.json 仍会被写入,其中 reviews 数组为空 — 即使检查没有任何可评估的内容,该文件的存在也是产物契约的一部分。

规范审计后的回归测试

在规范审计分类完成之后,检查 PROGRESS.md 中的累计 BUG 跟踪器。任何尚未有回归测试的规范审计 BUG,现在都需要一个。按照代码审查回归测试的相同惯例(预期失败标记、测试与发现的对应关系、可执行源文件),为规范审计确认的代码 bug 编写回归测试。

为什么需要这一步: 代码审查的 bug 能立即获得回归测试,因为测试就在审查之后编写。规范审计在测试编写完成之后运行,因此其确认的 bug 成了孤儿——它们出现在分类报告中,却从未获得测试。这一步填补了这一缺口。

单个审计员产物(强制)。 规范审计必须在 quality/spec_audits/ 下生成单个审计员报告文件,文件名包含 auditor(规范格式:YYYY-MM-DD-auditor-N.md,例如 2026-04-12-auditor-1.md;也接受:auditor_<model>_<date>.md)。门禁按 *auditor* 进行通配匹配——任何符合规范的名称都会匹配。每个审计员一个文件,而不仅仅是分类综合报告。每个审计员报告记录该审计员在分类协调之前独立发现的内容。如果只存在分类文件而没有单个审计员产物,则审计不完整——分类无法被验证,因为没有协调前发现的记录。此要求的存在是因为单个分类文件将发现与协调混为一谈,导致无法判断某项发现是被独立确认的,还是从单一来源综合而来的。

阶段 4 完成门禁。 在 quality/spec_audits/YYYY-MM-DD-triage.md 存在且单个审计员报告存在之前,阶段 4 不算完成。如果只有审计员报告而没有分类综合,在 PROGRESS.md 中将阶段 4 标记为 "partial — triage pending",并在继续之前完成分类。如果只有分类而没有单个报告,将阶段 4 标记为 "partial — auditor artifacts missing" 并重新生成它们。在确认分类文件和审计员报告都存在之前,不得勾选 PROGRESS.md 复选框。

用回归测试引用更新 BUG 跟踪器条目。将阶段 4(规范审计 + 分类)标记为完成。

阶段结束消息(强制 — 在阶段 4 完成后打印此消息,然后停止):

# Phase 4 Complete — Spec Audit

The Council of Three spec audit is done. [Summarize: N auditors ran, N net-new bugs
confirmed from triage, total bugs now at N. List any new bug IDs and summaries.]

To continue to Phase 5 (Reconciliation — TDD verification, writeups, closure), say:

    Run quality playbook phase 5.

Or say "keep going" to continue automatically.

打印此消息后,停止。除非用户明确要求,否则不要进入阶段 5。


阶段 5:审查后协调与收尾验证

v1.5.6 埋点: 现在追加 phase_start phase=5。对于每次门禁检查,追加 gate_check gate_name=X verdict=pass|fail|warn|skip。在阶段结束时,进行交叉验证(quality/results/quality-gate.log 非空)然后追加 phase_end phase=5。

源文件编辑防护栏(强制)。 阶段 5 将提议的修复作为补丁产物生成到 quality/patches/<BUG-NNN>-fix.patch 和 quality/patches/<BUG-NNN>-regression-test.patch。阶段 5 不得将这些补丁应用到 quality/ 之外的源文件。一次修改目标源代码树的自审计运行是缺陷,而非合法的阶段 5 输出——由操作员在一个单独的、受监督的步骤中决定何时应用补丁。在运行结束时,playbook 会调用 bin.run_state_lib.validate_no_source_edits(target_dir);如果该辅助工具报告任何非 quality/ 路径为脏,则追加一个 error recoverable:false 事件并引用这些违规项,然后以 run_end status=aborted 结束运行。此规则在 v1.5.6 中再次得到确认,此前 2026-05-02 的 Codex 引导运行在阶段 5 失控,在被终止前编辑了 quality/ 之外的五个源文件。

本阶段必需的参考文件:

  • quality/PROGRESS.md — 累计 BUG 跟踪表(权威发现列表)
  • references/challenge_gate.md — 用于误报检测的两轮挑战协议
  • references/requirements_pipeline.md — 评审后的核对流程
  • references/review_protocols.md — 反转后的回归测试清理
  • references/spec_audit.md — 冲突的验证探测协议

阶段 5 进入门禁(强制 — 硬性停止)。 在继续之前,确认以下所有阶段 4 产物均存在:

  1. quality/spec_audits/ 目录存在,并且至少包含一个 *triage* 文件(分诊综合报告)
  2. quality/spec_audits/ 至少包含一个 *auditor* 文件(单个审计员报告)
  3. quality/PROGRESS.md 存在,并且其阶段 4 行标记为 [x]

如果其中任何一项缺失,请停止并返回阶段 4。在确认规范审计产物存在之前,不要继续进行核对 — 没有分诊数据的核对会产生不完整的关闭报告。

重新阅读 quality/PROGRESS.md — 特别是累计 BUG 跟踪表。这是跨代码评审和规范审计的所有发现的权威列表。

挑战门禁(核对前强制)。 在运行关闭验证之前,对每个匹配自动触发模式的已确认 bug 应用挑战门禁。阅读 references/challenge_gate.md 了解完整协议。概括如下:

  1. 扫描 BUG 跟踪表,查找匹配任何自动触发模式的 bug(安全类发现、在引用位置带有设计决策注释的代码、没有规范依据的发现、处理同一关注点的兄弟代码路径却做法不同、关于缺失功能的发现)。
  2. 对每个触发的 bug,使用参考文件中描述的全新 sub-agent 运行两轮挑战。
  3. 将裁决记录在 quality/challenge/BUG-NNN-challenge.md 中。
  4. 应用裁决:CONFIRMED bug 正常继续。DOWNGRADED bug 调整其严重性。REJECTED bug 从 BUG 跟踪表中移除,并连同挑战推理重新安置到 BUGS.md 的 "Reviewed and dismissed" 附录中。

全程运用常识。 挑战门禁的主要目的是捕捉那些模式匹配压过判断的发现。如果一个 bug 会让你在向上游维护者报告时显得愚蠢 — 一个自文档化的占位符被标记为严重漏洞、一个有文档记录的设计决策被标记为缺陷、一个有意的功能缺口被标记为安全漏洞 — 它就不应通过挑战。常识测试不是众多因素之一;它是整个评审的框架。

为什么存在这个门禁: 在 v1.4.6 edgequake 基准测试中,代码评审确认了 42 个 bug,其中 7 个被评为 CRITICAL。经过人工评审,最强的发现(BUG-001,source_ids 覆盖)是 HIGH,而非 CRITICAL。六个 "CRITICAL" 租户隔离 bug 是有文档记录的功能缺口,并带有明确的 WHY-OODA81 注释。一个 "CRITICAL" JWT 发现(BUG-041)是一个自文档化的开发占位符,包含字面字符串 "change-me-in-production。" 模型在多轮反驳中一直为这些发现辩护,因为它的本能是发现并捍卫 bug,而不是运用常识判断什么构成缺陷。挑战门禁强制这种常识评审在发现最终确定之前发生。

  1. 运行审查后对账,按 references/requirements_pipeline.md 中所述执行。更新 COMPLETENESS_REPORT.md。
  2. 运行闭环验证: 对 BUG 跟踪器中的每一行,验证其要么有回归测试引用,要么有明确的豁免。如果有任何 BUG 两者皆无,现在就编写测试或豁免。
  3. Triage-to-BUGS.md 同步门禁(强制)。 重新阅读 triage 报告(quality/spec_audits/*-triage.md)。对每一个被确认为代码 bug 的发现,验证其出现在 quality/BUGS.md 中。如果 BUGS.md 不存在,现在就创建它。如果 BUGS.md 存在但缺少 triage 中已确认的 bug,则追加它们。一份 triage 报告确认了代码 bug 却没有对应的 BUGS.md 条目,即为不合规——在它们同步之前,该阶段不能标记为完成。此门禁之所以存在,是因为在 v1.3.21 基准测试中,javalin 的 triage 确认了 2 个 bug,但 BUGS.md 从未被创建。
  4. 在 spec-audit 反转后进行清理: 如果 spec audit 将任何代码审查 BUG 重新归类为设计选择或误报,则按 references/review_protocols.md 移除或迁移相应的回归测试。
  5. 解决 CR 与 spec-audit 的冲突: 如果代码审查和 spec audit 对同一发现意见不一致(一个说是 BUG,另一个说是设计选择),则按 references/spec_audit.md 部署验证探针,并将解决结果记录在 BUG 跟踪器中。

TDD sidecar 与日志一致性检查(强制)。 对 tdd-results.json 中的每一个 bug 条目,验证对应的日志文件存在且一致。如果 tdd-results.json 包含一个 verdict: "TDD verified" 的 bug,那么 quality/results/BUG-NNN.red.log 必须存在且首行为 RED,并且 quality/results/BUG-NNN.green.log 必须存在且首行为 GREEN。如果 sidecar 声称 "TDD verified" 但不存在 red-phase 日志,则该 verdict 缺乏依据——要么通过运行测试创建日志,要么将 verdict 降级为 "confirmed open"。此检查之所以存在,是因为 v1.3.46 基准测试显示 Agent 基于叙述性推理在 JSON 中写入 "TDD verified" verdict,却从未执行测试。

已执行的证据优先于叙述性产物(矛盾门禁)。 在运行终端门禁之前,检查已执行的证据与文字产物之间是否存在矛盾。已执行的证据包括:机械验证产物(quality/mechanical/*)、验证回执文件(quality/results/mechanical-verify.log、quality/results/mechanical-verify.exit)、回归测试结果(带有 xfail 结果的 test_regression.*)、TDD red-phase 日志文件(quality/results/BUG-NNN.red.log),以及管道过程中保存的任何 shell 命令输出。文字产物包括:REQUIREMENTS.md、CONTRACTS.md、代码审查、spec audit triage 和 BUGS.md。如果已执行的产物显示某个常量不存在(机械检查)、某个测试失败(回归测试),或某个 red-phase 确认了某个 bug(TDD 可追溯性)——但某个文字产物声称该常量存在、该 bug 已修复,或代码合规——则以已执行的结果为准。在继续之前,重新打开并更正矛盾的文字产物。具体而言:如果 mechanical-verify.exit 包含非零值,则 PROGRESS.md 不得声称 "Mechanical verification: passed",且终端门禁不得通过——无论任何其他产物怎么说。在 v1.3.18 中,triage 声称 RING_RESET 被保留(spec_audits/triage.md),BUGS.md 声称 "fixed in working tree",但 TDD 可追溯性显示断言 assert "case VIRTIO_F_RING_RESET:" in func 在当前源码上失败。这三者不可能同时为真——已执行的失败才是真相。此门禁本应捕获这一矛盾。 版本标记一致性检查(强制)。 从 SKILL.md 元数据中读取 version: 字段(使用引用文件解析顺序)。然后检查每一个生成的产物:PROGRESS.md 的 Skill version: 字段、每一行 > Generated by 归属行、每一个代码文件头部标记,以及每一个 sidecar JSON 的 skill_version 字段。每一个版本标记都必须与 SKILL.md 元数据完全一致。任何一处不匹配都视为基准测试失败——在继续之前修复该标记。设置此检查是因为在 v1.3.21 基准测试中,9 个仓库里有 5 个的版本标记来自更早的技能版本(v1.3.16 或 v1.3.20),原因是 PROGRESS.md 模板中包含了一个硬编码的版本号。

机械目录合规性检查。 如果 quality/mechanical/ 存在,它至少必须包含一个 verify.sh 文件。空的 quality/mechanical/ 目录是不合规的——它意味着该步骤被尝试过但被放弃了。如果本项目的范围内不存在 dispatch 函数契约,则完全不要创建 mechanical/ 目录。而是在 PROGRESS.md 中记录:Mechanical verification: NOT APPLICABLE — no dispatch/registry/enumeration contracts in scope. 如果确实存在 dispatch 契约,则 verify.sh 必须为 quality/mechanical/ 下每个已保存的提取文件包含一个验证块(而不仅仅是一个)。当存在多个产物时,只检查一个产物的 verify.sh 是不完整的。

验证回执门禁(在终端门禁前强制)。 如果 quality/mechanical/ 存在,则在终端门禁可以运行之前,下列回执文件也必须存在:

  • quality/results/mechanical-verify.log — 来自 bash quality/mechanical/verify.sh 的完整 stdout/stderr
  • quality/results/mechanical-verify.exit — 包含退出码的单行文件(例如 0)

如果任一文件缺失,现在运行 bash quality/mechanical/verify.sh > quality/results/mechanical-verify.log 2>&1; echo $? > quality/results/mechanical-verify.exit。如果退出码不是 0,则终端门禁失败——在机械不匹配被解决之前不要继续(应通过修复提取内容来解决,而不是通过编辑 verify.sh 或回执)。除非 mechanical-verify.exit 包含 0,否则 PROGRESS.md 不得声称 “Mechanical verification: passed”。设置此门禁是因为 v1.3.23 的 PROGRESS.md 声称所有验证均已通过,而 verify.sh 实际返回的是退出码 1——回执文件使这一声称可被审计。

TDD 日志闭环门禁(在终端门禁前强制)。 在继续进入终端门禁之前,枚举 quality/BUGS.md 中所有已确认的 bug ID 并验证:

  1. 每个已确认的 bug 都存在 quality/results/BUG-NNN.red.log。
  2. 如果该 bug 存在 quality/patches/BUG-NNN-fix.patch,则 quality/results/BUG-NNN.green.log 也必须存在。
  3. 每个日志文件的第一行是以下之一:RED、GREEN、NOT_RUN、ERROR。 如果任何检查失败,立即停止并使用 TDD 执行强制部分中语言感知的测试执行命令生成缺失的日志。不要在缺少 TDD 日志的情况下继续进入终端门禁——一个 bug 在 tdd-results.json 中被判定为 “TDD verified” 却没有对应的红阶段日志,这是一种矛盾。

终端门禁(在将 Phase 5 标记为完成之前强制):

前置条件检查: 终端门禁只有在 Phase 3(代码审查)和 Phase 4(规范审计)都已完成,或在 PROGRESS.md 中被明确标记为跳过并附有理由时,才可以运行。零 bug 结果只有存在代码审查和规范审计产物时才有效(即 quality/code_reviews/ 和 quality/spec_audits/ 目录中含有报告文件)。如果这些产物缺失且这些阶段未被明确跳过,则终端门禁失败——不要将 Phase 5 标记为完成。 BUGS.md 始终是必需的。 每次完成的运行都必须生成 quality/BUGS.md,无论是否发现了 bug。如果代码审查和规范审计确认零个源代码 bug,则创建 BUGS.md,其中包含一个 ## Summary,说明 "No confirmed source-code bugs found",并列出评估和排除了多少候选(例如 "Code review evaluated N candidates; spec audit evaluated M candidates; all were reclassified as design choices, test-only issues, or false positives")。这提供了一种对干净结果的肯定性断言,而不是含糊的文件缺失。一次完成但没有 BUGS.md 的运行是不合规的。

BUGS.md 标题格式。 每个确认的 bug 必须使用标题级别 ### BUG-NNN(例如 ### BUG-001 或 ### BUG-H1)。数字 ID(BUG-001)和带严重性前缀的 ID(BUG-H1、BUG-M3、BUG-L6)都是有效的。这是规范标题格式 —— 不是 ## BUG-001,不是 **BUG-001**,不是项目符号。### BUG-NNN 标题是下游工具在计数 bug 时 grep 的内容,也是 tdd-results.json id 字段必须匹配的内容。不一致的标题级别会导致机器可读的计数与文档不一致。

重新阅读 quality/PROGRESS.md。统计 BUG 跟踪器条目。然后:

  1. 向用户打印以下语句(这是强制性的,不是可选的):

    "BUG tracker has N entries. N have regression tests, N have exemptions, N are unresolved. Code review confirmed M bugs. Spec audit confirmed K code bugs (L net-new). Expected total: M + L."

  2. 将相同的语句写入 PROGRESS.md,放在一个新的 ## Terminal Gate Verification 部分下(紧跟在 BUG 跟踪器表之后)。这会将门禁持久化到产物中,以便审查者无需阅读会话日志即可验证它。

如果跟踪器条目计数不等于 M + L,请停止并核对 —— 有一个 BUG 从跟踪器中孤立了。在计数匹配之前,不要将第 5 阶段标记为完成。存在这个门禁是因为 v1.3.5 bootstrap 显示 Agent 在规范审计后可靠地跳过跟踪器更新,孤立了 30-50% 的已确认 bug。

回归测试函数名验证: 对于每个引用回归测试的 BUG 跟踪器条目,在回归测试文件中 grep 测试函数名并确认它存在。一个 Agent 可以在跟踪器中写一个测试名,而没有实际创建该测试。如果任何引用的测试函数不存在,请现在编写它,然后再通过门禁。

  1. 验证 PROGRESS.md 中的 With docs 元数据字段是否与现实匹配:如果 reference_docs/ 存在并包含文件,它应该显示 yes;否则显示 no。如果错误,请修正它。

产物文件存在性门禁(在将第 5 阶段标记为完成之前必须执行)。 在写入第 5 阶段完成复选框之前,验证每个必需的产物都作为磁盘上的文件存在 —— 而不仅仅是在 PROGRESS.md 中提及。运行这些检查(使用 ls 或等效命令):

  • quality/BUGS.md 存在(按 benchmark 34,所有已完成的运行均必需)
  • quality/REQUIREMENTS.md 存在
  • quality/QUALITY.md 存在
  • quality/PROGRESS.md 存在(显然——你正在向其中写入内容)
  • quality/COVERAGE_MATRIX.md 存在
  • quality/COMPLETENESS_REPORT.md 存在
  • quality/formal_docs_manifest.json 存在(v1.5.3——由 Phase 1 中的 bin/reference_docs_ingest.py 写入;当不存在正式文档时,空的 records[] 是有效的)
  • quality/requirements_manifest.json 存在(v1.5.3——权威的 REQ 记录,渲染到 REQUIREMENTS.md)
  • quality/use_cases_manifest.json 存在(v1.5.3——权威的 UC 记录,渲染到 USE_CASES.md / REQUIREMENTS.md 的叙述部分)
  • quality/citation_semantic_check.json 存在(v1.5.3——Phase 4 Layer-2 输出;对于 Spec Gap 运行,空的 reviews[] 是有效的)
  • 如果 Phase 3 已运行:quality/code_reviews/ 至少包含一个 .md 文件
  • 如果 Phase 4 已运行:quality/spec_audits/ 包含一个 triage 文件以及各个 auditor 文件
  • 如果 Phase 0 或 0b 已运行:quality/SEED_CHECKS.md 作为独立文件存在(并非内联在 PROGRESS.md 中)
  • 如果存在已确认的 bug:quality/bugs_manifest.json 存在(v1.5.3——按 schemas.md §8 的权威 BUG 记录)
  • 如果存在已确认的 bug:quality/results/tdd-results.json 存在
  • 如果存在已确认的 bug:对于 quality/BUGS.md 中的每个已确认 bug ID,quality/results/BUG-NNN.red.log 存在
  • 如果存在带有修复补丁的已确认 bug:对于每个具有 quality/patches/BUG-NNN-fix.patch 的 bug,quality/results/BUG-NNN.green.log 存在

对于每个缺失的文件,立即创建它。不要在缺少产出物的情况下将 Phase 5 标记为完成——如果 PROGRESS.md 中终端门禁验证所引用的文件在磁盘上不存在,该验证就毫无意义。设置此门禁是因为 v1.3.24 的基准测试表明,express 完成了所有阶段并在 PROGRESS.md 中编写了终端门禁部分,但 BUGS.md、SEED_CHECKS.md 以及代码评审/spec 审计文件从未写入磁盘。

Sidecar JSON 写入后校验(强制)。 在写入 quality/results/tdd-results.json 和/或 quality/results/integration-results.json 之后,立即重新打开每个文件并验证其包含所有必需的键。对于 tdd-results.json,必需的根键为:schema_version、skill_version、date、project、bugs、summary。bugs 中的每个条目必须具有:id、requirement、red_phase、green_phase、verdict、fix_patch_present、writeup_path。summary 对象必须包含 confirmed_open,与 verified、red_failed、green_failed 并列。对于 integration-results.json,必需的根键为:schema_version、skill_version、date、project、recommendation、groups、summary、uc_coverage。两个文件都必须具有 schema_version: "1.1"。如果有任何键缺失,立即添加——不要把不符合规范的 JSON 文件留在磁盘上。进行此校验是因为 v1.3.25 的基准测试表明,8 个仓库中有 6 个的 sidecar JSON 不符合规范:httpx 发明了一种替代 schema,serde 使用了旧式结构,javalin 省略了 summary 和各 bug 字段,其他仓库使用了无效的枚举值。 脚本验证的收尾关卡(强制,标记第 5 阶段完成前的最后一步)。 使用与参考文件相同的回退方式定位 quality_gate.py —— 按顺序遍历以下六种规范安装布局,取第一个命中的:quality_gate.py、.claude/skills/quality-playbook/quality_gate.py、.github/skills/quality_gate.py、.cursor/skills/quality-playbook/quality_gate.py、.continue/skills/quality-playbook/quality_gate.py、.github/skills/quality-playbook/quality_gate.py。从项目根目录运行它。该脚本会机械地校验:文件是否存在、BUGS.md 标题格式、sidecar JSON 的必需键 AND 每个 bug 的字段名(id、requirement、red_phase、green_phase、verdict、fix_patch_present、writeup_path)AND 枚举值 AND 摘要一致性、用例标识符、终结关卡部分、机械验证回执、版本戳、writeup 完整性、每个已确认 bug 的回归测试补丁是否存在,以及每个 writeup 中的内联修复 diff(每个 quality/writeups/BUG-NNN.md 都必须包含一个 ```diff 块)。如果脚本报告任何 FAIL 结果,请在继续之前修复每一项未通过的检查 —— 最常见的 FAIL 包括:(1) 缺少 quality/patches/BUG-NNN-regression-test.patch 文件,(2) 非规范的 JSON 字段名,例如用 bug_id 而不是 id,(3) TDD 摘要中缺少 confirmed_open,(4) writeup 没有内联修复 diff(第 6 节必须包含具体的 diff,而不只是“see patch file”)。在 quality_gate.py 以 0 退出之前,不要标记第 5 阶段完成。将脚本的完整输出追加到 quality/results/quality-gate.log。

v1.5.3 Layer-1 机械检查(schemas.md §10 不变量 #1–#18)。 除上述旧有关卡检查外,v1.5.3 中的 quality_gate.py 还强制执行 schemas.md §10 中定义的 Layer-1 不变量。每个不变量涵盖内容的简明对照表:

  • #1–#10 —— 核心契约检查。 引用层级门控、引用文档是否存在、引用哈希匹配、引用摘录是否存在 + 可定位(仅章节/行;页码永远不够)、bug→REQ 解析、前向链接解析、处置完整性、功能章节是否存在、无孤立的正式文档、INDEX.md 字段是否存在。
  • #11 —— 引用摘录的字节级相等。 关卡会按 schemas.md §5.4 对每个 Tier 1/2 引用重新运行 bin/citation_verifier.extract_excerpt,并拒绝任何与重新提取的摘录不是字节级相等的已存储 citation_excerpt。这就是 Layer-1 的反幻觉机制 —— 即使定位符是真实的,它也能捕获捏造或改写的摘录。
  • #12 —— 合法的 fix_type × disposition 组合,依据 schemas.md §3.4。
  • #13 —— manifest 包装的有效性,依据 schemas.md §1.6。
  • #14 —— REQ 层级受所引用 FORMAL_DOC 层级的约束(Tier 1 的 REQ 不能引用 Tier 2 的 FORMAL_DOC)。
  • #15 —— ID 唯一性,在每个 manifest 内。
  • #16 —— 冗余引用元数据(version、date、url、retrieved)在存在时必须与 FORMAL_DOC 一致。
  • #17 —— 语义检查的多数决规则。 对同一 Tier 1/2 REQ,3 个 overreaches 判定中有 ≥2 个即关卡失败(见第 4 阶段的 Layer 2 子检查)。
  • #18 —— 数组值唯一性,在 REQ.use_cases 和 UC.formal_doc_refs 中。

citation_stale 是关卡报告的标记,而不是引用记录上的字段。 当已存储的 citation.document_sha256 与实时的 FORMAL_DOC.document_sha256 不一致时,quality_gate.py 会在 quality_gate_report.json(或等价物)中写入一条 citation_stale 条目。不要将 citation_stale 写到引用记录本身上 —— 该记录保持为纯输入,而 stale 标记是关卡报告输出,依据 schemas.md §5.1 / §10 不变量 #3。 不要在此说明文字中实现门禁。 上面的第 1 层检查清单是 quality_gate.py 所强制执行内容的摘要——权威定义位于 schemas.md。门禁的实现(v1.5.3 实现的第 5 阶段)位于 quality_gate.py;SKILL.md 描述协议,但不复述这些不变量。

用例标识符格式。 REQUIREMENTS.md 必须为所有派生的用例使用规范用例标识符,格式为 UC-01、UC-02 等。每个用例都必须标注其标识符。这是机器可读可追溯性所必需的——该标识符格式使 quality_gate.py 和下游工具能够以编程方式对用例进行计数和交叉引用。以散文段落形式书写、不带标识符的用例是不符合规范的。

更新 PROGRESS.md:将第 5 阶段标记为完成。BUG 跟踪器现在应显示每个条目的关闭状态。

阶段结束消息(强制——在第 5 阶段完成后打印此消息,然后停止):

# Phase 5 Complete — Reconciliation and TDD Verification

All confirmed bugs now have regression tests, writeups, and TDD red-green verification.
[Summarize: N total confirmed bugs, N with TDD verified status, N with fix patches.
List all bug IDs with one-line summaries and their TDD verdicts.]

To continue to Phase 6 (Final verification and quality gate), say:

    Run quality playbook phase 6.

Or say "keep going" to continue automatically.

打印此消息后,停止。除非用户明确要求,否则不要继续进入第 6 阶段。


第 6 阶段:验证

v1.5.6 埋点: 现在追加 phase_start phase=6。在阶段结束时,进行交叉验证(quality/BUGS.md 非空且包含 ^## BUG- 章节,并且 quality/INDEX.md 已更新 gate_verdict 字段),然后追加 phase_end phase=6。在第 6 阶段关闭后,追加 run_end status=success(如适用,也可为 aborted / failed)。

此阶段所需的参考:

  • references/verification.md — 45 项自检基准

为什么需要验证阶段? AI 生成的输出可能看起来光鲜亮丽,却在细微之处出错。引用未定义 fixture 的测试报告 0 个失败但有 16 个错误——而“0 个失败”听起来像是成功。集成协议可能列出实际 schema 中不存在的字段名。验证阶段会在用户发现问题之前捕获这些问题,这一点很重要,因为对生成的质量手册的信任是脆弱的——一个错误的字段名就会削弱对其他一切的信心。

第 6 阶段的执行模型:增量式,而非单体式。 第 6 阶段以一系列独立的验证步骤运行,每个步骤只读取它所需的文件,检查一件事,并将其结果写入 quality/results/phase6-verification.log,然后再进行下一步。不要把全部产物一次性加载到上下文中。不要在读取产物时试图把完整的验证清单记在内存中。下面的每个步骤都是自包含的——读取文件、检查条件、追加结果、丢弃上下文。

步骤 6.1:机械验证关闭(强制的第一步)

如果 quality/mechanical/ 存在,第 6 阶段的字面意义上的第一个动作是:

bash quality/mechanical/verify.sh > quality/results/mechanical-verify.log 2>&1
echo $? > quality/results/mechanical-verify.exit

在 shell 中执行此命令。不要用 Python 脚本替代,不要读取产物文件并对其内容进行断言,不要跳过此步骤。命令必须是 bash quality/mechanical/verify.sh——不是 python3 -c "...",不是 cat quality/mechanical/... | grep ...,也不是任何其他等价形式。

记录退出码。如果非零,第 6 阶段立即失败。 不要继续进行后续步骤。回到提取步骤:删除不匹配的 *_cases.txt,用全新的 shell 重定向重新运行提取命令,重新验证,并更新所有引用了旧提取结果的下游产物。

在 PROGRESS.md 的 ## Phase 6 Mechanical Closure 下记录,并追加到 quality/results/phase6-verification.log:

[Step 6.1] Mechanical verification: PASS (exit 0)

为什么这不可替代: 在 v1.3.23 中,模型用 python3 -c "from pathlib import Path; ..." 替换了 bash verify.sh,该命令读取(伪造的)产物文件并对其内容进行断言——这是一个循环检查,尽管产物是伪造的却通过了。唯一可信的验证是重新运行生成该产物的同一 shell 管道,并对比结果。任何其他方法都可能被损坏的中间文件所欺骗。

步骤 6.2:运行 quality_gate.py(脚本验证检查)

运行机械验证关卡:

python3 quality_gate.py . > quality/results/quality-gate.log 2>&1  # locate via fallback (six canonical layouts, in order): quality_gate.py, .claude/skills/quality-playbook/quality_gate.py, .github/skills/quality_gate.py, .cursor/skills/quality-playbook/quality_gate.py, .continue/skills/quality-playbook/quality_gate.py, .github/skills/quality-playbook/quality_gate.py
echo $? >> quality/results/phase6-verification.log

读取 quality/results/quality-gate.log。如果它报告任何 FAIL 结果,请先修复每个失败的检查再继续。最常见的 FAIL 有:(1) 缺少 quality/patches/BUG-NNN-regression-test.patch 文件,(2) 非规范 JSON 字段名,如用 bug_id 而非 id,(3) TDD 摘要中缺少 confirmed_open,(4) 编写文档中没有内联修复 diff,(5) 缺少 TDD 红/绿日志文件。在 quality_gate.py 以 0 退出之前,不要继续。

追加到 quality/results/phase6-verification.log:

[Step 6.2] quality_gate.py: PASS (exit 0) — N checks passed, 0 FAIL, 0 WARN

本步骤覆盖验证基准:14(sidecar JSON)、17(测试文件扩展名)、18(用例数量)、20(编写文档)、23(机械产物)、26(版本戳)、27(机械目录)、29(分诊到 BUGS 同步)、34(BUGS.md 存在)、38(单个审计员报告)、39(BUGS.md 标题格式)、40(产物文件存在)、41(sidecar JSON 验证)、42(脚本验证关闭)、43(用例标识符)、44(回归测试补丁)、45(编写文档内联 diff)。

v1.5.3 Layer-1 不变量也在此处运行。 quality_gate.py 还强制执行 schemas.md §10 不变量 #1–#18(在上文 Phase 5 中概述)。特别地,脚本会按照 schemas.md §5.4 对每一条 Tier 1/2 引用重新运行 bin/citation_verifier.extract_excerpt,并拒绝任何与重新提取输出不逐字节相等的已存储 citation_excerpt——这是对摄取后篡改的捕获。如果此处任何 Layer-1 不变量失败,请修复底层清单记录(而不是关卡,也不是摘录)并重新运行。

步骤 6.3:测试执行验证

运行功能测试套件。仅读取 quality/test_functional.* 来确定测试命令:

  • Python: pytest quality/test_functional.py -v 2>&1 | tail -20
  • Java: mvn test -Dtest=FunctionalTest 或 gradle test --tests FunctionalTest
  • Go: go test -v 指向生成的测试文件所在的包
  • TypeScript: npx jest functional.test.ts --verbose
  • Rust: cargo test
  • Scala: sbt "testOnly *FunctionalSpec"

同时检查失败和错误。缺少夹具、导入失败或未解析依赖导致的错误都算作损坏的测试。预期失败(xfail)回归测试不计入此检查。

追加到 quality/results/phase6-verification.log:

[Step 6.3] Functional tests: PASS — N tests, 0 failures, 0 errors

这覆盖基准 8(所有测试通过)和 9(现有测试未被破坏)。

步骤 6.4:验证清单 — 逐文件检查

以小批量方式处理 references/verification.md 中剩余的验证基准。对于每一批,只读取所需的文件,检查条件,并追加结果。每批不要读取超过 2 个文件。

批次 A — QUALITY.md(基准 1-2、10): 读取 quality/QUALITY.md。统计场景数量。验证每个场景都引用了真实代码(grep 引用的函数名)。追加结果。

批次 B — 功能测试文件(基准 3-7): 读取 quality/test_functional.*。检查跨变体覆盖(约 30%)、边界测试数量、断言深度(值检查与存在性检查)、层级正确性(结果与机制)、变异有效性。

批次 C — 协议文件(基准 11-13): 读取 quality/RUN_CODE_REVIEW.md,然后读取 quality/RUN_INTEGRATION_TESTS.md,然后读取 quality/RUN_SPEC_AUDIT.md — 一次一个。检查每个文件都是自包含且可执行的。验证集成测试中的 Field Reference Table。

批次 D — 回归测试(基准 15-16、24): 如果 quality/test_regression.* 存在,则读取它。验证跳过守卫引用了 bug ID,验证补丁验证门禁命令,验证源码检查测试不使用 run=False。

批次 E — 枚举与分诊检查(基准 19、21-22、25、36): 读取 quality/code_reviews/*.md(仅枚举部分)。读取 quality/spec_audits/*triage*(仅验证探针部分)。检查双列表比较、可执行的探针证据、无循环机械产物引用、矛盾门禁。

批次 F — 延续模式(基准 32-33): 仅当 quality/SEED_CHECKS.md 存在时。读取它,验证机械执行,验证 PROGRESS.md 中的收敛部分。

将每一批结果追加到 quality/results/phase6-verification.log:

[Step 6.4A] QUALITY.md scenarios: PASS — 8 scenarios, all reference real code
[Step 6.4B] Functional test quality: PASS — 30% cross-variant, assertion depth OK
[Step 6.4C] Protocol files: PASS — all self-contained and executable
[Step 6.4D] Regression tests: PASS — all skip guards present
[Step 6.4E] Enumeration/triage: PASS — two-list checks present, probes have assertions
[Step 6.4F] Continuation mode: SKIP — no SEED_CHECKS.md

如果任何批次失败,请在继续下一批之前立即修复问题。

步骤 6.5:元数据一致性检查

读取 quality/PROGRESS.md(仅元数据和产物清单部分)。然后抽查:

  • 需求数量在 REQUIREMENTS.md 头部、PROGRESS.md 产物清单和 COVERAGE_MATRIX.md 头部之间保持一致。三者必须声明相同的数字。
  • With docs 字段准确反映 reference_docs/ 是否存在
  • Terminal Gate Verification 部分存在且已填写

然后读取 quality/COMPLETENESS_REPORT.md(仅结论部分)。验证没有残留的过时对账前文本 — 如果同时存在 ## Verdict 和 ## Updated verdict(或 ## Post-Review Reconciliation)部分,则完全删除原始的 ## Verdict 部分。最终文档必须恰好有一个 ## Verdict 标题。

追加到 quality/results/phase6-verification.log:

[Step 6.5] Metadata consistency: PASS — requirement counts match, version stamps consistent

如果任何元数据过时,请立即修复。

检查点:最终确定 PROGRESS.md

重新读取 quality/PROGRESS.md。更新:

  • 将阶段 6(验证基准)标记为完成并附上时间戳

  • 验证 BUG 跟踪器对每个条目都有闭环

  • 添加最后一行摘要:"Run complete. N BUGs found (N from code review, N from spec audit). N regression tests written. N exemptions granted."

  • 向用户打印建议的下一个提示词(强制,所有运行)。 这适用于每一次运行,包括基线 — 它不是迭代特定的。打印以下块,以便用户复制粘贴以开始下一次迭代:

    对于基线运行(无迭代策略):

    ────────────────────────────────────────────────────────
    Next iteration suggestion:
    "Run the next iteration of the quality playbook using the gap strategy."
    ────────────────────────────────────────────────────────
    

    对于迭代运行,使用以下映射确定下一个策略:

    • gap → 建议 unfiltered
    • unfiltered → 建议 parity
    • parity → 建议 adversarial
    • adversarial → 建议 "Run the quality playbook from scratch."(循环完成)

完成的 PROGRESS.md 是永久的审计追踪。它记录了该技能做了什么、发现了什么,以及如何解决每个发现。用户可以阅读它以了解运行情况、调试失败,并在多次运行之间进行比较。

收敛检查(仅限延续模式)

范围: 仅限本小节。上方的建议下一步提示词步骤是无条件的,必须在每次运行时执行,无论是否跳过此收敛检查。

此步骤仅在 Phase 0 已执行时运行(即 quality/SEED_CHECKS.md 已由先前运行的分析生成)。如果这是首次运行且没有先前历史,则跳到 Phase 7。

将本次运行的 bug 列表与种子列表进行对比:

  1. 统计净新增 bug: 本次运行的 BUGS.md 中与任何种子都不匹配的 bug(按 file:line)。如果某个 bug 在之前任何一次运行中都未被发现,则它是"净新增"的。
  2. 统计种子延续: 在本次运行中被重新确认的种子(Step 0b 中结果为 FAIL)。
  3. 统计种子解决: 现在已通过的种子(该 bug 自先前运行以来已修复)。

向 PROGRESS.md 写入一个 ## Convergence 小节:

## Convergence

Run number: N (N prior runs in quality/previous_runs/)
Seeds from prior runs: S (S confirmed, R resolved)
Net-new bugs this run: K
Convergence: [CONVERGED | NOT CONVERGED]

Net-new bugs:
- BUG-NNN: [summary] (file:line) — not in any prior run

收敛判定标准: 如果 净新增 bug = 0,则本次运行已收敛——本次运行发现的每个 bug 都已是先前运行中已知的。这意味着在声明的范围内,进一步运行不太可能发现更多 bug。

如果已收敛: 向用户打印:"本次运行未发现在先前 N 个已知 bug 之外的任何新 bug。此范围的 bug 发现已收敛。所有运行中确认的 bug 总数:T。" 然后进入 Phase 7。

如果未收敛——自动重新迭代。 当收敛检查显示净新增 bug > 0 且迭代次数尚未达到上限(默认:5)时,该技能会自动重新迭代:

  1. 在 PROGRESS.md 中记录迭代编号和净新增数量。
  2. 通过 bin/run_playbook.archive_previous_run(repo_dir, timestamp)(或在 Phase 6 成功时使用 bin.archive_lib.archive_run())归档当前的 quality/ 目录。这些操作会将 quality/ 快照到 quality/previous_runs/<timestamp>/quality/,并写入每次运行的 INDEX.md 以及一行 RUN_INDEX.md。
  3. 从 Phase 0 重新开始(此时它会在 quality/previous_runs/ 中发现刚刚归档的运行)。
  4. 向用户打印:"迭代 N 发现了 K 个净新增 bug。正在归档并开始迭代 N+1(最大 M)。"

迭代计数器在首次运行时从 1 开始。每次归档并重新开始都会使其递增。当计数器达到上限时,即使未收敛也停止迭代,并打印:"已达到最大迭代次数(M)但未收敛。上一次运行中发现了 K 个净新增 bug。所有运行中确认的 bug 总数:T。"

迭代上限。 默认最大值为 5 次迭代。如果用户的提示词中包含明确的上限(例如"以 3 次迭代运行 playbook"),则改用该上限。如果用户的提示词中写着"单次运行"或"不迭代",则完全跳过重新迭代,并将未收敛视为迭代前的行为:打印净新增数量并建议重新运行。

上下文窗口意识。 如果在重新迭代过程中的任何时候你察觉到上下文窗口已被大量消耗(例如,你产生的输出明显比先前迭代更短或质量更低),则停止迭代,将当前状态写入 PROGRESS.md,并打印:"因上下文限制停止迭代。已完成 M 次迭代中的 N 次。重新运行 playbook 以继续——Phase 0 将从 quality/previous_runs/ 中读取种子列表。" 这是一个安全阀,而非目标——大多数代码库会在 2-3 次迭代内收敛。

为什么这很重要: 单次 playbook 运行会以非确定性的方式探索代码库的一个子集。在 virtio 上的首次运行可能发现 BUG-001 和 BUG-004,但漏掉 BUG-005。第二次运行可能发现 BUG-005 和 BUG-006。到第三次运行时,如果没有出现净新增 bug,则探索很可能已覆盖了高价值区域。种子列表确保先前发现的 bug 在运行之间永不丢失,而收敛检查则告诉用户何时额外的运行会产生递减的回报。自动重新迭代意味着该技能是自包含的——调用方无需外部脚本或手动重新运行即可实现收敛。

阶段结束消息(强制——在 Phase 6 完成后打印此内容,然后停止):

# Phase 6 Complete — All Phases Done

The quality playbook baseline run is complete. Here's the summary:

[Include: total confirmed bugs, quality gate pass/fail/warn counts,
list of all bug IDs with one-line summaries and severities.]

Key output files:
- quality/BUGS.md — all confirmed bugs with spec basis and patches
- quality/results/tdd-results.json — structured TDD verification results
- quality/patches/ — regression test and fix patches for every bug

You can now run iteration strategies to find additional bugs. Iterations typically
add 40-60% more confirmed bugs on top of the baseline. The recommended cycle is:
gap → unfiltered → parity → adversarial.

To run all four iterations automatically, say:

    Run all iterations.

I'll orchestrate each strategy as a separate sub-agent with its own context window.

To run one iteration at a time, say:

    Run the next iteration of the quality playbook.

Or ask me about the results: "Tell me about BUG-001" or "Which bugs are highest priority?"

After you fix the bugs, say "recheck" to verify the fixes were applied correctly.

打印此消息后,停止。除非用户明确要求,否则不要继续执行迭代。

迭代结束消息(强制 — 每次迭代完成后打印此消息,然后停止):

# Iteration Complete — [Strategy Name]

[Summarize: N net-new bugs found in this iteration, total now at N.
List new bug IDs with one-line summaries.]

[If there are remaining strategies in the recommended cycle, suggest the next one:]
The next recommended strategy is [next strategy]. To run it, say:

    Run the next iteration using the [next strategy] strategy.

[If all four strategies have been run:]
All four iteration strategies have been run. Total confirmed bugs: N.
You can review the results, ask about specific bugs, or re-run any strategy.

After you fix the bugs, say "recheck" to verify the fixes were applied correctly.

Or say "keep going" to run the next iteration automatically.

打印此消息后,停止。除非用户明确要求,否则不要继续执行下一次迭代。


复查模式 — 验证 Bug 修复

复查模式是一种轻量级验证过程,用于检查上一次运行中发现的 bug 是否已修复。复查不会重新运行完整的六阶段流水线(60-90 分钟),而是读取现有的 quality/BUGS.md,针对当前源代码树逐一检查每个 bug,并报告哪些 bug 已修复、哪些仍未解决。一次典型的复查耗时 2-10 分钟。

何时使用复查模式: 当用户(或其他 Agent)已针对 playbook 发现的 bug 应用了修复之后。用户会说“复查”或“验证 bug 修复”或“检查哪些 bug 已修复”。

不要将复查模式用作运行完整 playbook 的替代方案。复查仅验证此前发现的 bug — 它不会发现新的 bug。

复查流程

第 1 步:读取 bug 清单。

读取 quality/BUGS.md 并解析每个 ### BUG-NNN 条目。对每个 bug,提取:

  • Bug ID(例如 BUG-001)
  • **File:** 字段中的文件路径和行号
  • 描述摘要(**Description:** 的第一句)
  • 严重程度
  • **Fix patch:** 字段中的修复补丁路径(例如 quality/patches/BUG-001-fix.patch)
  • **Regression test:** 字段中的回归测试路径

第 2 步:针对当前源代码检查每个 bug。

对每个 bug,按顺序执行以下检查:

  1. 修复补丁检查。 如果引用的路径上存在修复补丁,针对当前代码树运行 git apply --check --reverse quality/patches/BUG-NNN-fix.patch。如果反向应用成功(退出码 0),说明修复补丁已被应用 — 该 bug 很可能已修复。如果失败,说明修复尚未应用或代码已变更。

  2. 源代码检查。 打开所引用行号处的文件。阅读周围上下文(±20 行)。将所见内容与 bug 描述进行对比。有问题的代码是否已被修改?该修复是否解决了 bug 报告中描述的根因?

  3. 回归测试执行。 如果存在回归测试补丁:

    • 应用它:git apply quality/patches/BUG-NNN-regression-test.patch
    • 运行测试(使用项目的测试运行器)。如果测试通过,则该 bug 已修复。如果测试失败,则该 bug 仍然存在。
    • 反向应用补丁:git apply -R quality/patches/BUG-NNN-regression-test.patch

    如果回归测试补丁无法干净地应用(因为源代码已变更),请记录这一点,并仅回退到源代码检查。

  4. 判定。 分配以下状态之一:

    • FIXED — 修复补丁已应用且回归测试通过(或者,如果测试无法运行,源代码检查确认了修复)
    • PARTIALLY_FIXED — 有问题的代码已变更,但回归测试仍然失败,或者该修复只解决了 bug 的部分而非全部方面
    • STILL_OPEN — 原始有问题的代码未变更,或回归测试仍然失败
    • INCONCLUSIVE — 无法确定状态(文件已移动、代码经过大量重构、补丁无法应用)

第 3 步:生成复查结果。

使用以下 schema 写入 quality/results/recheck-results.json:

注意:复查 schema 使用 "schema_version": "1.0"(而非 "1.1"),因为其结构与 TDD sidecar 不同 — source_run 以及每个 bug 的 status/evidence 字段是复查 schema 独有的。质量门禁将此值校验为 "1.0"。

{
  "schema_version": "1.0",
  "skill_version": "1.5.6",
  "date": "YYYY-MM-DD",
  "project": "<project name>",
  "source_run": {
    "bugs_md_date": "<date from BUGS.md header>",
    "total_bugs": <N>
  },
  "results": [
    {
      "id": "BUG-001",
      "severity": "HIGH",
      "summary": "<one-line summary>",
      "status": "FIXED",
      "evidence": "<what confirmed the fix — e.g., 'reverse-apply succeeded + regression test passes'>"
    }
  ],
  "summary": {
    "total": <N>,
    "fixed": <N>,
    "partially_fixed": <N>,
    "still_open": <N>,
    "inconclusive": <N>
  }
}

同时将人类可读的摘要写入 quality/results/recheck-summary.md:

# Recheck Results

> Recheck of quality/BUGS.md from <date>
> Recheck run: <today's date>
> Skill version: <version>

## Summary

| Status | Count |
|--------|-------|
| Fixed | N |
| Partially fixed | N |
| Still open | N |
| Inconclusive | N |
| **Total** | **N** |

## Per-Bug Results

| Bug | Severity | Status | Evidence |
|-----|----------|--------|----------|
| BUG-001 | HIGH | FIXED | Reverse-apply succeeded, regression test passes |
| BUG-002 | MEDIUM | STILL_OPEN | Original code unchanged at quality_gate.py:125 |
| ... | ... | ... | ... |

## Still Open — Details

[For each STILL_OPEN or PARTIALLY_FIXED bug, include a brief explanation of what remains to be fixed.]

第 4 步:打印复查摘要。

向用户打印摘要表格,然后停止。示例:

# Recheck Complete

Checked 19 bugs from quality/BUGS.md against current source.

| Status | Count |
|--------|-------|
| Fixed | 17 |
| Still open | 2 |
| **Total** | **19** |

Fixed bugs: BUG-001, BUG-002, BUG-003, BUG-004, BUG-005, BUG-006, BUG-007,
BUG-008, BUG-009, BUG-010, BUG-011, BUG-013, BUG-014, BUG-015, BUG-016,
BUG-017, BUG-018

Still open: BUG-012 (stale .orig file still present), BUG-019 (benchmark 40
artifact list not updated)

Results saved to:
- quality/results/recheck-results.json (machine-readable)
- quality/results/recheck-summary.md (human-readable)
触发 recheck 模式

当用户说出以下任意内容时,recheck 模式会激活:"recheck"、"verify the bug fixes"、"check which bugs are fixed"、"recheck the bugs"、"run recheck mode",或其他明确表示他们想验证修复而不是寻找新 bug 的类似表述。触发后,完全跳过阶段 1-7,只执行上面的 recheck 流程。


阶段 7:呈现、探索、改进(交互式)

在生成并验证之后,清晰地呈现结果,并让用户掌控接下来发生的事。此阶段包含三个部分:可快速浏览的摘要、按需下钻,以及改进路径菜单。

不要跳过此阶段。 阶段 1-6 的自主输出是一个可靠的起点,但用户需要理解生成了什么、探索对他们重要的内容,并选择如何改进它。只有当拥有项目的人信任并理解它时,一本高质量 playbook 才有用。不加解释地丢出六个文件,只会产生没人阅读的产物。

第 1 部分:摘要表

呈现一个用户能在 10 秒内浏览完的单一表格:

Here's what I generated:

| File | What It Does | Key Metric | Confidence |
|------|-------------|------------|------------|
| REQUIREMENTS.md | Testable requirements with use cases | N requirements, N use cases | ██████░░ Medium — solid baseline from 5-phase pipeline, improves with refinement passes |
| QUALITY.md | Quality constitution | 10 scenarios | ██████░░ High — grounded in code, but scenarios are inferred, not from real incidents |
| Functional tests | Automated tests | 47 passing | ████████ High — all tests pass, 35% cross-variant |
| RUN_CODE_REVIEW.md | Three-pass code review | 3 passes | ████████ High — structural + requirement verification + consistency |
| RUN_INTEGRATION_TESTS.md | Integration test protocol | 9 runs × 3 providers | ██████░░ Medium — quality gates need threshold tuning |
| RUN_SPEC_AUDIT.md | Council of Three audit | 10 scrutiny areas | ████████ High — guardrails included |
| RUN_TDD_TESTS.md | TDD verification protocol | N bugs to verify | ████████ High — mechanical red-green cycle with spec traceability |

根据你实际生成的内容调整表格——文件名、指标和置信度会因项目而异。置信度列最重要:它告诉用户应该把注意力放在哪里。

置信度级别:

  • High — 直接来源于代码、规格或 schema。不太可能需要修订。
  • Medium — 合理推断,但可能出错。受益于用户输入。
  • Low — 最佳猜测。绝对需要用户输入才有用。

在表格之后,添加一个 "Quick Start" 区块,其中包含用于执行每个产物的可复制提示词:

To use these artifacts, start a new AI session and try one of these prompts:

• Run a code review:
  "Read quality/RUN_CODE_REVIEW.md and follow its instructions to review [module or file]."

• Run the functional tests:
  "[test runner command, e.g. pytest quality/ -v, mvn test -Dtest=FunctionalTest, etc.]"

• Run the integration tests:
  "Read quality/RUN_INTEGRATION_TESTS.md and follow its instructions."

• Start a spec audit (Council of Three):
  "Read quality/RUN_SPEC_AUDIT.md and follow its instructions using [model name]."

• Run TDD verification for confirmed bugs:
  "Read quality/RUN_TDD_TESTS.md and follow its instructions to verify all confirmed bugs."

根据实际项目调整测试运行器命令和模块名。重点是给用户可复制粘贴的提示词——不是描述他们可以做什么,而是他们实际会输入的内容。

在 Quick Start 区块之后,添加一行:

"你可以向我询问其中任何一项以查看详情——例如,'show me Scenario 3' 或 'walk me through the integration test matrix.'"

第 2 部分:按需下钻

当用户询问某个具体条目时,给出聚焦的摘要——不是整个文件,而是关键决策以及你不确定的地方。示例:

  • "Tell me about Scenario 4" → 展示场景文本,解释它来自哪里(哪种防御模式或领域知识),并标明哪些是你推断的、哪些是你确知的。
  • "Show me the integration test matrix" → 展示运行组,解释并行策略,并注明哪些质量门是你从 schema 推导出来的、哪些是猜的。
  • "How do the functional tests work?" → 展示三个测试组,解释到规格和场景的映射,并突出你最没把握的测试。

用户可能会在准备好改进任何内容之前进行多次下钻。这没问题——让他们按自己的节奏探索。

第 3 部分:改进菜单

在用户看过摘要(并可选地深入查看详细信息)后,展示改进选项:

“五种改进方式:”

1. 交互式审查需求 — 阅读 quality/REVIEW_REQUIREMENTS.md,按用例组织的需求引导式讲解。你可以选择特定用例深入查看,也可以按顺序全部走一遍。另一个模型也可以对完整性报告进行事实核查(跨模型审计)。适合:找出流水线遗漏的缺口。

2. 用不同模型细化需求 — 阅读 quality/REFINE_REQUIREMENTS.md 并运行一轮细化。你可以用任意 AI 模型运行——Claude、GPT、Gemini——每个模型都会发现不同的缺口。想用多少个模型都可以,直到收益递减为止。每一轮都会备份当前版本,并在 quality/VERSION_HISTORY.md 中记录变更。适合:把需求从基线推向完整。

3. 审查并加固其他条目 — 选择任意场景、测试或协议部分,我会和你一起过一遍。适合:收紧特定质量门禁、修正推断出的场景、补充遗漏的边界情况。

4. 引导式问答 — 我会就我无法从代码中推断的事项问你 3-5 个有针对性的问题:事故历史、预期分布、成本容忍度、模型偏好。适合:填补让场景更具权威性的知识缺口。

5. 输入额外文档 — 需求流水线在意图来源更多时效果更好。把以下任意内容指给我,我会用它们来细化需求和质量章程:

  • 导出的 AI 聊天记录(Claude、Gemini、ChatGPT 导出内容,Claude Code 会话记录)
  • 讨论过该项目的 Slack 或 Teams 频道
  • 关于该项目的邮件线程、Jira/Linear 工单或 GitHub issue
  • 设计文档、架构决策记录或会议纪要
  • 新闻组帖子、论坛讨论或邮件列表归档

你可以使用 Claude Cowork、GitHub Copilot 或 OpenClaw 等工具连接这些来源,并把它们收集到一个文件夹中,然后把这个文件夹指给我。适合:让场景和需求扎根于真实项目历史,而不是推断。

“你可以任意组合这些方式,顺序不限。你想先从哪一个开始?”

执行每个改进路径

路径 1:交互式审查需求。 引导用户查看 quality/REVIEW_REQUIREMENTS.md,并提供一起逐步过一遍的选项。该协议支持自主引导(选择用例)、完全引导(按顺序走查)以及跨模型审计(由不同模型对完整性报告进行事实核查)。进度记录在 quality/REFINEMENT_HINTS.md 中,以便用户可以从上次中断的地方继续。

路径 2:用不同模型完善需求。 引导用户查看 quality/REFINE_REQUIREMENTS.md。每一轮完善都会:将当前版本备份到 quality/history/vX.Y/,读取 REFINEMENT_HINTS.md 中的反馈,进行有针对性的改进,提升次版本号,并在 VERSION_HISTORY.md 中记录变更。用户可以用 Claude、GPT、Gemini 或任何其他模型来运行此流程——每个模型都能发现不同的盲区。持续运行,直到收益递减。

路径 3:审查并加固其他条目。 用户选择一个场景、测试或协议章节。逐步走查:展示当前文本,解释你的推理,询问是否准确。根据他们的反馈进行修订。如果功能测试发生变化,则重新运行测试。

路径 4:引导式问答。 根据你在探索过程中实际发现的内容,提出 3-5 个问题。以下类别涵盖了最常见的高杠杆缺口:

  • 场景的事件历史。 “我发现了 [具体的防御性代码]。是什么故障导致了这种情况?有多少条记录受到影响?”
  • 质量门禁阈值。 “我正在检查 [字段] 是否包含 [值]。什么样的分布是正常的?什么情况会表明有问题?”
  • 集成测试的规模和成本。 “该协议运行 [N] 个测试,成本约为 $[X]。我应该增加还是减少覆盖范围?”
  • 测试范围。 “我生成了 [N] 个功能测试。你现有的测试套件覆盖了 [其他领域]。是否存在缺口?”
  • 规范审计的模型偏好。 “你使用哪些 AI 模型?你是否注意到它们各自的具体优势?”

用户回答后,修订生成的文件并重新运行测试。

路径 5:输入额外文档。 用户引导你查看额外的意图来源——聊天历史、Slack 导出、邮件线程、Jira 工单、设计文档、会议记录、论坛存档。这些内容包含未进入正式文档的设计决策、事件历史和质量讨论。

  1. 扫描索引文件并导航到与质量相关的内容(与步骤 0 相同的方法,但现在有具体目标——你知道哪些需求需要佐证,哪些场景需要阈值,哪些缺口需要填补)。
  2. 提取:包含具体数字的事件故事、防御性模式的设计依据、质量框架讨论、跨模型审计结果,以及仅从代码中无法看到的行为契约。
  3. 将发现作为新的反馈条目填入 quality/REFINEMENT_HINTS.md,然后运行一次完善流程以更新需求。
  4. 用真实的事件细节修订 QUALITY.md 场景。用真实世界的值更新集成测试阈值。修订后重新运行测试。

如果用户在步骤 0 中已经提供了聊天历史,那你已经挖掘过了——但他们可能想引导你查看特定对话、连接额外来源,或要求你深入探究某个特定主题。

迭代

用户可以根据需要多次循环执行这些路径。每一轮都会让质量手册更加有据可依。当他们满意时,自然会继续前进——没有明确的“完成”步骤。


夹具策略

quality/ 文件夹与项目的单元测试文件夹相互独立。根据项目所用语言创建相应的测试设置:

  • Python: 使用 quality/conftest.py 存放 pytest 夹具。如果夹具以内联方式定义(pytest 的 tmp_path 模式中很常见),优先采用内联方式而非共享夹具。
  • Java: 使用带有 @BeforeEach/@BeforeAll 设置方法的测试类,或共享的测试工具类。
  • Scala: 混入测试规格的 trait(例如 trait FunctionalTestFixtures),或内联的数据构建器。
  • TypeScript/JavaScript: 使用带有 beforeAll/beforeEach 钩子的 quality/setup.ts,或内联的测试工厂。
  • Go: 在同一 _test.go 文件中编写辅助函数,或使用共享的 testutil_test.go。对测试辅助函数使用 t.Helper()。Go 惯例更倾向于内联测试设置,而非共享夹具。
  • Rust: 使用 #[cfg(test)] mod tests 代码块,或共享的 test_utils.rs 模块。对测试数据使用构建器模式。

检查现有测试文件,了解它们如何设置测试数据。无论现有测试采用何种模式,都照此复制。研究现有夹具模式,以了解贴近真实的数据形态。


术语

  • 功能测试 — 代码是否产生规格所要求的输出?区别于单元测试(孤立地测试单个函数)。
  • 集成测试 — 组件能否端到端协同工作,包括真实的外部服务?
  • 规格审计 — AI 模型阅读代码并与规格进行比对。不执行任何代码。可发现代码与文档不一致之处。
  • 覆盖率作秀 — 产生高覆盖率数字但无法发现真实缺陷的测试。例如:断言某函数未抛出异常,却不检查其输出。
  • 契合用途 — 代码在真实场景下是否做了它应该做的事?一个系统可以拥有 95% 的覆盖率,却仍然静默丢失记录。

原则

  1. 契合用途优先于覆盖率百分比
  2. 场景来自代码探索与领域知识
  3. 具体的失效模式让标准不容商量 — 抽象的需求会招致合理化解释
  4. 护栏能提升 AI 审查质量(行号、阅读函数体、下结论前先 grep)
  5. 先分诊再修复 — 许多“缺陷”其实是规格缺陷或设计决策
  6. 结构化审查存在上限(约 65%)。其余约 35% 是意图违背 — 缺失类缺陷、跨文件矛盾、设计缺口 — 对任何只阅读代码的工具都不可见。需求让不可见之物变得可见。
  7. 规格才是独特的贡献,而非审查结构。重点领域和审查协议,相对于从意图来源中推导出正确的可测试需求而言,都是次要的。
  8. 跨需求一致性检查至关重要。缺陷往往存在于两个各自正确的代码片段之间的缝隙中。仅按需求逐项验证无法发现这些缺陷。
  9. 保留所有推导出的需求 — 不要进行筛选。检查一条额外需求的成本很低;而因为剪掉了本可发现缺陷的那条需求,导致漏掉缺陷的成本很高。
  10. 失败的测试是缺陷存在的最有力证据。对每个已确认的缺陷及其修复补丁,运行红-绿 TDD 循环(测试在有缺陷的代码上失败,在修复后的代码上通过)。展示 FAIL→PASS 输出 — 审查者可以不同意你的修复方式,但无法反驳一个能复现问题的测试。

参考文件

在每个阶段推进过程中阅读这些文件:

文件阅读时机内容
references/exploration_patterns.md阶段 1(探索)模式适用性矩阵、深入分析模板、领域知识问题
references/defensive_patterns.md步骤 5(发现骨架)Grep 模式、如何将发现转化为场景
references/schema_mapping.md步骤 5b(schema 类型)字段映射格式、变更有效性规则
references/requirements_pipeline.md阶段 2(需求)五阶段流水线、版本管理协议、结转规则
references/constitution.md文件 1(QUALITY.md)包含逐节指导的完整模板
references/functional_tests.md文件 2(功能测试)测试结构、反模式、跨变体策略
references/review_protocols.md文件 3–4(代码审查、集成)两种协议的模板、补丁验证、跳过防护
references/spec_audit.md文件 5(三人委员会)完整审计协议、分诊流程、修复执行
references/iteration.md迭代(阶段 6 之后)四种迭代策略:差距、未过滤、对等、对抗
references/verification.md阶段 6(验证)完整的自检清单(45 项基准),包括结构化输出、补丁门禁、跳过防护验证、预检发现、版本标记、缺陷记录、枚举完整性、分诊可执行证据、代码提取的枚举列表、机械验证产物、源码检查测试执行、矛盾门禁、种子检查执行、收敛跟踪、sidecar JSON schema 验证、脚本验证的关闭门禁、规范用例标识符,以及记录内联修复差异

评论

支持 Markdown