# Write Spec

> 在要求写结构化的 spec、规格文档、行为规格或验收标准时使用。

- Skill: `rollrollroll/write-spec` (Agent Skill, multi-file: 6 files)
- Install (CLI): `npx skillmds@latest add rollrollroll/write-spec`
- Raw SKILL.md: https://api.skillmd.com/api/skills/rollrollroll/write-spec/raw
- Safety review: PASS (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: RollRollRoll (https://skillmd.com/u/rollrollroll)
- Updated: 2026-08-19
- Page: https://skillmd.com/skills/rollrollroll/write-spec

---


# Write Spec — 行为规格 Skill

## 你的任务

把一个**边界已经清晰的想法 / 需求**，转化为一份**可被验证的行为规格**：

1. **系统该有什么可观察行为** —— 用 Requirement + MUST 表达，每条都配 Scenario（WHEN→THEN）。
2. **明确必须不发生什么** —— 把"不做什么"转成 MUST NOT 负向需求 + 可验证检查。
3. **边界场景下如何表现** —— 边界值 / 空值 / 并发 / 幂等…… 逐项比对，适用的写成 Scenario。
4. **怎么算做完了** —— 可执行的成功标准，不是"能用就行"。

**刻意止步于此**：不做技术选型、不画架构、不拆任务、不排期。
你的产出是一份"行为说清楚了、验收定死了、可以放心进入实现"的规格，而不是实现方案。

> 一句话：把"我们要解决 Y、做 A/B、不做 C/D、成功标志 Z"的概念，钉成"系统 **MUST** 这样、
> **MUST NOT** 那样、在这些边界下表现如此、用这些可执行检查验收"的规格。

## 核心理念

spec 是**编码前的最后一道闸门**。需求里每一处没说清的行为、每一个没被表态的边界、
每一条沉默的"不做什么"，都会在实现期变成返工、扯皮或上线事故。把它写成可被验证的契约，让"做完没做完"不再靠口头判断。

write-spec 不挖意图，也不给方案。
它只做一件事：**把已清晰的概念，翻译成不会产生第二种理解的行为契约。**

## 何时用 / 何时不用

**适用**：

- 概念已清楚，准备进入实现前，需要一份可验证规格。
- 要新增一个功能 / 能力，或要改既有功能，需要先写清"改成什么样、怎么验收"。
- 协作中需要一份"实现期可对照、验收时可逐条核对"的依据。

**不适用**（别硬套）：

- 概念还模糊、意图不明确。
- 要的是技术选型 / 架构。
- 单行修复、错别字修正，或者需求已经非常明确、范围完全自包含的小修改。
- 已在写代码、定位 bug、做评审。

**⚠️ 加载约束（硬性）**：本 skill 的产出必须经一个**能实时 review 的活人**确认才放行。
禁止在 CI / 定时任务 / 自治循环等非交互场景里把它当作"自动产 spec"的工具——那种场景遇到
"没有 spec"，正确做法是**把它标记为 blocker 并停下**，而不是自动生成一份没人 review 的规格往下跑。

## 招牌机制：行为契约 + 双探针 ⭐

这是 write-spec 区别于"随手写个需求文档"的核心。一份 spec 不是把需求换种说法抄一遍，
而是让每条需求都过两关：

### 关一：可验证性

每条 Requirement 必须能写出至少一个 **Scenario**：`WHEN <触发条件> → THEN <可观察的结果>`。

- 写得出可观察结果 → 它是需求。
- 写不出（只能说"系统应该很好用 / 性能要好"）→ 它是愿望，不是需求。**打回重写成可观察的，或删掉。**

> 检验：把 Scenario 交给一个不懂业务的人，他能照着判断"通过 / 不通过"吗？不能，就还没写清。

### 关二：双探针强制覆盖

光写"要做什么"会漏掉一半的真实需求——漏在边界上，漏在"不该发生什么"上。
两个探针逐项扫，把漏的逼出来：

**边界探针（Edge Coverage）** —— 逐项自问"这条适用吗？"，适用的必须配 Scenario：

- 边界值（最大 / 最小 / 刚好越界）、空值（空输入 / 空集合 / null）、排序（顺序是否影响结果）、
  并发（同时操作同一对象）、幂等（重复执行结果是否一致）、精度（浮点 / 金额 / 时间）、
  编码（字符集 / 转义 / 二进制）、超时与失败（依赖不可用时）。

**禁止探针（Prohibition Coverage）** —— 把概念里每条"不做什么"转成可验证的负向需求：

- `不做自动同步` → `系统 MUST NOT 从 CI / 外部平台拉取或修改状态` →
  验证：`代码中不新增外部同步入口；UI 无同步配置项`。
- 关键：负向需求也要可验证。写不出"怎么检查它没发生"的，就还没转化完。

（两个探针的完整清单与"怎么把每一项转成 Scenario / MUST NOT"，见 [references/coverage-probes.md](references/coverage-probes.md)。）

## greenfield 多一层：能力覆盖图（Coverage Map）⭐

双探针抠的是"**选定要做的**需求，其边界与不做什么"（微观完整性）。但 greenfield 还有
一个更靠前的漏洞：**整类能力维度根本没被想到**。Coverage Map 补这一层（宏观全面性）——
系统列出"这个功能 / 领域有哪些能力维度"，给每个维度落一个**档位**
（`纳入 / 默认不做 / 后续版本 / 必须确认`），让全面性可被 review、漏项可被 catch；
再用"每行必落一档、不默认全纳入"防止全面滑向膨胀。

顺序是一个漏斗：**先用 Coverage Map 圈定做哪些维度，再对纳入的维度用双探针抠边界。**
（怎么列维度 / 判档 / 调研功能空间，见 [references/coverage-map.md](references/coverage-map.md)；
brownfield 不建此图，走 delta。）

## 工作流程（阶段 0 + 四个工作阶段）

### 阶段 0 · 定位与上下文

1. **扫项目**： 如果你还没有了解代码库，那么先探索代码仓库，以理解代码库当前的状态。**测试怎么跑**（决定"成功标准"能落成什么形式的检查）、已有 spec / 文档、相关代码。
2. **接上游**：若存在需求概念文件（`docs/proposal/*` 或用户指明的位置），读入作为输入；
   没有，就做一次**轻量**意图确认（确认"要解决什么、不做什么"）。
3. **判 greenfield / brownfield**：
   - 新增能力 → 写全量 spec。
   - 改既有功能 → 用 **delta**：只写 `ADDED Requirements` / `MODIFIED Requirements` / `REMOVED Requirements`，不重写整个系统。
4. **判规模**：若这其实是多个独立能力，**先提示拆分**，逐个写 spec，别把一份 spec 撑成全系统说明书。

### 阶段 1 · 圈定能力维度并分级确认（greenfield 先建 Coverage Map）

> **brownfield**：跳过调研与 Coverage Map——改动范围已被既有系统框定。只就**答案能改变
> spec 形状**的少数关键点（关键验收口径、需用户拍板的边界取舍、范围硬边界）确认式提问，
> 进 delta 起草。

**greenfield 分三步收敛，再起草：**

**1) 功能空间调研——调研与否由用户拍板（不是你）** —— greenfield 起草前，"要不要先做一轮
功能空间调研"是一个 **MUST 交给用户的决策**。你**主动、明确地问**，给出你的建议（调研 / 跳过+ 一句理由），然后**停下等用户回答**，不得在用户表态前继续：

- 用户选**调研** → 用 **deep-research**：聚焦①领域常见能力维度②按丰富度分档③哪些易漏却会改变
  spec 形状。**铁律**：产出是**功能空间参考，不是需求**，一项都不默认纳入。
- 用户选**跳过**（或一开始就说了不调研）→ 凭需求 + 自身知识自列维度，spec 里注明"未调研"。
- **调研选了却跑不起来**（deep-research 工具缺失 / workflow 失败 / 无网络）→ **不卡在反复重试**：
  如实告知用户"调研因 X 失败"，降级为凭领域知识自列维度（spec 注明"未调研：原因"），继续建
  Coverage Map；是否另寻调研方式由用户定。
- 本次属于**有成熟功能空间、易漏整类能力**的领域（权限 / 通知 / SSH 运维 / 支付 / 导入导出…）时，
  调研价值高，**更要问**——别因"需求看起来够详尽"替用户跳过。

**2) 建 Coverage Map** —— 把"需求已含 + 调研补充"的能力维度
汇成一张表，每行**必落一个档位**：

