用户说“修复这个可复现 bug”或要求根据失败报告修代码时使用。执行红灯测试、根因定位、最小修复、独立审查和回归;尚未确认的问题先用 cm-test,新功能和架构重设计转交 cm-prd。
Scanned 9/3/2026
Install to Claude Code
npx -y skills add kingxiaozhe/cm-workflow --skill cm-fix --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Cm Fix?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/kingxiaozhe-cm-fix)More formats (shields.io, HTML) on the badges page.
---
name: cm-fix
description: 用户说“修复这个可复现 bug”或要求根据失败报告修代码时使用。执行红灯测试、根因定位、最小修复、独立审查和回归;尚未确认的问题先用 cm-test,新功能和架构重设计转交 cm-prd。
---
# cm-fix — 缺陷修复小闭环
执行前读取 `../../runtime/project-context.md`、`../../runtime/orchestration.md`、
`../../runtime/review.md`、`../../runtime/model-efficiency.md` 与
`../../runtime/logging.md`。Codex 入口为 `$cm-fix`;Claude Code 跨平台入口为
`/cm-fix`,macOS/Linux 另有历史别名 `/cm:fix`。
用户明确要求外部专家,或为本次修复开启 AUTO 时,仍必须先完成第 1 步本地复现,
再按 `../../runtime/external-expert.md` 执行 `../external-expert/SKILL.md` 的任务
路由。代码、修复、测试和审查保持 LOCAL;只有竞争根因或高风险事实查证可路由到
CONSULT/VERIFY。外部假设必须回到本地证伪;咨询记录不能代替 2.5 或第 5 步独立
审查。
**用法**:`$cm-fix {specs路径} {代码项目路径} 缺陷描述(现象/报错/截图均可)`
两个路径校验通过后立即调用统一写入器记录 `run_start`;暂停/续跑沿用同一
`.cm-run.json`,本次缺陷闭环或观测闭环退出时写 `run_done`。不得直接拼 JSON。
## 项目角色路由
从代码项目根解析 `coder`、`tester`、`reviewer`(命令、参数和日志字段见
`runtime/workflow-routing.md`)。`coder` 只作为最小修复的请求路由元数据,`tester`
负责防护网/回归,`reviewer` 只描述独立审查候选通道;`declared-adapter` 必须记录为
未观测适配器,不能伪造调用或绕过本地执行与独立审查。resolver 返回非零或配置错误
时立即 `BLOCKED`,不得复现、修改或写入缺陷档案;配置不存在时保持当前默认行为。
`managed-adapter` 按 `runtime/model-efficiency.md` 返回文本建议并自动记录真实 usage;
复现、修复落盘、测试和独立审查仍由本地流程执行。
角色调用按 `runtime/model-efficiency.md` 只传当前缺陷的复现证据、根因范围、修复
diff、回归结果和对应规则;不重复投喂整仓、完整历史日志或其他缺陷上下文。失败输出
保留首个可行动错误与证据路径,防护网、独立审查和回归要求不因精简而变化。
修 bug 专用的**轻量闭环**——不走 N1–N8 全链(那是 feature 流程),也不许脱离工作流裸改(裸改没防护网没审查,修一个坏三个)。
**多缺陷输入**:先对全部缺陷做第 1-2 步(复现+定位),**按根因聚类**——同根缺陷合并为一次修复(多个失败测试、一次改动、档案互链),修复顺序按严重度排,不按输入顺序。不聚类的代价:三个现象一个根因跑三个闭环,且第一个修复落地后,后两个的复现步骤可能已失效(第 1 步卡死)。
**转交进场**(消费上游落盘物,不改上游流程):缺陷描述可附上游档案引用——`$cm-test` 的只读测试报告、`$cm-refactor` 档案的未修缺陷清单、N6 业务走查报告的偏差项、观测闭环的半份档案(按 slug 在 `fixes/` 检索)。带引用进场的缺陷,第 1 步**采信上游已有证据**(位置/现象/日志原文),仍须实际复现一次核实,但不从零摸排。
**$cm-ai 全局规则在本流程内同等生效**:灾难级才暂停、多方案自主决策留痕、状态落盘(node 写 `FIX`)、运行日志照记、独立审查按 `runtime/review.md` 执行。
**跨边界证据(条件触发)**:缺陷涉及跨进程/跨服务、异步队列或流、路由目标、缓存/状态不一致或时序偶现时,读取 `references/cross-boundary-debugging.md`;它只补定位证据,不新增入口、状态或完成标准。普通可复现缺陷不补表,仍走以下七步。
## 闭环七步(每个缺陷)
### 1. 复现(不能复现的 bug 不许修)
- 按描述实际操作/运行一次,拿到**失败证据**(报错原文、错误截图、错误返回值);**证据要用严格裁判**——宽容裁判会把坏产物蒙混成功(实跑:补丁类缺陷 GNU patch 的 fuzz 容错险些吞掉复现,换 git apply --check 才拿到硬证据)
- 复现不了 → 不猜着修,走**观测闭环**(偶现 bug 专用,两段式):
① 先判断是否命中跨边界证据条件;命中时按参考先列“边 → 预期证据 → 实际证据”,再在可疑路径加最小观测点(日志/埋点——观测点本身按最小改动+审查纪律入库,**观测点不是修复尝试**)
② 缺陷档案先落半份,状态记 `观测中`,写清"等什么证据(哪个日志出现什么内容)"
③ 本次命令正常收口退出,不挂着等——运行日志记 `run_done`,detail 写「观测中:等{什么证据}」;状态文件 state 复位,不留悬挂的 running
④ 证据到手后再次运行 `$cm-fix` 附上证据,**按 slug 定位 `fixes/` 下的半份档案**,从第 2 步定位续跑,档案续写、状态改 `修复中`,运行日志记 `resume`(detail 注证据摘要)
——**"我改了点东西你再试试"依然被禁止**
### 2. 定位(先找根因,不是找改哪行能让现象消失)
- 有业务地图(`docs/codebase-context/`)→ 先查 07 业务线路定位所在链路,08 修改影响映射表查波及面
- 无地图 → 从失败点向上追调用链,找到**根因层**(现象在 UI,根因可能在数据层)
- 命中跨边界证据条件 → 将调用链、每条边的最小证据、**最后正常边**与**首个失败边**写入缺陷档案;同时写“假设 → 支持证据 → 反证试验 → 结果”,一次只检验一个假设。日志与试验必须本地且脱敏,**不自动联网、不外发日志、不安装依赖、不重启服务、不清理缓存**。
- 输出一句话根因结论 + 波及面清单(本次修改会牵连哪些模块)——写进缺陷档案(第 7 步)
### 2.5 根因与修法对抗确认(条件触发;根因错误是本流程最贵的错误,必须在防护网之前拦)
任一**客观条件**命中才触发(简单缺陷零负担,判断依据同"门槛是客观项不是判断题"):波及面 ≥3 个模块 / 根因层与现象层不同层 / 观测闭环续跑的缺陷 / 拟走升级出口。
- 把根因结论 + 复现证据 + 波及面清单 + **拟采用修法(含放弃的备选)**交给新上下文的独立审查者;命中跨边界证据条件时一并交调用链、最后正常边、首个失败边和已完成的反证试验。提示词要义:「**假设这个根因判断是错的,找出更深层的解释;再审修法:治本还是治症?有没有更小的改动?会不会引入新耦合?**」。通道与降级规则同 N4
- **仅 1 轮**:推翻 → 回第 2 步重定位;分歧 → 交人裁决;通过 → 进第 3 步
- 凭证落 `{SPECS_DIR}/.reviews/fix-{slug}-cause-r1.md`——**命名带 `cause` 是有意的**:不落入第 5 步 `fix-{slug}-r*.md` 的匹配域,两个卡点各自独立,根因凭证不会误满足 diff 审查卡点
### 3. 防护网(先让 bug 有测试,再修)
- **写一个能复现此 bug 的失败测试**(红)——它是"修好了"的客观定义,也是永久回归资产;**红的原始输出落进档案**(第 5 步审查要核对红证据,从未红过的测试转绿是空话)
- 项目有存量测试 → 先跑一遍记录基线(修完对照,防止修 A 坏 B)
- 写不了自动化测试的形态(如纯视觉)→ 截图/录屏留"修前"证据
### 4. 修复(最小改动)
- 只改根因层,**禁止顺手重构**(N3 同款纪律:看不惯的代码记 LESSONS 待触发备忘,事后走 `$cm-refactor`,不在修 bug 时动)
- 修法有多个方案 → 自主决策选最优,`decision` 事件留痕
- **升级出口**:定位发现是设计缺陷/需要跨模块大改 → **停止硬修**,报告根因并建议走 `$cm-prd --change` 变更模式立项——bug 命令不承接架构手术。**已建资产不弃**:第 3 步的失败测试保留入库(它是缺陷的客观复现,新方案转绿即验收),档案状态记 `升级立项`,注明测试路径供立项后的流程直接接手
### 5. 审查(独立审查同 N4)
- 失败测试转绿 + 存量基线不退化后,按 `runtime/review.md` 审查本缺陷 diff(重点:根因是否真被修掉、有无只治症状、波及面有无遗漏)
- **防护网测试本身是审查对象**(实测最大问题类:测试是戏台):红的原因是否=该缺陷、断言测的是根因还是症状、有无安慰剂/前提共谋;**核对第 3 步落档的红证据**——没有红过的记录,测试可信度按不成立处理
- 所有缺陷零豁免;独立通道不可用时才记 `self-degraded`;≤2 轮上限同样生效
- `{slug}` 先规范成跨平台安全的 ASCII kebab;令 `REVIEW_FEATURE=fix-{slug}`、
`REVIEW_TASK=T-FIX-{slug}`。主执行者按真实 diff 写
`{SPECS_DIR}/.reviews/fix-{slug}-T-FIX-{slug}-a{attempt}-handoff.json`,格式与
`runtime/task-handoff.schema.json` 相同。先按 handoff 的完整 `changed_files` 运行
`cm-task-gate.py hash-implementation --project-root {CODE_PROJECT} --file ...`,把返回的
`implementation_sha256` 写入 handoff,再真跑:
```bash
python3 {CM_WORKFLOW_ROOT}/scripts/cm-task-gate.py check-n4 \
--handoff {HANDOFF_PATH} --reviews-dir {SPECS_DIR}/.reviews \
--feature fix-{slug} --task T-FIX-{slug} --project-root {CODE_PROJECT}
```
- 独立审查凭证严格落
`{SPECS_DIR}/.reviews/fix-{slug}-T-FIX-{slug}-r{attempt}.md`,包含当前 handoff
文件名和 SHA。审查完成后必须真跑下列命令;只有当前 attempt 的
`verdict: approved` 才能进入第 6 步:
```bash
python3 {CM_WORKFLOW_ROOT}/scripts/cm-task-gate.py check-n5 \
--handoff {HANDOFF_PATH} --reviews-dir {SPECS_DIR}/.reviews \
--feature fix-{slug} --task T-FIX-{slug} --project-root {CODE_PROJECT}
```
- `changes_requested` 后修改代码必须生成 attempt 2 handoff 并复审;第 2 轮仍有阻断项
写 `blocked` 并停止。文件存在、旧凭证或 `ls` 输出都不构成批准。
### 6. 回归(按波及面,不是只看 bug 消失)
- 跑第 3 步防护网测试(红→绿)+ 存量测试全量(对照基线)
- 按第 2 步波及面清单逐项走一遍关键流(同 B2 口径:波及面=回归范围)
- **回归失败的回路(显式分支,不许临场发挥)**:任何一项红 → 退回第 4 步重修,重修后**必须复审**且轮次并入第 5 步的 ≤2 轮总上限——上限耗尽仍打转 = 根因判断可疑,按升级出口处置,不许无限修-回归循环
### 7. 落盘(审计链闭合)
- **缺陷档案**:`{SPECS_DIR}/fixes/{YYYYMMDD}-{简短slug}.md`——现象 / 复现步骤 / 根因 / 修法(含放弃的方案)/ 波及面与回归结果 / 测试文件路径;命中跨边界证据条件时追加“证据链与假设”(调用链、边证据、最后正常边、首个失败边、反证结果)。这是缺陷知识库,同类 bug 再犯先查这里
- **METRICS.md 追加一行**:Feature 列写 `fix`,任务列写档案文件名,其余列同口径(轮次/拦截数/人工介入)
- 根因具普遍性(如"平台 API 返回结构变了")→ 追记 LESSONS.md([已结构化]/[仅记忆] 分级同 N5)
- Git 按有效 `policies.delivery`:diff 不 stage/commit;branch/draft-mr 提交
`fix: {一句话} (档案: fixes/xxx.md)`,审查摘要进 commit message(同 N4)
- 运行日志事件:`task_start`/`review`/`task_done`/`run_done` 照记,node 字段写 `FIX`
## 微缺陷快速通道(四个硬门槛全中才准走)
**门槛是客观项不是判断题**——"感觉这个 bug 很小"不构成理由,四条全中才走,任一不中走完整七步:
- [ ] 只改文案/样式/配置常量——**不新增、不修改任何条件分支与函数签名**
- [ ] 单文件且 diff ≤ 10 行
- [ ] 波及面为零(改动处无被其他模块引用的行为;有业务地图查 08 映射表核实)
- [ ] 有截图/文案前后对照可作验收证据
**快速通道可省**:第 3 步防护网测试、第 6 步全量回归(用前后对照截图代替)。
**不可省**:独立审查(凭证照落)、缺陷档案(显式标注 `快速通道`)、METRICS 行(Feature 列写 `fix-lite`)。
**快速通道的审查特化**:独立审查是该通道的主要质量防线,第一职责是复核四个客观门槛;diff 任一项不符或波及面存疑即打回完整七步。
> fix-lite 的占比进运行日志——快速通道被滥用(占比异常高/出现分支改动混入)时收紧门槛,数据说了算。
## 输出格式(每个缺陷收口时)
```text
🔧 缺陷闭环: {slug}
根因: {一句话}
修法: {一句话} | 放弃方案: {有则一句话,无则省}
防护网: 新增 {测试文件}(红→绿) · 存量基线 {N} 项无退化
审查: 独立审查({channel}) {通过/N轮N条} | 回归: 波及面 {N} 项通过
档案: fixes/{文件名} METRICS 已记
```
## 边界
- **不承接**:新功能(走 $cm-prd)、需求变更(走 $cm-prd --change)、架构级返工(升级出口交人立项)
- specs 目录没有 fixes/ 子目录时自动创建;没有 specs 目录的裸项目也可用:档案落代码项目 `docs/fixes/`,**审查凭证落 `docs/fixes/.reviews/`**(第 5 步卡点同样生效),METRICS 跳过
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!