工作流详解

诊断

把一个坏掉的行为从"复现"带到"根因有证据",并在你授权后完成修复,同时留下防回归的测试。

engineering-flow:diagnose只读 → 授权修复

Codex CLI

$engineering-flow:diagnose

Claude Code

/engineering-flow:diagnose

为什么需要这个工作流

修 bug 最常见的失败是边猜边改:没复现就断定原因,改完也说不清有没有治好。Diagnose 强制证据先行——先复现、再定位、后修复——并且在你授权修复之前完全只读。授权之后,第一次写入只能是回归测试,必须亲眼看到它失败,才允许改生产代码。

流程逐阶段拆解

下面每一条规则都取自源仓库里的工作流定义——这就是智能体真正被要求做的事。

  1. 01

    锁定症状与信号

    先说清哪里不对,再搭一个最快能看到它发生的信号。

    • 写清预期行为与实际行为的差别。
    • 读适用的指令和文档,以及相关实现、测试、调用方和近期改动。
    • 为这个确切症状搭最快的可用信号:聚焦测试、命令/请求、回放、最小复现程序、压力循环或性能测量。
    • 把信号调到更快、更确定、可以无人值守重复运行。
    • 现场只勘察一次并复用证据。确实无法自动复现时,如实说明尝试过什么并给出置信度,而不是猜。
  2. 02

    最小化并定位归属

    先亲眼看到失败,再逐层剥离,找到拥有这条规则的模块。

    • 先观察到失败,再下结论。
    • 在保持失败的前提下,删掉输入、步骤、依赖和调用方。
    • 跨边界跟踪数据流和控制流,并检查兄弟入口。
    • 定位到拥有被破坏不变式的那个模块。
    • 用一小组排好序的可证伪假设,每次只做一个能区分它们的观察。
    • 你否定这个诊断结论时,它保持只读、丢掉该结论,去找新的区分证据——不需要重新调用。
  3. 03

    授权后修复人工关卡

    你说"可以修"之前完全只读;之后先红后绿,没有例外。

    • 初始请求里就写了"修复",等于已经授予修复权限;否则先给出根因、证据、修复边界和剩余不确定性,然后暂停。
    • 之后同一任务里的一句"可以修了"同样授权,不需要另外调用 Develop。
    • 拿到授权后,第一次写入只能改回归测试;立刻运行它,观察到非零的失败结果,才允许动生产代码。
    • 之前的诊断探针、已经通过的既有测试套件、失败的编辑工具,都不能替代这次"红"。
    • 在拥有该规则的边界上做最小且清晰的改动,观察聚焦的"绿",并验证受影响的兄弟调用方。
    • 确实不存在正确的回归缝隙时,如实报告这个限制,而不是加一个测不到问题的测试。
    • 修复需要未定义的产品行为、或者会实质扩大范围时,先对齐这个增量并暂停等待批准。
  4. 04

    围绕根因加固

    只防住同一类回归,不多做。

    • 边界类缺陷只补能防住同类回归的相邻用例:below/at/above、before/at/after、首次/重复/并发、允许/拒绝。
    • 期望值从需求推导,不自己发明产品行为。
    • 只有根因确实暴露出规则分散、隐藏副作用、重复变化、状态转换分散或不稳定依赖时,才改进设计。
    • 不把一次聚焦修复变成大重构,也不在没有压力时套用设计模式。
  5. 05

    完成

    复验原始症状,并说清还有什么不确定。

    • 删掉临时诊断代码。
    • 复验回归信号、原始症状、相关兄弟路径,必要时加一个更广的检查;不重复跑没有变化的证据。
    • 对齐受影响的验收行为和权威文档。
    • 报告根因、证据、已授权的修复、加固内容和剩余不确定性。
    • 之后你指出同一缺陷还有遗漏部分时,直接重新进入修复与验证,不重跑整套诊断和审批。

不可绕过的规则

授权前只读

没有明确的修复授权就不动任何文件。你否定结论时它保持只读,回去找新证据。

先红后绿

授权后的第一次写入是回归测试,并且必须观察到它失败。任何探针或变通都绕不过这道关卡。

逐假设证伪

每次观察都用来区分排好序的假设,绝不同时改变两个变量。

如实说限制

确实没有正确的回归缝隙时,如实报告限制,而不是交一个测不到缺陷的测试。

一次真实调用

从你发出的 token 到你拿回的证据,这次对话实际长什么样。

$engineering-flow:diagnose 修复 calculateRenewalDate 在 1 月 31 日加一个月后进入 3 月的问题。先复现,定位根因,留下能检测该回归的测试。
  1. 智能体

    写清预期(2 月 28/29 日)与实际(3 月 3 日),并搭出最小可靠复现。

  2. 智能体

    逐层剥离,把根因定位到日期工具模块里的月末溢出,而不是报告症状的那个调用方。

  3. 智能体

    初始请求已经说了"修复",修复权限已经具备:先只写回归测试,并展示它失败。

  4. 智能体

    在日期工具模块内做最小修复,观察聚焦测试变绿,并检查同模块的兄弟调用方。

  5. 智能体

    报告根因、证据、修复了什么、加固了什么,以及还有什么不确定。

什么时候用它

  • bug、回归、间歇性故障、输出错误,或者实测到的性能下降。
  • 想在任何人动代码之前,拿到有证据支持的根因。
  • 修复必须留下一个能捕捉该回归的测试。
  • 上次修复没治住,需要知道为什么。

什么时候改用别的

你的情况改用
没有东西坏掉,你要的是新行为Develop
想对某个 diff 或分支拿一份问题报告Review
真正的问题是架构本身Code Design

常见问题

我只想知道原因,不想它改代码,可以吗?

可以,这就是默认行为。不带修复意图地调用,它会保持只读,给出根因、证据、修复边界和不确定性,然后停下来等你授权。

它给的根因我不认可怎么办?

直接说不对。它会保持只读,丢掉这个结论,去寻找新的区分证据——你不需要重新调用工作流。

为什么一定要先看到测试失败?

一个从没被观察到失败的测试,无法证明它真的能发现这个缺陷。先红后绿是硬关卡,之前的调试探针不能顶替。

如果这个 bug 写不了测试呢?

它会如实报告"没有正确的回归缝隙",而不是加一个无论有没有 bug 都会通过的测试。