20 KiB
20 KiB
lens1-cov — coverage + owner-gate
Đối tượng chấm: spec-4gd-khkk-tong-quat-31-07-2026.md (viết tắt spec:N)
Yêu cầu gốc: draft-yeu-cau-owner.md (viết tắt draft:N)
Lăng kính: (Q1) phủ đủ 5 mảnh scope + 2 yêu cầu bổ sung? · (Q6) OG list đủ chưa — có chốt lậu không?
Q1 — bảng mảnh → wave phủ → lỗ
| # | Mảnh (draft §3) | Wave spec | Trạng thái |
|---|---|---|---|
| (i) | Master data danh mục (draft:46) | K1 (spec:22, :36) | ⚠️ nguồn extract KHÔNG TỒN TẠI theo tên (F-1); acceptance chỉ đo SỐ DÒNG, 0 đo cột (F-14) |
| (ii) | eOffice sidebar 8 nhóm × 6 leaf (draft:48) | K4 (spec:23, :39) | ⚠️ thiếu deliverable FE route-map ×2 app (F-9); số 48 vs 42 + 2 dạng key (F-8) |
| (iii) | Cây toàn trình mirror sidebar (draft:50) | K5 (spec:23, :40) | ✅ nền có thật cho cả GĐ3 (Ct_*) lẫn GĐ4 (Hdc_* 7 leaf, DbInitializer.cs:1868,:1981-1987) |
| (iv) | Admin thu gọn (draft:52) | K6 (spec:23, :41) + K3 | ❌ vỡ 2 nửa: whitelist giữ đúng 2 mục owner bảo ẩn (F-2); nửa "8 designer" 0 wave 0 acceptance (F-3) |
| (v) | Dry-run E2E (draft:54) | K8 (spec:24, :43) | ⚠️ chạy prod, tác dụng phụ không xoá được + ping user thật, 0 gate (F-13) |
| bổ sung 1 | "Tạo luôn master data danh mục" (lời 10, draft:16) | K1 | = (i), xem F-1/F-14 |
| bổ sung 2 | "yêu cầu là dry-run luôn" (lời 10) | K8 | = (v), xem F-13 |
Đối chiếu 10 lời chốt verbatim §0 draft → wave/quyết định nào ăn
| Lời | Nội dung | Ăn ở đâu | Verdict |
|---|---|---|---|
| 1 (draft:7) | PE bự → bổ hạng mục nhỏ | QĐ2 + K2 (spec:13) | ✅ |
| 2 (draft:8) | hạng mục ≠ loại HĐ ≠ 5 form; "đặt tên field tách bạch" (draft:27) | — | ⚠️ F-15 (kỷ luật đặt tên rơi; spec vẫn xài "loại HĐ" 2 nghĩa trong cùng file) |
| 3 (draft:9) | duyệt xong → "đưa vào loại hợp đồng gì" | QĐ1 (spec:12) chỉ chốt CARDINALITY | ⚠️ F-15: cơ chế CHỌN loại HĐ/khuôn lúc bắc cầu K7 không giao cho ai |
| 4 (draft:10) | GĐ3 chỉ điều khoản | spec:7 | ✅ (cố ý ngoài scope) |
| 5 (draft:11) | ký nháy = mực trên bản cứng; "in khối ký đúng pattern" (draft:25) | chỉ nằm trong ngoặc lý do QĐ4 (spec:15) | ❌ F-11: 0 wave, 0 checklist |
| 6 (draft:12) | fan-out A1/A2 + chú thích ngắn | K4 | ✅ (chú thích ngắn không có phép đo — LOW, gộp F-8) |
| 7 (draft:13) | "Ẩn hết… chỉ còn Quy trình duyệt (Mới)" + chừa User + "theo nhóm duyệt" | QĐ7/K6 + QĐ2 | ❌ F-2 (whitelist mâu thuẫn) + ❌ F-3 (8 designer) |
| 8 (draft:14) | thêm sub-folder + sliderbar giống nhau | K5 | ✅ |
| 9 (draft:15) | giống nhau, chỉ khác form, đừng chế | spec:7 + acceptance SHA K5 (spec:40) | ✅ |
| 10 (draft:16) | dry-run + master data | K8 + K1 | ✅ có wave (chất lượng: F-1, F-13) |
Findings
F-L1-1 [HIGH] — Nguồn dữ liệu của K1 không tồn tại theo cái tên spec ghi
- Claim: "việc ĐẦU K1" = extract file gốc
SOL-CCM-SP-002(spec:19) trỏ vào một tên file 0 hit trên toàn câyD:\Dropbox\CONG_VIEC\SOLUTION. - Evidence:
find . -iname "*SP-002*"→ 0 hit; control-dương cùng lệnh cùng cây-iname "*FO-002*"→ 7 hit (FORM/SOL-CCM-FO-002.01…07) ⇒ không phải thước hỏng.QUY_TRINH/chỉ có 1 file:QT TRINH KY HOP DONG TP-NCC.docx(141.036 B). Draft:42 cũng ghi path…\QUY_TRINH\SOL-CCM-SP-002…. - Vì sao HIGH: K1 là wave nền của cụm 1; K2 (CatalogEntryId), K4 (ApprovalGroup) đều phụ thuộc. OG-5 (spec:30) chỉ phủ ca "extract vẫn mơ hồ", KHÔNG phủ ca "không tìm thấy file".
- Đề nghị: pin TÊN FILE THẬT + kích thước vào spec trước khi K1 chạy; nếu
QT TRINH KY HOP DONG TP-NCC.docxchính là SP-002 thì khai đính chính; acceptance K1 thêm "trích được bảng 3.5 với N dòng, N khai trước khi seed".
F-L1-2 [HIGH] — Whitelist "System subtree" GIỮ LẠI đúng 2 mục owner ra lệnh ẩn
- Claim: QĐ7 "chừa
Systemsubtree + AwV2" (spec:18) mâu thuẫn trực tiếp draft:52 ("+ 2 mục quy trình cũ (Quy trình Duyệt NCC · Quy trình HĐ)" nằm trong danh sách ẨN) và lời 7 (draft:13 "chỉ còn cái Quy trình duyệt (Mới) thôi"). - Evidence (đĩa):
DbInitializer.cs:1795(MenuKeys.Workflows, "Quy trình HĐ", MenuKeys.System, 95, …)·:1798(MenuKeys.PeWorkflows, "Quy trình Duyệt NCC", MenuKeys.System, 95, …)·:1801(MenuKeys.ApprovalWorkflowsV2, "Quy trình duyệt (Mới)", MenuKeys.System, 96, …). ⇒ cả 3 đều là CON củaSystem; whitelist cả subtree = giữ nguyên 2 mục cũ. Vế "+ AwV2" trong QĐ7 còn thừa (AwV2 vốn ở trong System). - Acceptance không bắt được: K6 (spec:41) "sidebar admin chỉ còn HỆ THỐNG + Quy trình duyệt (Mới)" — 2 mục cũ nằm BÊN TRONG "HỆ THỐNG" nên câu này vẫn đọc là PASS. Đây là dòng acceptance không phân biệt được đúng/sai.
- Đề nghị: whitelist ở mức KEY (
System, Users, Roles, Permissions, MenuVisibility, ApprovalWorkflowsV2+ con của AwV2), KHÔNG "subtree"; acceptance đổi thành liệt kê ĐỦ tên mục còn lại và ghi rõWorkflows/PeWorkflowsphải VẮNG.
F-L1-3 [HIGH] — Nửa "+= 8 designer nhóm-duyệt" của mảnh (iv) không có wave, không có acceptance
- Claim: draft:52 đòi "Quy trình duyệt (Mới) += 8 designer nhóm-duyệt (khuôn y Duyệt NCC (Mới): Bước—Phòng—Cấp, versioned + archived history)". Spec chỉ có 2 chữ "designer entry" trong mô tả K3 (spec:22) và "+ 8 designer" trong §① (spec:7) — 0 dòng checklist đo nó; sub-file invest còn chốt "0 designer mới" (
sub-invest-fable-b1a.md:53). - Evidence nền: tiền lệ là 2 leaf con của AwV2 (
DbInitializer.cs:1802-1803AwV2_DuyetNcc/AwV2_DuyetNccPhuongAn); route FE là allowlist HARDCODE 3 code (fe-admin/src/components/Layout.tsx:169:code === 'DuyetNcc' || 'DuyetNccPhuongAn' || 'Contract') ⇒ 8 designer nhóm cần +8 MenuItem +8 nhánh route, không tự có. - Acceptance hiện tại đo trật: K3 (spec:38) chỉ đo
GET /approval-workflows-v2?applicableType=10trả 8 — API trả 8 mà admin UI vẫn 0 mục designer nhóm thì vẫn PASS. - Đề nghị: hoặc thêm dòng checklist "8 leaf
AwV2_KHKK_N1..N8hiện dưới Quy trình duyệt (Mới), click mở đúng designer của Code tương ứng", hoặc khai TỪ CHỐI phạm vi (1 designer type-10 dùng chung) và cho owner biết vì đó là thứ anh nhìn thấy.
F-L1-4 [HIGH] — 4 OWNER-GATE được khai nhưng KHÔNG nối vào wave nào ⇒ không chặn được gì
- Claim: §② liệt OG-1/OG-2/OG-3/OG-5 (spec:26-30) nhưng §③ checklist (spec:36-44) 0 dòng nhắc tới gate; bảng wave (spec:22-24) cũng không ghi tiền-điều-kiện.
- Cụ thể OG-2 (roster map vai→user): phải gật TRƯỚC K3 (wave seed 8 workflow, spec:22) — spec nói "cần anh gật trước khi seed" (spec:28) nhưng DoD K3 (spec:38) không có dòng đó. Fan-out B4 dặn worker "bám sát spec-chi-tiết + checklist" (draft:86) ⇒ worker đọc §③, nơi gate vô hình.
- Rơi hẳn: cảnh báo ⚠️ của draft:52 "verify bản LIVE không phải archived trước khi wire" không xuất hiện ở bất kỳ đâu trong spec ⇒ nguy cơ seed roster từ bản workflow đã archive.
- Đề nghị: mỗi wave có gate thì DoD mở đầu bằng "[BLOCKED-BY OG-n] — chưa có gật thì không chạy"; thêm 1 dòng checklist "OG-1/2/3/5 đã có phán quyết bằng văn bản (link) trước khi cụm tương ứng khởi động"; OG-2 kèm bước verify workflow
QT-DN-V2-001bản LIVE.
F-L1-5 [HIGH] — Repurpose Lines per-hạng-mục phá nghĩa PeReferenceAmount, checklist 0 bất-biến tài chính
- Claim: QĐ2 (spec:13) đổi
Linestừ 1-row-per-NCC sang N-row-per-(NCC × hạng mục). Entity hiện tại nói rõ "1 row = 1 NCC (winner của PE nguồn)" vàPeReferenceAmount= SNAPSHOT tổng báo giá của NCC này trên phiếu PE (SUM Quote.IsSelected) — một con số PER-NCC-TOÀN-PHIẾU. - Evidence:
src/Backend/SolutionErp.Domain/ContractSigningPlans/ContractSigningPlanLine.cs:6(comment "1 row = 1 NCC"),:16-20(PeReferenceAmountsnapshot),:9-10(UNIQUE (PlanId, SupplierId) filteredWHERE IsDeleted=0). - Hệ quả: sau khi nhân dòng, mọi nơi SUM
PeReferenceAmounttheo phiếu sẽ nhân N lần (cùng NCC lặp lại trên N hạng mục). Spec tự gọi đúng tên lớp lỗi (S87/S88, spec:32) nhưng guard duy nhất là quy trình ("grep MỌI consumer"), còn acceptance K2 (spec:37) chỉ đo tạo phiếu / 409 / mở phiếu cũ / test validator âm — không có một phép so tiền nào. - Đề nghị: thêm dòng acceptance đo được: "trên ≥1 phiếu KHKK có sẵn, tổng tiền hiển thị/API TRƯỚC và SAU Mig 71 bằng nhau (chụp số)"; và chốt luôn ngữ nghĩa mới của
PeReferenceAmountở cấp dòng (chia? lặp? NULL?).
F-L1-6 [MED] — Acceptance K7 giaTri == ApprovedAmount mâu thuẫn chính default OG-1
- Claim: OG-1 default = GỘP N line → 1 HĐ (spec:12) nhưng acceptance K7 viết số ít
giaTri == ApprovedAmount(spec:42); gộp thì phải làSUM(ApprovedAmount)của các line cùng (NCC × dòng-danh-mục). - Evidence:
ContractSigningPlanLine.cs:24public decimal? ApprovedAmount— nullable, "CHỈ ghi tại choke-point finalize" ⇒ gộp khi có line NULL chưa được định nghĩa (bỏ qua? coi 0? chặn?). - Thiếu thêm: phạm vi gộp không khai — trong 1 phiếu, trong 1 PE cha, hay toàn cục theo (SupplierId, CatalogEntryId)? Đọc thẳng mặt chữ "gộp theo cặp (NCC × dòng-danh-mục)" có thể gộp xuyên phiếu/xuyên dự án.
- Đề nghị: viết lại acceptance thành
giaTri == SUM(ApprovedAmount) các line thuộc nhóm gộp+ khai rõ khoá gộp gồm cảContractSigningPlanId(hoặc PE cha) + xử lý NULL.
F-L1-7 [MED] — Treo #6 (phiếu KHKK cũ) chỉ được trả lời nửa MENU, rơi hẳn nửa DỮ LIỆU
- Claim: draft:76 hỏi "Mục '1. Kế hoạch ký kết HĐ (NCC-TP)' cũ (đã có phiếu?) → migrate/giữ/ẩn thế nào". QĐ6 (spec:17) trả lời phần MENU (giữ key, đổi label). Phần DỮ LIỆU: QĐ3 thêm cột
ApprovalGroup **int**(spec:14 — mặt chữ = non-null) mà không có backfill/default cho phiếu đã tồn tại. - Hệ quả đo được: K4 (spec:39) "leaf lọc đúng
ApprovalGroup" ⇒ phiếu cũ mang group mặc định 0 sẽ không thuộc leaf nào trong 8 nhóm = biến mất khỏi điều hướng mới. K2 (spec:37) "phiếu cũ mở nguyên vẹn" chỉ nóiCatalogEntryId=NULL, không đả động ApprovalGroup. - Đề nghị: chốt
ApprovalGroup int?(nullable) + quy tắc hiển thị phiếu chưa gán nhóm (leaf "Chưa phân nhóm" hoặc backfill về nhóm 1 kèm bằng chứng đếm row trước/sau).
F-L1-8 [MED] — Số leaf 48 vs 42 + hai dạng key song song (hệ quả của QĐ6, không ai đo)
- Claim: QĐ6 (spec:17) viết "nhóm 2-8 = key mới
Khkk_G{n}_*(48 leaf)" — nhóm 2-8 là 7 nhóm × 6 = 42 leaf mới; 48 là TỔNG (khớp checklist spec:39 "8 mục + 48 leaf"). - Evidence hình dạng thật:
DbInitializer.cs:1780Khkk_G1là GROUP dưới rootKeHoachKyKet; 6 leaf con làKhkk_WfView/List/Create/Pending/Approved/Deleted(:1782-1787) — không có infixG1_. Giữ key cũ ⇒ tồn tại song song 2 dạng (Khkk_ListvàKhkk_G2_List), mọi parser/route-map/seeder-grant phải xử 2 nhánh. - Đề nghị: khai rõ tổng 8 group + 48 leaf, trong đó 42 leaf mới + 7 group mới = 49 MenuItem mới; thêm acceptance "0 chỗ nào parse key bằng cách cắt cứng prefix" hoặc chấp nhận rename có backfill label (khuôn S155 đã nhắc).
F-L1-9 [MED] — K4 thiếu deliverable "route-map FE ×2 app"; acceptance K4 không ghi ×2 app
- Claim: leaf không có route ⇒ biến mất im lặng, không lỗi. Spec K4 (spec:23, :39) không nhắc gì tới static route map.
- Evidence:
fe-user/src/components/Layout.tsx:59-62,:82-83vàfe-admin/src/components/Layout.tsx:35-40đều hardcode đúng 6 keyKhkk_*;fe-admin/src/components/Layout.tsx:270if (!path) return null(leaf tự rụng); comment ngay tạife-admin/…/Layout.tsx:40: "[S159-đợt5 FLAG-1] thiếu là leaf drop SILENT (gotcha #50)"; run S159 đã dính thật ("fe-admin thiếu 2 route Khkk → FIX +2 staticMap"). - Thêm: K2/K5 có chữ "×2 app" trong acceptance, K4 không ⇒ rớt 1 app vẫn PASS. (Lưu ý tương tác: nếu K6 whitelist land trước, nhánh admin của 42 leaf thành vô ích — spec nên nói rõ K4 chỉ làm fe-user hay cả 2.)
F-L1-10 [MED] — "only-ONE-active-per-type VÔ HẠI" chưa chứng đủ, và acceptance K3 không thể phát hiện nếu sai
- Claim: spec:14 khẳng định vô hại vì "create chỉ check type, picker lọc
isUserSelectable" — biện luận này phủ 2 consumer, không phủ hết. - Evidence:
SolutionErp.Application/ApprovalWorkflowsV2/ApprovalWorkflowV2AdminFeatures.cs:341-343—.Where(w => w.ApplicableType == typeEnum && w.IsActive)rồiforeach (var old in actives) old.IsActive = false;⇒ mỗi lần tạo bản mới tắt toàn bộ workflow cùng type; sau khi seed 8 nhóm sẽ còn 1 active / 7 inactive, và mỗi lần admin tạo version cho nhóm X thì 7 nhóm kia lại bị tắt (hazard LẶP, không chỉ lúc seed). Consumer khác vẫn đọc cờ này::210versions.FirstOrDefault(v => v.IsActive). - Acceptance mù: K3 (spec:38) chỉ đếm
GET …?applicableType=10trả 8 — trả 8 bản kể cả 7 bảnIsActive=falsethì vẫn PASS. - Đề nghị: acceptance K3 thêm "8 bản đều
isActive=truesau seed" và "tạo version mới cho nhóm 5 xong, 7 nhóm còn lại vẫn active" (đây mới là phép làm TRƯỢT nếu 'vô hại' sai).
F-L1-11 [MED] — "App in khối ký nháy" không có chủ sở hữu
- Claim: lời 5 (draft:11) + draft:25 "app in khối ký đúng pattern"; spec chỉ để nó trong ngoặc lý do của QĐ4 ("hiển thị/in khối ký", spec:15). Không wave nào nhận, không dòng checklist nào đo. GĐ4 đã chốt 1-mốc xong từ S161 ⇒ không có wave GĐ4 để rơi vào.
- Đề nghị: hoặc gắn vào K1 (render khối ký từ chuỗi vai của dòng danh mục) với acceptance "in thử 1 phiếu, khối ký khớp cột chuỗi-nháy", hoặc khai defer công khai.
F-L1-12 [MED] — QĐ4 (vai TEXT 2 tầng) là ứng viên OWNER-GATE bị tự chốt (chốt lậu ứng viên #1)
- Claim: QĐ4 (spec:15) quyết định rằng chuỗi vai (TBP.CCM, QS…) chỉ là TEXT trên danh mục, còn người duyệt thật nằm ở V2 Levels — không có ràng buộc nào giữa 2 tầng. Hệ quả nghiệp vụ: giấy in ra ghi "TBP.CCM ký" trong khi người bấm duyệt có thể là ai khác; hệ thống không phát hiện, không có phép đo.
- Vì sao là quyền owner: đây là thứ owner nhìn thấy trên bản cứng và là lý do tồn tại của SP-002 (ai được ký). 4 quyết định khác được dán nhãn OG (1/2/3/5); QĐ4 thì không, dù mức độ nhìn-thấy-được cao hơn OG-3 (NĐUQ tham khảo).
- Đề nghị: gán [OWNER-GATE] hoặc khai LIMITATION tường minh + 1 dòng acceptance đối chiếu (ví dụ: cảnh báo mềm khi người duyệt ở Level không khớp vai ghi trên dòng danh mục).
F-L1-13 [MED] — K8 dry-run chạy PROD với 2 tác dụng phụ tự khai mà 0 gate
- Claim: spec:32 tự liệt rủi ro K8: "HỐ-1 S160 (HĐ DaPhatHanh không xóa được qua API)" + "notification bắn user thật"; acceptance K8 (spec:43) đòi "mã phiếu thật" ⇒ chạy trên dữ liệu thật. Draft:54 để ngỏ "prod/UAT". Không có OG nào cho việc tạo bản ghi không xoá được và ping nhân viên thật.
- Đề nghị: thêm [OWNER-GATE] "dry-run chạy prod hay UAT; nếu prod thì chấp nhận N bản ghi ZZTEST tồn tại vĩnh viễn + ai bị notify" — hỏi TRƯỚC K8, không hỏi sau.
F-L1-14 [LOW] — Acceptance K1 chỉ đo số dòng ⇒ bảng thiếu cột vẫn PASS
- Claim: draft:46 liệt cột bắt buộc: "mã nhóm A1…C3 + tên VN/EN + nhóm-duyệt 1-8 + người-ký + chuỗi nháy" (+ cột NĐUQ tham khảo theo QĐ5). Acceptance K1 (spec:36) chỉ đo N dòng + CRUD 200 + seed idempotent +
dotnet test. - Cụ thể rơi: "tên EN" không xuất hiện một lần nào trong spec.
- Đề nghị: liệt kê tập cột tối thiểu ngay trong dòng acceptance.
F-L1-15 [MED] — Lời 2+3 (3 trục độc lập / "đưa vào loại hợp đồng gì") chỉ được ăn một nửa
- Claim (a): draft:27 cảnh báo "Chữ 'loại HĐ' trong hội thoại mang 2 nghĩa — đặt tên field tách bạch". Spec không mang cảnh báo này sang, và chính spec dùng cả "đưa vào loại HĐ" (spec:12, nghĩa = dòng danh mục SP-002) lẫn "7 loại HĐ" (spec:7, nghĩa = ContractType) trong cùng một file ⇒ đúng cái bẫy owner cảnh báo.
- Claim (b) nặng hơn: cơ chế CHỌN loại HĐ/khuôn form lúc bắc cầu KHKK→HĐ không giao cho ai. K7 (spec:24, :42) chỉ nói bridge đọc
ApprovedAmount+ gộp theo OG-1; ai/ở đâu chọnContractType(7 loại, quyết cả mã HĐ RG-001 lẫn workflow pin) thì trống. Lời 3 (draft:9) đòi đúng bước này. - Đề nghị: 1 dòng acceptance K7: "màn tạo HĐ từ KHKK bắt chọn ContractType (mặc định suy từ …), mã HĐ sinh đúng RG-001 theo loại đã chọn".
Điểm CHỊU ĐƯỢC soi (khai 2 chiều, chống Smart-Friend)
- P1 — khai thiếu OG-4 là THẬT: spec:30 viết "Không có OG-4 trong sub-file — số nhảy là của lane, giữ nguyên không bịa". Đo lại:
grep -n "OG-" sub-invest-fable-b1a.md→ hit ở:36 (OG-1),:39 (OG-2),:40 (OG-3),:43 (OG-5),:53 (OG-2),:57 (OG-1)— 0 hit OG-4. Khai đúng, không bịa lấp chỗ trống. - P2 — tôi ĐÃ ĐỊNH flag sai và tự bác: dự định flag "GĐ4 không có sidebar 7 loại để mirror" ⇒ đo đĩa thì
Hdc_*7 leaf có thật (DbInitializer.cs:1868, nhãn:1981-1987) ⇒ BỎ finding, mảnh (iii) đứng vững. - P3 — QĐ7 gọi đúng tên hàm có thật:
isAdminHidden(fe-admin/src/components/Layout.tsx:182-184, hiện chỉ chặnCt_) +filterForAdmin(:186-190) + sidebar admin render 100% từ menu-tree động (:315) ⇒ cơ chế "1 file FE, 0 BE" khả thi. Lỗi của QĐ7 nằm ở tập whitelist (F-2), không ở cơ chế. - P4 — header spec khai rõ lane E/F chết + lead compile từ nhãn inline (spec:3) ⇒ truy được nguồn từng quyết định; đây là lý do lens này soi được §② nhanh.
Verdict
FAIL (spec chưa đủ chuẩn để mở fan-out B4 nguyên trạng) — 15 finding: 5 HIGH · 9 MED · 1 LOW.
Không phải bác toàn bộ: khung 8 wave / 3 cụm và 5/7 mảnh scope có wave phủ, luật khuôn được ràng bằng acceptance SHA. Nhưng 3 thứ phải sửa TRƯỚC khi worker cầm spec:
- F-2 + F-3 — mảnh (iv) đang thực thi ngược lời owner (giữ 2 designer cũ) và thiếu hẳn nửa "8 designer".
- F-4 — 4 owner-gate không nối vào wave nào ⇒ B4 sẽ chạy xuyên gate mà không ai chặn (đặc biệt OG-2 phải gật trước K3).
- F-1 + F-5 — K1 không có nguồn theo tên đã ghi; K2 đổi cardinality mà 0 bất-biến tiền tệ trong checklist.
Ba dòng acceptance đang không phân biệt được đúng/sai (mù): K6 (spec:41 — F-2), K3 (spec:38 — F-3 và F-10), K1 (spec:36 — F-14).
END — TOTAL: 15 finding (F-L1-1 → F-L1-15), 5 HIGH / 9 MED / 1 LOW.