ACDL研发流程11:结束Loop并冻结正式版本

ACDL研发流程系列第11篇,共15篇。

上一篇:ACDL研发流程10:通过真实使用和独立评审发现遗漏

下一篇:ACDL研发流程12:不同工作从哪里开始、在哪里结束

停止编码、Loop结束和正式版本是三件事

Agent完成最后一次代码修改时,一项工作还没有自动结束。测试结果可能尚未整理,环境中可能运行着另一个提交,计划中的步骤也可能发生了变化。如果此时只留下“代码已完成”,后续的人仍然不知道哪些结果可以相信。

一轮Loop进入Completed,也不表示正式产品版本已经形成。ACL(Agentic Coding Loop)只证明约定的实施与验证已经结束,DFL(Developer Feedback Loop)只证明一组真实任务已经使用并记录,ERL(Engineering Review Loop)只证明一个具体提交或版本范围已经独立检查。它们可以分别在不同时间结束,也可以暂时留在主线等待以后被某个版本选择。

正式版本回答的是更大的问题:这次准备向使用者交付哪些变化,采用了哪些代码和证据,还有什么限制,以及哪一个Git提交代表这个结果。

1
2
3
4
5
6
7
8
停止编码
→Agent不再增加本轮改动

Loop结束
→本轮范围、结果、证据和剩余问题已经确认;ACL还已合入目标分支并记录合入提交

正式版本形成
→若干已结束工作经过版本验收,由Git标签固定

这三个时刻可以相隔很久。一个小型维护ACL可以结束后继续留在main;几周以后,Director准备正式版本时再决定是否把它纳入。环境发布也可以发生在Loop执行中、DFL开始前或正式版本之后,不能代替其中任何一个结论。

先让每轮Loop如实结束

结束一轮Loop时,Agent先把启动时的目标和实际结果放在一起看,而不是只检查有没有最新提交。记录需要让Director看懂:

  • 本轮从哪个分支和提交开始,最后形成了什么提交或评审对象;
  • 实际完成了哪些实施、验证、真实使用或独立评审;
  • 哪些测试、发布和复核通过,在哪个环境得到结果;
  • 哪些步骤失败、跳过、不适用或与原方案不同;
  • 发现了什么问题,哪些已经解决,哪些由ISSUE、REQ、ACL或环境记录继续处理;
  • 本轮目标是否达到,以及这个结论不能证明什么。

计划中的步骤没有发生时,写“未执行”并说明影响,不把它从记录中删掉。实施改变了原方案时,保留变化原因和确认结果,不用最后的做法改写启动方案。Loop结束保存的不是一个漂亮故事,而是下一个人能够复核的实际过程。

整理完成后,先让Loop进入Review。ACL使用专门的评审入口,检查固定候选是否有与当前提交和Git树匹配的最近一次pnpm verify成功证据:

1
2
pnpm loop:review -- --id=ACL-000039 --dry-run
pnpm loop:review -- --id=ACL-000039

DFL和ERL使用pnpm loop:status -- --id=轮次编号 --status=Review,同步登记表和对应记录。

进入Review表示Agent认为结束条件已经具备,正在等待Director确认。它不是一种委婉的完成状态,也不能因为等待时间较长就自动变成Completed

Director检查本轮结论和未解决问题的去向。DFL和ERL在结论得到确认后可以进入Completed;ACL还必须先合入目标分支,并在主记录中把主线合入提交填写为实际提交。满足这些条件后,再明确确认:

1
pnpm loop:status -- --id=ACL-000039 --status=Completed --confirm="确认本轮结论和未解决问题去向"

命令会同步必要计划、记录和Loop登记表的状态,并记录Director的确认内容,但不能替代Director作出确认。对于ACL,脚本还会拒绝主线合入提交仍为待填写的记录。只修改登记表、只把文档改成Completed,或者在聊天中说一句“没问题”,都没有完整保存这次状态变化。

如果本轮目标已经放弃,使用Withdrawn如实停止,不把未完成工作包装成Completed。已经发生的调查、修改、失败和证据继续保留,编号也不重新使用。需要继续的部分可以建立新的Loop,并把原记录作为来源。

