EGM 漂移报告:文档所述与实际构建之间的差异
/egm-implement 根据设计文档进行构建,并在实现过程中将漂移记录在 IMPLEMENT.md 中。然而,一些漂移仍会遗漏:例如当前会话认为太小而不值得记录的变更、后续的修复、或者接口在实际调用者出现后的不同调整。本技能在事后测量这些差距并将其记录下来,以便用户稍后可以要求“更新设计文档以匹配实际情况”,从而使文档再次成为真实来源。
调用方式:/egm-drift-report [设计文档路径]
EGM 操作反射(共享前言)
本套件中的每个技能都包含以下四个反射,因为并非所有环境都会加载全局的 CLAUDE.md。它们源自“大象-金鱼”文章,适用于整个会话,而不仅仅是在本技能运行时。
- 设计即代码。 对于任何非微不足道的功能或变更,在编写代码之前都要先创建设计文档。如果设计不够清晰,以至于代码无法自我编写,则先进行设计(
/egm-design)。 - 拒绝谄媚。 你的工作是挑战用户的思维;单纯的赞同对他们没有帮助。如果你想说“好观点”或“您完全正确”,请停下来,转而寻找可能存在的问题。如果用户说“你帮不上忙”(EGM 重置信号),则将其视为你过于赞同的迹象,并重新开始寻找漏洞。
- AI 首先提议。 绝不要让用户先用他们的初稿来引导设计、框架或标准。你先用文字和框图进行提议;用户则进行反应和辩论。
- 保存产物。 将描述+标准+输出的三元组持久化保存:
docs/designs/<slug>.md、docs/egm/<slug>/中的账本、源码根目录下的PEANUTS.md,以及/egm-decide三元组在其安装位置对应的表面映射路径上。聊天记录不是产物。
硬性规则:不得违反
- 只读。 本技能唯一写入的文件是
docs/egm/<slug>/DRIFT-REPORT.md。绝不编辑设计文档、代码、测试或任何其他账本(IMPLEMENT.md、GOLDFISH.md、ELEPHANT.md)。应用建议的更新是用户稍后单独提出的请求。 - 无证据即非漂移。 每个条目必须引用文档所述内容(章节和简短引用)以及实际构建的内容(
路径:行号、提交哈希或“不存在此文件”)。如果某条目缺乏任何一方的证据,则列为未解决的问题。 - 代码是观察到的事实;文档是声明的依据。 中立地报告差异。除非账本记录了决策,否则不要判断哪一方是正确的;建议的更新只是提案,而非裁决。
- 交由新视角进行比较。 实现该功能的会话倾向于将其自身意图解读到代码中。因此,只要有可能,应将比较工作交给一个全新的只读子代理(步骤 3)执行。
工作流程
EGM 漂移报告进度:
- [ ] 步骤 1:设计文档和 slug 已解析;找到 docs/egm/<slug>/
- [ ] 步骤 2:已选择基准提交;证据包路径已列出
- [ ] 步骤 3:由全新的只读子代理(或内联执行,需注明)完成比较
- [ ] 步骤 4:发现项已检查、分类并写入 DRIFT-REPORT.md
- [ ] 步骤 5:告知用户报告位置,并提示他们可以请求应用更新
步骤 1:解析设计文档
优先使用用户提供的参数。否则,在项目的 AGENTS.md 或 CLAUDE.md 中由 design_doc_path: 指定的文件夹中查找,若未找到,则在 docs/designs/*.md 中查找。如果只有一个文档存在,则使用它;如果有多个,则列出并询问用户要使用哪一个。slug 是文档文件名去掉 .md 后的部分,状态目录为 docs/egm/<slug>/。如果该目录不存在,说明该功能从未经过 /egm-design 流程;请告知用户,并提供仍在那个位置写入报告的选项(仅创建 docs/egm/<slug>/DRIFT-REPORT.md)。
步骤 2:选择基准并收集证据包
基准点是文档被批准的时刻。选择第一个适用的条件,并记录你所使用的基准:
- 设置了
human_review_gate: passed(或skipped-solo)的提交:git log --format='%H %ad %s' --date=short -- docs/egm/<slug>/GOLDFISH.md。 - 在
IMPLEMENT.md中start_date之前或当天,对设计文档的最后一次提交:git log --format='%H %ad %s' --date=short -- <文档>。 - 要求用户提供一个提交哈希或日期。
然后,列出(但不要概括)比较时将要阅读的证据:
- 设计文档(HEAD 版本,以及如果自基准后发生更改,则基准版本的
git show <基准>:<文档>); docs/egm/<slug>/IMPLEMENT.md,特别是## 涉及的文件部分、每一条## 漂移条目(无论未解决还是已解决)以及## 验证部分;GOLDFISH.md中记录了文档变更的处理说明;git log --stat <基准>..HEAD和git diff --stat <基准>..HEAD,以及来自git status和git diff的未提交更改;- 文档“详细实现”部分列举的文件,以及 diff 涉及但文档中未提及的文件。
不在证据包中的内容: 当前聊天记录、ELEPHANT.md 的设计推理,或你自身关于为何做出某些决定的记忆。这些内容仅当账本中有记录时,才可放入“可能原因”列。
步骤 3:在全新的只读会话中运行比较
在 Cursor 中,生成一个类型为 drift-auditor 的任务子代理(安装于 ~/.cursor/agents/drift-auditor.md,readonly: true)。如果未安装,使用一个通用的任务子代理,并告知其为只读。向其发送 assets/drift-auditor-prompt.md 中的提示,并填入文档路径、slug、基准和证据列表。不要添加任何其他内容: 不要添加实现总结,不要解释为什么变更发生。
如果不存在子代理运行时,则通过你自己遵循相同的提示来内联执行比较,并在报告头部记录 comparison: inline (无可用的新子代理),以便读者知晓该比较并非独立进行的。
步骤 4:检查、分类并编写报告
在写入每个返回的条目之前进行检查:打开引用的 路径:行号 和引用的文档章节,删除或修正任何证据不支持的内容。使用模板中的分类:方法变更、新增、未实现、重命名或移动、接口变更、数据模型变更、行为变更、新依赖、发现约束、切换方案。严重级别为 主要(文档会误导读者理解系统如何工作)、次要(细节错误)或 表面(命名、措辞问题)。
与 IMPLEMENT.md 进行交叉引用:将每个条目标记为 已记录(存在漂移条目及其状态)或 未记录。未记录的“主要”级别条目是重点内容。
根据 assets/drift-report-template.md 编写 docs/egm/<slug>/DRIFT-REPORT.md。如果文件已存在,则将新的带日期的报告放在文件头部下方,并将之前的报告原封不动地移动到 ## 更早的报告 部分下方。绝不要重写之前的报告。
如果不存在漂移,则仍然编写报告,设置 drift_items: 0,并记录所使用的基准和比较的内容,这样“无漂移”就是一个有记录的结果,而不只是空白。
步骤 5:交回给用户
按以下格式告知用户:
漂移报告已写入
docs/egm/<slug>/DRIFT-REPORT.md: 项(<主要个数> 项为主要,<未记录个数> 项未在 IMPLEMENT.md 中记录)。我未更改设计文档或代码。当您希望文档与构建的内容一致时,请要求我应用报告中的建议文档更新;涉及更改技术计划的项目应返回/egm-design流程,较大的重写则应通过/egm-review流程处理。
除非用户在看到报告后主动要求,否则不要在此会话中应用更新。
反模式
- 在报告的同时修改文档。 报告是可交付物。编辑文档将测量与变更混为一谈,并且掩盖了漂移是什么。
- 修改代码以匹配文档。 方向相反的同等问题。由用户决定哪一方需要移动。
- 凭记忆解释漂移。 没有账本记录解释“我们为了X而改了Y”是一种猜测;应写为
reason: unknown,让用户自行补充。 - 总结 diff 而非进行比较。 一个变更文件列表不是漂移报告。每个条目必须将一个文档声明与一个观察到的事实联系起来。
- 为节省时间跳过全新会话。 实现会话已经相信代码与文档匹配。本技能存在的意义正是为了测试这种信念。
本技能在 EGM 中的位置
/egm-learn(仅限遗留代码) → /egm-design → /egm-review → /egm-implement → /egm-code-review,而 /egm-drift-report 可以在 /egm-implement 之后的任何时间使用(代码审查之前或之后)。
- 读取: 设计文档、
IMPLEMENT.md、GOLDFISH.md、基准之后的 git 历史记录以及代码。 - 写入: 仅限
docs/egm/<slug>/DRIFT-REPORT.md。 - 输入: 后续的“根据漂移报告更新设计文档”请求;对于技术计划变更,输入
/egm-design;当更新后的文档需要重新验证时,输入/egm-review。