wal: flush 20260801T1135
This commit is contained in:
@ -0,0 +1,130 @@
|
||||
CICD-K5K4C: PASS — 5/5
|
||||
|
||||
# cicd-monitor — verify deploy K5 + K4c (S166, 2026-08-01)
|
||||
|
||||
Push range `88e7ecf..e202393`. FE-ONLY, 0-mig cả 2 commit. Run **#439** (id 552) — **success**, 11:08:17 → 11:14:33 (**6m16s**).
|
||||
Artifact ghi TỪNG MỤC ngay khi có bằng chứng (luật #53: ghi-đĩa-TRONG-lúc-làm; return chỉ là tóm tắt).
|
||||
|
||||
---
|
||||
|
||||
## M0 — Mốc PRE (tự đo LIVE, KHÔNG tin số spec) — ĐO LÚC RUN CÒN `running`
|
||||
|
||||
Cửa sổ vàng: bắt được #439 ở trạng thái `running` lúc **11:09:15** ⇒ bundle LIVE lúc đó = PRE thật (không phải số chép lại).
|
||||
|
||||
| App | index-*.js | index-*.css | size (B) | Last-Modified | Content-Type |
|
||||
|---|---|---|---|---|---|
|
||||
| admin | `index-qOcoitOr.js` | `index-Cf3iCOOv.css` | 1.756.651 | 01 Aug 03:15:14 GMT (=10:15:14 +07) | application/javascript |
|
||||
| eoffice | `index-D9J3BbcA.js` | `index-DX1FRk5n.css` | 1.673.668 | 01 Aug 03:16:16 GMT (=10:16:16 +07) | application/javascript |
|
||||
|
||||
🔑 **PRE tự chứng là bundle #438 bằng LM, không chỉ bằng hash**: LM 10:15:14 / 10:16:16 nằm TRỌN trong cửa-sổ deploy #438 (10:10:19 → 10:16:42). Kết quả trùng baseline MEMORY — nhưng trùng đó là KẾT QUẢ ĐO, không phải giả-định đầu vào. (Bài "mốc PRE lão hoá sau MỖI deploy".)
|
||||
Content-Type `application/javascript` + ~1,7MB ⇒ không dính bẫy SPA-fallback (`text/html` ~900B).
|
||||
|
||||
## M0-bis — Chọn byte-marker CÓ RĂNG (verify 0-hit PRE TRƯỚC khi dùng)
|
||||
|
||||
**M-K5 (kỳ vọng CẢ 2 app)** — `Chưa có phiếu ở nhóm này`
|
||||
- PRE eoffice **0** · PRE admin **0**
|
||||
- control-DƯƠNG cùng file/cùng pipeline grep: `Kết cấu` = **1** ở CẢ 2 ⇒ 0-hit là ĐO THẬT, không phải grep chết / encoding hỏng.
|
||||
- src@`88e7ecf`: `git grep` exit=1 (0 hit) ⇒ marker **chưa tồn tại ở mốc PRE** — không dính bài "marker đã có sẵn từ deploy trước = 0 bit" (`Kết cấu` ở K4ab).
|
||||
- src@HEAD: có ở **cả** `fe-admin/src/components/pipeline/PipelineStageFolders.tsx:200` **và** `fe-user/.../PipelineStageFolders.tsx:200`, là JSX text (không phải comment).
|
||||
|
||||
**M-K4c (kỳ vọng CHỈ eoffice — differential)** — `Xem tất cả nhóm` · `quy trình ở nhóm khác` · `được Admin ghim cho nhóm`
|
||||
- cả 3: PRE eoffice **0**, PRE admin **0**; src@HEAD **chỉ** ở `fe-user/src/pages/pe/WorkflowMatrixViewPage.tsx` (dòng 134/161), 0 hit fe-admin.
|
||||
- ⇒ bất-đối-xứng CỐ Ý: POST phải eoffice ≥1 / admin **0**. Differential này tự chứng comment-strip + tự chứng ship đúng app.
|
||||
|
||||
❌ **LOẠI marker `xem tất cả`** (chữ thường): 3/3 hit trong repo đều nằm trong `//` comment (`Layout.tsx` ×2 + `WorkflowMatrixViewPage.tsx:55`) ⇒ Vite strip ⇒ **0 bit**. Soi ĐIỀU KIỆN trong source TRƯỚC khi phong làm marker (bài K3 `earlyFinalizeLocked`).
|
||||
|
||||
---
|
||||
|
||||
## Mục 1 — Run Gitea cho `e202393` ✅ PASS
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| head_sha | `e2023932568e731c5a6f8b7dd4ccd4ff4b3c6130` (khớp HEAD; `git log origin/main..HEAD` **rỗng**) |
|
||||
| run | **#439** / task id **552** / `status=success` |
|
||||
| thời gian | created 11:08:17 → updated 11:14:33 = **6m16s** (dải quen 5m3x–6m3x) |
|
||||
| tail log | `Deploy done. App pool started.` → `API /health/live -> 200` → `🏁 Job succeeded` |
|
||||
|
||||
**Range phủ `ce35f90`:** `88e7ecf..e202393` = **9 commit** — 2 code (`ce35f90` K5 10:44:32, `e202393` K4c 11:08:09) + **7** `wal:` commit (`ff4d4dc`,`13f7f82`,`284233f`,`80b8cf5`,`2023f41`,`d163f6d`,`fa999d8`).
|
||||
⚠️ Đề bài ghi "2 wal-commit kèm" — **đo được 7**. Không đổi kết luận (Gitea build cả *range*, K5 nằm trong range ⇒ được phủ), nhưng ghi lại vì đây lại là một mốc-đề-bài lệch với đĩa.
|
||||
`paths-ignore` (7-glob): `.claude/agent-memory/**` + `.claude/workflows/runs/**` bị bỏ qua, **nhưng** `fe-admin/**`, `fe-user/**`, `tests/**` KHÔNG ⇒ CI đúng ra phải chạy, và nó đã chạy.
|
||||
|
||||
## Mục 2 — Gate CI **622 = 45 D + 577 I** ✅ PASS (tách-phần, khớp từng vế)
|
||||
|
||||
Đo ở web-UI log `…/actions/runs/439/jobs/0/logs` (18.674 B):
|
||||
|
||||
| Project | dòng log | Failed | Passed | Skipped |
|
||||
|---|---|---|---|---|
|
||||
| `SolutionErp.Domain.Tests.dll` | L29 | **0** | **45** | 0 |
|
||||
| `SolutionErp.Infrastructure.Tests.dll` | L47 | **0** | **577** | 0 |
|
||||
| **Tổng** | | **0** | **622** | 0 |
|
||||
|
||||
- Khớp **dự đoán TRƯỚC khi đo**: 621 → 622, delta **+1** rơi TRỌN vào Infra (45 Domain đứng im) — đúng 1 `[Fact]` mới `ListDeletedContractSigningPlans_FiltersByApprovalGroup_ServerSide` trong `ContractSigningPlanCrudTests.cs` (file test DUY NHẤT trong range).
|
||||
- **control ÂM:** `grep -c 'Failed!'` = **0**; pattern lỗi build/test = **1 hit duy nhất** và là dòng vô hại của runner `Failed to setup Pty Unsupported` (L12, có ở mọi run) — không phải lỗi build/test.
|
||||
- **Flaky đã khai** `DeleteContractSigningPlan_SoftDeletes` (1/12 theo commit-msg K4c): run này **KHÔNG đỏ** (Failed:0; tên test 0-hit trong log vì log chỉ in dòng tổng-kết). Ghi mốc: #439 xanh sạch, chưa cần re-run.
|
||||
|
||||
## Mục 3 — Mig GIỮ 71 + `sys.tables` 97 ✅ PASS (2 nguồn)
|
||||
|
||||
- **Nguồn 1 — git:** `git diff 88e7ecf..e202393 -- '*Migrations*'` = **rỗng** ⇒ 0-mig ở phía code.
|
||||
- **Nguồn 2 — sqlcmd prod (đo SAU `status=success`, tức sau recycle):**
|
||||
`MIGTOP=20260731085624_AddKhkkApprovalGroupCatalogAndFinalizeRuntime` (= Mig 71, GIỮ) · `MIGCOUNT=71` · `SYSTABLES=97` (is_ms_shipped=0).
|
||||
- 🔑 **Mạnh hơn khớp-tổng — set-diff 2 chiều:** so DANH SÁCH `MigrationId` prod với danh sách file mig repo → **IN-PROD-NOT-IN-REPO = rỗng** và **IN-REPO-NOT-IN-PROD = rỗng**. Không drift chiều nào.
|
||||
|
||||
🔴 **Bắt được bug trong CHÍNH công thức đếm của tao (MEMORY).** Lần đếm đầu ra **70** ≠ prod 71 → suýt hô drift. Truy ra: recipe cũ `ls *.cs | grep -v Designer | grep -v Snapshot` **ăn nhầm** `20260717032812_AddPeApprovedBudgetSnapshot.cs` (Mig 67 có chữ "Snapshot" trong TÊN). Filter đúng phải neo đuôi: `grep -vE 'Designer\.cs$|ModelSnapshot\.cs$'` → **71**, khớp prod. Đúng lớp "vắng-mặt trông giống ổn": một mig biến mất im lặng khỏi phép đếm, và nếu prod cũng lệch 1 thì hai cái sai sẽ triệt tiêu nhau thành "xanh".
|
||||
|
||||
## Mục 4 — Bundle rotate ×2 app + byte-marker ✅ PASS
|
||||
|
||||
| App | PRE js | POST js | size PRE→POST | Δ | LM POST (=+07) | trong cửa-sổ deploy? |
|
||||
|---|---|---|---|---|---|---|
|
||||
| admin | `qOcoitOr` | **`C2FhHCNT`** | 1.756.651 → 1.758.685 | **+2.034** | 04:13:05 GMT = 11:13:05 | ✅ (11:08:17–11:14:33) |
|
||||
| eoffice | `D9J3BbcA` | **`DFOCQ2ks`** | 1.673.668 → 1.676.752 | **+3.084** | 04:14:05 GMT = 11:14:05 | ✅ |
|
||||
|
||||
CSS cũng xoay: admin `Cf3iCOOv`→`DqXm5Hpn` · eoffice `DX1FRk5n`→`DlN3yZ5L`.
|
||||
|
||||
**Byte-marker POST (điểm gắt nhất):**
|
||||
|
||||
| Marker | eoffice | admin | kỳ vọng | |
|
||||
|---|---|---|---|---|
|
||||
| `Chưa có phiếu ở nhóm này` (K5, ×2 app) | **1** | **1** | 1 / 1 | ✅ |
|
||||
| `Xem tất cả nhóm` (K4c) | **1** | **0** | 1 / 0 | ✅ |
|
||||
| `quy trình ở nhóm khác` (K4c) | **1** | **0** | 1 / 0 | ✅ |
|
||||
| `được Admin ghim cho nhóm` (K4c) | **1** | **0** | 1 / 0 | ✅ |
|
||||
| control-DƯƠNG `Kết cấu` | 1 | 1 | >0 cả 2 | ✅ grep còn sống |
|
||||
| control-ÂM chuỗi bịa `…nàyZZZ` | 0 | 0 | 0 cả 2 | ✅ grep không khớp-bừa |
|
||||
|
||||
🔑 **Differential khớp element-wise 4/4**: K5 vào CẢ HAI app, K4c CHỈ vào eoffice — đúng y hình dạng của diff (`fe-admin` chỉ bị K5 chạm; `WorkflowMatrixViewPage.tsx` chỉ có ở `fe-user`). Δ size cũng cùng chiều: eoffice +3.084 > admin +2.034 vì eoffice gánh K5+K4c còn admin chỉ K5 — một nhân-chứng ĐỘC LẬP với grep.
|
||||
|
||||
🔑 **Control âm tầng-2 (chứng ghi-đè thật, không phải thêm file):** GET hash CŨ sau deploy → `index-D9J3BbcA.js` = **200 `text/html` 876B**, `index-qOcoitOr.js` = **200 `text/html` 900B** ⇒ rơi về SPA-fallback ⇒ **bundle cũ đã biến mất khỏi đĩa**. (200 ở đây KHÔNG phải "còn sống" — discriminator là Content-Type, không phải status.)
|
||||
|
||||
## Mục 5 — Smoke 4 phép + spot route ✅ PASS (spot: đạt-bar nhưng 0-bit, xem caveat)
|
||||
|
||||
Bearer admin: `POST /api/auth/login` → `accessToken` len **468** ✅
|
||||
|
||||
| Endpoint | code |
|
||||
|---|---|
|
||||
| `GET /api/contracts` | **200** |
|
||||
| `GET /api/purchase-evaluations` | **200** |
|
||||
| `GET /api/menus` | **200** |
|
||||
| `GET /api/contract-signing-plans` | **200** |
|
||||
| control-ÂM `GET /api/khong-ton-tai-zzz` (có bearer) | **404** ✅ |
|
||||
| control-ÂM `GET /api/contracts` KHÔNG token | **401** ✅ |
|
||||
|
||||
**Spot `/khkk/workflow-matrix?type=10&group=3` (eoffice):** → **200** `text/html` **876B**.
|
||||
⚠️ **CAVEAT — con 200 này 0 bit.** Control-ÂM cùng dạng `/khkk/duong-dan-bia-zzz?type=10&group=3` cũng trả **200 `text/html` 876B**, **byte y hệt**. Đây là SPA-fallback rewrite `/*`→`index.html`: mọi đường dẫn đều 200. Bar đề bài ("chỉ cần app 200") ĐẠT, nhưng nó không phân biệt được route có thật hay không ⇒ không đọc thành "route chạy đúng".
|
||||
**Bằng chứng THẬT cho route** nằm ở 2 chỗ khác, và cả 2 đều dương:
|
||||
1. route đăng ký trong `fe-user/src/App.tsx:83` → `<Route path="/khkk/workflow-matrix" element={<WorkflowMatrixViewPage />} />`; leaf sidebar `Layout.tsx:86` `Khkk_WfView: '/khkk/workflow-matrix?type=10&group=1'`.
|
||||
2. logic lọc `?group=` của K4c đã có mặt **trong bundle eoffice đã ship** (3/3 marker = 1), và **không** có ở admin (0/3).
|
||||
|
||||
---
|
||||
|
||||
## Verdict
|
||||
|
||||
**PASS 5/5.** Run #439 `e202393` success 6m16s · gate **622 = 45 D + 577 I** (Failed 0, delta +1 khớp đúng 1 Fact mới) · Mig GIỮ **71** + `sys.tables` **97**, set-diff repo↔prod rỗng 2 chiều · bundle rotate ×2 app, LM in-window, marker differential 4/4 element-wise + 2 tầng control · smoke 4/4 + 2 control-âm.
|
||||
|
||||
**Treo / khuyến nghị (không chặn):**
|
||||
1. Bar "FE route 200" **không có răng** với SPA-fallback (POS ≡ NEG byte-identical). Lần sau muốn đo route: đo bằng byte-marker trong bundle, hoặc gọi API mà route đó dùng, đừng đo bằng status code của đường dẫn client.
|
||||
2. Recipe đếm mig trong MEMORY có **false-negative** (ăn `AddPeApprovedBudgetSnapshot`) — đã sửa sang filter neo-đuôi + ưu tiên set-diff thay khớp-tổng.
|
||||
3. Flaky `DeleteContractSigningPlan_SoftDeletes` (khai 1/12) chưa cắn ở #439; nếu đỏ ở run sau, đối chiếu mốc này trước khi coi là hồi-quy mới.
|
||||
|
||||
**Bundle baseline MỚI (post-#439):** admin `C2FhHCNT`/`DqXm5Hpn` · eoffice `DFOCQ2ks`/`DlN3yZ5L`. *(Snapshot-per-run — sẽ lão hoá ngay ở deploy kế.)*
|
||||
|
||||
END — CICD-K5K4C VERDICT=PASS 5/5
|
||||
@ -0,0 +1,67 @@
|
||||
IMPLFE-K6: DONE
|
||||
|
||||
# Lane FE K6 — admin thu gọn (S166, 2026-08-01)
|
||||
|
||||
SPEC PIN: spec-cụm2 K6 mục 1-4 + acceptance C1-C4 @`sub-invest-fable-b2-cum2.md:67-100`.
|
||||
Phạm vi: `fe-admin/src/components/Layout.tsx` **ONLY**.
|
||||
|
||||
## §0 Kế hoạch đo trước khi gõ
|
||||
- [ ] Đọc lại khối spec `:67-100` (12-key set viết sẵn — dùng NGUYÊN VĂN, không tự chế)
|
||||
- [ ] Đếm THẬT cây menu seed từ `DbInitializer.cs` (không đoán): `AwV2%` là 2 hay 3?
|
||||
- [ ] Xác định chính xác tập lá còn thấy sau lọc + LIỆT TÊN (C1)
|
||||
- [ ] Kiểm `filterForAdmin` lọc theo cây (cha ẩn ⇒ con biến mất theo?) — quyết định set có cần liệt con hay không
|
||||
|
||||
## §1 ĐO ĐĨA (ground truth) — TRƯỚC khi gõ
|
||||
|
||||
### 1.1 🔴 GIẢI xong ẩn-số spec để mở C1: `AwV2_Contract` **KHÔNG TỒN TẠI**
|
||||
Spec `:C1` treo: *"row `AwV2_Contract` có thể tồn tại DB ngoài seed… chốt N: 7 (nếu 2 AwV2) / 8 (nếu 3)"*.
|
||||
Đo: `grep -rn "AwV2_Contract" src/Backend fe-admin/src fe-user/src` → **0 HIT toàn repo**. `MenuKeys.cs:115-117` chỉ có root `ApprovalWorkflowsV2` + **2** leaf (`AwV2_DuyetNcc`, `AwV2_DuyetNccPhuongAn`); `:127-134` thêm 8 `AwV2_KhkkN1..8`. Seed rows: `DbInitializer.cs:1981-1983` (root + 2) + `:1988-1995` (8 designer).
|
||||
⚠️ Chú ý phân biệt: fe-admin `resolvePath:173` CÓ nhận code `'Contract'` → `/system/approval-workflows-v2/Contract`, nhưng đó là **bộ giải route chờ sẵn**, KHÔNG phải menu-row. Route-resolver có nhánh ≠ menu tồn tại. ⇒ **|AwV2 leaf| = 2 (seed) + 8 (designer)**.
|
||||
⇒ **N = 1 (Dashboard) + 4 (System-leaf) + 2 + 8 = 15.** (Dư-lượng thành thật: nếu ai đó INSERT tay `AwV2_Contract` thẳng vào DB prod thì +1; tôi không có đường đo prod trong rào lượt này — khai ở FLAG-2.)
|
||||
|
||||
### 1.2 Cơ chế lọc ⇒ chỉ cần liệt ROOT
|
||||
`filterForAdmin` lọc **ĐỆ QUY** mọi tầng (`.filter(...).map(n => ({...n, children: filterForAdmin(n.children)}))`) ⇒ ẩn 1 root là cả cây con chết theo. Tập 12 key chỉ liệt ROOT + 2 con của `System` (`Workflows`, `PeWorkflows` — parent = `System` nên KHÔNG chết theo root nào khác, phải liệt riêng). Liệt từng leaf vừa thừa vừa phải bảo trì lại mỗi lần BE thêm key.
|
||||
|
||||
### 1.3 `System` không phải lá
|
||||
`System` có 6 con (`Users/Roles/Permissions/MenuVisibility/Workflows/PeWorkflows`) + `ApprovalWorkflowsV2` ⇒ render `MenuGroup`, **không tính vào số LÁ**. Tương tự `ApprovalWorkflowsV2` là group của 10 leaf.
|
||||
|
||||
## §2 THỰC THI — 1 file `fe-admin/src/components/Layout.tsx` (+52 / −19)
|
||||
|
||||
1. **`ADMIN_HIDDEN_KEYS`** = Set 12 key **ĐÚNG NGUYÊN VĂN spec** (PurchaseEvaluations · KeHoachKyKet · Contracts · HopDongCung · Forms · Reports · Master · Hrm · Off · Personal · Workflows · PeWorkflows); `isAdminHidden = ADMIN_HIDDEN_KEYS.has(key) || key.startsWith('Ct_')`. Giữ luật prefix `Ct_` (thừa so với ẩn root `Contracts`, nhưng giữ để nếu mở lại root thì 28 leaf không ùa về theo — khai tại chỗ).
|
||||
2. **Vá-14 — viết lại TRỌN khối comment**: khai lineage **2 LẦN ĐẢO** (S29 ẩn → **S57 bỏ-ẩn** → **QĐ7 S164 ẩn LẠI rộng hơn**, "Admin thu về vai NƠI-CONFIG"), kèm câu chốt *"cả hai đều từng đúng, mốc sau thắng mốc trước — đừng khôi phục S57 vì tưởng gặp bug"*. Comment S57 cũ đã gỡ (nó đang nói ngược luật đang chạy).
|
||||
3. **Display-only #82** khai trong comment: route + quyền admin còn nguyên, deep-link `/purchase-evaluations` vẫn 200; **thu gọn = bớt lối đi trên menu, KHÔNG phải thu hồi quyền**; muốn chặn thật phải làm ở BE `[Authorize(Policy=…)]`.
|
||||
4. **Ghi chú móc nối K4a**: 42 leaf `Khkk_G{2..8}_*` nay bị cắt từ TẦNG CHA nên chuyện `resolvePath` fe-admin thiếu nhánh `Khkk_G*` hết là vấn đề (không còn "rơi im lặng" ở tầng leaf); kèm cảnh báo ngược: gỡ `KeHoachKyKet` khỏi Set thì PHẢI nới regex TRƯỚC + quyết `WfView` admin trỏ đâu.
|
||||
|
||||
## §3 CHỨNG
|
||||
|
||||
**C1 — đếm + LIỆT TÊN (dư/thiếu 1 = FAIL).** Dựng lại cây menu seed từ BE (72 tuple literal parse từ `DbInitializer` + 128 key sinh từ vòng lặp, hằng đọc thẳng `MenuKeys.cs`: `ContractTypeCodes`/`PurchaseEvaluationTypeCodes`/`KhkkGroupNumbers`/`KhkkLeafActions`) = **200 node**, rồi chạy **CHÍNH `ADMIN_HIDDEN_KEYS` + `isAdminHidden` + `filterForAdmin` đã ship** (cắt từ file bằng `indexOf`, chỉ bỏ annotation TS, có assert "còn annotation thì tự chết").
|
||||
> **Đối chứng tính đúng của cây dựng lại:** 113 key trong `MenuKeys.All` → **0 key thiếu menu-row** (invariant T6). Cây dựng sai thì chỉ số này vỡ ngay.
|
||||
|
||||
**166 lá TRƯỚC lọc → 15 lá SAU lọc**, đúng tên từng mục:
|
||||
```
|
||||
1 Dashboard 6 AwV2_DuyetNcc 9 AwV2_KhkkN2 12 AwV2_KhkkN5 15 AwV2_KhkkN8
|
||||
2 Users 7 AwV2_DuyetNccPhuongAn 10 AwV2_KhkkN3 13 AwV2_KhkkN6
|
||||
3 Roles 8 AwV2_KhkkN1 11 AwV2_KhkkN4 14 AwV2_KhkkN7
|
||||
4 Permissions
|
||||
5 MenuVisibility
|
||||
```
|
||||
16/16 assert OK: số = 15 · tập tên khớp CHÍNH XÁC (thừa=[] thiếu=[]) · AwV2 seed-leaf = 2 · 8 designer có mặt · 11 mục kiểm-ẩn đều biến mất (`Khkk_List`, `Khkk_G5_List`, `Pe_DuyetNcc_List`, `Ct_ThauPhu_List`, `Hdc_ThauPhu`, `Suppliers`, `CatalogUnits`, `Wf_ThauPhu`, `PeWf_DuyetNcc`, `Off_DanhBa`, `Hrm_HoSo`).
|
||||
**CONTROL-ÂM:** bỏ `'KeHoachKyKet'` khỏi Set ⇒ **15 → 63 lá (+48)** — đúng 8 nhóm × 6 leaf, chứng phép đo phân biệt được chứ không phải luôn ra 15.
|
||||
|
||||
**C2 — fe-user KHÔNG đổi:** `git diff --stat -- fe-user/src` = **RỖNG (0 file)** ✅ (đo diff, không đo bundle-hash — đúng #69/l3-F12).
|
||||
**C3** — mục "đếm 8 designer trong sidebar" thuộc acceptance K3, không đo ở đây; tuy vậy 8 `AwV2_KhkkN*` có mặt trong danh sách C1 ở trên nên coi như phụ-chứng.
|
||||
**C4 — display-only:** 0 dòng route, 0 dòng `usePermission`/`PermissionGuard` trong diff (diff chỉ chạm `ADMIN_HIDDEN_KEYS`/`isAdminHidden` + comment) ⇒ deep-link admin tới route bị ẩn menu vẫn render và API vẫn 200; rào THẬT ở BE authz.
|
||||
|
||||
**Build:** `npx tsc -b` exit 0; `npm run build` fe-admin PASS **1961 modules**, `dist/assets/index-B0OrpamE.js` 1,726.07 kB (gzip 429.28) · `index-AgG72YRZ.css` 86.93 kB · 620ms. Warning >500KB + `INEFFECTIVE_DYNAMIC_IMPORT` = PRE-EXISTING.
|
||||
**Rào:** `git diff --stat` = **đúng 1 file** `fe-admin/src/components/Layout.tsx` (52+/19−). 0 fe-user, 0 BE, **0 commit**.
|
||||
|
||||
## §4 FLAG cho lead
|
||||
|
||||
**FLAG-1 (MINOR — chốt số cho spec):** ẩn-số C1 đã giải: **N = 15** (không phải 7/8 như spec dự phòng — spec quên cộng 8 designer K3 vào công thức của chính nó, chỉ nhắc ở vế "SAU K3 = N+8"). Con số ăn khớp: 1 + 4 + 2 + 8 = 15.
|
||||
|
||||
**FLAG-2 (MINOR — dư-lượng thành thật):** tôi đo từ **SEED**, đúng cho DB dựng từ seeder. Nếu prod có menu-row được INSERT tay ngoài seeder (spec nghi `AwV2_Contract`) thì N thật = 15 + số row đó. Đo dứt điểm cần 1 câu `SELECT [Key] FROM MenuItems WHERE [Key] LIKE 'AwV2%'` trên prod — ngoài rào lượt này (không đụng BE/DB), nhờ lane có quyền chạy giúp nếu muốn đóng tuyệt đối.
|
||||
|
||||
**FLAG-3 (MINOR — quan sát, không tự sửa):** sau K6, `resolvePath` fe-admin còn **một loạt nhánh chết** (staticMap `Khkk_*`, `Hdc_*`, `Suppliers`, `Off_*`, `Hrm_*`… + regex `Pe_*`) — key không bao giờ tới nữa vì đã cắt ở tầng cha. Vô hại (chỉ là mã không chạy tới), và **cố ý không dọn** lượt này: dọn = xoá đúng thứ phải khôi phục nếu QĐ7 lại đảo lần 3, mà lịch sử file này đã đảo 2 lần. Nếu lead muốn dọn thì nói, tôi tách lượt riêng.
|
||||
|
||||
IMPLFE-K6-END
|
||||
|
||||
@ -0,0 +1,29 @@
|
||||
GATE-K6: IN-PROGRESS — đang đo, chưa chốt verdict (dòng-1 sẽ được ghi đè ở lượt cuối).
|
||||
|
||||
# Gate K6 — reviewer adversarial (S167, 2026-08-01)
|
||||
|
||||
Đối tượng: diff UNCOMMITTED `fe-admin/src/components/Layout.tsx` (+52/−19).
|
||||
Spec pin: `sub-invest-fable-b2-cum2.md:67-100` (K6 mục 1-4 + acceptance C1-C4).
|
||||
Lane artifact: `sub-implfe-k6.md`.
|
||||
|
||||
## R0 — Rào residual-write (đo TRƯỚC)
|
||||
|
||||
`git status --porcelain`:
|
||||
```
|
||||
M .claude/WAL.md
|
||||
M .claude/agent-memory/implementer-frontend/MEMORY.md
|
||||
M .claude/agent-memory/implementer-frontend/archive/2026-H2.md
|
||||
M .claude/auto-memory/MEMORY.md
|
||||
M .claude/auto-memory/feedback_claim_stronger_than_work.md
|
||||
M .claude/auto-memory/feedback_return_terminates_agent.md
|
||||
M .claude/governance/.session-counter.json
|
||||
M fe-admin/src/components/Layout.tsx
|
||||
?? .claude/sessions/session-9/_tiep-4.md
|
||||
?? .claude/workflows/runs/.../sub-cicd-verify-k5-k4c.md
|
||||
?? .claude/workflows/runs/.../sub-implfe-k6.md
|
||||
```
|
||||
⇒ Ngoài `.claude/*` (governance, ngoài phạm vi gate) chỉ có **đúng 1 file code**: `fe-admin/src/components/Layout.tsx`.
|
||||
**0 residual-write.** `git diff --stat` khớp lane khai: `71 +++++-----` = 52 thêm / 19 bớt.
|
||||
(Ghi chú: lane khai "đúng 1 file" trong `git diff --stat` — thực tế `git diff --stat` trần cho 8 file vì `.claude/*` cũng dirty; câu của lane chỉ đúng khi hiểu ngầm là "1 file CODE". Không phải lỗi thực chất, ghi để không ai đọc thành 0-dirty.)
|
||||
|
||||
## R1 — 12-key: so TỪNG CHỮ vs spec (đang đo)
|
||||
Reference in New Issue
Block a user