octopus-rpa-app-runner 技能升级需求 v2

原始文件:wecom_e588f9e2_octopus-rpa-app-runner_技能升级需求_v2.md

octopus-rpa-app-runner 技能升级需求 v2

基于《octopus-rpa-app-runner 技能升级 PRD》v1.0、当前 SKILL.md、Python/PowerShell 脚本、临时脚本与静态测试形成的可实施需求基线。

---

1. 文档信息

项目内容
文档名称octopus-rpa-app-runner 技能升级需求 v2
版本v2.0-draft
日期2026-08-06(Asia/Shanghai)
上游需求octopus-rpa-app-runner_技能升级PRD_20260806.md v1.0
目标版本技能下一次向后兼容的小版本升级
目标将“参数弹窗直接运行”和“关闭运行浮窗”从临时脚本收敛为安全、可观测、可测试的正式能力,并补齐契约与验收标准
实施边界增量升级现有技能,不重构 Octopus RPA Studio,不重写整个 runner,不引入远程调度平台

1.1 规范用语

---

2. 背景、现状与差距

2.1 已有能力

当前技能以 scripts/run_pywinauto.cmd + OctopusRpaAppRunner.py 为默认实现,以 OctopusRpaAppRunner.ps1 为兼容回退,已经具备:

2.2 原 PRD 的主要价值

原 PRD 正确识别了两个 P0 缺口:参数弹窗多输入框时需要受控“直接运行”;停止按钮不存在时需要显式“关闭浮窗恢复 Studio”。本 v2 保留这两个核心目标,不改变原 PRD 的业务方向。

2.3 现状差距

编号现状/歧义风险v2 处理方向
GAP-01--click-run-app-direct 尚无正式 CLI;临时脚本无内建确认误触真实生产运行正式命令、专用确认、弹窗快照复核
GAP-02close_run_window_if_present 存在但无正式 CLI;临时脚本无内建确认未授权停止/关闭;将“关闭”误报为“停止成功”正式命令、专用确认、分阶段结果与后置验证
GAP-03“直接运行”是独立接管现有弹窗,还是运行命令的一种参数策略,原 PRD 未定参数组合和确认范围不清同时定义集成策略与独立恢复命令,语义互斥且可验收
GAP-04多输入框只按数量拒绝,缺少标签到输入框的稳定映射契约填错字段或无法运行显式参数映射优先;自动映射仅限高置信度唯一匹配
GAP-05--skip-run-parameter-dialog 容易被理解为“跳过弹窗并继续运行”,实际是不等待/不处理把“首击成功”误当完整启动保留兼容但弃用,改名为明确的 leave 策略并输出未完成状态
GAP-06--yes-run 当前同时跳过首次运行确认和参数弹窗继续确认一次确认覆盖的动作范围不够清晰输出确认计划;直接运行必须被计划明确包含,独立接管使用专用确认
GAP-07--stop-run-window Python 找不到按钮返回 1,PowerShell 回退仍返回 0调用方无法一致判断失败统一动作结果、退出码和降级规则
GAP-08RUN_LIST_STATE 只有局部输出契约,其他动作多为自由文本Agent 难以可靠判断结果定义稳定的 key-value/JSON 结果契约和事件字段
GAP-09运行成功只输出 Clicked run / Done,缺少“请求、首击、弹窗、二次点击、已观测运行”的层级误报业务成功明确阶段状态;禁止把 UI 点击成功表述为业务完成
GAP-10没有统一错误码,异常大多聚合为退出码 1无法自动恢复或决定是否重试稳定错误码 + 退出码分类
GAP-11无完整幂等约束;重复直接运行可能重复点击,重复关闭结果被当失败重复执行产生副作用或噪声每个写操作定义幂等键、重复调用结果与禁止重试点
GAP-12argparse/PowerShell 未定义动作参数互斥;可同时传入多个主动作执行优先级隐式、调用结果意外主动作互斥校验,冲突直接失败且不触碰 UI
GAP-13互动选择支持 1,3 后顺序运行,但 Octopus 同时只能运行一个应用首个应用启动后第二个动作不可控本次限制单选;批量运行不在范围内
GAP-14“latest by prefix”实现包含关键词匹配,名称与实际语义不完全一致;同版本平局规则未写明选错生产应用明确兼容语义、候选输出和歧义阻断
GAP-15当前 tests_static.py 主要是 assert 与源码字符串检查;缺少 UI 适配层 mock、CLI 契约、错误码、状态转换测试改动易回归,静态通过不代表行为正确建立分层测试矩阵和生产动作门禁
GAP-16Python 与 PowerShell 能力、参数和返回语义已出现漂移回退路径行为不同P0 核心安全语义双实现一致;非核心差异显式声明
GAP-17config.json 写入无原子性/模式版本要求,路径合法性和敏感信息约束未定义配置损坏、泄露或误写最小配置 schema、原子写入、目录校验、日志脱敏
GAP-18SKILL.md 未明确内部主类和临时脚本复用边界再次误用类名或绕过安全门明确 OctopusPywinautoRunner;禁止以临时脚本绕过正式确认