目标版本不是一份提前承诺全部范围的计划

一项完成设计的REQ准备交付时,Director会先确定目标版本,并在docs/04-版本/产品版本总览.md建立Review入口。这个入口只说明当前准备组织哪一次交付,不提前保证所有候选需求和关联Loop最终都会进入。

目标版本、REQ排期和正式版本形成是三个不同动作:

1
2
3
4
5
6
7
8
建立目标版本
→为一次候选交付分配版本号并建立记录

REQ进入已排期
→确认它准备服务这个目标版本

正式版本形成
→确认实际纳入的内容,并创建Git标签

DFL和ERL记录中的“关联版本”也不是纳入证明。它只保存开始这轮工作时已知的版本背景。一轮DFL可能检查多个版本,一轮ERL也可能在目标版本尚未确定时开始。只有产品版本总览在验收时明确选择,这轮工作才成为该版本的验收证据,或者成为版本形成前必须通过的ERL。

计划版本为未确定的ACL同样不会因为合入main就自动属于下一个版本。Director准备版本时,可以选择其中与本次交付有关的工作,也可以让其它维护继续留在主线。

版本验收先选择实际纳入的内容

准备正式版本时,Director和Agent先从当前目标中筛选实际范围。产品版本总览需要明确列出:

  • 实际纳入的REQ,以及每项需求的验收场景得到什么结论;
  • 实际纳入的ACL及其完整提交;
  • 被选作验收证据的DFL和被选作版本形成前必须通过的ERL;
  • 版本源码提交、环境实际运行的提交、制品与配置,以及详细证据入口;
  • 明确排除的需求、Loop和未完成范围;
  • 尚未解决的问题及其影响和处理决定。

被选中的ACL、DFL和ERL需要已经进入Completed,历史上已经使用Accepted结束的记录可以继续按历史事实处理。还在In ProgressReview的Loop不能因为“只差确认”就算作已经纳入。

关联同一目标版本但没有被选中的DFL或ERL,不会自动阻止版本。它可能检查了另一个主题,也可能还没有实际执行。Director需要明确排除并说明影响,不能一面忽略未完成范围,一面宣称这些范围已经通过。

以“收藏会话”为例,某个候选版本可以选择收藏需求对应的ACL和一次真实使用DFL。Director根据权限与数据风险判断现有自动化验证已经足够,本次没有开展ERL,也可以形成版本;但发布说明和验收结论只能引用实际存在的ACL与DFL证据,不能写成“已经完成独立工程评审”。

回到最初问题判断版本是否真的可用

版本验收不是把所有通过的测试结果加在一起。Director重新回到REQ中的问题、期望结果和验收场景,判断当前候选是否真的解决了最初的用户问题。

收藏接口、页面和测试全部通过,却仍然无法让员工从长列表中更快找到收藏会话,这个版本就没有完成最初需求。相反,某项内部重构没有用户可见变化,只要它达到自己的工程目标,也不需要编造一段产品价值证明。

Director还要逐项查看未解决问题。它们不要求全部清零,但必须有清楚决定:

  • 在形成版本前修复,并用新的ACL和验证证据更新候选;
  • 把受影响功能或场景排除在本版本之外;
  • 作为已知限制保留,并说明影响和后续去向;
  • 对确实可以接受的剩余风险作出明确决定。

涉及Secret泄露、越权、跨员工访问、数据损坏、无法恢复或未批准业务写入的问题,不能只写进“已知限制”就继续。候选范围需要修复或排除;作为版本形成前必须通过检查的ERL已经规定阻断等级时,也要遵守开始评审前确定的标准。

证据不足时,版本继续保持Review。可以补验证、继续DFL、开展ERL、启动修复ACL,或者缩小实际范围。达到原定日期、已经投入很多时间和环境运行正常,都不能代替这次判断。

确定最终要打标签的提交,并写面向使用者的发布说明

验收范围稳定以后,Agent固定准备打标签的完整提交。这个提交要包含版本结论和发布说明,源码、文档、迁移、配置及生成内容也要与实际验收对象一致。工作树中未提交的修改不能暗中成为版本的一部分。

