Điều 30: Luật Bảo vệ Hồi quy — v1.2 BAN HÀNH
ĐIỀU 30: LUẬT BẢO VỆ HỒI QUY — Regression Protection Law v1.2 BAN HÀNH
(Bổ sung Hiến pháp Kiến trúc — Máy kiểm tra máy)
v1.2 BAN HÀNH | 2026-03-22 | S160 | Hội đồng GPT + Gemini: 2 vòng review → ĐỒNG THUẬN BAN HÀNH. Nguyên lý: "Mọi thay đổi chạm bề mặt người dùng phải CHỨNG MINH chức năng cũ chưa bị phá hỏng. Bằng chứng hợp lệ = kiểm thử tự động trên browser thật. API/SSR validation KHÔNG được coi là bằng chứng UI pass."
I. MỤC ĐÍCH
Bảo vệ mọi tính năng ĐÃ HOẠT ĐỘNG khỏi bị phá hỏng. Phương pháp: automated tests trong CI pipeline — chặn PR phá hỏng TRƯỚC KHI merge.
MÁY KIỂM TRA MÁY. Không phụ thuộc con người nhớ, tuân thủ, hay canh.
II. TẦNG 0: REGRESSION CONTRACT — SSOT CHO KIỂM THỬ
"Không có contract → test có chạy, CI có xanh, nhưng vẫn xanh cho sai thứ."
Mỗi trang critical PHẢI khai báo invariants — những gì KHÔNG ĐƯỢC mất.
Lưu trữ (hội đồng đồng thuận): Repo file = SSOT (tests/contracts/*.json). Directus regression_contracts = mirror read-only. Cấm edit tay trên Directus.
Mỗi contract chứa:
route, tier, required_rows, required_columns, required_links,
min_rows, smoke_keywords, owner, contract_version, last_verified_at
Phân loại trang:
| Tier | Loại | Test bắt buộc |
|---|---|---|
| A | Governance/production-critical | E2E + smoke + contract |
| B | Operational | Smoke + link check |
| C | Supporting | Smoke (không 404) |
III. 4 TẦNG BẢO VỆ
Tầng 0: Regression Contract
SSOT khai báo invariants. Playwright + smoke cùng đọc.
Tầng 1: E2E Tests (Playwright) — CHẶN TRƯỚC MERGE
Playwright = chuẩn hiến định (hội đồng đồng thuận). Chạy trên preview build (CI), không production.
Quy tắc:
- Trang Tier A PHẢI có E2E test đọc từ contract
- PR thay đổi DOM/column/row/link/route/shared component → BẮT BUỘC kèm test
- PR không có test cho tính năng mới = vi hiến
- 1 test FAIL = PR BLOCK (trừ waiver)
- Bug regression: tái hiện test đỏ TRƯỚC → fix → test xanh
3 loại test:
| Loại | Kiểm tra | Ví dụ |
|---|---|---|
| Content assertions | Dòng/cột/text cốt lõi | expect(getByText('CAT-SPE')).toBeVisible() |
| Navigation assertions | Link/route hoạt động | click → expect(page).toHaveURL(...) |
| Business-state assertions | Số liệu đúng logic | expect(rows.count()).toBeGreaterThanOrEqual(15) |
Selector contract: Critical elements Tier A PHẢI có data-testid. Không bám CSS class.
Tầng 2: Content Smoke Test — SAU DEPLOY
Chạy trên production URL. Check keywords bất biến từ contract.
Tầng 3: Visual Verify — RISK-BASED
Orchestrator verify trên browser. Bắt buộc khi: trang mới, layout lớn, bug class chưa test. Dần optional khi đạt 4 điều kiện: (1) Contract coverage 100% vùng thay đổi, (2) 0 regression lọt 3 release liên tiếp, (3) Flake < 2% trong 14 ngày, (4) 100% critical elements có data-testid.
IV. PHÂN LOẠI REGRESSION — 5 CẤP, 3 MỨC THI HÀNH
| Class | Loại | Thi hành |
|---|---|---|
| R1 | Mất dữ liệu/nội dung cốt lõi | 🔴 BLOCK |
| R2 | Mất điều hướng/link/CTA | 🔴 BLOCK |
| R3 | Sai số liệu | 🔴 BLOCK |
| R4 | Hỏng layout không chặn nghiệp vụ | 🟡 WARNING |
| R5 | Cosmetic | ℹ️ INFO |
V. QUY TRÌNH 3 MŨ
MŨ 1: CODE + TEST (bắt buộc mọi PR chạm UI)
→ Code + test → CI preview build → Playwright → ALL PASS
→ Artifact: Playwright report link
MŨ 2: DEPLOY + SMOKE (bắt buộc mọi deploy)
→ Merge → deploy → smoke-test.sh (keywords từ contract)
→ Artifact: smoke report
MŨ 3: VERIFY VISUAL (risk-based)
→ Orchestrator verify browser khi cần
→ Artifact: xác nhận visual pass
No Blind PASS: CẤM khai PASS bằng API 200 / SSR chunk / page load. Phải content assertions. Rule of Evidence: Không có artifact = mặc định FAIL.
VI. FLAKY TEST POLICY
- Fail > 3 lần / 7 ngày mà không phải regression → FLAKY
- Quarantine list: chạy nhưng KHÔNG block merge. TTL 7 ngày.
- Quarantine trần: tối đa 5 tests hoặc 10% suite (thấp hơn)
- Tạo flaky = incident kỹ thuật → fix root cause
- CẤM rerun bypass
VII. WAIVER PROTOCOL
- Cần: người duyệt (Huyên) + lý do + thời hạn
- TTL: 72h (hội đồng đồng thuận)
- Quá TTL chưa fix → tự nâng thành incident blocking
- Mỗi PR tối đa 1 waiver active
- Waiver KHÔNG áp dụng Tier A
- Tạo backlog ticket bắt buộc
VIII. CÔNG CỤ
| Công cụ | Tầng | Ghi chú |
|---|---|---|
| Playwright | Tầng 1 | Chuẩn hiến định. MIT. |
| GH Actions | Tầng 1 | CI runner |
| smoke-test.sh | Tầng 2 | Nâng cấp: + keywords |
| Chrome extension | Tầng 3 | Orchestrator |
| Playwright screenshot | Phụ trợ | Visual diff chọn lọc, không bắt buộc v1.2 |
IX. QUAN HỆ
- Điều 22: Điều 30 = Khiên (phòng ngừa). Điều 22 = Thuốc (phục hồi). Không thay thế nhau.
- Điều 28: Test pattern = khuôn mẫu viết 1 lần dùng lại.
- Assembly First: Playwright = công cụ có sẵn, không tự viết framework.
X. PILOT — 3 TRANG TIER A
Triển khai ngay cho: /knowledge/registries, /knowledge/registries/species, /knowledge/registries/health
Pilot bao gồm: Contract JSON + E2E tests + data-testid Tier A + CI workflow + smoke nâng cấp.
Điều 30 v1.2 BAN HÀNH | 2 vòng hội đồng GPT + Gemini đồng thuận | Pilot 3 trang Tier A.