diff --git a/docs/rpa-core-migration-guide-v2-diff.md b/docs/rpa-core-migration-guide-v2-diff.md new file mode 100644 index 0000000..c3c6a31 --- /dev/null +++ b/docs/rpa-core-migration-guide-v2-diff.md @@ -0,0 +1,66 @@ +# 迁入指南 V1 → V2 差异清单(含审查报告修正记录) + +> 配套文档:`docs/rpa-core-migration-guide-v2.md`(V2 正文)。 +> 本文记录三件事:① V1 各断言在真实源码下的判定;② 审查报告(docs/RPA-Review-Full.md)与真实源码不一致处的修正及理由;③ V2 新增内容清单。 +> 核查基线:2026-11-06 双侧真实工作区源码。 + +--- + +## 一、V1(rpa-core-migration-guide.md)逐项判定 + +分类口径:**保留** / **需要修改** / **过时或不再适用** / **尚未实现(V1 写成了现状或反之)**。 + +| # | V1 断言/内容 | 判定 | 真实源码依据(2026-11-06) | +|---|---|---|---| +| 1 | 包现状:719 能力、34 域、宿主桥 4 方法、五域 Driver | **保留** | 实测 capabilityCount()=719;DOMAINS/PLATFORM_GROUPS 34 域;host-bridge.ts 仍 4 方法+SubflowSource 2 方法 | +| 2 | "完全不依赖 Electron,check:deps 谁加就报错" | **过时(不实)** | vision.ts:18,66,432 + cv-vision.ts:51,213 共 5 处动态 `import("electron")`;check-deps.mjs:20 正则 `import\s+` 对 `import("electron")` 零匹配(实测),护栏从未能拦住 | +| 3 | "npm run rpa-cli 证明能独立跑" | **需要修改** | rpa-cli.ts:25 仍有副作用全量 import、:53-59 全局 getHandler 直调,只能证明能力可跑,不能证明注入/隔离/无 Electron | +| 4 | 第 -1 步:"对面 7 个契约包每个只有 1-9 个声明文件,都是空壳" | **过时(核心叙事失效)** | workflow-engine 25 文件完整实现;capability-gateway 321 行实现;browser-plugin 已接 playwright-core(358 行 Runner);windows-plugin 新增 native-observer.ts(292 行);runtime-governance 有 readiness 投影;windows-runner 17 文件(C# FlaUI observe-only)。仍空壳的只剩 computer-control Runner 与 WindowsRunner.click/type | +| 5 | "迁入本质 = 拿 rpa-core 实现去填对面的契约" | **需要修改** | 改为"接底座 + 让路":不重复造状态机/浏览器/UIA 观察,RPA 补的是执行半边(WindowsRunner.click/type、CDP 接管场景)与 719 能力规模 | +| 6 | 第 0 步作业 #2"重新生成 catalog 让 platformTag 生效(当时没生效)" | **已完成(V1 写成待办)** | 2026-11-05 已重生成:win32=687 / null=326;残留 3 个数字 1 脏值待清洗 | +| 7 | 第 0 步作业 #1 Bun 冒烟 | **尚未实现** | bun 未安装,未跑过任何 Bun test | +| 8 | 第 0 步作业 #3 注册方式决策 | **需要修改** | 并入 ADR-R1(全局表 vs engine-scoped);rpa-cli 仍用旧方式 | +| 9 | 第 1 步:搬包位置 `code/backend/packages/rpa-core`、改名 `@agent-worker/rpa-core`、git subtree、demo 冻结 | **保留** | backend package.json workspaces 含 `packages/*`、全包 `@agent-worker/*` 前缀、`workspace:*` 源码消费——核实无误 | +| 10 | 第 2 步 A:capability-gateway"对照后改,不自建 allowlist" | **需要修改** | gateway 已实现(authorize/execute/租约 60s/幂等/高影响审批),工作是写 adapter 而非"对照设计" | +| 11 | 第 2 步 A:workflow-engine"状态模型对齐" | **需要修改** | 对面状态机已实现并稳定(含 waiting_approval/waiting_user/unknown 态);RPA 侧缺 waiting_user/unknown;集成形态二选一(ADR-R2) | +| 12 | 第 2 步 A:computer-control/windows-plugin "五域 driver 与契约对照" | **需要修改** | 契约依旧(Runner 无实现),但出现新硬约束:对面安全模型禁止任意 PowerShell(native-observer.ts 约束注释 + *.exe 白名单)→ ADR-R3 | +| 13 | 第 2 步 B:内置浏览器"最大变数,对面还没定型" | **过时(变数已收敛)** | PlaywrightBrowserRunner 已实现(白名单三重检+证据);变数变为"双路径取舍"(ADR-R4) | +| 14 | 第 2 步 B:宿主桥 4 方法 + SubflowSource 2 方法注入 | **保留**(落点补充) | 对面 desktop 主进程无现成宿主桥,但有等价物(identity-login-window/execution-context/zoom.ts);新增 ScreenCaptureHost 注入面(vision 迁移所需) | +| 15 | 第 2 步 B:"AI 能力接对面模型网关" | **保留并具体化** | model-gateway 已实现(stream + ModelControlPlane 每次调用授权);RPA ai-service 仍读 HostBridge.loadAiConfig,改造点明确 | +| 16 | 第 3 步 7 条验收 | **需要修改** | 扩充为 10 条总验收(加 gateway 零调用、取消传播、双 Engine 隔离、Graph Validator、纯 Node 加载) | +| 17 | 三端计划"搬家前 5 件小事" | **已完成(V1 写成待办)** | ① PLATFORM_GROUPS 单一源+守卫测试 ✅ ② 驱动自动选+platform_unsupported ✅ ③ COM 分组核查 ✅ ④ 5 个测试补 skipIf ✅ ⑤ driver/platform.ts 收拢 ✅(2026-11-05 落地) | +| 18 | 三端计划"搬家之后按平台写驱动" | **保留**(补约束) | 驱动实现统一走 ADR-R3 原生通道;Linux 容器不能跑桌面 Runner(对面 README 约束) | +| 19 | 附 10 决策 #2"保留全局注册表"、#9"注册双入口过渡" | **需要修改(重开 ADR)** | 与对面多租户/插件模型冲突,重开 ADR-R1;其余 8 个决策维持 | +| 20 | "浏览器:外部浏览器(CDP)进包,内置浏览器留宿主"(决策 5) | **保留**(补 ADR) | 仍成立,但需 ADR-R4 明确与 Playwright 的关系 | + +## 二、审查报告(RPA-Review-Full.md)与真实源码不一致的修正 + +以真实源码为准,逐条记录修正理由: + +| # | 审查报告断言 | 真实源码(2026-11-06) | 修正理由 | +|---|---|---|---| +| 1 | §3 P1-NEW-03 / 附录 P0-03:Engine 完全无注入,`driver` 固定 `new WindowsDriver()` | **部分过时**:driver 已改惰性 getter,非 win32 抛 platform_unsupported(engine.ts:47-61 + error-codes.ts:43 + engine-driver.test.ts) | 报告基于 11-06 前的 ZIP 快照;此后落地了"驱动按平台自动选择"。但"createEngine() 无注入参数"这一半仍属实 | +| 2 | §8.3 / 附录 P1-01:catalog 1016 项里 1013 项 platformTag=null、3 项数字 1,"平台标记从未生效" | **部分过时**:现为 win32=687 / null=326 / 数字 1=3 | PLATFORM_GROUPS 单一源落地后重生成过 catalog。"3 个数字 1 脏值透传(build-catalog.mjs:246 对 truthy 不清洗)"仍属实,保留为待办 | +| 3 | §12.4:"跟随前台标签页无条件取 pages[0]" | **需限定范围**:followForegroundTab 本身仍取 pages[0](session.ts:211),但 withElementOnce/locateOnce 已改两段式(当前页优先、失败才跟随,:296-307/:518-523);evaluate 默认 follow=true 仍会先切 | 该缺陷的暴露面已从"所有元素操作"缩小到"跟随函数本身+evaluate 默认路径",严重度下调,但未根除 | +| 4 | §6 P0 行"Engine 无 Driver 注入;能力使用 defaultEngine" | **属实且更严重**:desktop.ts:9 在模块加载时捕获 `defaultEngine.driver`,非 win32 上 import 即抛错(比报告写的"使用时才碰到"更早暴露) | 复核确认,问题加重一档 | +| 5 | §3 P1-NEW-02:包依赖缺 @napi-rs/canvas/pdfjs-dist/@cantoo/pdf-lib | **属实(复核确认)**:rpa-core/package.json:17-32 仍缺这 3 项,main/exports 直指 src | 无修正,维持 P1 | +| 6 | §12.1:locate 与 withElement 对 xpath/Shadow DOM 支持不一致 | **属实(复核确认)**:locateOnce :465-517 仅 text/aria/else 三分支 | 无修正,维持 P1 | +| 7 | §12.3:CDP send() 无单命令超时/AbortSignal | **属实(复核确认)**:transport.ts:96-118 | 无修正,维持 P1 | +| 8 | 附录 P2-04:AI 请求无调用方 signal | **属实(复核确认)**:ChatCompletionOptions(ai-service.ts:39-48)无 signal 字段 | 无修正,维持 P2 | +| 9 | §12.5:桌面拾取无 AbortSignal | **属实(复核确认)**:desktop-pick.ts 全文零 signal 命中(取消是热键+轮询自有机制) | 无修正,维持 P1 | +| 10 | §2.2 "尚未完成 Agent-Employee 真实契约的编译级对接;当前没有 Agent-Employee 目标仓库真实源码作为本轮输入" | **已过时**:本机已有 D:/code/Agent-Employee 真实工作区,V2 已完成逐接口核查 | V2 的核查基线即基于该仓库 | +| 11 | 附录 §8 ADR 表"Driver 契约:RPA Driver 是否直接实现 computer-control?建议对齐宿主契约" | **升级为阻塞项**:对面的安全约束(禁任意 PowerShell、*.exe 白名单)与 RPA 驱动实现方式正面冲突,不是"对齐一下"而是二选一(V2 ADR-R3) | native-observer.ts 设计约束注释明示"不执行任意 PowerShell",为 V1 快照中没有的新事实 | +| 12 | 报告整体:审查对象是资料库 ZIP 快照(无 node_modules、未装依赖) | **V2 基线升级**:真实工作区 + 依赖已装 + 可实测(正则盲区构造用例、catalog python 统计、tsx 实测 capabilityCount=719) | 结论可信度提升;仍保留"未做实机 E2E/联调"的边界 | + +## 三、V2 相对 V1 的新增内容 + +1. **双侧事实清单**(V2 §2/§3):24 项 RPA 侧 + 12 项宿主侧,全部带 `文件:行号` 证据与状态标记——V1 无此层。 +2. **宿主侧巨变披露**:plugin-registry/plugin-worker(对面真实插件宿主)、model-gateway、Java 控制面(Spring Boot 454 文件、OpenAPI+Outbox、端口分工)、evidence-store——V1 完全未提。 +3. **6 项 ADR + 3 项 Q 待确认**(V2 §10),其中 R3(桌面安全模型)、R6(部署拓扑)为 V1 未识别的新阻塞项。 +4. **逐接入点七要素详单**(V2 §7,A1-A10):RPA 位置/AE 位置/兼容性/问题/改哪侧/方案/验收——V1 只有粗粒度对齐表。 +5. **模块对应关系表**(V2 §6):双侧模块一一对应 + 关系 + 现状。 +6. **分阶段实施计划**(V2 §8):0-6 阶段每阶段带硬验收门;新增"阶段 0 事实确认会"。 +7. **风险清单 10 项**(V2 §9):新增 R1 安全模型冲突、R2 部署拓扑、R10 底座演进过期风险。 +8. **能力治理映射方案**:719 能力 ↔ PermissionScope 13 项的映射生成策略(脚本从 catalog 生成 + 高风险域人工审)——V1 只说"不自建 allowlist"。 +9. **宿主桥注入面扩容预案**:4 方法 → +ScreenCaptureHost/DisplayCoordinateService(vision 迁移必需),V1 的 4 方法清单不再完整。 +10. **明确"未实现/设计中"口径**:computer-control Runner、WindowsRunner.click/type、MacDriver/LinuxDriver、Graph Validator、bun 冒烟、ScreenCaptureHost 全部标为未实现,防止把计划写成现状(用户红线 #7)。 diff --git a/docs/rpa-core-migration-guide-v2.md b/docs/rpa-core-migration-guide-v2.md new file mode 100644 index 0000000..e053612 --- /dev/null +++ b/docs/rpa-core-migration-guide-v2.md @@ -0,0 +1,345 @@ +# Agent-Employee RPA 迁入指南 V2(基于双侧真实源码核查) + +> 文档性质:对 `docs/rpa-core-migration-guide.md`(V1)的全面修订版。 +> 核查基线:2026-11-06,双侧**真实工作区源码**(非快照 ZIP、非审查报告转述)—— +> RPA 侧 `D:/code/PRA-only-demo`(main,工作区干净)、宿主侧 `D:/code/Agent-Employee`。 +> 与 V1 的逐条差异及审查报告修正记录见 `docs/rpa-core-migration-guide-v2-diff.md`。 +> 状态标记约定:**已实现**(代码在库)/ **部分实现** / **仅契约**(有类型无实现)/ **设计中** / **未实现** / **待确认**(不允许猜测)。 + +--- + +## 0. V2 核心结论(先读这个) + +1. **宿主底座已大变,V1 的"空壳契约"叙事大部分失效。** V1 说对面 7 个契约包每个只有 1-9 个声明文件、windows-runner 是 0 源文件空壳。实测(2026-11-06):7 个包中 5 个已有实质实现(workflow-engine 25 文件、capability-gateway 321 行、browser-plugin 已接 Playwright、windows-plugin 新增原生观察适配器、runtime-governance 有 readiness 投影),windows-runner 有真实 C# 原生实现(.NET 10 + FlaUI UIA3,observe-only)。**仍无实现的只剩两处:computer-control 的 Runner、windows-plugin 的 WindowsRunner.click/type。** + → 迁入的本质从 V1 的"拿实现去填契约"变为**"接底座 + 给已有实现让路"**:不重复造 workflow 状态机、不重复造 Playwright 浏览器、不重复造 UIA 观察。 +2. **RPA 侧此轮整改完成了一部分**:平台标记单一源(PLATFORM_GROUPS 34 域 + 守卫测试)、驱动按平台自动选择(platform_unsupported)、catalog platformTag 687 项首次生效、5 个真桌面测试补平台守卫、`driver/platform.ts` 收拢。**但接入前 P0 大部分未解决**:`createEngine()` 仍无注入参数、Registry 仍是进程级全局、超时不中止底层操作、取消被标为 failed、5 处动态 `import("electron")` 残留、包依赖缺 3 项。 +3. **迁入位置与名称维持 V1 结论**:`code/backend/packages/rpa-core` → `@agent-worker/rpa-core`,backend workspace(bun@1.4.3,workspaces 含 `packages/*`)放进去即生效,backend 全家统一 `@agent-worker/*` 前缀、`workspace:*` 源码消费。 +4. **两条硬边界不变且加严**(用户红线): + - 所有带副作用的能力必须经 capability-gateway(授权→租约→幂等→执行→审计),**不得绕行**; + - rpa-core **不得依赖 Electron 主进程**(当前仍有 5 处动态 import,是接入阻塞项)。 +5. **新增 6 项 ADR 待确认**(见 §10),其中最关键的两项: + - **ADR-R3 桌面执行安全模型冲突**:RPA 驱动 = spawn 任意 PowerShell 脚本;对面安全模型 = 受信 C# 原生进程 + `*.exe` 白名单 + 明文约束"不执行任意 PowerShell"。必须二选一,不能装作兼容。 + - **ADR-R6 部署拓扑**:backend 执行面跑在服务器(PostgreSQL/容器),而 RPA 桌面能力只能在用户 Windows 桌面交互会话里跑(对面自己也把 windows-runner 留宿主)。rpa-core 的哪些部分跑 backend、哪些跑宿主桌面进程,是迁移前必须定的大前提。 + +--- + +## 1. 核查方法与证据基线 + +- 双侧源码逐文件核查(两个独立探查通道 + 关键点人工复核),关键结论均带 `文件:行号` 证据。 +- 实测过的事实:`import("electron")` 逃过 check-deps 正则(构造用例 0 匹配);catalog.json platformTag 分布(null=326 / win32=687 / 数字 1=3);capabilityCount()=719;对面 capability-gateway 租约 TTL=60s、幂等表上限 4096。 +- 未验证(不写"通过"):Windows 实机 E2E、Bun 环境 test、对面真实链路联调。 +- 审查报告(`docs/RPA-Review-Full.md`)与真实源码不一致处,以源码为准并记录修正理由(见 diff 文档第 2 节)。 + +--- + +## 2. RPA 侧现状事实清单(2026-11-06 实测) + +| # | 事项 | 状态 | 证据 | +|---|---|---|---| +| 1 | Driver 惰性 getter + 非 win32 抛 `platform_unsupported` | 已实现 | engine.ts:47-61;error-codes.ts:43;engine-driver.test.ts | +| 2 | **Driver 可注入** | **未实现** | `createEngine()` 无参数(engine.ts:64-66);desktop.ts:9 等在模块加载时捕获 `defaultEngine.driver` | +| 3 | Registry 全局 Map、last-wins、runtime 读全局 getHandler | 属实(未改) | registry.ts:36-45;runtime.ts:260 | +| 4 | PLATFORM_GROUPS 单一源(34 域全 win32)+ buildDomainPlatformMap 真实实现 + 守卫测试 | 已实现 | register-all.ts:16-50,98-127;platform-groups.test.ts | +| 5 | withTimeout 监听 signal 但无 AbortController——超时不中止底层 | 属实(未修) | runtime.ts:33-56 | +| 6 | NodeState 类型含 cancelled,但 executeNode catch 把取消标成 failed | 属实(未修) | types.ts:142;runtime.ts:334-339 | +| 7 | 重试上限 100、黑名单式 isRetryable | 属实(未修) | runtime.ts:58-60,276 | +| 8 | Graph Validator | 未实现 | 全仓无 validateFlowGraph | +| 9 | 动态 `import("electron")` 5 处(vision.ts×3、cv-vision.ts×2) | 属实(未修) | vision.ts:18,66,432;cv-vision.ts:51,213 | +| 10 | check-deps.mjs 对 `import("electron")` 零匹配(盲区实测) | 属实 | check-deps.mjs:20 正则要求 `import\s+` | +| 11 | 包依赖缺 3 项:@napi-rs/canvas、pdfjs-dist、@cantoo/pdf-lib | 属实(未修) | rpa-core/package.json:17-32 对比 pdf.ts/vision.ts import | +| 12 | main/exports 直指 src 源码、private | 属实(决策项) | rpa-core/package.json:4-11 | +| 13 | rpa-cli 副作用全量 import + 全局 getHandler | 属实(未改) | scripts/rpa-cli.ts:25,53-59 | +| 14 | CDP transport 单命令无超时/无 AbortSignal/pending 仅断连清理 | 属实(未修) | transport.ts:96-118 | +| 15 | 两段式元素定位(当前页优先,失败才跟前台)| 已实现 | session.ts:296-307,518-523 | +| 16 | locate() 不支持 xpath / Shadow DOM(与 withElement() 不一致)| 属实(未修) | session.ts:465-517 对比 252-287 | +| 17 | HostBridge/SubflowSource 模块级单例 | 属实(未改) | host-bridge.ts:16-24,61-69 | +| 18 | AI ChatCompletionOptions 无 signal 参数 | 属实(未修) | ai-service.ts:39-48 | +| 19 | 桌面拾取无 AbortSignal(热键+轮询+deadline 自有机制)| 属实(未修) | desktop-pick.ts 全文零 signal 命中 | +| 20 | catalog platformTag:win32=687 / null=326 / **数字 1=3(脏值未清洗)** | 部分实现 | build-catalog.mjs:245-246 对 truthy 旧值透传 | +| 21 | catalog overrides(fields/removeFields/addFields) | 已实现 | catalog-overrides.mjs:6-24 | +| 22 | 能力 719 个 / 目录组件 1016(vendor 997 + native 16 + trigger 3)/ fields 4299 / 34 域 | 实测 | platform-groups.test.ts;catalog.json counts | +| 23 | 平台守卫测试 5 文件 + driver/platform.ts 唯一入口 | 已实现 | capabilities/*.test.ts;driver/platform.ts | +| 24 | Driver 五域方法均无 AbortSignal 参数 | 属实(未修) | driver/types.ts:87-119 | + +--- + +## 3. 宿主侧(Agent-Employee)现状事实清单 + +| 契约包/服务 | V1 描述 | 2026-11-06 实测 | 状态 | +|---|---|---|---| +| workflow-engine | 9 个声明文件,空壳 | **25 文件完整实现**:WorkflowEngine 接口(create/start/beginStep/executeStep(runner)/completeStep/pause/resume/cancel/requestApproval/decideApproval)、状态机迁移表、Memory+PostgreSQL 双存储、recovery、REST API、worker(并发上限/取消/排空) | 已实现 | +| capability-gateway | 空壳契约 | **321 行完整实现**:`authorize(ref, subjectId, policy) → CapabilityLease`(TTL 60s)、`execute(lease, runner)`、幂等键预占/结算(上限 4096)、高影响审批精确 actionId 放行、结果 leaseId/actionId 回显校验 | 已实现 | +| browser-plugin | 纯契约 | **已接 playwright-core ^1.64.1**:PlaywrightBrowserRunner 358 行(navigate/click/type/snapshot),域名白名单三重复检(导航前/落点后/动作前),证据 SHA-256 落盘;定位仅 css/aria/text(无 xpath) | 已实现 | +| windows-plugin | 纯契约 | 契约 + **新增 native-observer.ts(292 行受信宿主适配器)**:spawn C# 观察进程、证据 realpath/SHA-256/PNG 魔数校验;`WindowsRunner{click;type;readText;snapshot}` 接口仍无实现;manifest `rpa.windows`:type=highImpact,全部 idempotencyRequired | 部分实现 | +| computer-control | 纯契约 | **未变**:纯类型 + 3 纯函数(selectPreferredTarget 降级链、assertComputerActionAllowed、assertComputerResultEvidence);5 种 target kind、6 种 action、CoordinateSpace(DPI/缩放契约已就绪) | 仅契约 | +| runtime-governance | 空壳 | readiness 投影实现(readiness.ts 117 行),无插件生命周期契约 | 部分实现 | +| plugin-contract | 纯类型 | 类型底座 + `assertPluginManifest` 校验实现;**PermissionScope 13 项**(browser.domain/storage、desktop.window/input/process、filesystem.workspace/download、network.http、office.document、messaging.send/read、media.generate、monitoring.capture);CapabilityLease/ActionResult/CapabilityRef(`pluginId:capabilityId`) | 部分实现 | +| services/windows-runner | 0 源文件空壳 | **17 文件真实 C# 实现**(.NET 10 + FlaUI UIA3 + PrintWindow,stdin/stdout JSON 协议,**只认 observe**,click/type 未实现);TS 宿主适配器校验证据 | 部分实现(观察半边) | +| plugin-registry / plugin-worker | (V1 未提) | registry=清单登记+版本链校验(无动态 loader);plugin-worker=常驻执行进程,PG LISTEN/NOTIFY 认领 workflow/session 动作、租约续期、跨进程取消传播、崩溃接管→unknown。**这就是对面当前的插件宿主** | 已实现 | +| model-gateway | (V1 未提) | 21 文件实现包:ModelGateway.stream 流式调用 + ModelControlPlane(每次物理调用向 Java 控制面重新授权,短授权 60s) | 已实现 | +| Java 控制面 | (V1 未提) | `code/backend/control-plane/`:Spring Boot 4.1.1 / Java 21 / 454 个 Java 文件 / 9 Maven 模块;与 TS 面经 OpenAPI + Outbox + 短授权 grant 通信;端口 8887(Java)/8881(Admin)/8880(TS 执行面) | 已实现 | +| frontend/apps/desktop | Electron+SolidJS | 确认。**无 RPA 宿主桥**,但有等价物:identity-login-window(弹窗)、execution-context.ts(grant 桥)、zoom.ts(缩放);DPI/坐标契约在 computer-control CoordinateSpace 与 C# Protocol.cs | 部分实现 | + +对面安全模型要点(直接影响 RPA 桌面路线):windows-plugin 策略校验只允许 `*.exe` 进程名、不允许路径;native-observer.ts 设计约束明言"不执行任意 PowerShell";桌面交互 Runner 留宿主、不进 Linux 容器。 + +--- + +## 4. 原指南(V1)内容分类 + +| V1 内容 | 分类 | 处理 | +|---|---|---| +| 包现状描述(719 能力、34 域、宿主桥 4 方法、Driver 五域) | **保留**(微调) | 仍准确;宿主桥维持 4 方法不变 | +| "完全不依赖 Electron、check:deps 天天检查" | **过时/不实** | 5 处动态 import 逃过护栏;改为"静态依赖已清、动态残留待清",护栏必须升级 | +| 第 -1 步对面契约包全部空壳的叙事 | **过时** | 按 §3 改写:5/7 已实现,"填契约"变"接底座" | +| 第 0 步三件作业(bun 冒烟 / catalog 重生成 / 注册方式决策) | **部分保留** | catalog 重生成已完成(platformTag 687 生效,3 个脏值待清洗);bun 冒烟仍未做;注册方式决策并入 ADR-R1 | +| 第 1 步搬包(git subtree → code/backend/packages/rpa-core、改名 @agent-worker/rpa-core、demo 侧不双活) | **保留** | 双侧命名与 workspace 布局核实无误 | +| 第 2 步 A 类契约对齐表 | **需要修改** | capability-gateway/workflow-engine 从"对照后改对面"变"按已实现接口写 adapter";新增 plugin-contract/registry/worker 三层对接 | +| 第 2 步 B 类宿主注入表(浏览器=最大变数) | **需要修改** | 浏览器变数已收敛:对面有 Playwright 实现;变数改为"双路径取舍"(ADR-R4) | +| 第 3 步 7 条验收 | **需要修改** | 扩充为 §9 验收标准(加 gateway 零调用、取消传播、双 Engine 隔离等) | +| 三端计划(PLATFORM_GROUPS 单一源、驱动自动选、分组核查、测试守卫、平台判断收拢) | **已完成,从"待办"改"现状"** | 五件小事全部落地;平台硬约束一节保留为长期规范 | +| 附:10 个关键决策 | **大部分保留** | 决策 2"保留全局注册表"与决策 9"双入口"需按 ADR-R1 重新确认;其余不变 | + +--- + +## 5. 接入目标架构 + +```text +┌─ Agent-Employee(宿主:权威状态与治理的唯一来源)──────────────────────┐ +│ │ +│ Java 控制面 control-plane(:8887) ──OpenAPI/Outbox/短授权 grant──┐ │ +│ │ │ +│ TS 执行面 apps/api(:8880, Bun) │ │ +│ ├─ workflow-engine ← Run/Step 权威状态机(PG 存储+recovery) │ │ +│ ├─ capability-gateway← 授权→租约(60s)→幂等→执行→审计【唯一入口】│ │ +│ ├─ plugin-registry ← 清单登记 + 版本链校验(无动态 loader) │ │ +│ ├─ model-gateway ← AI 流式调用 + 每次调用控制面授权 │ │ +│ └─ services/plugin-worker ← 常驻执行进程(LISTEN/NOTIFY 认领) │ │ +│ ├─ browser-plugin → PlaywrightBrowserRunner(已实现) │ │ +│ └─ windows-plugin → windows-runner(C# FlaUI, observe-only)│ │ +│ │ +│ frontend/apps/desktop(Electron+SolidJS,用户桌面宿主) │ │ +│ └─ RPA 宿主桥实现落点(弹窗/DPI/AI 配置/子流程仓库) │ │ +└────────────────────────────────────────────────────────────────┘ + ▲ + │ CapabilityRunner(gateway 包皮,唯一执行通道) + │ Run/Step 事件回传(RPA 不建第二套状态) +┌─ RPA 迁入物(执行器与能力供给方)──────────────────────────────────────┐ +│ @agent-worker/rpa-core(packages/rpa-core 迁入,Bun 源码消费) │ +│ ├─ Flow Runtime(作为 workflow-engine 的执行引擎候选 / 步骤级 runner)│ +│ ├─ 719 能力 handler(纯 Node 部分可在 plugin-worker 服务器侧跑; │ +│ │ 桌面/视觉部分只能跑在用户桌面宿主进程——见 ADR-R6) │ +│ ├─ WindowsDriver(补齐对面 WindowsRunner.click/type 执行缺口,ADR-R3)│ +│ └─ CDP 外部浏览器会话(与 PlaywrightBrowserRunner 的取舍,ADR-R4) │ +│ @agent-worker/rpa-adapter(新增薄适配层) │ +│ ├─ CapabilityRunner:authorize/execute 包裹 → ref↔componentId 映射 │ +│ ├─ RunResult/NodeState ↔ WorkflowStatus/StepStatus 映射表 │ +│ └─ 宿主注入装配:HostBridge(4) + SubflowSource(2) + ScreenCaptureHost│ +└────────────────────────────────────────────────────────────────────────┘ +``` + +**权责原则(沿审查报告,逐条可执行):** +- workflow-engine 是 Run/Step 状态唯一权威;RPA Runtime 只回传事件,不落第二份终态。 +- capability-gateway 是唯一授权入口;RPA 侧 `getHandler()` **不对 adapter 之外暴露**(rpa-cli 顺手重写以作表率)。 +- computer-control 是桌面契约对齐对象;RPA 不新造并行的桌面抽象。 +- 宿主服务一律注入,禁用模块级 setter 承载多会话状态(现状 HostBridge 单例是过渡,见 ADR-R1)。 + +--- + +## 6. 模块对应关系表 + +| RPA 侧(packages/rpa-core) | Agent-Employee 侧 | 关系 | 现状 | +|---|---|---|---| +| `engine/runtime.ts` 流程执行 | `workflow-engine` WorkflowEngine/StepRun | RPA=执行算法候选,AE=权威状态 | 集成形态待 ADR-R2 | +| `engine/registry.ts` 全局注册表 | `plugin-registry` + `capability-gateway` CapabilityRef | ref↔componentId 映射层(rpa-adapter) | 映射待建 | +| 719 能力 handler | `plugin-contract` CapabilityDefinition + PermissionScope 13 项 | 能力清单生成 + 权限映射 | 待建(脚本生成) | +| `RunContext.signal` | `CapabilityExecutionContext.signal` | 均 AbortSignal,直通 | 兼容 | +| `NodeState`(idle/running/succeeded/failed/skipped/cancelled) | `StepStatus`(+waiting_user/unknown/pending) | 映射表;RPA 缺 waiting_user/unknown | 需补 | +| `human-dialog` 审批弹窗 | `WorkflowApprovalRequest`/decideApproval | 人审节点挂宿主 approval 流 | 需 adapter | +| `driver/windows/*`(PowerShell 五域) | `windows-runner` C#(observe-only)+ `WindowsRunner{click,type}` 契约 | RPA 补执行半边;安全模型冲突 | ADR-R3 | +| `browser/*` CDP 会话(BrowserLike) | `browser-plugin` PlaywrightBrowserRunner | 双路径取舍 | ADR-R4 | +| `ai-service.ts` loadAiConfig | `model-gateway`(ModelGateway.stream + ModelControlPlane) | RPA AI 能力改走宿主网关 | 需改造 | +| `host-bridge.ts` 4 方法 | frontend desktop main 进程(弹窗/坐标/AI 配置等价物已有) | 参考实现照抄本仓库 src/main/index.ts | 落点明确 | +| `SubflowSource` 2 方法 | 对面流程存储 | 包一层 | 小 | +| vision/cv-vision 截图+DPI | `computer-control` CoordinateSpace + C# PrintWindow | 宿主注入 ScreenCaptureHost | 待建 | +| 运行证据/截图 | `evidence-store`(S3) + `monitoring.capture` 权限 | 证据统一落对面 | 待接 | +| `check-deps.mjs` 依赖护栏 | backend 包边界 | 保留并升级(动态 import) | 需增强 | + +--- + +## 7. 逐接入点详单 + +每项按固定七要素:RPA 位置 / AE 位置 / 兼容性 / 问题 / 改哪侧 / 方案 / 验收。 + +### A1 Engine 与 Driver 注入 + +- **RPA 位置**:`packages/rpa-core/src/engine/engine.ts:47-66`(惰性 getter + `createEngine()` 无参);`capabilities/desktop.ts:9`、`common-final.ts:11`、`system-extended.ts`、`window-extended.ts`、`office.ts:15`、`ftp.ts`、`ocr-caps.ts:11` 捕获 `defaultEngine.*`(其中 desktop.ts:9 在**模块加载时**取 `.driver`,非 win32 下 import 即抛错)。 +- **AE 位置**:对面不关心 driver 细节;对齐契约是 `computer-control` 的 `ComputerRunner{observe;execute}`(computer-control/src/index.ts:99-102)与 `windows-plugin` 的 `WindowsRunner`。 +- **兼容性**:部分。平台错误语义(platform_unsupported)已就绪;注入面缺失。 +- **问题**:宿主无法注入测试替身或 computer-control 适配器;能力文件模块级捕获引擎状态(excelHandles/ftpClient/ocrInstance/driver),多会话共享。 +- **改哪侧**:RPA。 +- **方案**:`createEngine(options?: { driver?, hostBridge?, subflowSource?, registry? })`,全部可选、缺省保持现行为;能力文件改为经 RunContext/engine 参数取 driver 与资源表(模块级捕获改为首用时向 engine 取);幂等句柄表(excelHandles/ftpClient/ocrInstance)迁入 engine 实例字段(部分已是)。 +- **验收**:FakeDriver 注入测试覆盖五域;两个 Engine 各注入不同 FakeDriver 并行执行互不串用;非 win32 上 import 全部 34 域不抛错、调用桌面能力时才抛 platform_unsupported。 + +### A2 Registry 注册机制与实例隔离 + +- **RPA 位置**:`engine/registry.ts:36-45`(模块级 Map、last-wins、meta 可残留旧值);`runtime.ts:260`(全局 getHandler);`register-all.ts`(34 域 DOMAINS + PLATFORM_GROUPS + buildDomainPlatformMap)。 +- **AE 位置**:`plugin-registry`(清单登记+版本链,无动态 loader)、`capability-gateway` CapabilityRef(`pluginId:capabilityId` + version)。 +- **兼容性**:结构性错位。对面一切能力调用都带 CapabilityRef 与版本;RPA 是字符串 id 全局表。 +- **问题**:进程级注册在对面"多租户 + plugin-worker 常驻进程"模型下无法按租户隔离;componentId 与 CapabilityRef 无映射;同 id 覆盖无审计。 +- **改哪侧**:短期 RPA 侧固化 ADR + 新建 adapter 映射;长期 RPA 侧 engine-scoped registry。 +- **方案**:①ADR-R1 先定部署模型(单后端单能力集 → 全局表合法,把 `registerAll` 文档语义改为"加载到进程注册表",不假装实例隔离);②rpa-adapter 维护 `componentId ↔ (pluginId="rpa", capabilityId=componentId, version=catalog 版本)` 映射,由 catalog.json 生成并做完整性测试;③重复注册策略定为"显式覆盖 + 输出 warn 审计行"。 +- **验收**:映射表覆盖 719 能力(或明确排除清单);gateway 侧按 ref 解析到正确 handler;重复注册产生可审计日志。 + +### A3 Runtime 执行、超时、取消、重试 + +- **RPA 位置**:`runtime.ts:33-56`(withTimeout 只 reject 外层)、`runtime.ts:334-339`(取消标 failed)、`runtime.ts:58-60,276`(isRetryable 黑名单、retryCount≤100)、`driver/types.ts:87-119`(五域方法无 signal)。 +- **AE 位置**:`workflow-engine` StepRun.attempt/leaseEpoch/idempotencyKey、`workflow-worker` 跨进程取消传播与崩溃接管→unknown、`capability-gateway` execute 的 `ctx.signal?`。 +- **兼容性**:不兼容。对面以幂等键 + 租约纪元管理副作用安全;RPA 超时/取消/重试语义与它冲突。 +- **问题**:超时后底层 PowerShell/HTTP/CDP 仍执行(重复副作用);取消状态不一致;非幂等能力可被重试 100 次。**这是接入的第一阻塞项。** +- **改哪侧**:RPA。 +- **方案**:①节点尝试创建独立 AbortController,合并 Run 级 signal 与节点 timeout,贯通 handler→driver→PowerShell 子进程/HTTP/CDP(driver 五域方法加可选 `signal` 参数);②executeNode catch 优先映射 cancelled → `state.status="cancelled"`,不走 skipOnError/error route/retry;③重试改元数据驱动:CapabilityMeta 增 `idempotent`/`sideEffect`/`retryPolicy`,非幂等默认 0 次重试;④新增 `validateFlowGraph`(ID 唯一、边合法、入口/出口基数、环、悬空边)。 +- **验收**:构造 5 秒 Fake Handler + 100ms 超时,断言 handler 收到 abort 并停止、无并发重入;执行中取消后 Run 与 NodeState 均为 cancelled;对 File 写入/点击类能力验证"超时不自动重试";非法图执行前得到稳定错误码。 + +### A4 Capability Gateway(能力注册与权限治理) + +- **RPA 位置**:`registry.ts`(handler + meta 无权限字段);`resources/catalog.json`(仅 `risk: low|high`)。 +- **AE 位置**:`capability-gateway/src/index.ts:75-252`(已实现 authorize/execute/租约 60s/幂等/高影响审批);`plugin-contract` PermissionScope 13 项。 +- **兼容性**:接口契合度高——`CapabilityRunner = (input, ctx{lease,capability,signal?}) => Promise`,RPA handler `(ctx, node, args, component)` 包一层即可;ActionResult 需回显 leaseId/actionId(adapter 统一填)。 +- **问题**:①719 能力 ↔ 13 项 PermissionScope 无映射;②CapabilityMeta 无 sideEffect/idempotent/permission/approvalRequired 字段;③存在绕行面(rpa-cli、子流程直接 getHandler)。 +- **改哪侧**:新建 adapter(AE 仓库内包)+ RPA 补元数据。 +- **方案**:①rpa-adapter 实现 CapabilityRunner:gateway.execute(lease, runner) → ref→componentId → 构造 RunContext(signal 直通)→ handler → 结果包装 ActionResult;②权限映射表按 34 域 × PermissionScope 初稿生成(files→filesystem.workspace、http→network.http、desktop/windowExtended→desktop.input/window、utilityExtended→独立高影响 scope【待确认:现表无 process 执行域对应,需对面确认】、message→messaging.send);③高风险域标 highImpact 走审批(System_ExecuteCommand、键鼠、文件删除/覆盖、发消息);④meta 增治理字段(与对面 CapabilityDefinition 字段对齐)。 +- **验收**:审批拒绝/租约过期/权限不在白名单时 handler **零调用**(gateway 已有测试语义,adapter 层加 719 全量冒烟:未经 authorize 不得触达 handler);审计可关联 Agent/Run/Capability/审批结果。 + +### A5 Workflow Engine 执行契约 + +- **RPA 位置**:`engine/runtime.ts`(RunResult/NodeState)、`engine/types.ts:142`、human-dialog 审批弹窗、SubflowSource。 +- **AE 位置**:`workflow-engine/src/index.ts:278-311`(WorkflowEngine 接口)、`workflow-runtime.ts`、`workflow-worker.ts`、`approval-policy.ts`;`executeStep(..., runner)` 的 runner 类型即 `Parameters[1]`。 +- **兼容性**:状态映射大体可行;RPA 缺 `waiting_user`/`unknown` 两态;对面 StepStatus 无 RPA 的 `idle`。 +- **问题**:两套状态权威冲突风险;集成形态二选一未定(整体作为一个 capability vs 节点级映射为 step)。 +- **改哪侧**:adapter + 双侧小改。 +- **方案**:**推荐 MVP 方案 A**——整个 RPA 流程注册为**一个** capability(`rpa.flow.execute`),workflow-engine 的一个 step 调它,RunResult→ActionResult、节点级事件→event-bus 事件流、human-dialog→requestApproval 挂对面 approval 流、取消→signal 直通;方案 B(RPA 节点=step 1:1 映射)等方案 A 验收后按需评估。NodeState 增 `waiting_user`/`unknown` 两态(unknown 用于崩溃恢复对齐)。 +- **验收**:状态映射契约测试(含 waiting_user/unknown/cancelled 全分支);一次含审批节点、一次执行中取消、一次进程崩溃恢复的端到端演练;对面 Run 状态终态与 RPA RunResult 永远一致。 + +### A6 Computer Control 与 Windows 桌面执行 + +- **RPA 位置**:`driver/windows/*`(PowerShell 封装五域)、`capabilities/desktop-uia.ts`、`element.ts`。 +- **AE 位置**:`computer-control`(仅契约+3 纯函数)、`windows-plugin`(WindowsRunner{click;type;readText;snapshot} 无实现、native-observer.ts observe-only)、`services/windows-runner/native/*.cs`(FlaUI UIA3 observe-only)。 +- **兼容性**:**安全模型冲突**——RPA 驱动 spawn 任意 PowerShell;对面白名单只许 `*.exe`、明文"不执行任意 PowerShell"、证据要求 SHA-256。 +- **问题**:RPA 的执行半边(click/type)正是对面缺口,但实现方式过不了对面安全门。 +- **改哪侧**:双侧(视 ADR-R3)。 +- **方案**:推荐——把 RPA WindowsDriver 的五域执行逻辑**移植进 windows-runner 的 C# 原生进程**( FlaUI/CGEvent 等价实现 + 现成协议加 actuate 操作),RPA 侧 driver 抽象保留、Windows 实现改为可指向"原生进程通道"或"本地 PowerShell 通道"(后者仅 demo 使用,明确标注不走宿主治理);策略校验/证据断言复用对面 `assertComputerActionAllowed`/`assertComputerResultEvidence`。 +- **验收**:click/type 经策略校验(白名单进程/窗口、allowInput)+ 证据落盘;宿主拒绝时零副作用;同目标 observe→actuate→observe 闭环一致。 + +### A7 浏览器(Browser Plugin vs RPA CDP 会话) + +- **RPA 位置**:`packages/rpa-core/src/browser/*`(transport/external,进包部分)+ `src/main/browser/session.ts`(接管/拾取,留守部分);已知缺陷:transport 单命令无超时(:96-118)、locate 不支持 xpath/Shadow DOM、evaluate 默认 follow=true。 +- **AE 位置**:`browser-plugin`(PlaywrightBrowserRunner 已实现:白名单三重检、AbortSignal 透传、证据 SHA-256;定位 css/aria/text,无 xpath)。 +- **兼容性**:双实现并行,语义不同(Playwright 自管浏览器 vs RPA 接管用户已开浏览器/复用登录态)。 +- **问题**:重复投资;RPA CDP 链路自身有 P1 缺陷;对面定位器无 xpath(RPA 拾取器产出 xpath/css/aria/text 混合 selector)。 +- **改哪侧**:ADR-R4 决策后双向小改。 +- **方案**:**宿主动作默认走对面 browser-plugin**(复用底座原则);RPA 浏览器能力作为**第二 Runner** 后迁,迁前先修 transport 超时 + 统一 resolveElement(一次修复覆盖 locate/click/type/getText);若保留 RPA 路径,域名白名单必须接同一份 BrowserContextPolicy(不得自建白名单)。 +- **验收**:同一定位用例集(css/aria/text/[xpath 视决策])在所选路径上全部通过;白名单拒绝 URL 时导航前即拦截;证据落 evidence-store。 + +### A8 平台适配(Windows / Linux / macOS) + +- **RPA 位置**:`register-all.ts` PLATFORM_GROUPS(34 域全 win32)、`driver/platform.ts`、`engine/engine.ts:47-61`、5 个 skipIf 测试;catalog 687 win32 / 326 null / **3 个数字 1 脏值**。 +- **AE 位置**:`plugin-contract` Platform 类型;windows-runner 明确"留在宿主、不进 Linux 容器"(README)。 +- **兼容性**:兼容(两边都是 win32-first 务实路线)。 +- **问题**:①catalog 3 个 `platformTag: 1` 脏值透传(build-catalog.mjs:246 对 truthy 不清洗);②对面 CapabilityDefinition 未见 platform 字段(**待确认**:插件清单如何表达平台限制)。 +- **改哪侧**:RPA(清洗);对面(清单平台字段,待确认后)。 +- **方案**:build-catalog 归一化——源值不在 `win32|darwin|linux|null` 白名单的一律重派生;三端扩展节奏沿用 V1 第三节(Linux xdotool/AT-SPI、Mac AX/CGEvent/TCC、Office 分端实现),驱动实现统一走 ADR-R3 的原生进程通道。 +- **验收**:catalog 全量过 schema 校验(1016/1016);非 win32 上 Core 可加载、桌面能力明确报 platform_unsupported;Mac/Linux CI 跑纯逻辑子集。 + +### A9 Electron 依赖与 Core 独立性(含包闭包) + +- **RPA 位置**:vision.ts:18,66,432、cv-vision.ts:51,213(动态 `import("electron")`);check-deps.mjs:20(正则盲区实测);rpa-core/package.json:17-32(缺 @napi-rs/canvas、pdfjs-dist、@cantoo/pdf-lib;main 直指 src、private)。 +- **AE 位置**:backend 执行面是 Bun(无 Electron);Electron 只在 frontend/apps/desktop;截图/坐标对面等价物是 C# PrintWindow + CoordinateSpace 契约。 +- **兼容性**:不兼容。视觉能力在对面 backend 进程必然失败。 +- **问题**:Core 不是 Electron-free;护栏查不出动态 import;单包安装缺 3 个依赖。 +- **改哪侧**:RPA。 +- **方案**:①抽 `ScreenCaptureHost`/`DisplayCoordinateService` 接口并入 HostBridge 注入面(弹窗/DPI×2/AI 配置 4 方法 → 增至 6 方法,或独立 host services 包——实现期定,倾向并入 HostBridge 减少 API 面);vision/cv-vision 只依赖接口,宿主未注入时抛 `host_service_unavailable`;②check-deps 升级为覆盖 `import()`/`require()`/`createRequire()`(先补正则,中期 AST);③补齐 3 个依赖声明(pdf.js 与 canvas 为原生/大件,评估 optionalDependencies + 能力级降级);④消费方式锁定 **Bun 源码消费**(对面全家 workspace:* 源码依赖,与现状一致),锁 bun@1.4.3 做 CI 冒烟。 +- **验收**:无可解析 electron 的纯净 Node/Bun 环境 Core 全量 import 成功;视觉能力未注入 Host 时返回 host_service_unavailable、注入 Fake Host 后可测;隔离目录仅按包声明装依赖跑通 PDF/OCR 代表能力。 + +### A10 插件生命周期、异常隔离与资源清理 + +- **RPA 位置**:无插件概念;资源清理散在能力内(PowerShell 子进程、ws、FTP/OCR 句柄);历史上有 catch{} 吞错模式(已部分修复)。 +- **AE 位置**:`plugin-contract` PluginManifest(apiVersion/minCoreVersion/entrypoint/rollbackVersion)+ assertPluginManifest;`plugin-registry` 版本链校验;`plugin-worker`(崩溃接管→unknown、租约续期、跨进程取消)。 +- **兼容性**:RPA 需要一张插件"外壳"才能进对面宿主。 +- **问题**:719 能力不可能逐个成插件;RPA 无崩溃恢复语义(对面 unknown 态)。 +- **改哪侧**:adapter 为主。 +- **方案**:RPA 以**单一插件**接入(manifest id 建议 `rpa.core`,能力按域分批暴露为 CapabilityDefinition 清单,随 catalog 生成);异常隔离靠节点级 try/catch + AbortSignal(A3);资源清理建统一 finally 清单(子进程 kill、ws close、临时文件删除)并纳入取消路径;崩溃恢复复用对面 workflow-recovery(NodeState.unknown 对齐)。 +- **验收**:杀掉 plugin-worker 进程后 Run 转入 unknown 并可恢复;取消后无残留子进程/连接/临时文件;manifest 通过 assertPluginManifest 与 registry 版本链。 + +--- + +## 8. 分阶段实施计划 + +> 原则:先 RPA 侧收口(便宜、不依赖对面),再垂直切片,再规模化。不为了架构统一搞大重构;每阶段有硬验收门。 + +| 阶段 | 内容 | 前置 | 验收门 | +|---|---|---|---| +| **0 事实确认**(双侧,1 次评审会) | 过 §10 六项 ADR;对面确认 CapabilityDefinition 平台字段、utilityExtended 对应 scope | 无 | ADR 有书面结论 | +| **1 RPA 侧收口**(本仓库) | A3 四件(取消贯通/状态映射/重试元数据/Graph Validator)+ A1 注入参数 + A9(Electron 残留、check-deps 升级、依赖闭包)+ A2 的 ADR 固化 + catalog 脏值清洗 + rpa-cli 重写(显式注册、经 engine 取 handler) | 无 | 审查报告 §7 第一/二阶段清单全绿;纯 Node 环境 Core 全量加载 | +| **2 迁入与 adapter 骨架** | git subtree 迁包改名 @agent-worker/rpa-core;bun@1.4.3 test 冒烟(exceljs/pdf/PowerShell 编码);新建 @agent-worker/rpa-adapter(CapabilityRunner + ref 映射 + 状态映射表);demo 侧冻结 | 阶段 1 + ADR-R1/R2 | bun test 纯逻辑全绿;未经 gateway 不可达 handler;719 映射完整性测试 | +| **3 垂直切片** | 一个文件能力 + 一个 HTTP 能力走通:workflow-engine create/start → gateway authorize → adapter → rpa-core handler → 事件/证据回传 → cancel 中途取消;方案 A(rpa.flow.execute 整体注册) | 阶段 2 | 取消/审批/审计全链有证据;对面 Run 终态与 RunResult 一致 | +| **4 浏览器与桌面双 ADR 落地** | ADR-R4:宿主动作切 browser-plugin,RPA 浏览器能力修完 transport/resolver 后作为第二 runner 接入;ADR-R3:windows-runner C# 扩展 actuate(RPA 五域逻辑移植) | 阶段 3 | §7-A6/A7 验收条目 | +| **5 能力规模化** | 34 域按风险分批:files/data/http/ftp → office/excel/word(COM 仅 win32)→ desktop/utility 高影响(末批+审批);CapabilityDefinition 与权限映射随批生成 | 阶段 4 | 每批过 gateway 全量冒烟 + 审批矩阵抽查 | +| **6 平台扩展** | V1 第三节三端计划原样生效(Linux/macOS 驱动按 ADR-R3 原生通道) | 阶段 5 | 三平台 CI 矩阵;产品按 platformTag 置灰 | + +**不搬的东西**(维持 V1 清单):界面渲染层、悬浮框/取色器、本地视觉 onnxruntime、流程存储、内置浏览器编排——由宿主提供或对面重做;其中"本地视觉"明确**不进 backend**(原生依赖 + 桌面截图依赖),留在宿主桌面进程。 + +--- + +## 9. 风险清单与总验收标准 + +### 风险清单 + +| # | 风险 | 等级 | 缓解 | +|---|---|---|---| +| R1 | 桌面安全模型冲突(PowerShell vs 原生进程白名单)导致桌面能力无法过审 | 高 | 阶段 0 就把 ADR-R3 定死;并行准备 C# 移植估算 | +| R2 | 部署拓扑错配:rpa-core 整包进 backend,但桌面/视觉能力只能在用户桌面跑 | 高 | ADR-R6 先定:纯 Node 能力 → plugin-worker;桌面/视觉 → 宿主桌面进程加载同一包的子集 | +| R3 | Registry 全局单例在多租户 backend 的隔离缺陷 | 高 | 短期按 ADR-R1 限定部署模型;长期 engine-scoped registry 列入 backlog | +| R4 | 浏览器双路径重复投资 | 中 | ADR-R4 一票定路径;未选路径冻结不投入 | +| R5 | 719 能力的治理映射与元数据补齐工作量失控 | 中 | 脚本从 catalog 生成初稿 + 人工只审高风险域;分批(阶段 5) | +| R6 | Bun 与 Node 行为差异(exceljs/pdf-lib/PowerShell 编码) | 中 | 阶段 2 bun 冒烟前置,差异清单化 | +| R7 | demo 侧与 backend 双活跃漂移 | 中 | git subtree + "迁移后 demo 冻结"纪律(V1 决策 3) | +| R8 | 两套状态机语义漂移(NodeState vs StepStatus) | 中 | 映射表 + 契约测试常驻 CI | +| R9 | catalog 源数据(shizai)上游已删,重生成受阻 | 低 | 已从对面历史恢复至 temp/catalog-source;计划快照入库 | +| R10 | 对面底座继续快速演进,本文行号/接口过期 | 中 | 本文标注核查日期;联调前对关键接口做增量 diff | + +### 总验收标准(迁移完成的定义) + +1. Bun@1.4.3 下包 typecheck/test 全绿(不以 Node 测试替代)。 +2. FakeDriver/Host 注入可用,双 Engine 隔离行为符合 ADR-R1。 +3. 全部已暴露能力经 capability-gateway:审批拒绝/租约过期/无权限时 handler 零调用,审计四元组(Agent/Run/Capability/审批)可追踪。 +4. 取消/超时/重试测试证明:超时即中止底层、取消不进 error route、非幂等零自动重试、无并发重入。 +5. Graph Validator 拒绝非法流程图于执行前。 +6. 纯 Node/Bun 环境(无 electron 可解析)Core 全量加载;视觉路径 Host Mock 可测。 +7. 隔离目录按包声明安装依赖,代表能力(文件/Excel/HTTP/PDF)可跑。 +8. 垂直切片端到端演练通过:含一次审批、一次中途取消、一次进程崩溃恢复(unknown→恢复)。 +9. Windows 10/11 实机回归:UIA/浏览器/Office/DPI/多屏/安装包资源 + 取消场景。 +10. catalog 1016 项全过平台 schema 校验;能力平台范围与真实实现一致。 + +--- + +## 10. 待确认清单(ADR,不猜测) + +| ADR | 问题 | 建议倾向 | +|---|---|---| +| R1 | Registry 作用域:backend 是否多租户/多权限域并存? | 短期全局表 + 语义真实化;长期 engine-scoped | +| R2 | 集成形态:RPA 流程=单个 capability(方案 A)还是节点=step 映射(方案 B)? | 方案 A 起步 | +| R3 | 桌面执行安全模型:RPA PowerShell 驱动 vs 对面"受信 C# 原生进程"红线 | C# 扩展 actuate,PowerShell 通道仅限 demo | +| R4 | 浏览器双路径:Playwright(自管)vs RPA CDP(接管用户浏览器/登录态) | 宿主动作走 Playwright;RPA 路径作为接管场景第二 runner | +| R5 | 包消费方式:确认 Bun 源码消费 + bun 版本矩阵(1.4.3?) | 源码消费(与对面现状一致) | +| R6 | 部署拓扑:rpa-core 各域分别跑在 backend plugin-worker 还是宿主桌面进程? | 纯 Node 域→backend;桌面/视觉/弹窗域→宿主进程(同一包按域加载) | +| Q1 | CapabilityDefinition 是否需要 platform 字段(对面清单未见) | 待对面确认 | +| Q2 | utilityExtended(命令执行)对应哪个 PermissionScope(13 项中无直接对应) | 待对面确认(可能需扩 scope) | +| Q3 | human-dialog 弹窗宿主落点:desktop Electron 窗口 or 宿主网页? | 待确认(倾向 Electron 桌面宿主) | + +--- + +## 11. 本指南边界 + +- 全部结论基于 2026-11-06 双侧工作区源码静态核查 + 少量脚本实测(正则盲区、catalog 统计、capabilityCount);未执行 Windows 实机 E2E 与对面联调,未运行的测试不写成通过。 +- 行号会随代码演进过期,以函数/接口名为准。 +- 本轮只改文档,不改业务源码(用户指令);阶段 1 起的代码改动另行排期。