- **纳入** → 阶段 2 写成 Requirement + Scenario。
- **默认不做** → 写成 MUST NOT 或在覆盖表标注（可被 review 反对）。
- **后续版本** → 进覆盖表 + 待解问题。
- **必须确认** → 按第 3 步分级。

不默认全纳入——每行都有收敛决策。

**3) 分级确认（别一次抛几十个问题）** —— 对需澄清的点分三级：

- **现在问**：答案会改变 spec 结构（核心数据模型 / 主流程 / 范围硬边界）→ 现在聚焦提问，一次一问或小批量。
- **采用默认**：不影响主方向 → 记"采用保守默认：X"，不打断。
- **放 Open Questions**：重要但不阻塞本版 → 进 spec「待解问题」。

> 检验：「这个问题不问，spec 能不能起草？」能 → 它**不是**"现在问"。

列维度 / 判档 / 调研的完整清单见 [references/coverage-map.md](references/coverage-map.md)。

### 阶段 2 · 起草 spec（行为契约）

按 [references/spec-template.md](references/spec-template.md) 写：

- **背景 / 范围**（简短）：为什么做、覆盖什么、显式不覆盖什么。
- **能力覆盖与档位**（greenfield）：把 Coverage Map 以精简表落盘，让 review 一眼看到哪些做 / 不做 / 为什么；纳入项对应到下面的 Requirement。
- **行为需求**：Requirement + MUST/SHALL + 每条配 Scenario（WHEN→THEN）。brownfield 用 delta 标注。
- **不做什么（MUST NOT）**：禁止探针的产物，每条配可验证检查——**优先写用户可观察的行为**（如"UI 无编辑入口""不返回被禁数据"）；代码 / 依赖检查（"无写库路由""无引入某库"）只作**验收辅助**，除非"不得引入某类外部调用 / 持久化 / 网络行为"本身就是产品 / 安全约束。
- **边界场景覆盖**（索引）：把边界探针逐项映射到对应 Requirement / Scenario；行为只写在 Scenario 里，本节不重复写行为，只做覆盖核对。
- **成功标准**：可执行的检查（最好能对应到"怎么跑测试"）。
- **待解问题**：还没定、但需要记录的点。

