diff --git a/docs/n12r-internal-operator-minimal-retry-2026-07-09.md b/docs/n12r-internal-operator-minimal-retry-2026-07-09.md new file mode 100644 index 0000000..a9ebeff --- /dev/null +++ b/docs/n12r-internal-operator-minimal-retry-2026-07-09.md @@ -0,0 +1,341 @@ +# N12R 内网操作员最小重做步骤 + +日期:2026-07-09 + +适用对象:内网测试沙盒操作员。 + +目的:修正本次 N12R 返回包中 `selected-window.json` 缺失和 `dump_uia` 失败的问题,重新生成一个可被外网校验接受的 N12R 采集包。 + +## 1. 本次失败原因 + +本次返回包被外网校验拒收,核心原因是窗口句柄写错了。 + +日志中写成了: + +```powershell +$selectedHwnd = "<0x290E6E>" +``` + +这是错误写法。`` 里的尖括号只是提示格式,实际填写时必须删掉。 + +正确写法是: + +```powershell +$selectedHwnd = "0x290E6E" +``` + +因为多了尖括号,后续窗口匹配失败: + +```text +selected hwnd not found in scan result: <0x290E6E> +``` + +所以: + +1. `windows/selected-window.json` 没有生成。 +2. `dump_uia` 使用了无效 hwnd。 +3. `uia/dump-uia-main.json` 返回 `WINDOW_NOT_FOUND`。 + +## 2. 重做前确认 + +在内网测试沙盒中打开 PowerShell,进入仓库根目录: + +```powershell +cd E:\isphere-ai-bridge +``` + +确认 iSphere / IMPlatformClient 已经人工登录,并且主窗口可见、没有最小化。 + +不要执行以下动作: + +```text +搜索联系人 +打开会话 +发送消息 +发送文件 +接收/下载文件 +自动登录 +注入 +hook +读取内存 +绕过安防 +``` + +## 3. 推荐做法:重新运行 scan_windows + +窗口句柄可能已经变化,所以推荐先重新扫描窗口。 + +如果沿用原采集编号: + +```powershell +$captureId = "2026-07-08-internal-sandbox-a" +$captureRoot = "runs\internal-sandbox-live-capture\$captureId" +$helper = Resolve-Path -LiteralPath "runs\win-helper\ISphereWinHelper.exe" +``` + +重新扫描可见窗口: + +```powershell +@{ + protocol = "isphere.helper.v1" + request_id = "n12r-scan-windows-retry" + op = "scan_windows" + timeout_ms = 5000 + args = @{ include_all_visible = $true } +} | ConvertTo-Json -Depth 8 -Compress | + & $helper --json | + Set-Content -Path "$captureRoot\windows\scan-windows.json" -Encoding UTF8 +``` + +查看候选窗口: + +```powershell +Get-Content -Path "$captureRoot\windows\scan-windows.json" -Encoding UTF8 | ConvertFrom-Json | + Select-Object -ExpandProperty data | + Select-Object -ExpandProperty windows | + Where-Object { $_.process_name -match "iSphere|IMPlatform|IMPP" -or $_.title -match "iSphere|IMPlatform|IMPP" } | + Format-Table hwnd,pid,process_name,title,class_name,visible,score -AutoSize +``` + +从输出中选择 iSphere / IMPlatformClient 主窗口的 `hwnd`。 + +示例中之前的候选值是: + +```text +0x290E6E +``` + +如果这次扫描输出变了,请使用新的 `hwnd`。 + +## 4. 正确保存 selected-window.json + +把下面命令中的 `0x290E6E` 改成你刚刚确认的真实窗口句柄。 + +注意:不要加尖括号。 + +正确: + +```powershell +$selectedHwnd = "0x290E6E" +``` + +错误: + +```powershell +$selectedHwnd = "<0x290E6E>" +``` + +保存所选窗口元数据: + +```powershell +$selectedHwnd = "0x290E6E" + +$scanObj = Get-Content -Path "$captureRoot\windows\scan-windows.json" -Encoding UTF8 | ConvertFrom-Json +$selected = $scanObj.data.windows | Where-Object { $_.hwnd -eq $selectedHwnd } | Select-Object -First 1 +if (-not $selected) { throw "selected hwnd not found in scan result: $selectedHwnd" } +$selected | ConvertTo-Json -Depth 8 | Set-Content -Path "$captureRoot\windows\selected-window.json" -Encoding UTF8 +``` + +确认文件已经生成: + +```powershell +Test-Path -LiteralPath "$captureRoot\windows\selected-window.json" +``` + +期望输出: + +```text +True +``` + +## 5. 重新执行 dump_uia + +```powershell +@{ + protocol = "isphere.helper.v1" + request_id = "n12r-dump-uia-main-retry" + op = "dump_uia" + timeout_ms = 15000 + args = @{ + hwnd = $selectedHwnd + max_depth = 8 + include_text = $true + max_children = 100 + } +} | ConvertTo-Json -Depth 12 -Compress | + & $helper --json | + Set-Content -Path "$captureRoot\uia\dump-uia-main.json" -Encoding UTF8 +``` + +检查结果是否成功: + +```powershell +$dump = Get-Content "$captureRoot\uia\dump-uia-main.json" -Encoding UTF8 | ConvertFrom-Json +$dump.ok +$dump.error +``` + +期望: + +```text +True +``` + +并且 `$dump.error` 应为空或为 `null`。 + +如果仍然是 `WINDOW_NOT_FOUND`,说明窗口句柄已经失效。请回到第 3 步重新扫描并选择新的 hwnd。 + +## 6. 重新创建脱敏副本 + +```powershell +Copy-Item -LiteralPath "$captureRoot\uia\dump-uia-main.json" -Destination "$captureRoot\uia\dump-uia-main-redacted.json" -Force +``` + +然后人工打开: + +```text +$captureRoot\uia\dump-uia-main-redacted.json +``` + +脱敏可见敏感文本,例如: + +```text +人员姓名 +手机号 +邮箱 +消息文本 +联系人名称 +敏感业务标题 +类似 token / 密码 / cookie 的字符串 +``` + +尽量保留这些结构字段: + +```text +control_type +automation_id +class_name +framework_id +bounds +is_enabled +is_offscreen +children +``` + +## 7. 修正 source-notes.txt + +打开: + +```text +$captureRoot\metadata\source-notes.txt +``` + +把这些字段从 `是/否` 改成真实值: + +```text +iSphere manually logged in: 是 +client opened before capture: 是 +main window visible: 是 +``` + +如果真实情况不是“是”,不要继续打包,先重新完成对应动作。 + +## 8. 修正 operator-notes.txt + +打开: + +```text +$captureRoot\notes\operator-notes.txt +``` + +不要保留 `<...>` 示例内容。请改成真实说明。 + +示例: + +```text +打开的客户端: iSphere / IMPlatformClient +登录方式: 人工正常公司流程 +是否使用 MFA/SSO: 是,不包含任何秘密 +所选窗口 hwnd: 0x290E6E +选择该窗口的原因: process_name 为 IMPlatformClient,标题为国网甘肃省电力公司,visible=True,score=65 +已做脱敏: 已检查 dump-uia-main-redacted.json,移除可见敏感文本 +采集问题: 首次把 hwnd 写成 <0x290E6E> 导致失败,本次已修正为 0x290E6E 后重新采集 +forbidden actions performed: no +``` + +## 9. 复制出去前必须验证 + +运行必需文件检查: + +```powershell +$required = @( + "$captureRoot\metadata\source-notes.txt", + "$captureRoot\helper\version.json", + "$captureRoot\helper\self-check.json", + "$captureRoot\windows\scan-windows.json", + "$captureRoot\windows\selected-window.json", + "$captureRoot\uia\dump-uia-main.json", + "$captureRoot\uia\dump-uia-main-redacted.json", + "$captureRoot\notes\operator-notes.txt" +) +foreach ($path in $required) { + if (-not (Test-Path -LiteralPath $path)) { throw "missing required file: $path" } +} +"N12R retry package files present: $captureRoot" | Tee-Object -FilePath "$captureRoot\metadata\verification-summary.txt" +``` + +运行 JSON 解析检查: + +```powershell +Get-Content "$captureRoot\helper\version.json" -Encoding UTF8 | ConvertFrom-Json | Out-Null +Get-Content "$captureRoot\helper\self-check.json" -Encoding UTF8 | ConvertFrom-Json | Out-Null +Get-Content "$captureRoot\windows\scan-windows.json" -Encoding UTF8 | ConvertFrom-Json | Out-Null +Get-Content "$captureRoot\windows\selected-window.json" -Encoding UTF8 | ConvertFrom-Json | Out-Null +Get-Content "$captureRoot\uia\dump-uia-main.json" -Encoding UTF8 | ConvertFrom-Json | Out-Null +Get-Content "$captureRoot\uia\dump-uia-main-redacted.json" -Encoding UTF8 | ConvertFrom-Json | Out-Null +``` + +检查 UIA dump 必须是成功: + +```powershell +$dump = Get-Content "$captureRoot\uia\dump-uia-main.json" -Encoding UTF8 | ConvertFrom-Json +if (-not $dump.ok) { throw "dump_uia failed: $($dump.error | ConvertTo-Json -Depth 8 -Compress)" } +``` + +## 10. 重新压缩返回 + +```powershell +Compress-Archive -LiteralPath $captureRoot -DestinationPath "$captureRoot.zip" -Force +``` + +把新的 zip 或目录返回给外网协调环境。 + +返回时请同时说明: + +```text +N12R 重采/补采包已准备好。 +路径: runs/internal-sandbox-live-capture/2026-07-08-internal-sandbox-a/ +人工 iSphere 登录: 是 +采集期间主窗口可见: 是 +forbidden actions performed: no +本次已修正 hwnd,不再包含尖括号;selected-window.json 已生成;dump_uia ok=true +``` + +## 11. 外网收到后如何判断 + +外网协调环境会重新运行: + +```powershell +powershell -NoProfile -ExecutionPolicy Bypass -File .\scripts\validate-n12r-return-package.ps1 ` + -PackageRoot <返回包目录> ` + -ReportPath <包外报告路径> +``` + +只有 validator 输出: + +```text +Decision: ACCEPT +``` + +才能进入 N13 selector 设计。 +