wal: flush 20260729T1236
This commit is contained in:
@ -0,0 +1,231 @@
|
||||
# cicd-verify `1a47a61` — S159 ĐỢT-2 "tab strip 4 GĐ + menu 4-GĐ + đánh số 01-07 nhóm HĐ"
|
||||
|
||||
> Ghi-TỪNG-MỤC-trong-lúc-làm (chống #53). File = SẢN PHẨM CHÍNH; return chỉ tóm tắt.
|
||||
> Đợt-1 `b5799fc` (PASS 9/9) ở file `cicd-verify-b5799fc.md` — KHÔNG chạm.
|
||||
> Bắt đầu: 2026-07-29 ~12:07+07 · cicd-monitor (READ-only)
|
||||
|
||||
---
|
||||
|
||||
## M1 — Push + phạm-vi commit · ✅ PASS
|
||||
|
||||
```
|
||||
git log -1 → 1a47a61c21b62329c76bdef14a5daa9630c66db3
|
||||
[CLAUDE] FE-User: tab strip 4 giai doan tren phieu PE + menu 4-GD
|
||||
+ danh so 01-07 nhom HD (UAT anh Kiet) · 2026-07-29 12:06:19 +0700
|
||||
git log origin/main..HEAD → EMPTY (đã push)
|
||||
```
|
||||
|
||||
Range `b5799fc..1a47a61` = **2 commit / 10 file**; trong đó 2 file là
|
||||
`.claude/workflows/runs/**` (ignored) ⇒ **8 file CODE, 190+/18−** — khớp CHÍNH XÁC brief.
|
||||
|
||||
| File code | ± | loại |
|
||||
|---|---|---|
|
||||
| `fe-admin/src/components/pe/PePipelineStrip.tsx` | +65 | **MỚI** |
|
||||
| `fe-user/src/components/pe/PePipelineStrip.tsx` | +65 | **MỚI** (mirror) |
|
||||
| `fe-admin/src/components/pe/PeDetailTabs.tsx` | +3 | wire strip |
|
||||
| `fe-user/src/components/pe/PeDetailTabs.tsx` | +3 | wire strip |
|
||||
| `fe-user/src/components/Layout.tsx` | +5 | menu 4-GĐ |
|
||||
| `fe-user/src/pages/UserDashboardPage.tsx` | 18 ± | đổi nhãn GĐ2/GĐ3 |
|
||||
| `src/Backend/SolutionErp.Domain/Identity/MenuKeys.cs` | +7 | key mới |
|
||||
| `src/Backend/SolutionErp.Infrastructure/Persistence/DbInitializer.cs` | +42/− | **seeder-only** |
|
||||
|
||||
⇒ BE có đụng nhưng **0 controller/service, 0 migration** — chỉ hằng-số key + seeder.
|
||||
`fe-admin` CÓ sửa ⇒ **admin bundle PHẢI rotate** (khác đợt-1 nơi admin rotate là do #69 mode-A).
|
||||
|
||||
**Mirror md5 (kiểm chứng "mirror md5-identical" trong brief):**
|
||||
```
|
||||
ef7b782409d02b5a6a2f1bf4c2e97b42 fe-admin/src/components/pe/PePipelineStrip.tsx
|
||||
ef7b782409d02b5a6a2f1bf4c2e97b42 fe-user/src/components/pe/PePipelineStrip.tsx
|
||||
```
|
||||
✅ **BYTE-IDENTICAL** — 2 app dùng đúng 1 nội dung, không lệch bản.
|
||||
|
||||
## M2 — Migration VẮNG là ĐÚNG · ✅ PASS
|
||||
|
||||
```
|
||||
git diff --name-only b5799fc..1a47a61 -- '*Migrations*' → 0 dòng
|
||||
```
|
||||
BE-change chỉ là `MenuKeys.cs` (const) + `DbInitializer.cs` (seeder runtime) ⇒ **không sinh schema**.
|
||||
Mig prod kỳ vọng đứng nguyên **68** / 89 bảng. Thay đổi menu đi qua **SEEDER lúc app khởi động**,
|
||||
nên rủi ro thật nằm ở M7 (double-insert / đè nhãn), KHÔNG ở `__EFMigrationsHistory`.
|
||||
|
||||
## Pre-deploy bundle snapshot (chốt TRƯỚC khi deploy land)
|
||||
|
||||
Đo **2026-07-29 12:07:19+07** (run #423 vừa start, chưa tới step deploy):
|
||||
|
||||
| App | js | css | HTTP |
|
||||
|---|---|---|---|
|
||||
| admin | `index-BHodkPNV.js` | `index-DiNJjaoo.css` | 200 |
|
||||
| user | `index-0GO8mgrG.js` | `index-BARVqkP-.css` | 200 |
|
||||
|
||||
✅ Khớp CHÍNH XÁC baseline hậu-đợt-1 ⇒ baseline hợp lệ, đợt-2 chưa land.
|
||||
|
||||
## M-src — Marker kỳ vọng, đếm trên SOURCE (chốt trước khi soi bundle)
|
||||
|
||||
Đếm BYTES utf-8. (Bài học đợt-1: occurrence trong COMMENT bị minifier strip ⇒ đối chiếu occurrence-CODE.)
|
||||
|
||||
| Chuỗi | UserDashboardPage | PePipelineStrip (user) | PePipelineStrip (admin) | vai trò |
|
||||
|---|---|---|---|---|
|
||||
| `Kế hoạch ký kết HĐ` | 2 | 2 | 2 | dương |
|
||||
| `Hợp đồng cứng` | 2 | 3 | 3 | dương |
|
||||
| `Toàn trình 4 giai đoạn` | 1 | 1 | 1 | dương (giữ từ đợt-1) |
|
||||
| `Đề xuất ký kết hợp đồng` | **0** | **0** | **0** | ÂM — nhãn cũ đợt-1 đã đổi |
|
||||
| `Ký cứng & phát hành` | **0** | **0** | **0** | ÂM |
|
||||
|
||||
## M3 — Poll terminal · ✅ PASS
|
||||
|
||||
- **id=536 · run_number=423 · head_sha `1a47a61c`** · created 12:06:25 → **`status=success` 12:12:09**
|
||||
- **Duration 5m44s** (đợt-1 5m59s) — trong dải bình thường.
|
||||
- kề trên: #422 id=535 `b5799fc` success (đợt-1) ⇒ hai run tách bạch, không nhầm.
|
||||
|
||||
### M3b — Test gate · ✅ 562 EXACT
|
||||
`…/actions/runs/423/jobs/0/logs` (17.737 ký tự):
|
||||
```
|
||||
Passed! - Failed: 0, Passed: 45, Skipped: 0, Total: 45, 167 ms - SolutionErp.Domain.Tests.dll
|
||||
Passed! - Failed: 0, Passed: 517, Skipped: 0, Total: 517, 1m26s - SolutionErp.Infrastructure.Tests.dll
|
||||
```
|
||||
`Failed!` ×0. **45+517 = 562**, khớp cả TỔNG lẫn TÁCH-PHẦN. Delta 0 — đúng cho commit không kèm test mới.
|
||||
|
||||
## M4 — Bundle rotate · ✅ PASS 4/4 (đo 12:12:38+07)
|
||||
|
||||
| App | asset | TRƯỚC (hậu đợt-1) | SAU | KQ |
|
||||
|---|---|---|---|---|
|
||||
| **admin** | js | `BHodkPNV` | **`D6Pz7nfV`** | ✅ **ROTATE** (bắt buộc — `fe-admin` CÓ sửa) |
|
||||
| admin | css | `DiNJjaoo` | **`B1ErASuI`** | ✅ ROTATE (utility mới của strip) |
|
||||
| **user** | js | `0GO8mgrG` | **`Bpb8WEuY`** | ✅ **ROTATE** |
|
||||
| user | css | `BARVqkP-` | **`7oAYFlzM`** | ✅ ROTATE |
|
||||
|
||||
⚠️ Khác đợt-1 ở chỗ: đợt-1 admin-css FROZEN vì 0 admin-src; đợt-2 admin-css rotate vì strip mang class mới
|
||||
⇒ hình-dạng rotate **nhất quán với nội dung diff**, không phải nhiễu #69.
|
||||
|
||||
Artifact thật:
|
||||
```
|
||||
USER index-Bpb8WEuY.js ct=application/javascript size=1.585.946 LM=12:11:43+07 (in-window)
|
||||
ADMIN index-D6Pz7nfV.js ct=application/javascript size=1.676.677 LM=12:10:45+07 (in-window)
|
||||
```
|
||||
|
||||
## M5 — Byte-marker 2 bundle · ✅ PASS (6/6 dương EXACT · 4/4 âm VẮNG)
|
||||
|
||||
| Chuỗi | USER bundle | ADMIN bundle | Kỳ vọng |
|
||||
|---|---|---|---|
|
||||
| `Kế hoạch ký kết HĐ` | **2** | **1** | dương ✅ |
|
||||
| `Hợp đồng cứng` | **2** | **1** | dương ✅ |
|
||||
| `Toàn trình 4 giai đoạn` | **2** | **1** | dương ✅ |
|
||||
| `Đề xuất ký kết hợp đồng` | **0** | **0** | ÂM ✅ (nhãn đợt-1 đã đổi) |
|
||||
| `Ký cứng & phát hành` | **0** | **0** | ÂM ✅ |
|
||||
|
||||
🔑 **Quy luật đếm rút ra (nối tiếp bài học comment-strip đợt-1): bundle-count = SỐ MODULE chứa chuỗi**
|
||||
(bundler pool hằng-số chuỗi trong 1 module → nhiều occurrence cùng file gộp còn 1):
|
||||
- USER = 2 module chứa marker (`PePipelineStrip.tsx` + `UserDashboardPage.tsx`) ⇒ **2** ✅
|
||||
- ADMIN = 1 module (`PePipelineStrip.tsx`; `Layout.tsx` chỉ thêm route `'/dashboard'`, KHÔNG chứa nhãn) ⇒ **1** ✅
|
||||
|
||||
Đúng cho **cả 3 marker × 2 app = 6/6**, tức "đúng-BỘI-SỐ" chứ không chỉ "tìm thấy ≥1".
|
||||
Kiểm chứng phụ: `grep -rn` 2 chuỗi ÂM trên toàn `fe-user/src` + `fe-admin/src` = **0 hit** ⇒ marker âm vắng ở bundle là do mã đã gỡ, không phải do đọc sai.
|
||||
|
||||
**Control ÂM 2 tầng (cả 2 app):** hash CŨ (`0GO8mgrG` / `BHodkPNV`) **và** hash bịa đều trả 200 nhưng
|
||||
`ct=text/html` 876 B (user) / 900 B (admin) ⇒ bundle cũ **biến mất khỏi đĩa** = chứng ghi-đè thật.
|
||||
|
||||
## M6 — Smoke · ✅ PASS 4/4
|
||||
```
|
||||
/health/live 200 Healthy · /health/ready 200 Healthy · admin 200 · eoffice 200
|
||||
```
|
||||
|
||||
## M7 — Menu-data prod sau app-pool recycle · ✅ 5/5 mục được giao
|
||||
|
||||
**(a) Root count — chống double-insert:** `SELECT COUNT(*) FROM MenuItems WHERE ParentKey IS NULL` = **12** ✅ (không 13/14).
|
||||
Bổ sung: **`DUPKEYS=0`** (không key nào lặp) · `MENUTOTAL=107`.
|
||||
|
||||
**(b) 2 root mới đúng vị trí:**
|
||||
```
|
||||
KeHoachKyKet ord=26 IsVisible=1 ✅
|
||||
HopDongCung ord=32 IsVisible=1 ✅
|
||||
```
|
||||
Permission 2 root mới: mỗi key **13 rows / 13 canread** — đúng 13 role × 1, **không nhân đôi** ✅
|
||||
|
||||
**(c) 3 root vẫn ẩn:** `Hrm` ord28 vis=**0** · `Off` ord29 vis=**0** · `Personal` ord30 vis=**0** ✅
|
||||
|
||||
**(d) 2 root đã rename** (đối chiếu prefix, KHÔNG so byte VN qua console): `PurchaseEvaluations` và
|
||||
`Contracts` đều bắt đầu `Duy…` (= "Duyệt NCC" / "Duyệt hợp đồng") ✅
|
||||
|
||||
**(e) 7 nhãn đánh số CÒN NGUYÊN** (backfill silent vì equal):
|
||||
```
|
||||
Ct_ThauPhu 01. · Ct_GiaoKhoan 02. · Ct_NhaCungCap 03. · Ct_DichVu 04.
|
||||
Ct_MuaBan 05. · Ct_NguyenTacNcc 06. · Ct_NguyenTacDv 07.
|
||||
```
|
||||
**(f) Control ÂM `Pe%`:** rows=**197** canread=**185** ✅ EXACT (seeder không đụng vùng PE — đúng comment code).
|
||||
|
||||
---
|
||||
|
||||
## 🔴 M8 — PHÁT HIỆN NGOÀI CHECKLIST: grant 38-key của ĐỢT-1 ĐÃ BỊ REVOKE · ❌ FAIL
|
||||
|
||||
Trong lúc soi Serilog để chứng minh seeder có chạy thật, bắt được dòng:
|
||||
```
|
||||
2026-07-29 12:12:00.028 +07:00 [INF] Revoked 9 permission rows — … HRM/Văn phòng số/Cá nhân/
|
||||
Hợp đồng/Danh mục khỏi non-Admin (chỉ Admin thấy — S58 + S92)
|
||||
```
|
||||
⇒ đi đo lại grant-set 38 key mà đợt-1 đã áp tay lúc 11:15:
|
||||
|
||||
| Thời điểm | Đo được |
|
||||
|---|---|
|
||||
| **11:46** (đợt-1, **TRƯỚC** khi pool restart) | 38 key · min=max=**13/13** · tổng 494 canread |
|
||||
| **12:14** (sau restart đợt-2) | 38 key · **min=1 max=2** · tổng **47/494** — **0 key nào còn 13** |
|
||||
|
||||
Phân bố còn lại: **`Admin`=38 · `Procurement`=9 · 11 role còn lại = 0.** ⇒ mất **447/494** canread.
|
||||
|
||||
**Nguyên nhân (đọc code, không suy đoán)** — `DbInitializer.cs:2203-2236`
|
||||
`RevokeTemporarilyHiddenModulesAsync`, chạy **mỗi lần app khởi động, KHÔNG có cờ gate**:
|
||||
```csharp
|
||||
.Where(p => p.RoleId != adminRoleId
|
||||
&& (p.MenuKey.StartsWith("Hrm") || p.MenuKey.StartsWith("Off")
|
||||
|| p.MenuKey == MenuKeys.Personal
|
||||
|| p.MenuKey == MenuKeys.Contracts || p.MenuKey.StartsWith("Ct_")
|
||||
|| p.MenuKey == MenuKeys.Master || p.MenuKey == MenuKeys.Suppliers
|
||||
|| p.MenuKey == MenuKeys.Projects|| p.MenuKey == MenuKeys.Departments
|
||||
|| p.MenuKey.StartsWith("Catalog"))
|
||||
&& (p.CanRead || p.CanCreate || p.CanUpdate || p.CanDelete))
|
||||
… row.CanRead = false; row.CanCreate = false; row.CanUpdate = false; row.CanDelete = false;
|
||||
```
|
||||
Tập revoke **TRÙNG KHỚP CHÍNH XÁC** grant-set 38 key (Contracts + `Ct_*` + Master/Suppliers/Projects/
|
||||
Departments/`Catalog*`). ⇒ **Grant tay 11:15 về bản chất KHÔNG BỀN: mỗi lần app restart là bị gỡ lại.**
|
||||
Đây đúng mẫu `feedback_wipe_durability_check_reseed` — nhưng CHIỀU NGƯỢC: data-change thủ công bị
|
||||
**seeder/revoker ungated** ăn mất, thay vì seed ungated tự mọc lại.
|
||||
|
||||
**⚠️ Tự đính chính đợt-1 (KHÔNG sửa file đợt-1 theo yêu cầu):** mục M7 file `cicd-verify-b5799fc.md`
|
||||
đo lúc **11:46**, mà pool restart của run #422 xảy ra ~**11:49** ⇒ phép đo đó nằm **TRƯỚC** recycle,
|
||||
nên câu "App pool recycle không hề đụng menu-data" trong file đợt-1 **chưa được chứng minh** và nay
|
||||
đã bị bác. 3 root ẩn + `Pe%` 197/185 vẫn đúng (nằm ngoài / miễn nhiễm), **chỉ phần grant 38-key sai.**
|
||||
(`Hrm/Off/Personal` bị revoke cũng vô hại vì chủ đích chính là ẩn chúng.)
|
||||
|
||||
**Vì sao log chỉ có 1 dòng `Revoked`:** step deploy `Remove-Item …\api\* ` xoá luôn thư mục `logs`,
|
||||
nên log hiện chỉ chứa từ 12:12 trở đi ⇒ **không thể dùng log để quy trách nhiệm cho restart 11:49 hay 12:12**;
|
||||
điều chắc chắn là revoker ungated và trạng thái HIỆN TẠI đã mất grant.
|
||||
|
||||
**Khuyến nghị (KHÔNG tự sửa — READ-only, escalate em main):**
|
||||
1. Grant 38-key muốn BỀN thì phải sửa **code** `RevokeTemporarilyHiddenModulesAsync` (thu hẹp tập, hoặc
|
||||
thêm env-flag gate), **không** áp SQL tay — SQL tay sẽ chết ở lần deploy kế.
|
||||
2. Sau khi sửa, nghiệm thu bắt buộc bằng **restart THẬT** rồi mới đo (không đo trước recycle).
|
||||
3. Không rollback `1a47a61` — regression này **không do đợt-2 gây ra**, đợt-2 ship đúng.
|
||||
|
||||
---
|
||||
|
||||
## VERDICT: **PARTIAL — 8/9**
|
||||
|
||||
| # | Mục | KQ |
|
||||
|---|---|---|
|
||||
| 1 | Push + range 8 file code 190+/18− + mirror md5 identical | ✅ |
|
||||
| 2 | Migration VẮNG là ĐÚNG (0 file `*Migrations*`) | ✅ |
|
||||
| 3 | Run #423 success 5m44s | ✅ |
|
||||
| 4 | Test gate **562** (45+517, 0 fail) | ✅ |
|
||||
| 5 | Bundle rotate 4/4 (admin js+css **bắt buộc** đổi, user js+css) | ✅ |
|
||||
| 6 | 3 marker dương USER + 3 dương ADMIN, count = số-module EXACT | ✅ |
|
||||
| 7 | 2 control ÂM vắng ở cả 2 bundle + control hash-cũ/bịa `text/html` | ✅ |
|
||||
| 8 | Smoke health ×2 + FE ×2 · menu-data 5/5 mục được giao · 0 double-insert (root=12, dupkeys=0) | ✅ |
|
||||
| 9 | **Grant 38-key đợt-1 sống sót recycle** | ❌ **FAIL — còn 47/494, mất 447** |
|
||||
|
||||
**Đợt-2 (`1a47a61`) tự nó SHIP ĐÚNG HOÀN TOÀN — không khuyến nghị rollback.**
|
||||
Cờ đỏ số 9 là **hệ quả cấu trúc của revoker ungated có sẵn**, chỉ lộ ra khi app restart; cần fix bằng CODE.
|
||||
|
||||
Baseline mới sau đợt-2: admin js `D6Pz7nfV` / css `B1ErASuI` · user js `Bpb8WEuY` / css `7oAYFlzM`;
|
||||
gate 562; Mig 68 / 89 bảng (không đụng); menu root = 12.
|
||||
|
||||
<!-- END cicd-verify-1a47a61 · VERDICT=PARTIAL 8/9 -->
|
||||
|
||||
@ -51,7 +51,26 @@
|
||||
- [x] **Đ2-e — build FE ×2 PASS + test 562 PASS** (seeder đụng ⇒ chạy đủ) → **commit `1a47a61` push** (8 file, 190+/18−)
|
||||
- [!] **Đ2-f — cicd verify `1a47a61`** đang chạy (kèm check seeder-re-run không double-insert: 12 root, 7 nhãn `01.` nguyên)
|
||||
|
||||
🔸 fe-admin sidebar: 2 root placeholder sẽ **drop silent** (không thêm staticMap admin — cố ý, admin không cần placeholder; ghi để khỏi đọc thành bug)
|
||||
🔸 fe-admin sidebar: ~~2 root placeholder drop silent~~ → **đổi @đợt-3**: admin CÓ staticMap + ComingSoonPage (skeleton có con ⇒ group rỗng bên admin sẽ xấu; mirror luôn cho sạch).
|
||||
|
||||
## ĐỢT-3 — ảnh thứ 2 của anh + 🔴 SỰ CỐ REVOKER (phát hiện đắt nhất arc)
|
||||
|
||||
**Owner verbatim (ảnh 2, ~11:4x):** ① *"Cho viết hoa - Bên trong cũng phân các list ra tương tự như duyệt NCC"* (→ Kế hoạch ký kết HĐ) ② *"Thêm Sub và đánh số như Duyệt Hợp đồng, viết hoa và các danh sách tương tự như Duyệt NCC"* (→ Hợp đồng cứng).
|
||||
|
||||
- [x] **Đ3-a — skeleton menu prod**: 12 row (`Khkk_G1`+4 leaves khuôn Duyệt-NCC · `Hdc_×7` tái dùng nhãn 01.-07.) + `perm=156` (=12×13). Root có con ⇒ **uppercase tự động** (Layout `:247`). Đo: khkk_con=5 · hdc_con=7 ✅
|
||||
- [x] **Đ3-b — `ComingSoonPage` mirror ×2** (md5 `6aaa7f87…`): PePipelineStrip current=stage + mô tả + banner "cấu trúc menu hiển thị trước để mọi người góp ý" + Quay-lại `navigate(-1)` (không phụ thuộc route riêng app) · route `/coming-soon` ×2 · staticMap **11 leaf** ×2 (query riêng từng mục giữ active-state — gotcha #50)
|
||||
|
||||
### 🔴🔴 SỰ CỐ — grant 38-key đợt-1 BỊ REVOKE ở app-restart #423 (cicd đợt-2 mục 9, FAIL 8/9)
|
||||
|
||||
- **Đo:** còn 47/494 canread (Admin=38 · Procurement=9 · **11 role = 0**) — mất **447 dòng**. Gốc: `DbInitializer.cs:2203-2236` `RevokeTemporarilyHiddenModulesAsync` **UNGATED mỗi startup**, tập revoke (nhánh **[S92 2026-06-29]** *"anh chốt chỉ Admin thấy"*) **trùng khớp chính xác** grant-set 38 key.
|
||||
- **Bản chất:** owner hôm nay (❹ *"hiển thị hết để mọi người góp ý"*) **SUPERSEDE chính quyết định S92 của owner** — code còn thi hành quyết cũ. Đúng **chiều-ngược gotcha #75/#76** (`wipe-durability` S91): seeder ungated thắng data-change tay; đổi trạng thái bền = đổi CODE, nghiệm thu = **restart THẬT**.
|
||||
- 🔴 **Lỗi quy trình của LEAD (nhận):** grant SQL đợt-1 mà **không audit seeder cho revoker ngược** — memory `feedback_wipe_durability_check_reseed` có sẵn bài này, em áp chiều re-add mà không soi chiều revoke. Máy không bắt được; `cicd-monitor` bắt nhờ **đo-sau-restart** + tự đính chính M7 đợt-1 của chính nó (*"đo lúc 11:46, pool recycle ~11:49 ⇒ claim durability chưa từng được chứng minh"*).
|
||||
- **Xử 2 nhịp:** ① re-grant SQL ngay `regrant=447` → 38/38 = 13/13 (user mất menu ~vài phút quanh #423) ② **gỡ nhánh [S92] khỏi revoker** (giữ Hrm/Off/Personal — ý ❸) + grant bền `reviewKeys += ContractMenuKeys()+MasterMenuKeys()+KhkkKeys()+HdcKeys()` (fresh-env hội tụ; prod đi đường SQL vì nhánh grant key-thường là skip-existing không nâng row false).
|
||||
- **Đối chứng thuận:** `Khkk_/Hdc_` (156 perms) **không match prefix revoker** ⇒ sống qua #423 — giải thích vì sao menu 4-GĐ + nhãn 01-07 nguyên mà chỉ bộ 38-key rơi.
|
||||
|
||||
- [x] **Đ3-c — spec-change 3 test** (S92→S159, *"update test cũ + code chung commit"*): `AdminOnlyModulesRevokeTests` tách `StillHiddenKeys`(3) ⟂ `ReopenedKeys`(8) + ⭐ **REGRESSION-GUARD**: re-add nhánh S92 vào predicate ⇒ test đỏ ngay · `ProcurementMasterAccessSeedTests` ×2 đọc lại isolation bằng **CỜ CAO** (CanRead all-role giữ true). **517/517 PASS lại.**
|
||||
- [x] **Đ3-d — commit `2a72695` push** (9 file, 234+/27−)
|
||||
- [!] **Đ3-e — cicd verify `2a72695`**: mục CHÍNH = **restart-durability 6(a)** — 38-key phải GIỮ 13/13/38 **SAU** `status=success` (đúng bài M7); control âm 6(c) Hrm/Off/Personal vẫn 0.
|
||||
- [x] **T2 — Prod menu data** ✅ **LIVE + VERIFY TRỌN** (`prod-backup-pre-apply.txt` → apply `hide=3 upd=99 ins=376` → `prod-verify-post-apply.txt`):
|
||||
· Inspect lộ thực-trạng ≠ giả định: Master subtree có matrix 13-row/key (canread 2/13) nhưng **`Ct_*` 28 key = 0 ROW** (chưa từng seed), `Contracts` root 1 row ⇒ INSERT 376 + UPDATE 99, số khớp toán từng đồng (9×11=99 · 28×13+12=376)
|
||||
· Verify: **38/38 key min=max=13 canread** · 3 root `IsVisible=0` · control âm **Pe_* 197/185 NGUYÊN** (❹ "để như cũ") · `Hrm_Config*` canread=7 nguyên (vùng đang-làm loại khỏi grant, đúng ý ❸)
|
||||
|
||||
Reference in New Issue
Block a user