**纯行为**：不写技术选型 / 架构 / 数据模型 / 任务（**行为级约束例外**——如
"MUST NOT 引入外部网络调用"这种可验证的行为约束，属于 spec；"用 Redis 做缓存"这种技术选型，不属于）。

### 阶段 3 · 自检（双重，落盘前过一遍）

**① spec 卫生**：

- 占位符 / TODO / 没写完的节？补全。
- 自相矛盾？（两条需求打架、Scenario 与 Requirement 不一致）
- 范围过大？需要拆成多份？
- 歧义？（任何一条能有两种解读 → 选一种写死）

**② 覆盖自检**（双探针回扫）：

- 每条 Requirement 都有 Scenario 吗？
- 边界探针逐项过了吗？适用的都写了吗？
- 概念里每条"不做什么"都转成 MUST NOT 了吗？
- 成功标准是可执行的吗？
- （greenfield）Coverage Map 每行都有唯一档位、无"待定"残留；"纳入"都成了 Requirement、关键"默认不做"都成了 MUST NOT 吗？
- （greenfield）有没有把调研维度无脑全纳入（膨胀）？

就地修复，不必重复 review。

### 阶段 4 · 用户 review 门禁

1. **落盘**：把 spec 写入仓库（默认就写文件——spec 是要进仓库、实现期持续更新的工件）。
   位置见下文「产物与落盘」。
2. **请用户 review**，并明确这条规矩：
   > **未通过 review 的 spec，不得采用。**
3. 用户要改 → 回阶段 2 / 3 修订并重过自检；用户**显式确认** → 过门。
4. **过门后**：**不自动调用其他skill、不开始写代码**。本 skill 到"规格确认"为止。

**哪些回答不算 "yes"**：

- "你看着办 / 都行" = 委托，不是决策。
- "听起来不错" = 模糊回应。
- 沉默后一句"那就开始吧" = 放弃，不是确认。

## 产物与落盘

- **默认单份文档**，内容是行为契约（Requirement / MUST / Scenario / MUST NOT / 边界 / 成功标准）。
- **位置**：跟随仓库既有 spec 约定——若已有 `docs/specs/` ，就跟随；
  否则默认 `docs/specs/<YYYY-MM-DD>-<主题>-spec.md`（目录不存在先跟用户确认）。
- **brownfield** 用 delta，只写这次改了什么。
- 规模极大 / 多能力时，**可提议**拆成 per-capability 多文件，但这是 scale-up，不是默认。

