# CI/CD Monitor — Archive 2026-07 (verbatim, FROZEN additive-only) > Curated L1→L2 by em-main (S98 2026-07-02 — garble-pressure #53 structural: L1 19.9KB > self-target 17.1KB). Records moved from `MEMORY.md` **content-exact (terminator normalized CRLF→LF — V3 verified sha-match trên text nội dung)**; L1 keeps compressed stubs + 🔑 pattern-keys. Lookup: `archive/_INDEX.md`. NEVER rewrite existing bytes; append-only. --- - **🟢🟢 S96+S97 FINAL-SESSION-REVIEW (2026-07-01 end, em main "review kỹ trước đóng session") — 11-commit day (S96 #478-480 + S97 #481-484 + docs closeouts) ALL-DEPLOYED-HEALTHY, verdict CLEAN.** HEAD=`5c914e4` (docs-only) → latest code=`fb2dfa9` #484. Re-verified whole-session GO on LIVE prod: **Gitea recent tasks ALL status=success** #478→#484 (no stuck/cancelled/fail; #484 21:30:36→21:35:49 in-baseline ~5m). **Mig 61 APPLIED-PROD** (`__EFMigrationsHistory` top==`20260701142752_BackfillEndedByLevelFinalizeFromChangelog`, pre=Mig60). **BACKFILL RE-CONFIRMED** A/005=1,A/008=1,A/010=0 (global flag-dist: 2×`=1` + 11×`=0` = exact target set, no over-reach). **sys.tables=88 excl-EFHistory / 89 incl** (⚠️ RECONCILE: S97-note-89 counted WITH `__EFMigrationsHistory`; 88+1=89 CONSISTENT no-drift; data-only Mig61 count-unchanged=correct). **Health 4×200** (ready/live/admin-root/eoffice-root). **Auth-login OK** token-len 468, **PE-list 200** (5KB items valid), menus/suppliers 200. **SignalR WIRED** bodyless-POST→411 (IIS Length-Required pre-auth NOT 404) · with-body→**200 full negotiate JSON** (connectionId+WebSockets transport) · no-auth→401 (JwtBearer challenge OK) — gotcha #25 clear. **BE ship-proof** `SolutionErp.Infrastructure.dll` mtime **21:31:39 in-#484-window** + w3wp fresh PIDs 21:32:41/21:35:25 (recycle happened). **⚠️ BUNDLE ROTATED AGAIN since #484-entry**: admin js **`mEGqlNWc`** (was `CeTA7Z82`) / user js **`Dnrp4PU1`** (was `CGaAyXen`) · CSS FROZEN admin `Bbtesa6B`/user `BmuPz_Dy`. Both REAL (admin 1637596b / user 1543944b vs SPA-trap-control `ZZfake…`→919b) · Last-Modified admin 14:34:26Z=21:34:26+07 / user 14:35:20Z=21:35:20+07 BOTH in-#484-window · immutable-max-age-1y. **⟹ #69 CONFIRMED: unconditional FE-rebuild rotates hash EVERY deploy even DATA-FIX commit (0 `fe-*/src` diff) — rotation=deploy-artifact NOT ship-signal; real-FE-ship = diff fe-src + real-size + Last-Modified-in-window (all satisfied by #483 real badge-FE + #484 benign-rotate).** 🔑 **WHOLE-SESSION GO = every-commit-CI-success + Mig-top==HEAD + backfill-exact + control-untouched + 4×health-200 + auth+PE+SignalR-wired + BE-dll+w3wp-in-window + bundles-real-in-window.** ⚠️ tooling: w3wp `$_.StartTime` mangled thru nested ssh→PS (S42) → base64-EncodedCommand fixed; sys.tables 2-variants to reconcile EF-history inclusion. - **🟢 S97 #484 (id=484, run_number 370) `fb2dfa9` GO ~5m (PASS) — DATA-FIX Mig 61 backfill EndedByLevelFinalize từ Changelogs (fix Mig 60 soi NHẦM bảng), phiếu finalize-CCM hết hiện sai "Đã được CEO duyệt", anh Kiệt FDC UAT.** 3 files: **Mig 61 `20260701142752_BackfillEndedByLevelFinalizeFromChangelog`**+Designer (data-only NO-schema, chỉ `Sql()` UPDATE set=1 cho phiếu có finalize-marker ở `PurchaseEvaluationChangelogs`) + docs/gotchas.md. Poll running→success ~21:31→21:36:28 (~5m in-baseline; ⚠️ `started_at/stopped_at`=None trong tasks API). status=success ⟹ test-gate green (baseline **440**). 🔴🔴 **BACKFILL EFFECT VERIFIED-PROD (điểm quan trọng nhất) sqlcmd `SELECT MaPhieu,EndedByLevelFinalize WHERE Phase=7`**: **A/005=1, A/008=1** (finalize-CCM set 0→1 = fix ăn) · **A/010=0** (CEO thật giữ nguyên = control OK, backfill KHÔNG over-reach). 🔴 **Mig 61 APPLIED-PROD**: `__EFMigrationsHistory` top==Mig61 (pre=Mig60, advanced). 🔴 **endsBeforeCeo FLIP LIVE (API)**: A/005 `3da9b890` → `endsBeforeCeo=True` (trước False = exact-bug-fix) · A/010 `31faef0d` → `False` (control). ⚠️ DTO field `endedByLevelFinalize`=None (không expose shape này) NHƯNG derived `endsBeforeCeo` phản-ánh col-DB=1 đúng ⟹ verify col qua sqlcmd NOT DTO. 🎯 **DATA-FIX ⟹ NO-FE-change**: không snapshot bundle (0 `fe-*/src` diff; #69 rotate benign nếu có ≠ ship-signal). Smoke: api-ready/admin-root/eoffice-root 200×3 + `GET /purchase-evaluations` **200** (list không vỡ). 🔑 **DATA-FIX-BACKFILL PASS = CI-success + Mig-top==HEAD + sqlcmd-target-rows-flip-EXACT(A/005+A/008=1) + control-untouched(A/010=0) + derived-API-field-FLIP-live + smoke-200**. ⚠️ tooling: busy-wait favicon-spin ~10s/iter(40×)=TOO-SLOW → 250×/iter≈50s hit terminal; integrated-auth `-E` `-h -1 -W`; A/010-id qua sqlcmd-inline-lookup. - **🟢 S103 #487 (rn 373) `f0874dd` GO ~4m (13:54:31→~13:58) — GOVERNANCE/SCRIPTS-ONLY (28 file = 25 docs/.md ignored + 3 non-ignored trigger #41: `memory-budget.json` + `scripts/{crystallized-backfill,applied-eval-nokey}.ps1`; 0 .cs/.csproj/fe-src/Mig):** status=success (test gate 440 passed, `conclusion=None` quirk on tasks-endpoint = trust success) · Mig 61 frozen `__EFMigrationsHistory` top==repo-HEAD (0 mig added) · smoke 200×6 (api/ready + admin/root + eoffice/root + auth accessToken-len468 + PE-list + contracts + menus) · SignalR bodyless-411 / empty-token-401 = wired+gated (out-of-scope, 0 noti code) · bundle hash **FROZEN** 2 app (admin `mEGqlNWc`/`Bbtesa6B` + user `Dnrp4PU1`/`BmuPz_Dy` = #486 baseline) + Last-Modified in-window 13:58:33/13:59:29+07 + real-size 1.64/1.54MB vs fake-919b SPA-control = ship-proof. **#69-REFINE ×4** (#333→#485→#486→#487): 0 fe-src diff ⟹ hash frozen + fresh copy. GOVERNANCE-PASS stable ×4 (#476/#485/#486/#487). ⚠️ poll.py break-cond on `conclusion` null-check over-spun 6 iter after status=success reached iter4 — FIX break-cond to `status==success` OR `completed`, not conclusion-populated. - **🟢 S100 #486 (rn 372) `5ee32c0` GO 5m17s (15:32:11→15:37:28) — GOVERNANCE-ONLY (19 file = 18 .md/docs ignored + `scripts/governance-detectors.ps1` non-ignored → trigger #41; 5 docs-only commits trước [525a01a…513aa09] đúng 0-run):** Mig 61 frozen history-top + sys.tables 89 · smoke 200×7 (health-ready/admin/eoffice + auth accessToken + PE-list + contracts + menus) · bundle hash **FROZEN** 2 app + Last-Modified in-window 15:36:08/15:37:01+07 + real-size 1.64/1.54MB vs fake-919b control = ship-proof. **#69-REFINE ×3** (#333→#485→#486): 0 fe-src diff ⟹ hash frozen + fresh copy. GOVERNANCE-PASS stable ×3 (#476/#485/#486). 🔧 Poll: python `time.sleep` in-script chạy ĐƯỢC foreground (chỉ bash `sleep` builtin bị block) — hết cần busy-wait spin. - **🟢 S107 #489 (rn 375, id 489) `21387cd` GO 5m33s (09:28:08→09:33:41+07, poll iter8) — GOVERNANCE-ONLY 14-file (+office-document 12th sub agent+skill+roster wiring; `hmw.js`+`memory-budget.json` non-ignored → #41 CI-run; prior `1eea51b` .md-only NO-run đúng filter):** status=success (gate 440, conclusion=null quirk) · 0 BE/FE src ⟹ **Mig FROZEN 62** `ExpandSupplierFields` history-top + **sys.tables=89** ✓ · smoke health/admin/eoffice **3×200** · **bundle JS ROTATED-benign** admin `ChSNAJBK`→`BVyH-FY7` / user `Bn2w1znH`→`EDsZebvn`, CSS frozen ×2 + real-size 1.64/1.55MB application/javascript + LM-in-window 09:32:12/09:33:07+07 vs fake-control 919b-text/html = REAL-ship. 🔑 **#69 TWO-MODE CONFIRMED: governance 0-fe-src có thể ROTATE (#312+#489) hoặc FROZEN (#333/#485-487) — cả 2 benign; ship-proof duy nhất = LM-in-window + real-size; hash-delta chỉ là chỉ báo phụ, KHÔNG flag rotation-on-0-src làm anomaly.** - **🟢 S104 #488 (rn 374, id 488) `778fc98` GO ~4m (poll iter4→success, updated_at 16:11:25+07) — FULL-STACK Supplier 9→27 field + Mig 62 `ExpandSupplierFields` (BE+FE 2-app, NCC/TP Excel-import anh Kiệt FDC):** status=success (test gate 440 passed, `conclusion=None` tasks-quirk = trust success) · **Mig 62 APPLIED-PROD** `__EFMigrationsHistory` top==repo-HEAD, present=1 · **AddColumn ×18** (17 nullable str + `Status` int) VERIFIED sys.columns=18 + Suppliers-total-35-cols · **sys.tables=89 UNCHANGED** (Mig source 0 CreateTable/DropTable — schema-add-only, count-invariant ✓) · **🔑 UN-CRAM DATA-OUTCOME EXACT:** 4 NCC (TRUONGGIANG/TANPHU/TGN/DONGDUONG) all Note=NULL (guarded `Sql()` ran) + Note-still-Loại-count=**0** + PackageCategory/BankAccount/LegalRepresentative populated + Status=1 + LinkGuq populated for DONGDUONG+TRUONGGIANG (TANPHU/TGN legit no-GUQ in source) · smoke health 3×200 + auth accessToken-len468 + **GET /api/suppliers 200 (22 items) DTO carries 18 new keys** (packageCategory/bankAccount/legalRepresentative/linkGuq/officeAddress/contactPhone/status/note) w/ proper VN-diacritics · SignalR bodyless-411=wired · **bundle JS ROTATED** admin `ChSNAJBK`/user `Bn2w1znH` (real fe-src diff SuppliersPage+PathLink+types) CSS-frozen + LM-in-window 16:10 + real-size 1.64/1.55MB + marker `officeAddress`/`legalRepresentative` grep-HIT vs SPA-trap-919b-control = REAL-ship (#69: rotation HERE meaningful, real src-diff). ship-proof BE Infra.dll 16:07 + w3wp recycle 16:11:50. 🔑 **FULL-STACK-SCHEMA-ADD + DATA-UN-CRAM PASS = CI-success + Mig-top==HEAD + AddColumn-count-EXACT + sys.tables-invariant + target-rows-outcome-EXACT (Note-cleared/new-cols-populated/marker-count-0) + DTO-new-keys-in-API + bundle-real-ship-marker-grep + dll/w3wp-in-window.** ## Archived 2026-07-12 S111 curate — runs #490-#494 verbatim (from L1 MEMORY.md) - **🟢 S110-spot #494 (rn 380, id 494) `ac3f122` GO 5m00s (20:45:41→20:50:41+07, found-completed) — GOVERNANCE 10-file (mark-stamp + VALID_ROLES 12; `hmw.js` non-md → #41 CI-run; `38262d8` cicd-MEMORY .md-only push cùng-đợt → 0-run ✓ #41 2-chiều):** status=success (gate 440) · 0 fe/BE/mig src ⟹ Mig FROZEN 62 top + sys.tables=89 ✓ · smoke 3×200 · **bundle FROZEN ×5-streak** (`BVyH-FY7`/`EDsZebvn` + CSS = #490→#493) + LM-in-window 20:49:15/20:50:08+07 + size 1,644,931/1,551,280b = ship-proof. 🔑 spot-check-detection: coordinator bắt #494 qua **LM prod MỚI-HƠN window run trước** — LM-newer-than-last-verified-window = missed-run detector. - **🟢 S110 #493 (rn 379, id 493) `6ee60cd` GO 5m24s (20:39:21→20:44:45+07, iter6) — GOVERNANCE 3-commit range (`162f0b9` .md-only + `debe82f` H21+MTv3 25-file [`hmw.js` comment-only + `.gitignore` non-ignored → #41 range-eval CI-run, AS-6 verified] + `6ee60cd` .md-only):** status=success (gate 440) · 0 fe/BE/mig src ⟹ Mig FROZEN 62 history-top `ExpandSupplierFields` + MIGCOUNT=62 + sys.tables=89 ✓ · smoke 3×200 · **bundle FROZEN ×4-streak** (admin `BVyH-FY7`/`Bbtesa6B` · user `EDsZebvn`/`BmuPz_Dy` = #490→#492) + LM-in-window 20:43:17/20:44:11+07 + real-size 1,644,931/1,551,280b vs fake-919b = ship-proof. 🔑 non-.md-in-governance-push trigger-pattern lặp ×3 (#490 budget.json/#491+#493 hmw.js) — stable; frozen-streak ×4 củng cố #69-REFINE (byte-identical src ⟹ same hash, LM+size = signal duy nhất). - **🟢 S109 #492 (rn 378, id 492) `f5a5c3e` GO 5m21s (17:21:34→17:26:55+07, found-completed 0-poll) — MEMORY-ONLY 10-file (9 .md ignored + `memory-budget.json` non-ignored → #41 CI-run, AS-6 prediction VERIFIED):** status=success (gate 440) · 0 fe/BE/mig src ⟹ Mig FROZEN 62 history-top `ExpandSupplierFields` + MIGCOUNT=62 + sys.tables=89 ✓ · smoke 3×200 (health/ready + 2 FE roots) · **bundle FROZEN ×3-streak** (admin `BVyH-FY7`/`Bbtesa6B` · user `EDsZebvn`/`BmuPz_Dy` = #489→#491) + LM-in-window 17:25:26/17:26:22+07 + real-size 1,644,931/1,551,280b vs fake-919b = ship-proof. 🔑 `memory-budget.json` trigger-pattern lặp #490 — single non-.md file trong memory-push đủ CI-run (#41 range-eval); frozen-streak ×3 củng cố #69-REFINE (0-fe-src ⟹ byte-identical output, LM+size = signal duy nhất). - **🟢 S108 #491 (rn 377, id 491) `69957fd` GO 5m06s (14:35:12→14:40:18+07, iter7) — GOVERNANCE 9-file (`hmw.js` comment-fix non-ignored → #41 CI-run; archive-carry `f1af05c` 2-file .md-only → 0-run ✓ #41 2-chiều VERIFIED cùng-đợt):** status=success (gate 440) · 0 fe/BE/mig src ⟹ Mig FROZEN 62 history-top + sys.tables=89 ✓ · smoke 3×200 · **bundle FROZEN ×2** (admin `BVyH-FY7`/`Bbtesa6B` · user `EDsZebvn`/`BmuPz_Dy` = #489/#490) + LM-in-window 14:38:50/14:39:44+07 + real-size 1,644,931/1,551,280b vs fake-919b = ship-proof. 🔑 #69 FROZEN-streak ×2 (#490→#491) sau ROTATE #489 — cùng 0-fe-src 3-run liên-tiếp cho cả 2 mode; LM+size vẫn signal duy nhất. - **🟢 S107-closeout #490 (rn 376, id 490) `d74f67f` GO 5m32s (10:39:30→10:45:02+07, iter6) — GOVERNANCE-CLOSEOUT 7-file (6 .md + `memory-budget.json` non-ignored → #41 CI-run):** status=success (gate 440) · 0 BE/FE src ⟹ Mig FROZEN 62 history-top + sys.tables=89 ✓ · smoke 3×200 · **bundle FROZEN ×2** (admin `BVyH-FY7`/`Bbtesa6B` · user `EDsZebvn`/`BmuPz_Dy` = #489) + LM-in-window 10:43:38/10:44:36+07 + real-size 1.64/1.55MB app-js vs fake-919b = ship-proof. 🔑 #69 TWO-MODE back-to-back cùng-phiên: #489 ROTATE → #490 FROZEN trên cùng 0-fe-src — LM+size là signal duy nhất. Orphan-record OK (precedent #485). ## Archived 2026-07-13 S115 curate — runs #384/#383/#496/#495 verbatim (from L1 MEMORY.md) - **🟢 S114 #384 (rn 384, id 498) `d436af2` GO 5m17s (22:22:40→22:27:57+07 2026-07-12, owner anh Kiệt) — PE multi-NCC per hạng mục (winner-truth đổi whole-supplier `IsWinner` → per-hạng-mục `Quote.IsSelected`; endpoint `select-winner` body `{supplierIds}`→`{detailId,supplierIds}`; Mig 65 data-only 2-dir backfill; 18-file: 7 BE incl PurchaseEvaluationWorkflowService+DbInitializer-sync, 2 FE PeDetailTabs both apps, 7 PE test, Mig65 2-file no-ModelSnapshot):** status=success · **gate CONCRETE `runs/384/jobs/0/logs`: Domain 45 + Infra 441 = 486/0-fail/0-skip** (+9 vs #383 477) · **Mig 65 `BackfillPeQuoteIsSelectedAndWinnerInvariant` APPLIED-PROD** (history-top + **invariant-violations=0** [IsWinner⟺Any(IsSelected), 33 sup/23 winners] + sys.tables=89 frozen [data-only, 2 mig-file no-ModelSnapshot = correct]) · **FE REAL-SHIP js×2 css-FROZEN** admin js `acprMqfB`→`D51OYyGV` · user js `Ck3BTDdA`→`BVdssm5S` (CSS `CfunQHbd`/`DGqqHQXS` frozen — `.tsx`-only) ship-proof= real-size 1,655,105/1,561,453b + `application/javascript` + LM 15:26:37/15:27:29 GMT in-window + byte-verify `trúng thầu theo từng hạng mục`+`thắng hạng mục`+`trúng thầu cho hạng mục` present both vs SPA-trap 919b · **select-winner WIRED** POST bogus-bearer+body→401 vs bogus-route 404 (401≠blanket). smoke health/ready+live + admin/eoffice roots ALL 200. 🔑 js-rotate+css-frozen = FE-logic-no-style fingerprint. - **🟢 S113 #383 (rn 383, id 497) `5fa11b5` GO 5m14s** — Supplier import v2 + Mig 64 `AddSupplierPublishState` APPLIED-PROD (IsPublic backfill 37/37, sys.tables 89) · gate 477 (45D+432I) · FE real-ship js+css both apps admin `acprMqfB`/`CfunQHbd` · user `Ck3BTDdA`/`DGqqHQXS` (byte-verify `Tải file mẫu`/`Đã công bố`/`Nháp (ẩn)`) · endpoints `/suppliers/import/template`+`?published=true` WIRED 401 · smoke ALL 200 — verbatim → git `8304d08` + `_INDEX`. - **🟢 S112 #496 `e100ef0` GO 5m25s** — PE workflow + Supplier Excel-import Phase B + Mig 63 `AddSupplierImportSourceFields` APPLIED-PROD (2 AddColumn, sys.tables 89) · gate 458 (45D+413I) · FE admin `Cixlt_MA`/user `BhBOG1dn` · 🔑 411-refine: bodyless-POST→411 ANY route → re-probe WITH body → 401/415 (matched) vs 404 (missing) — verbatim → `2026-07.md`/`_INDEX`. - **🟢 S111 #495 (rn 381, id 495) `8aa3869` GO 5m11s (11:45:21→11:50:32+07 2026-07-12, iter6) — H22 WAL adopt 30-file +767 (0 src/BE/FE/mig; non-ignored: settings.json + wal-flush.ps1 + hmw.js + deploy.yml + governance-detectors.ps1 + .gitattributes → CI-run ĐÚNG thiết kế):** status=success (gate 440) · **deploy.yml TỰ-ĐỔI trong chính commit (D10 +2 paths-ignore `.claude/agent-memory/**` + `.claude/workflows/runs/**`) — run created+parse+chạy trọn 5m11s = YAML hợp lệ, workflow-self-change PASS** · Mig FROZEN 62 history-top `ExpandSupplierFields` + sys.tables=89 ✓ · smoke 3×200 (health/ready + 2 FE roots) · **bundle FROZEN ×6-streak** (admin `BVyH-FY7`/`Bbtesa6B` · user `EDsZebvn`/`BmuPz_Dy` = #490→#494) + LM-in-window 11:49:07/11:50:00+07 + size 1,644,931/1,551,280b byte-identical #494 vs fake-919b = ship-proof. 🔑 **AS-6 BASELINE SHIFT từ #495: paths-ignore 7-entry — memory-budget.json/agent-memory/run-trace push HẾT trigger (trigger-pattern #490/#492 DEAD); phân loại trigger giờ soi file ngoài 7-glob.** - **🟢 S116 #386 (rn 386, id 500) `88368fd` PE-nhập-giá-ÂM ô báo giá + submit-guard all-zero GO 5m28s (17:08:42→17:14:10+07 2026-07-13; 7-file: FE PeDetailTabs.tsx ×2 mirror [112 dòng/app] + BE PurchaseEvaluationWorkflowService.cs [:206 `selectedThanhTien.Sum()<=0`→`.All(x=>x==0)` — cho giá ÂM=phát-sinh-giảm/hoàn-tiền NCC=giá THẬT] + 4 test-file; NO migration → tables 89 giữ):** status=success · **gate CONCRETE `runs/386/jobs/0/logs`: Domain 45 + Infra 450 = 495** (+9 vs S114/S115 486; Infra 441→450, Domain frozen 45) · **FE JS-ROTATE ×2 / CSS-frozen** admin js `D51OYyGV`→`Dd55jBpj` (css `CfunQHbd` frozen) · user js `BVdssm5S`→`DVDr1UQ4` (css `DGqqHQXS` frozen) = FE-logic-no-style fingerprint (khớp PeDetailTabs.tsx logic-only) · byte-verify #77 NEW bundle: `Đã nhập giá chào thầu`=1 + `hoàn tiền NCC`=1 + `Đơn vị được chọn chưa có giá chào thầu`=1 + `phát sinh giảm`(toggle)=1 PRESENT (đều =0 ở old-frozen D51OYyGV pre-deploy — chứng NEW-code ship; `Có giá là được`=0 minify-diff non-load-bearing) · size real 1,656,224/1,562,572b (vs 919b SPA-trap) · LM admin 10:12:47 / user 10:13:41 GMT = 17:12/17:13+07 IN-window · smoke ALL: api ready+live 200, admin+eoffice 200, PE 401 alive+secured · 🔑 **PRE-DEPLOY frozen-bundle-at-S115 TRAP-avoided**: poll til status=success TRƯỚC re-snapshot (grep-sớm khi status=running → false-FAIL frozen; xác nhận CI running 17:11 → success 17:14 → bundle rotate). cicd-lane CLEAN-return no-garble. - **🟢 S115 #385 (rn 385, id 499) `81b59f0` GOVERNANCE/TOOLING-ONLY GO 5m23s (12:25:31→12:30:54+07 2026-07-13, harness adopt presence-not-age + hmw.js STOP-HARD; 20-file: 0 src/fe/mig/test — non-ignored trigger = `.claude/workflows/hmw.js` + `scripts/memory-archive-gate.ps1` [`.ps1`∉`scripts/**.md` ⟹ CI-run ĐÚNG #41; rest .md/.json under docs/agent-memory/workflows-runs/broadcasts IGNORED]):** status=success · **gate CONCRETE `runs/385/jobs/0/logs`: Domain 45 + Infra 441 = 486/0-fail/0-skip = S114 baseline EXACT** (0 src/tests diff → count frozen ✓) · **FE bundle FROZEN ×4** admin js `D51OYyGV`/css `CfunQHbd` · user js `BVdssm5S`/css `DGqqHQXS` = S114 verbatim (NO rotate) — deploy physically re-copied (LM 05:29:32/05:30:26 GMT = 12:29:32/12:30:26+07 IN-window) BUT byte-identical (size 1,655,105/1,561,453b = S114 EXACT) ⟹ #69-REFINE 0-fe-src=identical-Vite=same-hash+size+fresh-LM · SPA-trap ctrl fake-hash 919b text/html · Mig FROZEN 65 (0 migration-file diff; API health/ready 200=startup OK) · smoke 4/4 200 (api ready+live, admin, eoffice). 🔑 GOVERNANCE-ONLY PASS: non-.md-in-.claude (hmw.js/.ps1) STILL trigger CI (#41 LIVE post-#495 D10); FROZEN-hash+fresh-LM+identical-size = no-accidental-rotation proof. cicd-lane clean-return no-garble. - **🟢 S117 #387 (rn 387, id 501) `316a82f` PE endsBeforeCeo-pointer-aware + duyệt-theo-khoảng-Min–Max + Mig 66 `AddPeApprovedPriceRange` APPLIED-PROD GO 5m36s (11:14:09→11:19:45+07 2026-07-14; 19-file: BE 7 [Domain/Config/Features/Service/IService/Dtos/Controller] + FE 6 [PeDetailTabs+PeWorkflowPanel+types ×2-app] + Mig 3 + test 2 [NEW PeApprovedPriceFinalizeTests + PeFinalizeProjectionTests mod]):** status=success · **gate CONCRETE web-UI-path `runs/387/jobs/0/logs` (NO /api/v1/): Domain 45 + Infra 456 = 501** (+6 vs S116 495; Infra 450→456, Domain frozen 45; 0-fail/0-skip) · **Mig 66 APPLIED-PROD** sqlcmd `COL_LENGTH('PurchaseEvaluations','ApprovedPriceMaxAmount')=9` + history-top `20260714035636_AddPeApprovedPriceRange` + sys.tables **89 giữ** (AddColumn decimal(18,2) no-new-table) · **FE JS-ROTATE ×2/CSS-frozen** admin js `Dd55jBpj`→`cFI7ih4a` (css `CfunQHbd` frozen) · user js `DVDr1UQ4`→`MxgooVZw` (css `DGqqHQXS` frozen) = FE-logic-no-style fingerprint · byte-verify #77 BOTH-app NEW bundle: `cả Min và Max`=1 + `duyệt theo khoảng`=1 + `ProMinMax`=2 + `Min–Max`(en-dash)=1 PRESENT (all=0 in OLD DVDr1UQ4 captured pre-deploy — NEW-code ship proof; ⚠️ `PRO Min`=1 in OLD = pre-existing label `ProMin:'PRO Min'` = FALSE-discriminator) · size real 1,656,696/1,563,044b (vs 919b SPA-trap) · LM admin 04:18:21/user 04:19:16 GMT = 11:18/11:19+07 IN-window · smoke ALL 200 (api ready+live, admin, eoffice) · PE 401-secured: GET-list no-token+bogus→401, POST /transitions bogus+no-token→401, /select-winner bogus→401 (no 500) · 🔑 pre-deploy bundle-snapshot BEFORE poll-success (captured OLD-hash+OLD-feature=0) → post-success re-snapshot = clean rotation proof. cicd-lane CLEAN-return. - **🟢 S118 #389 (rn 389, id 503) `c808b9a` SECURITY-AUTHZ gate ReportsController→Reports.Read GO 5m34s (15:55→16:00:57+07 2026-07-14; 3-file: ReportsController.cs [+2 `[Authorize(Policy="Reports.Read")]` on `dashboard`+`contracts/export`; `my-dashboard` kept-open scope-currentUser] + AuthorizePolicyRegressionTests.cs [+4 reflection] + gotchas.md):** status=success · **gate `runs/389/jobs/0/logs`: Domain 45 + Infra 464 = 509** (+4 vs #388 505; Infra 460→464 = +4 authz reflection; 0-fail/skip) · **dll NEW** 15:58:21+07 (was 15:33:21 = app restarted in-window) · **🎯 DB `Reports.Read`→Admin-ONLY** sqlcmd prod (scp .sql→`-i`, cleaned): 1 role CanRead=1 (`Admin`); `Procurement` row CanRead=0 → non-admin dashboard/export=**403 by-construction** (4-attr-test + policy-Admin-only-DB) · smoke: health/live 200, admin 200, eoffice 200, dashboard/export/my-dashboard no-token=**401** (class-level `[Authorize]` intact) · **NO-FE** (0 fe-src → bundle=S117 `cFI7ih4a`/`MxgooVZw` frozen) · **NO-Mig**. Password-free per task (403 by-construction not curl-proven). **cicd-lane return GARBLED #53** (memory-curation slice, NOT verdict) → **em-main-solo curl+sqlcmd recovered**; verdict-substance disk-verified TRUE (509-gate + `Reports.Read`→Admin-only + 401 no-token all git/prod-corroborated). [harvest-curator S118-end F1: nhãn "CLEAN-return" cũ SAI, đã sửa.] - **S126 (2026-07-16) run 508/#394 `e9124fc` GOVERNANCE-TOOLING GO [opus, 0-garble]:** gate **509 PASS exact** (45+464, 0 fail) · bundle **FROZEN byte-id S117 #387** (`cFI7ih4a`/`MxgooVZw`, LM in-window + real-size = re-shipped hash-frozen, benign #69 same-hash, 0 hoist) · smoke 200×5 · **89 bảng + Mig 66 top = no-drift**. 4 non-.md (.json/.js/.ps1) vẫn trigger full CI per #41. ⚠️ bare `/health`=404 UNMAPPED (thật = `/health/live`+`/ready`) — đừng FAIL; jq không có → python json; python capture_output cp1252 → curl -o + open(utf-8); Windows-python không thấy `/tmp`. - **S133 (07-17) verify d4fbced PE budget-freeze [wf_4eadbcf6-c25, return sạch — verdict landed SAU khi lead /pause; harvest-liền lúc notification, lead CHƯA re-verify độc lập]:** VERDICT **GO 5/5** — Run **#398** success ~5.5m (gate **520** = 45D+475I, 0 fail/skip); Mig 67 prod: history-top + **11 cột ApprovedBudget\* exact** + backfill **18/18 phiếu DaDuyet chua=0** + sys.tables **89** no-new-table; bundle rotate ×2: admin js `yCkX-2Bp`→**`3NCdyODe`** css `CXD7q9xH`→**`B--dUHcm`** · eoffice js `DKSD4p9k`→**`CKsoiNCI`** css `CjwZwYJo`→**`BuntB63r`**, real-size 1.657.025/1.563.373B, LM 11:18:42/11:19:36+07 in-window; byte-verify #77: `budgetFrozen`=1 + `Ngân sách chốt tại thời điểm duyệt`=1 cả 2 js mới, old-hash control = 900B SPA-trap 0-hit; smoke 4×200 + PE 401-secured. **Surprise: CSS CŨNG rotate cả 2 app** (spec đoán "CSS có thể frozen") — PeDetailTabs badge sinh utility-class mới → content-hash đổi theo content, benign #69; phá streak bundle-FROZEN S129-S132. Lesson tool: python `capture_output text=True` crash cp1252 trên title CI tiếng Việt → dùng `text=False` bytes + `json.loads(bytes)`; foreground sleep bị chặn → `python time.sleep` poll-loop OK. Tag `[s133, run-398, go-5-5, css-rotate-benign, mig67-backfill-18]` - **S134 (07-17) verify 6664a61 PE lũy-kế tạm-tính [wf_f366f38d-498 · return CLEAN no-garble] `[engine: opus-worker]`:** VERDICT **GO 5/5** — Run **#399** (id=513) success 5m27s (14:27:29→14:32:56+07); gate **528 EXACT từ log** (45D+483I, +8 PePendingAccumulationTests); Mig 67 top FROZEN + sys.tables 89 (0-mig by-construction, `git diff -- *Migrations*` empty); bundle rotate ×2 admin js `3NCdyODe`→**`BVCukFP5`** css `B--dUHcm`→**`CBzUlgOA`** · eoffice js `CKsoiNCI`→**`DoxyEOxh`** css `BuntB63r`→**`BHsBUA8e`** (FE-src đổi 6 file ⇒ rotate expected; CSS = amber utilities benign #69), real-size 1.659.037/1.565.367B + LM in-window; **byte-verify #77 qua python urllib BYTES**: `pendingPriorPes`=2 + `Tạm tính`=3 + `phiếu trước cùng gói thầu CHƯA duyệt`=2 cả 2 js, control old-hash 900B **ct=text/html** 0-hit; smoke 4×200 + PE 401. Learned: (1) **urllib bytes + `body.count(marker.encode())` = bulletproof cp1252** cho marker tiếng Việt (khác subprocess text=True crash S133); (2) **ct=text/html là SPA-trap discriminator SẠCH HƠN size-919B** (shell size drift per build — 900B lượt này); (3) tasks-API có thể blip empty-200 transient → poll-loop absorb. Poll held-off verify khi running (iter 0-2) đúng bài #242. Tag `[s134, run-399, go-5-5, ct-html-discriminator, urllib-bytes-marker]` ## Run #407 `4510cea` (2026-07-23) — moved from L1 @S155 curate, byte-exact - **07-23 verify 4510cea (App: chuẩn-hóa mã dự-án normalize + PE attach-gate FE both-apps) [em-main spawn, return CLEAN]:** VERDICT **PASS 5/5** — Run **#407** (id=521) success ~5m36s (17:11:54→17:17:30+07); gate **532 EXACT từ log** (45 Domain + 487 Infra, 0 fail/skip) — **+4 vs prev run #406/8b6df0a (483I)** = 4 `ProjectCodeNormalizationTests` (delta-proof: dotnet summary KHÔNG in tên-test riêng → dùng delta prev-run + build-success + all-pass). NO-Mig: `git diff 8b6df0a..4510cea -- *Migrations*` EMPTY + prod history-top `AddPeApprovedBudgetSnapshot` (Mig 67, từ S133 KHÔNG phải push này) = repo-HEAD unchanged + sys.tables **89** — code-only no-drift by-construction. **Bundle JS rotate cả 2 app / CSS FROZEN cả 2** (đúng dự-đoán — PeDetailTabs.tsx ×2 = pure button-gating logic, no new Tailwind utility): admin js `DGPE6Nkb`→**`B2j1LQ-v`** css `CBzUlgOA` frozen · eoffice js `DlTwAgJj`→**`C3wbJegk`** css `BHsBUA8e` frozen; real-size 1.660.902/1.567.232B, LM 17:16:01/17:16:54+07 in-window; SPA-trap control fake-hash `index-ZZfakehash0.js`=900B **ct=text/html** (discriminator OK). smoke 4×200 (health/live+ready, admin, eoffice). Baseline shift: **Infra 464(S118)→483(run406)→487**, Mig-latest = **Mig 67** ("Mig 66" essentials-line STALE — updated). Pre-deploy snapshot captured WHILE running (đúng bài #242 verify-post-success). Tag `[run-407, pass-5-5, js-rotate-css-frozen, delta-proof-+4, code-only-no-mig]` --- ## Run #416 `b1bae77` (2026-07-27) — moved from L1 @S157 curate, byte-exact - **07-27 verify b1bae77 (Workflow: quy-trình duyệt TẠI CHỖ + cờ F6 `AllowApproverDelete` đợt-1) [S155, MIG-BEARING deploy, CLEAN-return]:** VERDICT **PASS 6/6** — Run **#416** (id=529) success **5m31s** (12:37:18→12:42:49+07); gate **551 EXACT từ log** (45 Domain + **506** Infra, 0 fail/skip) — **+19 vs run #407 (532)**, **KHỚP CHÍNH XÁC số lead đo local (551)** = cross-check 2-nguồn. **Mig 68 `20260727033522_AddPeAllowApproverDelete` VERIFIED-APPLIED-PROD** (AddColumn `AllowApproverDelete` bit NOT NULL default `(CONVERT([bit],(0)))` trên `ApprovalWorkflowLevels`; history-TOP + `INFORMATION_SCHEMA.COLUMNS` **cả 2 cùng có ⟹ không lệch**; sys.tables **89** giữ nguyên đúng AddColumn-no-new-table). 🔑 **Reviewer FLAG F8 (mig-file rớt khỏi commit ⟹ `Invalid column name` hạ 7 module V2) LOẠI TRỪ bằng 3 lớp:** (i) pre-deploy baseline 12:38 history-top còn `AddPeApprovedBudgetSnapshot` ⟹ mig áp TRONG cửa-sổ này không phải sẵn có; (ii) smoke 8/8 HTTP 200 `Invalid column name`=0 (PE·HĐ·Đề-xuất·Nghỉ-phép·Tăng-ca·Công-tác·Đặt-xe + AwV2); (iii) **phép mạnh nhất = `GET /api/approval-workflows-v2` trả `allowApproverDelete` ×54 materialize qua EF từ DB thật** — DB thiếu cột thì chính query này đã ném. Endpoint mới `PUT /api/approval-workflows-v2/{id}` no-token → **401** + **control route bịa → 404** (discriminator sạch, 401 có nghĩa). Bundle **JS rotate CẢ 2** (admin `hHISK1Ig`→**`CiUBEEJr`** css `CBzUlgOA`→**`DX5ew0wg`** rotate; eoffice `CJeXZso2`→**`DFh7GK0t`** css `BHsBUA8e` **FROZEN** = #69-REFINE lành tính, 2 file fe-user là logic/type no-new-utility) real-size 1.670.035/1.570.257B, LM 12:41:28/12:42:22+07 **in-window**; byte-verify #77 marker `allowApproverDelete` admin ×7 / eoffice ×1 ⟹ đúng mã F6 đã ship. SPA-trap control `ct=text/html` 900/876B. health live+ready 200. Tag `[run-416, pass-6-6, mig-bearing, F8-averted-3-layer, col-materialize-x54, js-rotate-both, gate-551-khớp-local]` ## Run #419 `a52a91e` (2026-07-28) — moved from L1 @S159 curate, byte-exact - **07-28 verify `a52a91e` (PE: cảnh báo amber ô Địa điểm khi dự án thiếu Location) [S157, FE-ONLY 2-app, CLEAN-return]:** VERDICT **PASS 9/9** — Run **#419** (id=532) success **5m40s** (09:40:18→09:45:58+07); gate **562 EXACT từ log** (45 Domain + **517** Infra, 0 fail/skip) — khớp canonical `docs/STATUS.md:452` **cả TỔNG lẫn TÁCH 45/517** (khớp thành-phần > khớp tổng). NO-Mig đúng kỳ vọng: `git diff f4494cf..a52a91e -- 'src/Backend/*' '*Migrations*' | wc -l` = **0** ⇒ Mig vẫn 68, 89-table, KHÔNG query DB (không có gì để đối chiếu). 🔑 **Phép quyết định = byte-marker #77, KHÔNG tin status CI:** tải thẳng JS prod, `bytes.count(marker.encode())` 4 chuỗi VN độc lập → **2/2 app, count=2 mỗi app = KHỚP SỐ FILE/app trong diff** (`PeHeaderForm`+`PeWorkspaceCreateView`) — "đúng-BỘI-SỐ" mạnh hơn "tìm thấy ≥1", bắt được cả ca ship nửa-vời. Bundle js rotate CẢ 2 (admin `BK8w3QxU`→**`8-QYcMOg`** · eoffice `DYnxSI0T`→**`DptYR4wL`**; css `DiNJjaoo`/`BRCvEHvC` FROZEN ×2 = #69-REFINE lành tính — utility `text-amber-700`/`text-[11px]` đã có sẵn) real-size 1.675.282/1.575.513B, LM 09:44:33/09:45:30+07 in-window. 🆕 **Control âm 2 TẦNG (tái dụng):** (i) fake-hash→200 nhưng `ct=text/html` 900/876B marker=0; (ii) **hash CŨ cũng rơi về text/html ⇒ bundle cũ BIẾN MẤT khỏi đĩa** = chứng GHI-ĐÈ thật (mạnh hơn hash-delta đơn thuần). Smoke: health live+ready 200 · login 200 tok-468 · `/api/projects` 200 (đúng nguồn `location` feature đọc) · PE/menus/suppliers 200. ⚠️ **Self-correct on-disk:** viết "range=6 file" SAI (đó là số của 2 commit) — range thật **13 commit/26 file** (11 `wal:` xen giữa); đính chính ngay, BE=0 không đổi. Tag `[run-419, pass-9-9, fe-only, marker-2of2-count-exact, old-hash-gone-control, js-rotate-css-frozen, gate-562]` ## Run #423 `1a47a61` (2026-07-29, S159 đợt-2) — moved from L1 @S159 curate, byte-exact - **07-29 verify `1a47a61` ĐỢT-2 (tab strip 4 GĐ trên phiếu PE + menu 4-GĐ + đánh số 01-07 nhóm HĐ) [S159, 8 file code 190+/18−, FE×2 + seeder-only BE]:** **PARTIAL 8/9** — Run **#423** (id=536) success **5m44s**; gate **562 EXACT** (45+517). 0 migration (BE chỉ `MenuKeys.cs` const + `DbInitializer.cs` seeder). Bundle rotate **4/4** (admin js `BHodkPNV`→`D6Pz7nfV` css `DiNJjaoo`→`B1ErASuI` — admin-css rotate ĐÚNG vì fe-admin có sửa, khác đợt-1 frozen; user js `0GO8mgrG`→`Bpb8WEuY` css `BARVqkP-`→`7oAYFlzM`). Mirror `PePipelineStrip.tsx` 2 app **md5 IDENTICAL** `ef7b7824…`. 🔑 **Quy luật đếm marker (nối tiếp bài comment-strip): bundle-count = SỐ MODULE chứa chuỗi** (bundler pool hằng-số trong 1 module ⇒ nhiều occurrence cùng file gộp còn 1). USER=2 module→2 · ADMIN=1 module→1, đúng **6/6** (3 marker × 2 app) = 'đúng-BỘI-SỐ'. 2 control ÂM (`Đề xuất ký kết hợp đồng`, `Ký cứng & phát hành`) =0 cả 2 bundle + grep repo-wide 0-hit. Menu-data 5/5: **root=12 (0 double-insert) · DUPKEYS=0** · 2 root mới `KeHoachKyKet` ord26 / `HopDongCung` ord32 vis=1 (13 rows/13 canread mỗi key) · 3 root vẫn vis=0 · rename prefix `Duy…` ×2 · `Pe%` 197/185. 🔴 **FAIL #9 — BẮT ĐƯỢC REGRESSION NGOÀI CHECKLIST:** Serilog `Revoked 9 permission rows … Hợp đồng/Danh mục khỏi non-Admin` ⇒ đo lại grant-38-key của đợt-1: **47/494 canread, 0 key còn 13** (Admin=38 · Procurement=9 · 11 role còn lại=0, mất 447). Gốc = `DbInitializer.cs:2203-2236` **`RevokeTemporarilyHiddenModulesAsync` UNGATED chạy MỖI startup**, tập revoke TRÙNG KHỚP grant-set ⇒ **grant SQL tay không bao giờ bền, phải sửa CODE**. ⚠️⚠️ **BÀI HỌC LỚN NHẤT — bẫy ĐO-TRƯỚC-RECYCLE: pool restart nằm ở CUỐI deploy-window, nên đo DB lúc run còn `running` = đo trạng thái CŨ, KHÔNG chứng minh được 'sống sót recycle'. Mọi mục durability PHẢI đo SAU `status=success`.** (đợt-1 tao đo 11:46 vs restart 11:49 → kết luận sai). ⚠️ deploy `Remove-Item …pi\*` **xoá luôn `logs/`** ⇒ Serilog chỉ còn từ lần deploy cuối, không truy ngược được restart trước. ⚠️ prod Identity table = **`Roles`** không `AspNetRoles` (#472 tái xác nhận). Đợt-2 tự nó ship ĐÚNG — KHÔNG rollback. Evidence: `runs/2026-07-29-S159-tong-quan-pipeline-menu/cicd-verify-1a47a61.md`. Tag `[run-423, partial-8-9, do-truoc-recycle-trap, revoker-ungated-durability, marker-count-per-module, gate-562]` ## Moved @S160 (2026-07-29) — verbatim from L1 (moved-not-cut; pointer _INDEX treo cho (51-bis)) - **07-29 verify `2a72695` ĐỢT-3 (gỡ nhánh S92 khỏi revoker + skeleton menu GĐ2/GĐ4 + ComingSoonPage×2) [S159, 9 file code, 0 mig]:** ✅ **PASS 9/9 — ĐÓNG regression tao bắt ở đợt-2.** Run **#424** (id=537) success **5m56s**; gate **562** giữ nguyên (3 test SỬA theo spec-change, không thêm ⇒ tổng không đổi). Bundle rotate **4/4** (admin `D6Pz7nfV`→`CC1pGE1F`/`B1ErASuI`→`DWDbm5As` · user `Bpb8WEuY`→`DeAg7MWm`/`7oAYFlzM`→`BQIZ-rUe`); marker `Phân hệ đang được triển khai`=1 cả 2 bundle + `Quay lại`=4; hash CŨ→`text/html` = chứng ghi-đè. Menu-tree: Khkk=5 · Hdc=7 · root=12 · DUPKEYS=0 · 3 root vis=0. 🔑 **PHÉP DURABILITY LÀM ĐÚNG (sửa lỗi đo-sớm đợt-2) — khuôn 3 CHÂN KIỀNG, tái dùng cho mọi ca 'fix có bền không':** (i) **CHỨNG MINH có restart THẬT trước khi đo** — `w3wp` PID StartTime 12:39:56 trong cửa-sổ deploy + **dòng ĐẦU log = 12:40:03 `Applying migrations...`** (dùng được vì deploy xoá `logs/` ⇒ log mở lại = boot mới) + DLL mtime; (ii) đo CÁI CẦN: 38-key **min=13 max=13 keys=38, tổng 494/494** SAU restart (đợt-2 chính phép này ra 47/494); (iii) **control ÂM chống Goodhart**: `Hrm/Off/Personal` non-Admin vẫn **=0** ⇒ revoker CÒN SỐNG, nên (ii) xanh KHÔNG phải do vô hiệu hoá cả hàm. **Thiếu (iii) thì 'fix' bằng cách xoá luôn checker cũng xanh y hệt.** Bổ sung: `Revoked` **0 dòng** trong log = ĐÚNG (hàm chỉ log khi `rows.Count>0`; nay 0 row cần lật, so 447 ở đợt-2) — **vắng-mặt phải giải-trình bằng cơ-chế, đừng đọc thành thiếu dữ liệu**. Guard mới có RĂNG 2 vế: `StillHiddenKeys` phải false + `ReopenedKeys` phải TRUE ⇒ re-add nhánh S92 là CI đỏ. ⚠️ Bẫy số: nhãn `01.-07.` đếm ra **14** (kỳ vọng 7) — tách prefix ra `Ct_`=7 + `Hdc_`=7 + other=0, đúng thiết kế 'GĐ4 tái dùng nhãn đã đánh số', KHÔNG phải nhân đôi. ⚠️ seeder grant là **skip-existing** ⇒ không tự nâng row `false` sẵn có trên prod; prod phải re-grant SQL + revoker thôi lật. Evidence: `runs/2026-07-29-S159-tong-quan-pipeline-menu/cicd-verify-2a72695.md`. Tag `[run-424, pass-9-9, durability-3-chan-kieng, restart-proof-w3wp-log-head, control-am-chong-goodhart, gate-562]` ## Moved @S162 (2026-07-30) — verbatim from L1 (moved-not-cut; MEMORY 26.9KB->target <17.1KB) - **07-29 verify `a8027c0` W1 KHKK — Mig 69 `AddContractSigningPlans` [S161, 30 file +8987/−22]:** ✅ **PASS 6/6** — Run **#427** (id=540) success **5m40s**; gate **566 = 45D+521I** (0 fail/skip, +4 test W1). Mig 69 APPLIED-PROD: MIGTOP `20260729122015_AddContractSigningPlans` · MIGCOUNT 68→**69** · `sys.tables` **89→96 (+7 khớp 7 CreateTable)** · 7 bảng `ContractSigningPlan{s,Lines,DossierItems,LevelOpinions,Attachments,Changelogs,Approvals}`. MenuItems **142→142 GIỮ** (policy-key ⟂ menu-key). 🔑 **KHUÔN ĐO-CỜ (không đếm ROW) — tái dùng cho mọi seeder UPGRADE-if-exists:** row đã tồn tại CanRead-only ⇒ đếm row = 0-bit; đo PRE/POST **cờ** 8 key: 7 key đích 13/0/0/0 → **13/13/13/2**, vế ÂM liệt-kê-toàn-bộ `CanDelete=1` = **đúng 14 row = {Admin,Drafter}×7** (11 role kia D=0), Drafter (non-Admin) C/U/D=1. 🔑 **Control ÂM NỘI-HỌ mạnh nhất từ trước tới nay: `Khkk_G1` bị seeder CỐ Ý bỏ khỏi danh sách 7 key** ⇒ nó phải đứng yên 13/**0/0/0** — và nó đứng yên ⟹ chứng "đúng NGƯỜI làm, đúng TẬP", không phải thứ gì lật bừa cả họ. **Đọc seeder DỰ ĐOÁN `0 added + 91 upgraded` (91=7×13) TRƯỚC khi đo → log prod khớp từng đồng** (`added=0` = đúng đường upgrade, F-S1 đóng). Marker `QT-KHKK-V2-001` grep repo TRƯỚC ⇒ độc quyền 1 site fe-admin ⇒ dự đoán admin=1/user=0, đo đúng; **control ÂM 3 TẦNG**: hash CŨ `D0sXA0fe` → `ct=text/html` 900B **trùng khít hash BỊA** ⇒ 200 là SPA-fallback, bundle cũ đã bị ghi đè. admin js+css rotate (`M8SDA7Ps`/`C3xzT0H9`); user FROZEN nhưng **LM 20:10:00 in-window** ⇒ #69 mode-B lành tính. Restart chứng bằng **w3wp pid=4980 StartTime 20:10:05 TRÙNG dòng CI `App pool started`** + DLL mtime 20:07:50. Label F-7 sống: `?applicableType=10` → `"applicableTypeLabel":"Kế hoạch ký kết HĐ"`, `active:null/history:[]` + sqlcmd `ApplicableType=10`=0 ⇒ chưa dựng WF (đúng W1). Smoke 4 endpoint 200 + **route bịa 404** (chứng 200 CÓ NGHĨA). Durability `Ct_` **637/637** CanRead, root 12, DUPKEYS 0. Evidence: `runs/2026-07-29-S161-khkk-w1-schema/cicd-verify-a8027c0.md`. Tag `[run-427, pass-6-6, do-CO-khong-dem-ROW, control-am-noi-ho-key-bi-bo-sot, du-doan-91-upgraded-khop, control-am-3-tang-bundle, mig69-96-bang, gate-566]` - _(**#426 S159 đợt-5 `ea962b1` menu 6-leaf + `GET /contracts/deleted` + bỏ hero — PASS 9/9**: gate 562, 5m38s. JS rotate cả 2 app (admin `CC1pGE1F`→`D0sXA0fe` · user `CLfAftby`→`Y6dW_5CM` +css `B6bUSFBt`→`6YIAufJR`); admin-css FROZEN nhưng **LM 14:44:29 in-window** ⇒ lành tính (#69 mode-B, khuôn đợt-4 dùng lại được ngay). 🔑 **CỨU FALSE-FAIL — luật MỚI về control ÂM:** brief bảo `Toàn trình 4 giai đoạn` phải VẮNG; tao grep repo-wide TRƯỚC khi đo → chuỗi vẫn sống hợp lệ ở `PePipelineStrip.tsx:24` **`aria-label`** (cả 2 app, có từ đợt-2) ⇒ **dự đoán bundle=1 chứ không 0**, đo đúng 1. Áp máy móc là FAIL OAN. Thay bằng `Quy trình mua sắm` (eyebrow hero) — `grep -rc` 2 app = **0 hit mọi file** ⇒ ĐỘC QUYỀN ⇒ bundle=0 = chứng hero đã gỡ (kèm `UserDashboardPage` 63.124→50.142 B). ⟹ **LUẬT: trước khi nhận 1 chuỗi làm control ÂM phải grep repo-wide xác nhận nó ĐỘC QUYỀN cho thứ mình muốn chứng vắng; chuỗi dùng-chung chỉ làm marker DƯƠNG.** 🔑 **SEEDER-INSERT delta khớp TOÁN (khuôn mạnh, tái dùng):** đo baseline TRƯỚC deploy rồi so SAU restart — `Ct_%_WfView` 0→**7** · `_Approved` 0→**7** · `_Deleted` 0→**7** · `Khkk_%` 5→**7** · nhãn `Ct_%_Pending`=`Đang%` 0→**7** · Dashboard `%quy tr%` 0→**1** · **MenuItems 119→142 = +23 = 7+7+7+2 khớp từng đồng** · root 12 · DUPKEYS 0 · **21 key mới đủ 13/13 canread** (nhánh reviewKeys skip-existing ăn vì key HOÀN TOÀN MỚI — khác đợt-2/3 nơi row `false` sẵn có không được nâng). **Endpoint mới:** `GET /api/contracts/deleted` → **401** + **control route bịa → 404** ⇒ 401 CÓ NGHĨA, không phải catch-all (đừng chỉ đo 401 trần). ⚠️ brief ghi `/contracts/deleted` thiếu prefix — route thật có `[Route("api/contracts")]`. **Durability lần 3:** 38-key **494/494** · control âm Hrm/Off/Personal=0 · `Pe%` 197/185 · `Hdc_` nhãn 7 · 3 root ẩn. ⚠️ **Bẫy phạm-vi mới: `Ct_*` nay đẻ thêm 21 key ⇒ `LEFT(MenuKey,3)='Ct_'` cho ra 59 key, KHÔNG so được với đợt trước — phải NOT LIKE 3 hậu tố mới để giữ đúng tập 38 gốc.** Evidence: `runs/2026-07-29-S159-tong-quan-pipeline-menu/cicd-verify-ea962b1.md`. Tag `[run-426, pass-9-9, control-am-phai-DOC-QUYEN, seeder-delta-khop-toan, 401-voi-control-404, durability-restart-3, query-scope-re-anchor, gate-562]` - **07-31 verify `50e6d8c` S164 K1 SP-002 danh-mục-loại-HĐ (20 file: 11 BE + 6 FE + 1 test + 2 docs, +Mig 70):** ✅ **PASS 6/6** — Run **#434** (id=547) success **6m31s** (dài nhất 4-run gần đây: #431/#432/#433 ~5m50; hợp lý vì +Mig+seed-86+8-test — chưa tới ngưỡng escalate). Gate **598 = 45D + 553I** (0 fail/skip) — Domain **GIỮ 45**, Infra **545→553 = +8** ⇒ delta rơi TRỌN vào Infra đúng nơi file test mới nằm (đối-chiếu TÁCH-PHẦN bắt được điều tổng-số giấu). Mig 70 `20260731072441_AddContractCatalogEntries` **TOP prod**, `sys.tables` 96→**97** khớp `grep -c CreateTable`=**1**. 🔑 **TAM-GIÁC 3 NGUỒN ĐỘC-LẬP** cho seed: source-parse `DbInitializer` == sqlcmd prod == **API materialize qua EF** — cả 3 ra `86` + `1:5·2:10·3:5·4:23·5:14·6:15·7:13·8:1` y hệt; nguồn 3 mạnh nhất vì đi trọn Domain→Infra→Api (200, 25.374 B, distinct-code 86). Serilog `Seeded 86 contract catalog entries (S164 SP-002)` @15:52:27 + control-ÂM findstr chuỗi-bịa 0 hit. Bundle **4/4 ROTATE** (admin `B43R6Y17`→`CKgq0YlH`, user `NLI5umBg`→`CHMCU35C`) + **4/4 hash CŨ rơi `text/html` 876/900 B** = ghi-đè thật; LM 15:51:06/15:52:07 in-window. Smoke 8/8: `/health` bare **404** (control) · `/health/{ready,live}` 200 · endpoint mới không-token **401** kèm **2 route BỊA 404** ⇒ 401 CÓ NGHĨA. w3wp PID 2644 StartTime 15:52:13 in-window + log dòng-đầu `Applying migrations...` ⇒ đo SAU recycle (né #423). ⚠️ **BÀI MỚI — 0-hit là DƯƠNG-GIẢ tới khi soi format**: grep `Passed!` lần đầu **0 hit** chỉ vì log dùng 2-khoảng-trắng (`Passed! - Failed: 0`); suýt báo "không thấy dòng test". Cùng class: parse seeder lần 1 ra **78** (regex line-anchored, tuple xuống dòng) — vứt số, parse lại ra 86 + cross-check `raw code-literal`=86. ⚠️ **hash CI ≠ hash local build** (local dự-báo `BE7zE81C`/`DSXJJbJq`, CI ra khác) ⇒ CẤM lấy hash local làm mốc kỳ-vọng prod, luôn re-snapshot LIVE. Evidence: `runs/2026-07-31-S164-4gd-khkk-fanout/sub-cicd-verify-k1.md`. Tag `[run-434, pass-6-6, tam-giac-3-nguon, 0-hit-la-duong-gia, gate-598, mig-70, hash-CI-khac-local]` - **07-30 verify `bfc7b79` S162 cây-4-folder-GĐ (FE-ONLY, 17 file, 12 FE = 6+6 đối xứng ×2 app):** ✅ **PASS 5/5** — Run **#432** (id=545) success **5m35s**; gate **590 = 45D+545I** (0 fail/skip). 0 mig/0 BE ⇒ không chân EF. Bundle **4/4 ROTATE** (admin js `BBQKvUMa`→`DXoYDy7R` · user js `BV5--mPf`→`o8KDluD1`, css cả 2 đổi); `index.html` LM 10:09:07 in-window + `Cache-Control:no-cache`. 🔴 **BẪY MỚI — MOVING-TARGET `HEAD~1`:** phiên có Stop-hook WAL **tự commit giữa lúc verify** ⇒ `HEAD~1` đổi nghĩa từ 'cha commit đích' thành 'chính commit đích' trong ~6 phút. Tao đã kết SAI '2 marker có sẵn ở parent ⇒ vô giá trị'; đo lại bằng SHA tuyệt đối `8eba137` thì **cả 2 = 0 hit** ⇒ marker hợp lệ. **LUẬT: verify commit X luôn neo `X^..X` bằng SHA, CẤM dùng `HEAD~1`** (mọi repo có hook auto-commit). 🔑 **Khuôn MỚI 'ĐẾM TRỌN HỌ bằng 1 REGEX'**: `pipeline-[a-z-]{0,24}index` quét bundle ra **đúng 3 phần tử** `{contract×2, khkk×1, pe×1}` khớp source element-wise ⇒ vừa là vế DƯƠNG, vừa tự chứng regex không quét bừa (mạnh hơn đếm chuỗi rời). Dự-đoán-trước-khi-đo khớp từng đồng: `contract-index`=2 (= số FILE trong diff) · VN `Kế hoạch Hợp đồng`=**1** (source 3 − **2 comment**) · raw-UTF8 không escape. ⚠️ **suýt FAIL OAN lần nữa:** `Kế hoạch ký kết HĐ` (nhãn strip cũ) = **8/app** — KHÔNG dùng làm control ÂM được vì synthesis ghi rõ nhãn folder GĐ2 **cố ý khác** nhãn strip; 1-mới + 8-cũ cùng sống = chứng phân-biệt-phiên-bản. Control ÂM: chuỗi-BỊA `pipeline-hardcopy-index`=0 (source cũng 0) + hash BỊA & **hash CŨ cả 2 app** đều `ct=text/html` **876B/900B trùng khít size index.html** ⇒ bundle cũ biến mất = ghi đè thật. Smoke 4×200 + bare `/health` **404** (control). WAL-commit `a07b942` (3 file `.md`) bị `paths-ignore` nuốt ⇒ không đẻ run rác. Evidence: `runs/2026-07-30-S162-cay-4-folder-gd/sub-cicd-monitor-2.md`. Tag `[run-432, pass-5-5, CAM-HEAD~1-neo-SHA, dem-tron-ho-1-regex, control-am-DOC-QUYEN-lan-2, gate-590, fe-only]` ### [moved from L1 @S166 curate 2026-08-01] verbatim run entries - **07-31 verify `0779f2d` S164 K2 SP-002 KHKK mang hạng-mục + nhóm duyệt N1-8 (23 file: 9 BE + 8 FE + 3 test + Mig 71 ×3 + 2 ignored-path):** ⚠️ **PARTIAL 5/6** — deploy KHỎE, điểm trừ = **phép đo không có răng**, không phải lỗi ship. Run **#435** (id=548) success **6m12s**. Gate **609 = 45D + 564I** (0 fail/skip) — Domain **GIỮ 45**, Infra 553→**564 = +11** khớp TỪNG VẾ kỳ-vọng "9 lane + 2 gate-fix". Mig 71 `20260731085624_AddKhkkApprovalGroupCatalogAndFinalizeRuntime` TOP prod (MIGCOUNT=71), `sys.tables` **97 GIỮ NGUYÊN** khớp `grep -c CreateTable`=**0** (control dương `grep -c AddColumn`=4). 🔴 **BÀI LỚN NHẤT — ACCEPTANCE RƠI VÀO CHÂN-LÝ-RỖNG**: `ContractSigningPlans` prod **0 dòng cả PRE lẫn POST** ⇒ cả 3 acceptance mục 4 (`COUNT(group=1)==COUNT(*)` → `0==0`; `NOT BETWEEN 1 AND 8`=0; Σ tiền `NULL==NULL`) đều "xanh" mà **0 bit thông tin** — backfill hụt sẽ trông Y HỆT. Tác giả Mig 71 đã khai bẫy này ở comment ("đo local Σ = tập RỖNG hai phía… phép đo prod mới có răng") — nay prod cũng rỗng nốt ⇒ phép đo prod CŨNG hết răng. KHÔNG hạ FAIL (không có gì sai) nhưng CẤM đọc thành PASS. 🔑 **Đối-sách khi acceptance rỗng → thay bằng bằng-chứng KHÔNG-phụ-thuộc-số-dòng**: (a) 4 cột đúng kiểu/null/default qua `INFORMATION_SCHEMA`; (b) **hoán-đổi index chứng bằng LIỆT KÊ TRỌN HỌ 14 index** — 3-cột unique filtered `([IsDeleted]=(0))` CÓ + 2-cột cũ MẤT, vắng-mặt suy từ danh-sách-đầy-đủ nên là vắng-mặt ĐO ĐƯỢC (mạnh nhất mục 4); (c) Σ bất-biến chứng theo **CẤU TRÚC**: grep cột tiền trên Mig 71 ra 2 hit **đều là comment `//` dòng 23-24** ⇒ 0 câu lệnh thực thi, đúng kể cả khi có dữ liệu; (d) EF materialize 200-không-500. 🔑 **MỚI — chứng query-param ĐƯỢC WIRE bằng bind-error**: `?group=abc` → **400** (param lạ mà bị nuốt thì ASP.NET trả 200) + khớp nguồn `Controller:42 [FromQuery(Name="group")] int? group`; `?group=1/2/8` chỉ ra `{"items":[],"total":0}` = VACUOUS. Áp bài K1: soi **thân RAW** trước khi tin parser ⇒ rỗng THẬT. Control DƯƠNG đường-ống list: `/api/catalogs/contract-catalog` **86 item** (seed K1 nguyên) ⇒ ống chạy, `items:[]` là bảng rỗng thật. Bundle **4/4 ROTATE** (admin `CKgq0YlH`→`DVQEwGwf`, user `CHMCU35C`→`CZAYiWWa`) + hash CŨ **và hash BỊA** cùng rơi `text/html` 900/876 B ⇒ `text/html` thật sự nghĩa "không tồn tại"; LM 17:10:20/17:11:20 in-window. Smoke: `/health/{ready,live}` 200 + bare `/health` **404** control · no-token **401** kèm **2 route BỊA 404**. w3wp **PID 5364 = `SolutionErp-Api`** (map PID→pool bằng `appcmd list wp` vì VPS có 6 w3wp chung VIETREPORT — CẤM đoán PID) StartTime 17:11:25 + Serilog dòng-đầu `Applying migrations...` 17:11:27 ⇒ mọi đo DB từ 17:12+ = SAU recycle. Quan sát cho K4b: `?group=999` → **200** (biên API không chặn ngoài-miền 1..8, hiện vô hại); ghost-window `EndedByLevelFinalize` luôn 0 tới khi K3 land = ĐÚNG hiện trạng. Evidence: `runs/2026-07-31-S164-4gd-khkk-fanout/sub-cicd-verify-k2.md`. Tag `[run-435, partial-5-6, chan-ly-rong-vacuous, liet-ke-tron-ho-index, wire-proof-bang-bind-400, gate-609, mig-71, map-PID-pool]` - **S166 (08-01) re-verify `15349e8` K3 — PASS 6/6 `[LEAD SEED ON-BEHALF TẠI-CỬA — mày chết #53 ×2 (lượt-1 session-limit 18:50 @S165 sau §0 · lượt-2 S166 sau §1-§5, return "Smoke is clean" mà §6 chưa ghi đĩa); §6 lead đo lại 4 phép on-behalf, KHÔNG tin lời khai suông]`:** Run **#436** success 6m11s (match theo `head_sha`, control neo run kề = #435 K2). Gate **614 = 45D + 569I** khớp TỪNG VẾ (+5 khớp subject K3); control ÂM `grep -c 'Failed!'` = 0. Mig **GIỮ 71** — mục "GIỮ NGUYÊN" ít bit ⇒ răng lấy từ **control DƯƠNG cùng phiên** (§4 seed chứng startup-hook sống). **§4 = khuôn mẫu dự-đoán-trước-khi-đo**: đọc seeder → dự đoán 8wf×3step×11level + finalize 2+8=10 → sqlcmd khớp TỪNG ĐỒNG + shape element-wise từng email + 3-nguồn-độc-lập (source ⟂ sqlcmd ⟂ Serilog `Seeded 8 KHKK group workflows`) + control ÂM (OUTSIDE=2 nguyên · OUTOFSET=0). **§5 FROZEN-eoffice = hệ-quả bắt-buộc dự-đoán TRƯỚC curl** (diff fe-user 14 dòng toàn `//` comment → Vite strip → byte-identical; marker POS `KhkkN[1-8]` admin=1/eoffice=0 + NEG transition PRE-có-POST-mất; ❌ marker `earlyFinalizeLocked` LOẠI vì tên biến local bị minifier đổi = 0 bit). **Recycle-proof 2 nguồn**: PID 5364→**1900** StartTime 18:27:28 + Serilog dòng-đầu 18:27:40 (deploy xoá logs/). Ghi chú route: KHKK = kebab-case `/api/contract-signing-plans` (đề bài lead ghi nhầm không-gạch). Evidence: `runs/2026-07-31-S164-4gd-khkk-fanout/sub-cicd-verify-k3.md` (§6 + END do lead). Tag `[s166, run-436, pass-6-6, du-doan-truoc-khi-do, frozen-la-he-qua, marker-bien-local-0-bit, chet-53-x2-artifact-cuu, seed-on-behalf-tai-cua]` - **S166 (08-01) verify `88e7ecf` K4a+K4b sidebar 8-nhóm × 6-leaf + nối `?group=` (33 file: 4 BE + 8 FE + 1 test + 20 ignored) — PASS 7/7 `[phủ LUÔN #437 F-1 `7a903cf` chưa verify riêng]`:** Run **#438** success 6m23s (#437 6m22s; chuỗi #436→#437→#438 liền mạch = control neo 2 tầng). Gate **621 = 45D + 576I**; **F-1 = 614 (Infra GIỮ 569, +0)** ⇒ **trọn +7 thuộc K4** — 🔑 **verify 2-run một lượt cho chuỗi delta KHÉP KÍN, quy được test mới về đúng commit** (1 run lẻ không làm được). Mig GIỮ 71. 🔑 **BẮT MỐC PRE ĐỀ BÀI SAI BẰNG ĐO**: lead giao `MENU_TOTAL PRE=143 ⇒ 192`; đo LIVE lúc #438 còn `running` ra **151** → truy phạm-vi thay vì hô drift: K3 đã đẻ 8 row `AwV2_KhkkN1..N8` (liệt kê đủ tên, `AwV2_ALL=10`=2 cũ+8) ⇒ 143+8=151, **kỳ vọng đúng = 200**; đo POST = **200**. ⇒ mốc PRE trong spec luôn phải re-đo, số cũ lão hoá sau MỖI deploy. 🔑 **TAM-GIÁC 3 NGUỒN cho seed**: source-parse (`KhkkGroupNumbers[2..8]×(1+6)`=49; ×13 role=637) ⟂ sqlcmd (menu 151→200, perm 1584→**2221**) ⟂ **Serilog** (`Seeded 49 menu items` + `Backfilled 1 menu labels` + `Seeded 49 admin permissions` + `all-roles: 588 added + 0 upgraded`). 🔑 **phân rã 49+588=637 khớp cơ-chế 2-site skip-existing** (588=49×12 role còn-lại) — con số KHÔNG suy được từ tổng ⇒ bit thật. ⚠️ **PERM row ≠ policy**: `Permissions(RoleId,MenuKey,4 cờ)` = **1 ROW**/cặp; "49×4=196" của đề bài là POLICY authz, cấm cộng vào PERM_TOTAL. 🔑 **A5 restart ×2 THẬT** (`appcmd recycle`, PID 7020→**220**→**6636**, 3 dòng `Applying migrations...`): 8 chỉ số ĐỨNG IM + **soi ĐIỀU KIỆN log trong source trước khi đọc im-lặng** (`if (added>0)` `:2183/:2247/:2310/:2524`) ⇒ vắng dòng ⟺ 0 added (không phải đoán từ im-lặng). Control ÂM #84: `Hrm*/Off*` giữ **29/377** qua cả 3 mốc = revoker vừa SỐNG vừa KHÔNG lố sang `Khkk_*`. 🔴 **MARKER LEAD GỢI Ý BỊ BÁC BẰNG ĐO**: `Kết cấu, hạ tầng, phá dỡ` đã có từ `7a903cf` (git show = 1 hit cả 2 app) ⇒ **đo ra 1/1 trong bundle POST = 0 bit** (sẽ "xanh" kể cả khi K4 không ship). Thay bằng 3 marker có transition: POS `/khkk/list?group=1` **4/4 khớp element-wise số lần trong source** · NEG `/khkk/list?view=deleted` 0/0 (grep repo-wide = độc quyền) · 🔑 **DIFFERENTIAL `workflow-matrix?type=10&group=` admin 0 / eoffice 2** — 2 mũi: chứng bất-đối-xứng CỐ Ý ship + tự chứng comment-strip (hit admin duy nhất nằm trong `//`). Bundle JS ROTATE ×2 (`1yiNV4VH`→`qOcoitOr` · `DoULfmdT`→`D9J3BbcA`), CSS FROZEN lành tính, 4 LM in-window; control 2 tầng hash-CŨ **và** hash-BỊA cùng text/html 900/876. A1 Procurement+Drafter **8 group + 48 leaf**; A1-bis `/api/menus/me` materialize qua EF **8 grp + 42 leaf + 6 cũ = 56** + 8 nhãn đúng dấu. Smoke 401/401 + **2 route bịa 404** + 200×4; 🔑 **gỡ giới-hạn phép đo**: `?group=abc` no-token = 401 (authz chặn trước bind) → lấy bearer re-probe ra **400 bind-error** ⇒ chứng `?group=` wire THẬT. ⚠️ Treo cho wave sau: bảng vẫn **0 dòng** ⇒ `?group=n` chứng ống+bind, KHÔNG chứng lọc-đúng-nhóm (chân-lý-rỗng kế thừa K2); `?group=999`→200 chưa chặn ngoài-miền. Evidence: `runs/2026-07-31-S164-4gd-khkk-fanout/sub-cicd-verify-k4ab.md`. Tag `[s166, run-438, pass-7-7, phu-2-run-delta-khep-kin, moc-PRE-de-bai-sai, marker-lead-0-bit-bac-bang-do, differential-marker, log-condition-truoc-khi-doc-im-lang, gate-621]`