关于 fable-recover
fable-recover 是面向反复失败、结果矛盾或修改看似无效时的诊断技能。它要求 Agent 暂停产品代码修改,通过针对性探查区分可能原因,再依据新证据提出一次范围明确的修复。
主要功能
- 01诊断期间暂停产品代码修改
- 02构建最小可复现故障
- 03按可区分的预测排列原因
- 04探查测试框架、环境和执行路径
- 05将一次有限修复关联到预期证据
适用场景
- 01调查反复出现的测试失败
- 02追踪不受源码修改影响的行为
- 03比较运行时与 CI 故障
- 04诊断间歇性或特定数据问题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ immamdouhaboammar/ get-fable --skill fable-recover安装后在 Claude Code 中输入/fable-recover确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
skill.package.jsonagents/openai.yamlevals/scenarios.jsonexamples/recovering-stale-test-cache.mdreferences/attribution-ladder.mddiagnostic-falsification-playbook.mdtemplates/recovery-diagnosis.template.md详细介绍
Fable Recover
别再把变更耗在失败的假设上。再次修改代码之前,先重建对因果关系的确信。
使命
当 Agent 最容易变得不理性、徒增成本时,恢复流程便会启动:同一任务已失败不止一次、输出与预期相矛盾,或修改似乎毫无效果。
目标不是“换个方法试试”,而是解释此前的尝试为何失败,证伪相互竞争的原因,并依据新证据提出一次有理有据的修复。
何时启动
- 同一命令、测试或行为在两次实质上相似的实现尝试后仍然失败;
- 输出似乎过时,或没有反映已知的源代码更改;
- 测试与运行时结果不一致;
- 证据与关键假设相矛盾;
- 失败时而出现、时而消失,或取决于时间、环境;
- Agent 准备在没有新诊断信息的情况下重复执行命令或应用补丁。
何时不要启动
- 首次失败是当前编辑引入的简单语法或类型错误;
- 只是尚不清楚架构,且没有重复失败(
fable-discover); - 正确观察到 TDD 中预期的 RED 阶段;
- 范围明确的审查发现已有显而易见、界定清楚的修复方法。
失败分类
先对证据进行分类,而不是先看代码。
| 类别 | 典型信号 | 首要探查 |
|---|---|---|
| 测试框架 | 未到达断言、夹具/模拟/设置错误 | 验证测试路径和夹具 |
| 环境 | 因本地/CI/操作系统/环境而异 | 版本、环境变量、当前工作目录、权限 |
| 构建产物/缓存 | 源代码更改未反映出来 | 入口点、构建时间戳、缓存、dist |
| 执行路径 | 编辑的代码从未执行 | 跟踪/插桩/注册情况 |
| 依赖/版本 | API/运行时语义异常 | 锁文件、解析出的版本、官方来源 |
| 数据/状态 | 只有部分夹具/账户/订单失败 | 最小失败状态、持久化边界 |
| 并发/时序 | 间歇性/与顺序有关 | 确定性协调、共享状态 |
| 产品逻辑 | 已验证测试框架/路径,断言仍持续出错 | 隔离算法/分支 |
| 不变量/设计 | 局部修复会让故障转移到别处 | 找出被违反的跨组件规则 |
在排除成本更低的外部原因之前,不要直接归因于产品逻辑。
恢复流程
阶段 1 — 暂停修改
诊断发生变化之前,不要再编辑生产代码。保留失败状态并收集准确证据。
记录:
- 命令/操作;
- 准确的错误/输出;
- 工作区/提交/修改代次;
- 已经尝试过的操作及其差异;
- 预期观察结果。
阶段 2 — 最小化复现
找出最小且可靠的复现方式。如果故障不稳定,记录随机种子/顺序/时间/环境,并在再次修复之前先解决确定性问题。
阶段 3 — 建立假设队列
列出 2-5 个合理原因,并按以下标准排序:
- 能否解释所有已观察到的证据;
- 根据近期更改判断的可能性;
- 证伪的成本/风险。
每个假设都必须预测一项可用于区分它与其他假设的观察结果。
反例:“可能是缓存。”
正例:“CLI 执行的是过时的 dist/cli.js;若属实,源文件时间戳会晚于 dist,直接调用源文件会显示新的行为。”
阶段 4 — 沿归因阶梯排查
优先使用成本最低、最能区分假设的探查方式:
- 测试框架 — 测试/探查是否使用真实输入到达预期断言/路径?
- 环境/构建产物 — 分支、当前工作目录、环境、版本、构建、缓存、进程是否正确?
- 执行路径 — 编辑的代码是否确实被执行?注册的是哪个实现?
- 数据/依赖 — 输入/版本/状态是否与假设不同?
- 产品逻辑 — 证明以上各项无误后,隔离出错的分支/算法。
- 不变量/设计 — 如果局部逻辑各自看来合理,但整个系统仍有错误,找出被违反的系统契约。
这套阶梯是指引,不是仪式。只有现有证据已经证实时,才可跳过某一层。
阶段 5 — 观察不充分时进行插桩或二分
使用范围有限的临时诊断、二分查找/二分排查、一次切换一个变量,或比较已知正常/异常的状态。
每次只改变一个诊断维度,以便解读结果。
阶段 6 — 证伪,而非累积猜测
每次探查后:
- 否定假设;
- 增强假设;
- 或调整队列。
不要让已被证据推翻的解释继续以“可能仍有关联”的形式存在。
阶段 7 — 形成修正后的诊断
有效的诊断应解释:
- 为何出现观察到的故障;
- 为何之前的尝试未能修复问题;
- 有哪些证据能将其与其他可能性区分开;
- 最小限度的修复需要改变什么,才能改变结果。
阶段 8 — 执行一项范围明确的修复
返回 fable-execute 或 fable-tdd,执行一项修复并验证一项预期结果。如果诊断揭示了架构方面的不确定性,则转到 plan/discover。
决策规则
- 除非明确的环境/状态变量发生变化,或重跑是为了明确测量非确定性,否则绝不重复执行未作更改且已失败的命令。
- 记录证据前,不要动辄删除缓存/构建产物;破坏性清理可能会抹去证明问题由陈旧状态导致的线索。
- 如果源代码变更没有产生运行时效果,应先确认实际执行的产物/路径,再次编辑逻辑前不要跳过这一步。
- 如果故障仅在 CI 中出现,应先比较环境/版本/并行度;不要假设 CI“存在随机性”。
- 如果故障与特定数据有关,应先缩小导致故障的数据/状态范围,再进行大规模重构。
- 如果出现依赖项/版本方面的假设,将外部语义验证交给
fable-research。 - 如果本地补丁导致故障在组件之间转移,应怀疑存在共同的不变量/设计问题,并返回
fable-plan。 - 类似的失败修复会累积为连续失败;表面的语法修改不会重置诊断责任。
不变量
- 在形成修正后的诊断之前,恢复过程仅限诊断/只读操作。
- 每次新的探查都应能区分不同假设。
- 被证据推翻的假设必须移除。
- 诊断插桩是临时的,修复后应清理。
- 最终修复的范围明确,并与可预测的可观察结果相关联。
恢复过程自身的失败类型
盲目清理
重置缓存/构建产物后问题消失,但根因不明。如果没有获得因果证据,应记录为未解决。
假设泛滥
列出一长串可能性,却没有用于区分的探查。对它们排序,并测试成本最低的区分方法。
诊断期间修改
Agent 在仍未确定原因时修改产品,导致故障状态失效。在安全的情况下,撤销/恢复诊断基线,然后重新收集证据。
确认偏误
只运行支持首个理论的探查。至少为最主要的假设添加一项证伪测试。
非最小复现
庞大的套件/系统引入了过多混杂因素。解读结果前,先隔离出更小的路径。
反模式
- 基于相同因果理论打第三/第四个补丁;
- 未记录前后证据就“清除缓存看看”;
- 一直重跑不稳定的命令,直到通过;
- 未比较环境就归咎于环境;
- 到处添加大量日志;
- 一次改变多个诊断变量;
- 保留已被证据推翻的假设;
- 解决了症状,却无法解释之前为何失败。
恢复信息包
Failure/reproduction:
Attempts already made:
Hypothesis queue:
Probe → observation → hypothesis effect:
Revised diagnosis:
Why prior attempts failed:
Bounded repair:
Expected proof after repair:
Residual uncertainty:
Next Skill:
完成标准
仅在满足以下条件时,恢复才算完成:
- 已有足够可靠的复现方法,或已明确描述非确定性;
- 已通过证据证伪主要的替代原因;
- 诊断与已失败的假设/尝试有实质区别;
- 拟议的修复范围明确,且能预测具体的观察变化;
- 执行可以继续,而无需再次盲目重试。
深入资源
- 深入指南:
references/diagnostic-falsification-playbook.md - 现有阶梯:
references/attribution-ladder.md - 示例:
examples/recovering-stale-test-cache.md