docs: add N12R operator retry steps
This commit is contained in:
341
docs/n12r-internal-operator-minimal-retry-2026-07-09.md
Normal file
341
docs/n12r-internal-operator-minimal-retry-2026-07-09.md
Normal file
@@ -0,0 +1,341 @@
|
||||
# N12R 内网操作员最小重做步骤
|
||||
|
||||
日期:2026-07-09
|
||||
|
||||
适用对象:内网测试沙盒操作员。
|
||||
|
||||
目的:修正本次 N12R 返回包中 `selected-window.json` 缺失和 `dump_uia` 失败的问题,重新生成一个可被外网校验接受的 N12R 采集包。
|
||||
|
||||
## 1. 本次失败原因
|
||||
|
||||
本次返回包被外网校验拒收,核心原因是窗口句柄写错了。
|
||||
|
||||
日志中写成了:
|
||||
|
||||
```powershell
|
||||
$selectedHwnd = "<0x290E6E>"
|
||||
```
|
||||
|
||||
这是错误写法。`<HWND>` 里的尖括号只是提示格式,实际填写时必须删掉。
|
||||
|
||||
正确写法是:
|
||||
|
||||
```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 设计。
|
||||
|
||||
Reference in New Issue
Block a user