---

3. 目标与成功指标

3.1 产品目标

  1. 多输入框弹窗出现时,技能能安全地:显式映射参数后运行、经用户确认后不填直接运行,或保持弹窗等待人工处理。
  2. 浮窗残留时,技能能经独立确认执行“尝试停止 -> 关闭浮窗 -> 验证 Studio”,并如实报告每一步,而不把关闭视为停止证明。
  3. 所有动作具有稳定命令语义、结果字段、错误码、退出码和最小可回归测试。
  4. 保持现有默认 Python 路径和 PowerShell 回退,不扩大为系统级架构重构。

3.2 成功指标

---

4. 范围与非范围

4.1 本次范围

4.2 非范围

---

5. 角色与场景

5.1 角色

角色诉求权限边界
业务用户选择并运行指定 RPA,恢复 Studio必须确认真实运行、直接运行、停止/关闭等副作用动作
Agent将自然语言转换为安全 CLI 计划并解释结果不得自行补充确认;不得将点击成功说成业务成功
运维/开发排障、查看进程、维护配置和回退实现清理/重启仍需显式授权
测试人员无生产副作用验证状态机和契约默认使用 mock/静态/只读;现场动作使用白名单应用与单独确认

5.2 核心场景

---

6. 功能需求

6.1 动作与命令语义

ID优先级需求
FR-001P0新增正式主动作 --click-run-app-direct:仅在已检测到合法 Octopus 参数弹窗时,不修改输入框,点击唯一可用的“运行应用”按钮。
FR-002P0--click-run-app-direct 不得从应用列表选择应用、不得点击列表 running、不得创建默认目录、不得保存配置;弹窗不存在时返回 PARAM_DIALOG_NOT_FOUND,不得启动 Studio。
FR-003P0独立直接运行动作必须获得专用授权 --yes-direct-run,或在交互模式展示弹窗快照、未填写字段数量和“不填任何输入”的风险后得到肯定答复。仅有 --yes-run 不得授权独立接管一个既有弹窗。
FR-004P0集成运行命令允许通过 --parameter-dialog-policy direct 声明多输入框时直接运行;该策略必须在首次运行确认文本中明确展示。此时 --yes-run 可授权完整计划,但输出必须记录 CONFIRM_SCOPE=initial_run,direct_parameter_continue
FR-005P0新增正式主动作 --close-run-window:检测浮窗 -> 获取快照 -> 确认 -> 再次校验同一浮窗 -> 尝试停止 -> 等待 -> 必要时关闭浮窗 -> 验证 Studio/浮窗状态。
FR-006P0独立关闭浮窗必须使用 --yes-close-run-window 或交互确认;--yes-run--yes-restore-existing-run--yes-direct-run 均不得替代。
FR-007P0--stop-run-window 语义保持为“只尝试停止,不关闭”;找不到停止按钮或无法确认点击时返回非成功结果,绝不隐式升级为 close。
FR-008P0运行新应用前发现已有浮窗时,继续使用 --yes-restore-existing-run 独立授权恢复旧运行;该授权只对确认时的窗口快照有效,不授权新应用运行。
FR-009P0所有主动作必须互斥。主动作包括 list、run exact、run latest、current/check、process snapshot、stop、close、restart clean、direct parameter continue、set-default-only。冲突时返回参数错误且不得访问 UI。
FR-010P1互动选择本次只允许选择一个应用;输入多个编号时提示“不支持批量运行”并要求重新选择,不得顺序点击多个生产应用。

