cs-feat-impl
cs-feat-impl
到这一步用户已经在方案上签过字了,你的活是把方案变成代码。容易出问题的不是写代码本身,而是实现路上发现方案没覆盖到的情况时怎么办——硬冲下去就把方案当摆设了。下面整套规则就是为了让"停下来"成为默认动作。
共享路径与命名约定看
codestable/reference/shared-conventions.md第 0 节。
写代码时的三条姿态
具体规则是这三条姿态的落点,理解姿态比记规则重要。
1. 默认写最少的代码
只写当前步骤明确要的东西。不顺手加"以后可能要"的可配置项、抽象层、参数开关、防御性兜底。判据:写完一段觉得"是不是还得加点 X",先问 X 是不是当前用户能感知到的——不是就别加。整体写完一看 200 行其实 50 行能讲清楚 → 重写。多出来的代码不是中性的,是后人维护的负担。
2. 只动该动的,不顺手"改善"邻居
改某个函数时只改那个函数。同文件里别的函数风格丑、命名怪——除非和本次改动直接冲突,否则别碰。新代码风格匹配当前文件已有写法。混进的"顺手改"会把功能 PR 稀释成"一坨综合改动",review 成本翻几倍。值得改的按下文"顺手发现"格式记成后续 issue。
孤儿处理:你这次改动让某个 import / 函数变成死代码 → 删掉。不是你改动造成的死代码 → 留着记成顺手发现。
3. design 没说的事别自己拍板
写到一半发现 design 没覆盖的角落(边界条件、错误路径、方案外文件)——默认停下来回 design 谈。下面"补丁分支"和"术语守护"是这条姿态的两个典型落点;任何"design 没明说我替它选了一个"的瞬间都触发。
启动检查
1. 方案文件够不够撑实现
frontmatter:doc_type=feature-design / feature 一致 / status=approved / summary 非空 / tags ≥ 2。
标准 design(节 0/1/2/3/4):
- 第 0 节有内容;第 1 节含"明确不做"和复杂度档位
- 第 2.1 名词层用"现状 → 变化"两段式,每个新增/变更接口至少一个示例 + 来源位置
- 第 2.2 编排层开头有主流程图,"现状 → 变化"齐全,流程级约束已记
- 第 2.3 挂载点按"删了它 feature 是否消失"判据,没把内部代码改动误列进来
- 第 3 节有关键场景清单 + 反向核对项(不含测试代码 / framework 选型)
Fastforward design(节 0/1/2/3):
- 第 0 含"明确不做";第 1 有改动点(文件 + 函数/类型名)
- 第 2 验收标准每条可验证;第 3 推进步骤有退出信号
任一项不达标 → 退回 cs-feat-design 补齐。原因:方案漏的项实现时一定要现场补,等于绕过 checkpoint。
注意:标准 design 第 3 节"验收契约"只说"做完后什么应该成立",不说"具体怎么做"。改动文件清单 / 函数级落点 / 测试代码归 implement 自决,不要因为 design 里没写就退回去要求补。
2. {slug}-checklist.yaml 在不在
- 文件存在,
feature字段一致 steps非空(design 已产出,paradigm 维度切片,4-8 步);checks非空- 不存在 → 退回
cs-feat-design生成
3. 把上下文读全
- 方案 doc 全文(标准 design 重点:第 1 节、2.1/2.2/2.3/2.4、3)
{slug}-checklist.yaml、需求来源(用户描述 + brainstorm note)、AGENTS.md- 第 2.1 节接口示例的来源位置 / fastforward 第 1 节改动点提到的代码文件——读相关函数即可
4. 跟用户确认从哪一步开始
通常第 1 步;接续上次中断从已 done 的下一步继续。
design 给的 steps 是 paradigm 维度切片(编排骨架 → 计算节点 → 持久化 → 测试),具体每步改哪个文件由你执行时决定。如果某一步实际是 3 个独立子动作、或发现微重构是它的前置(参考反射检查),跟用户对齐后追加 / 拆分 steps,不偷偷做。
design 第 2.5 节微重构的衔接:
-
如果 2.5 结论是"做微重构(拆文件)"或"做微重构(重组目录)",checklist 第 1 步就是它——独立跑完,按 2.5 节"行为不变怎么验证"那条核对:
- 拆文件:编译绿灯 + 现有测试通过 + 对外接口签名零 diff
- 重组目录:编译绿灯 + 现有测试通过 + diff 仅限文件移动 + import 路径更新(没有任何函数体改动)
不要合并到下一步——一旦混在一起,行为变更和结构变更就分不开,出问题回滚不到干净中间态
-
如果 2.5 结论是"不做"但写到中途反射检查触发了拆分信号 → 走下面"反射检查"那条路径(停下来 → 和用户对齐 → 能 provable 解决就追加独立 step),不要绕过用户确认偷偷追加
-
如果 2.5 末尾有"建议沉淀的 convention"段:implement 阶段不主动归档——只在重组目录跑通且行为零改动确认后,在汇报里带一句"design 2.5 建议沉淀的 convention 已就绪,等 acceptance 阶段确认是否走 cs-decide",把决定权交给 acceptance / 用户
实现期间的几条核心约束
严格按 steps 顺序走
按 steps 列表顺序执行,不合并、不跳。每完成一步立即把 status pending → done。
最常见违规是"顺手把下一步也做了"——每步都对应独立可验证的退出信号,两步合做意味着出问题时不知道是哪一步引入的、回滚也回不到干净中间态。
不做方案外的改动
发现值得重构的点(参考 AGENTS.md "边实现边识别"),只要不在本次功能影响面内就记成后续 issue:
> 顺手发现:{文件:行号} {问题简述}。不在本次范围,记录待后续 issue。
顺手改的代码不在方案里,验收对不上;后人 git blame 也分不清是为本次功能还是顺手。
术语守护
标准 design:新写的类型 / 函数 / 变量名都要去方案 doc 第 0 节对照,不允许出现 doc 里没有的新概念。要引入新概念 → 先停下来改第 0 节、grep 防冲突、用户确认。
Fastforward design:没有正式术语表,但要新起概念名时也要 grep 一下当前代码防冲突。
代价:术语冲突意味着同概念两个名字 / 同名字两个概念——后者会让搜索完全失效。
出现"补丁分支"的冲动时停下来
写代码时冒出 if (特殊情况) { 特殊处理 } 这种结构,停。这种分支基本只有一个原因:方案没覆盖到这种情况。继续写得到的是"为了让代码能跑而加的特殊逻辑"——下次别人改这块时不知道这个分支为什么存在。回方案谈:补进 design / 砍掉 / 明确为遗留问题。
代码质量反射检查
除上面流程约束外,还有一组针对代码质量的反射检查——看 codestable/reference/shared-conventions.md 第 7 节。
核心:不是"超过 N 行必须拆",而是"遇到 X 情况就停下来问自己"。每条对应 AI 默认会走进去的坑(往大文件继续追加、往大类加方法、补丁分支、复制粘贴、第 4+ 个参数、往万能 util 堆东西)。
反射检查结论是"要拆 / 新建文件 / 重命名 / 抽共用层"且超出现有 steps 范围 → 跟用户商量决定,不偷偷拆完继续写。判据按和 design 2.5 一致的边界分两路(避免 impl 自己造一套口径):
- 能用"只搬不改行为"解决(拆函数 / 拆文件 / 移动定义,编译器全程绿灯,对外签名零 diff)→ 和用户对齐后追加为独立 step插在当前 step 之前,跑完独立验证退出再继续
- 超出"只搬不改行为"边界(要改函数签名 / 改返回值结构 / 改调用关系语义 / 模块拆合)→ 本 feature 不做,记成"顺手发现"格式提示用户后续走
cs-refactor,当前 step 用最少的改动绕过去;不要因为"反正都看到了"就在 feature 里顺手做掉——这会把功能 PR 稀释成综合改动,也违反 design 2.5 早就划好的边界
写完后输出统一汇报
所有步骤完成后用下面模板汇报,停下来等用户 review。
固定模板的意义:含糊汇报等于把验证责任推回用户。固定模板逼你把改了哪些文件、是否触碰方案外、是否引入新概念一一说清楚。
## 实现完成汇报
### 动了哪些文件
{git status 真实输出}
### 改了哪些函数 / 类型(按步骤分组)
**步骤 N:{步骤名}**
- file:line 函数名 改动类型(新增 / 修改 / 删除)
### 是否触碰到方案外的文件?
{是 / 否。是的话说明原因 + 是否已同步更新方案 doc}
### 是否引入了方案 doc 里没有的新概念 / 抽象?
{是 / 否。是的话说明已回填方案 doc(标准 design 补第 0 节 + 第 2.1 节;fastforward 补第 1 节)并做过 grep 防冲突}
### 代码质量反射检查自检
{对照 shared-conventions 第 7 节,触发哪些信号 + 怎么处理;都没触发写"无触发"}
### 推进顺序退出信号核对
{对照 steps 逐条列 action + exit_signal + status(应全为 done)}
### 验收场景自检
**标准 design**:对照第 3 节关键场景清单,每条靠什么证据满足(类型 / 单测 / 集成 / 手工 / assert)+ 反向核对项是否守住
**Fastforward design**:对照第 2 节验收标准逐条核对
汇报后停等 review。
测试用例怎么落
标准 design 第 3 节"关键场景清单"每条 = 一个可验证行为约束。你的活是把每条变成可观察证据:单测 / 集成 / 手工操作 / 类型编译期保证。
具体怎么测、用什么 framework、mock 怎么搭——design 没规定,自决。但你得在 steps 里写清楚"哪一步落哪个测试",汇报里逐项核对每条场景都有证据。
测试通过 ≠ 验收场景满足——前者只说明你写的用例过了,不说明每条场景都有用例覆盖。
类型系统保证的(如 TypeScript 签名直接排除某种调用),汇报里说"类型签名已落地,编译期保证"。
退出条件
- 所有 steps 的 status 都
done - 完成汇报已输出,用户 review 通过
- 没有未处理的"需要叫停"信号
- 第 3 节关键场景每条都有证据 / 测试覆盖(fastforward 对照第 2 节)
- 没有"顺手发现"被偷偷修掉(都进 issue 列表)
- 没有方案外文件改动(或已同步更新方案 doc)
退出后
告诉用户:"所有步骤完成,方案 doc 已同步。下一步阶段 3 验收闭环,触发 cs-feat-accept。"
别自己顺手开始写验收报告——验收需要独立的 checklist 节奏,提前进入会让把关失效。
实现过程中如果踩到了项目通用的硬约束 / 命令陷阱 / 环境设置("啊原来这个项目要先 X 才能 Y",一两行能讲清、下个 feature 的 AI 还会再撞一次)→ 在告诉用户去 accept 前顺便提一句:"这次发现 {具体那条},是不是要 cs-note 一下加到 AGENTS.md,免得下次再踩?"——单条即可,不连写多条;用户说"等 accept 一起处理" 就跳过,accept 第 8 节会兜底盘点。
容易踩的坑
- 代码只写了一部分就发完成汇报——汇报只在全部完成后发一次
- 汇报里写"修改了相关文件"而不列 file:line
- 看到方案外的代码顺手改了
- 引入新类型 / 概念但没回去更新方案 doc
- 加
if (用户是 X) { 特殊处理 }补丁分支而不停下来 - 用户 review 还没通过就自己进入验收阶段
- 关键场景清单一条都没落证据
- 把 paradigm 维度 steps 当 file:line 读——steps 是切片策略不是改动清单;step 内部偷偷拆子步骤而不跟用户对齐 = 绕过 review