GPT Review Round 2 — Điều 30 v1.1: Luật Bảo vệ Hồi quy
GPT Review Round 2 — Điều 30 v1.1: Luật Bảo vệ Hồi quy
Ngày: 2026-03-22 Vai trò: Hội đồng Kiến trúc — phản biện vòng 2 Tài liệu đã đọc qua Agent Data:
knowledge/dev/architecture/regression-protection-law.md(v1.1)knowledge/dev/ssot/operating-rules.md(v4.58)knowledge/dev/architecture/dieu30-review-request.md
Đánh giá v1.1: ĐỦ BAN HÀNH
v1.1 đã sửa đúng gần như toàn bộ các lỗ hổng kiến trúc của v1.0. Đây đã là bản đủ chắc để ban hành và chạy pilot. Không nên kéo dài thêm nhiều vòng review. Từ điểm này trở đi, giá trị lớn nhất đến từ pilot thật trên 3 trang Tier A và điều chỉnh từ dữ liệu chạy thật.
Trả lời 7 câu hỏi
1. Contract storage: mix A + B
Chọn: B là SSOT + A là mirror/read model, không chọn C.
Lý do:
- Regression Contract là một phần của code/test boundary, nên SSOT tốt nhất là file versioned trong repo (
tests/contracts/*.json). Review qua PR, diff rõ, branch đi cùng code, rollback dễ, CI đọc trực tiếp. - Nhưng hệ thống Incomex cũng cần quản trị/hiển thị contract như entity kiến trúc. Vì vậy nên có Directus mirror (
regression_contracts) để tra cứu, dashboard, phân loại Tier/R-class/owner, nhưng không phải nơi edit chính. - Không chọn inline trong test file làm đường chính vì sẽ làm contract bị phân mảnh, khó tái sử dụng cho smoke, khó kiểm kê coverage.
Phán quyết cụ thể:
- SSOT: JSON/YAML files trong repo
- Mirror: Directus collection sync một chiều từ repo → Directus
- Không cho edit tay trên Directus ở phase đầu
2. Fixture vs staging: pilot dùng fixture, chưa cần staging riêng
Chọn: Fixture cho pilot + staging là phase sau, không đợi staging mới làm.
Lý do:
- Mục tiêu của Điều 30 hiện tại là bắt regression UI semantic như mất dòng, mất cột, mất link, mất content. Bài toán này fixture mode xử lý rất tốt nếu fixtures được cố định và đủ giàu.
- Staging Directus riêng phản ánh thật hơn, nhưng kéo thêm hạ tầng, sync dữ liệu, auth, seed, drift. Với Assembly First và nhu cầu triển khai nhanh, dựng staging ngay bây giờ là nặng tay.
- Pilot 3 trang Tier A chưa cần hạ tầng mới để chứng minh giá trị của luật.
Điều kiện để fixture mode đủ tin cậy:
- fixtures phải mô phỏng đúng các invariant critical từng trang
- có ít nhất 1 fixture “happy path” và 1 fixture “regression bait” cho các cột/hàng/link critical
- smoke production vẫn chạy sau deploy để bù khoảng trống “data thật”
Khi nào mới cần staging:
- khi bắt đầu có auth phức tạp, permissions, joins động, hoặc regression phụ thuộc data shape thật mà fixture không mô phỏng nổi
- hoặc khi số trang Tier A vượt ngưỡng và bug bắt đầu lọt do fixture drift
3. Regression class 5 vs 3: giữ 5 cấp trong luật, map về 3 mức thi hành
Chọn: Giữ 5 cấp, nhưng execution chỉ cần 3 outcome.
Lý do:
- 5 cấp không hề quá chi tiết ở tầng luật; nó giúp phân biệt đúng bản chất mất dữ liệu, mất điều hướng, sai số liệu, hỏng layout, cosmetic.
- Nhưng ở tầng CI/ops, chỉ cần 3 outcome để đơn giản hóa vận hành:
- Block: R1-R3
- Warning: R4
- Info: R5
Như vậy vừa giữ được ngôn ngữ phân tích tốt, vừa không làm CI/report rối.
4. data-testid: làm ngay cho Tier A, không đợi TD toàn hệ
Chọn: Làm ngay nhưng có chọn lọc.
Lý do:
- Nếu không có selector contract sớm, Playwright sẽ phải bám text/CSS mong manh; pilot sẽ nhanh xanh rồi nhanh vỡ.
- Không cần retrofit toàn hệ ngay. Chỉ cần bắt buộc cho:
- 3 trang Tier A pilot
- mọi element critical mới sinh ra từ nay
Quy tắc đề xuất:
- Tier A: bắt buộc
data-testidcho row/column/link/CTA critical ngay trong pilot - Tier B/C: cho phép dùng semantic selectors trước, bổ sung dần sau
- Mọi component shared mới chạm critical UI: phải có selector contract ngay
5. Waiver TTL: 72h hợp lý hơn 48h
Chọn: 72h.
Lý do:
- 48h hơi gắt với team rất nhỏ + AI agents + khả năng cuối tuần/lệch múi giờ.
- 1 tuần thì quá dễ biến waiver thành “để đó rồi quên”.
- 72h giữ đủ áp lực để sửa thật, nhưng thực tế hơn cho vận hành hiện tại.
Khuyến nghị:
- default waiver TTL = 72h
- quá TTL mà chưa fix → tự động nâng severity/tạo incident/backlog blocking
- mỗi PR chỉ được tối đa 1 waiver active cùng lúc
6. Tiêu chí hạ Mũ 3: không dùng % coverage chung, dùng 4 điều kiện đồng thời
Chọn: Risk-based gate with measurable criteria, không dùng duy nhất “>90% coverage”.
Mũ 3 chỉ được hạ từ bắt buộc → optional/canary khi đồng thời đạt 4 điều kiện:
- Tier A contracts coverage = 100% cho trang nằm trong phạm vi thay đổi
- 0 regression lọt qua production trong 3 chu kỳ release liên tiếp đối với nhóm trang đó
- Flake rate suite < 2% trong 14 ngày gần nhất
- Critical selectors ổn định: 100% element critical có
data-testidhoặc selector contract tương đương
Nếu thiếu 1 điều kiện → Mũ 3 vẫn bắt buộc cho các thay đổi risk cao.
Tức là Mũ 3 không hạ theo cảm giác, cũng không hạ chỉ vì “test nhiều rồi”.
7. Sẵn sàng Pilot? Còn gì cần sửa?
Phán quyết: Sẵn sàng Pilot.
v1.1 đã đủ để triển khai pilot cho 3 trang Tier A: Registries, Species Matrix, Health.
Chỉ còn 3 chỉnh sửa nhỏ nên chèn trước khi ban hành/pilot:
- Chốt contract storage model rõ trong luật: repo SSOT, Directus mirror
- Chốt execution mapping của regression class: R1-R3 block, R4 warning, R5 info
- Chốt tiêu chí hạ Mũ 3 theo 4 điều kiện trên, thay vì wording mở
Ngoài 3 điểm đó, không còn gì đủ lớn để trì hoãn pilot.
Đề xuất thêm
1. Thêm field contract_version + owner
Mỗi regression contract nên có:
contract_versionownerlast_verified_at
Để biết ai chịu trách nhiệm khi contract stale.
2. Thêm chỉ số contract coverage
Pilot report nên luôn có:
- số trang Tier A có contract / tổng số trang Tier A
- số invariant có test / tổng invariant
Không có chỉ số này sẽ khó biết đang phủ đến đâu.
3. Thêm quy tắc bug-first test
Nếu regression đã xảy ra thật như S160, bắt buộc:
- viết test tái hiện bug đỏ trước
- rồi mới fix
- rồi mới đóng issue
4. Thêm quarantine cap
Flaky quarantine list nên có trần, ví dụ:
- tối đa 5 test hoặc 10% suite
- vượt trần = incident quy trình kiểm thử
Tránh biến quarantine thành bãi rác.
Kết luận cuối
Điều 30 v1.1 đã đủ để ban hành và chạy pilot.
Không nên tối ưu quá mức trên giấy thêm nữa. Hãy chốt bản này, pilot trên 3 trang Tier A, lấy dữ liệu thực chiến rồi ra v1.2 nếu cần.