其他
调试修复落地后撰写工程复盘:记录根因、修复、验证与漏网原因…
在调试已产出并验证修复后、关闭工单前,为工程师受众撰写包含根因、机制、修复、验证和漏网原因的正式复盘记录。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 48/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 55/100 ×0.15
适用场景
调试修复落地后撰写工程复盘:记录根因、修通用
解决思路
- 在调试会话已经明确落地修复后、关闭 ticket 前主动提出起草 post-mortem;收到 /post-mortem 触发,或用户说 write the post-mortem/postmortem/RCA/root cause analysis、document this fix、write up the root cause、close out this bug with a writeup,或交来已修复且验证的 bug 要求写文档时执行。
- 起草前逐一确认四项必需输入,缺一不可:存在可靠复现(不是“有时发生”,而是下一个人可运行的确定性或高概率 flake 复现);根因已知(机制已识别,不是假设);修复已定位(PR / commit / branch pointer);修复已验证(原始复现现在通过,客户工作负载/失败测试现在成功)。若有缺失,列出缺失项并停止,不写任何一行。
- 若来自 debug-mantra,使用其步骤 1–4 的产出,尤其用步骤 4 的 breadcrumb ledger 作为原始素材;这些必需输入直接对应 debug-mantra 步骤 1–4。
- 按固定顺序组织内容块;Summary、Root cause、Fix、Validation 为强制项,其余为条件项但通常存在。
- Summary(强制):用一段话写清用户/工作负载层面什么坏了、哪一句话修复了什么,并附 JIRA key、PR number、owner;让只读这段的读者得到正确答案。
- Symptom:写实际观察到的现象,包括测试输出、错误消息、日志行、性能数字、客户报告;保留具体标识符,不要转述失败模式。
- Root cause(强制):写真实 bug 机制;欢迎且预期使用代码标识符,如函数名、文件路径、结构体字段、分支条件、引入问题变更的 commit SHA;端到端走完因果链;这是最昂贵也最能证明复盘价值的 section,未来你会依赖它。
- Why it produced the symptom:把根因连接到症状;通常不明显,例如 bug 在 `tadaLaunchPrepare` 但可见失败是数小时后客户训练 run 挂起;走完整链条,让只知症状的读者不必重新推导就能连回原因。
- Fix(强制):写改了什么,以及为什么该变更解决根因而非隐藏症状;链接 PR / commit;若此前修复尝试只是掩盖症状,点名该尝试并解释它错在哪,这段历史也是原因的一部分。
- How it was found:简短写调试路径,包括什么复现使它变确定、什么工具破解它(debugger、source tracing、knob enumeration、in-code instrumentation,即 debug-mantra 步骤 2 的级联)、尝试并拒绝的假设及每个一行拒绝理由(从 breadcrumb ledger 拉取)、确认原因的那个单一实验;面向下一个调试者,使其可学习。
- Why it slipped through:写什么允许 bug 到达 branch / release / customer;从真实原因中选择:CI gap(没有测试覆盖此路径/配置)、latent code(编写时正确,后被不同文件的后续变更破坏)、workload gap(此前没有真实工作负载到达此代码路径)、incomplete prior fix(防御检查隐藏症状,根因未动)、review miss(变更可评审,但含义未被发现);若诚实答案是“没有好理由——我们本应捕获”,就这么写;保持 blameless,描述缺口而非人。
- Validation(强制):写如何知道修复有效,要具体:原始失败测试现在通过(测试名、链接)、客户工作负载现在完成(工作负载标识、运行链接)、性能回归解决(前后数字)、stress / soak / fuzz 运行干净完成(时长、规模)、其他受影响配置/工作负载也已测试;若只验证一个配置,明确写出来,例如 “validated on Llama-2-70B / 8 GPUs / DeepSpeed; not retested on other workloads.”,不要暗示比实际更广的覆盖。
- Action items / follow-ups:写修复 PR 之外的具体下一步;每项包含 what + owner + tracking artifact,例如:在 <seam> 添加回归测试(Owner,测试名);重构以防一类 bug(Owner,ticket);关闭 CI gap:<new check>(Owner,PR);更新 doc / runbook(Owner,link);为注意到的相邻问题开相关 ticket(Owner,key);若没有行动项,写 “None — the fix is sufficient and no class-of-bug follow-up is warranted.”,不要为显得全面而编造行动项。
- 采用工程到工程 tone,区别于 management-talk:代码标识符是一等公民,保留 `tadaLaunchPrepare`、`tada/prim.h::syncWaitPeer`、`scratchBuf`、commit SHAs、line numbers,让未来工程师能 grep 回变更。
- 机制优先于叙事:走实际因果链,不要软化成“同步问题”;明确说哪个函数在哪个 gate 下跳过了哪个事件。
- 使用主动语态、具体主语、短段落。
- 不要含糊:删除 “We believe” / “appears to” / “may have”;要么陈述事实,要么不写。
- 保持 blameless:描述 bug、缺口、修复;绝不写 “X should have caught this”;CI gap 是失败模式,不是人。
- 不做倡导:post-mortem 记录发生了什么和下一步;若要主张重构,写单独 proposal,并从 action items 链接过去。
- 按输出流程执行:先确认四项必需输入全部满足,否则列出并停止,不起草。
- 确认发布位置;默认源 ticket 的 JIRA comment;其他有效目标包括 PR description、`docs/postmortems/<ticket>.md`、internal wiki page;形态相同,只有包装变化。
- 以单个 chat block 产出草稿。
- 发布前取得 sign-off;若发回 JIRA,展示精确 ADF payload,等待明确 “post it” / “go ahead” / “yes”,然后执行 `POST /rest/api/3/issue/<KEY>/comment`;仅打印输出无需批准。
- 提供 management-talk handoff:问 “Want a leadership-flavored version? I can hand this to `management-talk`.”,但不要自动执行。
- 遵守硬规则:没有四项必需输入拒绝起草;假设的 post-mortem 比没有更糟。
- 绝不编造 root cause、owner、validation runs 或 action items;若某 section 的事实不在,询问,不要用看似合理的文字填补缺口。
- 绝不在工程记录中剥离 code identifiers;它们是索引;领导版重构是 management-talk 的职责,不是你的。
- 保持 blameless。
- 诚实说明验证覆盖;若只测一个配置,明说;暗示更广覆盖是滋生重复回归的失败模式。
- 发布到 JIRA 前必须获得 sign-off;仅打印输出无需批准;绝不要从此技能发布到非 JIRA 目的地。
- 一次迭代正常,三次是异味;若用户第三轮还在修订,问具体哪个 section 错,不要继续盲目微调。
- 质量检查参考 worked example:命名所有代码标识符;端到端走因果链,让读者能 grep 到问题行;点名先前修复尝试及其错误;记录确认根因的确切实验(如 `numStreams = 2` 使其消失);诚实说明验证覆盖(“not retested on other model sizes” 是信息而非漏洞);行动项有 owner 和 tracking artifact。
适用边界 · 注意事项
- Bug 尚未修复,或修复尚未验证:假设的 post-mortem 会误导;拒绝并告诉用户缺什么。
- 客户可见故障/事故:需要单独 incident report(时间线、影响范围、on-call 分页历史、沟通);本技能只覆盖 bug-fix,生产前先标记并确认。
- 琐碎修复(typo、显而易见的一行改动):PR description 就是记录;不要制造仪式。