0023 需求类型、质量门、按切片实现
背景
到 1.7 为止,所有需求走同一条路:方案设计 → 审核 → 一个 agent 实现全部任务 → 评审 → 验证。三个问题反复出现:
- 不同类型的需求要不同的做法。 修缺陷要先复现、找到原因;重构要先锁住现有行为;"能不能做"的评估根本不该写代码。用新功能的做法处理它们,结果常常"做了,但不是要的":缺陷改的是现象,重构顺手改了行为,评估做成了半成品。
- "规范"只是提示词里的建议。 lint、测试、构建是否通过,靠实现 agent 自己说,评审 agent 再跑一遍;中间没有任何确定性的检查,改坏了也可能写成"通过"。
- 大需求一个 agent 做不完。 上下文被填满、时限 4 小时、中断后整步重做。
业界的做法(Matt Pocock 的 skills、pstack、Claude Code 和 Cursor 的最佳实践)在这几点上相同:按任务类型走不同的剧本;能用工具判定的交给确定性的检查,不靠模型自评;把工作切成可以单独验证的纵向切片。
决定
需求类型
- spec 头部的
- 类型:由引擎读取。缺陷、重构、评估三种有自己的剧本;新需求、小改动和其他写法走原来的流程。配置requirementTypes可以关掉某个剧本(该类型改走原来的流程)。 - 剧本不新增步骤,而是改变已有步骤做什么:每种类型一个提示词文件
engine/prompts/types/<类型>.md,按"## 步骤名(步骤 ID)"分节,引擎把"所有步骤"一节和当前步骤的一节接在本步骤任务之后,并在<pipeline-context>中写明类型。步骤 ID、结果文件和状态都不变,续跑、增量继续、分阶段执行照常适用;prompts.local/types/可以覆盖。剧本可以改步骤的显示名称(缺陷的方案设计叫"复现与定位")。 - 缺陷:方案设计改为复现与定位,先提交一个修复前失败的复现测试或脚本,写
diagnosis.md(根因、影响面)。复现不了时结果文件写reproduced: false和要问的问题,流水线像方案审核阻塞一样暂停,把问题发回对话。修复必须让复现转绿,评审要实际确认它修复前失败。 - 重构:先补特征测试锁住现有行为,单独提交;之后小步改动,每步全绿;评审的首要问题是"行为有没有变",特征测试的断言被改要说明理由。
- 评估:只读。调研评估写
assessment.md→ 评估审阅 ⇄ 修订 → 评估报告;没有实现、代码评审、提测和验证,执行方式一律按连续。功能目录之外有文件被改动时,引擎把它写进报告的上下文。报告最后给出需求草稿,对话可以接着提一个新需求。 - 类型由
/req在访谈时判断并请用户确认;访谈的重点随类型变化(复现步骤、必须不变的行为、要回答的问题)。
质量门
- 项目配置
checks列出流水线自己运行的检查(格式、lint、类型检查、单元测试、构建),由/req-setup从实际跑通的命令写入。端到端测试和需要启动服务的检查不放这里,它们属于功能验证。 - 每次尝试开始时(方案设计之前,任何提交之前)运行全部检查,记录基线。放在方案设计之前,是因为缺陷的复现测试在复现与定位时就提交了,基线晚了会把整个测试检查记成"原本就失败"。
- 代码实现(每一片)、评审问题修复、缺陷修复结束后运行与改动相关的检查。只有改动前通过、现在失败的检查拦下:把命令和输出的最后部分作为追问发回同一个 agent(它还记得自己改了什么),最多
qualityGate.fixAttempts次(默认 2)。仍然失败时照常继续,结果写进状态文件,交给代码评审(要求按阻塞或重要提出)和报告(结论最高为"有遗留问题")。不让一个 lint 问题卡住整个需求,也不会无声地放过。 - 比较以"一项检查"为单位,不细到测试用例:粗,但与项目的测试框架无关。原本就失败的检查不拦,但会在报告中列出。
- 检查通过系统 shell 运行(Windows 上是 cmd.exe),命令要写成各系统通用的形式,与
paseo.json的约定相同。没有配置检查时一切照旧,报告注明"未配置"。
多模块与关联仓库
- 检查可以带
cwd或paths:只有改动碰到这些路径时才运行,单仓库多模块的项目只检查改动的模块。 - 项目配置
relatedRepos登记其他仓库(例如前端项目的后端)。步骤在<pipeline-context>中看到它们的位置、分支和提交,按related-repos.md只读参考:不修改、不提交;验证需要对方服务时优先用已部署的测试环境。 - 两边都要改的"联合需求"(父子运行、接口约定、联合验证)不在这个版本,单独设计。
按切片实现
- 方案的实施计划分成纵向切片(每片能单独演示和验证),设计步骤在结果文件的可选字段
slices中列出;方案修订可以给出新列表。 - 档位在
slices.profiles中(默认只有标准档)、且有两片以上时,代码实现按片逐个启动新的 agent(步骤键implement-s<序号>),每片各自提交、各自过一次质量门;中断后只重做当前片。超过slices.max(默认 6)时最后几片合并。只有一片、快速档时与原来相同。 - 子需求(把大需求拆成几个各有 spec 的需求)不在这个版本:切片已经解决上下文和中断的问题。
范围检查
- 设计结果的可选字段
files列出预计改动的文件和目录。代码评审前,引擎比对这次尝试实际改动的文件(不含功能目录),把清单之外的交给评审逐一判断:必需的写理由,无关的要求撤回。评审同时增加"影响面"一节,并明确只把影响正确性、安全、数据和验收的问题提为阻塞或重要,避免评审意见把代码越改越复杂。
影响
- 状态文件只增加可选字段(
type、codeBase、gate),格式版本仍为 1;结果文件增加可选字段。回滚到 1.7 后,旧引擎忽略这些字段;按切片实现中断的需求,旧引擎会把整个实现重做一遍。 - 有检查的项目,每次尝试多一次基线运行,写代码的步骤之后各多一次检查运行。检查要能在几分钟内跑完。
- 不同的需求类型复用同一套步骤和状态:以后增加类型(界面改动、数据变更、性能优化)只需要一个剧本文件和少量引擎分支。
本页由仓库中的 docs/adr/0023-types-gate-slices.md 生成。在 GitHub 上编辑