PRA-only-demo/docs/rpa-core-migration-guide-v2.md

42 KiB
Raw Blame History

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 全部拍板(2026-11-06),仅剩 2 个小问题(Q1/Q2)需对面口头确认,详见 §10。已定基调:
    • R3 桌面执行:C# 路线——五域执行逻辑移植进 windows-runner 原生进程,PowerShell 通道仅限本 demo。
    • R6 部署拓扑:按能力域拆分——纯 Node 域进 backend plugin-worker,桌面/视觉/弹窗域装用户电脑 Electron 宿主,同一包按分组加载。
    • R1 能力清单:全局一份,权限隔离全交对面网关按租户管。
    • R4 浏览器:按场景分工——RPA 场景用咱们 CDP 接管(复用登录态/真实页面),对面 Playwright 留给 AI 智能体;白名单与证据共用对面一套。
    • R5 消费方式:源码 git subtree 并入对面仓库统一编译,Bun 锁 1.4.3。

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. 接入目标架构

┌─ 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=权威状态 已拍板方案 A(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<ActionResult>,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<CapabilityGateway["execute"]>[1]。
  • 兼容性:状态映射大体可行;RPA 缺 waiting_user/unknown 两态;对面 StepStatus 无 RPA 的 idle。
  • 问题:两套状态权威冲突风险;集成形态二选一未定(整体作为一个 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 永远一致。

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 已拍板:C# 扩展 actuate,见 §10)。
  • 方案:推荐——把 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 已拍板(按场景分工):RPA 场景走咱们 CDP 接管(主力),对面 Playwright 留给 AI 智能体场景。
  • 方案:①RPA 浏览器能力迁前先修 transport 单命令超时 + 统一 resolveElement(一次修复覆盖 locate/click/type/getText);②CDP 接管路线接对面 BrowserContextPolicy 白名单与证据体系(不自建白名单);③与对面确认 rpa.browser 插件清单承载咱们的 runner;④PlaywrightBrowserRunner 保持现状服务 AI 智能体场景,双方不重复投资。
  • 验收:同一定位用例集(css/aria/text/xpath)在咱们 CDP 路径全部通过;白名单拒绝 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 次评审会) 向对面同步 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 一致
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 置灰

不搬的东西(维持 V1 清单):界面渲染层、悬浮框/取色器、本地视觉 onnxruntime、流程存储、内置浏览器编排——由宿主提供或对面重做;其中"本地视觉"明确不进 backend(原生依赖 + 桌面截图依赖),留在宿主桌面进程。


9. 风险清单与总验收标准

风险清单

# 风险 等级 缓解
R1 桌面安全模型冲突 → 已缓解(ADR-R3 拍板 C# 路线):残余风险转为 C# 移植工作量与工期 中 阶段 0 与对面确认 actuate 扩展量;RPA 五域逻辑先行整理成移植清单
R2 部署拓扑错配 → 已缓解(ADR-R6 拍板按域拆分):残余风险为宿主进程加载子集的工程实现 中 阶段 2 按 PLATFORM_GROUPS 分组做宿主子集加载验证
R3 Registry 全局单例在多租户 backend 的隔离缺陷 高 短期按 ADR-R1 限定部署模型;长期 engine-scoped registry 列入 backlog
R4 浏览器双路径重复投资 低(已缓解) R4 已拍板按场景分工(RPA=CDP 接管,AI 智能体=Playwright),白名单与证据共用一套,无重复投资
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. 决策与待确认清单

已拍板(2026-11-06,本方负责人确认)

ADR 问题 决定
R1 Registry 作用域:backend 是否多租户并存 全局一份能力清单(菜单所有租户共用),权限隔离完全由 capability-gateway 按租户管;长期将清单挂到 engine 实例(已从对面源码确认 WorkflowIdentity 带 tenantId,但清单本身无需按租户复制)
R3 桌面执行安全模型:RPA PowerShell 驱动 vs 对面"受信 C# 原生进程"红线 C# 扩展 actuate:把 RPA 五域执行逻辑移植进 windows-runner 原生进程;PowerShell 通道仅限本 demo,不进宿主
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"(单步执行/任意步回退)时局部启用,事件流已备好数据不返工

待对面对确认(仅剩小问题,不猜测)

Q# 问题 评审要点
Q1 CapabilityDefinition 是否需要 platform 字段(对面清单未见) 建议对面补字段或约定由 catalog platformTag 承载
Q2 utilityExtended(命令执行)对应哪个 PermissionScope 13 项中 desktop.process 是候选,需对面确认语义(backend 无桌面,进程执行属哪域)

已回答:Q3(human-dialog 弹窗落点)已由 R6 回答——用户电脑 Electron 宿主窗口;仅样式/交互细节与对面 UI 对齐。


11. 本指南边界

  • 全部结论基于 2026-11-06 双侧工作区源码静态核查 + 少量脚本实测(正则盲区、catalog 统计、capabilityCount);未执行 Windows 实机 E2E 与对面联调,未运行的测试不写成通过。
  • 行号会随代码演进过期,以函数/接口名为准。
  • 本轮只改文档,不改业务源码(用户指令);阶段 1 起的代码改动另行排期。