如果正式版本包含可执行产品变化,需要按当前《开发与验证》完成相应的完整发布验证,并保存能够对应到候选提交或完整Git树的证据。验证过程中候选发生变化,原结果不能继续证明新代码;修复后需要重新选择受影响的验证范围。

详细命令输出继续保存在验证和实施证据中,产品版本总览只汇总实际范围、关键结果、限制、Director结论和入口。不要把每轮测试的详细过程和输出复制进版本文档,也不要让读者为了理解一次发布先阅读几十份实施记录。

每个正式版本另有一份V0.X-发布说明.md,面向实际使用者说明:

  • 新增了哪些可以观察到的行为;
  • 修复了哪些已经存在的问题;
  • 有哪些工程、运维、升级或兼容影响;
  • 哪些范围没有纳入,当前有哪些已知限制;
  • 使用了哪些关键验收和发布验证。

发布说明只写能够从本次范围和证据核实的结果。提交标题写了“优化”,不表示使用者一定能够感知优化;某个DFL没有开展,也不能根据设计预期补写成已经实机通过。没有对应内容的分类可以直接说明没有,不用为了让文档饱满而补造变化。

Director确认以后用Git标签固定版本

当实际范围、验收场景、证据、排除项、剩余问题和发布说明都已经清楚,Director才确认版本可以形成。这里确认的是一个具体候选提交和一组具体事实,不是笼统批准“最近这些工作”。

Git标签创建前,产品版本总览和发布说明保持Review。Agent先把已经确认的版本结论和发布说明写入准备打标签的提交,再创建指向这个完整提交的V0.X标签,并核对标签确实存在、名称正确、指向预期提交。

1
2
3
4
固定版本候选提交
→Director确认实际范围和验收结论
→创建并核对V0.X Git标签
→记录真实标签和完成状态

Git标签让版本获得一个始终指向同一Git提交的固定标识。REQ中的目标版本、ACL编号、GitHub Milestone、Pull Request、发布分支、Docker镜像名称和某个环境的部署状态都不能替代这个标签。

“冻结正式版本”不是禁止仓库继续开发,也不是把所有相关文档变成不可修改。它表示以后提到这个版本时,始终能够回到同一个Git提交、同一份发布说明和同一组验收事实。后来发现问题时建立新的ISSUE、ACL或版本,不移动旧标签,也不把后续结果追溯写成旧版本当时已经具备。

创建标签后,再更新版本和REQ状态

真实Git标签创建并核对以后,Agent完成最后的状态更新:

  • 在产品版本总览中记录实际标签、标签提交、验收结论和已知限制;
  • 把版本及其发布说明从Review改为Completed
  • 把实际纳入的REQ从已排期改为已完成
  • 确认本版本采用且没有未关闭阻断问题的相关设计处于Accepted
  • 再次核对标签、版本总览、发布说明和实际提交相互一致。

这些状态更新不能提前发生。REQ进入已完成表示它已经随正式版本交付,不表示代码已经合并或某轮ACL刚刚结束。发布说明进入Completed也以真实存在的Git标签为前提。

正式版本形成后,不代表它已经部署到每个环境。环境记录继续回答某个环境当前运行什么提交、制品和配置,版本记录回答哪个提交经过正式验收。某个环境可以暂时停留在旧版本,也可以在正式版本形成前运行候选用于DFL,两类记录各自回答自己的问题,不能用环境状态代替版本结论。

回头检查版本怎样形成

1
2
3
4
5
6
7
8
9
10
各轮ACL、DFL或ERL完成自己的范围
→Agent整理实际结果并进入Review
→Director确认每轮结论和问题去向
→Loop进入Completed
→准备正式交付时选择实际纳入范围
→回到REQ验收场景和剩余风险作判断
→固定候选提交并形成发布说明
→Director确认版本结论
→创建并核对Git标签
→完成版本、REQ和相关设计状态

一项工作走到Loop结束就可以停下,不需要为了显得完整而立即制造正式版本。只有Director明确准备一次正式交付时,才把多轮已结束工作组成版本。下一章将从不同类型的实际任务出发,说明它们应该从ACDL的哪里进入,又在什么位置结束。