6.2 参数对话框

ID优先级需求
FR-011P0将参数弹窗处理定义为策略:auto(默认)、mapdirectleave。不得因检测失败自动从 auto 降级到 direct
FR-012P0auto 仅在恰有一个可写 Edit,且满足高置信度规则时填写目录并点击;零个、多个或只读输入均阻断二次点击并返回可操作错误。
FR-013P0direct 必须枚举并输出 PARAM_INPUT_COUNT、非空/空值状态(不得输出敏感值)和 PARAM_DIALOG_FINGERPRINT,然后执行专用确认机制;确认前不得改值或点击。
FR-014P1map 支持重复参数 --parameter <key>=<value>。key 匹配优先级为 AutomationId 精确匹配 > 关联 Label 精确匹配 > 可访问名称精确匹配;同层级多匹配、零匹配或一个控件被多个 key 命中均失败。
FR-015P1多输入框映射不得仅凭控件顺序自动填写。若要按索引映射,必须使用显式 index:<1-based> key,并输出控件摘要供用户确认;默认禁用索引猜测。
FR-016P1参数值写入后必须回读验证;不支持 ValuePattern 时可使用现有键盘回退,但仍需回读或返回 PARAM_VALUE_UNVERIFIED,不得直接点击“运行应用”。
FR-017P1对目录型参数,在写入前规范化路径;是否自动创建目录必须由 --create-missing-directories 明确授权,或在交互确认计划中列明。不得因 direct 策略创建目录。
FR-018P1leave 表示完成应用列表首击后不等待/不处理参数弹窗,结果必须是 RUN_STAGE=initial_clickedSTART_VERIFIED=false;原 --skip-run-parameter-dialog 保留为该策略的弃用别名。
FR-019P1参数弹窗识别必须同时满足:窗口属于 OctopusRPA.Studio 进程、存在唯一“运行应用”按钮、存在参数区域标识;多个候选弹窗时返回歧义错误,不得取第一个。
FR-020P1点击“运行应用”前必须按窗口 handle、pid、按钮标识和输入控件摘要复核指纹;指纹变化则取消本次授权并要求重新确认。

6.3 应用选择与启动验证

ID优先级需求
FR-021P1--run-exact-name 必须严格全名匹配,零匹配/多匹配均不点击。
FR-022P1--run-latest-by-prefix 为兼容旧名称可保留,但必须文档化实际为 token/前缀候选匹配;候选属于多个明显不同业务前缀或最高版本平局时,输出候选并阻断,除非精确前缀可唯一消歧。
FR-023P0运行阶段至少区分:selectedinitial_clickedparameter_waitingparameter_submittedstart_observedstart_unverifiedcancelledfailed
FR-024P0Done 只能表示命令流程结束,不得表示 RPA 业务完成。成功点击参数弹窗按钮后,应尝试观测浮窗、运行列表或受控进程证据;无证据时返回 start_unverified,并可使用警告类退出码。
FR-025P1验证优先级为:运行列表显示目标应用 > 新的合法运行浮窗 > Octopus BrowserBridge/受控 Edge 进程变化。仅进程证据不得证明具体应用名称。
FR-026P1验证应使用动作前后的快照差异,避免把早已存在的浮窗/进程误认为本次启动结果。

6.4 浮窗停止与关闭

