Grill,然后规范驱动开发
两个工作流程,背靠背执行,中间有一次交接:
- Grill(Matt Pocock,
grill-me→to-spec):以设计树的形式对用户进行多轮面试,直到没有任何隐性假设。然后将已达成共识的理解综合成一份规范,不提出任何新问题。 - 构建(DeepLearning.AI + JetBrains,基于编码代理的规范驱动开发):规范以
requirements.md、plan.md和validation.md的形式存放在仓库中,位于带日期的目录下,按任务组在独立分支上实现,根据validation.md进行验证,记录在变更日志中,合并后,重新规划路线图。
Grill 阶段替代了 SDD 课程固定的三问题面试(范围 / 决策 / 上下文),采用完整的设计树面试。SDD 课程替代了 to-spec 的“发布到问题跟踪器”步骤,改用与代码共存并在代码变更时同步更新的规范文件。
概述
使用时机:当变更足够大,预先编写规范比返工更经济时——例如新功能、路线图阶段、MVP 冲刺,或向遗留代码库添加 SDD。单行修复和纯粹的错误排查(使用 pstack-engineering 进行根因分析)则跳过。
触发短语:“grill me then spec it”、“grill to spec”、“spec-driven”、“SDD”、“feature spec”、“work on the next phase”、“start the next feature”。
硬性关卡(绝不能跳过):
- 只有在用户确认 Grill 阶段达成共识后,才能写入规范文件(关卡 A)。
- 只有在用户批准规范文件后,才能编写代码(关卡 B)。
- 只有在
validation.md中的每一项都通过后,才能合并(关卡 C)。
执行说明
在开始时解析 SPECS=${SDD_SPECS_DIR:-specs} 和 BASE=${SDD_BASE_BRANCH:-<repo default branch>}。以下路径相对于项目根目录。
阶段 0 — 环境熟悉(事实是你的工作)
- 阅读项目的
AGENTS.md/CLAUDE.md、README.md以及任何术语表或 ADR。遵循仓库自身的 Git 规则(包装器、分支命名、禁止强制推送)。 - 检查是否存在章程:
$SPECS/mission.md、$SPECS/tech-stack.md、$SPECS/roadmap.md。- 全部存在 → 进入阶段 1,处理下一个功能。
- 缺失,新项目 → 第一次 Grill 针对章程本身(使命、目标受众、技术栈缺口)。其输出是这三个文件,其中
roadmap.md被拆分为非常小的、每个都可独立交付的阶段。 - 缺失,现有代码库(遗留系统) → 首先探索代码,根据实际存在的内容起草章程(技术栈、约定、已发布功能作为已完成阶段),然后仅对缺口和未来路线图进行 Grill。
- 如果用户未指定功能名称,则目标为下一阶段:路线图中第一个所有项均未选中(
[ ])的部分。 - 探索该功能将触及的代码。绝不要问用户那些仓库、工具或文档可以回答的问题。如果工具链支持,将广泛探索委托给一个全新的子代理,并且不要因此阻塞无关问题。
阶段 1 — Grill(设计树面试)
持续面试用户,直到达成共识。将计划视为一棵设计树:每个决策都会分支成依赖于它的决策。
- 按轮次进行。前沿是指所有先决条件已确定的未定决策。在一轮中提出整个前沿的问题,然后等待回答。
- 为每个问题编号,并给出你的推荐答案。措辞应使“是”表示接受推荐。
- 如果一个问题的答案依赖于本轮中其他仍开放的问题,则此问题属于后续轮次。
- 在各轮次中,至少覆盖 SDD 的维度:范围(它收集、暴露、做什么;数据形状)、决策(存储、可见性、验证、UI 模式、架构)、上下文(语气、约束、栈限制、开放问题)和测试切入点:功能将在何处被测试。优先使用现有切入点和尽可能高的切入点;理想情况是只有一个。
- 新的依赖、模式变更和公共 API 变更始终是显式问题,绝不能是假设(
tech-stack.md是权威)。
回合格式:
❓ **Q1** - **<标题>**: <问题,如果有选项>
➡️ <推荐答案>
---
❓ **Q2** - ...
如果工具链有结构化问题工具(Claude Code AskUserQuestion),你可以用它提出最多包含四个选择题的回合;否则使用上述文本格式。
当前沿为空时,Grill 阶段结束。用简短列表总结已确定的决策,并要求用户确认。
关卡 A: 在用户确认总结之前,不得继续。
阶段 2 — 转为规范(综合,不提出新问题)
将对话内容转化为规范。不要再次进行面试;如果出现真正的缺口,说明 Grill 阶段遗漏了一个分支:仅询问那一个缺失的问题,然后继续。
- 从
$BASE创建分支:如果是路线图阶段,使用phase-<N>-<kebab-name>;否则使用feature/<kebab-name>(或仓库自身的约定)。 - 重新阅读
$SPECS/mission.md和$SPECS/tech-stack.md,以及现有功能规范以了解风格。 - 创建
$SPECS/YYYY-MM-DD-<feature-name>/(使用今天的日期),并根据references/spec-templates.md编写三个文件:requirements.md—to-spec内容(问题、解决方案、详尽的编号用户故事列表、实施决策、测试决策、超出范围)加上 SDD 的 范围/决策/上下文 章节。不包含文件路径或代码片段,除非是一个经过精简的原型片段,它能比文字更精确地固定一个决策。plan.md— 编号的任务组,每个任务组均可独立实现和测试,包含编号的子任务。validation.md— 自动化检查(精确命令)、手动演练、边界情况、面向用户文本的语气检查,以及完成定义。
- 可选,如果用户要求或仓库通过问题追踪工作:也可将需求发布为一个 Issue(
gh issue create)并从requirements.md链接它。 - 向用户展示这三个文件(路径加简短摘要)。
关卡 B: 等待批准。反馈(例如“为 X 添加一个任务组”、“组件应放在自己的文件中”)首先应用于规范,并保持每个文件同步。
阶段 3 — 实现
- 按顺序实现任务组。每个组之后:运行项目的测试和类型检查,使用反映该组名称的消息提交,在
plan.md中勾选对应的框。 - 如果实现表明规范有误或不完整,则在与代码的同一提交中更新规范。规范和代码永不偏离。
- 彼此之间没有依赖关系的组可以分配给并行子代理(每个在自己的工作树中;遵循宿主的工作树规则),由你合并回来。
- 未经用户批准不得添加新依赖,即使某个组“需要”它。
阶段 4 — 验证
- 运行
validation.md中的每一个自动化检查,并粘贴实际输出。 - 执行手动检查(对于 UI,实际驱动它:浏览器自动化或截图,而不是“应该能工作”)。
- 可选深度审查:让审查者从三个角度(正确性、规范符合性、可维护性)在分支差异上提出问题,然后修复阻碍项。
- 询问用户是否需要根据已构建的内容澄清规范。
关卡 C: 每个完成定义项均通过,或用户明确豁免一项(在 validation.md 中记录豁免)。
阶段 5 — 闭环
- 在
$SPECS/roadmap.md中将该阶段标记为完成([x])。 - 更新
CHANGELOG.md(# Changelog,## YYYY-MM-DD标题最新在前,自上次记录日期以来每个有意义的变更一个要点)。如果存在项目changelog技能则使用它。 - 提交,切换到
$BASE,合并分支,删除它,根据仓库规则推送。 - 重新规划: 询问是否有任何学到的经验需要修改
mission.md、tech-stack.md或路线图(合并、拆分或重新排序阶段)。跨领域的决策(例如“使用 Vitest”、“响应式 UI”)进入tech-stack.md/mission.md,并回溯应用到现有规范。 - 提供下一阶段:它再次从阶段 1 开始。
环境变量
| 变量 | 默认值 | 描述 |
|---|---|---|
SDD_SPECS_DIR | specs | 章程和功能规范目录,相对于项目根目录 |
SDD_BASE_BRANCH | 仓库默认分支 | 功能分支从中创建并合并回的目标分支 |
验证检查清单
- 在任何功能规范之前检查章程是否存在(
mission.md、tech-stack.md、roadmap.md) - 每个 Grill 问题都附有推荐答案提出;没有询问仓库可以回答的事实
- 在写入任何规范文件之前,用户确认了决策总结(关卡 A)
-
requirements.md、plan.md、validation.md存在于功能分支上的$SPECS/YYYY-MM-DD-<name>/目录下 - 在编写代码之前,用户批准了规范(关卡 B)
- 每个任务组提交时测试通过;计划框已勾选
- 只要实现偏离了规范,规范即已更新
- 所有
validation.md检查均已运行并附有实际输出(关卡 C) - 路线图阶段已勾选,变更日志已更新,分支已合并并删除
- 已询问重新规划问题
已知陷阱
- 无休止的 Grill。 Grill 在前沿为空时结束,而不是在你好奇心耗尽时。不要重新询问已确定的决策;不要询问属于代码审查的细节。
- 在 to-spec 阶段进行面试。 阶段 2 是综合阶段;新问题意味着 Grill 阶段不完整。只问那一个缺失的问题,而不是进行第二次面试。
- 在关卡 A/B 之前编写。 SDD 课程明确说明:在面试回答之前,不要将任何内容写入磁盘。代码在规范批准之前编写会破坏该方法。
- 阶段太大。 一个无法在一次审查中看完的阶段应在制定规范前在路线图中拆分。
- 规范偏离。 在实现过程中提出的变更首先应用于规范,然后再应用于代码。不再匹配代码的规范比没有规范更糟糕。
- 需求中的文件路径。 它们会很快失效;请描述模块和接口(路径最多属于
plan.md的子任务)。 - 仓库规则优先。 来自仓库
AGENTS.md的分支名称、推送包装器、工作树位置和归属规则会覆盖此处的默认设置。
请参阅 references/spec-templates.md 了解文件模板,以及 references/sources.md 了解每个部分的来源。