7.4 KiB
7.4 KiB
GATE-K5: IN-PROGRESS
Gate K5 — adversarial review cây pipeline GĐ2 mở 8 sub-folder nhóm (S166, 2026-08-01)
Vai: reviewer (READ-only, verdict-only). Ghi TỪNG MỤC, Edit sau mỗi mục (chống #53).
§0 Mốc đo (neo trước khi soi)
- Lệnh:
git status --porcelain+git rev-parse HEADlúc 1st-measure. - 🔴 LỆCH TIỀN-ĐỀ #1: spec lead nói "diff chưa commit trên HEAD
88e7ecf". Đĩa đo được HEAD =ff4d4dc9d0b745867f83b5349f3c239d6b2ee798. Phải truygit logxem88e7ecfnằm đâu trước khi tin base. - 🔴 RÀO GIT #1:
git statuscó?? menus.jsonở ROOT repo (untracked, ngoài spec 4 file). Cần đo: file gì, có bị commit ké không. - Cây làm việc lúc mốc-0 (8 file M + 3 ??): 4 file code đúng spec + 4 file
.claude/**+ 3 untracked.
§1 Phân lập diff + rào git (đo, không tin lời khai)
git log:88e7ecfLÀ tổ tiên của HEAD ⇒ tiền-đề lead đúng về nội dung, sai về tên mốc: giữa88e7ecfvà HEAD có 3 commitwal: flush.git diff --name-only 88e7ecf..HEAD= 6 file, TOÀN BỘ.claude/**, 0 file code ⇒ base code vẫn là88e7ecf. Verdict K5 đo trêngit diff(working-tree vs HEAD).- 🔴 Cây PHÌNH GIỮA LƯỢT (lần thứ 3 trong 3 gate liên tiếp): HEAD
ff4d4dclúc đo-0 →13f7f82sau ~2 tool-call. Phân lập:git diff --stat -- fe-admin fe-user src tests= đúng 4 file, +466/−108 khớp spec TỪNG SỐ. git status --porcelain -- src tests fe-admin fe-user= 0 dòng??⇒ không có file code chưa track (bài "HIGH nằm ở git" KHÔNG tái phát trong vùng code).- 🔴 RÀO GIT —
menus.json44.656 B nằm ở ROOT repo, untracked (mtime 10:25, nội dung = payload/api/menus/me, sản phẩm phụ của lane cicd verify prod). Không phải file của K5, nhưng nếu lead commit bằnggit add -A/git add .thì nó lên repo. Đây là finding về THAO TÁC COMMIT sắp tới, không phải về diff K5. - Cùng loại:
.claude/agent-memory/implementer-frontend/archive/2026-H2.mduntracked (hợp lệ, nên add có chủ đích).
§2 Build gate — TÔI TỰ CHẠY, không nhận lời khai
| lệnh | nơi chạy | exit |
|---|---|---|
npx tsc -b |
fe-user |
0 |
npx tsc -b |
fe-admin |
0 |
Lời khai lane (tsc -b ×2 exit 0 + npm run build ×2) khớp phần tôi đo lại. Bundle hash lane khai (index-CZUcTUUg.js / index-BZWvx0Y8.js) tôi KHÔNG kiểm lại — chưa deploy nên không có ô canonical để đối chứng; ghi rõ là lời khai chưa đo, đừng đọc thành đã-verify (bài K4a ③). |
§3 SOI-1 — Node nhóm đúng nguồn + route khớp K4b ✅
- 1 nguồn, 0 map thứ hai.
grep KHKK_APPROVAL_GROUPS|khkkGroupMenuLabeltoànfe-user/src+fe-admin/src: consumer = hook K5 (:217/:228/:230) +KhkkCreatePage+KhkkListPage, tất cả import từ@/types/khkk. Không có mảng 8 phần tử nào khác, không có bảng nhãn thứ hai. - 8 node dựng bằng
KHKK_APPROVAL_GROUPS.map(...)(hằng[1..8] as const), nhãnkhkkGroupMenuLabel(n)="{n}. " + KHKK_APPROVAL_GROUP_LABELS[n]— derive, không chép. - 🟢 ĐỐI CHIẾU LIVE (tôi tự đo, không nhận lời khai): so nhãn cây suy ra ⟂ nhãn thật trong payload
/api/menus/me(menus.jsonprod) → 8/8 KHỚP TỪNG KÝ TỰ, cả 8 nodeKhkk_G1..G8đềudisplayLabel = null. Tức hôm nay cây và sidebar gọi cùng một nhóm bằng cùng một tên. - Route:
onOpenAll → /khkk/list?group=${n}. Đối chiếu K4b:Layout.tsx:217khkkLeafPath(group,'List')=/khkk/list?group=${group}, và leaf tĩnhKhkk_List: '/khkk/list?group=1'(:63) ⇒ chuỗi TRÙNG KHÍT. - Nối end-to-end (3 chặng, đo cả 3):
KhkkListPage.tsx:79-80đọcsearchParams.get('group')+ rào^[1-8]$→:124gửigrouplên server → BEContractSigningPlanFeatures.cs:757-758q.Where(p => p.ApprovalGroup == request.ApprovalGroup). Không phải tham-số-trang-trí (khác hẳn bài K4a ①). - Sáng đúng mục sidebar:
Layout.tsx:388-390isActive = pathname khớp && queryMatches(...)(so khớp TẬP query) ⇒?group=ntừ cây ăn khớp leaf nhóm n. Lời khai lane "trang tự sáng đúng mục" đúng, đã kiểm.
§4 SOI-2 — Phân phiếu, fallback, bất-biến Σ ✅ (1 MINOR)
- KHÔNG có ca phiếu rơi khỏi cả 9 ngăn. Vòng
:215-224là if/else toàn phần: khớptypeof g === 'number' && GROUPS.includes(g)→ ngăn n; mọi thứ còn lại (null · undefined · thiếu field · 0 · 9 · NaN · chuỗi) →khkkUngrouped. Không nhánh nàocontinue/bỏ qua. - Σ enforce ở đâu — trả lời thẳng: ở CẤU TRÚC, không phải ở kỷ luật.
khkkLeavesvà các ngăn cùng sinh từ một mảngkhkkItemsbằng một phép phân hoạch;stage.leavesgiữ vai danh sách phẳng canonical vàstageCount()(PipelineStageFolders.tsx:96) vẫn đếm trên nó ⇒ chip số của folder cha không thể lệch tổng các ngăn.console.warn:252chỉ là chuông, và là DEV-only. - Thứ tự đúng: ngăn "(chưa phân nhóm)"
pushở:238-245TRƯỚC khireducetính Σ ở:251⇒ chuông không tự báo động giả. - Ngăn lạc gần như không thể xảy ra (đo BE):
ApprovalGrouplàintnon-null, validatorInclusiveBetween(1,8)(:353-356), default 1 (:399), backfill Mig 71 = 1, và 0 đường update nào ghi lại field này. ⇒ nhánh fallback là phòng thủ, không phải đường sống. - 🟡 MINOR-1 — nhãn ngăn lạc hứa một đằng, đi một nẻo:
onOpenAll: () => navigate('/khkk/list')(:243). Không kèm?group=⇒ BE không lọc gì cả, trang mở ra là toàn bộ phiếu của cả 8 nhóm, trong khi nhãn và tooltip nói "Mở danh sách: (chưa phân nhóm)". Sidebar cũng không sáng mục nào (query rỗng không khớp leaf nào). BE hiện không có bộ lọc "không thuộc nhóm nào" để trỏ tới, nên đây là hạn chế thật chứ không phải quên gõ. Đề nghị: bỏonOpenAllcho riêng ngăn này (component đã có nhánh<span>khi thiếuonOpenAll,:151-155) — mất một cú bấm gây hiểu nhầm, không mất gì khác.
§5 SOI-3 — Ngăn rỗng render THẬT ✅
Đo đường đi, không đọc lời khai — 3 chốt, không chốt nào lọc theo length:
- Dựng:
KHKK_APPROVAL_GROUPS.map(...)—.maptrên hằng 8 phần tử, 0.filtertrong cả khối. - Vẽ:
PipelineStageFolders.tsx:287-295stage.groups !== undefined ? stage.groups.map(g => <GroupFolder…>)— vẽ thẳng mảng nhận được, không điều kiện phụ. - Trong ngăn:
GroupFoldercount === 0→ vẫn render<details>đủ (chevron + tên bấm được +SoonChip), thân in "Chưa có phiếu ở nhóm này."
- Nhánh "Chưa có dữ liệu ở giai đoạn này." (
:296) nay bị nhánhgroupschặn trước ⇒ GĐ2 rỗng hiện 8 ngăn thay vì 1 dòng. Đúng spec "HIỆN ĐỦ 8 kể cả rỗng". - Không đụng
hideEmpty: vẫn lọc ở tầng stage bằngstageCount()=leaves.length⇒ đang tìm-kiếm mà gói không có KHKK thì cả folder GĐ2 ẩn, không đổ ra 8 ngăn rỗng.
(đang tiếp tục §6)