ID优先级需求
FR-027P0--close-run-window 输出 STOP_ATTEMPTEDSTOP_CLICKEDWINDOW_CLOSE_ATTEMPTEDWINDOW_CLOSEDSTUDIO_RESTOREDRUN_STOP_VERIFIED 六个独立字段。
FR-028P0找不到停止按钮时,交互确认必须明确:“将关闭浮窗以恢复 Studio,但无法证明任务已经停止”;只有专用关闭确认覆盖该风险后才能关闭。非交互命令若已给 --yes-close-run-window,确认计划中应预先声明此降级。
FR-029P0关闭浮窗后必须重新枚举窗口。Studio 可访问但运行列表为 unknown 时结果为 partial;运行列表仍为 active 时结果为失败/不安全,不得输出“停止成功”。
FR-030P1浮窗不存在且 Studio 可用时,重复 --close-run-window 返回 already_restored,退出成功,不触发任何点击。浮窗和 Studio 均不可识别时返回状态未知,不启动 Studio。
FR-031P1若停止点击后浮窗自行消失,禁止继续向旧 handle 发送 close;直接进入后置验证。
FR-032P1close 操作不得杀进程。只有独立 --restart-studio-clean 能执行受限进程清理,且继续遵守现有显式授权和 Edge 进程树边界。

6.5 配置、兼容与文档

ID优先级需求
FR-033P1config.json 增加 schema_version,保留现有 DataDirectory 读取兼容;写入采用临时文件 + 原子替换,失败不得破坏旧配置。
FR-034P1默认不持久化 --parameter 值;本次仅允许继续记忆非敏感目录。日志不得输出令牌、密码或疑似敏感字段的值。
FR-035P1SKILL.md 必须明确主类名 OctopusPywinautoRunner,但将内部方法标记为非稳定 API;不得再推荐通过临时脚本绕过正式确认。
FR-036P1Python 是默认实现;PowerShell 为回退。两者对 P0 命令、确认边界、错误码和退出类别必须一致;暂不支持的增强参数必须明确返回 UNSUPPORTED_IN_FALLBACK,不得静默改变语义。
FR-037P1临时脚本可保留一个迁移版本,但调用时必须打印弃用提示并转发正式 CLI;不得继续保留无确认的独立实现。后续小版本可移除。

---

7. 非功能需求

ID优先级需求
NFR-001P0安全默认:不确定即阻断;unknown 不得解释为空闲或成功。
NFR-002P0可审计:每次命令生成 OPERATION_ID,确认、快照、动作和验证事件均关联该 ID。
NFR-003P1性能:在桌面会话正常时,弹窗检测默认 12 秒内结束;关闭浮窗后置验证默认 15 秒内结束;超时可配置但必须有上限。
NFR-004P1可靠性:UI 控件引用在关键点击前重新查询;不得长时间持有虚拟化列表行或已变化弹窗控件。
NFR-005P1可测试性:业务决策逻辑与 pywinauto/PowerShell UI 调用应可通过适配器或 mock 隔离测试;不要求整体重构。
NFR-006P1可维护性:Python 与 PowerShell 共享同一份文档化错误码/输出契约;测试检查行为而非大量源码字符串。
NFR-007P1兼容性:Windows 10/11、PowerShell 5.1+、现有技能本地 .venv;不得要求全局 Python 包。
NFR-008P1日志编码统一为 UTF-8;机器输出字段使用 ASCII key,值按 UTF-8 输出。
NFR-009P2可诊断性:--output json 时提供控件摘要和阶段耗时,但不得包含输入框原始敏感值。

---

8. 安全约束与确认机制

8.1 动作授权矩阵

动作默认行为所需非交互确认不可替代的确认
列应用/查状态/进程快照只读执行不得产生任何副作用
首次点击应用列表运行按钮阻断并询问--yes-run不授权恢复旧浮窗或独立接管弹窗
集成流程采用 direct 参数策略在首次确认中明确展示后执行--yes-run + --parameter-dialog-policy direct输出确认范围必须含 direct continue
独立接管既有参数弹窗并直接运行阻断并询问--click-run-app-direct --yes-direct-run--yes-run 不可替代
仅停止浮窗显式命令执行--stop-run-window 本身代表请求;若产品要求二次确认则使用专用确认找不到按钮不得自动 close
独立关闭浮窗恢复 Studio阻断并询问--close-run-window --yes-close-run-window其他 yes 标志不可替代
为新应用恢复旧运行阻断并询问--yes-restore-existing-run不授权新应用运行
清理进程并重启 Studio保持现有显式维护动作门禁独立维护确认不得由 close/stop 自动触发

