Lane N3 (Co4E Studio) — dùng bộ workflow refactor-god-file, mỗi bước có characterization test trước khi tách, hậu kiểm ranh giới tầng sau mỗi bước: - skills_list_panel.py / agent_list_panel.py — 2 khu vực sidebar - co4e_canvas_widget.py + canvas_items.py + canvas_interaction_mixin.py — Co4ECanvas tách 3 file (vượt 400 dòng nếu đứng một mình) - node_property_panel.py + node_property_actions_mixin.py + step_config_section.py — StepConfigPanel, cùng lý do - co4e_run_control_widget.py — RunsPagePanel (trang Flow Status) - co4e_chat_view.py — ChatPanel + _ChatInput + helper autocomplete - palette_list.py — _PaletteList dời khỏi ui/co4e_tab.py, hết import ngược presentation -> ui (agent/skills panel giờ import top-level) ui/co4e_tab.py giảm 2089 -> 1878 dòng, chỉ còn phần wiring + business logic (Co4ERunManager/AgentWorker chưa đổi — nằm ngoài phạm vi này, xem docstring presentation/co4e/co4e_tab.py). ui/co4e_canvas.py và ui/co4e_config_panel.py còn lại là compat shim re-export, không đổi API cho bên gọi. Thêm tests/test_co4e_integration.py — dựng thật Co4ETab qua build_co4e_tab(), lái luồng qua nhiều panel trong cùng instance (thêm node, mở/gập chat, chuyển trang Flow Status rồi quay lại không mất state canvas) — bắt lỗi wiring xuyên-panel mà characterization test từng panel riêng không thấy được. Đã xác minh: pytest 348 passed/1 skipped, tools/check_co4e.py sạch, không file nào >400 dòng, domain/application không import PySide6, và so pixel before/after (git worktree tại HEAD cũ) ra 0/1.125.000 pixel khác biệt. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
9.4 KiB
Báo cáo refactor — Chat view / Composer (widget cuối) — làn N3 Co4E Studio
- Ngày: 2026-08-25
- Người: Lâm (hiephv3@fpt.com)
- Nhánh:
gamma/refactor - Phạm vi: trích xuất
_ChatInput,_skill_names,_agent_names,_directive_tokenvà phần dựng UI củaChatPanel(từ_build_chatcũ) trongui/co4e_tab.pysangpresentation/co4e/co4e_chat_view.py.
1. Số test thay đổi thế nào so với baseline
Lệnh đo (chạy lại đúng lệnh baseline ngay trước khi viết báo cáo này):
.venv/Scripts/python.exe -m pytest tests -q --tb=no -rA --continue-on-collection-errors
Kết quả vừa đo:
347 passed, 1 skipped in 8.10s
So với baseline được giao (Phase 0): 346 passed, 0 failed, 0 collection_errors, 1 skipped.
| Trước (Phase 0) | Sau (vừa đo lại) | |
|---|---|---|
| passed | 346 | 347 |
| failed | 0 | 0 |
| collection_errors | 0 | 0 |
| skipped | 1 (giữ nguyên, lý do đã biết — thứ tự import CONFIG_DIR giữa các file test, không liên quan chat view) |
1 (cùng lý do) |
+1 passed đúng bằng đúng 1 test mới tests/characterization/test_co4e_chat_view.py
được thêm trong đợt này. Không có test fail mới, không có collection error mới →
không hồi quy.
- Lỗi MỐC CŨ có từ trước (nợ của làn khác): không có — 0 collection error, 0 failed ở cả trước và sau.
- Flaky đã biết (
tests/test_atomic_json.py::test_ghi_de_nhieu_lan_van_dung,PermissionError [WinError 5]khi Windows giữ khoá file tạm): không xuất hiện trong lần đo cuối cùng này (347 passed, 0 failed). Trong lượt soát trước đó nó có xuất hiện đúng 1 lần trên 2 lần chạy (1 failed, 346 passed, 1 skipped), rồi lần chạy kế tiếp lại xanh (347 passed, 1 skipped) — đúng đặc điểm flaky đã biết, không quy cho đợt trích xuất này.
2. File đã tạo, file đã sửa
Theo git status --porcelain (đối chiếu với whitelist được cấp cho lượt chat-view):
Tạo mới (thuộc lượt này):
presentation/co4e/co4e_chat_view.py— file production mới (258 dòng, ≤ 400 dòng, chỉ import PySide6.QtCore/QtWidgets, không đụng domain/application).tests/characterization/test_co4e_chat_view.py— test đặc trưng hoá hành vi cũ.docs/architecture/co4e-split-map-chat-view.mddocs/architecture/co4e-split-map-chat-view.jsondocs/architecture/co4e-refactor-run-report-chat-view.md— chính file báo cáo này (trước lượt này file chưa tồn tại — đây là khoảng thiếu mà bước soát đã ghi nhận, nay bù lại).
Sửa (thuộc lượt này):
ui/co4e_tab.py— dây lại để dùngChatPanel/_ChatInputtừ module mới thay vì định nghĩa tại chỗ.
Các mục khác trong git status (canvas widget, node property, run control, agent
panel, run manager, v.v.) không thuộc lượt chat-view — đó là dấu vết của các làn/
phiên khác đang chạy song song trên cùng thư mục làm việc (repo này có nhiều phiên
Claude chạy đồng thời). Không đụng, không sửa trong lượt này.
3. Cổng chặn (Phase 5)
Kết quả: ĐỎ ("clean": false).
Tuy nhiên toàn bộ vi phạm liệt kê không thuộc phần lượt chat-view đã viết ra — kiểm
tra riêng 5 đường dẫn thuộc whitelist của lượt này
(presentation/co4e/co4e_chat_view.py, tests/characterization/test_co4e_chat_view.py,
docs/architecture/co4e-split-map-chat-view.md, .json, ui/co4e_tab.py): không có
đường dẫn nào trong 5 file này xuất hiện trong danh sách violations.
Danh sách vi phạm thật (đỏ) đến từ file của các làn khác đang tồn tại chung trong working tree (không do lượt chat-view tạo ra):
FORBIDDEN(khớpforbidden_pathscủa N1):presentation/co4e/canvas_interaction_mixin.py,canvas_items.py,co4e_canvas_widget.py,co4e_run_control_widget.py,node_property_actions_mixin.py,node_property_panel.py,step_config_section.py,ui/co4e_canvas.py,ui/co4e_config_panel.py, cùng cácdocs/architecture/co4e-split-map*.md/jsonvàco4e-refactor-run-report*.mdkhác của N1.OUTSIDE_WHITELIST(file mới không khớpallowed_write_globscủa lượt này):application/workflows/co4e_workflow_service.py,domain/workflows/run_record.py,presentation/co4e/agent_list_panel.py,canvas_geometry.py,presentation/co4e/co4e_tab.py(khácui/co4e_tab.pyđược phép),skills_list_panel.py, và các test/fakes tương ứng (test_co4e_agent_panel.py,test_co4e_canvas_geometry.py,test_co4e_canvas_widget.py,test_co4e_run_manager_behavior.py,test_co4e_runs_page.py,test_co4e_skills_panel.py,test_node_property_panel.py,fake_co4e_workflow_service.py,test_build_co4e_tab.py,test_co4e_workflow_service.py).
Kết luận: cổng chặn báo đỏ ở mức toàn working tree, không phải đỏ do lượt
chat-view — vì cổng chặn quét nguyên git status chung, còn nhiều làn/phiên khác đang
ghi đè cùng thư mục. Phần việc riêng của lượt chat-view (5 đường dẫn whitelist) sạch.
4. Bước soát output — 2 lượt
Không có phát hiện ở mức CHAN (chặn) trong bất kỳ lượt soát nào — cả hai lượt đều
có verdict: "DAT" (đạt).
Lượt 1 — soát tests/characterization/test_co4e_chat_view.py: verdict DAT.
Một phát hiện mức SUA:
- Dòng 193:
assert ci._popup.width() == max(280, ci.width())— assertion rỗng nghĩa cho riêng claim "280" vìci.width()mặc định (chưa show/setFixedWidth) là 640 trong môi trường test, luôn thắng trongmax()bất kể 280 đổi thành gì < 640. Xác nhận bằng mutation thật (280→300 trongui/co4e_tab.py): test vẫn xanh (1 passed in 2.01s). 23 case còn lại trong file đều bắt được mutation tương ứng (11/12 hành vi bị làm hỏng → test đỏ đúng như kỳ vọng).
Lượt 2 — soát presentation/co4e/co4e_chat_view.py: verdict DAT. Hai phát hiện
mức SUA, một mức GHI_NHAN:
SUA:docs/architecture/co4e-refactor-run-report-chat-view.md(đúng file này) chưa tồn tại tại thời điểm soát — thiếu deliverable bắt buộc của quy trình. Đã bù lại bằng chính báo cáo này.SUA: docstring module (dòng 6-7, 15-18) trích sai số dòng gốc trongui/co4e_tab.py(lệch 3-35 dòng, ví dụ_build_chatghi "1030-1093" nhưng thật là "1065-1128" theogit show HEAD). Không ảnh hưởng hành vi — thân hàm đã được đối chiếu bằngast.get_source_segment+difflibvà IDENTICAL 100% với bản gốc. Đây là lỗi trích dẫn tài liệu, chưa sửa trong lượt viết báo cáo này (ngoài phạm vi được giao cho lượt này — chỉ viết báo cáo, không sửa code sản xuất).GHI_NHAN: hai filedocs/architecture/co4e-refactor-run-report-node-property.mdvàco4e-refactor-run-report-run-control.md(thuộcforbidden_pathscủa lượt chat-view) có thay đổi/tồn tại — nhưng nội dung xác nhận thuộc lane khác (node-property, run-control), không phải do lượt chat-view đụng vào. Không quy lỗi cho lượt này.
Ngoài ra, bước soát đã tự chạy lại bộ test 2 lần độc lập để loại trừ flaky trước khi kết
luận: lần 1 gặp 1 failed (đúng flaky test_atomic_json đã biết), lần 2 347 passed, 1 skipped, 0 failed — nhất quán với con số ở mục 1.
5. Việc để lại cho lần chạy sau / cần báo người khác
Để lại cho lần sau (trong phạm vi lượt chat-view, chưa làm ở lượt viết báo cáo này):
- Sửa docstring module trong
presentation/co4e/co4e_chat_view.py(dòng 6-7, 15-18) để khớp đúng số dòng thật trongui/co4e_tab.py(HEAD):_skill_names60-64,_agent_names67-70,_directive_token121-133,_ChatInput136-225,_build_chat1065-1128 — hiện ghi sai (63-73, 124-228, 1030-1093). - Làm chặt lại assertion popup-width-floor tại
tests/characterization/test_co4e_chat_view.py:193(claim "280" hiện không được khoá thật vìci.width()mặc định 640 luôn thắng trongmax()) — cần setcivề chiều rộng nhỏ hơn 280 trước khi assert, hoặc mock riêng, để test thực sự khoá hằng số 280. ui/co4e_tab.pyvẫn còn nhiều phần khác chưa tách (không thuộc phạm vi widget chat/composer) — các widget khác đã có báo cáo riêng của N1 (canvas-widget,node-property,run-control).
Cần báo người khác trong team: không có phát hiện mới nào ngoài phạm vi làn này cần escalate ở lượt này. Ghi nhận (không phải lỗi mới, chỉ là quan sát): repo đang có nhiều phiên Claude/nhiều làn chạy song song trên cùng một working tree, khiến cổng chặn của lượt chat-view báo đỏ ở mức toàn cục do file của các làn khác — điều này không phải do lượt chat-view gây ra và không cần hành động thêm từ N3, nhưng đội điều phối nên biết để không hiểu nhầm là lượt này làm vỡ ranh giới của N1.