eo-fix — Bug 修复
SkillDev toolsSingle entry point for the defect-fixing methodology: verbal bug reports get located and fixed directly; feedback fixes within the implement-test-review loop also go through this skill (in-loop branch, executed by the original impl worker). Triggers: fix a bug / there's a bug / it errored / behavior
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the eo-fix — Bug 修复 skill
What this skill tells your AI
The instructions your AI receives, as published by simpleeve/eo-skills in eo-fix/SKILL.md and read by ahel’s review.
三层按需付费:默认快路 ≈ 直接修 + 30 秒记账;只有要推翻一个「可能是有意的行为」时才取证;只有定位不了才深挖。对一个 typo,本 skill 的开销趋近于零——任何不触发的层都不存在。
核心原则
- 快路优先:明显缺陷(报错、崩溃、数据错、无争议逻辑错)不查任何文档,直接修
- 推翻行为前必取证:现象是「应该/不应该」类语义分歧时,先花几百 token 确认该行为不是有意设计——防止静默推翻已确认的决策
- 落点记账不豁免:修复必须落进体系(勾 AC / commit 前缀),这是 archive 归集、看板、retro 统计的输入
- 定位靠代码反查:症状 grep 源码 + git log 前缀追溯,精确且便宜;禁止全局 grep eo-doc 正文
- 深挖有门:升级必宣告、结束必还原
前置
必须能找到 .eo-project.json。同目录存在 .eo-project.local.json 时顶层字段覆盖合并(local 优先)。找不到 → 报错退出,提示运行 /eo-project-init。
工作流程
第一步:分诊(一眼定路)
| 现象特征 | 走 |
|---|---|
| 「坏了 / 报错 / 崩了 / 数据不对」——对错无需文档裁决 | 快路(第二步 → 第三步) |
| 「这里应该… / 为什么会… / 这个行为不对吧」——行为疑似有意实现、涉及业务规则或数值 | 取证路(第二步 → 第四步) |
| 描述弥散、无从下手 | 第二步定位;仍无果 → 深挖(第五步) |
同时按 ../eo-shared/lessons.md §1 消费 lessons——同类坑踩过的,「规则」节直接给答案或作假设先验。
第二步:定位(代码反查为主,~500-900 token)
- 锚定代码:有症状字符串(报错文案 / UI 文案)→ 直接 grep 源码,几乎一步中的;没有 →
.codegraph/索引存在则codegraph explore定位模块入口,不存在则按目录收敛直读源码 - 反查归属:
git log --oneline -n 20 -- <嫌疑文件>看 commit 前缀——[<change-id>](slug 或存量数字前缀)→ 相关 change 直达;fix:/ui:→ 直改历史(无书面期望);无前缀 → 存量代码 - 需要书面期望时只读该 change 的 frontmatter + §2 AC,不通读
辅路(代码反查不灵时才用):扫 eo-doc/changes/INDEX.md——活跃 change 置顶且通常只有 0-3 个,先看它们(刚做完的最容易坏);不中再按关键词扫 archived 区。候选 >3 或全无匹配 → 追问用户。
第三步:快路修复
最小变更修复 → 用户给的复现步骤转成回归验证跑通 → 跳到第六步落点记账。中途发现行为其实可能是有意的 → 转第四步。修复代码注释零溯源:change/AC/finding 标记与修复辩护不进注释(项目级完整纪律见 eo-doc/agent-handbook/comments.md,如已启用)。
复现与回归都取最低成本层:修前先在该层复现失败(这是根因判断的依据,也是「改完看起来对了」之外唯一的证据),修后在同层验通过。层的选法——纯逻辑用单测 / node -e 等价复刻(秒级),接口契约用一次请求,确属集成 / UI 态才起环境(环境纪律见 ../eo-shared/ac-spec.md)。不要每改一行就重新 build + 起环境。
第四步:取证路(仅语义分歧)
证据瀑布——期望行为不是单一锚点,按可得性降级取证:
| 优先 | 证据 | 作用 |
|---|---|---|
| 1 | 用户当下的口述 | 最高权威,永远存在 |
| 2 | 相关 change 的 §2 AC(若有) | 最优书面期望 |
| 3 | eo-doc/state/ 现状篇(若 state.enabled 启用) | 意图佐证:行为被现状篇记为规则 = 曾被认为正常(state 是代码派生快照,只能佐证不能裁决);篇≠码 → 文档陈旧,提示可跑 /eo-doc-manager sync |
| 4 | <project_root>/decisions/ 与 brainstorm/ 的记录 | 意图佐证:行为被钉为决策 = 曾被认为正常(只能佐证意图,不能裁决代码对错) |
| 5 | git 归属(commit 前缀) | 追溯行为来源 |
判定与动作:
| 取证结果 | 动作 |
|---|---|
| 行为查无出处(无 AC 声明、decisions 无记载)且按口述明显是缺陷 | 按快路修(第三步) |
| 行为是有意设计(AC 声明过 / decisions 钉为规则 / change 意图明确) | 停手告知:「这是 特意做的(AC-x)」;用户仍要改 → 纯外观 / 文案类按 trivial 直改,并顺手就地精化对应 AC 文本(意图不变);涉及功能语义 / 交互逻辑 → 转 /eo-change(带上取证结论) |
| AC 写漏且 change 未 archived | 确认后先补 §2/§3 再修(Update preserves context) |
| 记录与代码矛盾 | 以代码为准重判 |
修复范围守界:预估改动超出 trivial 量级(需方案权衡、动对外接口,判据见 ../eo-shared/granularity.md §2)→ 停手建议开 change,不硬修。
第五步:深挖模式(自动升级)
触发即向用户宣告:「常规定位失败,进入深挖模式:会临时插桩/加日志/git bisect,结束后还原现场。」
- 读 references/investigation.md,按四阶段执行(固定复现 → 假设清单 → 二分排除 → 验证还原)
- 调查记录写
tmp/eo/fix/<date>-<slug>.md(可丢弃工件) - 根因确认后回第一步分诊定路,再走修复
- 根因有普适教训 → 提议
/eo-project-record沉淀
第六步:落点记账(任何路都不豁免,~30 秒)
- 有相关活跃 change → 勾选涉及的 TODO/AC(人工项不代勾,勾选权归用户;被本次改动弄脏的已勾项按 ../eo-shared/ac-spec.md「勾变脏即取消」处理),commit 带
[<change-id>]前缀;改动影响其 acceptance.md 人工项的入口/行为 → 按 ../eo-shared/acceptance.md「失效与重置」取消该项勾选并注明原因;改动影响其 evidence.md 的入口/行为/截图事实 → 按 ../eo-shared/evidence.md「刷新与失效」同步刷新对应段;顺带更新其 frontmatter 的brief(写法见 ../eo-shared/summary.md;写不出留空) - 无 → 直改落地:commit 带
fix:前缀(见 ../eo-shared/conventions.md) state.enabled且eo-doc/.sync-cursor已存在时才顺带报 sync 游标落后量(last_commit..HEADcommit 数):落后 >10 个 commit → 建议顺手跑一次/eo-doc-manager sync(直改提交会被 sync 按路径增量收割)。未启用 state 或游标未建立(尚未首次同步)→ 不报,零打扰
第七步:收尾速报
修复完成:<一句话根因>
- 改动:<file:line 级别的简述>
- 验证:<复现步骤回归结果 / AC 核对结果>
- 落点:计入 <change-id> / 直改(fix: commit <hash>)
- (取证时)行为出处:<AC-x / decisions 记载 / 查无出处>
- (深挖时)调查记录:tmp/eo/fix/<file>;建议沉淀 lesson:<是/否>
循环内分支(implement-test-review 反馈修复)
适用:test.md 有未决失败项,review.md 有 open P0/P1,或 acceptance.md 有「不通过」项。由 /eo-loop 派发到原 impl worker 执行(worker 复用纪律不变——本分支只是换方法论,不换人),或循环会话内直接调用。status 为 reviewed 时(产出阻塞结果的 skill 正常已按回退边置回;没置则此刻补)→ 先置回 implementing。
与口喷路径的差异只有两条:免定位(反馈报告即定位输入,跳过第二步);带核销职责(第 1/5 步与交接速报)。分诊三路由原样生效——明显缺陷走快路;finding 与已确认 AC / 已钉决策冲突(「这个行为本来就不对」类)走取证路,防静默推翻;定位不了或链路连环失败走深挖,链路类缺陷用「全链审查」变体(见 references/investigation.md)。
- 熔断检查(修复动手前)
- 凭报告与对话机械可判:同一 change 修复轮次 ≥3,或各轮失败触发位置互不相同(打地鼠信号)→ 停,不开始修复,用户三选一: a) 豁免一轮:放行本轮,change.md 末尾记「熔断豁免:<日期>」 b) 卡点检查:走下方子流程,按根因结论定出口 c) 回炉:转 /eo-change 回炉子流程(方案实质修订 + 重新确认)
- 读取反馈:同会话反馈已在上下文 → 不重读报告文件;跨会话 → 只读报告的未决清单 + 结论,按 open 项定点读详情,不通读全文。根因为
test-asset的 finding 不由本分支消费,交/eo-test;本分支只处理业务实现项 - 分诊定路 + 修复:按 P0 > P1 > P2 逐一过第一步分诊表定路,各走快路 / 取证 / 深挖;修复代码注释零溯源(纪律同上)
- 双向取证,取最低成本层:每个缺陷先复现失败、修后在同层验通过——「改完看起来对了」不算证据;层选法同主流程第三步
- 涉及的自动 AC 就地重验;被本次修复弄脏的已勾 AC 按 ../eo-shared/ac-spec.md「勾变脏即取消」处理;修复改变了人工项的入口/行为 → 按 ../eo-shared/acceptance.md「失效与重置」更新对应验收项;修复改变了入口/行为/截图事实 → 按 ../eo-shared/evidence.md「刷新与失效」同步刷新 evidence.md 对应段
- 回写未决清单:每个业务实现缺陷修复并同层验通过后,把对应报告清单行置
fixed并填修复 commit——verified由复审方核销,本分支不写 - 修复提交带
[<change-id>]前缀 - 交接:回原复审方核销(增量,不重开全文)。交付速报列:
反馈来源、修复 commit、受影响 AC、局部验证、下一节点 - 修复不开新 change;发现根源是方案/需求问题 → 停下告知用户,转 /eo-change 回炉子流程(实质修订 + 重新确认;意图不变的口径精化不必回炉,就地补 AC 即可)
卡点检查子流程(熔断三选一选 b 时执行)
spawn 一个新鲜上下文 subagent(执行者自述不作数——修了 3 轮的 agent 是判断自己为何修不好的最差人选),输入按 manifest 给,禁止默认通读报告全史:
- change.md 全文
- test.md / review.md 的未决清单 + 结论 + open/fixed 项定点详情
- change-review.md 当前结论、acceptance.md 不通过项、implement.md 偏差记录(各自存在时)
[<change-id>]提交列表与涉及文件的 scoped diff、本 change 相关的未提交脏 diff
产出五分类根因 + 建议出口:
| 根因 | 出口 |
|---|---|
| change 方案/架构不合理 | 转 /eo-change 回炉子流程 |
| 链路失败语义残缺(向前写链,恢复面的洞逐次暴露) | 走深挖「全链审查」变体:枚举链上全部可死点 + 逐点恢复证明矩阵,按矩阵批量修 |
| AC 口径漂移(各轮按不同理解打回) | 回 /eo-change 钉死口径(意图不变的精化,不必回炉) |
| 纯实施质量问题 | 方向没错,建议豁免一轮继续修 |
| 测试基建/环境假失败 | 修基建;报告未决清单注明假失败供用户裁决 |
结论一行写入 change.md 末尾:卡点检查:<根因>,<日期>。失败关闭:subagent 起不了(槽位/工具不可用)→ 不得用执行者自述替代,记「卡点检查未执行」,用户在「稍后重试 / 直接回炉 / 单轮豁免」中裁决。
关键约束
| 约束 | 说明 |
|---|---|
| 明显缺陷不查文档 | 快路不做任何取证,速度对齐「直接修」 |
| 推翻行为前必取证 | 语义分歧不取证就改代码 = 可能静默推翻已确认决策,禁止 |
| 落点记账不豁免 | 三层里唯一的必做项 |
| 验证取最低成本层 | 能复现该缺陷的最便宜的层就是对的层(纯逻辑 → node -e / 单测,秒级);起环境是最后手段,不是默认 |
| 定位禁全局 grep eo-doc | 代码反查为主,INDEX 辅路 |
| 修复范围守界 | 超 trivial 量级 / 需方案权衡 → 转 change,不硬修 |
| 深挖必宣告、必还原 | 插桩/日志/bisect 结束后全部还原 |
| 需求变更不伪装成 fix | 功能语义 / 交互逻辑的期望变更就是 /eo-change 的事,哪怕改动很小;纯外观 / 样式 / 文案的期望变更不算——按 granularity §2 trivial 直改(前缀选择见 conventions §2.5) |
| 注释纪律 | 一切流程溯源标注(change 编号/slug、TODO/AC、finding P0-x/P1-x、FAIL-x)严禁进代码注释(溯源走 commit 前缀);不写「为何正确」的辩护;提交前对新增注释自检一眼;存量过时/误导注释顺手清理。项目启用 eo-doc/agent-handbook/comments.md 时以该篇为准 |
| 循环内修复归本 skill | test/review/acceptance 反馈的修复走循环内分支(原 impl worker 执行);eo-implement 无独立修复模式 |
典型场景
场景 1 · 明显缺陷(快路,全程不碰 eo-doc):「导出报错了」→ grep 报错文案锁定文件 → 修 → 回归验证 → git log 见 [batch-export] 且该 change 活跃 → 勾 AC、[batch-export] 前缀提交。
场景 2 · 有意设计被误报(取证路的价值时刻):「列表怎么把已归档的也显示出来了,去掉」→ 反查归属 [list-archive-view] → 该 change 的 AC-3 白纸黑字「归档项默认可见」→ 停手:「这是 list-archive-view 特意做的,要推翻它就是需求变更」→ 用户确认后转 /eo-change。没有这一步,这个已确认决策就被静默推翻了。
场景 3 · 需求变更伪装:「积分过期改成 90 天了」→ decisions 记载 30 天规则、代码一致——有意设计 → 转 /eo-change。
场景 4 · 难缠 bug:「偶发卡死,复现不稳定」→ 定位无果 → 宣告深挖 → 四阶段 → 根因回分诊 → 修复 + 还原 + 建议沉淀 lesson。
场景 5 · 循环内打地鼠(全链审查):记账链 Test 连续 FAIL 且各轮触发点互不相同(终局等待面 / 锁权限 / 重试误判已入账)→ loop 打地鼠信号命中,用户选全链审查 → 原 impl worker 走深挖链路变体:枚举链上全部可死点,配不出恢复证明的点 = 洞 → 按死点矩阵批量修 → 台账置 fixed,回原 tester 复验。
Signals
- GitHub stars
- 31
- Forks
- 6
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
eo-fix- Source
- github.com/simpleeve/eo-skills