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.
This commit is contained in:
2026-09-17 16:40:06 +08:00
parent 75b2ec4123
commit bc0b92bcdc
25 changed files with 2347 additions and 0 deletions
+45
View File
@@ -0,0 +1,45 @@
# P0-01 配置路径与测试隔离 — 执行证据
日期:2026-09-16(无人值守轮次)
平台:Windows 11 10.0.26200 x64 · Python 3.10.21`.venv`)· PyQt6/Qt 6.10.0/6.10.2 · 离屏 `QT_QPA_PLATFORM=offscreen`
## 根因(源码确认)
1. `core/llm_engine.py` 模块常量 `CONFIG_PATH` + `_load_config()` 不读 `HAOCODE_CONFIG_FILE` → 三个 Qt workerAgent/Chat/Title)直接读项目内真实配置。
2. `ui/views/main_window.py:3133`webview_backend 分支)与 `:5244``init_model_popup`)直接 `open(data/config.json)`,绕过环境变量。
3. `ui/views/bash_panel.py` 有私有的环境变量解析(双入口,非统一)。
4. `core/db_manager._DEFAULT_DB` 为模块级全局,测试在 import 前重定向的既有模式成立,沿用。
## 修复摘要
- 新增 `core/config_paths.py``config_path()``HAOCODE_CONFIG_FILE` 优先、调用时解析)+ `load_config()`(缺失/损坏/非对象 → 可见警告 + 安全空 dict,不抛异常)。
- `core/llm_engine.py`:删除 `CONFIG_PATH` 常量;`_load_config()` 委托 `load_config()`(保留函数名兼容既有调用方)。
- `ui/views/main_window.py`:两处直接 open 改走 `core.config_paths.load_config`
- `ui/views/bash_panel.py``_cfg_path()` 委托统一 `config_path()`,删除私有 `_CFG_PATH` 常量。
- 新增 `tests/_test_env.py``isolate(tag, config)` 统一创建临时配置 + 临时数据库并在 import MainWindow 前完成重定向。
- 改造 3 个在范围测试使用统一临时环境:`tests/smoke_bash_panel.py``tests/test_error_persist.py``tests/test_agent_core.py`(provider 用例改读临时配置中的 `testprov`,不再依赖真实配置)。
- 新增 `tests/test_config_isolation.py`open/sqlite 拦截器 + 缺失/损坏/非对象回归 + AST 静态扫描。
## 定向测试(命令 / 退出码 / 结果)
| 命令 | 退出码 | 结果 |
|---|---|---|
| `python tests/test_config_isolation.py` | 0 | ALL PASS14 项断言) |
| `python tests/test_error_persist.py` | 0 | 39 PASS(与交接基线 39 一致) |
| `python tests/smoke_bash_panel.py` | 0 | 116 PASS(与交接基线 116 一致) |
| `python tests/run_tests.py`test_agent_core.py 的仓库标准运行方式,pytest 由 harness stub | 0 | 41 passed, 0 failed(与交接基线 41 一致) |
注:`python tests/test_agent_core.py` 直接运行在本仓库不可用(文件无独立 runner 且 .venv 不装 pytest,见 requirements.txt 说明),按其设计经 `tests/run_tests.py` 运行;P2-04 聚合入口将统一固化该运行方式。
## 完成证据对应
- **拦截器证明**MainWindow 构造 + `save_panel_width` 写回全程,所有 `config.json`(含原子写 `.tmp`)打开路径均位于 `tempfile.gettempdir()/haocode_test_cfgiso_<pid>/`;真实配置路径(仅以字符串比较)从未出现在打开记录中。未读取、未散列真实配置。
- **临时配置读写**`llm_engine._load_config()` 读到 `testprov``save_panel_width(340)``load_panel_width() == 340`,写路径落临时目录。
- **数据库隔离**sqlite3.connect 拦截记录中临时库之外零连接/写入。
- **缺失/损坏/非对象**:三个回归用例均返回 `{}` 且 stdout 含明确警告(`[config] 配置文件缺失/读取/解析失败/不是 JSON 对象`),进程正常退出。
- **静态扫描**`core/``ui/``tools/``main.py` 中除 `core/config_paths.py` 外不存在 `config.json` 字符串字面量(AST 级,docstring/注释排除)。
## 观察项(未扩范围,留待后续)
- `tests/smoke_offscreen.py``smoke_mode.py``smoke_copy_session.py` 只重定向了数据库、未设置 `HAOCODE_CONFIG_FILE`(不在 P0-01 允许修改清单内)。本轮运行这些套件时在启动环境显式导出临时配置;P2-04 聚合入口将按子进程强制注入临时环境,彻底闭环。
- `tests/diag_live_agent.py:19``tests/tune_model_popup.py:155` 直接引用真实配置路径;二者属 live/tune 人工脚本,默认聚合排除。