8.2 交互确认内容

直接运行确认必须展示:

关闭浮窗确认必须展示:

8.3 确认有效期和竞态保护

---

9. CLI 与输出契约

9.1 推荐 CLI

run_pywinauto.cmd --click-run-app-direct [--yes-direct-run]
run_pywinauto.cmd --close-run-window [--yes-close-run-window]
run_pywinauto.cmd --run-exact-name NAME --parameter-dialog-policy auto|map|direct|leave [--parameter KEY=VALUE ...] [--yes-run]
run_pywinauto.cmd --run-latest-by-prefix KEY --parameter-dialog-policy auto|map|direct|leave [--yes-run]
run_pywinauto.cmd --output text|json

约束:

9.2 文本输出

机器可依赖的最终结果块必须每行一个 KEY=VALUE,至少包含:

CONTRACT_VERSION=2
OPERATION_ID=<uuid>
ACTION=<action>
RESULT=success|partial|cancelled|failed|already_satisfied
STAGE=<state>
CHANGED=true|false
VERIFIED=true|false
ERROR_CODE=<code-or-empty>
MESSAGE=<single-line-human-readable-message>

动作可增加字段,例如:

PARAM_DIALOG_FOUND=true
PARAM_INPUT_COUNT=3
DIRECT_RUN_CLICKED=true
STOP_ATTEMPTED=true
STOP_CLICKED=false
WINDOW_CLOSED=true
STUDIO_RESTORED=true
RUN_STOP_VERIFIED=false
RUN_LIST_STATE=unknown

要求:

9.3 JSON 输出

--output json 必须只向 stdout 输出一个合法 JSON 对象;诊断日志写 stderr。最小 schema:

{
  "contract_version": 2,
  "operation_id": "...",
  "action": "close_run_window",
  "result": "partial",
  "stage": "studio_restored",
  "changed": true,
  "verified": false,
  "error": {"code": "RUN_STOP_UNVERIFIED", "message": "..."},
  "evidence": {
    "stop_attempted": true,
    "stop_clicked": false,
    "window_closed": true,
    "studio_restored": true,
    "run_list_state": "unknown"
  }
}

9.4 退出码

退出码类别示例
0成功、已满足或用户主动取消verified success、already restored、cancelled
2状态未知/部分完成,调用方不得当作安全run list unknown、窗口已关但停止未验证、启动未验证
3参数/用法错误主动作冲突、缺少配套参数、非法 policy
4未授权非交互环境缺少对应 yes 标志
5目标不存在或歧义弹窗不存在、应用零/多匹配、多个候选弹窗
6UI 动作失败或竞态控件消失、指纹变化、点击失败、回读失败
7环境/依赖失败无 pywinauto、本地 venv 缺失、非活动桌面会话
1未分类内部错误(兜底)编程错误或未映射异常

用户取消虽返回 0,但 RESULT=cancelledCHANGED=false,调用方不得将其当作动作成功。

9.5 错误码

至少提供以下稳定错误码:

---

10. 状态机

10.1 运行状态机

IDLE/STUDIO_READY
  -> APP_SELECTED
  -> RUN_CONFIRMED
  -> INITIAL_RUN_CLICKED
     -> START_OBSERVED                         (无参数弹窗)
     -> PARAMETER_WAITING                      (检测到弹窗)
        -> PARAM_AUTO_MAPPED -> PARAM_SUBMITTED
        -> PARAM_EXPLICITLY_MAPPED -> PARAM_SUBMITTED
        -> DIRECT_RUN_CONFIRMED -> PARAM_SUBMITTED
        -> LEFT_FOR_MANUAL -> START_UNVERIFIED
        -> CANCELLED
     -> START_UNVERIFIED                       (超时无明确证据)
  -> FAILED

转换约束:

