ACDL研发流程05:决定为什么要改变产品

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

上一篇:ACDL研发流程04:需求怎样走完整个ACDL

下一篇:ACDL研发流程06:共同完成产品与架构设计

Agent最容易在问题不清楚时显得高效

Agent很擅长把一句话迅速变成界面、接口和代码。问题是,如果这句话本身混入了未经确认的假设,Agent也会很快把错误方向做得像模像样。

例如,“给会话增加收藏按钮”听起来已经可以开发,但它没有说明员工遇到了什么困难,也没有说明收藏以后怎样帮助员工。直接从这句话开始,讨论很容易围绕按钮位置、图标和数据库字段展开,真正的问题反而没人再问。

进入设计之前,Director和Agent需要先回答两件事:现在到底发生了什么,产品是否准备作出改变。先弄清发生了什么,再决定产品要不要改变;已经想到的方案不能反过来冒充问题。

第一步:先描述发生了什么

问题描述要从使用现场开始,而不是从已经想到的功能名称开始。对于本章的例子,可以先写成:

员工的会话越来越多。需要再次查看一段重要内容时,员工经常要在列表中反复滚动和打开多个会话,仍然很难快速找到目标。

这段话还不是需求,但它已经说清了谁遇到问题、当时想完成什么任务以及现在受到什么阻碍。接下来可以继续补充:这种情况出现得多不多,哪些员工受到影响,搜索和最近使用是否已经解决了一部分问题,以及我们掌握的是实际观察还是猜测。

Director不需要独自完成调查。Agent可以查看当前产品和代码,整理已有反馈,复现现象,找出相似功能,也可以追问描述中的空白。但Agent此时产出的是调查材料,不是替Director作出的产品决定。

一个有用的问题描述通常能让读者看出:

  • 谁在什么情况下遇到了困难;
  • 当前实际发生了什么;
  • 问题造成了什么影响;
  • 哪些内容已经确认,哪些仍然只是推测;
  • 为什么这件事值得继续处理。

不需要跨会话保留的一次性观察,可以继续留在当前讨论中。问题需要以后继续调查、交给其它Agent处理,或者需要长期保留来源和去向时,再为它分配ISSUE编号并登记。

第二步:判断是ISSUE还是REQ(Requirement)

ISSUE和REQ保存的不是同一种东西。ISSUE保存一个需要继续处理的问题,REQ保存一项已经确认需要改变产品的需求。

最实用的判断方法,是看“处理完成后,当前已经确认的承诺会不会改变”。这里的承诺来自已经确认的设计,不是来自代码恰好怎样运行。

1
2
3
4
5
6
7
8
9
10
已经确认需要改变用户行为、业务规则、权限、数据边界或正式范围
→登记REQ

还不知道是实现缺陷、新需求还是环境问题
→先登记ISSUE并调查

代码没有做到已经确认的设计
→这是实现问题
→需要跨会话追踪时登记ISSUE
→问题和范围已经清楚时可以直接准备ACL

如果员工目前只是偶尔找不到会话,还不确定问题来自列表错误、搜索失效还是缺少新的产品行为,就先登记ISSUE。ISSUE记录发现时间、环境、操作、期望结果、实际结果、影响、证据和下一步,让后续Agent不必重新猜测问题从哪里来。

如果已经确认产品需要提供一种新的方式,让员工主动标记并重新找到重要会话,就可以直接登记REQ,不需要为了流程完整先制造一个ISSUE。REQ是Requirement的缩写,它负责追踪为什么改变产品、希望得到什么结果以及最终进入了哪个正式版本。

ISSUE调查结束后可能有不同去向:实现偏离已有设计的问题进入实施;需要改变产品的问题转为REQ;环境问题进入环境处理;重复、误报或不再处理的问题保留判断依据后结束。ISSUE不是较小的REQ,REQ也不是换了名字的ISSUE。

第三步:把REQ(Requirement)写到Director能够决定是否继续

REQ的目标不是让Agent马上写代码,而是让Director能够判断这项改变是否值得进入设计。正文先写清四件事:问题、期望结果、非目标和验收场景。

以“收藏会话”为例,可以这样表达:

  • 问题:员工难以从大量会话中重新找到重要内容;
  • 期望结果:员工可以标记自己有权访问的重要会话,之后能够容易地再次找到;
  • 非目标:本次不同时建设共享收藏、标签分类和智能推荐;
  • 验收场景:员工收藏会话后,刷新页面和重新登录仍能看到收藏状态,并能从列表中优先找到它;取消收藏后恢复普通显示。

这里故意没有决定使用新的数据表还是已有字段,也没有规定接口路径和前端组件。REQ描述产品为什么改变和成功以后能观察到什么,具体实现留给后面的设计。

验收场景也不是一句“功能开发完成”。它要让Director能够实际操作,让Agent能够据此设计测试。例如,重新登录后收藏状态是否保留是一项可观察结果;“接口已经实现”只能证明存在一段代码,不能证明员工的问题得到解决。

需求从出现到进入设计,通常会经过以下状态:

1
2
待评估 →候选 →已选中
↘不采纳

待评估表示刚刚登记,还没有判断是否值得保留;候选表示问题值得继续考虑,但现在不一定投入;已选中表示Director确认可以开始产品与架构设计。多个候选需要比较顺序和依赖时,再使用路线图;一项明确需求不需要为了形式完整先写路线图。

需求被选中时还不确定目标版本。设计可能发现新的依赖、风险或不可行之处,过早排期只会把一个尚未理解清楚的想法包装成承诺。等设计得到确认以后,再决定是否交付以及放入哪个目标版本。

