From d99be8f4ab34d679b892146a5fabc834c2ff5f45 Mon Sep 17 00:00:00 2001 From: yu <1919727607@qq.com> Date: Fri, 6 Nov 2026 11:36:10 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20ADR-R2=20=E8=A1=A5=E8=AE=B0=20A++=20?= =?UTF-8?q?=E6=A3=80=E6=9F=A5=E7=82=B9=E5=8D=8F=E8=AE=AE=EF=BC=88=E4=B8=A4?= =?UTF-8?q?=E4=BE=A7=E6=94=B9=E5=8A=A8=E6=B8=85=E5=8D=95+=E8=90=BD?= =?UTF-8?q?=E5=9C=B0=E8=8A=82=E5=A5=8F=EF=BC=89=EF=BC=9B=E6=A0=87=E5=AE=9A?= =?UTF-8?q?=E9=98=B6=E6=AE=B51=E5=B7=B2=E5=AE=8C=E6=88=90=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/rpa-core-migration-guide-v2.md | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/docs/rpa-core-migration-guide-v2.md b/docs/rpa-core-migration-guide-v2.md index f3c288c..93842e2 100644 --- a/docs/rpa-core-migration-guide-v2.md +++ b/docs/rpa-core-migration-guide-v2.md @@ -12,7 +12,7 @@ 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 项。 +2. **RPA 侧接入前 P0 整改已于 2026-11-06 完成(迁移阶段 1 收口)**:节点尝试级 AbortController(超时即真中止底层操作)、取消映射 cancelled 不走 error route、重试改 `idempotent` 元数据门控、图校验器执行前拒非法流程图、`createEngine(options)` 注入参数(driver/hostBridge/subflowSource/registry)、视觉能力 5 处动态 `import("electron")` 清零改走 HostBridge.screen 注入、check-deps 覆盖动态 import、catalog 脏值修复、rpa-cli 显式注册重写。★ 标记明细见 §2/§7/§8。**接入前仅剩**:bun@1.4.3 冒烟(阶段 2 前置)、包依赖 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(授权→租约→幂等→执行→审计),**不得绕行**; @@ -23,6 +23,7 @@ - **R1 能力清单**:全局一份,权限隔离全交对面网关按租户管。 - **R4 浏览器**:按场景分工——RPA 场景用咱们 CDP 接管(复用登录态/真实页面),对面 Playwright 留给 AI 智能体;白名单与证据共用对面一套。 - **R5 消费方式**:源码 git subtree 并入对面仓库统一编译,Bun 锁 1.4.3。 + - **R2 集成形态(含 A++ 补记)**:方案 A——整个 RPA 流程注册为 `rpa.flow.execute` 单能力,事件流旁路+人审升级两补丁;事件流再升级为检查点协议(崩溃后带 resumeToken 断点续跑),权威账本始终单 step。两侧改动清单见 §7-A5。 --- @@ -180,7 +181,7 @@ - **兼容性**:部分。平台错误语义(platform_unsupported)已就绪;注入面缺失。 - **问题**:宿主无法注入测试替身或 computer-control 适配器;能力文件模块级捕获引擎状态(excelHandles/ftpClient/ocrInstance/driver),多会话共享。 - **改哪侧**:RPA。 -- **方案**:`createEngine(options?: { driver?, hostBridge?, subflowSource?, registry? })`,全部可选、缺省保持现行为;能力文件改为经 RunContext/engine 参数取 driver 与资源表(模块级捕获改为首用时向 engine 取);幂等句柄表(excelHandles/ftpClient/ocrInstance)迁入 engine 实例字段(部分已是)。 +- **方案(★ 已实现,2026-11-06 阶段 1-A1)**:`createEngine(options?: { driver?, hostBridge?, subflowSource?, registry? })`,全部可选、缺省保持现行为;能力文件改为经 RunContext/engine 参数取 driver 与资源表(模块级捕获改为首用时向 engine 取);幂等句柄表(excelHandles/ftpClient/ocrInstance)迁入 engine 实例字段(部分已是)。 - **验收**:FakeDriver 注入测试覆盖五域;两个 Engine 各注入不同 FakeDriver 并行执行互不串用;非 win32 上 import 全部 34 域不抛错、调用桌面能力时才抛 platform_unsupported。 ### A2 Registry 注册机制与实例隔离 @@ -200,7 +201,7 @@ - **兼容性**:不兼容。对面以幂等键 + 租约纪元管理副作用安全;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 唯一、边合法、入口/出口基数、环、悬空边)。 +- **方案(★ 已实现,2026-11-06 阶段 1-A3)**:①节点尝试创建独立 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(能力注册与权限治理) @@ -221,7 +222,11 @@ - **问题**:两套状态权威冲突风险;集成形态二选一未定(整体作为一个 capability vs 节点级映射为 step)。 - **改哪侧**:adapter + 双侧小改。 - **方案**:**已拍板(ADR-R2)方案 A + 两补丁**——整个 RPA 流程注册为**一个** capability(`rpa.flow.execute`),workflow-engine 的一个 step 调它,RunResult→ActionResult、节点级事件→event-bus 事件流(旁路,不进权威账本)、human-dialog→requestApproval 挂对面 approval 流、取消→signal 直通。补丁 1:节点事件流保透明;补丁 2:人审/高危节点照常升级对面审批。方案 B(节点=step 1:1)的触发条件留档:仅当对面产品确认需要"逐步控制 RPA"(单步执行/任意步回退)时局部启用,届时事件流已备好数据不返工。NodeState 增 `waiting_user`/`unknown` 两态(unknown 用于崩溃恢复对齐)。 -- **验收**:状态映射契约测试(含 waiting_user/unknown/cancelled 全分支);一次含审批节点、一次执行中取消、一次进程崩溃恢复的端到端演练;对面 Run 状态终态与 RPA RunResult 永远一致。 +- **A++ 检查点补记(2026-11-06,本方负责人确认)**:在方案 A 骨架内将节点事件流升级为检查点协议(决策全文见 §10-R2)。 + - **RPA 侧改动**:①事件负载增 `nodeId`/`status`/`checkpointId`/`idempotencyKey`/`resumable` 字段;②`rpa.flow.execute` 接受可选 `resumeToken`,重入时从最近检查点续跑(幂等句柄表已迁 engine 实例字段,地基现成);③幂等键生成与传递贯通(复用 A3 的 `idempotent` 门控,仅补 key 生成与透传)。 + - **对面侧改动**:①workflow-engine 对 `rpa.flow.execute` 所在 step 的重试/恢复策略允许带 resumeToken 重入(不新建 step、不改租约语义);②event-bus 消费端识别检查点事件并入审计链;③崩溃恢复时把 resumeToken 经 adapter 回传(复用 workflow-recovery 的 unknown→恢复路径)。 + - **落地节奏**:阶段 2 只做事件负载字段设计定稿(payload 预留,近零成本);阶段 3 垂直切片做最小验证(崩溃→重入续跑);阶段 4/5 规模化时强制执行。 +- **验收**:状态映射契约测试(含 waiting_user/unknown/cancelled 全分支);一次含审批节点、一次执行中取消、一次进程崩溃恢复的端到端演练;对面 Run 状态终态与 RPA RunResult 永远一致;崩溃重入演练——杀掉执行进程后带 resumeToken 续跑,已完成节点不重复执行、幂等键防重复副作用。 ### A6 Computer Control 与 Windows 桌面执行 @@ -260,7 +265,7 @@ - **兼容性**:不兼容。视觉能力在对面 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 冒烟。 +- **方案(★ 已实现,2026-11-06 阶段 1-A9)**:①抽 `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 插件生命周期、异常隔离与资源清理 @@ -282,9 +287,9 @@ | 阶段 | 内容 | 前置 | 验收门 | |---|---|---|---| | **0 事实确认**(双侧,1 次评审会) | 向对面同步 6 项已拍板结论(R1-R6)并预估 C# actuate 扩展量;确认 2 个小问题(Q1 platform 字段 / Q2 utilityExtended 权限归属);确认事件流接口与 rpa.browser 清单备案 | 无 | Q 有书面结论 | -| **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 一致 | +| **1 RPA 侧收口**(本仓库)✅ **已完成(2026-11-06,提交 9b76dc6/1da0082/1a20dd7/5e8fc96)** | 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 映射 + 状态映射表);A++ 事件负载字段设计定稿(nodeId/检查点/幂等键,见 §7-A5);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 整体注册)+ A++ 检查点续跑最小验证(崩溃→resumeToken 重入,见 §7-A5) | 阶段 2 | 取消/审批/审计全链有证据;对面 Run 终态与 RunResult 一致 | | **4 浏览器与桌面双 ADR 落地** | ADR-R4(已拍板):RPA 浏览器能力修完 transport/resolver,接对面白名单与证据体系后作为 RPA 场景主力 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 置灰 | @@ -306,7 +311,7 @@ | 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 | +| R8 | 两套状态机语义漂移(NodeState vs StepStatus) | 中 | 映射表 + 契约测试常驻 CI;A++ 检查点协议(ADR-R2 补记)统一崩溃恢复语义 | | R9 | catalog 源数据(shizai)上游已删,重生成受阻 | 低 | 已从对面历史恢复至 temp/catalog-source;计划快照入库 | | R10 | 对面底座继续快速演进,本文行号/接口过期 | 中 | 本文标注核查日期;联调前对关键接口做增量 diff | @@ -336,7 +341,7 @@ | R4 | 浏览器双路径 | **按场景分工**:RPA 场景走咱们的 CDP 接管路线(复用用户登录态/真实页面——RPA 核心价值);对面 PlaywrightBrowserRunner 留给 AI 智能体场景(无头自管浏览器)。约束:①咱们 CDP 路线必须接对面 BrowserContextPolicy 白名单与证据体系,不自建;②迁移前修完 transport 超时与定位器不统一两缺陷;③需对面在插件清单给咱们的 runner 备案(rpa.browser) | | R5 | 包消费方式 | **源码并入 + 锁版本**:git subtree 进对面仓库统一编译,Bun 锁 1.4.3(与对面全家 workspace:* 源码消费现状一致) | | R6 | 部署拓扑:rpa-core 各域跑在哪 | **按能力域拆分部署**:纯 Node 域→backend plugin-worker;桌面/视觉/弹窗域→用户电脑 Electron 宿主;同一包按 PLATFORM_GROUPS 分组加载,不维护两份代码 | -| R2 | 集成形态:RPA 流程=单个 capability(方案 A)还是节点=step 映射(方案 B) | **方案 A + 两补丁**:RPA 流程=`rpa.flow.execute` 单能力,对面一个 step 一次租约一次结算;节点级事件走 event-bus 旁路(保透明、不进权威账本);人审/高危节点照常升级对面审批。**不用 B 的理由**(记录在案):双账本一致性(崩溃窗口两边分歧、破坏对面 recovery 的单账本假设)、控制流节点无副作用无法映射 CapabilityRef、审批/重试粒度与业务语义错位。**B 的触发条件**:对面产品确认需要"逐步控制 RPA"(单步执行/任意步回退)时局部启用,事件流已备好数据不返工 | +| R2 | 集成形态:RPA 流程=单个 capability(方案 A)还是节点=step 映射(方案 B) | **方案 A + 两补丁**:RPA 流程=`rpa.flow.execute` 单能力,对面一个 step 一次租约一次结算;节点级事件走 event-bus 旁路(保透明、不进权威账本);人审/高危节点照常升级对面审批。**不用 B 的理由**(记录在案):双账本一致性(崩溃窗口两边分歧、破坏对面 recovery 的单账本假设)、控制流节点无副作用无法映射 CapabilityRef、审批/重试粒度与业务语义错位。**B 的触发条件**:对面产品确认需要"逐步控制 RPA"(单步执行/任意步回退)时局部启用,事件流已备好数据不返工。**A++ 补记(2026-11-06 二次拍板)**:方案 A 骨架不变,节点事件流从"透明度日志"升级为**检查点协议**(nodeId+状态+幂等键+可恢复标记),崩溃后 `rpa.flow.execute` 带 resumeToken 重入、从最近检查点续跑,权威账本仍为单 step、无双账本;B 的隐藏触发条件(长流程断点续跑,RPA 桌面场景高发)由此覆盖而无需节点=step。业界对照:UiPath Orchestrator=Job 黑盒+日志旁路(≈A);Camunda/Zeebe External Task 的"单引擎假设"不适用于双引擎集成;AWS Step Functions callback≈补丁 2。两侧改动清单与落地节奏见 §7-A5 | ### 待对面对确认(仅剩小问题,不猜测)