---
name: forge-feature-doc
description: 维护每个功能一份给人看的「需求设计文档」（docs/modules 下，一个功能一份）：待拍板置顶，按需写背景、目标、流程、布局、状态、交互细节、业务规则、召回、AI 生成（prompt）、效果、成本、系统，先图后字，只写当前设计，末尾记关键改动，附出图与上线前检查。新建、更新、同步、补充这份文档都用它，别直接手改——它有固定写法和检查。用户说「出设计文档」「PRD 太长看不懂」「把设计文档同步一下」「重拍截图」「上线前看文档跟上没有」时用；用户抱怨看不到功能现在的设计、不知道最近改了什么时也用；forge 各阶段改了规则、文案、交互、布局、阈值、prompt、模型、架构后收尾也用，哪怕用户没明说。不处理写给 AI 的 PRD/DESIGN（forge-prd、forge-design）、骨架上定布局（forge-design-lab）、改 prompt 本身（prompt-craft）、进度（forge-status）。
---

# forge-feature-doc — 每个功能一份给人看的需求设计文档

交付 `docs/modules/<功能>.md` 和它的图（`docs/assets/visuals/<英文短名>/overview/`）：开头是待拍板，按需写 12 个部分，先图后字，只写当前设计，末尾记关键改动。配套三个脚本：出示意图、给真实页面截图加标注、上线前检查。

## 定位与边界

像一个会画图的产品搭档——把「这个功能长什么样、按什么规则跑、效果由哪些数决定、还缺你哪些决定」讲透：先放图，再用一两行字注释，不把 PRD、DESIGN 换个说法再讲一遍。

核心立场：读者是要拍板、注意力有限的人（按 ADHD 友好来写）。forge 产出的 PRD、DESIGN、feature-spec 是写给 AI 执行的，必然很长，读者审不过来，迭代中改了什么也看不到，文档和代码就一路漂移。所以这份文档只写当前设计里决定九成效果的内容，固定顺序、按需取舍，每部分先图或表；历史只留末尾 15 条关键改动；凡是改变效果的改动，都要在这里留下痕迹。

边界之外的交出去：写给 AI 的 PRD、feature-spec 交 forge-prd；DESIGN.md 文字规格和 token 表交 forge-design；在真比例骨架上定布局交 forge-design-lab；写或改 prompt 本身交 prompt-craft；写代码交 forge-eng；进度交 forge-status；复盘交 forge-fupan。对外文章、发布公告不在范围。

一次只处理一个功能。

## 按需读取

| 文件 | 什么时候读 |
|---|---|
| `references/writing-rules.md` | 新建前；第一次在某个项目里更新前（12 个部分各写什么、怎么展示、ADHD 写法、只写现在） |
| `references/stage-map.md` | 被某个 forge 阶段调用、要判断改哪几部分时 |
| `references/visuals.md` | 出图前（示意图模板、截图脚本写法、标注约定、踩坑） |
| `references/example-ai-search.md` | 第一次在新项目里用、想看完整范例时 |

## 意图分流

| 意图 | 信号 | 应答 |
|---|---|---|
| 新建 | `docs/modules/<功能>.md` 不存在 | 走「新建」全流程 |
| 阶段更新 | 文档已存在；来自某阶段收尾，或用户说「更新」并指出改了什么 | 走「更新」，只动受影响的部分 |
| 出图 | 「截图」「示意图」「重拍」「图过期了」 | 只走「出图」 |
| 检查 | 「上线前」「检查文档」，或 forge-review / forge-ship 调用 | 只走「检查」 |
| 潜在 | 用户抱怨文档太长看不懂、调整看不到，但没要求出文档 | 一句话说明能做什么，问要不要建；不自动开工 |

## 工具

`{skill}` 指本 skill 目录。scaffold 会把另外三个脚本复制到项目的 `scripts/design-doc/`，项目里没装本 skill 也能跑。

