将用户的代码变更请求从起始点推进到最终目的地,并以另一个模型作为评审者。用户决定两次:在解释器处决定方法,在发布消息处决定结果。中间的一切都由你负责。
另一个模型是用户指定的模型家族中,在 orchestrator_capabilities 里最新、且使用用户指定努力级别的模型。相同的模型和努力级别将用于后面的每一个来回、代码循环和评审,除非是关键决策的辩论。如果模型家族或努力级别缺失,请询问用户,在得到答复前不做任何其他事。
一个运行者(runner)将在步骤3中代表你进行辩论(使用 back-and-forth 技能的运行者)。除非用户指定了一个运行者:默认为使用中等努力级别的最新 Fable 模型,与另一个模型辩论;对于关键决策,使用高努力级别的最新 Fable 模型,与使用高努力级别的最新 Astra 模型(代替另一个模型)进行辩论。关键决策是指 design.md 中的结构性问题触发,并且你能陈述一个其答案可能改变方法的提问。当运行者或其搭档的模型不可用时,请告知用户,并亲自与另一个模型辩论方法。
1. 目的地和规则
确定变更的最终去向:经过测试的本地变更、推送的分支、打开的 PR、已合并或已部署。仅当不明确且答案会改变工作时才询问。说“see it through”并不批准任何推送、PR 或部署;只有发布消息的批准才行。
你正在修改的仓库的规则,以及用户指向的任何流程文件,在与该技能冲突时优先适用。
变更已构建完成。 当用户说变更已经完成时,已构建的内容就是方法,发布消息是第一个批准:不要发送解释器,也不要运行来回。在步骤2和3的位置:
- 确定基线:对于未合并的分支,取其与目标分支的合并基础,该基础是在其最后一次合并目标分支后确定的;一旦合并,取变更前的那个提交。如果不清楚,请询问。当变更已合并时,目的地是指本次运行的后续提交将去往的地方;如果不清楚,请询问。
- 根据用户的话语和变更本身所说明的内容(提交消息、PR 文本)编写请求,并标记你推断的内容。
- 找出在基线的工作树上失败但在变更上通过的那些检查,从变更已有的测试开始(在基线上只应用变更的测试和测试工具块来运行它们),并且只为那些没有测试证明的承诺行为编写一个检查;对于没有显示失败的变更,例如性能提升或重构,编写一个证明其承诺的检查。按步骤2的方式设置层级。保留那些最少的、能证明变更承诺的每个行为的检查作为验收基线,就像步骤4保留的那样,并注明哪些是在变更之后编写的;变更的其他测试则保持开放,以便简化(simplify.md)。
- 将方法写入一个文件:变更了什么,design.md 的基础及其结构性问题对已构建内容的回答,以及步骤3的失败检查。
然后从显示复现通过继续步骤4,并将该基线和该文件作为代码循环的“方法”。发布消息说明没有解释器被批准,并包含任何结构性替代方案以及任何改变用户所得结果的发现。
2. 复现
对于错误,在编写修复之前,先在基线上复现它:一个失败的测试,以及当用户可以观察到该错误时,正在运行的产品显示它,如 capture.md 所述进行捕获,当验证流程还不能捕获时,手动完成。对于功能,编写用户应该看到或能够做什么。当你无法复现错误时,在构建修复之前告知用户,并将你对此所说的任何话写为“来自代码阅读(未尝试)”。一个没有找到任何东西的检查,只有当你在它存在时看到它找到了那个东西,才算数。
不要为尚未复现的失败路径构建防护措施;而是在解释器中将其列为后续事项。
通过仓库的验证技能进行复现和证明:仓库中的 .agents/skills/verify/,或者仓库的 AGENTS.md 指定的位置。如果没有,或者它没有覆盖你需要的流程,暂时手动复现,并将使用 make-verifiable 技能构建该覆盖率作为方法的一部分。
然后设置层级。完整模式:当变更的行为涉及持久化、并发、授权、迁移、公共契约、破坏性影响或共享状态所有权时,或者当你无法判断变更代码如何被访问或测试覆盖程度时;根据你找到的调用者和状态写入者来判断,而不是根据文件名。轻量模式:其他情况。如果轻量运行中出现了上述任何情况,则转为完整模式。
3. 设计和解释器
在选择方法之前,阅读 design.md 并执行其要求。在完整模式中,与模型就方法进行来回辩论(back-and-forth 技能),将 design.md 中的比例估计作为其上下文中的前提进行核对,并在选项中包含一个较小版本和不做变更;在轻量模式中,仅当 design.md 的触发器触发或强方法之间存在实质性差异时才这样做,否则由你直接编写方法。在上下文中,向运行者提供你的基础及其引用、你复现的内容和你仅阅读的内容,以及用于会话暂存或临时文件夹中记录的路径;在提问中,根据请求编写,同时询问变更的着陆点(包括调用者和兄弟情况)、验收案例以及留给你的工作。当一个设计问题是一个你可以通过运行某些东西来观察的事实时,通过隔离的检出或临时数据进行一次性实验来解决,而不是询问用户;实验不交付任何产品。
然后编写失败检查:检查 code-loop 技能的简要头中的条件,以及依赖于你正在修改的行为的各方,对每个适用的条件,命名将覆盖它的测试或你接受的限制。
向用户发送解释器,使用通俗的语言,按以下顺序的标题。每个事情只说一次。
- 问题: 用户今天看到什么,谁遇到它以及频率如何(观察或估计;没有报告意味着未知,而不是罕见),为什么它重要,以及你的复现,如果有捕获则包含在内;对于功能,今天缺少什么。当用户要求变更时,以他们的话语开头。
- 发生原因: 通俗地解释原因;对于功能,今天有什么阻碍。如果没有任何阻碍,对于功能可以省略此标题。
- 变更内容: 完成后用户将看到或能够检查什么,以及哪些超出范围。如果缺少某些会改变工作的内容,请在此处询问。
- 方法: 代码中哪些部分发生变化以及位置,你将如何证明它,包括任何
make-verifiable工作以及哪些检查随变更一起交付或保留作为证据,交付和维护的成本是多少,为什么在“问题”下权衡了范围和危害后这是值得的,以及评审者会关心的失败检查条目。 - 权衡的替代方案: 每一个强替代方案,design.md 的结构性选项(只要存在一个可信的选项),每个方案都说明为什么被否决。
- 评审者可能提出的问题: 每个可能的问题及其答案。
然后停止:在用户批准之前不要构建任何东西。任何措辞的普通批准都允许你构建。任何其他内容都逐字地放回到同一个来回中,作为进一步的交流,超出其交流限制,并作为修改后的解释器返回;再次停止。在轻量模式且没有来回的情况下,你自己修改解释器并再次停止。
批准覆盖了按书面形式的解释器。当测试、演示或评审改变了用户所得的结果、其可见行为、兼容性、范围、你将采取的交付行动或解释器接受的权衡时,引用它反驳的句子,与模型一起解决,发送一个说明变更内容的修订解释器,并再次停止。更小的发现,例如使用不同的内部辅助函数,则放在发布消息的“自上次以来的变更”部分。
4. 构建和证明
在改变行为之前,保存复现和每一个可以在变更存在之前运行的验收检查:提交解释器要交付的那些检查,并将其余的保存下来,或者当没有任何东西需要提交时,将它们全部保存为仓库外部的补丁。它们共同构成了验收基线,并且它们都会在最终候选版本上再次运行:之后对它的任何编辑都会进入代码循环和发布消息,并附上其差异以及它是否改变了承诺的行为。
按照 design.md 设定的顺序构建已批准的方法。当变更改变了验证技能覆盖的流程时,在同一变更中更新该流程。显示步骤2中的复现通过,通过验证技能并在用户可以观察到时在产品中显示。然后按照 simplify.md 的说法简化差异。然后,使用模型对完整差异运行代码循环(code-loop 技能),将用户的请求(或代表它的简要)作为请求,解释器作为方法(如果有运行者的记录也附上),验收基线作为验收,以及层级。
在最终候选版本上,当用户可以看到或执行变更所改变的内容时,通过验证流程进行捕获,如果无法捕获则使用 make-verifiable 扩展流程,对于错误,通过相同的流程在基线上捕获相同的场景,以便前后匹配。按照 capture.md 的说法选择、制作和审查捕获,并检查它是否显示了你要声称的内容。捕获显示了变更,而检查证明了它,因此基线的捕获或失败运行的捕获永远不能作为通过。没有可见内容的变更不需要捕获。
5. 编写
根据项目的模板起草 PR、问题或发布文本,如果模板有空间则将捕获放在那里,或者放在它们自己的标题下。在 GitHub 上,当你发布时使用 gh pr create --attach(或 gh pr edit)附加它们,除非仓库有自己的工具;当它非零退出时,在重试之前检查 PR 是否存在,因为它可能已经存在。在任何陈述事实的公共文本(描述、回复、状态更新)发布之前,一个模型的新鲜评审者会根据证据、捕获(作为其帧和节奏报告的录制)和差异来检查它:每个声明都为真且有依据,每个勾选的框都为真。删除证据不支持的声明;不要回避它。
在每次推送之前,重新检查每个勾选框和每个声明背后的检查,并重新制作每个捕获,前提是本次变更可能影响到它们。
6. 发布消息
向用户发送:对解释器、自上次以来的变更、证据、捕获、编写、差异以及你将在批准后采取的确切行动进行两到三句话的总结。当代码循环结束时存在未解决的争议时,以此开头:每个声明,每一方展示了什么,以及批准交付了什么。在发送之前,重新进行 design.md 的重叠检查。停止直到用户批准。
7. 推进到目的地
执行已批准的行动,然后将变更推进到其目的地:
- 在每次推送之前和根据通知采取行动之前,获取远程头并检查变更的当前状态。在其他人的推送基础上构建,比较树而不是提交哈希;不要用陈旧的本地版本替换他们的工作。当变更落地、关闭或被其他人的版本替换时,将到达目的地的内容与你最后验证的头和未解决的问题进行比较。报告差异或未包含的内容,不要重新添加他们故意删除的内容。
- 每个评审发现,无论是内联还是评审正文中的,都需要完整阅读,得到一个修复或一行原因;一个在基线上同样发生的发现,就像
code-loop判断预先存在的发现一样处理。一个改变行为的修复需要进行代码循环。 - 当事实证明已发布的文本错误时,更正文本。
- 一个改变范围或方法的请求将回到步骤3,并且一旦构建,将发送新的发布消息;一个适用于本次变更之外的请求,在到达时连同其链接一起发送给用户:在此处执行并不意味着在其他地方也执行。
- 对于部署,针对已部署的内容运行验证流程。
8. 经验教训
当用户、PR 评审者或发布后的任何东西发现了代码循环遗漏的问题,或者代码循环发现了一个阻塞点或应该发现的点,在你修改的仓库中的 .agents/lessons/log.md 中添加一个条目;对于用户不拥有的仓库,则放在保存其流程的文件夹中。每个条目:日期、变更、被谁发现了什么、模块、错误类别和原因。
然后读取日志。一个检查可以捕捉到的教训,如果出现两次,则变成 lint、类型、测试或验证检查;一个需要判断力的教训,如果出现两次,则变成仓库 AGENTS.md 中的一行;一个模块中的两个条目,或者任何模块中的两个同类错误(例如在 await 期间被另一个操作更改的状态),则变成一个结构性问题,在提出任何重构之前命名它们共享的原因。在你最终的消息中将每个列为后续事项;重构作为其自己的 see-it-through 运行。
当变更到达其目的地,或者当你报告了确切的阻塞点和剩余工作,并且经验教训条目(如果需要)已写入时,任务完成。