---
name: product-feature-tech-implement
description: >
  基于功能设计文档与现有源码，端到端实现一个产品功能：开发、代码 review、测试用例编写与执行，
  循环迭代直到测试通过，最终产出用户手册与实现总结文档（保存到当前项目 markdown/ 目录）。
  触发条件：用户提供了功能设计文档（PRD/设计文档/需求描述）+ 源码目录（或代码库路径），
  并希望"实现这个功能"、"开发这个功能"、"把这个设计文档变成代码"、"做这个功能的开发+测试"、
  "完整实现并测试"、"端到端开发"，或明确要求按"开发-review-测试"循环推进直到测试通过。
  也适用于需要额外运行环境的开发任务，例如 PostgreSQL/MySQL 等数据库插件开发
  （可能需要编译、搭建实例、配置参数、初始化、跑测试）、需要启动服务进程才能测试的后端功能、
  需要特定运行时环境的库或框架功能。
  即使用户只是说"帮我把这个功能做出来"、"按设计文档实现一下"、"这个功能开发完了麻烦测试一下"，
  但同时给出了设计文档和代码路径，也应使用本 skill。
  本 skill 的核心是严格的"开发 ⇄ Review"循环 + "测试者不预先看代码"的盲测试原则，
  因此当用户提到"独立测试"、"测试不能看代码"、"先写测试用例再看代码"、"black-box 测试"时，
  也应优先使用本 skill。
  不适用于：只是要求"写一个脚本"、"改一行代码"、"快速修一个 bug"等轻量级、
  无需走完整开发-review-测试闭环的任务；也不适用于纯粹的代码评审（无需新开发功能）
  或纯粹的测试用例编写（无设计文档、无需开发）这类单一环节请求——
  这些更适合直接处理而非套用本 skill 的完整闭环流程。
---

# Product Feature Tech Implement

一个把"功能设计文档 + 源码"变成"经过 review、经过测试、可交付"代码的闭环流程。

核心思想很简单：**开发者和审查者反复拉锯，直到审查者满意；然后测试者在完全不知道代码长什么样的情况下，
只根据设计文档独立写出测试用例，再去跑这些测试连同已有测试；测试不过就打回开发，测试过了才算完。**
这个"测试者不能偷看代码"的约束是整个 skill 里最容易被悄悄破坏、也最值得认真保护的一条规则——
原因见下面"为什么要盲测试"。

## 为什么要盲测试

如果测试用例是照着代码写的，那测试只能验证"代码做了它自己以为该做的事"，却验证不了
"代码做了设计文档真正要求的事"。这两者的差距正是 bug 藏身的地方：开发者对需求的理解偏差、
遗漏的边界条件、想当然的默认值——这些错误一旦被同一个脑子既写进代码又写进测试，测试就会
和代码一起错，谁也发现不了。让测试者只看设计文档独立写测试，本质上是用"两个互不通气的理解"
互相校验，偏差才会暴露出来。这就是为什么测试阶段要明确写着"千万不要先看代码"——不是走流程，
是这一步存在的全部意义。

## 整体状态机

```
                    ┌─────────────────────────────┐
                    │   读取设计文档 / 源码 / 上下文   │
                    │   （PG 插件等场景额外读取依赖）   │
                    └───────────────┬───────────────┘
                                    │
                                    ▼
        ┌──────────────────────────────────────────────────┐
        │  循环 A：开发 ⇄ Review（直到 review 通过）           │
        │                                                    │
        │   developer 子代理 ──写/改代码──▶ reviewer 子代理     │
        │        ▲                              │            │
        │        └──────review 意见 / 修复要求────┘            │
        └───────────────────────┬────────────────────────────┘
                                │ review 通过
                                ▼
        ┌──────────────────────────────────────────────────┐
        │  tester 子代理（独立、不看代码）                      │
        │   - 若本任务此前已写过测试 → 跳过编写，直接复用         │
        │   - 否则：只读设计文档，独立编写新测试用例              │
        │   - 跑【新测试 + 已有测试】（含必要的环境搭建）         │
        │   - 输出测试报告                                     │
        └───────────────────────┬────────────────────────────┘
                                │
                  ┌─────────────┴─────────────┐
                  │ 测试失败                     │ 测试通过
                  ▼                            ▼
        回到循环 A 开头                    任务完成，关闭三个角色
        （带着测试报告去修 bug /              生成用户手册 + 总结文档
         补全未覆盖的功能）
```

整个外层是一个"无限循环"——没有预先设定的最大轮数，因为一个功能到底要改几轮谁也说不准。
但"无限"不等于"放任不管"：每一轮必须真的取得进展（修复了具体问题、补全了具体功能点），
如果连续多轮都在原地打转（同一个问题被反复打回、测试报告和上一轮几乎一样），就不再是
"继续迭代"，而是"卡住了"——这时候停下来把情况摊开给用户看，比硬着头皮空转更负责任。
具体判断标准见下面"何时该向用户求助而不是继续循环"。

