# REVIEW SYNTHESIS — /fable-clone reviewer 6 lane (S160, verdict hội tụ SUA-TRUOC-THI-CONG)

> Engine: `/fable-clone reviewer` ensemble tier-opus, run `wf_0eb994aa-a63`. 6 lane: anchor-A (rỗng — fail StructuredOutput, sub-file đĩa còn) · anchor-B · anchor-C · wave-logic · owner-consistency · security.
> **5/5 lane trả verdict = SUA-TRUOC-THI-CONG.** Anchor spec ĐỨNG vững (24-28/28 đúng dòng, 0 anchor-trôi sau arc-2) — lỗi nằm ở **mô-tả tại neo + acceptance + default lấn quyền + hố chưa khai**, KHÔNG ở số dòng.
> Lead verify độc lập 5 claim load-bearing @S160 (dưới) — **5/5 CONFIRMED trên đĩa**. Đây là review THẬT có răng.

## Lead verify độc lập (chống rubber-stamp ngược — 5/5 confirmed)

| Claim | Lane | Verify đĩa | Verdict |
|---|---|---|---|
| Seeder-grant no-op: row `Contracts`/`KeHoachKyKet`/`Khkk_*` seed CanRead-only + nhánh non-Pe skip-existing `continue` | S1·O3·O4·04 | `DbInitializer.cs:2204-2213` (read-only concat) + `:2242-2245` (`continue`) + khuôn UPGRADE `:2367-2374` | ✅ THẬT |
| Seed workflow type=3 = **1 trạm** (binh.le CCM), không phải 3 | 02 | `DbInitializer.cs:239-265` "1 Bước Phòng CCM × 1 Cấp" | ✅ THẬT |
| `GetEligiblePhases` KHÔNG có `DaPhatHanh(9)`/`ChoDuyet(10)` | C2·01 | `ContractFeatures.cs:334-350` (dừng ở DangDongDau) | ✅ THẬT |
| `GET /api/contracts` KHÔNG có param `type` | C1·05 | `ContractsController.cs:16-24` (7 param, 0 `type`) | ✅ THẬT |
| `LogWorkflowTransitionAsync` = hàm Contract có FK vật lý ⇒ truyền plan.Id = FK-547 | B2 | `IChangelogService.cs:28` signature contractId-typed | ✅ THẬT (plausible→confirmed sig) |

## DISPOSITION per finding (nhóm theo hành động)

### 🔴 NHÓM 1 — CHECKPOINT OWNER (không tự quyết, surface cho anh)

| # | Finding | Vì sao chờ anh |
|---|---|---|
| **O1·O2** | W8 authz O-B đặt làm DEFAULT tự chạy | O-3 `SC:49` nêu ĐÍCH DANH 2 vật (`ContractWorkflowService.cs:48-66` + controller class-trần) = "NGOÀI SCOPE, treo chủ đích, wave chạm phải hỏi anh"; `STATUS.md:13` anh **tái khẳng định** ❹ 1 ngày trước; `run.md:17`④ chính lời tôi "KHÔNG tự coi được sửa". ⇒ **FIX = demote W8 về fully owner-gated, default O-A do-nothing**; câu hỏi posture surface cho anh. Reviewer KHÔNG có thẩm quyền mở lại (O2). |
| **B7 (6 tên ratified)** | 6 tên test W3 từ `SC:377-382` ratified lệch khuôn repo (English-predicate, census 0/460) | Đổi tên = sửa spec ĐÃ ratified ⇒ heads-up cho anh (12 tên W5/W6/W7 tôi tự sửa được vì mới). |

### 🟠 NHÓM 2 — FIX correctness (safe direction, lead tự sửa spec)

