wal: flush 20260801T1037

This commit is contained in:
pqhuy1987
2026-08-01 10:37:08 +07:00
parent 13f7f82525
commit 284233f2dc
6 changed files with 175 additions and 19 deletions

View File

@ -1,4 +1,4 @@
CICD-K4AB: IN-PROGRESS — 0/7
CICD-K4AB: PASS — 7/7 (run #438 success 6m23s · gate 621=45+576 · Mig GIỮ 71 · seed 49 menu+637 perm tam-giác-3-nguồn · A1 8+48 & A5 restart×2 đứng im · bundle JS ROTATE ×2 marker 3/3 · smoke 401/404/200 + bind-400)
# cicd-monitor — verify deploy K4a+K4b SP-002 (`88e7ecf`) + phủ luôn F-1 (`7a903cf`)
@ -203,4 +203,121 @@ literal** (minifier giữ nguyên) và đều có **transition PRE→POST đo đ
admin có đúng 1 lần xuất hiện và nó nằm trong `//` (dòng 39) nên phải ra 0; nếu admin ra 1 thì hoặc
comment lọt vào bundle hoặc tao grep nhầm file.
### §6.1 — ĐO BUNDLE (sau khi dự đoán trên đã ghi đĩa) — ✅ PASS, khớp 3/3 marker
| App | PRE (§0.1) | POST (đo 10:23) | CT | Size | Last-Modified |
|---|---|---|---|---|---|
| admin js | `index-1yiNV4VH.js` | **`index-qOcoitOr.js` ROTATE** | application/javascript | 1.756.651 | 01/08 03:15:14 GMT = **10:15:14 +07** |
| admin css | `index-Cf3iCOOv.css` | `index-Cf3iCOOv.css` FROZEN | text/css | 86.364 | **10:15:14 +07** |
| eoffice js | `index-DoULfmdT.js` | **`index-D9J3BbcA.js` ROTATE** | application/javascript | 1.673.668 | 01/08 03:16:16 GMT = **10:16:16 +07** |
| eoffice css | `index-DX1FRk5n.css` | `index-DX1FRk5n.css` FROZEN | text/css | 92.148 | **10:16:16 +07** |
- **JS ROTATE ×2 = ĐÚNG YÊU CẦU** (cả 2 app đổi code thật: Layout + ListPage + CreatePage + types).
- Cả 4 LM **trong cửa-sổ deploy** 10:10:19→10:16:42 ⇒ deploy CÓ chạm cả 4 file (#69: LM-in-window mới là
ship-proof, hash-delta thì không). **CSS FROZEN lành tính**: K4a/K4b không thêm class Tailwind mới
(chỉ đổi chuỗi route + logic), LM vẫn in-window ⇒ re-ship byte-identical (#69 mode-B), KHÔNG phải kẹt bundle cũ.
- **Control ÂM 2 tầng** — hash CŨ **và** hash BỊA cùng rơi `text/html` 900 B / 876 B:
`admin/index-1yiNV4VH.js`→text/html 900 · `eoffice/index-DoULfmdT.js`→text/html 876 · `admin/index-ZZfakeZZ.js`→text/html 900.
`text/html` thật sự nghĩa "không tồn tại" (SPA-fallback), và **bundle PRE đã biến mất khỏi đĩa = chứng ghi-đè**.
**Byte-marker đo trên file tải về (`adm.js` 1.738.624 ký tự · `eof.js` 1.658.019 ký tự):**
| Marker | Kỳ vọng §6 | admin | eoffice | |
|---|---|---|---|---|
| POS `/khkk/list?group=1` | >0 cả hai | **4** | **4** | ✔ (khớp ĐÚNG 4 = số lần trong source mỗi app — element-wise, không chỉ ">0") |
| NEG `/khkk/list?view=deleted` | 0 cả hai | **0** | **0** | ✔ (chuỗi độc quyền, PRE source =1 ⇒ transition đo được) |
| DIFF `workflow-matrix?type=10&group=` | admin 0 · user 2 | **0** | **2** | ✔ (bất-đối-xứng cố ý ship + comment bị strip đúng như dự đoán) |
| _(marker lead gợi ý)_ `Kết cấu, hạ tầng, phá dỡ` | — | **1** | **1** | 🔴 **=1 ở CẢ HAI ⇒ xác nhận bằng ĐO rằng nó 0-bit**: có mặt bất kể K4 ship hay không |
## §5 — Acceptance A1 (quyền user-thường) + A5 (idempotent qua restart ×2) — ✅ PASS
**A1 — SQL JOIN `Permissions × Roles × MenuItems`, role NON-admin:**
```
Procurement : GROUP = 8 LEAF = 48 (CanRead=1)
Drafter : GROUP = 8 LEAF = 48 (CanRead=1)
```
- Khớp ĐÚNG kỳ vọng đề bài "8 group + 48 leaf". Toán khép: group 8 = `Khkk_G1` + `Khkk_G2..G8`;
leaf 48 = 6 (nhóm-1 không-infix) + 42 (nhóm 2..8) ⇒ tổng 56 = `MENU_KHKK_PCT`.
- Toàn họ: `PERM_KHKK_CANREAD1 = 728 = 56 × 13`**KHÔNG role nào bị hụt** (nếu 1 role sót thì ≤ 715).
**A1-bis — chứng ĐI TRỌN STACK (nguồn thứ 3, mạnh nhất): `GET /api/menus/me` materialize qua EF**
(http 200, 44.656 B; parse cây theo `key`, không grep thô):
```
GROUP distinct = 8 LEAF distinct = 42 per-group = {G2..G8 : 6 mỗi nhóm}
OLD nhóm-1 leaf non-infix = 6 [Khkk_Approved, Khkk_Create, Khkk_Deleted, Khkk_List, Khkk_Pending, Khkk_WfView]
TOTAL Khkk* distinct = 56
Khkk_G1 -> 1. Thiết bị, máy móc, vật tư phụ (A1) Khkk_G5 -> 5. Thầu phụ xây dựng (B2)
Khkk_G2 -> 2. Kết cấu, hạ tầng, phá dỡ & DV hỗ trợ thi công (A2-A3) Khkk_G6 -> 6. Thầu phụ MEP (B3)
Khkk_G3 -> 3. Hoạt động văn phòng (A4) Khkk_G7 -> 7. BCH công trường (C1-C3)
Khkk_G4 -> 4. Vật tư (B1) Khkk_G8 -> 8. HĐ chưa ủy quyền — CEO (5.2)
```
⇒ 8 nhãn ra ĐÚNG tới dấu tiếng Việt qua đường Domain→Infra→Api (không phải chỉ có row trong bảng);
`per-group = 6 đều` chứng không nhóm nào thiếu leaf. **Đây là cái sqlcmd không nói được.**
**A5 — RESTART APP-POOL ×2 THẬT** (`appcmd recycle apppool /apppool.name:SolutionErp-Api`, KHÔNG gọi seeder lẻ
qua reflection — chuỗi `SeedAsync` đủ chỉ chạy lúc boot):
| Mốc | w3wp PID | StartTime | MENU_TOTAL | Khkk menu | PERM_TOTAL | Khkk perm | CanRead=1 | A1 Proc leaf | CTRL Hrm/Off CanRead=1 |
|---|---|---|---|---|---|---|---|---|---|
| sau deploy | 7020 | 10:16:22 | 200 | 56 | 2221 | 728 | 728 | 48 | **29** |
| **restart #1** | **220** | **10:23:55** | 200 | 56 | 2221 | 728 | 728 | 48 | **29** |
| **restart #2** | **6636** | **10:24:38** | 200 | 56 | 2221 | 728 | 728 | 48 | **29** |
- **Restart là THẬT, không no-op**: PID đổi 3 lần (7020→220→6636) + `appcmd` xác nhận đúng pool
`SolutionErp-Api` + Serilog có **3 dòng `Applying migrations...`** (10:16:23 · 10:23:57 · 10:24:39).
- **Idempotent**: sau boot 2 và 3, Serilog **KHÔNG có** `Seeded … menu items` / `Seeded … admin permissions` /
`Seeded all-roles review perms`. Đây là suy luận CÓ CƠ SỞ, không phải đoán từ im-lặng — đã soi điều kiện
log trong source: `DbInitializer.cs:2180-2183 if (added > 0)` · `:2247 if (updatedLabels > 0)` ·
`:2310 if (added > 0)` · `:2524 if (added > 0 || upgraded > 0)`. ⇒ vắng dòng ⟺ **0 added / 0 upgraded**.
Cộng với 8 con số DB đứng im hoàn toàn ⇒ seeder hội tụ, không nhân bản row.
- **Revoker-proof (#84)**: `Hrm*`/`Off*` giữ **29/377** CanRead=1 qua cả 3 mốc. Đây là control ÂM có RĂNG
2 chiều: revoker vẫn CHẠY mỗi boot (nếu chết → bung lên 377) và vẫn KHÔNG chạm `Khkk_*` (nếu quét lố →
728 tụt). Đúng như comment K4a khai ở `DbInitializer.cs` ("filter chỉ bắt prefix `Hrm*`/`Off*` + `Personal`").
- Nhãn `Khkk_G1` giữ nguyên bản backfill qua cả 2 restart ⇒ `labelBackfill` không lật ngược về skeleton.
## §7 — Smoke prod — ✅ PASS
```
GET /api/contract-signing-plans (no token) -> 401 authz đóng đúng
GET /api/contract-signing-plans/deleted?group=1 (no token) -> 401 route MỚI cũng đóng
GET /api/contract-signing-plans-khong-ton-tai-xyz -> 404 \ 2 route BỊA
GET /api/route-rac-k4ab-999 -> 404 / ⇒ 401 ở trên CÓ NGHĨA
GET /health/ready -> 200
GET /health/live -> 200
GET https://admin.solutions.com.vn/ -> 200
GET https://eoffice.solutions.com.vn/ -> 200
```
🔑 **401 chỉ có nghĩa vì đi kèm 404 của route bịa** — nếu server nuốt mọi path thành 401 thì phép đo rỗng.
**Giới hạn phép đo đã gỡ được (đề bài dự phòng đúng):** `?group=abc` **không token → 401**, tức authz chặn
TRƯỚC model-binding ⇒ không đọc được bind-error. Đã lấy bearer admin re-probe để đóng lỗ này:
```
(có token) ?group=abc -> 400 <- BIND-ERROR: param ĐƯỢC WIRE thật (nếu bị nuốt, ASP.NET trả 200)
(có token) ?group=1 -> 200 ?group=8 -> 200 (không group) -> 200
(có token) /deleted?group=1 -> 200
body ?group=1 = {"items":[],"total":0,"page":1,"pageSize":20,"totalPages":0,"hasNext":false,"hasPrev":false}
```
`?group=` **nối end-to-end THẬT** (chứng bằng 400 bind-error, không bằng lời khai).
⚠️ **2 quan sát KHÔNG hạ verdict, chuyển tiếp cho wave sau:**
1. **Chân-lý-rỗng còn nguyên (kế thừa K2):** `ContractSigningPlans` prod vẫn **0 dòng**`items:[]` với MỌI
group. Phép đo `?group=n` chứng được **đường ống + binding**, KHÔNG chứng được **lọc đúng nhóm**
backfill/lọc sai sẽ trông y hệt. Muốn có răng phải có ≥1 phiếu thật ở ≥2 nhóm khác nhau.
2. `?group=999`**200** (không phải 400/404): biên API vẫn không chặn ngoài-miền 1..8 — **y hệt K2 ghi
nhận**, chưa hồi quy nhưng cũng chưa đóng. Vô hại hôm nay vì bảng rỗng.
---
END sub-cicd-verify-k4ab — VERDICT=PASS 7/7
(1: run #438 success 6m23s match head_sha + #437 F-1 success 6m22s, chuỗi #436#437#438 liền mạch ·
2: gate 621 = 45D + 576I tách-phần, F-1 = 614 (+0) ⇒ trọn +7 thuộc K4, control ÂM Failed!=0 cả 2 log ·
3: Mig GIỮ 71 / top 20260731085624, 2 nguồn repo ⟂ prod ·
4: seed 49 menu + 637 perm + backfill 1 label — TAM-GIÁC 3 nguồn (source-parse ⟂ sqlcmd ⟂ Serilog
49+588=637), shape 8 nhóm × 6 kids element-wise, recycle-proof PID 4876→7020 + Serilog dòng đầu ·
5: A1 Procurement/Drafter 8-group + 48-leaf + menus/me materialize 8+42+6=56 qua EF; A5 restart ×2 THẬT
(PID 7020→220→6636) 8 chỉ số ĐỨNG IM + log-condition đã soi source ⇒ 0 added; revoker Hrm/Off giữ 29 ·
6: bundle JS ROTATE ×2 (1yiNV4VH→qOcoitOr · DoULfmdT→D9J3BbcA), 4 LM in-window, marker 3/3 khớp
(POS 4/4 · NEG 0/0 · DIFF admin 0 / user 2); marker lead gợi ý ĐO RA 1/1 ⇒ bác vì 0-bit ·
7: smoke 401/401 + 404 route bịa ×2 + 200 ×4; bind-error 400 chứng ?group= wire thật)

View File

@ -0,0 +1,27 @@
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 HEAD` lú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 truy `git log` xem `88e7ecf` nằm đâu trước khi tin base.
- 🔴 **RÀO GIT #1:** `git status``?? 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`: `88e7ecf` LÀ tổ tiên của HEAD ⇒ tiền-đề lead đúng về **nội dung**, sai về **tên mốc**: giữa `88e7ecf` và HEAD có **3 commit `wal: 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ên `git 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 `ff4d4dc` lúc đo-0 → `13f7f82` sau ~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.json` 44.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ằng `git 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.md` untracked (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 ③).
(đang tiếp tục §3)