10.2 浮窗恢复状态机

RUN_WINDOW_DETECTED
  -> CLOSE_CONFIRMED
  -> SNAPSHOT_REVALIDATED
  -> STOP_ATTEMPTED
     -> STOP_CLICKED -> WAIT_FOR_DISAPPEAR
     -> STOP_NOT_AVAILABLE
  -> WINDOW_ALREADY_GONE -> VERIFY_STUDIO
  -> WINDOW_CLOSE_ATTEMPTED -> WINDOW_CLOSED
  -> VERIFY_STUDIO
     -> RESTORED_AND_STOP_VERIFIED
     -> RESTORED_BUT_STOP_UNVERIFIED
     -> STILL_ACTIVE
     -> RESTORE_FAILED

10.3 可观测状态与业务状态

技能仅声明:

技能不得声明:

---

11. 幂等性与重试

动作重复调用规则自动重试边界
list/current/process snapshot天然只读,可重试可对读取超时做有限重试,不产生 UI 副作用
direct parameter run非幂等;点击后不得自动重复点击仅可在点击前重新查找/复核;点击结果未知时返回 partial,不重试
initial run click非幂等Invoke 调用后即使验证超时也不得再次点击
parameter value write在同一弹窗、同一目标值下可幂等写入回读失败可重查一次;不可切换到其他输入框
stop run window条件幂等点击后可轮询状态,不自动第二次点击未知按钮
close run window目标状态幂等已恢复返回 already_satisfied;旧 handle 消失后不发送 close
set default directory同值幂等原子写失败可保留旧配置,不循环覆盖

建议以 OPERATION_ID + action + target fingerprint 记录进程内动作账本;本次不要求跨进程持久化幂等键。

---

12. 异常处理

12.1 通用原则

  1. 参数校验失败:不初始化 UI、不写配置。
  2. 目标歧义:输出候选摘要,等待用户选择,不猜测。
  3. 确认后对象变化:作废确认,不自动套用到新对象。
  4. 点击结果未知:停止副作用动作,返回 partial/unknown,不盲目重试。
  5. 只读命令遇到浮窗:报告受限,不关闭、不停止、不启动 Studio。
  6. Python 默认实现失败时,不得在已执行副作用后自动切换 PowerShell 重做;只允许在任何点击前、安全可判定时回退。

12.2 关键异常表

场景处理结果
参数弹窗不存在,执行 direct不启动 Studio,不点击其他按钮PARAM_DIALOG_NOT_FOUND, exit 5
两个合法参数弹窗输出候选数量/摘要,不选第一个PARAM_DIALOG_AMBIGUOUS, exit 5
多输入框且 auto保留弹窗,不填不点PARAM_INPUT_AMBIGUOUS, exit 5
map 缺字段或一对多不写任何字段;映射计划应先整体校验PARAM_MAPPING_FAILED, exit 5/6
写入后无法回读不点击运行应用PARAM_VALUE_UNVERIFIED, exit 6
direct 确认后弹窗变化不点击STALE_CONFIRMATION, exit 6
stop 找不到按钮stop 命令失败;close 命令按已确认降级继续STOP_BUTTON_NOT_FOUND
close 后 Studio 恢复、状态 unknown如实报告 partialRUN_STOP_UNVERIFIED, exit 2
close 后运行列表 active报仍有运行,不执行进程清理RUN_STOP_UNVERIFIED, exit 2/6
无活动桌面/锁屏不尝试坐标点击UI_SESSION_UNAVAILABLE, exit 7
配置损坏忽略为默认值前先警告;不覆盖损坏文件,除非显式修复CONFIG_INVALID

---

13. 验收标准

13.1 P0 验收

