Files
Haocode/docs/agent-handoff/evidence/P0-02.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

57 lines
3.9 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.
# P0-02 合并重复的 `MainWindow.eventFilter` — 执行证据
日期: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`
## 根因(源码确认)
- `MainWindow` 类体内定义了两个 `eventFilter`(行 3697 与 3763):后定义者覆盖前者,前者的
`_active_streams` 守卫是死代码。
- 生效版本(3763)用 `btn_send.isEnabled()` 做守卫,而 `set_send_button_state` 只切换
图标、从不禁用按钮 → 守卫恒真 → 流式生成中按 Enter 会落入 `send_message` 的中断路径
(触发停止),与注释声称的「生成时按回车无效,防止误触」相反。
## 修复摘要(仅 `ui/views/main_window.py` 事件过滤逻辑)
- 删除行 3763 的重复 `eventFilter`(及其后不可达的两行过期分节注释)。
- 保留行 3697 处为 `MainWindow` 唯一 `eventFilter`Enter(无 Shift)→ `send_message(from_enter=True)`
并消费事件(一次按键至多一次调用);Shift+Enter → 返回 False 放行换行;其他对象/事件交父类。
- `send_message(self, from_enter: bool = False)`:函数顶部为发送规则单一实现:
1) `btn_send` 禁用 → 一律不发送;
2) `from_enter=True` 且当前会话在 `_active_streams` → 直接返回(Enter 不参与停止/中断语义);
3) 按钮点击路径行为完全不变(流式中点击 = 原有红色停止按钮中断语义,含 Fix B/C)。
- `_update_send_button_state` 未改(其语义与规则一致)。
## 定向测试(命令 / 退出码 / 结果)
| 命令 | 退出码 | 结果 |
|---|---|---|
| `python tests/test_main_window_event_filter.py` | 0 | ALL PASS18 项断言) |
| `python tests/smoke_offscreen.py` | 0 | ALL PASS: 8/8 |
| `python tests/smoke_mode.py` | 0 | ALL PASS |
| 回归 `python tests/test_config_isolation.py` | 0 | ALL PASS14 项) |
| 回归 `python tests/test_error_persist.py` | 0 | 39 PASS |
| 回归 `python tests/smoke_bash_panel.py` | 0 | 116 PASS |
注:`smoke_offscreen.py` / `smoke_mode.py` 自身只重定向数据库、未设置 `HAOCODE_CONFIG_FILE`
(不在 P0-02 允许修改清单内)。本轮运行时在进程环境显式导出指向临时配置的
`HAOCODE_CONFIG_FILE`;P2-04 聚合入口将按子进程强制注入临时环境,彻底闭环。
## 完成证据对应(test_main_window_event_filter.py
- **AST 静态断言**:解析 `ui/views/main_window.py``MainWindow` 类体内 `eventFilter` 定义恰好 1 个(行 3697);
- **Enter 可发送**A1–A5):空闲 + 按钮可用 + 有文本 → 一次 Enter 恰好一次 `send_message(from_enter=True)`
调用(计数 wrapper 包住真实实现),流同步注册、输入框清空、错误路径自清理;
- **Enter 被禁用**B1B3):`btn_send.setEnabled(False)` → 至多一次调用且无流、输入内容保留(规则在 `send_message` 内生效);
- **流式时 Enter 被拦截**C1C3):注入假流 → Enter 后假流对象未被替换、字段未被改动(未触发中断)、输入保留;
- **Shift+Enter 换行**D1–D3):零调用,事件放行到输入框(光标处插入 `\n`)、无流;
- **其他键/事件交父类**(E1–E2):按 `a` 正常插入字符、零发送调用;
- **一次按键至多一次调用**:A/B/C/D 各用例均以调用计数断言(全部 ≤1 且语义正确)。
## 行为变化说明
- 流式生成中按 Enter:旧(生效)代码会触发停止/中断;新代码 no-op(Enter 只管发送,
停止只走按钮)。这与被覆盖版本注释中声明的原始意图(「生成时按回车无效,防止误触」)
和 P0-02 硬约束(「流式生成时不得发送」)一致,属本任务预期的确定性修复。
- 发送按钮点击路径(含流式中点击 = 中断):逐行未动。