## 开始之前：收集必要输入

进入循环前，先确认手上有这些东西，缺什么就问用户要什么（用 `ask_user_input_v0` 或直接提问都行，
看哪个更顺手）：

1. **功能设计文档**：路径或内容。这是 developer 和 tester 共同的"宪法"——两边都依据它工作，
   但谁也不许看对方依据它做出的产物（开发者不看测试用例，测试者不看代码）。
2. **源码目录**：现有代码库的路径，开发者要在这个基础上改。
3. **额外运行依赖**（按需）：如果功能涉及需要独立运行环境才能测试的场景——最典型的是数据库插件
   开发（PostgreSQL/MySQL 等），需要额外确认：
   - 数据库源码/安装路径，编译方式
   - 是否已有现成实例，还是需要本次搭建一套测试集群
   - 必要的连接信息、权限、配置参数
   - 参考 `references/postgres-extension.md` 了解 PG 插件场景的具体环境搭建步骤
   其他场景类推：任何"代码本身之外，测试还依赖外部服务/进程/环境"的情况，都在这一步问清楚，
   不要等 tester 子代理跑到一半才发现少了张图纸。
4. **现有测试套件位置**（如果有）：tester 子代理需要知道"已有测试"在哪里，才能在新测试之外
   一并跑它们，防止改动破坏了原本好用的功能。

如果用户的描述已经包含了以上信息，直接提取使用，不要为了走流程而重复发问。

## 任务状态文件：让循环记得自己做到哪了

子代理之间不共享记忆，每一轮都是全新开始的对话；如果不显式记录状态，"测试用例是否已经写过"
"现在是第几轮"这类信息就会在每次循环里丢失，导致 tester 把测试重写一遍（违反用户的明确要求），
或者整个流程不知道何时该喊停。

在项目目录下维护一个状态文件 `markdown/.feature_implement_state.json`（隐藏文件，不算交付物，
不要出现在最终汇报里），结构大致如下：

```json
{
  "feature_name": "一句话功能描述，用于文件命名",
  "design_doc_path": "...",
  "source_dir": "...",
  "iteration": 3,
  "loop_a_rounds_this_iteration": 2,
  "test_suite_written": true,
  "test_suite_path": "...",
  "history": [
    {"iteration": 1, "review_verdict": "未通过", "test_verdict": "未运行", "summary": "首版实现，review 发现 3 处问题"},
    {"iteration": 2, "review_verdict": "通过", "test_verdict": "失败", "summary": "review 通过，但测试发现并发场景未处理"},
    {"iteration": 3, "review_verdict": "进行中", "test_verdict": "未运行", "summary": "修复并发问题"}
  ]
}
```

每次开始新一轮（无论是循环 A 内部还是测试失败后回到循环 A）之前先读这个文件，结束时更新它。
`test_suite_written` 是关键字段——只要它是 `true`，tester 子代理这次就不再重新编写测试用例，
而是直接复用 `test_suite_path` 里已有的测试，把新一轮的代码拿去跑；只有在测试本身也需要因为
设计文档变更而调整时才重写，并且要明确告诉用户"测试用例本身也改了，原因是……"。

## 角色说明

三个角色的详细职责、输入输出格式、产出要求都写在 `agents/` 目录下，进入对应阶段时去读：

- `agents/developer.md` —— 子代理 1：开发者
- `agents/reviewer.md` —— 子代理 2：代码审查者
- `agents/tester.md` —— 子代理 3：测试者（**进入这个阶段前，先读它里面关于"如何保证盲测试"的部分**）

## 根据运行环境调整执行方式

"子代理"这个词在不同环境里对应不同的实际能力，下面按环境分别说明该怎么落地这个流程。
不确定自己在哪个环境，看当前可用的工具列表里有没有任务派生/子代理类工具，没有就按
"无子代理环境"处理。

### 有子代理能力的环境（如 Claude Code、Cowork）

这是流程设计的原生形态，按字面执行即可：

- 循环 A 内，developer 和 reviewer 各自是独立的子代理调用，每次调用把当前所需上下文
  （设计文档、上一轮 review 意见、上一轮测试报告——如果有）整理后传入，子代理各自独立工作，
  互不偷看对方的"私货"（developer 看不到 tester 写的测试代码细节，tester 完全看不到 developer
  写的实现代码）。
- tester 子代理在被派生时，**prompt 里只能包含设计文档和已有测试套件的位置，绝对不能包含
  代码目录路径或代码内容**，这是物理隔离，比任何"请不要看代码"的口头约束都可靠——这件事的
  安全性建立在你没有把代码位置写进 tester 的 prompt 这个事实上，而不是建立在它会不会自觉
  遵守约束上。
