From 747339ff233539a104449b673dbab9253ab7db93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=9F=B3=E5=A4=B4?= <3301352378@qq.com> Date: Thu, 9 Jul 2026 15:57:17 +0800 Subject: [PATCH] docs: design N14 UIA selector report --- ...26-07-09-n14-uia-selector-report-design.md | 343 ++++++++++++++++++ 1 file changed, 343 insertions(+) create mode 100644 docs/superpowers/specs/2026-07-09-n14-uia-selector-report-design.md diff --git a/docs/superpowers/specs/2026-07-09-n14-uia-selector-report-design.md b/docs/superpowers/specs/2026-07-09-n14-uia-selector-report-design.md new file mode 100644 index 0000000..155ecc9 --- /dev/null +++ b/docs/superpowers/specs/2026-07-09-n14-uia-selector-report-design.md @@ -0,0 +1,343 @@ +# N14 UIA Selector Report Design + +日期:2026-07-09 + +## 1. 背景 + +N13 已合并到 `main`,当前已有: + +- `internal/uiaselector/catalog.go`:首批只读 selector catalog。 +- `internal/uiaselector/dump.go`:读取 N12R UIA dump fixture。 +- `internal/uiaselector/matcher.go`:离线匹配 selector,返回结构化节点摘要。 +- `scripts/verify-n13-uia-selectors.ps1`:验证 N13 包和边界。 + +N14 的目标是把 N13 的“可定位”能力变成可交付、可审计的离线报告能力,便于内网采集包返回后快速判断 selector 稳定性和覆盖情况。 + +## 2. 目标 + +N14 建设一个离线报告生成流程: + +1. 输入一个 UIA dump JSON 文件。 +2. 使用 `DefaultCatalog()` 对全部 selector 执行只读匹配。 +3. 输出机器可读 JSON 报告。 +4. 输出人工可读 Markdown 报告。 +5. 在严格模式下,如果存在未命中、歧义命中或非法 selector,则返回非零退出码。 +6. 报告不包含完整可见文本,只包含 `has_name` 和 `name_length` 这类派生字段。 + +N14 只处理离线文件,不访问正在运行的 iSphere,不调用 WinHelper,不新增 helper op,不新增 MCP tool。 + +## 3. 非目标 + +N14 不做以下事项: + +```text +连接内网 iSphere +live dump 当前窗口 +新增 helper op +新增 MCP tool +点击控件 +输入文本 +打开会话 +搜索联系人 +发送消息 +发送文件 +接收文件 +读取聊天内容 +导出完整 visible text +``` + +N14 也不改变 N13 selector 语义。selector 的 `allowed_use` 继续固定为 `read_only_locate`。 + +## 4. 方案比较 + +### 方案 A:只扩展 PowerShell verifier + +做法:在 `scripts/verify-n13-uia-selectors.ps1` 里临时拼接报告。 + +优点:改动小。 + +缺点:报告逻辑难测试,PowerShell 对 Go 内部类型不可见,后续难复用。 + +### 方案 B:新增 Go 报告模型和 CLI,PowerShell 只做包装 + +做法:在 `internal/uiaselector` 增加 report 生成器;新增一个小型 CLI,例如 `cmd/uia-selector-report`。PowerShell 脚本只调用 CLI 并检查输出。 + +优点:核心逻辑可单测;报告结构可稳定复用;CLI 可用于本地、CI 和证据包验收。 + +缺点:新增一个命令入口,需要少量命令行参数解析。 + +### 方案 C:把报告能力接到 MCP 工具 + +做法:新增 MCP 只读工具,对外暴露 selector report。 + +优点:未来可被外部客户端直接调用。 + +缺点:现在会扩大运行面,且 N13/N14 仍处在离线证据验证阶段,不适合作为本阶段目标。 + +推荐采用方案 B。 + +## 5. 推荐设计 + +N14 新增一个“离线报告生成器”,由 Go package 和 CLI 组成。 + +核心分层: + +```text +cmd/uia-selector-report/main.go + 解析参数,调用 report 生成器,写 JSON/Markdown 文件,设置退出码。 + +internal/uiaselector/report.go + RunCatalogReport(root, catalog) -> Report + WriteReportJSON(report, path) + WriteReportMarkdown(report, path) + +internal/uiaselector/report_test.go + 使用 N12R redacted fixture 验证报告结构、命中数量、文本脱敏和严格模式判断。 + +scripts/verify-n14-uia-selector-report.ps1 + 运行 Go 测试,运行 CLI 生成报告,检查报告存在且不包含禁止字段或动作词。 +``` + +N14 不需要新增独立 catalog 文件。首版直接复用 `DefaultCatalog()`。 + +## 6. 报告数据模型 + +建议 JSON 报告顶层结构: + +```json +{ + "ok": true, + "source_dump": "internal/uiaselector/testdata/n12r-2026-07-09-uia-redacted.json", + "catalog_size": 10, + "matched_count": 10, + "unmatched_count": 0, + "ambiguous_count": 0, + "generated_at_utc": "2026-07-09T00:00:00Z", + "selectors": [ + { + "selector_id": "main_window", + "description": "iSphere / IMPlatformClient 主窗口", + "allowed_use": "read_only_locate", + "stability_score": 95, + "evidence": { + "capture_id": "2026-07-08-internal-sandbox-a", + "uia_path": "root" + }, + "matched": true, + "match_count": 1, + "matches": [ + { + "path": "root", + "control_type": "Window", + "automation_id": "frmMain", + "class_name": "WindowsForms10.Window.8.app.0.d3a00f_r29_ad1", + "framework_id": "WinForm", + "has_name": true, + "name_length": 9 + } + ], + "warnings": [] + } + ], + "warnings": [] +} +``` + +要求: + +- `selectors[].matches[]` 复用 `NodeMatch` 的安全摘要字段。 +- 不输出 `name`、`value`、完整 visible text。 +- `generated_at_utc` 由调用方注入 clock,测试中使用固定时间,避免 golden 文件抖动。 +- `ok=false` 只用于报告生成过程失败或 catalog 非法;selector 未命中不让整个报告失败,但会影响严格模式退出码。 + +## 7. Markdown 报告格式 + +Markdown 报告用于人工审阅,建议结构: + +```markdown +# N14 UIA Selector Report + +- Source dump: `...` +- Catalog size: 10 +- Matched: 10 +- Unmatched: 0 +- Ambiguous: 0 + +## Summary + +| Selector | Status | Matches | Stability | Evidence path | +| --- | --- | ---: | ---: | --- | +| main_window | matched | 1 | 95 | root | + +## Selector Details + +### main_window + +- Description: iSphere / IMPlatformClient 主窗口 +- Allowed use: read_only_locate +- Status: matched +- Match count: 1 + +Matches: + +| Path | ControlType | AutomationID | ClassName | FrameworkID | HasName | NameLength | +| --- | --- | --- | --- | --- | --- | ---: | +| root | Window | frmMain | WindowsForms10.Window.8.app.0.d3a00f_r29_ad1 | WinForm | true | 9 | +``` + +Markdown 里同样禁止完整可见文本。 + +## 8. 严格模式 + +CLI 提供 `-strict` 参数。 + +严格模式规则: + +- 报告生成失败:退出码 `1`。 +- 任一 selector `matched=false`:退出码 `2`。 +- 任一 selector `match_count>1`:退出码 `3`。 +- catalog 中存在 `allowed_use != read_only_locate`:退出码 `4`。 +- 报告文本包含禁止字段或动作词:verifier 失败。 + +非严格模式下,未命中或歧义只写入报告和 warnings,CLI 仍返回 `0`。 + +## 9. CLI 参数 + +建议命令: + +```powershell +go run ./cmd/uia-selector-report ` + -dump internal/uiaselector/testdata/n12r-2026-07-09-uia-redacted.json ` + -out-json runs/n14-selector-report/n12r-selector-report.json ` + -out-md runs/n14-selector-report/n12r-selector-report.md ` + -strict +``` + +参数含义: + +- `-dump`:必填,UIA dump JSON 路径。 +- `-out-json`:可选,JSON 报告路径;为空则不写 JSON 文件。 +- `-out-md`:可选,Markdown 报告路径;为空则不写 Markdown 文件。 +- `-strict`:可选,启用严格退出码。 + +CLI 不接收 live hwnd,不接收进程名,不调用任何 Windows UI 自动化 API。 + +## 10. 测试策略 + +N14 implementation plan 必须采用 TDD。 + +核心测试: + +1. `TestRunCatalogReportMatchesAllN13Selectors` + - 读取 N12R redacted fixture。 + - 对 `DefaultCatalog()` 生成报告。 + - 断言 `catalog_size=10`、`matched_count=10`、`unmatched_count=0`、`ambiguous_count=0`。 + +2. `TestReportDoesNotExposeVisibleText` + - 生成 JSON。 + - 断言 JSON 不包含字段名 `name` 和 `value`。 + - 断言 JSON 包含 `has_name` 和 `name_length`。 + +3. `TestMarkdownReportDoesNotExposeVisibleText` + - 生成 Markdown。 + - 断言 Markdown 不包含已知 root visible text。 + - 断言 Markdown 包含 structural fields:`automation_id`、`control_type`、`class_name`。 + +4. `TestStrictModeClassifiesFailures` + - 构造一个缺失 selector 的 catalog。 + - 断言严格模式返回未命中退出分类。 + +5. `TestCLIWritesJSONAndMarkdownReports` + - 用 `go run ./cmd/uia-selector-report` 或拆分后的 main runner 测试。 + - 断言输出文件存在,JSON 可解析,Markdown 有 Summary 表格。 + +6. `TestReportRejectsNonReadOnlyCatalogEntries` + - 构造 `allowed_use=write` 的 selector。 + - 断言报告 `ok=false` 或严格模式分类为非法 catalog。 + +## 11. 验证脚本 + +新增: + +```text +scripts/verify-n14-uia-selector-report.ps1 +``` + +职责: + +1. 确认 `go` 可用。 +2. 运行 `go test ./internal/uiaselector -count=1`。 +3. 运行 `go test ./cmd/uia-selector-report -count=1`,如果 CLI 有测试包。 +4. 调用 CLI 生成报告到 `runs/n14-selector-report/`。 +5. 解析 JSON 报告,确认 catalog/match 统计符合 N12R fixture。 +6. 扫描 JSON/Markdown 输出,确认不含: + - `"name"` + - `"value"` + - `send_after_approval` + - `send_file_after_approval` + - `receive_file_after_approval` + - `open_conversation` + - `InvokePattern` + - `ValuePattern.SetValue` + +`runs/` 已在 `.gitignore` 中忽略,报告输出不进入提交。 + +## 12. 文件规划 + +后续 implementation plan 建议新增或修改: + +```text +internal/uiaselector/report.go +internal/uiaselector/report_test.go +cmd/uia-selector-report/main.go +cmd/uia-selector-report/main_test.go +scripts/verify-n14-uia-selector-report.ps1 +``` + +保持不修改: + +```text +native/ISphereWinHelper/Program.cs +internal/tools/winhelper.go +cmd/isphere-mcp/main.go +``` + +如果 implementation plan 中发现必须改 MCP/helper 文件,应停止并重新提交设计审批。 + +## 13. 风险和边界 + +主要风险: + +1. 报告误包含可见文本。 + - 缓解:复用 `NodeMatch`,JSON/Markdown writer 做禁止字段扫描测试。 + +2. CLI 被误解为 live 工具。 + - 缓解:命令名和参数只出现 `dump` 文件路径,不出现 hwnd/process/live。 + +3. strict 退出码影响 CI 使用。 + - 缓解:默认非严格,验证脚本明确启用 `-strict`。 + +4. 后续 selector 扩容导致 golden 报告抖动。 + - 缓解:测试断言结构和统计,不依赖整份 golden 文本。 + +## 14. N14 验收条件 + +N14 可接受条件: + +1. 可以从 N12R redacted fixture 生成 JSON 报告。 +2. 可以从同一 fixture 生成 Markdown 报告。 +3. 报告显示 10 个 N13 selector 全部唯一命中。 +4. 报告不包含完整 visible text,不包含 `name` 或 `value` 字段。 +5. `-strict` 在 N12R fixture 上返回 `0`。 +6. verifier 脚本通过。 +7. 没有新增 MCP tool,没有新增 WinHelper op,没有修改 live action surface。 + +## 15. 推荐下一步 + +下一步写 N14 implementation plan,按以下任务拆分: + +1. TDD 新增 report model 和 catalog report generator。 +2. TDD 新增 JSON/Markdown writer。 +3. TDD 新增 CLI。 +4. 新增 verifier 脚本。 +5. 跑全量验证并提交。 \ No newline at end of file