来源:#199 架构审查 grilling 后缓抽 的独立加深项(2026-07-20)。本 issue 承接该共识,独立于 #199 推进。
依赖 :建议在 #199 (装配收拢)落地后再做。
背景
src/main/deepagent/runtime.ts 中 buildDeepAgentRuntime(约 line 633)内有一个 ~120 行的 delegatedRuntimeAdapter.run 闭包,它是 ADR-0061「每个 Delegated Agent Run 拥有隔离运行时」的实现本体 ——子 model / child graph / MemorySaver / 工具 scope 收窄 / 审批门控全在其中。
deepagent 已形成 8 个聚焦的 delegated-* 模块(configuration-snapshot / run-coordinator / run-repository / model-selection / run-failure / subagent-adapter / tool-action-repository / tool-approval-scheduler),此闭包是唯一仍陷在装配 god-file 里的委派逻辑 。
为什么从 #199 缓抽(而非遗漏)
它是审批/工具门控的业务最高风险路径 ,承载:
ADR-0061 隔离运行时
ADR-0062 工具 scope 只收窄不扩大
ADR-0063 审批模式继承自父运行
Delegated Failure Isolation(失败隔离)
把它 relocation 捆进 #199 那种「行为保持」的结构重构,会使任何审批回归无法归因 (结构改动 vs 逻辑改动)。它是可干净分离的独立加深,应单独做、先补测试再动结构。
方案
把闭包抽成显式工厂,补全 delegated-* 族:
createDelegatedRuntimeAdapter(parentContext): DelegatedRuntimeAdapter
DelegatedRuntimeAdapter 接口已存在 (delegated-agent-run-coordinator.ts:69,单方法 run(request)),seam 非 hypothetical——coordinator 已依赖它。
抽出后获得专属测试面 :可单测「配置快照 + 父上下文 → 隔离运行时」,不必整体起一个 root run。
关键设计输入(动结构前需先解决)
父→子继承契约要收窄成刻意设计的窄接口 。闭包当前隐式捕获约 10 项父级上下文:currentApprovalMode、builtInToolNames、allMcpServers、mcpServers、skillSnapshot、provider、project、overrides、sessionId、delegatedRunCoordinator。需甄别哪些是子运行真正需要继承 的(对应 CONTEXT.md 的 Delegated Permission Context / Agent Tool Scope / Conversation Skill Snapshot 传播),哪些是偶然捕获,收进一个内聚的 parentContext,避免做成「把父运行内部全漏给委派模块」的浅 seam。
解开 coordinator ↔ adapter 循环 :当前 adapter(633) 在闭包体内引用 coordinator(760),coordinator(760) 又持有 adapter,靠闭包延迟绑定。抽成独立模块后需改为 coordinator 以参数/thunk 注入。
前置 / 验收
不做(domain-modeling 纪律)
不更新 CONTEXT.md:用到的 Delegated Agent Run / Agent Tool Scope / Delegated Permission Context 均为既有领域词。
不立 ADR:这是排序决策的承接项,非「拒绝且防重提」。
Spec(/to-spec 调研补充,2026-07-26)
调研结论:问题仍然存在,且前置已满足 ——#199 装配收拢已合入(装配模块已抽出),但 delegatedRuntimeAdapter 闭包原封未动仍在 runtime god-file 内(约 130 行),是 issue 预判的"唯一仍陷在装配文件里的委派逻辑"。
前置验收项的现状盘点:
Architecture review 01 — Collapse the Agent Run assembly god-file #199 落地 ✅;两个集成测试(parallel-delegated-runtime、delegated-agent-run contract)均存在。
纯函数层已有专属单测 ✅:工具 scope 收窄(agent-tool-scope)、审批中断解析(shared-infra 的 interrupt 解析)、模型选择(delegated-model-selection)、配置快照、coordinator、审批调度器。
缺口 :闭包的组合行为(配置快照 + 父上下文 → 隔离运行时)没有任何单元级测试面,只能靠整跑集成测试覆盖;失败分类模块(delegated-run-failure)无专属测试。这正是本票要创造的测试面。
循环确认:闭包体内引用 coordinator(审批中间件构造处),coordinator 又持有 adapter,靠闭包延迟绑定——与 issue 描述一致。
闭包实际隐式捕获的父级上下文核对为:审批模式、父内建工具名集、父 MCP server 集与全量 MCP 目录、Conversation Skill Snapshot、provider、模型 overrides(含 allowedTools)、Project 与 Agent 文件根、Conversation 标识、coordinator(循环项)。与 issue 所列一致。
Problem Statement
Delegated Agent Run 的隔离运行时构造——业务上审批/工具门控风险最高的路径——是装配文件里一个约 130 行的匿名闭包。维护者无法单独测试"给定配置快照与父上下文,子运行时是否正确隔离、正确收窄、正确继承审批模式";任何审批回归都无法归因到结构改动还是逻辑改动;父→子的继承契约是隐式的闭包捕获,谁也说不清哪些捕获是刻意设计、哪些是偶然。
Solution
把闭包抽成显式工厂,补全 delegated-* 模块族:工厂接收一个刻意设计的窄父上下文接口 ,返回 coordinator 已依赖的既有 DelegatedRuntimeAdapter(单方法 run(request))。父→子继承项从隐式捕获升级为显式契约字段;coordinator ↔ adapter 的闭包延迟绑定改为显式注入(审批门控能力以延迟提供者注入 adapter,而非让 adapter 持有整个 coordinator)。行为零变更;装配文件只剩组合调用。
User Stories
作为 CDF 维护者,我想让"配置快照 + 父上下文 → 隔离运行时"可以脱离完整 root run 单独测试,以便审批/门控回归能在单元层被拦住。
作为 CDF 维护者,我想让父→子继承契约成为一个显式的窄接口,以便评审时能看出每个继承项对应哪条领域规则(Delegated Permission Context / Agent Tool Scope / Conversation Skill Snapshot 传播),而不是从闭包捕获里逆推。
作为 CDF 用户,每个 Delegated Agent Run 继续拥有隔离运行时:子模型、子图、内存 checkpointer、受限文件后端各自新建,父运行状态不被子运行污染(ADR-0061 行为不变)。
作为 CDF 用户,Delegated 工具 scope 继续只收窄不扩大:子运行可用工具永远是父可用集合经目标 Agent 配置与快照排除后的子集(ADR-0062 行为不变)。
作为 CDF 用户,Delegated 运行继续继承父 Conversation 的审批模式:父运行需要审批的工具类别,子运行同样进审批门控,不多不少(ADR-0063 行为不变)。
作为 CDF 用户,单个子运行失败继续被隔离为结构化失败结果,不拖垮父运行与并行批次中的其他子运行(Delegated Failure Isolation 行为不变)。
作为 CDF 用户,子运行的 Skill 预载继续只能从 Conversation Skill Snapshot 内选择,快照冻结语义不变。
作为 CDF 用户,单发与并行委派继续共享同一 coordinator 的并发窗口、持久身份与运行时工厂,进度与审批投影行为不变。
作为 CDF 维护者,我想让审批回归可归因:结构迁移提交不含逻辑改动,逻辑改动(若未来有)发生在有专属测试面的模块里。
作为 CDF 维护者,我想消除 coordinator ↔ adapter 的隐式循环,让依赖方向可从构造签名读出。
作为测试作者,我想用假的图执行器与假的 MCP 装载在 adapter 接缝上断言子运行时的组成(工具集合、门控集合、系统提示、模型选择、checkpointer 隔离),不真正调用模型。
作为 CDF 维护者,我想为失败分类补上专属单测,明确各类子运行失败(无效结构化输出、中断、超限、异常)映射到的结构化结果。
Implementation Decisions
既有 seam 复用 :不新增接口形状——工厂返回 coordinator 已依赖的 DelegatedRuntimeAdapter(单方法 run(request)),DelegatedRuntimeRequest 契约不变。全库新增 seam 数为一(工厂本身)。
窄父上下文接口 :显式字段限定为调研核对出的继承项——审批模式(ADR-0063)、父内建工具名集与父 MCP 标识(ADR-0062 收窄基线)、全量 MCP 目录(供快照排除后的子候选集)、Conversation Skill Snapshot、provider 标识与模型 overrides(委派模型选择输入)、Project 根与 Agent 文件根(文件系统限域)、Conversation 标识。不得把父运行其余内部状态漏进该接口。
解循环 :adapter 需要的审批门控能力(为门控工具构造审批中间件)以延迟提供者/回调注入,coordinator 构造后完成绑定;adapter 不再引用 coordinator 整体。
模块归属 :新工厂加入 delegated-* 模块族,与配置快照、run coordinator、模型选择、失败分类、审批调度器并列;装配文件(runtime)只做组合:构造父上下文 → 建工厂 → 建 coordinator → 注入门控提供者。
可注入执行依赖 :图构建(deepagents createDeepAgent)与 MCP 工具装载在工厂依赖中可注入,生产默认用真实实现——这是获得单元测试面的前提,不改变生产行为。
行为零变更 :子运行时组成、审批继承、scope 收窄、失败隔离、结构化结果解析、进度回调、并发窗口全部逐行为保持;本票不顺手修任何逻辑。
提交纪律 :先补测试(见下),后做纯结构迁移,两个提交独立可回滚。
Testing Decisions
好的测试只验证外部行为:给定配置快照 + 父上下文 + 假执行依赖,断言子运行时的可观察组成与结果——子工具集合是父集合的收窄结果、门控集合等于按父审批模式解析的集合、Skill 预载 ⊆ 快照、模型选择输出、无效结构化输出降级为截断摘要成功结果、中断出现时报审批不可用错误;不断言闭包内部结构或调用次序。
结构迁移前 先在现有整体(经 coordinator + 假 adapter 或集成测试)补齐三条领域规则的行为锚点:审批继承(ADR-0063)、scope 只收窄(ADR-0062)、失败隔离——迁移后同样的断言在工厂接缝上重写为单元测试。
为失败分类模块补专属单测(各失败形态 → 结构化结果字段),填补现有空白。
先例:coordinator 测试的假 adapter 注入写法、delegated-model-selection 的纯函数测试写法、两个 deepagents 集成测试(迁移后必须全绿,作为零行为变更的最终判据)。
验证:pnpm test 覆盖 deepagent 全簇;重点回归 parallel-delegated-runtime 与 delegated-agent-run contract 两个集成测试。
Out of Scope
Further Notes
背景
src/main/deepagent/runtime.ts中buildDeepAgentRuntime(约 line 633)内有一个 ~120 行的delegatedRuntimeAdapter.run闭包,它是 ADR-0061「每个 Delegated Agent Run 拥有隔离运行时」的实现本体——子 model / child graph /MemorySaver/ 工具 scope 收窄 / 审批门控全在其中。deepagent 已形成 8 个聚焦的
delegated-*模块(configuration-snapshot / run-coordinator / run-repository / model-selection / run-failure / subagent-adapter / tool-action-repository / tool-approval-scheduler),此闭包是唯一仍陷在装配 god-file 里的委派逻辑。为什么从 #199 缓抽(而非遗漏)
它是审批/工具门控的业务最高风险路径,承载:
把它 relocation 捆进 #199 那种「行为保持」的结构重构,会使任何审批回归无法归因(结构改动 vs 逻辑改动)。它是可干净分离的独立加深,应单独做、先补测试再动结构。
方案
把闭包抽成显式工厂,补全
delegated-*族:DelegatedRuntimeAdapter接口已存在(delegated-agent-run-coordinator.ts:69,单方法run(request)),seam 非 hypothetical——coordinator 已依赖它。关键设计输入(动结构前需先解决)
currentApprovalMode、builtInToolNames、allMcpServers、mcpServers、skillSnapshot、provider、project、overrides、sessionId、delegatedRunCoordinator。需甄别哪些是子运行真正需要继承的(对应 CONTEXT.md 的 Delegated Permission Context / Agent Tool Scope / Conversation Skill Snapshot 传播),哪些是偶然捕获,收进一个内聚的parentContext,避免做成「把父运行内部全漏给委派模块」的浅 seam。前置 / 验收
parallel-delegated-runtime.deepagents.integration.test.ts、delegated-agent-run.deepagents-contract.integration.test.ts)全绿。不做(domain-modeling 纪律)
CONTEXT.md:用到的 Delegated Agent Run / Agent Tool Scope / Delegated Permission Context 均为既有领域词。Spec(/to-spec 调研补充,2026-07-26)
Problem Statement
Delegated Agent Run 的隔离运行时构造——业务上审批/工具门控风险最高的路径——是装配文件里一个约 130 行的匿名闭包。维护者无法单独测试"给定配置快照与父上下文,子运行时是否正确隔离、正确收窄、正确继承审批模式";任何审批回归都无法归因到结构改动还是逻辑改动;父→子的继承契约是隐式的闭包捕获,谁也说不清哪些捕获是刻意设计、哪些是偶然。
Solution
把闭包抽成显式工厂,补全 delegated-* 模块族:工厂接收一个刻意设计的窄父上下文接口,返回 coordinator 已依赖的既有
DelegatedRuntimeAdapter(单方法run(request))。父→子继承项从隐式捕获升级为显式契约字段;coordinator ↔ adapter 的闭包延迟绑定改为显式注入(审批门控能力以延迟提供者注入 adapter,而非让 adapter 持有整个 coordinator)。行为零变更;装配文件只剩组合调用。User Stories
Implementation Decisions
DelegatedRuntimeAdapter(单方法run(request)),DelegatedRuntimeRequest契约不变。全库新增 seam 数为一(工厂本身)。Testing Decisions
pnpm test覆盖 deepagent 全簇;重点回归 parallel-delegated-runtime 与 delegated-agent-run contract 两个集成测试。Out of Scope
Further Notes