- 三个子代理任务都结束、且最终测试通过后，不需要额外动作"关闭"它们——子代理本身是按任务
  生命周期存在的，任务完成即结束。

### 无子代理能力的环境（如 Claude.ai 网页/客户端）

这种环境下，"派生子代理"实际上是你自己依次扮演三个角色，在同一个对话上下文里完成。
这时"测试者不看代码"的物理隔离没有了——你作为同一个 Claude，扮演 developer 时已经读过代码，
扮演 tester 时没法真的"忘记"读过的内容。诚实面对这个限制，用下面的办法尽量减少污染，
而不是假装隔离仍然存在：

1. **先写测试，再细看代码**：进入 tester 阶段时，即使你脑子里有代码的模糊印象，也要先只
   重新读一遍设计文档，把测试用例写下来落盘，写完之后才去翻代码细节执行测试。这样测试用例
   的设计依据是有记录可查的（设计文档本身），不是凭着刚才读代码时的印象反推的。
2. **在测试用例文件里写明依据**：每个测试用例标注一句"对应设计文档第几节/哪个需求点"，
   这样事后review的人也能看出测试是不是真的独立于实现的具体写法。
3. **角色切换时显式声明**：在回复里清楚说明"现在切换到 reviewer 角色，只依据设计文档和
   增量代码"，"现在切换到 tester 角色，重新对照设计文档而非刚才看到的实现细节来设计用例"——
   这不是给用户看的表演，是帮你自己在长对话里真正切换思维框架，效果是实打实的。
4. 如果用户对"测试必须真正独立"这一点要求很高（比如这是个安全敏感场景），可以直接告诉用户
   当前环境做不到物理隔离，建议的替代方案是：你先生成测试用例文件，用户开一个新对话/新会话
   只把设计文档喂给一个全新的 Claude 实例去写测试，再拿回来给你跑——这是更可靠但更费事的做法，
   由用户决定是否需要。

无论哪种环境，"循环 A 直到 review 通过""测试失败打回循环 A"这套状态机逻辑本身不变，
变的只是 developer/reviewer/tester 之间的隔离强度。

## 何时该向用户求助而不是继续循环

下面这些情况出现时，暂停循环，把情况清楚地告诉用户，而不是埋头继续转：

- **同一个问题被打回两次以上仍未解决**：说明这可能不是实现细节问题，而是设计文档本身有歧义
  或矛盾，需要用户澄清意图，开发者和审查者再怎么拉锯也解不开一个本身说不清楚的需求。
- **测试环境搭建本身失败**（比如 PG 实例起不来、依赖装不上）且尝试了合理的排查后依然卡住：
  这通常是环境/权限问题，不是代码问题，继续循环不会有帮助。
- **测试报告和上一轮几乎一样**（同样的用例、同样的失败点），说明上一轮的"修复"没有真正起作用，
  值得停下来看看是不是 developer 子代理误解了 review 意见或测试报告。
- **设计文档里的某个需求点在现有代码架构下几乎无法实现**，或者实现代价（比如要推翻现有架构）
  明显超出了"实现一个功能"的合理范围：这是架构级决策，应该让用户知道并做选择，不该由循环自己
  decide。

求助时把当前状态文件里的 history 摘要给用户看一下，让用户能快速看懂"已经试了什么、卡在哪"，
而不是从头解释一遍。

## 任务完成后：用户手册 + 总结文档

测试通过、循环结束后，再做两件事，都是 Markdown 格式，保存到当前项目的 `markdown/` 目录：

**用户手册**（文件名建议 `markdown/{功能名}_用户手册.md`）：写给"会用这个功能但不关心实现细节"
的人看——这个功能是什么、怎么用、有哪些参数/选项、典型使用场景举例、常见问题。不要把实现细节
或开发过程写进去，那是下一份文档的内容。

**实现总结文档**（文件名建议 `markdown/{功能名}_实现总结.md`）：写给"想知道这个功能是怎么做出来的"
的人看——做了哪些代码改动（文件、模块层级即可，不需要逐行解释）、过程中 review 发现并修复了
哪些问题（这是有价值的信息，说明代码质量是怎么被把关的，不要省略）、测试覆盖了哪些场景、
测试过程中发现并解决了什么问题、最终经过了几轮迭代。可以直接基于状态文件里的 `history` 整理，
这正是它存在的目的之一。

写完这两份文档后，可以视情况删除或保留状态文件 `.feature_implement_state.json`——如果用户后续
可能基于同一个状态继续迭代这个功能（比如又来了新需求），保留它会让"循环记得做到哪了"这件事
对未来的请求依然有效；如果这是个一次性任务，清理掉也无妨。
