Files
Haocode/docs/agent-handoff/EXECUTION_STATE.md
T
sorrow404null bc0b92bcdc docs: add agent handoff docs, verification guide, and repair evidence
Add docs/agent-handoff (backlog, execution state, verification, platform plan, per-task evidence), repo AGENTS.md, and architecture notes updated for the dual-renderer design.
2026-09-17 16:40:06 +08:00

66 lines
9.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 全量修复执行状态
状态:ACTIVE
总目标:完成 REPAIR_BACKLOG.md 中所有待实施任务
## 调试铁律(跨压缩持久,每次恢复后必须遵守)
- **所有调试命令、测试与诊断脚本执行都必须设置显式的最长耗时预算(timeout)**。
- 若中途因超时跳出,先定位卡点,再允许延长预算重跑;**严禁不设超时让它无限卡死**。
当前任务:全部完成(P0-01 → P2-04
当前阶段:COMPLETE(自动化部分;Windows 真机双渲染路径已验证;Linux 真机平台验证项见各任务 evidence)
最后完成动作:Windows 真机验证 —— ① `core/webview2.py` 加 byte[] 加载回落(本机 D: 卷 .NET “网络位置”怪癖),真桌面 WebView2 启动成功(Runtime 153.0.4234.32、controller ready、NavigationCompleted、截图像素证实聊天区真实 DOM 渲染);② `HAOCODE_FORCE_QTWEBENGINE=1` 真桌面回落验证(独立 per-instance profile、无 taskkill、渲染正常);③ P2-02 真机截图(diag_panel_scrollbar 真桌面 ALL PASS,三图已更新);④ T0 守卫真机交叉验证(diag 实例被锁自动回落,未误杀主程序 WebView2);证据更新 evidence/P1-03.md、evidence/P2-02.md、evidence/P2-03.md
下一步唯一动作:P2-03 人工清单 1–5 可在本机真实 WebView2 模式下走查(app 现可正常以 WV2 启动,当前前台实例为强制 QtWebEngine 模式,重开即默认 WV2);其余为 Linux 真机验证(P1-03/P1-04),需 Ubuntu 桌面主机
当前修改文件:core/webview2.pybyte[] 加载回落 + BaseException 防护)、docs/agent-handoff/evidence/{P1-03,P2-02,P2-03}.md、evidence/win_real_*_mainwindow.png(新)
最近测试结果:test_wv2_guard 10/10(修复后无回归);diag_panel_scrollbar 真桌面 ALL PASSrun_all 25/25(前次终态)
尚未验证的平台:Linux X11、Linux WaylandP1-03 启动链、P1-04 X11 XGrabKey 真实注册/命中、Wayland portal 三态均需真机);Windows 真机双渲染路径(WebView2 + QtWebEngine 回落)已于 2026-09-17 验证,仅剩 P2-03 人工遮罩走查(1–5,可本机执行)
阻塞项:无
观察项:
- 【P1-01 教训·offscreen QtWebEngine 诊断】未 `window.resize()`+`show()``innerHeight=0`,锚点/滚动几何全废;诊断必须先 resize+show、等待 `innerHeight>0`、再显式 `load_messages_to_web` 重载
- 【P1-01 教训】`runJavaScript` 回调不能返回 DOM 元素(转换失败);`wait_until` 条件一律返回原语(`cond ? 1 : 0`
- 【P1-01 教训】批次渲染守卫(`__rwPageRendering`)必须在**调度时刻**捕获,延迟回调(rAF+setTimeout)触发时批次已结束、标志已复位,届时再读会漏放 `scrollIntoView` 触发 'newer' 振荡
- 【P1-01 设计】页 = 半窗(`size//2`),非整窗:整窗页会使向上换页锚点必被裁出窗口,≤2px 锚点恢复不可达
- 【P1-02 教训】Windows 下 argv 列表形态 Popen 会被 `list2cmdline` 转义内部引号(`\"`),cmd.exe 不认 → 显式 cmd 契约必须用**字符串命令行** `cmd.exe /d /s /c "<cmd>"`
- 【P1-02 发现】旧 `shell=True` 对带引号程序名实为直接 CreateProcessW(不经 cmd);显式 cmd 后行为统一且可预测
- 【P1-03 教训】`QTimer.singleShot` 单位是**毫秒**(25 = 25ms),兜底预算要写 30000;事件循环启动前不触发
- 【P1-03 教训】QtWebEngine 顺序硬约束:QtWebEngineWidgets 必须先于 QApplication 导入;QWebEngineProfile 必须先于使用它的 page/view 创建,且 setPersistentStoragePath/setCachePath 要在 profile 使用前调
- 【P1-03 发现】PyQt6-WebEngine 6.10 未暴露 `QWebEnginePage.errorOccurred`(Qt 6.5+ API),加载失败诊断用 loadFinished(ok) + processEvents 循环
- 【P1-03 教训】改构造函数签名必须保旧式位置调用:`CustomWebPage(browser)` 的 view 会被新首形参误当 profile,按 `isinstance(QWebEngineProfile)` 分派
- 【P1-04 教训】PyQt6`QThread.run()` 内任何未处理异常 = **abort 整个进程**(退出码 127、无 traceback、stdout 缓冲丢失,极难诊断)→ QThread.run() 必须顶层 try/except 全捕获 + 日志
- 【P1-04 教训】`ctypes.byref(x)` 返回 CArgObject:真实 CDLL 调用正常,传给测试替身(普通可调用对象)会 TypeError —— 替身端 `getattr(arg, "_obj", arg)` 还原原对象
- 【P1-04 教训】Windows 上 `os.pipe()` 的 fd 不能可靠用于 select()10093/10038)——跨平台可 select 假 fd 用 `socket.socketpair()`;且 `a.send()` 的数据在 b 的接收缓冲(方向别写反)
- 【P1-04 发现】`file://` URI 解析用剥前缀+unquote 而非 urlparse().path`file://D%3A%5Cx`(无第三斜杠)会被当 netlocgdbus portal 的 FilePicked/Finished 信号都发在 request 对象上
- 【P2-01 教训】Qt:对刚展开、布局尚未 flush 的 QPlainTextEdit 立即设水平滚动值,随后的挂起 resize flush 会把滚动清零——真实用户无法在未渲染框上滚动,属测试时序伪影;测试设滚动前必须先 settle(N1×N2 探针矩阵证实 N2≥1 即稳定)
- 【P2-01 教训】offscreen harness 收尾用 `os._exit``sys.exit` 后 QtWebEngine 渲染/GPU 子进程可能不回收 → 解释器挂起至 timeout;管道执行时只看输出会误判通过(必须验 EXIT 码)
- 【P2-02 教训】offscreen 下 QPlainTextEdit 的 `grab()` 文档区不填充(黑图)但 `panel.grab()` 正常;像素断言一律走 `widget.render(painter)`(渲染到透明 QPixmap),且先做健全性检查(文本色/handle 色像素计数>0)防黑图假通过
- 【P2-02 教训】PyQt6`Qt.Vertical``Qt.Orientation.Vertical``QStyleOptionSlider()` 无参构造(不接受 widget);`subControlRect(cc, opt, sc, widget)` 参数序 + 滚动条箭头子控件枚举名是 `SC_ScrollBarSubLine/AddLine``CC_ScrollBar` 属于 `QStyle.ComplexControl`
- 【P2-02 发现】裸控件(无样式表祖先)`style()` 是基础风格,空 option 下 subControlRect 返回 0 矩形——「原生参照」只能靠 sizeHint/实际几何对照(原生横条 14px vs 面板 8px
- 【P2-03 发现】offscreen/无真实事件循环时 `processEvents()` **不处理 DeferredDelete**`deleteLater()` 后必须显式 `QCoreApplication.sendPostedEvents(None, QEvent.Type.DeferredDelete)` 才会真正删除(offscreen 测试断言"已删除"前必须冲刷;生产事件循环常驻不受影响)
- 【P2-03 教训】PyQt6 `setGeometry``(QPoint, QSize)` 重载→构造 `QRect(tl,size)``QTest.mouseClick(widget, button, modifier, pos)` 第 3 参是 **modifier**`QTest` 在独立模块 `PyQt6.QtTest`
- 【P2-03 发现】`core/webview2.py` `get_environment()``taskkill /F /IM msedgewebview2.exe` + 共享默认 profile 不可重定向 → 无人值守自动化不得走真实 WebView2 启动路径;真机验收走人工清单(拥有者顶层 Tool 窗 z 序上必盖 WebView2 原生子 HWND,机制与生产已验证的 AttachmentPreviewOverlay 同构)
- 【P2-03 结构判据】顶层窗可带 owner parent`setWindowFlags(Tool|Frameless)``parentWidget()` 仍可非 None;判据是 `isWindow()` / `window() is self`,不是 `parentWidget() is None`
- 本机无系统级 Python 3.10;已用 uv 安装 CPython 3.10.21(用户目录托管)并重建项目内 `.venv`Python 3.10.21),与文档基线对齐
- WSL 存在 Ubuntu-22.04(当前 Stoppedpython3.12.3,未装 PyQt6);未检测到 X11/Wayland 桌面会话
- `tests/diag_live_agent.py:19``tests/tune_model_popup.py:155` 直接引用真实配置路径;属 live/tune 脚本,默认聚合排除,不属 P0-01 允许范围
- `readme.md` 提及的 `haocode.spec`/`pyi_rth_trace.py` 不在本快照内(打包属后续阶段,不影响源码运行)
环境探测(只读):
- OSWindows 11 10.0.26200 x64
- Python:默认 3.13 / 3.12.10,无 3.10`.venv` = **3.10.21**uv 重建,P0-01+ PyQt6 6.10.2 + PyQt6-WebEngine 6.10.0 + openai 2.26.0 + pythonnet 3.1.0 + PyMuPDF 1.28.0
- WebView2 Runtime153.0.4234.32 存在
- WSLUbuntu-22.04Stopped)、docker-desktopRunning
任务状态表:
- P0-01: COMPLETE
- P0-02: COMPLETE
- P0-03: COMPLETE2026-09-16 复核通过,文档一致性修订已固化)
- P1-01: COMPLETE
- P1-02: COMPLETEWindows 侧自动化全绿;Linux 进程组用例 C3 待 Linux 环境运行生效)
- P1-03: COMPLETEWindows 侧自动化 + offscreen 真实启动链全绿;Linux 真机与 root/容器 `--no-sandbox` 接受路径待对应环境验证)
- P1-04: COMPLETEWindows 侧自动化全绿:路由矩阵/X11 替身/portal 替身/offscreen 真实启动链;Linux X11 XGrabKey 真实注册与 Wayland portal 授权/取消/无 portal 三态待真实 Linux 宿主手动验证,见 evidence/P1-04.md
- P2-01: COMPLETE(两栏启动倒序 + 状态保持,offscreen 全量覆盖,无平台相关项;见 evidence/P2-01.md
- P2-02: COMPLETEoffscreen 全量覆盖 + 无泄漏断言;Windows/Linux 真机截图待对应环境运行 diag_panel_scrollbar.py;见 evidence/P2-02.md
- P2-03: COMPLETEoffscreen 结构+行为全量覆盖 34/34;审计确认唯一受影响遮罩;Windows 真机 WebView2 人工验收清单见 evidence/P2-03.md
- P2-04: COMPLETE(聚合入口 tests/run_all.pyWindows 25/25 PASSWSL/3.12 FAIL 0 + 21 有理由 SKIP;夹具演示非零退出码;独立/聚合输出一致;暴露并修复 T9 陈旧断言与 compaction.py 3.11+ dataclass 缺陷;见 evidence/P2-04.md