| # | Finding | Fix |
|---|---|---|
| **S1·O3·O4·04** | Grant no-op ⇒ 403 giết dry-run (W1 KeHoachKyKet + W8 Contracts) | Đổi MỌI grant site sang khuôn **UPGRADE-if-exists** (`SeedProcurementMasterAccessAsync:2367-2374`), chạy SAU revoke; acceptance đo **CanCreate/CanUpdate CỜ**, KHÔNG đếm row. |
| **B3** | W3 "PORT không kích hoạt" = containment GIẢ (Designer type=10 render checkbox admin-opt-in ⇒ 1 tick bật đường "PHÁ VỠ") | W3 **KHÔNG port** 2 nhánh kết-thúc-sớm; W1 Designer type=10 **ẩn/tắt** 2 checkbox `AllowApproverFinalize`/`SkipToFinal` (hoặc khai rõ + gate owner). |
| **B2** | Changelog: dùng hàm Contract FK-vật-lý = FK-547 runtime | W3 ghi vào **`ContractSigningPlanChangelogs`** (bảng W1 #6) qua method KHKK-riêng, KHÔNG `LogWorkflowTransitionAsync` của Contract. |
| **B1** | choke-point "DUY NHẤT" sai — admin-override gán qua biến (lớp #81) | W3 kê **2 write-path** finalize + test admin-override. |
| **C1·05** | `GET /contracts` 0 param `type` ⇒ 7 leaf Hdc trùng list | W7: thêm `type` vào `ListContractsQuery` (BE nhỏ) — KHÔNG lọc client-side trần-100. |
| **C2·01** | eligiblePhases 0 phase-9 ⇒ HRA/BOD/CCM thấy rỗng + 403 | W6 mở view phase-9 cho actor bản-cứng (đúng cách: membership-workflow-của-HĐ, KHÔNG role-blanket); W7 phụ thuộc W6-view (thêm cạnh đồ thị). +LIST test + ca ÂM pin ROLE. |
| **C3·03** | grant-list thiếu `HrAdmin` + `AuthorizedSigner` (b.19/b.20 signer) | Thêm 2 vai vào grant W1+W8. |
| **02** | Seed workflow HĐ 1 trạm, E2E hứa 3 trạm | Plan §4: thêm bước **dựng workflow type=3 3-trạm qua Designer** (data setup), KHÔNG dựa seed. |
| **S2** | Attachment 3 handler 0 IDOR/0 phase-guard; O-B `DELETE attachments`→`Contracts.Delete`⇒ Drafter xóa scan HĐ người khác | W8: thêm mục attachment authz (IDOR + phase-guard) vào scope; plan §4 khai hố. |
| **B5** | `ConflictException` định vị sai ⇒ "204 KHÔNG 409" PASS SẴN 0-bit | W5 acceptance chạy tới **lượt duyệt Cấp-1** (`currentApprovalLevelOrder=1`), không dừng ở trình. |
| **B6** | Pin `ApprovalWorkflowId` thiếu guard `ApplicableType==Contract` (forge) | W5: +ca ÂM forge workflow type 1/2/10. |
| **B4** | mô-tả khuôn `PEWS:1008` sai (khuôn đúng = `ContractFeatures.cs:356-360` LUẬT+grep) | W3 sửa trỏ khuôn. |
| **B8·13/13 tên mới** | "baseline" vô định + tên test lệch khuôn repo (English-predicate) | Định nghĩa baseline = "số-đo-ngay-trước-wave"; đổi 12 tên mới sang khuôn repo. |
| **C5** | `AuthorizePolicyRegressionTests` hardcode 4 action `ApprovalWorkflowsV2Controller` ⇒ 0-bit cho Contracts | W8 test mới phải tự phủ ContractsController, không dựa test cũ. |
| **B13·S4** | W6 vá inbox bỏ nhánh admin; ca ÂM view không pin role | thêm nhánh admin + pin role ca ÂM. |
| **06·F-B10..16·C6·F-07·F-09** | LOW: b.14-16 default, anchor lệch-biên, badge proxy `ScannedSigned`, cover FO-002.01 thiếu purpose | gom sửa lúc thi công wave tương ứng. |

## Điểm DƯƠNG (reviewer tự xác nhận — chống rubber-stamp)

- Gate 5-anchor W3/W5/W6 = **15/15 đúng** · `ApprovalWorkflow.cs:95+:116-125` đúng class-trong-file + 4 cờ · 3 claim chẩn W6 đo đúng · `CreateContractFromEvaluationMultiWinnerTests` có thật · `ResolveV2InboxIdsAsync` có thật `:817` · `w3:30` giữ đúng `AND PlanId=@id` · baseline plan §3 6/6 khớp (kể cả prod curl Contracts=0) · 28 neo 0 anchor-trôi.

## ✅ OWNER-DECISION @S160 (AskUser) + FIX ĐÃ ÁP

- **W8 authz = O-A (để mở, không siết).** W8 GỠ khỏi dry-run → `spec-wave-w8` rewrite thành biên bản O-A + disclose 3 rủi ro (Reject-guard · attachment-IDOR · Create-seq) khoanh ZZTEST+backup. Hệ quả: grant-list HrAdmin/AuthorizedSigner (F-C3) + AuthorizePolicyRegression-Contracts (F-C5) + O-B seeder (F-S1 phần Contracts) đều **MOOT** — không siết thì không cần grant Contract.
- **Tên test = khuôn repo** (anh chốt đổi). Đã đổi 6 W3 + 5 W5 + 5 W6 + 3 W7 + 2 W2 sang English-predicate.

**FIX NHÓM-2 đã áp (13 spec-edit):** plan §2/§4/§5/§7 (W8→O-A · dựng workflow 3-trạm F-02 · grant upgrade #12 · disclose §4.7 · baseline+tên-test §7 · cạnh W7⊃W6) · W1 (grant UPGRADE-if-exists F-S1 + đo CỜ + ẩn 2 checkbox early-finalize type=10 F-B3 + Designer site :144-148) · W2 (tên + grant-ăn) · W3 (2-write-path finalize F-B1 + changelog KHKK-riêng chống FK-547 F-B2 + bỏ port F-B3 + khuôn-trỏ F-B4 + tên) · W5 (acceptance tới Cấp-1 F-B5 + forge-negative F-B6 + tên) · W6 (view per-HĐ 3-site F-S3/F-C2 + LIST test F-01 + role-pin ÂM F-S4 + kiểm-xóa-mềm + tên) · W7 (param `type` F-C1 + badge InitialSigned F-C6 + cover purpose F-09 + O-A authz + tên + vai-thật-verify).

## Kế tiếp
1. ✅ Owner-decision + 13 fix NHÓM-2 — XONG.
2. ⏳ `/fable-real reviewer` chốt cuối trên spec ĐÃ SỬA (verify fix landed + leftover LOW).
3. hmw Opus-5-MAX thi công từng wave theo Plan cha + kiểm.

<!-- END review-synthesis-clone-s160 · 5 lane SUA-TRUOC · 5/5 claim lead-verified · ~40 finding · 2 owner-gate + ~18 fix -->