## 核心原则（不要违反）

1. **行为契约，不是需求复述** —— 每条需求都要能写出可观察的 Scenario。
2. **先扫上下文，再写 spec** —— 脱离代码库（尤其"测试怎么跑"）的 spec 是愿望清单。
3. **双探针是强制项** —— 边界与"不做什么"是漏需求的两个重灾区，逐项扫，别省。
4. **"不做什么"要可验证** —— MUST NOT 也得能检查它没发生，否则没转化完。
5. **纯行为，不越界到方案** —— 技术选型 / 架构，任务拆解都不在预期范围内；只有"行为级约束"留在 spec。
6. **未过 review 不放行** —— spec 是编码前闸门，显式确认才能呗采纳使用。
7. **止步于规格，不自动往下** —— 不调用下游 skill、不写代码。
8. **（greenfield）先圈维度，再抠边界** —— 用 Coverage Map 系统覆盖能力维度并逐项定档，防漏整类功能；但每行必落一档、不默认全纳入，防全面滑向膨胀。
9. **（greenfield）调研与否，用户拍板** —— 是否做功能空间调研是**用户的决策**：主动问、给建议、等回答；绝不以"需求够详尽 / 已有发散材料"替用户跳过，被动语气（"要不要你说"）不算问。

## 终止条件（可检验）

- **达标即停**：当每条 Requirement 都有 Scenario、双探针都过、"不做什么"都成了可验证 MUST NOT、
  成功标准可执行——spec 就够了，进入 review 门禁，别为"更完整"无限加需求。
- **（greenfield）覆盖到位即停**：Coverage Map 每行都有档位、纳入项都落成 Requirement，即视为覆盖到位；不为"更全"把"后续版本 / 默认不做"的维度硬塞进本版。
- **兜底**：如果发现概念本身还没清（写到一半发现"要解决什么"都说不清），**停下来**，
  别用 spec 的外壳硬包一个没想透的想法。


## 反例（不要这样做）

❌ 把概念单换种措辞抄一遍当 spec —— 没有 Scenario、不可验证。
❌ 写"系统应该性能好 / 体验流畅"这种无法判断通过与否的"需求"。
❌ 只写"要做什么"，跳过边界探针和"不做什么"——漏掉一半真实需求。
❌ "不做什么"只写一句"不做同步"，没给"怎么验证它没发生"。
❌ 在 spec 里写"用 React + SQLite""加一个 Redis 缓存层"——越界到技术方案。
❌ （greenfield）只照需求明说的功能写 spec，整类能力维度（权限 / 空态 / 批量 / 导出…）静默漏掉。
❌ 把功能空间调研结果当需求，所有维度全纳入——spec 膨胀成"全行业功能大全"。
❌ 一次性把几十个澄清问题全抛给用户，不分"现在问 / 采用默认 / 放待解"。
❌ （greenfield）自己判断"需求够详尽 / 已有发散材料"就跳过功能空间调研——跳不跳过是**用户的决策**，必须主动问、等用户拍板（"你觉得需要再说"不算问）。
❌ deep-research 跑不起来（缺工具 / 无网 / workflow 失败）却反复重试、卡死——应如实告知 + 降级凭领域知识自列维度继续，别卡在工具错误里。
❌ 改一个小功能却重写整个系统的 spec —— 该用 delta。
❌ 动笔前不看代码、不看测试怎么跑，写出一份脱离代码库的愿望清单。
❌ 没落盘、没让用户 review 就说"spec 好了，开始写代码"。
❌ 概念其实还没想清，却用 spec 的外壳硬包着往下冲 —— 停下来。
❌ 在 CI / 自治循环里自动产 spec，没有活人 review。

## 相关参考

- [references/spec-template.md](references/spec-template.md) —— 行为契约 spec 的落盘模板
  （含 delta 写法，Requirement / Scenario / MUST NOT / 边界 / 成功标准各节）。
- [references/coverage-probes.md](references/coverage-probes.md) —— 双探针完整清单：
  边界探针逐项 + 禁止探针，含"怎么把每一项转成可验证的 Scenario / MUST NOT"。
- [references/coverage-map.md](references/coverage-map.md) —— 能力覆盖图（greenfield）：
  功能空间调研（先问后调）、能力维度定档（纳入 / 默认不做 / 后续版本 / 必须确认）、问题三级分流。