REQ的需求状态和Markdown文档状态表达两件不同的事。候选已选中说明需求走到了哪里;DraftReviewAccepted说明一份文档是否已经可以采用。不要用“设计中”“开发中”作为需求状态,也不要因为REQ正文已经写得完整,就宣称需求已经排期或完成。

GitHub Issues怎样与本地ISSUE联动

到这里,需求管理的核心判断已经讲清:先理解真实问题,再决定使用ISSUE继续调查,还是使用REQ确认一项产品变化。GitHub Issues解决的是另一个问题——怎样让不了解当前项目文档目录的人提交反馈,并在熟悉的讨论和看板入口中看到进展。

GitHub Issues适合接收反馈、继续讨论和查看工作进展。项目外部的参与者可以直接提交看到的现象、复现步骤和期望结果,Director和Agent也可以在其中补充调查线索。

但GitHub Issue不是ACDL中负责维护编号和状态的正式记录。它的标题、正文、标签和打开状态都可能被人工修改,也不能完整表达问题与REQ、ACL、DFL、ERL、版本和环境记录的关系。当前项目仍然以docs/03-实施/ISSUE/README.md中的本地ISSUE台账保存正式编号、状态、严重程度和处理去向。

两者建立关系后各自保留自己的作用:

1
2
3
4
5
GitHub Issue
→接收原始反馈、开展讨论、提供看板入口

ISSUE-六位编号
→保存正式编号、当前状态和后续去向

不是每个本地ISSUE都必须创建GitHub Issue。只在GitHub入口有助于收集反馈、开展讨论或展示进展时建立关联。反过来,GitHub上的普通反馈也不自动成为本地ISSUE;能够在当前讨论中直接判断和处理的内容,无需为了同步而分配编号。

从GitHub新反馈建立本地ISSUE

新建的GitHub反馈可以先使用status:待登记标签。这个标签只表示它还没有通过本地ISSUE登记判断,不是ACDL新增的一种正式问题状态。

Director或Agent先阅读反馈,确认来源、现象和已知事实。如果问题需要跨会话复现、调查、决定或处理,再用issue:import为它取得本地编号。先使用--dry-run预览准备写入的文件和编号:

1
2
pnpm issue:import -- --github=42 --repository=example-org/acdl-project --category=实现缺陷 --severity=S2 --dry-run
pnpm issue:import -- --github=42 --repository=example-org/acdl-project --category=实现缺陷 --severity=S2

导入会保留GitHub原始反馈,把它作为问题来源,并在本地ISSUE台账中记录一对一的外部关系。分类和严重程度仍由复核事实决定,不直接照搬提交者的选择。

如果复核后确认它是重复反馈、不属于本项目,或者可以在当前会话内直接处理,就在GitHub中说明判断,不为了让工具产生结果而导入本地。

关联两边已经存在的问题

有时问题已经先在DFL、ERL、环境记录或当前开发中取得本地ISSUE编号,后来才出现对应的GitHub Issue。这时不再导入第二个本地问题,而是把两个已有编号关联起来:

1
2
pnpm issue:link -- --id=ISSUE-000036 --github=42 --repository=example-org/acdl-project --dry-run
pnpm issue:link -- --id=ISSUE-000036 --github=42 --repository=example-org/acdl-project

一个本地ISSUE只能关联一个GitHub Issue,一个GitHub Issue也不能同时代表多个本地ISSUE。发现重复入口时,先确定哪个本地ISSUE负责保存正式编号和处理结论,再把其它入口标记为重复并指向它。

关联操作只建立编号之间的关系,不会因为GitHub Issue已经关闭就把本地问题改成已关闭,也不会用GitHub标签覆盖本地分类和严重程度。

从本地ISSUE单向同步到GitHub

建立关联以后,本地ISSUE台账继续由Director和Agent根据调查、实施与验证事实更新。GitHub用于显示结果,不反向决定本地状态。

需要检查两边是否一致时,先运行不带--apply的同步命令。它只报告差异,不修改GitHub:

1
pnpm issue:sync -- --repository=example-org/acdl-project

确认差异符合预期后,再明确使用--apply更新GitHub:

1
pnpm issue:sync -- --repository=example-org/acdl-project --apply

同步会把本地ISSUE编号写入GitHub标题,更新正文中的受管理摘要和根据本地状态自动生成的标签,并根据本地ISSUE是否已经结束打开或关闭GitHub Issue。已关闭映射为已经完成;不处理重复映射为不计划处理;其它本地状态保持GitHub Issue打开。

GitHub提交者的原始反馈正文和人工添加的分类标签会继续保留。同步只修改明确由仓库管理的内容,不把整个GitHub正文重写成本地台账副本。GitHub中的手工关闭、重新打开或改标签也不会反向改写本地事实。

本地ISSUE台账和同步工具的变化进入main后,Sync GitHub IssuesWorkflow会读取仓库内容,执行同一套单向同步。这个Workflow只获得修改GitHub Issues所需的权限,不会修改仓库文件,也不影响代码质量检查。

同步失败只表示GitHub展示可能落后。本地ISSUE的编号、状态和处理关系仍以仓库中的台账为准。

需求管理结束在哪里

这一阶段结束时,Director确认的不是实现方案,而是“这个问题值得进入产品与架构设计”。REQ进入已选中,表示问题、期望结果、非目标和验收场景已经足以支持下一步讨论;它不表示技术方案已经确定、目标版本已经承诺或Agent可以开始编码。

1
2
3
4
5
真实问题或反馈,包括需要持续处理的GitHub反馈
→判断是否需要长期追踪
→使用ISSUE调查,或者直接登记REQ
→Director决定候选是否进入设计
→REQ进入已选中

下一章从这项已经选中的REQ开始,说明怎样在系统、能力和横切设计中找到负责当前答案的位置,并把产品行为和技术方案整理成可以一致指导实施的设计。