wal: flush 20260801T1037
This commit is contained in:
@ -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)
|
||||
|
||||
|
||||
|
||||
@ -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` có `?? 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)
|
||||
Reference in New Issue
Block a user