Files
Agent-System-Documents/docs/proposals/2026-10-07-agent-stack-q2q3-plans.md
T
weichen a042edaa73 Propose the Q2 and Q3 implementation plans: topologies and convergence
Why: N1-N3/Q1/I1-I2 are closed; per the completion doc dependency
order Q2 then Q3 are next. Both need plans grounded in current code:
squad has no topology abstraction (two modes, dormant Cond
combinators, dead FactItem.Verified), RespondDecision has no actor
attribution (the mailbox acceptance attack surface), WorkflowDef
execution compresses steps into SpawnSubagent, and adapters/a2a does
not exist.
Evidence: three-area survey with file:line citations at the pinned
baselines (agent-squad c462bc4, backend 6e02a1f); the review
equivalence baseline is quoted from backend runReview with its test
anchors; the P4 ruling is quoted verbatim from agent-harness.md.
Impact: documentation only; Q2 implementation starts after merge,
Q3 after Q2 closes.
Refs: 2026-10-02-agent-stack-completion.md Q2/Q3 sections
2026-10-07 23:27:56 +00:00

101 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 方案:Q2 拓扑 + Q3 收敛与互通——现状核验与增量实施
日期:2026-10-07。上游:[2026-10-02-agent-stack-completion.md](2026-10-02-agent-stack-completion.md)「Q2 拓扑」「Q3 收敛与互通」节(范围与验收的唯一权威)、[2026-10-01-agent-harness.md](2026-10-01-agent-harness.md) P4 裁定(Q3 行为等价的判据原文)。
基线 pin:agent-squad `c462bc4`、agent-native `1ac21c6`、backend `6e02a1f`、core `a253a40`(均为已合入 main)。本文所有 file:line 以这些 SHA 为准;实施时先复核再引用。
依赖状态:N1/N2/N3/Q1/I1/I2 全部闭卡。总提案依赖序「Q3 在 Q2、N1、I1 之后」满足。两阶段各自单独任务卡(本文覆盖两个方案;Q2 先实施,Q3 在 Q2 闭卡后开工)。
## 第一部分:Q2 拓扑
### 一、现状核验(三路侦察)
引擎面:只有 `standard`/`leader` 两个 mode(engine.go:94-96,383-400,RunMetadata.Metadata 字符串),**无拓扑抽象**。Q1 图层可表达 sequential(graph.go:62-68 链式默认)与 parallel(Parallel/Needs 同层 + 写集串行,graph.go:56-61,165-182);环 fail-closed(graph.go:71-73)。router 只有 pre-plan 分诊(router.go:24-52)。leader 有 delegation 循环(leader.go:180-385)但账本只有 `Delegations`(leader.go:51-66),无卡顿检测;轮次上限有(MaxLeaderTurns=8,termination.go),**无独立重规划上限**;leader 绕过图循环直接 runOneStep(leader.go:328-341)。Termination 的 Cond/And/Or 组合子(termination.go:59-120)已建但**休眠**(只有测试消费)。`FactItem.Verified`(models.go:148)声明未用。
mailbox 攻击面:`RespondDecision`(hitl.go:99-108)**无 actor 归属**——任何能调 `engine.Respond` 的调用方发 `Choice:"approve"` 都清权限门。现有防线:fireWakeup 只自动决 gap/escalation(engine.go:1216-1227,回归 TestWakeupDoesNotApprovePermission)、自由文本不决议 choice 门、过期只合成 fail/cancel、wakeup 上限自动 abort。mailbox 若经 Respond 投递或扩 fireWakeup 白名单即破防。
review 等价基线(backend runReview,review.go:41-92):并行 N finder(semaphore 3,真并发被 review_test.go:16-33 钉住)→ 宽松 JSON 解析(首 `[` 末 `]`,丢空 issue)→ 按 (location,issue) 去重、上限 10 → 每条独立 verifier(VERDICT: PASS/FAIL/PARTIAL 尾行判定)→ 只留 PASS(fail-closed)→ severity 稳定排序 → 报告恒带「已丢弃 N 条未验证」。squad 侧今天只有质量 Checker+修复预算(单轮),无此拓扑。
task-board/long-running:平台 SQLite 队列有 claim/lease/heartbeat/orphan 恢复(adapters/sqlite/queue.go:133-348)但未接 Steps 图;checkpoint 三档+图连续性+run 锁已就位(runstore.go:94-212)。conformance 基建齐全:scriptBackend/replayBackend/leaderScriptBackend + MockPlanner(engine_test.go:13-80、conformance_test.go:19-47、leader_test.go:15-90)。
### 二、设计决策
1. **拓扑一等化但不做大重构**:`Blueprint` 与 `RunOptions` 增 `Topology string`(空 = 现行 standard 图,零行为变化);`squad/topology.go` 注册内置拓扑名与各自 Spec。图可表达的(sequential/parallel/loop/router/evaluator-optimizer/long-running)编译为 Steps+引擎旗标;需要独立驱动的(leader 增强/review/group-chat/task-board)走驱动分支;handoff/mailbox 是**跨拓扑原语**(任何拓扑可用)。
2. **loop 不做图环**:保持环 fail-closed。`StepSpec.Loop *LoopSpec{MaxIterations, UntilField, UntilEquals}`——步骤完成后条件不满足且预算未尽时**重置为 pending 再武装**(推广 rerunForRepair 语义);预算走 Termination(唤醒休眠的 Cond 组合子)。
3. **router 进图**:`StepSpec.Branches []Branch{When{Field,Equals}, Then []stepID}`——router 步完成后按黑板字段/步骤输出判定,未选中分支的步骤置 skipped(skipped=依赖已满足,join 步照常推进)。
4. **mailbox 的防线是构造性的**:投递路径**永不经过 Respond**;同时给 `RespondDecision` 加 `Actor`(human/system/agent,空=human 保持既有调用方语义),`applyDecision` 对 permission/confirmation/quality_review 三类门拒绝非 human 的 choice 决议(双保险)。
5. **review 等价以报告字节形态为判据**:squad review 驱动复用 backend runReview 的解析/去重/判定/排序/文案常量(同一格式串),conformance 断言与 review_test.go 同款(并发找、去重后逐条验、丢弃计数、severity 序)。
6. **task-board 做 squad 侧原语**(claim/lease/complete + 依赖门),语义与平台队列对齐;平台队列桥接记为后续项(completion doc 的「platform 队列改成 task-board」在桥接层,非本 WP 阻塞)。
### 三、工作包
| WP | 内容 | 验收对应 |
|---|---|---|
| Q2-WP1 | 拓扑面 + 图可表达五件:Topology 字段与注册表;sequential/parallel conformance;loop 再武装(LoopSpec+Cond 预算);router 分支(Branches+skipped);evaluator-optimizer(loop 复合:draft→evaluate→MinScore 不达标再武装,MaxRounds 预算);long-running(Deadline 打包进 terminationOf + checkpoint 组合 conformance) | 验收一(6/12 拓扑) |
| Q2-WP2 | leader 增强 + mailbox:进度账本(Progress 条目+卡顿检测 StuckTurns)、重规划上限(Replans/MaxReplans 独立于 MaxTurns,触顶降级收口);mailbox 原语(RunState 邮箱、PostMessage、步前投递进任务书、永不触 Respond)+ RespondDecision.Actor + 非 human 决议拒绝 | 验收一(8/12)+ 验收三 |
| Q2-WP3 | review + handoff + group-chat:review 驱动(并行 finder→解析去重→逐条 verify→fail-closed 过滤→等价报告);handoff 原语(StepSpec.Handoff、所有权转移记录、finalize 取链尾输出、目标收过滤历史);group-chat 驱动(共享转录、轮转/主持人选人、预算停机) | 验收一(11/12)+ 验收二 |
| Q2-WP4 | task-board + 收口:claim/lease/complete 原语与依赖门、孤儿租约再武装;全 12 拓扑 conformance 汇总跑;级联(backend 嵌套 pin → Dev) | 验收一(12/12) |
conformance 统一形态:脚本化后端(scriptBackend/replayBackend/leaderScriptBackend 家族扩展),零模型零网络;每拓扑一个 `TestTopologyConformance_<name>`。
### 四、Q2 验收总表
| 总提案验收 | 机器证据 | WP |
|---|---|---|
| 每种拓扑有一个脚本化后端的 conformance | 12 个 TestTopologyConformance_*(sequential/parallel/loop/router/leader/handoff/group-chat/review/evaluator-optimizer/long-running/task-board/mailbox) | WP1-4 |
| review 等价于今天的「并行找问题、逐条验证、丢掉未验证」 | review conformance 断言与 backend review_test.go 同款:finder 真并发、去重后 verify 调用数=unique 数、只留 PASS、「已丢弃 N 条未验证」计数、severity 序 | WP3 |
| mailbox 消息不能把挂起的权限批准掉 | TestMailboxCannotApprovePermission(挂 permission 门→投「approve」消息→门仍挂起)+ TestWakeupDoesNotApprovePermission 原样通过 + Actor 拒绝路径测试 | WP2 |
### 五、Q2 边界与非目标
- 不改 leader 绕过图循环的执行形态(记为已知债,统一驱动属后续重构)。
- 平台队列桥接、backend review_findings 切换到 squad review 拓扑:后续项(Q3+ / RDM 阶段按需)。
- group-chat 的发言人策略只做轮转与主持人两种(脚本可判定);LLM 选人策略不进库。
- Termination Cond 组合子被 loop/long-running 唤醒后,既有标量路径不动。
## 第二部分:Q3 收敛与互通
### 一、现状核验
WorkflowDef 在 core(plugin.go:56-84):六类步骤(prompt/tool/hitl/artifact/card/script)+ StepCritic,**无条件分支字段**;golden 样本 workflow_def.json。执行器 `runtime/workflow.go`(步循环 125-200、critic 重试 202-244、prompt 步压 SpawnSubagent 312-334)+ `workflow_script.go`(脚本宿主 38-56、限额 19-24、DeniedTools 180)。数据层 `internal/workflow/`(registry/render/validate,P4 上限 11-16)。**「压成 SpawnSubagent」退役对象**:squadadapter stepBackend "agent-system"(adapter.go:150-212,DefaultBackend adapter.go:79,内置四角色全部 agent-system 380-392)。
P4 裁定原文(agent-harness.md:102-112):声明式 ≤20 步;模型生成 ≤8 步、禁 script、执行前必须确认;critic 每步 ≤3(缺省 1)、整条 ≤6、无法解析按不通过;脚本回调 ≤50、单行 ≤1MB、超时 600/1800s 含等人;`runtime.workflowScripts` 默认关;模型脚本必须确认、**插件脚本免确认**;脚本禁 run_python/run_shell/run_workflow/派发类;小队入口无 run_workflow。代码落点齐全(validate.go:11-40,80-83;workflow.go:64-76;workflow_script.go:26-28,38-56,103-115)。
demo 插件在 Dev 仓根 `plugins/example/`:demo.brief(意图 demo.brief,五步:hitl choice→prompt+critic「核对标记:P4」→artifact→card→hitl confirm)、demo.script(单 script 步 → demo.py:wf.tool/wf.ask/wf.artifact/wf.step)。host_test.go:214-256 直接装载它。
a2a:**全仓不存在**,从零建(规划位置 agent-squad/adapters/a2a 独立 go.mod;A2A 1.0 Agent Card/任务状态机对齐,completion doc:54,102,239)。默认执行后端:`runtime.entry` 默认 direct(settings.go:39,灰度注释);direct 已跑 agent-native 内核;squad 工具路径默认后端 "agent-system"(要切);RunEntry 已是 agent-native(entry.go:103)。A/B:eval/switch.go 的 DecideSwitch 骨架 + N1 wp5_ab_test.go 先例;缺「同批任务双跑记录差异」harness。委派模板:内核 SubagentFactory 已有 目标/输入/可写范围/非目标/完成判据/交付物(adapter.go:299-343),**缺「输出格式」与「工具面」**两节。
### 二、工作包
| WP | 内容 | 验收对应 |
|---|---|---|
| Q3-WP1 | 编译器:core.WorkflowDef → squad Blueprint/Steps(prompt→agent-native 角色步、hitl→RequiresApproval/intent 步、tool/artifact/card→宿主工具步、script→codeorch 宿主步、critic→Checker+MinScore+RepairBudget;P4 全部上限与 DeniedTools 迁入编译器;计划确认与模型脚本确认保留、插件脚本免确认、workflowScripts 开关保留) | demo.brief/demo.script 经编译图跑通 |
| Q3-WP2 | 退役与切换:删 internal/workflow 数据层执行依赖、runtime/workflow.go+workflow_script.go 退役(run_workflow 三分支改投编译图)、stepBackend "agent-system" 删除、DefaultBackend→agent-native、runmgr WorkflowRunner 分支移除 | P4 行为一致(步数上限/确认/脚本开关逐项测试) |
| Q3-WP3 | 委派模板补全:任务书增「输出格式」「工具面」两节(SubagentFactory 与 stepBackend 遗产路径统一);adapter_test 任务书断言扩展 | 委派模板含目标、输出格式、工具和边界 |
| Q3-WP4 | adapters/a2a(新模块):Agent Card 发布(描述本团队能力)+ 远端智能体 Executor 客户端(A2A 任务状态机对齐 ExecResult);双向 conformance(本地起假 A2A 服务端) | adapters/a2a 双向 |
| Q3-WP5 | A/B 对照与默认后端:任务级 direct vs squad(编译图) 双跑 harness(扩 eval/switch.go),同批任务(含 demo.brief 场景)记录差异(不要求字节级相同);DecideSwitch 达标则 runtime.entry 默认切 squad 的证据入卡 | A/B 对照记录差异 |
| Q3-WP6 | 级联闭链 + 任务卡验收证据 | — |
### 三、Q3 验收总表
| 总提案验收 | 机器证据 | WP |
|---|---|---|
| demo.brief 与 demo.script 经编译后的图跑通 | 装载 Dev 仓 plugins/example → 编译 → squad 引擎(脚本化后端)跑通两个工作流的 conformance | WP1 |
| 行为与 P4 裁定一致(步数上限、确认、脚本开关) | 逐项测试:20/8 步上限、3/6 重试、计划确认卡、模型脚本确认、插件脚本免确认、workflowScripts 默认关、DeniedTools、小队入口无 run_workflow | WP1-2 |
| A/B 对照记录差异,不要求字节级相同 | eval harness 输出差异报告入任务卡(DecideSwitch 判定 + 差异清单) | WP5 |
### 四、Q3 边界与非目标
- `runtime.entry` 默认值切换本身是**设置变更**:A/B 达标后由 WP5 证据支持、在卡上记录,若 DecideSwitch 不达标则保持 direct 并记录差异(验收只要求「对照记录差异」)。
- a2a 只做库层双向(Card 发布 + Executor 客户端 + 假服务端 conformance);产品暴露 A2A 端点属后续。
- 平台 task 队列翻译成 squad run(更深的产品合一)不在 Q3(completion doc 归 Q 系列后续)。
- internal/workflow 的**数据形态**(WorkflowDef 校验/渲染语义)迁入编译器后原包删除;golden 契约样本随迁。
## 五、风险与回退(两阶段共用)
- **Q2 loop 再武装**与修复重跑共用重置语义:以「预算独立计数」隔离(loop 迭代不占 RepairBudget),测试钉住互不侵占。
- **Q2 router skipped 传播**:skipped=依赖满足的既有语义使 join 步在分支未选时照常推进——conformance 钉住 join 行为,防止「全分支跳过导致空转完成」被误判成功(报告需列 skipped 分支)。
- **Q3 退役面大**:以「编译器先行、双轨并行一个增量、退役单独增量」推进;退役 PR 前 demo 插件双轨对照(旧 runner vs 编译图)记录差异。
- **Q3 默认后端切换**:行为变化门禁是 A/B harness,不达标不切(settings 默认值不动即回退)。
- mailbox/Actor 默认值兼容:空 Actor=human 保持全部既有调用方与测试语义不变(新增拒绝路径只影响显式非 human)。