# 浏览器会话与证据契约 真实浏览器分析不能用“端口已监听”“动作已注册”或“页面出现日志”代替成功。每次导航、注入和调用都要绑定到当前浏览器会话与当前文档,并在状态变化后重新确认。 ## 操作前 1. 读取浏览器连接状态,确认连接的是用户指定的浏览器,而不是新建的临时页面。 2. 列出页面并锁定 `tabId`、当前 URL 和当前文档身份;没有稳定文档身份时,至少记录页面 URL 与导航时间。 3. 注入或修改前记录操作 ID、目标页面、脚本版本指纹和预期作用范围。 4. 页面发生导航、刷新、跨文档 iframe 切换或调试器重新连接后,旧的元素引用、调用栈、断点和注入确认全部视为失效,必须重新快照或重新注入。 ## 操作中 - 超时只表示“结果未知”,不表示操作没有执行。不要盲目重放可能有副作用的登录、签名或状态修改动作;先读取状态、事件和当前文档。 - 调试器暂停时,调用、导航和注入的返回值可能只是“已排队”或“等待恢复”。必须恢复后再次读取状态,不能把旧的暂停信息当成新结果。 - 桥接断开时,清理未完成请求;重新连接后重新列页面并重新绑定文档。只有幂等的只读操作可以自动重试,登录和加密动作默认不自动重放。 - 事件、源代码和请求体采用有界读取;敏感字段默认只保留长度、哈希或脱敏预览,不能因为导出失败而放宽范围。 ## 操作后 JSRPC action 级结果至少要同时出现: - 输入明文或其明确的参数标识; - 非空的最终请求体; - 最终请求 route/URL; - HTTP 状态; - 最终业务响应。 如果浏览器控制面能提供会话信息,额外保存如下绑定: ```json { "session": { "connected": true, "tabId": 1, "documentId": "document-generation" }, "operation": { "id": "operation-id", "status": "confirmed", "applied": true } } ``` `status=timeout`、`status=pending`、`applied=false`、文档身份缺失或返回中包含错误标记时,只能报告为未确认。使用 `scripts/validate_browser_evidence.py` 生成 `artifacts/browser_evidence.json`,再把它作为最终报告的验证依据。 ## 最小恢复顺序 ```text 读取桥接状态 → 列出页面 → 重新绑定 tab/document → 重新快照或注入 → 触发一次动作 → 等待最终网络请求 → 导出有界证据 → 校验交付契约 ``` 不要用旧页面的元素引用、旧 WebSocket 请求 ID 或旧文档上的 Hook 结果替代这条恢复链。