2026-04-13 06:21:53 +08:00
|
|
|
|
---
|
|
|
|
|
|
name: easysdd-feature-implement
|
2026-04-15 15:36:10 +08:00
|
|
|
|
description: feature 流程的阶段 2——按 design.md 的推进顺序写代码,写完用统一格式做完成汇报给用户 review。前提是 design.md 已经 approved(标准 design 含测试设计,或 fastforward design 含验收标准),并且同目录下有 checklist.yaml。触发场景:用户说"方案确认了开始实现"、"按方案写代码"、"开工"。实现中遇到方案没覆盖到的情况(新概念、范围外文件、需要打补丁分支)要主动停下来回到方案谈,不要硬冲。
|
2026-04-13 06:21:53 +08:00
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
# easysdd-feature-implement
|
|
|
|
|
|
|
2026-04-15 15:36:10 +08:00
|
|
|
|
到这一步用户已经在方案上签过字了,你的活是把方案变成代码。听起来直白,但实际容易出问题的不是写代码本身,而是**实现路上发现方案没覆盖到的情况时怎么办**——硬冲下去就把方案当摆设了,停下来回去谈又觉得麻烦。下面整套规则就是为了让"停下来"成为默认动作。
|
2026-04-13 06:21:53 +08:00
|
|
|
|
|
2026-04-15 15:36:10 +08:00
|
|
|
|
> 共享路径与命名约定看根技能 `easysdd` 第二节。到这一步 feature 目录已经由 brainstorm 或 design 创建好。
|
2026-04-13 06:21:53 +08:00
|
|
|
|
|
2026-04-15 15:36:10 +08:00
|
|
|
|
---
|
2026-04-13 06:21:53 +08:00
|
|
|
|
|
2026-04-15 15:36:10 +08:00
|
|
|
|
## 启动检查
|
2026-04-13 06:21:53 +08:00
|
|
|
|
|
2026-04-15 15:36:10 +08:00
|
|
|
|
动手前先过这几关:
|
2026-04-13 06:21:53 +08:00
|
|
|
|
|
2026-04-15 15:36:10 +08:00
|
|
|
|
### 1. 方案文件够不够撑实现
|
2026-04-13 06:21:53 +08:00
|
|
|
|
|
2026-04-15 15:36:10 +08:00
|
|
|
|
打开 design.md,先看 frontmatter:
|
2026-04-13 06:21:53 +08:00
|
|
|
|
|
2026-04-15 15:36:10 +08:00
|
|
|
|
- 文件头有 YAML frontmatter,`doc_type=feature-design`
|
|
|
|
|
|
- `feature` 字段跟当前 feature 目录一致
|
|
|
|
|
|
- `status=approved`
|
|
|
|
|
|
- `summary` 非空,`tags` 至少 2 个
|
2026-04-13 06:21:53 +08:00
|
|
|
|
|
2026-04-15 15:36:10 +08:00
|
|
|
|
然后看节内容——标准 design 和 fastforward design 的检查项不一样:
|
2026-04-13 06:21:53 +08:00
|
|
|
|
|
2026-04-15 15:36:10 +08:00
|
|
|
|
**标准 design(节编号 0/1/2/3/4)**:
|
|
|
|
|
|
- 第 0 节(术语约定)有内容
|
|
|
|
|
|
- 第 2 节(接口契约)有具体代码指针
|
|
|
|
|
|
- 第 3 节(实现提示)的改动计划落到具体路径和函数
|
|
|
|
|
|
- 第 3 节的推进顺序步骤明确,有退出信号
|
|
|
|
|
|
- 第 3 节的测试设计按功能点覆盖,每个功能点都有测试约束 / 验证方式 / 用例骨架
|
2026-04-13 06:21:53 +08:00
|
|
|
|
|
2026-04-15 15:36:10 +08:00
|
|
|
|
**Fastforward design(节编号 0/1/2/3)**:
|
|
|
|
|
|
- 第 0 节(需求摘要)含"明确不做"
|
|
|
|
|
|
- 第 1 节(设计方案)有改动点(文件路径 + 函数 / 类型名)
|
|
|
|
|
|
- 第 2 节(验收标准)每条可验证(操作步骤 + 期待结果)
|
|
|
|
|
|
- 第 3 节(推进步骤)步骤明确,有退出信号
|
2026-04-13 06:21:53 +08:00
|
|
|
|
|
2026-04-15 15:36:10 +08:00
|
|
|
|
任一项不达标就停下来,告诉用户先回 `easysdd-feature-design` 补齐。原因是方案漏的项实现时一定要现场补——而现场补意味着用户没在方案上把过关,等于绕过了 checkpoint。
|
2026-04-13 06:21:53 +08:00
|
|
|
|
|
2026-04-15 15:36:10 +08:00
|
|
|
|
### 2. checklist.yaml 在不在、能不能用
|
2026-04-13 06:21:53 +08:00
|
|
|
|
|
2026-04-15 15:36:10 +08:00
|
|
|
|
`checklist.yaml` 的生命周期看 `easysdd/reference/shared-conventions.md`。本阶段只消费并推进 `steps` 这一段:
|
2026-04-14 16:35:38 +08:00
|
|
|
|
|
2026-04-15 15:36:10 +08:00
|
|
|
|
- 文件存在,`feature` 字段跟当前 feature 目录一致
|
|
|
|
|
|
- `steps` 列表非空,每条 status 为 `pending`(接续上次中断时部分会是 `done`,正常)
|
|
|
|
|
|
- 不存在 → 停下来,让用户回 `easysdd-feature-design` 生成
|
|
|
|
|
|
|
|
|
|
|
|
### 3. 把上下文读全
|
|
|
|
|
|
|
|
|
|
|
|
动手前必读:
|
|
|
|
|
|
|
|
|
|
|
|
- 方案 doc 全文
|
|
|
|
|
|
- checklist.yaml
|
|
|
|
|
|
- 需求来源(用户描述 + brainstorm note,如有)
|
|
|
|
|
|
- `AGENTS.md`
|
|
|
|
|
|
- 第 2 节契约示例里提到的所有现有代码文件——读相关函数即可,不必通读
|
2026-04-13 06:21:53 +08:00
|
|
|
|
|
2026-04-15 15:36:10 +08:00
|
|
|
|
### 4. 跟用户确认从哪一步开始
|
2026-04-13 06:21:53 +08:00
|
|
|
|
|
2026-04-15 15:36:10 +08:00
|
|
|
|
通常是第 1 步,但如果是接续上次中断,参考 checklist.yaml 里已 `done` 的步骤,从下一步继续。
|
2026-04-13 06:21:53 +08:00
|
|
|
|
|
2026-04-15 15:36:10 +08:00
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 实现期间的几条核心约束
|
|
|
|
|
|
|
|
|
|
|
|
下面这些不是凭空的禁令,每条背后都有具体代价。理解了为什么再去执行才不会僵化。
|
|
|
|
|
|
|
|
|
|
|
|
### 严格按 checklist.yaml 的步骤顺序走
|
|
|
|
|
|
|
|
|
|
|
|
按 `steps` 列表顺序执行,不合并步骤、不跳步。每完成一步立即把该步 `status` 从 `pending` 改为 `done`。
|
|
|
|
|
|
|
|
|
|
|
|
最常见的违规是**"顺手把下一步也做了"**——为什么不行?因为方案里把动作切成步骤是有用意的:每一步都对应一个独立可验证的退出信号。两步合在一起做意味着出问题时你不知道是哪一步引入的,回滚也回不到一个干净的中间态。
|
|
|
|
|
|
|
|
|
|
|
|
### 不做方案外的改动
|
2026-04-13 06:21:53 +08:00
|
|
|
|
|
2026-04-15 15:36:10 +08:00
|
|
|
|
读代码时如果发现值得重构的点(参考 `AGENTS.md` 里"边实现边识别"那节),只要**不在本次功能影响面内**,就记成后续 issue,不要顺手改。
|
|
|
|
|
|
|
|
|
|
|
|
记录格式:
|
2026-04-13 06:21:53 +08:00
|
|
|
|
|
|
|
|
|
|
```markdown
|
2026-04-15 15:36:10 +08:00
|
|
|
|
> 顺手发现:{文件:行号} {问题简述}。不在本次范围,记录待后续 issue。
|
2026-04-13 06:21:53 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-04-15 15:36:10 +08:00
|
|
|
|
为什么这么严?顺手改的代码不在方案里,验收时核对不上;后人看 git blame 也分不清哪些改动是为了这次功能、哪些是顺手。一次混进去三五个"顺手",整个 PR 就讲不清楚到底改了什么。
|
|
|
|
|
|
|
|
|
|
|
|
### 术语守护
|
|
|
|
|
|
|
|
|
|
|
|
新写的类型名、函数名、变量名都要去方案 doc 第 0 节对照,不允许出现 doc 里没有的新概念。觉得需要引入新概念时,先停下来改方案 doc 第 0 节、grep 防撞车、用户确认,再继续写代码。
|
2026-04-13 06:21:53 +08:00
|
|
|
|
|
2026-04-15 15:36:10 +08:00
|
|
|
|
这条的代价同样具体:术语撞车意味着将来同一个概念在代码里有两个名字,或者两个不同的概念共用同一个名字——后者尤其致命,会让搜索完全失效。
|
2026-04-13 06:21:53 +08:00
|
|
|
|
|
2026-04-15 15:36:10 +08:00
|
|
|
|
### 出现"需要打补丁分支"的冲动时停下来
|
2026-04-13 06:21:53 +08:00
|
|
|
|
|
2026-04-15 15:36:10 +08:00
|
|
|
|
如果你写代码写到一半冒出 `if (特殊情况) { 特殊处理 }` 这种结构,**停**。
|
2026-04-13 06:21:53 +08:00
|
|
|
|
|
2026-04-15 15:36:10 +08:00
|
|
|
|
新功能里出现这种补丁分支基本只有一个原因:方案没覆盖到这种情况。继续硬写下去得到的是一段"为了让代码能跑而加的特殊逻辑",下次别人改这块时根本不知道这个分支为什么存在。正确做法是回到方案谈,要么把这个情况补进 design 里、要么砍掉、要么明确为遗留问题。
|
2026-04-13 06:21:53 +08:00
|
|
|
|
|
2026-04-15 15:36:10 +08:00
|
|
|
|
---
|
2026-04-13 06:21:53 +08:00
|
|
|
|
|
2026-04-15 15:36:10 +08:00
|
|
|
|
## 写完后输出统一汇报
|
2026-04-13 06:21:53 +08:00
|
|
|
|
|
2026-04-15 15:36:10 +08:00
|
|
|
|
所有步骤写完后用下面这个固定模板出一份汇报,然后**停下来等用户 review**。
|
2026-04-13 06:21:53 +08:00
|
|
|
|
|
2026-04-15 15:36:10 +08:00
|
|
|
|
为什么要固定模板?因为含糊汇报("大致完成了"、"应该没问题")等于把验证责任全推给用户。固定模板逼着把改了哪些文件、是否触碰方案外的东西、是否引入新概念这几件事一一说清楚,用户拿着这份汇报就能定向去看,不用从 git diff 重读一遍。
|
2026-04-13 06:21:53 +08:00
|
|
|
|
|
2026-04-15 15:36:10 +08:00
|
|
|
|
```markdown
|
|
|
|
|
|
## 实现完成汇报
|
|
|
|
|
|
|
|
|
|
|
|
### 动了哪些文件
|
|
|
|
|
|
{运行 git status,贴真实输出}
|
|
|
|
|
|
|
|
|
|
|
|
### 改了哪些函数 / 类型(按步骤分组)
|
|
|
|
|
|
**步骤 N:{步骤名}**
|
|
|
|
|
|
- file:line 函数名 改动类型(新增 / 修改 / 删除)
|
|
|
|
|
|
- ...
|
|
|
|
|
|
|
|
|
|
|
|
### 是否触碰到方案外的文件?
|
|
|
|
|
|
{是 / 否。是的话说明为什么,以及是否已同步更新方案 doc}
|
|
|
|
|
|
|
|
|
|
|
|
### 是否引入了方案 doc 第 0 节里没有的新概念 / 抽象?
|
|
|
|
|
|
{是 / 否。是的话说明已在第 0 节补充并做过 grep 防撞车}
|
|
|
|
|
|
|
|
|
|
|
|
### 推进顺序退出信号核对
|
|
|
|
|
|
{对照 checklist.yaml steps,逐条列出 action + exit_signal + status(应全为 done)}
|
|
|
|
|
|
|
|
|
|
|
|
### 测试约束自检
|
|
|
|
|
|
**标准 design**:
|
|
|
|
|
|
{对照方案第 3 节测试设计,每个功能点的测试约束——当前实现是否满足?靠什么保证(类型系统 / 单测 / 集成 / 运行时 assert)?}
|
|
|
|
|
|
|
|
|
|
|
|
**Fastforward design**:
|
|
|
|
|
|
{对照方案第 2 节验收标准,逐条核对是否满足}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
汇报后停下等 review。用户提修改意见就按意见改,改完再次发简短确认,反复直到用户明确放行进入验收阶段。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 测试用例怎么落
|
|
|
|
|
|
|
|
|
|
|
|
方案第 3 节测试设计里的**关键用例骨架**是实现测试的输入,不是装饰——按骨架写出完整测试用例。
|
|
|
|
|
|
|
|
|
|
|
|
注意一个常见误解:**测试通过 ≠ 测试约束满足**。测试通过只说明你写的那些用例都过了,但不说明每条测试约束都被某个用例覆盖了。所以汇报时要逐项确认每个功能点的测试约束都已被某个用例覆盖。
|
|
|
|
|
|
|
|
|
|
|
|
如果某条测试约束靠类型系统保证(比如 TypeScript 的类型签名直接排除了某种调用),在汇报里说明"该类型签名已落地,编译期保证"。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
2026-04-13 06:21:53 +08:00
|
|
|
|
|
|
|
|
|
|
## 退出条件
|
|
|
|
|
|
|
2026-04-15 15:36:10 +08:00
|
|
|
|
- [ ] `checklist.yaml` 所有 steps 的 status 都更新为 `done`
|
|
|
|
|
|
- [ ] 完成汇报已输出,用户明确 review 通过
|
|
|
|
|
|
- [ ] 没有未处理的"需要叫停"信号
|
2026-04-14 16:35:38 +08:00
|
|
|
|
- [ ] 第 3 节测试设计里每个功能点的测试约束都有测试覆盖(fastforward 时对照第 2 节验收标准)
|
2026-04-15 15:36:10 +08:00
|
|
|
|
- [ ] 没有"顺手发现"被偷偷修掉(都进了 issue 列表)
|
|
|
|
|
|
- [ ] 没有方案外的文件改动(或改动已同步更新方案 doc)
|
|
|
|
|
|
|
|
|
|
|
|
---
|
2026-04-13 06:21:53 +08:00
|
|
|
|
|
|
|
|
|
|
## 退出后
|
|
|
|
|
|
|
2026-04-15 15:36:10 +08:00
|
|
|
|
告诉用户:"所有步骤完成,方案 doc 已同步。下一步是阶段 3:验证闭环。可以触发 easysdd-feature-acceptance 技能。"
|
|
|
|
|
|
|
|
|
|
|
|
别自己顺手开始写验收报告——验收阶段需要独立的 checklist 节奏,提前进入会让验收的把关性失效。
|
2026-04-13 06:21:53 +08:00
|
|
|
|
|
2026-04-15 15:36:10 +08:00
|
|
|
|
---
|
2026-04-13 06:21:53 +08:00
|
|
|
|
|
2026-04-15 15:36:10 +08:00
|
|
|
|
## 容易踩的坑
|
2026-04-13 06:21:53 +08:00
|
|
|
|
|
2026-04-15 15:36:10 +08:00
|
|
|
|
- 代码只写了一部分就发完成汇报——汇报只在全部步骤完成后发一次
|
|
|
|
|
|
- 汇报里写"修改了相关文件"而不列具体 file:line
|
|
|
|
|
|
- 看到方案外的代码顺手改了
|
|
|
|
|
|
- 引入新类型但没回去更新方案 doc 第 0 节
|
|
|
|
|
|
- 加 `if (用户是 X) { 特殊处理 }` 补丁分支而不停下来反思方案
|
|
|
|
|
|
- 用户 review 还没通过就自己进入验收阶段
|
|
|
|
|
|
- 测试设计里的用例骨架一条都没实现,或测试约束没逐条验证
|