| 脚本 | 什么时候 | 用法 | 失败降级 |
|---|---|---|---|
| `scaffold.mjs` | 新建 | `node {skill}/scripts/scaffold.mjs --repo <仓库> --feature <功能名> --slug <英文短名> --types ui,backend,ai` | — |
| `render-diagrams.mjs` | 改了 `overview/src/*.html` | `NODE_PATH="$(npm root -g)" node scripts/design-doc/render-diagrams.mjs <overview 目录>` | 没有 Playwright：只交 HTML 源文件，说明图待补 |
| `annotate.mjs` | 写项目截图脚本时引用 | 见 `references/visuals.md` | 本地服务没起：用设计骨架页面截图 |
| `check.mjs` | 每次改完；review / ship 门禁 | `node scripts/design-doc/check.mjs [基准分支]` | 报错先在已知健康的文档上验证脚本，再信结果 |

## 新建

1. **读资料**：项目 `docs/README.md` 的文档规则（没有就跳过），再读 PRD、feature-spec、讨论稿、已有的长文档。只取决定效果的事实；数值以代码和配置为准，文档和代码对不上时以代码为准并记下。
2. **判类型**：有没有界面、有没有后端、有没有 AI 或算法，决定写哪几部分（对照表在 `writing-rules.md`）。判断不了就问一句。
3. **建骨架**：跑 `scaffold.mjs`。
4. **填内容**：照 `writing-rules.md` 写。还没定的进「待你拍板」并标 ⚠️；定了还没做的标 ⏳。关键改动从 git log 和 CHANGELOG 里挑影响效果的补齐（最多 15 条），理由查不到就写「理由未记录」。
5. **出图**：现状和流程两张示意图必出。有界面的：设计阶段用 forge-design-lab 骨架截图，实现后用真实页面截图加标注；两者都截不到时画页面示意（`page-mock.html`），不画只有方框的线框。
6. **检查、打开、汇报**：跑 `check.mjs`，用 `open -a "Visual Studio Code" <文档>` 打开（无界面运行时跳过），在对话里按下面的格式汇报。

## 更新

1. **定位受影响的部分**：对照 `stage-map.md`（规则、文案、交互、布局、阈值、prompt、模型、架构各对应哪几部分）。
2. **原位改成新的当前值**：正文不写「改为」，旧值只进关键改动。
3. **重出受影响的图**。
4. **关键改动加一行**：`| MM-DD | 部分 | 旧 → 新 | 为什么 |`，最新在上；超过 15 条删最早的，更早的历史在 git 里。
5. **检查、汇报**。

文档更新和功能改动放进同一个提交。分开提交，文档就会落后，这正是漂移的来源。

## 出图

- **示意图**（现状、流程、漏斗、管道、架构）：改 `overview/src/*.html`，模板来自 `{skill}/assets/diagrams/`，然后跑 `render-diagrams.mjs`。
- **页面图**（布局标注、状态缩略图、交互细节放大）：用项目的截图脚本，没有就照 `visuals.md` 新写一个，引用 `annotate.mjs`。登录态、额度、失败这类状态用拦截返回的假数据造出来。
- 出完逐张看一遍：标签有没有被截断、有没有压住正文、数字和代码是否一致。

## 检查

跑 `check.mjs`。它报四类问题：`watch` 覆盖的代码改了但文档没改，或 `watch` 写了不存在的路径；正文和示意图源文件里出现讲历史的词；关键改动超过 15 条；图片或链接指向不存在的文件、用了绝对路径，文件引用没写成链接。`watch` 只能按文件盯，大文件里只有一部分和设计有关也照写；改动确实不影响设计时，在提交说明里写「设计文档无需更新：<文档名>」，检查放行并把它列出来，留个记录。被 forge-review / forge-ship 调用时，没通过就拦下；用户明确说跳过才放行，并在汇报里写明跳过了什么。

## 输出

**文档骨架**（顺序锁死；不适用的部分整节删掉，不写「不涉及」）：

