Soát lại plan.md thì thấy CASAN là NĂM tiêu chí C-A-S-A-N, không phải ba. Tiêu
chí A có hai vế, tôi mới đạt vế đầu:
vế 1 0 API key plaintext trong JSON -> đã đạt từ 25/08
vế 2 MỌI thao tác ghi tệp đi qua AtomicJsonFile -> CHƯA
Toàn repo còn 15 chỗ ghi JSON thẳng. Bốn trong đó là của Gamma (vùng Co4E):
core/co4e.py:236 lưu workflow ghi thẳng, không nguyên tử gì cả
core/co4e.py:310 lưu agent ghi thẳng
core/co4e_run_manager.py:156 tmp + replace tự viết
application/workflows/co4e_workflow_service.py:178 tmp + replace tự viết
Hai chỗ đầu nguy hơn: tắt máy giữa lúc lưu là mất luôn workflow hoặc agent.
Hai chỗ sau nhìn thì có vẻ ổn vì đã tmp + replace, nhưng thiếu hai thứ:
* không fsync — dữ liệu có thể còn nằm trong bộ đệm ổ đĩa khi mất điện, nên
"nguyên tử" chỉ đúng với crash tiến trình, không đúng với mất điện;
* dùng thẳng Path.replace, đúng chỗ dính PermissionError [WinError 5] mà tôi
vá hôm 25/08 — Defender giữ handle file vừa tạo. Tần suất đo được khoảng
1/140 lần lưu, nhân với số lần lưu lịch sử chạy flow.
11 chỗ còn lại thuộc team khác (accounts, admin_agents, custom_agents, flows,
groups, history, projects, skills, tasks). Không đụng vào; cần báo lên vì
tiêu chí A là tiêu chí TOÀN DỰ ÁN, Gamma sạch không cứu được cổng.
Đã kiểm application/ vẫn không kéo PySide6 vào sau khi thêm import mới
(tiêu chí C). 714 test xanh, 24/24 checker qua.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
conversation application service, AtomicJsonFile fix) vào sau khi tách 6
widget UI Co4E (N3)
Đã kiểm trước khi merge: ui/co4e_tab.py và ui/routing_toggle.py đều bị 2
bên cùng đụng, nhưng ở vùng dòng khác nhau hoàn toàn (bên kia sửa
_apply_co4e_routing/RoutingToggle cho R03-T05, N3 chỉ đụng phần dựng
sidebar/canvas/chat) — không có xung đột logic thật.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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>
Sáu việc trong "mục chung" của bản phân công, làm trước khi ba nhánh tính năng
tách ra.
1. Khung 5 tầng theo đúng đường dẫn plan.md: domain/ application/
infrastructure/ presentation/ platform/ + tests/fakes/ — 38 __init__.py.
Trước đó là 0 file, mà mọi task của cả ba người đều ghi vào đây.
Đã kiểm platform/ không che khuất module platform của stdlib.
2. Hợp đồng SecretStore và ConfigRepository (Protocol, chưa cài đặt) + fake
chạy trong bộ nhớ. Danh sách thuộc tính không bịa: đếm 156 lời gọi
ctx.config.* trong 29 file rồi lấy những cái dùng thật, xếp theo số lần.
Cố ý bỏ config.data (36 lời gọi, nhiều nhất) — bê dict thô sang kiến trúc
mới là bê nguyên vấn đề cũ.
3. tests/test_contracts.py — bài nghiệm thu, không phải test cho vui. Bài
chính chạy tiến trình riêng và khẳng định dùng fake KHÔNG kéo theo
cowork_local.config lẫn PySide6; đó là điều kiện để N2 và N3 code ngay hôm
nay thay vì đợi bản thật ngày 23 và 26/08.
4. scripts/audit_security.py — CASAN Check 1, Gamma chủ trì (hạn 30/08). Viết
sớm để kiểm liên tục trong lúc chuyển API key, không đợi tới ngày cổng.
Lần chạy đầu ra 3 báo động giả (secret_in_output là tên quy tắc, api_key="x"
là dữ liệu test) nên đã siết: ngưỡng độ dài, hằng liệt kê, hình dạng khoá
i18n, và dấu "# casan: allow" làm lối thoát chuẩn.
--self-test cắm 4 credential thật + 5 mẫu vô hại để chứng minh nó còn cắn
được — một máy quét không tìm thấy gì chỉ có giá trị nếu chứng minh được nó
biết tìm.
5. Ba check CASAN vào CI, chạy mọi PR thay vì dồn tới 30/08. Check 2 và 3
thuộc Team Hoa và Team Duy, chưa có script — bước CI bỏ qua nếu file chưa
tồn tại, để thêm cổng không làm đỏ CI của hai team kia.
6. docs/refactor/GammaTeam_decisions.md — hai quyết định chờ nhóm trưởng chốt:
provider_conf() còn trả api_key hay không (ảnh hưởng 5 nơi, 3 nằm ngoài
team), và số phận 24 checker UI sẽ vỡ khi file bị dời.
96 test xanh (90 cũ + 6 mới). CASAN Check 1: 0 credential lộ.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>