# WAVE-8 — Authz Contract: ✅ BIÊN BẢN QUYẾT ĐỊNH O-A (GỠ KHỎI DRY-RUN)

> 🔴 **KHÔNG PHẢI WAVE THI CÔNG.** Anh chốt @S160 (AskUser): **O-A — để mở, không siết.** File này giữ lại làm biên bản + disclose rủi ro, KHÔNG có code.

## Quyết định

Review ensemble (`review-synthesis-clone-s160.md` F-O1/F-O2/F-S1) bắt: plan bản đầu đặt **O-B (siết per-action)** làm default tự chạy — **lấn quyền owner**. Vì:
- `SC:49` (O-3, ratified): *"Lỗ hổng an ninh `ContractWorkflowService.cs:48-66` + controller HĐ class-trần: NGOÀI SCOPE, treo có chủ đích. Wave nào chạm module Contract phải hỏi lại anh."*
- `docs/STATUS.md:13` (S159, 1 ngày trước): anh **tái khẳng định** ❹ *"đang phát triển → cho hiển thị hết để mọi người góp ý"*.
- `run.md:17` ④ (chính lời lead): *"riêng LỖ HỔNG authz S156 … KHÔNG tự coi là được sửa hay được bỏ qua"*.

⇒ Lead surface câu hỏi cho anh. **Anh chọn O-A: để mở, không siết** (đúng tinh thần "hiển thị hết để góp ý").

## Hệ quả

- **KHÔNG** gắn per-action policy lên `ContractsController` (giữ `[Authorize]` trần).
- **KHÔNG** vá nhánh Reject-trước-guard (O-C bị bỏ — anh không chọn).
- **KHÔNG** seeder-grant gì cho Contract (không cần — class-trần = mọi user auth ghi được).
- W8 **không tiêu 1 dòng code**; dry-run chạy W1+W2+W3+W6+W5+W7.

## 🔴 Rủi ro CHẤP NHẬN CÓ Ý THỨC (disclose — anh nhận, KHÔNG phải lỗ chưa biết; = plan-cha §4.7)

Trong dry-run, **mọi user đăng nhập**:
1. TraLai/TuChoi **bất kỳ HĐ ở bất kỳ phase** (kể cả DaPhatHanh) — `ContractWorkflowService.cs:49-66` Reject chạy trước mọi guard.
2. Upload/xóa/tải **attachment** (kể cả scan đã ký/đóng dấu) của HĐ bất kỳ — `ContractAttachmentFeatures.cs:56-152` 3 handler **0 IDOR + 0 phase-guard** (review F-S2).
3. Create HĐ **ăn sequence mã thật** nếu chọn dự án thật — `ContractFeatures.cs:113-118`.

**Khoanh bằng:** CHỈ chạy trên dự án **ZZTEST** + **backup DB** trước mỗi đợt (`scripts/backup-sql.ps1`) + dặn team. Prod hiện **0 HĐ thật** nên bề mặt tấn công lên data thật = rỗng cho tới khi có người nhập HĐ thật ngoài dry-run.

## Bật lại sau này (nếu anh đổi ý)

O-B (siết per-action) = ~1 file controller + grant **UPGRADE-pattern** (không insert — xem plan §5 #12). O-C thêm vá Reject `:49` = +1 điều kiện `fromPhase==ChoDuyet` trong service. Cả hai vẫn cần anh gật vì chạm module Contract (O-3).

<!-- END W8 = biên bản O-A · 0 code · rủi ro disclose · reversible -->