AC对应需求Given / When / Then
AC-001FR-001~003Given 一个合法、多输入框参数弹窗;When 执行 direct 且未确认;Then 不修改输入、不点击,返回 confirmation required。
AC-002FR-001~004Given 同一弹窗;When 用户确认“不填直接运行”;Then 复核指纹,仅点击唯一“运行应用”,输出输入框数量和点击结果。
AC-003FR-002Given 无参数弹窗;When 执行 direct;Then 不启动 Studio、不创建目录、不点击其他控件,返回 PARAM_DIALOG_NOT_FOUND
AC-004FR-005~006Given 浮窗存在;When close 未确认;Then stop/close 点击均为 0。
AC-005FR-005, FR-027~029Given 浮窗有停止按钮;When 已确认 close;Then 先 stop,若浮窗消失不再 close,并输出六个阶段字段与后置验证。
AC-006FR-028~029Given 浮窗无停止按钮;When 已确认 close;Then 输出 stop 未点击,再关闭浮窗;若状态未知则 result=partial、exit 2,不宣称停止成功。
AC-007FR-007Given 浮窗无停止按钮;When 仅执行 stop;Then 不关闭浮窗,返回非成功错误码。
AC-008FR-008Given 有旧浮窗且要运行新应用;When 只有 --yes-run;Then 不恢复旧浮窗、不运行新应用,要求 restore 确认。
AC-009FR-009Given 同时传 list 与 run;When CLI 解析;Then exit 3,UI 访问和配置写入均为 0。
AC-010FR-011~013Given 多输入框、policy=auto;When 运行;Then 不填不点,保持 parameter_waiting 并返回歧义。
AC-011FR-023~026Given按钮点击成功但无后置证据;When 验证超时;Then start_unverified/exit 2,不输出业务成功。
AC-012NFR-001Given run list unknown;When 查询或后置验证;Then RUN_LIST_SAFE=false,不可进入安全空闲状态。

13.2 P1 验收

AC对应需求Given / When / Then
AC-013FR-014~016Given 两个带唯一 AutomationId/Label 的 Edit;When 提供完整 map;Then 整体校验后逐项写入并回读,再点击。
AC-014FR-015Given 两个无标识 Edit;When 未提供 index 映射;Then 不按顺序猜测。
AC-015FR-018Given policy=leave;When 首击后出现弹窗;Then 不处理弹窗,结果为 initial_clicked/start_unverified。
AC-016FR-019~020Given确认后窗口 handle 或控件摘要变化;When 准备点击;Then 返回 stale confirmation,点击数为 0。
AC-017FR-010Given互动输入 1,3;When 解析;Then 提示不支持批量,不点击任何应用。
AC-018FR-030Given无浮窗且 Studio 已可用;When close;Then already_satisfied、changed=false、exit 0。
AC-019FR-033Given旧版仅含 DataDirectory 的 config;When 读取并更新;Then 值兼容,原子写出 schema_version,失败时旧文件完整。
AC-020FR-036Given同一 mock 场景;When Python 与 PowerShell 执行 P0 动作;Then动作边界、错误码和退出类别一致。
AC-021FR-037Given运行旧临时脚本;When 调用;Then展示弃用提示并进入正式 CLI 确认门,不可直接点击。
AC-022NFR-002Given任意动作;When查看输出;Then所有阶段事件和最终结果具有同一 operation_id。

13.3 发布门槛

---

14. 测试矩阵

层级用例PythonPowerShell是否允许生产副作用
静态语法、help、参数互斥、弃用别名必测必测
单元参数策略、确认范围、状态转换、错误码、退出码必测可通过函数级脚本测试
单元多输入框 label/AutomationId/index 映射与歧义必测必测 P1 核心
单元窗口/弹窗 fingerprint 比较和 stale confirmation必测必测
单元latest 匹配、平局、批量选择拒绝必测必测
单元config 旧 schema、原子写失败、敏感字段脱敏必测必测
Mock UIdirect:无弹窗/单弹窗/多弹窗/按钮消失/点击异常必测必测 P0
Mock UIclose:有 stop/无 stop/stop 后消失/close 失败/状态 unknown必测必测 P0
契约text 与 JSON schema、stdout/stderr、operation_id必测必测
回归list/current 保持只读,浮窗存在时不恢复必测必测
回归stop 不自动 close,restart clean 不扩大进程树必测必测
集成只读--list-only--current-running--process-snapshot必测回退抽测
现场受控参数弹窗直接运行用户确认后默认实现通过后再抽测是,需白名单
现场受控无 stop 按钮时 close 恢复用户确认后默认实现通过后再抽测是,需维护窗口

