写好规格
你很少从白纸开始写规格。你用纯语言描述一次变更,/rasen:propose 起草需求和场景,然后你把它们打磨好。本页讲的就是最后这一部分——"好"长什么样,以及如何引导 AI 朝这个方向靠。
这是评审一次变更的伴侣:评审是找出草稿中的弱点,写作是知道强稿由什么构成。
规格是行为,不是代码
规格说的是你的系统做什么,用任何人都能检验的术语——而不是它是怎么构建的。它由需求(行为陈述)和场景(证明它们的具体例子)构成。
### Requirement: Session Timeout
The system SHALL expire a session after 30 minutes of inactivity.
#### Scenario: Idle timeout
- GIVEN an authenticated session
- WHEN 30 minutes pass with no activity
- THEN the session is invalidated and the user must re-authenticate
把如何做——队列、库、表模式——留在 design.md 或代码中。当行为和实现混进一个需求里时,这条需求就不再可测试了,一旦代码改变就会开始过时。
什么是好需求
好需求是一条行为,陈述得清楚到你可以把它交给别人来测试。
一条语句,一个
SHALL/MUST。 如果一条需求有三个"并且还"子句,那真的是三条需求。拆开它们。可观测。 代码外的人应该能分辨它是否成立。"系统 SHALL 在上传超过 10 MB 时显示错误横幅"是可观测的。"系统 SHALL 优雅地处理大型上传"则不然。
强度合适。 Rasen 使用 RFC 2119 关键字,它们意思不同:
关键字 含义 MUST/SHALL硬性需求。不可商量。 SHOULD强烈建议,有理由的例外可以接受。 MAY真正可选。 默认选
MUST/SHALL。仅当你真正的意思是"除非有充分理由不这样做"时才用SHOULD。
需求的测试:一个从未见过代码的测试人员能分辨它是否通过吗? 如果不能,它需要磨得更锐利。
什么是好场景
场景是需求证明其价值之所在。每一条都是具体的 GIVEN / WHEN / THEN,可以成为自动化测试。
- 它检验自己的需求。 一个只是用别的词重述需求的场景什么都测不了。让它成为一个有特定情形、有特定结果的场景。
- 覆盖重要的情形,而不仅是成功路径。 成功登录很容易。空输入、过期令牌、二次点击、那些会出错的东西——那是 bug 住的地方,也是场景最有价值的地方。
- 给场景在标题里起名。 "Scenario: Rejects an expired token"让评审者一眼看出覆盖了什么;"Scenario: Test 2"则没有。
一个有用的习惯:批准之前,问我最希望看到什么东西不被破坏?——并确保某条场景点名了它。
选择合适的增量种类
一次变更用三种章节类型描述对规格的编辑。用对了就能保持你的已归档规格诚实:
## ADDED Requirements—— 之前不存在的全新行为。## MODIFIED Requirements—— 已存在的行为现在在改变。包括完整的新版本;一行关于什么改了的说明对评审者有帮助。## REMOVED Requirements—— 行为在消失,附上一行为什么。
归档时,ADDED 被附加到主规格,MODIFIED 替换旧版本,REMOVED 被删除。如果你把真正的改动标为 ADDED,最终会有两条竞争的需求;如果你把新行为描述为 MODIFIED,就没有东西能替换。拿不准时,打开当前规格看看需求是否已经在那里。
给变更定好大小
最常见的创作错误不是一条措辞不好的需求——而是一次变更想做三次变更的工作。
好的变更有一个你能用一句话说清的意图。 "添加深色模式开关。" "限制登录端点的速率。" "从 cookies 迁移会话。" 如果描述变更需要很多"并且还",那就是该拆分它的信号。
变更太大的迹象:
- 提案的范围读起来像一份不相关功能的清单。
- 审查它需要整个下午,所以没人会审。
- 两个人无法在它上面工作而不碰撞。
- 一半的任务可以各自交付。
小一点的变更更容易审查、更容易在一个专注的会话里构建、六个月后当归档是仅存物时更容易思考。你总是可以并行运行好几次变更——参见编辑与迭代和工作流。
反面也会发生:一行拼写修复不需要三条需求和一份设计文档。把仪式规模与利害关系匹配。
如何引导 AI 朝好草稿靠
因为 /rasen:propose 做第一稿,你得到的质量跟踪你给的质量。你不必手工写需求——你要把 AI 指挥好:
- 陈述意图和边界。 "添加一个尊重 OS 设置、在首次加载时跟随 OS 设置的深色模式开关——别动现有的主题 API。" 超出范围的那一半和范围内的一半一样重要。
- 点名你在意的情形。 "确保有一个场景涵盖已经手工选过主题的用户。" AI 会覆盖你指向的东西。
- 然后编辑。 它是纯 Markdown。收紧含糊的
SHALL、删掉测不了什么的场景、加上它漏掉的那个情形——或让 AI 来:"那个超时需求很含糊,把它钉到 30 分钟。"
起稿、磨锐、重复。几轮那样会产生一份你信得过的规格,这就是全部要点。
一份快速清单
- 每条需求都是一条可观测的行为,带
SHALL/MUST。 - 没有实现细节被烤进需求中。
- 每条需求都至少有一条真正检验它的场景。
- 重要的边界和错误情形有场景,不只是成功路径。
- Deltas 对照当前规格正确使用了 ADDED / MODIFIED / REMOVED。
- 整个变更有一个你能用一句话陈述的意图。