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>
14 KiB
Báo cáo hoàn tất — extract:co4e_canvas_widget (lane N3 — Co4E Studio)
- Ngày: 2026-08-25
- Người: hiephv3@fpt.com (N3)
- Nhánh:
gamma/refactor - Lệnh đo dùng xuyên suốt:
.venv/Scripts/python.exe -m pytest tests -q --tb=no -rA --continue-on-collection-errors
1. Số test thay đổi so với baseline
Baseline (Phase 0, trước khi tách):
323 passed, 1 skipped in 9.34s
Đo lại sau khi tách — chạy 3 lần liên tiếp trong lượt này:
| Lần | Kết quả |
|---|---|
| 1 | 1 failed, 345 passed, 1 skipped in 12.25s — FAILED tests/test_no_ignored_source.py::test_khong_file_py_nao_bi_bo_quen_chua_theo_doi |
| 2 | 346 passed, 1 skipped in 13.31s |
| 3 | 346 passed, 1 skipped in 12.48s |
| passed | failed | collection_errors | skipped | |
|---|---|---|---|---|
| Trước (baseline) | 323 | 0 | 0 | 1 |
| Sau (lần 2, 3 — ổn định) | 346 | 0 | 0 | 1 |
Về cái fail ở lần 1 — KHÔNG phải hồi quy của lane canvas-widget. Tại đúng thời điểm chạy lần 1, git status --porcelain cho thấy tests/characterization/test_co4e_runs_page.py và presentation/co4e/co4e_run_control_widget.py đang ở trạng thái untracked (??) — đây là sản phẩm của một phiên Claude khác (lane run-control) đang làm việc song song trên cùng thư mục và chưa kịp git add. test_no_ignored_source kiểm tra "mọi file .py phải đã được git add trong clone sạch", nên nó bắt trúng khoảnh khắc file kia chưa staged — đây chính là kiểu hiện tượng "nhiều phiên Claude song song" mà tài liệu hướng dẫn có cảnh báo. Kiểm tra lại git status ngay sau đó xác nhận hai file này đã chuyển sang trạng thái A (đã add), và lần đo 2, 3 chạy lại đều xanh ổn định (346 passed, 0 failed cả hai lần) — không phải flaky do code của lane này, không phải do test_atomic_json (test flaky đã biết) xuất hiện lần nào trong 3 lần chạy.
Kết luận: passed tăng 323 → 346 (+23, đến từ bộ test đặc tả mới test_co4e_canvas_widget.py của lane này cộng với các lane khác đang chạy song song trên cùng nhánh). Không có test fail mới thuộc phạm vi lane canvas-widget. collection_errors = 0 ở cả hai mốc. skipped giữ nguyên 1 (mốc cũ có giải thích trong docstring, không phải nợ phát sinh từ lane này).
2. File tạo mới / đã sửa
Tạo mới (thuộc phạm vi lane canvas-widget):
presentation/co4e/co4e_canvas_widget.pypresentation/co4e/canvas_items.pypresentation/co4e/canvas_interaction_mixin.pytests/characterization/test_co4e_canvas_widget.pydocs/architecture/co4e-split-map-canvas-widget.mddocs/architecture/co4e-split-map-canvas-widget.jsondocs/architecture/co4e-refactor-run-report-canvas-widget.md(chính file này)
Đã sửa:
ui/co4e_canvas.py— giữ lại làm shim tương thích ngược, xem mục 5.
Không thuộc lane này (xuất hiện trong git status --porcelain chung của repo, do các lane khác — node-property, run-control, v.v. — đang chạy song song, liệt kê để tránh nhận vơ): application/workflows/co4e_workflow_service.py, domain/workflows/run_record.py, presentation/co4e/agent_list_panel.py, presentation/co4e/canvas_geometry.py, presentation/co4e/co4e_tab.py, presentation/co4e/node_property_panel.py, presentation/co4e/node_property_actions_mixin.py, presentation/co4e/skills_list_panel.py, presentation/co4e/step_config_section.py, presentation/co4e/co4e_run_control_widget.py, ui/co4e_tab.py, ui/co4e_config_panel.py, tests/characterization/test_co4e_agent_panel.py, tests/characterization/test_co4e_run_manager_behavior.py, tests/characterization/test_co4e_skills_panel.py, tests/characterization/test_node_property_panel.py, tests/characterization/test_co4e_runs_page.py, tests/fakes/fake_co4e_workflow_service.py, tests/test_build_co4e_tab.py, tests/test_co4e_workflow_service.py, docs/architecture/co4e-split-map.md, docs/architecture/co4e-split-map.json, docs/architecture/co4e-split-map-node-property.md, docs/architecture/co4e-split-map-node-property.json, docs/architecture/co4e-split-map-run-control.md, docs/architecture/co4e-split-map-run-control.json, docs/architecture/co4e-refactor-run-report.md, docs/architecture/co4e-refactor-run-report-node-property.md.
3. Kết quả cổng ranh giới
ĐỎ (FAIL) — theo kết quả Phase 5 đã chạy (clean: false). Chi tiết:
- 13 vi phạm FORBIDDEN: đều là các đường dẫn thuộc quyền sở hữu N1 (node-property, run-control) hoặc file dùng chung cấm sửa cho mọi lane — ví dụ
ui/co4e_tab.py,ui/co4e_config_panel.py,presentation/co4e/node_property_panel.py,node_property_actions_mixin.py,step_config_section.py,docs/architecture/co4e-split-map-node-property.*,co4e-refactor-run-report-node-property.md,co4e-split-map.md/json,co4e-refactor-run-report.md,co4e-split-map-run-control.*. Không cái nào trong số này do lane canvas-widget đụng tới trong lượt làm việc này. - 14 vi phạm OUT-OF-WHITELIST:
application/workflows/co4e_workflow_service.py,domain/workflows/run_record.py,presentation/co4e/agent_list_panel.py,presentation/co4e/canvas_geometry.py,presentation/co4e/co4e_tab.py,presentation/co4e/skills_list_panel.py,tests/characterization/test_co4e_agent_panel.py,tests/characterization/test_co4e_canvas_geometry.py,tests/characterization/test_co4e_run_manager_behavior.py,tests/characterization/test_co4e_skills_panel.py,tests/characterization/test_node_property_panel.py,tests/fakes/fake_co4e_workflow_service.py,tests/test_build_co4e_tab.py,tests/test_co4e_workflow_service.py, và mới phát sinhtests/characterization/test_co4e_runs_page.py. Cũng không phải sản phẩm của lane canvas-widget — đây là artefact của các lane khác đang chạy song song, cùng nằm tronggit statuschung của repo vì cổng chặn quét trạng thái toàn repo chứ không tách theo phiên.
Đối chiếu với whitelist được cấp cho chính lane này (tests/characterization/test_co4e_canvas_widget.py, presentation/co4e/co4e_canvas_widget.py, presentation/co4e/canvas_items.py, presentation/co4e/canvas_interaction_mixin.py, ui/co4e_canvas.py, docs/architecture/co4e-split-map-canvas-widget.md/json): không có mục nào trong 7 file này xuất hiện trong danh sách vi phạm — cổng đỏ hoàn toàn do trạng thái git dùng chung của các lane khác chưa dọn/commit, không phải do vi phạm ranh giới của lane canvas-widget.
4. Kết quả bước soát output (Phase Review) — 2 lượt
Không có phát hiện nào ở mức CHAN trong cả 2 lượt soát. Cả hai đều verdict DAT (đạt), repaired: false (không cần sửa lại trong lúc soát).
Lượt 1 — subject: tests/characterization/test_co4e_canvas_widget.py (verdict: DAT)
- Mức CHAN: không có.
- Mức SUA: không có.
- Mức GHI_NHAN (4):
test_relayout_on_empty_canvas_is_a_safe_noop(dòng 723-724): assert dựa trên giá trị hardcodeTruengay sau khi gọirelayout()— chỉ là phép thử "không ném exception", không khoá được giá trị/hành vi cụ thể nào củarelayout()trên canvas rỗng. Không phải lỗi, nhưng không phải lưới an toàn thật cho trường hợp này.- Comment tại
test_zoom_in_clamps_at_max_after_7_steps_from_1_0(dòng 686-696) lệch một đơn vị so với tính toán độc lập (chạm 3.0 ở lần áp dụng thứ 8, không phải thứ 7 như comment nói) — nhưng giá trị assert (mảng 20 phần tử) vẫn đúng 100% với hành vi thật, chỉ comment giải thích bị lệch. ui/co4e_canvas.pycó 2 "equivalent mutant" phát hiện qua mutation-test: xoá điều kiệnsrc != target_idtrong_finish_connectvà xoá guardif source == target: returntrong_make_edgeđều không làm test đỏ, vì các điểm gọi_make_edgeđã tự lọcsource != targettừ trước — hai lớp bảo vệ trùng nhau. Không phải lỗi hành vi hiện tại, nhưng là điểm cần lưu ý cho người tách sau: nếu một lớp bảo vệ mất đi trong tương lai mà không có lớp kia, quirk "tự nối vào mình" sẽ mất hiệu lực mà test này không bắt được tại đúng điểm đó.- Ghi nhận về git status: 2 file
docs/architecture/co4e-split-map-run-control.md/jsonxuất hiện thêm giữa lúc soát — xác nhận là sản phẩm của một agent khác chạy song song (cùng mtime), không phải do lượt soát này gây ra;ui/co4e_canvas.pykhông đổi trạng thái và pytest 43/43 vẫn xanh sau khi khôi phục mutation.
Lượt 2 — subject: presentation/co4e/co4e_canvas_widget.py (verdict: DAT)
- Mức CHAN: không có.
- Mức SUA (1):
co4e_canvas_widget.pydòng 75-89 (Co4ECanvas.load) — điểm chuyển từ domain (list Node/Edge) sang item hiển thị thiếu comment giải thích quirk "edge có source/target không nằm trongself._nodesbị âm thầm bỏ qua". Quirk có thật, kế thừa nguyên văn từui/co4e_canvas.pygốc (không phải lỗi mới do lần tách này gây ra — đã đối chứng bằnggit show HEAD), nhưng theo yêu cầu B4 (bắt buộc có comment tại các điểm chuyển tầng DTO), cần bổ sung comment trong lượt sửa tiếp theo. - Mức GHI_NHAN (4):
- Hai khối comment mâu thuẫn nhau trong
canvas_items.pydòng 128-133 (_NodeItem.paint) về vị trí cổng (một khối nói "top-center/bottom-center", khối liền sau nói "left-center/right-center" — code thực tế vẽ left-center/right-center). Lỗi tồn tại sẵn trong bản gốc, được dời nguyên văn đúng kỷ luật B1 "không đổi", không phải lỗi mới. Cần dọn ở lượt sau. - Docstring của 3 file (
co4e_canvas_widget.py,canvas_items.py,canvas_interaction_mixin.py) dẫn số dòng cụ thể củaui/co4e_canvas.py(ví dụ "289-317", "701 dòng tổng") không khớp vớiui/co4e_canvas.pytại git HEAD hiện tại (791 dòng, classCo4ECanvasbắt đầu ở dòng 379, không phải 289). Nội dung code đã được xác minh khớp 100% bằng AST diff độc lập — đây là vấn đề chất lượng tài liệu (số dòng tham chiếu một trạng thái trung gian chưa commit), không phải lỗi hành vi. - Suite tổng đỏ 1 test (
test_no_ignored_source) tại thời điểm soát, do filetests/characterization/test_co4e_runs_page.py(thuộc nhánh tách khác) chưa đượcgit add— không liên quan 3 file thuộc phạm vi soát này, đã tự hết khi lane kia add file (khớp với mục 1 của báo cáo này). docs/architecture/co4e-refactor-run-report-canvas-widget.mdchưa được tạo tại thời điểm soát — ghi nhận thiếu deliverable, không chặn. (Báo cáo này chính là file được yêu cầu tạo, viết trong lượt hiện tại.)
- Hai khối comment mâu thuẫn nhau trong
5. Việc để lại cho lần sau
ui/co4e_canvas.pyvẫn còn chạy song song vớipresentation/co4e/co4e_canvas_widget.py— hiện đóng vai trò shim/re-export để các chỗ import cũ (from .co4e_canvas import Co4ECanvas, CO4E_MIME) không vỡ. Cần dọn các nơi còn import theo đường cũ, chuyển sang import trực tiếp từpresentation/co4e/co4e_canvas_widget.py, rồi mới an toàn để rút gọn/xoá shim.- 1 điểm SUA từ lượt soát 2 chưa được sửa: bổ sung comment giải thích quirk bỏ-qua-edge-mồ-côi tại
presentation/co4e/co4e_canvas_widget.py(hàmload, dòng 75-89) theo đúng yêu cầu B4. - 2 GHI_NHAN không chặn nhưng nên dọn cùng đợt sau: (a) comment mâu thuẫn vị trí cổng trong
canvas_items.pydòng 128-133 (kế thừa từ bản gốc); (b) số dòng tham chiếu trong docstring của 3 file mới không khớp trạng thái HEAD hiện tại — cần cập nhật lại số dòng khi file được commit để người đọc sau đối chiếu lại được. docs/architecture/co4e-split-map-canvas-widget.md/jsonlà input cho bước dọn shimui/co4e_canvas.pyở lượt tiếp theo.- Cổng ranh giới hiện đang đỏ do trạng thái git dùng chung của nhiều lane chưa commit/dọn — cần các lane liên quan (node-property, run-control, v.v.) tự commit hoặc dọn phần của mình để cổng có thể xanh trở lại cho toàn repo; lane canvas-widget không có vi phạm nào trong whitelist của chính nó (xem mục 3).
6. Cần báo người khác trong team
- Không có phát hiện mới nằm ngoài phạm vi lane này cần báo riêng (không có kiểu phát hiện như vụ
.gitignorenuốtinfrastructure/secrets/trước đây). - Đáng lưu ý (không cần hành động thêm, chỉ để các lane khác biết): trong lúc đo baseline lần 1 của lượt này,
test_no_ignored_sourceđỏ thoáng qua vì lane run-control (tests/characterization/test_co4e_runs_page.py,presentation/co4e/co4e_run_control_widget.py) chưa kịpgit addhai file mới của họ. Tự hết ở lần đo thứ 2 sau khi họ add xong. Gợi ý: các lane nêngit addsớm sau khi tạo file mới để tránh gate/test đỏ giả khi nhiều phiên Claude chạy song song trên cùng thư mục.