测试实现要求:

---

15. 版本迁移与兼容策略

15.1 CLI 迁移

旧能力v2 行为兼容计划
--yes仍仅等价 --yes-run保留一个小版本并警告,不扩大权限
--skip-run-parameter-dialog等价 policy=leave保留一个小版本并打印弃用提示
--stop-run-window继续只 stop修正 PowerShell 失败仍 exit 0 的不一致;发布说明标记行为收紧
临时 click_run_app_direct.py转发正式 direct CLI一个小版本后移除
临时 close_run_window_direct.py转发正式 close CLI一个小版本后移除
config.json 无 schema按 schema v1 兼容读取下次写入迁移到 schema v2,原子替换
--run-latest-by-prefix保留旧名与 token/前缀匹配增加歧义阻断,不静默选跨业务候选

15.2 行为变化说明

15.3 发布步骤

  1. 先落地错误码、结果对象、参数互斥和 mock 测试。
  2. 实现 Python direct/close 正式入口及确认。
  3. 对齐 PowerShell P0 安全语义,或对未支持能力明确阻断。
  4. 更新 SKILL.md、help、临时脚本转发和迁移说明。
  5. 运行静态、单元、mock、只读集成测试。
  6. 获得用户单独确认后进行受控现场验收。

---

16. 待确认项

ID优先级待确认问题建议默认决策
TBD-01阻塞 P0独立 --stop-run-window 是否也必须增加二次 yes 标志?当前命令本身已是显式动作。本次保持命令即授权;Agent 自然语言层仍需用户明确说“停止”。
TBD-02阻塞 P0close 在找不到 stop 时,是否允许非交互 --yes-close-run-window 直接覆盖“仍关闭”的降级风险?允许,但 help/结果必须明确该标志包含此降级。
TBD-03阻塞 P1多输入框 --parameter key=value 的首批 key 是否以 AutomationId/Label 为主,是否需要维护应用级别名配置?本次只做通用精确映射;应用级模板不在范围内。
TBD-04非阻塞start_observed 是否要求浮窗出现即可,还是必须运行列表出现目标名称?浮窗可作为启动观测成功,但仅运行列表可验证具体应用;输出 evidence_level 区分。
TBD-05非阻塞PowerShell 回退是否必须在同一版本支持 map,还是只保证 P0 direct/close?P0 direct/close 同版;map 可返回明确 unsupported,不得静默 direct。
TBD-06非阻塞用户取消是否沿用 exit 0,还是使用单独退出码?保持 exit 0 兼容,以 RESULT=cancelled 区分。
TBD-07非阻塞现场验收使用哪个无敏感副作用的白名单应用,以及由谁确认业务影响?发布前由业务负责人指定,未指定则只做 mock 和只读验收。
TBD-08非阻塞参数对话框中的已有非空值是否允许日志输出摘要长度/哈希?默认只输出 empty/non-empty,不输出长度和哈希。
TBD-09非阻塞--output json 是否纳入本次 P1,还是先稳定文本 key-value?建议 P1 同版实现,若排期不足至少保留结果对象并锁定 schema。

---

17. 需求追溯

原 PRD 需求v2 对应
REQ-01 --click-run-app-directFR-001~004、FR-011~013、FR-019~020、AC-001~003
REQ-02 --close-run-windowFR-005~008、FR-027~032、AC-004~008、AC-018
REQ-03 参数对话框交互升级FR-011~020、参数映射与确认机制、AC-010、AC-013~016
REQ-04 SKILL.md 类名/复用说明FR-035、FR-037;保留类名说明但禁止绕过正式安全门
REQ-05 用例回归与验证第 13、14 节完整验收与测试矩阵

---

18. 最终交付物

---

*本需求尊重原 PRD 的增量升级范围,核心聚焦参数弹窗直接运行与关闭浮窗恢复,不扩展为整个 RPA 系统重构。*