# 三阶段契约 本文件是三阶段的判断细则。**它只规定"怎么判断",不新增检查点**——检查只有收尾那一次。 --- ## 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` 的问题;不会改变产物的疑问,自己判断即可。 **先自己查证,再问用户。** 查证时格外看两处——它们专门用来避免重复劳动: 1. 搜 `devflow/rejected/` —— 这个方案是不是已经被否决过? 2. 搜已归档的 `decision.md` —— 相关决策的历史理由是什么? 3. 读相关代码 / 配置 / 测试;看 `openspec/specs/` 有没有既有规格 4. **能复现的问题先复现**——一次成功的复现比一轮追问更有信息量 **什么时候算够**:你能写出一份 proposal,别人读了知道要做什么、不做什么。**没有"至少 N 个问题"的要求**——问题数不是质量指标。 ### 上下文读取顺序 ```text devflow/glossary/CONTEXT.md ← 术语,先对齐语言 devflow/rejected/ ← 有没有被否决过的相似方案 已归档的 decision.md ← 有没有相关的历史决策 openspec/specs/ ← 相关的既有能力规格 ``` **第二步和第三步最重要。** 一个已经被否决过的方案,如果你不知道,就会重新提出一遍、重新争论一遍——这正是决策档案存在的理由。 ### 确认点 1 的汇报格式 **向用户汇报时不超过 10 行:** - 方案方向(1–2 句) - 关键假设(没有验证、但方案依赖它的部分) - 主要风险 - **放弃的备选**(1–2 条,连同为什么) - 请求实现授权 **不要**复述 proposal、不要列产物清单、不要贴对齐表格。用户要的是判断依据,不是工作汇报。 --- ## Build — 做出来 ### 分步实现与验证 按 `tasks.md` 的纵向切片推进。**每完成一层先验证,再进下一层**——一次写完再验,出了问题无法定位是哪一层。 第一个切片完成后,对照 `specs/` 检查一次:验收场景是否真的成立。**规格写得含糊会在这里第一次暴露。** ### 冲突三分法的判断细则 先分类,再动手。分类的错误比不分类更糟。 **怎么区分"规格不准"和"代码偏离"**:问一句——**"如果完全按规格做出来,行为对不对?"** | 回答 | 分类 | 处理 | |---|---|---| | 对,但我没按规格做 | **代码偏离** | 改代码,不动 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`。 ### 收尾检查 三步,一次做完: 1. `decision.md` 存在 2. 含 `## Alternatives considered`,或显式的 `` 3. `## Verification` 里没有不可重跑的结论 **豁免**:纯机械或局部编辑(不改变行为、契约、结构、流程或理由)。豁免要**显式**——在 `decision.md` 或提交信息里写出来,让"跳过"是有意识的选择。 --- ## 中断与恢复 **流程状态全部在文件里,不依赖对话记忆。** 换会话、隔天继续时,按下面的顺序读一下就知道停在哪: | 观察到 | 当前在 | |---|---| | 没有 `openspec/changes//` | Think 之前 | | 有 `proposal.md`,但 `decision.md` 缺 `## Problem` | Think 进行中 | | 有 `proposal.md` 和 `decision.md`,但没有实现授权 | **确认点 1** | | 有实现,但 `decision.md` 缺 `## Decision` / `## Consequences` / `## Verification` | Close 进行中 | | `decision.md` 五节齐全 | 收尾检查 + 确认点 2 | **恢复时不重新提问已经解决的问题。** 先读 `decision.md` 和 `proposal.md`——已经确认过的内容就在里面。