[CLAUDE] Docs: S162 closeout - cay 4-folder GD ship prod + bookend-close 5 vong/10 vai
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 5m54s
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 5m54s
- Cay 4-folder giai doan duoi tung goi thau (bfc7b79, cicd PASS 5/5 Run #432)
- Bookend-close: H1 PASS_WITH_FLAGS · H2 GATE-FAIL 4 · H24 20 FLAG · trio MIXED
· ring1 26D/2T · ring2 19D/1T · harness-audit 43D/4T · ctx-audit TRUOT 7 FLAG
- Lead va trong phien: F-01/F-02/F-04 + A1 archive + A2 distill + skill KHKK
+ comment mirror self-ref (SHA-pair 6/6 giu, build x2 EXIT 0)
- MIND-5 = refresh @closeout dau tien (nhip thu 5, theo de ctx-audit)
- STATUS 3 row canonical + dong CURRENT · HANDOFF 6 slot danh so (54)-(59)
- gotcha #85 · error-ledger E-015/E-016 + AS-19/AS-20 · Phase 12 roadmap
- 4 errata khai thang: tally view-stale-count thoi 1 · enum thieu 1 class
· tong L1 lech 54 B · A2 tren trigger duong-gia (R10)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@ -0,0 +1,156 @@
|
||||
# sub-cicd-monitor-2 — verify deploy `bfc7b79` (S162 cây 4 folder GĐ, FE-ONLY)
|
||||
|
||||
> Ghi-đĩa-TRONG-lúc-làm (#53). Mỗi mục ghi NGAY khi đo xong. Kết bằng dòng `END … VERDICT=`.
|
||||
|
||||
## CHÂN 1 — Push + path-filter (Stage 1) ✅ ĐO 10:05:52
|
||||
|
||||
- HEAD = `bfc7b79f724998cc71a5e3307a1266f31b2e5731` · subject `[CLAUDE] FE-User+FE-Admin: cay 4 folder GD duoi tung goi thau (Duyet NCC / Ke hoach HD / Duyet HD / HD cung) x2 app + 5 fix review F-1/3/4/6/7`
|
||||
- Commit date `2026-07-30 10:04:32 +0700`
|
||||
- `git log origin/main..HEAD` = **EMPTY** ⇒ đã push thật.
|
||||
- Diff `HEAD~1..HEAD` = **17 file, +1839/−12**:
|
||||
- **12 file FE** = 6 fe-admin + 6 fe-user (đối xứng ×2 app): `components/pipeline/PipelineStageFolders.tsx` (MỚI), `components/pipeline/PipelineTreePanel.tsx`, `hooks/usePipelineStages.ts`, `pages/contracts/HardCopiesPage.tsx`, `pages/khkk/KhkkListPage.tsx`, `pages/pe/PurchaseEvaluationsListPage.tsx`
|
||||
- 5 file governance/run-trace: `.claude/agent-memory/frontend-designer/MEMORY.md`, `.claude/governance/.session-counter.json`, `runs/2026-07-30-S162-*/{run.md,ship-synthesis.md,sub-reviewer-1.md}`
|
||||
- **0 BE file · 0 migration** (`git diff --name-only HEAD~1 HEAD -- '*Migrations*'` = 0) ⇒ xác nhận FE-ONLY, **KHÔNG có chân EF-mig** (đúng brief).
|
||||
- Path-filter (`.gitea/workflows/deploy.yml` 7-glob): `fe-*/src/**.tsx|.ts` **KHÔNG khớp** glob nào ⇒ **CI PHẢI TRIGGER**. (`.session-counter.json` cũng không khớp `scripts/**.md`; nhưng FE file đã đủ trigger.)
|
||||
|
||||
**CHÂN 1 = PASS.**
|
||||
|
||||
## BASELINE PRE-DEPLOY (chụp 10:05:52, tức 80s sau commit — deploy ~5min nên đây là bundle CŨ)
|
||||
|
||||
| App | JS cũ | CSS cũ |
|
||||
|---|---|---|
|
||||
| admin.solutions.com.vn | `index-BBQKvUMa.js` | `index-BLUPWD4D.css` |
|
||||
| eoffice.solutions.com.vn | `index-BV5--mPf.js` | `index-HIRTruGh.css` |
|
||||
|
||||
**Xác thực "đúng là bundle CŨ"** (`curl -I`, đo 10:07):
|
||||
- admin `index-BBQKvUMa.js` → `Last-Modified: Wed, 29 Jul 2026 17:22:18 GMT` = **30-07 00:22:18 +0700** · `Content-Length: 1.734.048` · `ct=application/javascript`
|
||||
- user `index-BV5--mPf.js` → `Last-Modified: Wed, 29 Jul 2026 17:23:14 GMT` = **30-07 00:23:14 +0700** · `Content-Length: 1.650.214` · `ct=application/javascript`
|
||||
⇒ khớp mốc deploy W7 **#431** đêm qua, **trước** commit 10:04:32 ⇒ đây ĐÚNG là baseline PRE-deploy đợt này.
|
||||
|
||||
## ⚠️ ĐÍNH CHÍNH GIỮA CHỪNG — HEAD DI CHUYỂN (bẫy moving-target)
|
||||
|
||||
Lúc 10:12 phát hiện `git log -1 HEAD~1` trả về **chính bfc7b79** ⇒ HEAD đã nhảy sang commit mới `a07b942 wal: flush 20260730T1005` (10:05:59). Mọi phép đo dùng `HEAD~1` từ đây bị lệch 1 nấc.
|
||||
- **Sửa:** neo TUYỆT ĐỐI bằng SHA — parent thật của bfc7b79 = **`8eba137 wal: flush 20260730T0946`**. Diff `8eba137..bfc7b79` = **đúng 17 file / +1839−12** (khớp số đã ghi ở CHÂN 1 ⇒ CHÂN 1 vẫn ĐÚNG, chỉ lý-do-neo phải sửa).
|
||||
- `a07b942` chạm **3 file `.md`** (`WAL.md`, `agent-memory/reviewer/{MEMORY.md,archive/2026-07.md}`) ⇒ khớp glob `**/*.md` + `.claude/agent-memory/**` ⇒ **KHÔNG trigger CI**, và đang **UNPUSHED** ⇒ `origin/main == bfc7b79`, không có run thứ 2 chen ngang. ✅
|
||||
|
||||
## CHÂN 2-prep — CHỌN MARKER (grep repo-wide TRƯỚC, dự-đoán TRƯỚC khi đo)
|
||||
|
||||
Brief gợi ý 2 marker. Kiểm chứng cả 2 ở **parent `8eba137`**:
|
||||
- `git grep -c "pipeline-khkk-index" 8eba137 -- fe-user/src fe-admin/src` → **exit=1, 0 hit**
|
||||
- `git grep -c "Kế hoạch Hợp đồng" 8eba137 -- …` → **exit=1, 0 hit**
|
||||
- `git ls-tree 8eba137 -- */components/pipeline/` → **rỗng** ⇒ `PipelineStageFolders.tsx` là file **MỚI TINH** ở bfc7b79.
|
||||
⇒ **Cả 2 marker ĐỘC QUYỀN cho commit này** (không phải chuỗi dùng-chung có sẵn) ⇒ hợp lệ làm ship-proof DƯƠNG.
|
||||
|
||||
**Đếm ở source `bfc7b79` (mỗi app):**
|
||||
- `pipeline-khkk-index` = **1** (`hooks/usePipelineStages.ts:78` `queryKey`), ASCII ⇒ không lo unicode-escape.
|
||||
- `Kế hoạch Hợp đồng` = **3**, nhưng **2 nằm trong COMMENT** (`PipelineStageFolders.tsx:3` header-comment · `usePipelineStages.ts:188` comment `── GĐ2 ──`), chỉ **1 là CODE THẬT** (`PipelineStageFolders.tsx:24` `2: 'Kế hoạch Hợp đồng',`).
|
||||
|
||||
🔮 **DỰ ĐOÁN TRƯỚC KHI ĐO (khuôn comment-strip S159 #425):** bundle mỗi app phải có
|
||||
- `pipeline-khkk-index` ≥ 1
|
||||
- `Kế hoạch Hợp đồng` (hoặc dạng `\uXXXX` escape) = **1** (2 comment bị minifier cắt), **KHÔNG phải 3**.
|
||||
|
||||
**Marker thứ 3 (lấy từ `ship-synthesis.md`) — `pipeline-contract-index`:** parent `8eba137` = **0 hit**; ở `bfc7b79` = **2 file/app × 1** (`hooks/usePipelineStages.ts` + `pages/contracts/HardCopiesPage.tsx` — chính là F-7 invalidate).
|
||||
🔮 Dự đoán: bundle = **2/app** (khuôn "đúng-BỘI-SỐ = số FILE trong diff", S157) — caveat: nếu minifier gộp literal trùng thì còn 1; mốc CHẮC = ≥1.
|
||||
|
||||
## CHÂN 3-prep — chuẩn hoá tên endpoint health (đo 10:11, PRE-deploy)
|
||||
|
||||
| URL | code |
|
||||
|---|---|
|
||||
| `https://api.solutions.com.vn/health/live` | **200** |
|
||||
| `https://api.solutions.com.vn/health/ready` | **200** |
|
||||
| `https://api.solutions.com.vn/health` (bare) | **404** |
|
||||
⇒ đúng như đã biết: bare `/health` UNMAPPED. **404 ở đây là control ÂM tiện dụng — chứng 200 hai route kia CÓ NGHĨA, không phải catch-all.**
|
||||
|
||||
## CHÂN 2 — Gitea Actions run (poll)
|
||||
|
||||
- Match theo `head_sha` (KHÔNG theo run_number): **`id=545` · `run_number=432` · `head_sha=bfc7b79f7249…` · `name=build-deploy` · `event=push`**
|
||||
- URL: https://git.baocaogiaoduc.vn/vietreport-admin/solution-erp/actions/runs/432
|
||||
- Poll 30s/iter: 10:07:38 → 10:10:20 `status:"running"` (iter 1-6) → **iter 7 @10:10:52 `status:"success"`**, `updated_at 2026-07-30T10:10:32+07:00`. (`tasks` endpoint không populate `conclusion` ⇒ tin `status` — đã biết.)
|
||||
- **Duration ≈ 5m35s** (commit 10:04:32 → job succeeded 10:10:32). Nằm trong dải bình thường ~3-6min, KHÔNG cần escalate.
|
||||
|
||||
### Test gate (log web-UI `…/actions/runs/432/jobs/0/logs`, HTTP 200, 17.916 B)
|
||||
```
|
||||
03:05:07Z Passed! - Failed: 0, Passed: 45, Skipped: 0, Total: 45 — SolutionErp.Domain.Tests.dll (net10.0)
|
||||
03:07:37Z Passed! - Failed: 0, Passed: 545, Skipped: 0, Total: 545 — SolutionErp.Infrastructure.Tests.dll (net10.0)
|
||||
```
|
||||
⇒ **45 + 545 = 590 PASS · 0 fail · 0 skip** — khớp TÁCH-PHẦN đúng suite hiện hành brief nêu (FE-only nên số giữ nguyên, không delta). ✅
|
||||
|
||||
### Mốc deploy trong log (giờ UTC trong log = +0700 − 7)
|
||||
- `03:10:04Z ✓ built in 2.02s` (FE build xong)
|
||||
- `03:10:09Z Deploy done. App pool started.` = **10:10:09 +0700**
|
||||
- `03:10:23Z API /health/live -> 200` (gate health của chính CI)
|
||||
- `03:10:32Z 🏁 Job succeeded`
|
||||
|
||||
**CHÂN 2 = PASS** (run success + gate 590/0/0).
|
||||
|
||||
## CHÂN 3 — Bundle hash delta ×2 app (đo 10:11:5x, SAU status=success)
|
||||
|
||||
| App | asset | CŨ (10:05:52) | MỚI (sau deploy) | rotate? |
|
||||
|---|---|---|---|---|
|
||||
| admin | js | `index-BBQKvUMa.js` | **`index-DXoYDy7R.js`** | ✅ |
|
||||
| admin | css | `index-BLUPWD4D.css` | **`index-BZ5F-g1w.css`** | ✅ |
|
||||
| eoffice | js | `index-BV5--mPf.js` | **`index-o8KDluD1.js`** | ✅ |
|
||||
| eoffice | css | `index-HIRTruGh.css` | **`index-yNZDmVNz.css`** | ✅ |
|
||||
|
||||
**4/4 rotate** (mode-A #69). `index.html` admin: `Last-Modified: Thu, 30 Jul 2026 03:09:07 GMT` = **10:09:07 +0700 → IN deploy-window** · `Cache-Control: no-cache` (đúng hardening S88, shell luôn revalidate).
|
||||
Hash prod mới `o8KDluD1` ≠ local-build-đời-trước-fix `JKWooGXp` — đúng kỳ vọng brief (prod ship bản SAU 5 fix).
|
||||
|
||||
**Bundle MỚI là JS THẬT** (không phải SPA-fallback): `index-o8KDluD1.js` → `ct=application/javascript` **1.667.332 B** · `index-DXoYDy7R.js` → `ct=application/javascript` **1.751.166 B**.
|
||||
|
||||
**Control ÂM 3 TẦNG (khuôn S159 — chứng "200 ≠ tồn tại"):**
|
||||
| probe | HTTP | ct | size | đọc ra |
|
||||
|---|---|---|---|---|
|
||||
| eoffice `/assets/index-ZZZZZZZZ.js` (hash BỊA) | 200 | **text/html** | 876 | SPA-fallback ⇒ 200 trần vô nghĩa |
|
||||
| eoffice `/assets/index-BV5--mPf.js` (hash **CŨ**) | 200 | **text/html** | **876 — trùng khít hash bịa** | bundle cũ **đã biến mất khỏi đĩa** = bị ghi đè |
|
||||
| admin `/assets/index-BBQKvUMa.js` (hash **CŨ**) | 200 | **text/html** | **900 = đúng size `index.html` admin** | ghi đè |
|
||||
⇒ Không còn bundle cũ nào cache-được ⇒ **deploy ship THẬT**, không phải "action xanh mà file giữ nguyên".
|
||||
|
||||
**CHÂN 3 = PASS (4/4 hash rotate + ghi-đè chứng bằng control âm).**
|
||||
|
||||
## CHÂN 4 — Marker nội-dung trong bundle MỚI (đo trên file đã tải, đếm BYTE bằng python)
|
||||
|
||||
Đo cả 2 app (`index-o8KDluD1.js` 1.667.332 B · `index-DXoYDy7R.js` 1.751.166 B) — **kết quả GIỐNG HỆT nhau**, khớp tính đối-xứng 6+6 file trong diff:
|
||||
|
||||
| probe | dự đoán | eoffice | admin | |
|
||||
|---|---|---|---|---|
|
||||
| `pipeline-khkk-index` | ≥1 | **1** | **1** | ✅ |
|
||||
| `pipeline-contract-index` | **2** (= số FILE chứa nó trong diff) | **2** | **2** | ✅ đúng BỘI-SỐ |
|
||||
| `Kế hoạch Hợp đồng` (raw UTF-8) | **1** (3 ở source − 2 comment) | **1** | **1** | ✅ đúng y dự đoán |
|
||||
| dạng escape `ế…` / `ế…` | 0 (vì bundle giữ UTF-8 thô) | 0 | 0 | ✅ nhất quán |
|
||||
| **ÂM** `pipeline-hardcopy-index` (chuỗi BỊA, `git grep` ở `bfc7b79` = **0 hit**) | **0** | **0** | **0** | ✅ |
|
||||
|
||||
**Control ÂM mạnh nhất — ĐẾM TRỌN HỌ (self-validating):** regex `pipeline-[a-z-]{0,24}index` quét toàn bundle ⇒ tập thu được **đúng 3 phần tử** `{contract×2, khkk×1, pe×1}`.
|
||||
Đối chiếu source `bfc7b79`: `contract`=2 file · `khkk`=1 · `pe`=1 (`PipelineTreePanel.tsx`) ⇒ **khớp TỪNG phần tử, không thừa không thiếu**. Cả 3 đều **0 hit ở parent `8eba137`** ⇒ cả họ là hàng MỚI của commit này.
|
||||
⇒ vế DƯƠNG >0 bằng chính regex đó **trước** khi tin vế ÂM (đúng luật), và vế ÂM có 2 lớp: chuỗi-bịa cùng-hình-dạng = 0 · họ-đếm-trọn không có phần tử lạ.
|
||||
|
||||
⚠️ **1 chuỗi KHÔNG dùng làm control ÂM được — khai thẳng:** `Kế hoạch ký kết HĐ` (nhãn strip cũ) đếm được **8/app**. Đây **không phải lỗi**: `ship-synthesis.md` ghi rõ nhãn folder GĐ2 `Kế hoạch Hợp đồng` **CỐ Ý khác** nhãn strip `Kế hoạch ký kết HĐ`. Hai chuỗi **cùng tồn tại** ⇒ nếu tao lấy nó làm control-ÂM thì đã FAIL OAN (đúng bài học S159 #426: control ÂM phải ĐỘC QUYỀN). Ngược lại, việc `1` (nhãn mới) và `8` (nhãn cũ) cùng có mặt chính là bằng chứng phân-biệt-phiên-bản: bundle chứa **thêm** nhãn mới chứ không thay nhãn cũ.
|
||||
|
||||
**CHÂN 4 = PASS.**
|
||||
|
||||
## CHÂN 5 — Smoke (đo sau status=success)
|
||||
|
||||
| URL | HTTP | ct / size |
|
||||
|---|---|---|
|
||||
| `https://api.solutions.com.vn/health/live` | **200** | text/plain 7 B |
|
||||
| `https://api.solutions.com.vn/health/ready` | **200** | text/plain 7 B |
|
||||
| `https://admin.solutions.com.vn/` | **200** | text/html 900 B |
|
||||
| `https://eoffice.solutions.com.vn/` | **200** | text/html 876 B |
|
||||
| `https://api.solutions.com.vn/health` (bare, **control ÂM**) | **404** | — |
|
||||
CI tự đo trong log cũng khớp: `03:10:23Z API /health/live -> 200`. 404 của route bare chứng 3 con 200 kia CÓ NGHĨA.
|
||||
|
||||
**CHÂN 5 = PASS.**
|
||||
|
||||
## Ghi chú cho lần sau (đề xuất bổ sung MEMORY)
|
||||
|
||||
1. 🔴 **Bẫy MOVING-TARGET HEAD**: phiên có Stop-hook WAL tự commit ⇒ `HEAD~1` **đổi nghĩa giữa lượt verify**. Lượt này `HEAD~1` từ chỗ "cha của commit đích" biến thành "chính commit đích" trong ~6 phút. **Luật: verify commit X phải neo `X^..X` bằng SHA tuyệt đối, KHÔNG bao giờ dùng `HEAD~1`.** Lỗi này suýt làm tao kết luận ngược 180° (đã kết "2 marker có sẵn ở parent ⇒ vô giá trị", sự thật là **cả 2 đều 0 hit ở parent**).
|
||||
2. Khuôn **"đếm TRỌN HỌ bằng 1 regex"** (`pipeline-[a-z-]*index`) mạnh hơn đếm từng chuỗi rời: vừa cho vế DƯƠNG, vừa tự chứng regex không quét bừa (không có phần tử lạ), lại đối chiếu được element-wise với source.
|
||||
3. `paths-ignore` nuốt trọn commit `wal:` (toàn `.md` + `agent-memory/**`) ⇒ WAL-commit chen giữa **không** đẻ run rác. Xác nhận lại lần nữa ở lượt này.
|
||||
|
||||
---
|
||||
|
||||
**END verify `bfc7b79` (run #432 / id=545) — VERDICT=PASS 5/5** (CHÂN 1 push+filter · CHÂN 2 run success + gate 590 = 45+545 · CHÂN 3 bundle 4/4 rotate + ghi-đè · CHÂN 4 marker khớp dự-đoán + control âm 2 lớp · CHÂN 5 smoke 4×200 + control 404). FE-ONLY ⇒ không có chân EF-migration (0 file `*Migrations*` trong diff). 0 blocker, 0 khuyến nghị rollback.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user