- Record rejected answers in decision.md at the moment they are rejected - Allow explicit pre-authorized Build via a pre-authorized marker line - Land scripts/check-dev-flow.sh and derive devflow/index.md from archives - Add dev-flow process artifacts (decisions, prd) for open changes
6.3 KiB
三阶段契约
本文件是三阶段的判断细则。它只规定"怎么判断",不新增检查点——检查只有收尾那一次。
Think — 想清楚
澄清:借用 grill-with-docs,但收窄范围
方法来自 grill-with-docs —— 一次只问一个问题并等待回答、能通过探索代码回答的自己去探索、术语确认后立即写入 CONTEXT.md。这些不在这里重复。
范围由本流程收窄:
grill-with-docs自身的取向是 "interview me relentlessly … until we reach a shared understanding"。 relentless 是对问题质量的,不是对数量的。 只问答案会改变proposal.md/specs//tasks.md的问题;不会改变产物的疑问,自己判断即可。
先自己查证,再问用户。 查证时格外看四处——前两处专门用来避免重复劳动:
- 搜
devflow/rejected/—— 这个方案是不是已经被否决过? - 搜已归档的
decision.md—— 相关决策的历史理由是什么? - 读相关代码 / 配置 / 测试;看
openspec/specs/有没有既有规格 - 能复现的问题先复现——一次成功的复现比一轮追问更有信息量
什么时候算够:你能写出一份 proposal,别人读了知道要做什么、不做什么。没有"至少 N 个问题"的要求——问题数不是质量指标。
上下文读取顺序
devflow/glossary/CONTEXT.md ← 术语,先对齐语言
devflow/rejected/ ← 有没有被否决过的相似方案
已归档的 decision.md ← 有没有相关的历史决策
openspec/specs/ ← 相关的既有能力规格
第二步和第三步最重要。 一个已经被否决过的方案,如果你不知道,就会重新提出一遍、重新争论一遍——这正是决策档案存在的理由。
确认点 1 的汇报格式
向用户汇报时不超过 10 行:
- 方案方向(1–2 句)
- 关键假设(没有验证、但方案依赖它的部分)
- 主要风险
- 放弃的备选(1–2 条,连同为什么)
- 请求实现授权(或记录
<!-- pre-authorized: 日期 + 范围/原因 -->)
不要复述 proposal、不要列产物清单、不要贴对齐表格。用户要的是判断依据,不是工作汇报。
pre-authorized 是显式旁路,不是默认。 它适合用户已在对话中明确说"直接做"的快节奏场景。写它 = 承认确认点被有意识地跳过;不写而直接进 Build = 违规。授权状态的唯一载体是这行标记——恢复会话时以它为准。
Build — 做出来
分步实现与验证
按 tasks.md 的纵向切片推进。每完成一层先验证,再进下一层——一次写完再验,出了问题无法定位是哪一层。
第一个切片完成后,对照 specs/ 检查一次:验收场景是否真的成立。规格写得含糊会在这里第一次暴露。
参考实现先读,再动手
tasks.md / design.md 点名"参考 XXX 实现"的,实现前完整读它。路径不明确时按类名/模式 Grep 定位。
设计文档点名参考而实现时没看,是返工最常见的来源(SuperBizAgent 复盘:山东商客接口因此返工 4-5 次)。
第一次在某区域写代码、或要用项目现有基础设施(MQ/统一请求结构/工具类)时,同此处理。
冲突三分法的判断细则
先分类,再动手。分类的错误比不分类更糟。
怎么区分"规格不准"和"代码偏离":问一句——"如果完全按规格做出来,行为对不对?"
| 回答 | 分类 | 处理 |
|---|---|---|
| 对,但我没按规格做 | 代码偏离 | 改代码,不动 OpenSpec |
| 不对,规格本身就写错了 | 规格不准 | 暂停,改 OpenSpec,再继续 |
| 说不清 / 涉及设计方向 | 不确定 | 暂停,问用户 |
"不确定"这一类必须真的停下来问。 判断设计方向是用户的权力,不是 agent 可以代劳的—— 把设计问题当成实现问题自行消化,是返工最常见的来源。
冲突的分类、证据和处置结果写进 decision.md 的正文。
Close — 收好尾
补齐 decision.md
Think 阶段已经写下了 ## Problem 和 ## Alternatives considered。Close 要补的是后三节:
## Decision —— 校准为实际发布的做法(现在时)。
Think 时写的是"打算怎么做",Close 要把它改成"实际做了什么"。 如果两者不一致,不要偷偷改成后者——把差异写出来,它本身就是有价值的决策记录。
## Consequences —— 必须同时写收获和代价,包括已知限制。
只写收获的是营销文案,不是档案。未来维护者最需要判断的,恰恰是"这个代价现在还接受得了吗"。
## Verification —— 写成可重跑的命令或明确的人工步骤。
| 不写 | 写 |
|---|---|
| 已确认年份筛选控件存在 | grep -c 'year-filter' knowledge-index.html → ≥1 |
| 手动测试一下 | 选择 2026,只显示 date 以 2026 开头的条目 |
判据:换一个人拿着这一节,能不能在 5 分钟内重跑一遍?
格式细则与校准案例见 decision-note.md。
收尾检查
三步,一次做完:
decision.md存在- 含
## Alternatives considered,或显式的<!-- alternatives-not-recorded --> ## Verification里没有不可重跑的结论
豁免:纯机械或局部编辑(不改变行为、契约、结构、流程或理由)。豁免要显式——在 decision.md 或提交信息里写出来,让"跳过"是有意识的选择。
中断与恢复
流程状态全部在文件里,不依赖对话记忆。 换会话、隔天继续时,按下面的顺序读一下就知道停在哪:
| 观察到 | 当前在 |
|---|---|
没有 openspec/changes/<slug>/ |
Think 之前 |
有 proposal.md,但 decision.md 缺 ## Problem |
Think 进行中 |
有 proposal.md 和 decision.md,但没有 <!-- pre-authorized 也没有对话中的明确授权 |
确认点 1 |
有 <!-- pre-authorized: ... --> 或已获授权,实现未完成 |
Build 进行中 |
实现完成,decision.md 缺 ## Decision / ## Consequences / ## Verification |
Close 进行中 |
decision.md 五节齐全 |
收尾检查 + 确认点 2 |
恢复时不重新提问已经解决的问题。 先读 decision.md 和 proposal.md——已经确认过的内容就在里面。