```
# <功能名>
> 写给人看的需求设计文档：先看图，字只做注释。⚠️ = 待你拍板 ⏳ = 已定未做完。末尾「关键改动」记最近的重要调整。
**一句话**：…  **阶段**：…
## 待你拍板          必有；每条带建议
## 1. 需求背景        必有；现状失败的例子（图或数字）+ 不超过 3 行
## 2. 目标与成功标准   必有；标准 / 怎么算达到 / 现在；「不做」一行
## 3. 用户流程        必有；流程图
## 4. 页面布局        有界面；标注图
## 5. 状态一览        有界面；状态缩略图 + 文案表
## 6. 交互与细节      有界面；局部标注图，一图一句
## 7. 业务规则        有后端；规则表，数值写死
## 8. 召回 / 数据逻辑  有 AI 或算法；漏斗图
## 9. AI 生成（prompt）有 AI；管道图 + 关键规则
## 10. 效果样例与评估  有 AI；真实输出 + 评估方法
## 11. 成本与速度      有 AI 或重计算；小表
## 12. 系统怎么搭      有后端；架构图
## 细节在哪          必有；链接表
## 关键改动          必有；最多 15 条
```

**每次运行后的对话汇报**（三行，待拍板有变化再加一行）：

```
设计文档 <路径>
- 改了：<部分>（<一句话>）
- 关键改动：+1「<那一行>」
- 检查：通过 / 未通过（<原因>）
```

## 红线

1. **截图只读**。所有非 GET 请求一律拦下，状态用假数据造。项目的本地服务可能连着生产库、带着付费模型的 key，一次误提交就写了生产数据、花了真钱，而且收不回来。
2. **图和数值不编**。页面图来自真实页面或设计骨架，数值取自代码和配置，示意图里的数也一样。读者拿这份文档拍板，一张错的图比没有图更糟。
3. **不写凭证和内部地址**。文档、图和 skill 都会被提交、同步出去。

## 边界与失败处理

| 情况 | 处理 |
|---|---|
| 项目没有 `docs/modules/` 或 `docs/README.md` | 照常新建；有 README 就在它的文档地图里加一行入口，没有就在汇报里提一句，不为此新建 README |
| 资料不全（只有一句需求） | 只写背景、目标、流程和待拍板，其余整节先不建 |
| 本地服务没起、改不了后端 | 页面图用设计骨架或页面示意；状态用拦截假数据 |
| 同一功能已有长文档（模块附录、旧总览） | 不删不并：留作「细节在哪」的链接目标，在它开头加一行指向本文档。「一个功能一份」指的是带 `watch` 的这一份 |
| 数值只在生产环境变量里，代码没有默认值 | 取 `.env.example` 或配置说明里的值，标「未核对生产」；不读生产 `.env`（里面有密钥），要核对请用户确认。「没配也不报错」本身考虑进待拍板 |
| 没有 Playwright | 只交示意图的 HTML 源文件和截图清单，说明图待补 |
| 文档和代码对不上 | 以代码为准改文档；拿不准的进待拍板 |
| 用户要改的是 PRD / DESIGN 本身 | 交给对应 skill；它们改完，再由本 skill 同步这份文档 |

## 各阶段怎么接

| 谁 | 什么时候调用本 skill | 主要动哪几部分 |
|---|---|---|
| forge-prd | PRD / feature-spec 定稿后 | 新建；背景、目标、流程、规则、待拍板 |
| forge-design、forge-design-lab | 设计定稿后 | 布局、状态、细节（骨架截图） |
| prompt-craft | prompt 改完后 | AI 生成、效果样例 |
| forge-eng | 实现完成后 | 召回、成本、系统；页面图换成真实截图；去掉 ⏳ |
| forge-bugfix | 修复改变了设计时 | 对应部分 + 关键改动 |
| forge-review、forge-ship | 上线前 | 跑检查，不过就拦 |
