ADR 0053 — Dev Lead 作为区域,以及由用户授权的并行
- 状态: 已接受(在 FASE 14d 中实现,2026-08-07)
- 日期: 2026-08-05
- 背景: FASE 14d
- 撤销以下 ADR 的切分: ADR 0038(通用区域机制,以及通过
module_map的动态区域)
背景
今天 dev agent 的并行是:activate 时每个模块一个 agent,再通过一次点击接受(AcceptParallelizationUseCase)为每个模块加一个额外的(dev-<modulo>-2)。没有会话上限。没有任何东西阻止一个项目为每个模块启动一个 agent 再各加一个额外的,花费随之上涨而无人授权。
FASE 14d 决定由 lead 来评估多少个 agent 是值得的,而在会话中超过两个需要用户授权。
本 ADR 解决的张力
所讨论的并行是 dev 的,而 Dev Lead 不存在。现有区域有两个,成员固定、手写在
apps/web/src/lib/agents.ts 中:qa(lead qa,成员 qa-automacao 和
qa-performance-seguranca)和 infra。
更糟的是:CLAUDE.md 明确禁止了所需的两件事——
“不要实现 Dev Lead,也不要通过 module_map 实现动态区域”以及“不要实现通用区域机制(agent_areas/按区域预算)”。
用户的决定是解除这两项禁令,真正实现 Dev Lead。本 ADR 记录这一点及其原因。
为什么 dev 区域不能硬编码
qa 和 infra 的成员在编写时就已知。dev 区域不是:其成员是 module_map 中每个模块一个,由 Arquiteto 决定,每个项目不同,并在架构被修订时变化。
这正是第 8 阶段的切分所推迟的情况。当所有区域都是静态时,它是诚实的;当第一个动态区域进入时就不再如此。没有这个机制就做不出 Dev Lead——这就是两项切分一起取消的原因,而不是出于方便。
决策
1. 区域变成按项目的数据
引入 agent_areas 和 agent_area_members,按项目限定作用域:
agent_areas:project_id、key(今天为dev、qa、infra)、lead_agent_id、max_parallel(默认 2)agent_area_members:area_id、agent_id
qa 和 infra 继续带着已有成员诞生——机制成为来源,硬编码的列表从 agents.ts 中消失。gate 的外部合约不变:消费者看到的是每个 gate 一个裁定,与今天完全相同,而第 4 阶段的测试套件必须不经修改保持绿色。这就是来源的替换没有泄漏到区域之外的证据。
dev 区域在 activate-execution 中诞生,当前 module_map 中每个模块一个成员。
2. lead 决定,超过 2 时由用户授权
lead 评估手头的工作值得多少个 agent——它不再是代码中的一个数字。但他的决定对花费没有最高主权:
- 在
max_parallel(默认 2)以内,lead 启动 agent 并继续; - 超过这个数,就变成
parallelize类型的proposed_action,经由所有带外部效果的动作所走的同一审批流水线。用户决定,决定留在 event log 中。
上限是会话的,不是模块的。按模块计数会允许 N 个模块 × 2 个 agent 而无需任何授权,这就是换了个名字的今天的漏洞。
AcceptParallelizationUseCase(一次点击接受)被吸收:它变成这个 proposed_action 的批准路径,而不是与流水线并行的一个按钮。
3. max_parallel 可按 lead 配置
在设置界面中,每个 lead 有自己的值,默认 2。这是 lead 无需询问就能使用的上限——而不是用户可以批准的上限。
4. 当授权反复出现时,Anamnese 提议提高
当它察觉用户一再批准同样的请求时,会提议提高该 lead 的 max_parallel——采用它已在使用的同一假设机制,以真实 event id 为证据,由用户决定。
它不会自行提高。把这件事自动化就是产品在提高自己的花费上限,而这恰恰是审批流水线存在所要阻止的。
5. Dev Lead 是对话型 agent,接收来自 Arquiteto 的 handoff
这不是 Arquiteto 在启用时的角色:它是自己的 agent(dev-lead),有指令、模型 binding 和在对话中的位置,与 Criativo、PO 和 Arquiteto 一样。
链条变为 Arquiteto → Dev Lead → 执行。今天 Arquiteto 结束后,执行由用户的一个按钮启用,中间没有人评估工作;有了 Dev Lead 就有了关于并行的对话者——这正是 14d 的要点,也是“由 lead 决定”不沦为一句空话所需要的。
这契合已有的 handoff 规则,而不是开一个例外:外部 handoff 只指向区域 lead 或没有区域的 agent。今天 dev-<modulo> 是没有区域的 agent,因此可以被指向;一旦成为 dev 区域的成员,它们就不再可以——执行唯一的外部地址变成 Dev Lead。ADR 0038 的层级对 dev 适用,无需特例。
直接后果:
- 内部委派。 Dev Lead →
dev-<modulo>是区域委派,私有,在delegations表中,area = "dev"——与 QA 和 Infra 相同的路径。子 agent 的失败把来源报告给 lead,由 lead 决定并记录事件。 - “Ativar execução”按钮换主人。 它不再是触发器,而成为对 Dev Lead 计划的接受:他说明想要多少个 agent 以及原因,用户批准——在上限内无需仪式,超过上限则通过第 2 项的
proposed_action。 - 专属指令。 Dev Lead 需要知道的是
module_map、可领取的 backlog 和当前上限。他不写代码:他分配工作并为之负责。
已于 2026-08-07 答复: gate 之后的修正继续直接交给开出 PR 的
dev-<modulo>。这保持第 4 阶段测试套件和当前内部合约不变;与层级的一致性较弱,但可逆——以后在 lead 存在并被证明之后,可以改为经过 lead。在 Dev Lead 尚未实现的现在就做决定,将是在黑暗中选择。
后果
有利
- 并行的花费开始有上限也有主人。今天两者都没有。
- 区域机制不再是声明过的债务,而成为机制,第一个动态区域证明它适用于困难的情况。
budget por área(第 8 阶段切分中的另一项)只差一步:缺失的那张表开始存在。
不利
- 这是自第 8 阶段以来最大的结构性变化,并触及 handoff 流程:Arquiteto 改为交给 Dev Lead,而不是交给用户的手动启用。
- 多一个对话型 agent,就是每次执行在写任何代码之前多一个 LLM 轮次。它换来的是花费上限有了主人;如果他的计划在上限之内,他的成本就是请求本身的成本。
delegations.area今天是带有 "qa" 和 "infra" 的 TEXT;它会增加 "dev",并开始有一个在表中的事实来源。迁移需要保持历史可读。- 替换
qa/infra成员的来源对它们来说是纯粹的风险,没有直接收益——通过保持第 4 阶段测试套件不变作为验收标准来缓解。
考虑过的备选方案
没有 Dev Lead 的会话上限。 它会交付核心价值——带授权的花费上限——而不违反任何切分,这也曾是推荐方案。被拒绝,因为它让“由 lead 决定”没有主人:上限会存在,但没有人评估多少个 agent 值得,而那是 14d 所要求的一半。
只应用于 QA 和 Infra。 忠实于文本,今天就能实现,但价值很低:这两个区域成员固定,几乎没什么可决定的,也不触及 dev 的并行——那才是花费发生的地方。
代码中更大的固定数字。 这就是今天存在的东西换了个值。什么也解决不了:没有授权,任何数字都是任意的。