Files
solution-erp/.claude/workflows/runs/2026-08-01-S169-bookend-open/sub-harvest-curator-sleep-batchA-S170.md
2026-08-03 09:57:05 +07:00

111 KiB
Raw Blame History

sub-harvest-curator — /sleep-recovery-memory-l2 Phase 1 (GATHER + DEDUP) — batch A/2 — S170

Vai: harvest-curator (H2) · PROPOSE-ONLY — file này là kênh run-trace B4/B6, KHÔNG phải ghi trí-nhớ. Batch A = cicd-monitor (5 verbatim) + implementer-backend (4 verbatim) = 9 file gen-0. Phương-pháp: đóng-kín TỪNG file (chống cross-file bleed) — cụm-dedup + importance-tag + bản-nén-nháp 4-field SE + danh-sách token. Khung 4-field SE: VIỆC · KẾT-LUẬN(+commit/file:line) · BÀI-HỌC · BẤT-NGỜ — rút gọn câu chữ, KHÔNG bỏ field. Token-list = nguyên-liệu coverage-diff của lead: {surprise · guard · file:line · root-cause · gotcha#}. Thiếu = gate FAIL. Lưu ý đọc: mọi token dưới đây trích NGUYÊN VĂN từ verbatim gen-0; bản-nén là ĐỀ-XUẤT, chưa phải bản chốt.


cicd-monitor/2026-05-q2 (3.877 B — "Archive Recent Runs Q2, Plan B detail")

Đặc-điểm file: 1 entry DUY NHẤT (Run #231) + header-rule. Archive S32 em-main proxy curate, lý-do = MEMORY.md 27KB → target ~24KB.

Cụm-dedup

# Cụm Thành-phần gộp Tag
A1 Run #231 Plan B Contract V2 wire — VERDICT=PARTIAL deploy PASS (3m30s, bundle 2/2 rotate, Mig 32+33 applied, 5/5 smoke, V1 compat) + seed PARTIAL vừa
A2 DISCOVERY #6 — DemoSeed flag nuốt seed V2 → gotcha #51 phát-hiện + log-evidence + 2 fix-option (a) admin-tạo-tay / (b) carve-out + escalate + Resolution Run #232 38f1c4d chọn (b) cao
A3 Test-gap: ~150 LOC ApproveV2Async 0 test (đúng khuôn gotcha #48 high-risk) test baseline 111 unchanged + khuyến-nghị Plan B+1 cao
A4 SlaExpiryJob ERR cluster 5 entry — nhiễu prod CÓ TRƯỚC, KHÔNG liên-quan Plan B 4 transition V1 fail + phán-định unrelated + escalate riêng thấp

Ghi-chú dedup: A2 vốn nằm rải 2 đoạn (phát-hiện ở thân + Resolution ở dòng cuối) — gộp 1 cụm vì cùng một sự-kiện đóng-mở.

Bản-nén-nháp 4-field

[cao] A2+A3 — Run #231/#232 Plan B Contract V2 (PARTIAL → đóng)

  • VIỆC: Verify Run #231 (id=345) push 6eec8d7..3e92584 11 commit — Plan B wire Contract V2 (Mig 32/33 + ApproveV2Async + 6 FE × 2 app).
  • KẾT-LUẬN: VERDICT=PARTIAL — deploy PASS (CI 3m30s; bundle 2/2 rotate leEMWFLU→BBADl46y + Dgn1iU9E→DA_VI3zO; Mig 32 20260522051059_AddApprovalWorkflowToContract + Mig 33 20260522052240_AddContractLevelOpinions applied prod; API 200 + 5/5 smoke; 7 HĐ V1 nguyên-vẹn) nhưng SEED PARTIAL: QT-HD-V2-001 0 row (ApplicableType=3) ⇒ dropdown FE rỗng ⇒ V2 KHÔNG test được E2E. Đóng bằng Run #232 38f1c4d carve SeedSampleContractWorkflowV2 ra khỏi DemoSeed-gate (option b) + gotcha #51.
  • BÀI-HỌC: deploy-xanh ≠ feature-dùng-được — phải verify DỮ-LIỆU SEED (sqlcmd đếm row đúng ApplicableType), không dừng ở bundle-hash + smoke-200. Và: refactor >100 LOC (ApproveV2Async ~150 LOC) đi kèm 0 test = đúng khuôn rủi-ro gotcha #48, UAT-skip-test không áp cho scope refactor.
  • BẤT-NGỜ: thứ chặn feature lại là feature-flag CỐ Ý (DemoSeed:Disabled=true, thiết-kế Plan T S23 t10 để UAT sạch), không phải bug — 2 chủ-đích đúng đắn va nhau; và CICD-monitor từ chối tự quyết (a) hay (b), escalate em-main.

[thấp] A4 — SlaExpiryJob ERR cluster

  • VIỆC: phân-loại 5 entry ERR 12:58:16 nổi lên cùng lúc deploy.
  • KẾT-LUẬN: pre-existing V1 noise — ConflictException Transition X→Y không hỗ trợ trên 4 cặp phase (DangInKy→DangKiemTraCCM, DangSoanThao→DangGopY, DangGopY→DangDamPhan, DangTrinhKy→DongDau); 0 dính V2; 0 regression.
  • BÀI-HỌC: log-ERR trùng cửa-sổ deploy ≠ do deploy — phải soi enum/phase trong message để quy trách.
  • BẤT-NGỜ: job auto-approve V1 vẫn đang fail âm-thầm trên HĐ legacy, tách hẳn thành việc điều-tra riêng.

Token-list (verbatim, cicd-monitor/2026-05-q2)

  • gotcha#: #48 (dẫn — refactor >100 LOC Service chạm changelog/audit) · #51 (SINH MỚI — DemoSeed gate) · "44 gotchas cross-ref" (không ở file này, xem q3)
  • surprise: CRITICAL DISCOVERY #6 (NEW gotcha to add) · "seed gap is feature-flag design choice not deploy failure" · "Decision NOT for CICD Monitor — escalating" · "0 new tests added Plan B (~150 LOC ApproveV2Async NO test cover)" · "bro UAT ... V2 wire E2E NOT testable UAT mode"
  • guard: DemoSeed:Disabled=true feature-flag gate · Reviewer ApplicableType=Contract guard (hotfix commit trong range) · paths-ignore/test-gate 111 baseline · feedback_uat_skip_verify (rule được viện-dẫn) · Rule §6.5 "KHÔNG cắt narrative"
  • root-cause: "DemoSeed feature flag gates Plan B Chunk A2 sample V2 workflow seed" ⇒ QT-HD-V2-001 NOT seeded in prod (0 rows ApplicableType=3) ⇒ V2 endpoint trả {"active":null,"history":[]} ⇒ dropdown Create rỗng
  • file:line / định-danh: log 2026-05-22 12:57:44 [INF] DemoSeed:Disabled=true → skip workflow + contracts + PE + sample V2 seed (Plan T S23 t10 + Plan B Chunk A2 Contract V2) · SeedSampleContractWorkflowV2 · ApproveV2Async (~150 LOC) · Run #231 id=345 · Run #232 sha=38f1c4d · push range 6eec8d7..3e92584 (11 commit) · Mig 32 20260522051059_AddApprovalWorkflowToContract · Mig 33 20260522052240_AddContractLevelOpinions · cột ApprovalWorkflowId + CurrentApprovalLevelOrder · bảng ContractLevelOpinions (0 row) · bundle leEMWFLU→BBADl46y (admin) / Dgn1iU9E→DA_VI3zO (user) · QT-HD-V2-001 (ApplicableType=3) / QT-DN-V2-001 v1+v2 (ApplicableType=1) · CI 3m30s 12:54:24→12:57:54 · SlaExpiryJob 5 ERR @12:58:16 · 4 transition DangInKy→DangKiemTraCCM / DangSoanThao→DangGopY / DangGopY→DangDamPhan / DangTrinhKy→DongDau · archive-header: S32 curate, 27KB→~24KB, ngưỡng 25KB

cicd-monitor/2026-05-q3 (3.949 B — "Archive Q3, S34 curate")

Đặc-điểm file: 3 entry — 1 cặp FAIL→PASS (dày), 1 verify cumulative, 1 setup-baseline.

Cụm-dedup

# Cụm Thành-phần gộp Tag
B1 Cặp Run #215 FAIL → #216 PASS = gotcha #48 SQLite tie-break 2 test fail cùng root-cause + phân-tích tie-break + fix .Where(Summary Contains) + 8 phút turnaround + nhận-định "UAT skip-test rủi-ro cho refactor" cao
B2 Verify S22 chốt cuối + Discovery #3 **/*.md glob nuốt CI 12 commit PASS/104 test/Mig 30 + giả-thuyết spec BỊ BÁC + gotcha #47 hạ xuống vai-trò PREVENTIVE cao
B3 Setup baseline 2026-05-12 khởi-tạo agent, 44 gotcha + 5-stage + 3 skill, 0 run thấp

Ghi-chú dedup: B1 vốn là 2 mục Run riêng nhưng verbatim đã tự gộp title "catch+fix pair" — giữ 1 cụm, KHÔNG tách (tách sẽ mất mạch nhân-quả).

Bản-nén-nháp 4-field

[cao] B1 — Run #215 FAIL → #216 PASS (gotcha #48)

  • VIỆC: Verify Plan AB Chunk A (Changelog visibility: Bug 1 Budget Adjust + Bug 2 Return Mode) — 1 commit 3 file, BE PurchaseEvaluationWorkflowService.cs +207/-95 + 2 FE PeDetailTabs.tsx.
  • KẾT-LUẬN: #215 (id=329, cdfd542, push e23f51c..cdfd542) FAIL ở test_infra 51/53 — 2 test ReturnMode báo Expected changelog.ContextNote not to be <null>; deploy KHÔNG chạy (bundle giữ nguyên Run #214, Mig 31 TOP 1 y cũ). #216 (id=330, 8c05947) PASS — chỉ sửa TEST (+7/-2) thêm .Where(c => c.Summary!.Contains("Chuyển phase")) trước OrderByDescending(CreatedAt).First(); code Chunk A không revert; 58/58 + 53/53, bundle 2/2 rotate, 10:13→10:21 = 8 phút.
  • BÀI-HỌC: SQLite + clock đóng-băng ⇒ 2 changelog cùng CreatedAtOrderByDescending tie-break trả nhầm bản-ghi ⇒ test "lấy entry mới nhất" là thước không xác-định; phải lọc theo NỘI-DUNG (Summary) chứ đừng dựa thứ-tự thời-gian. Refactor BE >100 LOC nên dotnet test local TRƯỚC push — UAT skip-test không đủ.
  • BẤT-NGỜ: test đỏ mà code sản-phẩm đúng — lỗi nằm ở thước đo; và CI test-gate chặn đúng lúc nên bro tránh được audit-trail vỡ trên prod (fail lại hoá may).

[cao] B2 — Verify S22 cumulative + Discovery #3 (glob **/*.md)

  • VIỆC: Verify chốt S22, push 3d725c4..cc8a7d3 12 commit (Plan C/D/E + Mig 30 F4 per-NV Approver edit Budget).
  • KẾT-LUẬN: VERDICT=PASS — 33 user active prod, bundle 2/2 rotate, 104/104 test (+1 so baseline S21=103), Mig 30 xác-nhận prod. Discovery #3: commit cc8a7d3 gồm docs + 4 agent MEMORY.md vẫn bị CI SKIP vì glob **/*.md khớp .md ở MỌI độ sâu.
  • BÀI-HỌC: glob **/*.md trong paths-ignore khớp cả file .md nằm sâu trong .claude/agent-memory/ ⇒ giả-thuyết "thư-mục đó sẽ trigger CI" bị bác bằng quan-sát, không bằng suy-luận.
  • BẤT-NGỜ: gotcha #47 KHÔNG chết mà đổi vai — vẫn đúng như biện-pháp PHÒNG cho file state non-.md tương-lai dưới .claude/agent-memory/.

[thấp] B3 — Setup baseline

  • VIỆC: khởi-tạo CI/CD Monitor 2026-05-12.
  • KẾT-LUẬN: nạp nền: 44 gotcha cross-ref + checklist 5-stage + 3 skill preload + khuôn verify bundle-hash; chưa monitor run nào.
  • BÀI-HỌC: vai bắt đầu bằng NỀN tri-thức + checklist, không bắt đầu bằng run.
  • BẤT-NGỜ: (không có — entry mốc; giữ vì là gốc truy-vết baseline 44 gotcha / 5-stage.)

Token-list (verbatim, cicd-monitor/2026-05-q3)

  • gotcha#: #48 (SQLite tie-break — cặp catch+fix) · #47 (đổi vai → PREVENTIVE) · dải nền #39-#52 · "44 gotchas cross-ref" (baseline 05-12)
  • surprise: Discovery #3 first surfaced + "Spec hypothesis ... disproven for this commit" · "Side benefit: CI test gate caught BEFORE prod deploy — bro UAT spared broken Plan M edge case audit trail" · "Plan AB Chunk A code cdfd542 KHÔNG bị revert" · "Demonstrates test-after UAT mode CAN tolerate edge case bug if next chunk lands within minutes — but ... UAT skip-test rule risky for refactor scope" · "Deploy NOT shipped ... bro UAT screenshot pre-deploy stale"
  • guard: test-gate CI chặn trước deploy (test_domain + test_infra) · .Where(c => c.Summary!.Contains("Chuyển phase")) (fix-guard chọn đúng entry) · paths-ignore glob **/*.md · Stage 4.6 sqlcmd seed verify (header) · 5-stage checklist + 10-surface-point per-NV (header)
  • root-cause: ApplyReturnModeAsync thêm Changelog MỚI (EntityType=Workflow + Action=Update + Summary, khôngContextNote) ở cuối, cùng SaveChangesAsync với LogTransitionAsync (có ContextNote=comment) ⇒ SQLite + frozen test clock ⇒ cùng CreatedAt.OrderByDescending(c => c.CreatedAt).FirstAsync() tie-break trả nhầm entry Workflow · Discovery #3 root-cause: glob **/*.md khớp .md ở mọi độ sâu
  • file:line / định-danh: PurchaseEvaluationWorkflowService.cs +207/-95 · ApplyReturnModeAsync line 403-412 · LogTransitionAsync line 100 · PeDetailTabs.tsx (2 FE mirror filter) · test PurchaseEvaluationWorkflowServiceReturnModeTests.ApplyReturnMode_OneStep_AtStep1_ResetsToBuoc1Cap1_KeepsChoDuyet · test ...ApplyReturnMode_OneLevel_AtStep1Level1_ResetsToBuoc1Cap1_KeepsChoDuyet · lỗi Expected changelog.ContextNote not to be <null> · Run #215 id=329 cdfd542 (1m06s) / Run #216 id=330 8c05947 (+7/-2) · push e23f51c..cdfd542 · Run #214 (baseline bundle) · Mig 31 TOP 1 · Run S22: push 3d725c4..cc8a7d3 12 commit, Mig 30 F4, 33 user, 104/104 (baseline S21=103) · commit cc8a7d3 (docs + 4 agent MEMORY.md → CI SKIPPED) · PE c6e9 · 51/53 → 58/58 + 53/53 · 10:13→10:21 (8 phút) · setup 2026-05-12

cicd-monitor/2026-05-q4 (10.576 B — "late May, S32-S34 verbose Run entries")

Đặc-điểm file: 7 entry — 3 Run deploy (#238, #237, #350) + 3 snapshot phi-deploy (S33 startup, S32 wrap, S32 startup) + 1 cumulative-Run S26. Archive S36 startup curate.

🔴 Coverage-note cho lead: header (dòng 3) khai archive gồm "Discovery #8 NEW collection naming" nhưng THÂN FILE 0 hit Discovery #8 — nội-dung nằm ở entry S35/S36 KHÔNG thuộc file này. Đây là con-trỏ mồ-côi trong header, không phải mất dữ-liệu; khi nén đừng chép nhãn #8 vào bản-nén của file này (sẽ thành cite-bịa).

Cụm-dedup

# Cụm Thành-phần gộp Tag
C1 Chuỗi 3 Run module-mới S33→S34 (#350 → #237 → #238) — Hrm schema → Hrm wire → Office directory 3 entry Run, cùng khuôn: ALL-PASS 5 stage + Stage 4/4.6 sqlcmd + menu-seed verify + Pattern 12-bis cookie-cutter; bundle-chain nối liền 3 mốc cao
C2 Snapshot phi-deploy S32×2 + S33×1 (startup/wrap/health-check) trùng nặng: cert notAfter · 3-endpoint smoke 200 · bundle baseline · "foundation entries CONFIRMED preserved" · docs-only skip #41 · MEMORY size-watch vừa
C3 DISCOVERY #7 — paths-ignore thiếu eval/** ⇒ deploy lãng-phí tách khỏi C2 vì là phát-hiện có hành-động, không phải snapshot cao
C4 S26 Run #222-#227 — khuôn "hybrid verify" (spawn 1× đầu Phase, self-verify polish) 1 entry, nhưng là bài-học KINH-TẾ spawn (ROI), giá-trị dài-hạn cao
C5 3 ca "gotcha KHÔNG xảy ra" + 1 ca "test bắt được 0" (rải trong C1) #1 MediatR / #44 silent-403 / #51-áp-đúng / BW1-7 caught NOTHING vừa

Ghi-chú dedup: C2 gộp 3 entry vì cùng nội-dung tái-khẳng-định (cert 2026-07-23, smoke 200, foundation preserved) — chỉ 3 dữ-kiện là RIÊNG: MEMORY 24.9KB/221 dòng (S32-start), MEMORY 27→24.2KB + agent-id (S32-wrap), Mig TOP 5 + last-5-Run (S33-start). C5 cố-ý tách vì "âm-tính" dễ bị nén mất mà lại là bằng-chứng khuôn đã ổn-định.

Bản-nén-nháp 4-field

[cao] C1 — Chuỗi deploy 3 Run module-mới (Hrm → Office), ALL PASS

  • VIỆC: Verify 3 Run liên-tiếp: #350 48a99e1 (Mig 34 EmployeeProfile 17 entity + Plan C test BW1-BW7) → #237 79a8343 (Hrm CQRS endpoint + FE 2 app + menu seed) → #238 ea440da (Office /api/directory Danh bạ nội bộ BE+FE 2 app).
  • KẾT-LUẬN: 3/3 PASS (3m38s / 3m50s / ~3m30s). Test 58+62=120/120 giữ nguyên từ #350 trở đi (62 = 53 baseline + 9 BW). Bundle-chain khớp liền mạch: admin BUTKoqRP(#350 giữ)→CqGMUMOr(#237)→ChA9_vP5(#238); user CMHv2GS4C_HKyxBeDCpX7akt. Mig 34 20260526110207_AddEmployeeProfiles TOP 1 xuyên cả 3. Seed verify sqlcmd: EmployeeProfiles 33 row (16 demo + 14 Solutions thật + 3 admin/test) + EmployeeCodeSequences NV/2026 LastSeq=33 khớp nguyên-tử; menu key Hrm+Hrm_HoSo rồi Off+Off_DanhBa (+2 row Permission auto-grant); /api/directory trả 13.6KB/34 dòng phủ đủ 9 phòng ban.
  • BÀI-HỌC: khuôn Pattern 12-bis cookie-cutter mirror (PE→Hrm→Office) chạy end-to-end không cần đăng-ký thủ-công: namespace mới SolutionErp.Application.Office được MediatR auto-discover. Verify module-mới phải gồm 3 lớp: build/test → bundle-rotate → sqlcmd seed + menu-key + permission-row (bundle xanh không nói gì về seed).
  • BẤT-NGỜ: cả 3 Run không bắt được lỗi nào — kể cả bộ test BW1-BW7 vừa thêm cũng "caught NOTHING, all PASS first try"; và LastSeq=33 khớp đúng 33 row là bằng-chứng codegen nguyên-tử không rò.

[cao] C3 — DISCOVERY #7: eval/** ngoài paths-ignore

  • VIỆC: rà vì sao Run #234 b223466 (3m52s) chạy dù commit chỉ là docs + eval/*.json của S31 RAG.
  • KẾT-LUẬN: paths-ignore thiếu eval/** ⇒ mọi commit telemetry RAG kích deploy ~3m30s vô-ích (0 thay-đổi code); đề-xuất em-main cân thêm 'eval/**' nếu tần-suất tăng. (Đối-chứng: b832f43..5400983 4 commit docs-only SKIP đúng theo #41.)
  • BÀI-HỌC: path-filter phải rà theo thư-mục MỚI sinh ra (eval/, telemetry) — filter đúng hôm qua thành thủng hôm nay khi repo mọc thư-mục mới.
  • BẤT-NGỜ: cùng một filter vừa đúng (skip 4 commit docs) vừa thủng (chạy eval/**) trong cùng cửa-sổ vài ngày — sai-sót là VẮNG-MẶT một dòng, không phải dòng sai.

[cao] C4 — Khuôn "hybrid verify" (S26, Run #222-#227)

  • VIỆC: Plan AG series (PE List tree-view) 6 Run liên-tiếp — chọn cách verify tiết-kiệm.
  • KẾT-LUẬN: spawn CICD-Monitor 1 lần ở Run #222 0bf6c7e (bundle 2/2 rotate C8TvDy7r→CWHIdoFo / BvcWrq2z→Bg2FNeIz, smoke 5/5 200, PE List API giữ 9 field, test-gate 111, Mig 31 y cũ); #223-#227 (AG2-AG6) em-main tự verify (bundle mắt-thường + push OK + Gitea auto-trigger 3-4 phút). AG4 cross-stack (DTO +4 field Drafter*/Department* + 3 projection JOIN) chạy dotnet test 111/111 local trước push. 0 regression toàn cụm.
  • BÀI-HỌC: ROI spawn: 1× đầu Phase-wire là đủ cho kịch-bản 1 dev solo lặp nhanh; chunk polish (CSS/UX/copy) tự verify — re-spawn ~150K × N là phí.
  • BẤT-NGỜ: cách rẻ hơn lại không giảm an-toàn — vì chunk polish không đụng shape API; ranh-giới "được tự verify" là có/không đổi hợp-đồng dữ-liệu, chứ không phải kích-thước diff.

[vừa] C2 — Snapshot phi-deploy S32/S33 (hạ-tầng + tự-kiểm)

  • VIỆC: 3 lượt spawn read-only không có deploy nào để soi (S32 startup, S32 wrap, S33 health-check).
  • KẾT-LUẬN: VERDICT=HEALTHY — 0 unpushed (HEAD=5400983), 5 Run gần nhất SUCCESS (#235/#234/#233/#232/#231), 3 endpoint smoke 200 (0.23s/0.29s/0.31s), Mig prod TOP 5 khớp repo không drift (33→32→31→30→29), cert api.solutions.com.vn notAfter Jul 23 01:58:16 2026 GMT (~58 ngày, auto-renew ~2026-06-23 cửa-sổ win-acme 30d). Tự-kiểm: MEMORY 24.9KB/221 dòng sát ngưỡng 25KB → sau curate còn 24.2KB; RAG 2949 chunk, search_memory top rerank 0.906.
  • BÀI-HỌC: phiên không-deploy vẫn có việc: canh cert · drift Mig · kích-thước MEMORY · sức-khoẻ RAG — và ghi lại baseline bundle-hash để lượt sau có mốc so.
  • BẤT-NGỜ: /healthz trả 404 — canonical là /health/live; và Gitea API gọi unauth (token rỗng) vẫn đọc được lịch-sử Run.

[vừa] C5 — Bốn ca "âm-tính" đáng giữ

  • VIỆC: ghi nhận các bẫy ĐÃ BIẾT nhưng KHÔNG tái-diễn trong 3 Run.
  • KẾT-LUẬN: gotcha #1 không dính (namespace Application.Office mới vẫn được MediatR auto-discover); gotcha #44 silent-403 không thấy ([Authorize] mức class trên DirectoryController cho mọi user đã đăng-nhập); gotcha #51 được áp đúng chiều (SeedDemoEmployeeProfilesAsync cố-ý KHÔNG gate DemoSeed:Disabled vì là seed HẠ-TẦNG); EmployeeProfiles 33 không tăng ở #237 = guard idempotent chạy.
  • BÀI-HỌC: ghi cả kết-quả ÂM-TÍNH có chủ-đích — nếu chỉ ghi lỗi, lần sau không ai biết bẫy đã được kiểm hay bị bỏ quên.
  • BẤT-NGỜ: bài-học từ #51 (seed bị gate nhầm) đã đảo thành tiêu-chí phân-loại DEMO-seed ⟂ INFRASTRUCTURE-seed và được viện-dẫn chủ-động ở Run sau.

Token-list (verbatim, cicd-monitor/2026-05-q4)

  • gotcha#: #1 (MediatR auto-discovery — KHÔNG dính) · #41 (path filter docs-only skip — dẫn 3 lần) · #44 (silent 403 — NOT observed) · #48 (SQLite tie-break — foundation preserved ×2) · #51 (INFRASTRUCTURE vs DEMO seed — dẫn + áp)
  • Discovery#: #5 (sqlcmd pattern — "UPDATED from") · #6 (INFRASTRUCTURE vs DEMO seed Stage 4.6) · #7 (NEWpaths-ignore thiếu eval/**) · #8 (chỉ có ở HEADER dòng 3 "NEW collection naming", 0 hit trong thân — con-trỏ mồ-côi)
  • surprise: DISCOVERY #7 NEW: path filter paths-ignore MISSING eval/** → ... triggered ~3m30s deploy wastefully (no code change) · Gotcha #44 silent 403 NOT observed · Application/Office namespace mới auto-discovered MediatR — KHÔNG gotcha #1 · Plan C BW1-BW7 ROI: test gate caught NOTHING this run (all PASS first try) · SeedDemoEmployeeProfilesAsync correctly NOT gated DemoSeed:Disabled per gotcha #51 lesson · EmployeeProfiles total=33 (unchanged Run #350 baseline — idempotent guard skip) · /healthz 404 N/A — /health/live canonical · Gitea API unauth (token empty OK) · Pattern saved: CICD Monitor spawn 1× đầu Phase wire ROI tốt ... re-spawn ~150K × N wasteful · bundle hash 2/2 UNCHANGED (... expected NO FE) · Pattern 12-bis cross-module mirror reaffirmed strong
  • guard: class-level [Authorize] trên DirectoryController · idempotent guard skip (EmployeeProfiles 33 không đổi) · DemoSeed:Disabled gate (và ca cố-ý không gate) · paths-ignore + glob **/*.md · Stage 4 + Stage 4.6 sqlcmd seed verify · test-gate CI + "Implementer Reviewer pre-commit gate strong" · MEMORY ngưỡng 25KB · win-acme cửa-sổ renew 30d · EmployeeCodeSequences LastSeq nguyên-tử · BW-guard: BW4 ForbiddenException outsider · BW5 wrong ApplicableType · BW6a UNIQUE composite · BW6b UPSERT 1 row · BW6c Cascade delete · BW7 V1 fallback ConflictException
  • root-cause: eval/** KHÔNG có trong paths-ignore ⇒ commit eval/*.json (S31 RAG) kích deploy vô-ích · **/*.md khớp mọi độ sâu ⇒ commit docs+MEMORY bị SKIP đúng thiết-kế · seed hạ-tầng từng bị nhốt nhầm sau DemoSeed (bài #51) ⇒ tiêu-chí tách DEMO ⟂ INFRASTRUCTURE
  • file:line / định-danh: Run #238 ea440da push edba4ae..ea440da 2 commit/23 file (7b0781b curate 4 agent MEMORY = 8 file MD) · DirectoryFeatures.cs · DirectoryController.cs route /api/directory · MenuKeys.cs (+Off, Off_DanhBa) · DbInitializer.cs · FE ×2 app: types/directory.ts, pages/office/InternalDirectoryPage.tsx, App.tsx, Layout.tsx, menuKeys.ts · directory 13.6KB / 34 row / 9 phòng ban · bundle CqGMUMOr→ChA9_vP5 + C_HKyxBe→DCpX7akt · namespace SolutionErp.Application.Office · ~25K token · Run #237 79a8343 3m50s push 48a99e1..79a8343 3 commit/18 file (0e191de Task 4+6 · 9616ae2 Task 5 FE ×2 · 79a8343 MEMORY 3 agent) · EmployeesController + EmployeeDtos + EmployeeFeatures · /api/employees GET list + paged page=1&pageSize=5 · bundle BUTKoqRP→CqGMUMOr + CMHv2GS4→C_HKyxBe · key Hrm + Hrm_HoSo · mẫu NV/2026/0007 (BOD 1 — Director, Ban Giám đốc, hireDate 2021-08-01) · ~30K token · Run #350 48a99e1 3m38s push 5400983..48a99e1 4 commit/34 file (1bc6b70 docs 3 MD · b3444a3 3 MEMORY · 0605f19 Plan C +4 test file +9 [Fact]/Theory · 48a99e1 Mig 34 + 17 entity/config new + 7 modified) · test_infra 62/62 = 53 + 9 BW (BW1 happy Cấp 1→2 · BW2 terminal DaPhatHanh + gen mã · BW3 skipToFinal F2 admin opt-in · BW4-BW7 xem mục guard) · build_be +6555 LOC · Mig 34 20260526110207_AddEmployeeProfiles · SeedDemoEmployeeProfilesAsync · EmployeeProfiles 33 (16+14+3) · NV/2026/0001-0003 EmployeeStatus=1 Active Nationality="Việt Nam" · ~30K token · S33 startup: HEAD=5400983 · 5 Run: #235 1e1c9a2 3m38s / #234 b223466 3m52s / #233 e199603 / #232 38f1c4d / #231 3e92584 · skip range b832f43..5400983 · smoke api/health/live 0.23s + admin 0.29s + eoffice 0.31s · sqlcmd ssh vietreport-vps "powershell ... '.\\SQLEXPRESS' -E" · Mig TOP 5: AddContractLevelOpinions(33) → AddApprovalWorkflowToContract(32) → RefactorSkipToFinalToApproverLevel(31) → AddAllowApproverEditBudgetToLevels(30) → RefactorAdvancedOptionsToPerLevelAndDrafterUser(29) · cert api.solutions.com.vn notAfter Jul 23 01:58:16 2026 GMT · bundle baseline index-BUTKoqRP.js / index-CMHv2GS4.js · ~12K token · S32 wrap: agent id a505a02d84fc1fabe · MEMORY 27→24.2KB · 5 commit docs-only · cert 2026-07-23 (openssl s_client) · Plan G 11 module backlog · BW1-BW7 spec ready · 3 trigger chờ S33 (a) G-H1 Hồ sơ NS · (b) BW test bundle · (c) UAT smoke V2 contract · ~3K token · Tag [wrap, phase-9-to-phase-10, cicd] · S32 startup: MEMORY 24.9KB / 221 lines · search_memory query "Run 232 Plan B Hotfix CICD SeedSampleContractWorkflowV2" rerank 0.906 / 0.828 / 0.816 · RAG 2949 chunk · last push f938bf5 (S31 docs patch cicd-monitor.md) · ~10K token · S26: Run #222 0bf6c7e ~12K · bundle C8TvDy7r→CWHIdoFo + BvcWrq2z→Bg2FNeIz · smoke 5/5 200 · PE List API 9 field · test-gate 111 · Mig 31 unchanged · Run #223-#227 = Plan AG2-AG6 · AG4 DTO +4 field DrafterUserId/DrafterName/DepartmentId/DepartmentName + 3 projection JOIN Users+Departments · dotnet test 111/111 local pre-push · ~150K × N wasteful

cicd-monitor/2026-05-runs (59.848 B — "Archive Runs Q2, Run #186 → #221 / S21 t3 → S25 Plan AF")

Đặc-điểm file: file LỚN NHẤT batch A. 3 phần: (a) "Last curate logs" 6 mục tóm-tắt · (b) "Run entries archived" 20 mục Run đầy-đủ · (c) "Key patterns extracted (cumulative S21-S25)" 8 mục = lớp chưng-cất có sẵn. Header khai nguồn MEMORY.md ~72KB/~211 dòng/~14 entry → mục-tiêu ~25-30KB.

🔴 3 cảnh-báo cho lead TRƯỚC khi nén: (1) TRÙNG NỘI-FILE: phần (a) và phần (b) chồng nhau 4 lần — #202 (dòng 16 vs 88) · #203 (20 vs 109) · #210 (24 vs 145) · #219 (36 vs 168). Nhưng #215 (dòng 28) và #217 (dòng 32) CHỈ có ở phần (a) — nếu nén bằng cách "bỏ phần tóm-tắt, giữ phần đầy-đủ" thì mất trắng Run #217 (Plan AC, nguồn duy nhất của pattern "capture pre-call mutation state" + Discovery #5). (2) TRÙNG LIÊN-FILE (chỉ báo, KHÔNG gộp — giữ đóng-kín): mục "Verify S22 chốt cuối cumulative" có ở cả file này (dòng 54, bản DÀY) lẫn 2026-05-q3.md (dòng 22, bản MỎNG); Run #215 có ở cả hai (dòng 28 mỏng ở đây / q3 dòng 10 dày). ⇒ khi lead hợp-nhất phải chọn bản DÀY hơn, đừng chọn theo thứ-tự file. (3) 🔐 BÍ-MẬT LỘ TRONG FILE (ưu-tiên cao, ngoài phạm-vi nén): dòng 48 chứa mật-khẩu DB prod dạng thôappsettings.Production.jsonC:\inetpub\solution-erp\api\, user=vrapp + pwd=<24 ký-tự, CỐ Ý KHÔNG chép lại ở đây>. File này git-tracked. Đề-xuất em-main: (i) khi nén redact chuỗi đó, (ii) cân nhắc xoay mật-khẩu vì đã nằm trong lịch-sử git. Vai này KHÔNG tự sửa (propose-only).

Cụm-dedup

# Cụm Thành-phần gộp (Run) Tag
D1 Chuỗi hotfix per-NV lookup discrimination → checklist 10 điểm #194 PARTIAL (K3 DTO thiếu field) → #195 (K10, chốt 8 điểm) → #201 (Plan N, điểm 9) → #202 (Plan O, 4 site cascade) → #203 (Plan P, điểm 10) cao
D2 Saga Discovery #3 — paths-ignore xét TRỌN push-range #188 (Discovery #2) → S22-chốt (bác giả-thuyết) → #200 (bất-thường) → #201 (lần 2) → #202 (lần 3, chốt) → #210 (lần 4, không áp-dụng) → Key-pattern 1 cao
D3 Chuỗi audit-trail S25 (Plan AB→AF) #215 FAIL → #217 (AC) → #218 (AC2) → #219 (AD) → #220 (AE) → #221 (AF) cao
D4 Chuỗi schema Mig 28→31 + backfill #186 (Mig 28) · #187 (Mig 29 + backfill 48/48 & 0/13) · #188 (Plan C/D/E) · S22-chốt (Mig 30) · #194 (Mig 31) vừa
D5 Plan T — tắt DemoSeed + CHỨNG bằng restart thật #207 (flag) · #208 (T5 xoá + T6 restart chứng-minh) cao
D6 Đo-đạc / vận-hành (7 phát-hiện công-cụ) #186 endpoint Gitea · #187 updated_at trễ · #188 rate-limit 429 + cache token · #217 Discovery #5 · #203 Discovery #4 · #221 503 + route/accessToken · #187 credential prod cao
D7 Phình MEMORY 35→72KB, 8 lần cảnh-báo leo thang rải ở cuối mọi mục phần (a) + #218/#219/#220/#221 cao
D8 Đánh-bóng UX FE + 1 ca revert-trong-phiên #204 (banner mx-5) · #209 (Plan U truncate) · #210 (Plan AA widen + revert Plan U) · #214 (wrap fix) thấp
D9 "Key patterns extracted" 8 mục — lớp chưng-cất SẴN CÓ phần (c) dòng 182-201 cao
D10 Tác-dụng-phụ UAT tự khai + giới-hạn phép đo tự khai #202 caveat #2 (PE/025 10→98) · #203 side-effect + "Test 2 409 = không đổi state" · #203 "NV Test không khả-thi (quét 20 PE)" · #194 "presumed ×4" · #219 sqlcmd bỏ qua (thiếu PROD_DB_PASSWORD) cao

Ghi-chú dedup: D1 và D2 đan nhau về mặt Run (#201/#202 nằm ở cả hai) nhưng khác trục (một bên là lỗi CODE, một bên là hành-vi CI) ⇒ giữ 2 cụm, khi nén phải viết 2 dòng riêng cho cùng Run. D8 gộp 4 Run vì nội-dung là CSS, giá-trị dài-hạn thấp — trừ chi-tiết "Plan U bị Plan AA revert cùng phiên" (giữ, vì đó là bài về đọc bundle-hash tích-luỹ).

Bản-nén-nháp 4-field

[cao] D1 — Chuỗi per-NV lookup discrimination (Plan K → P), sinh checklist 10 điểm

  • VIỆC: wire cờ opt-in per-NV (Allow* theo từng slot Approver) xuyên Mig 29/30/31, rồi vá 5 lượt liên-tiếp khi lộ ra thiếu điểm nối.
  • KẾT-LUẬN: #194 098baa6 PARTIAL — schema + FE checkbox thứ 7 đã ship nhưng AwLevelDto (ApprovalWorkflowV2AdminFeatures.cs:23-38) thiếu hẳn param AllowApproverSkipToFinal (chỉ tồn-tại trong comment dòng 60) + ToDto:156-158 thiếu ⇒ checkbox đọc/ghi vào hư-vô. #195 0062fcb vá 15 LOC ⇒ 13 key round-trip PASS, đúc checklist 8 điểm. #201 fb3c22c (Plan N) vá PurchaseEvaluationFeatures.cs:765 thêm && l.ApproverUserId == currentUser.UserId + fallback admin ⇒ điểm 9. #202 a1c8386 (Plan O) quét ra 4 site cùng khuôn (...WorkflowService.cs:204 + :258-260, ...DetailFeatures.cs:75-76, ...Features.cs:314-315) + 3 test hồi-quy (111/111). #203 1727bd5 (Plan P) vá Controller TransitionPeBody từ 3 → 7 paramđiểm 10.
  • BÀI-HỌC: với schema OR-of-N (nhiều NV cùng một Cấp), mọi FirstOrDefault(... Order == ...)điểm mù: phải quét TOÀN kho (grep -n "FirstOrDefault.*Order.*==") chứ không chỉ sửa handler lộ bệnh. Và record body của Controller phải soi-gương số param với Command — thiếu field thì ASP.NET không báo lỗi, chỉ lặng-lẽ default.
  • BẤT-NGỜ: bug sống trên prod 2-3 ngày3 lượt refactor liên-tiếp (Mig 29/30/31) đều trượt — verbatim tự khai "em main + Reviewer + Implementer all missed across 3 plan"; đồng-thời checklist phình 6 → 8 → 9 → 10 điểm, tức mỗi lần "đã đủ" đều sai.

[cao] D2 — Saga Discovery #3 (paths-ignore xét trọn push-range)

  • VIỆC: truy vì sao commit docs-only vẫn kích CI (ngược gotcha #41), qua 5 lần quan-sát.
  • KẾT-LUẬN: giả-thuyết đầu (Discovery #2, Run #188): ".claude/agent-memory/** không nằm trong paths-ignore nên kích CI" → BỊ BÁC ở S22-chốt vì **/*.md khớp mọi độ sâu (cc8a7d3 SKIP đúng). Chốt sau 3 lần củng-cố (#200 f4055a1, #201 fb3c22c, #202 a1c8386 — lần 3 0 file agent-memory nên loại hẳn biến này): Gitea xét paths-ignore trên TRỌN push-range, chỉ cần 1 commit trung-gian có file không-bị-ignore là cả range chạy. #210 mixed-diff nên không tính là bằng-chứng.
  • BÀI-HỌC: muốn loại một biến thì phải tìm ca VẮNG biến đó mà hiện-tượng vẫn còn (#202 là ca then-chốt) — thêm ca có-biến chỉ củng-cố giả-thuyết sai. Ghi rõ ca nào không tính là bằng-chứng (#210) cũng quan-trọng ngang ca tính.
  • BẤT-NGỜ: kết-luận cuối là "lỗi" nhưng verbatim đánh giá "Anomaly is BENEFICIAL" — CI chạy dư lại cứu được gate verify trên commit docs; và gotcha #47 tuy bị bác vẫn giữ giá-trị phòng-ngừa cho file non-.md tương-lai.

[cao] D3 — Chuỗi audit-trail S25 (Plan AB → AF): 5 khuôn phục-hồi lịch-sử

  • VIỆC: làm "Lịch sử duyệt" hiển-thị đúng + cứu dữ-liệu lịch-sử đã ghi thiếu.
  • KẾT-LUẬN: #215 FAIL (tie-break, xem q3) → #217 a734bf2 (AC) thêm Approval-row nhánh Reject Service:75-103 + prefix [Duyệt vượt cấp tới Cấp cuối] :472, xác-minh 6/6 approval có đủ 8 key → #218 25837b6 (AC2) FE dựng synthetic Reject row từ Changelog entityType=5 (20 entry, 8 Workflow-entry, khớp keyword "Trả về") → #219 0aaf2df (AD) bỏ badge from/to + extractNextTargetHint() parse \[Bước (\d+) — Cấp (\d+)\] → #220 9ea62be (AE) vá 9 site UserName = currentUser.FullName ?? currentUser.Email (4 Features + 5 DetailFeatures) → #221 506cada (AF) FE userMap useMemo dựng từ 5 nguồn nhúng sẵn (drafter/approvals/levelOpinions/departmentOpinions/approvalFlow.steps), 3 nấc: tin entry.userName → tra map → "Hệ thống". Cumulative 7 commit, 1 catch + 6 PASS, 0 regression.
  • BÀI-HỌC: khi phát-hiện "field X không set ở N chỗ giống nhau", vá cả N chỗ một lượt thay vì chỗ báo lỗi (AE: 1 lộ + 8 phòng-xa). Dữ-liệu cũ đã hỏng thì cứu ở FE bằng dữ-liệu đã nhúng sẵn trong bundle — không cần đổi hợp-đồng API, né luôn ràng-buộc /api/users chỉ-admin.
  • BẤT-NGỜ: bằng-chứng chốt Bug 1 là một dòng dữ-liệu cũ còn sót: entry Budget Adjust 02:31:39 entityType=1userName="" — tức prod tự lưu giữ vật-chứng tiền-sửa để đối-chứng sau deploy; và AD bỏ bớt thông-tin (badge from/to) lại làm UI đúng hơn vì phần lớn là ChoDuyet→ChoDuyet tự-lặp.

[cao] D5 — Plan T tắt DemoSeed + chứng bằng restart THẬT

  • VIỆC: chặn seed demo tự mọc lại trên prod (#207 0b97840, #208 7b7b28f).
  • KẾT-LUẬN: bọc 5 method demo trong if (!demoSeedDisabled) (V1 workflow ×2, demo Contract, demo PE, sample AW V2); GIỮ 8 nhóm seed hạ-tầng (Roles/Admin/30 user UAT/master/template/catalog/backfill). T5 xoá 4 PE + 1 V2 + 2 V1 + cascade; T6 ép Restart-WebAppPool SolutionErp-Api rồi sqlcmd: PE=0, V2=0, V1=0, master còn nguyên (Users 33 · Suppliers 19 · Projects 9 · Contracts 7). Tổng R+S+T ≈ 720 dòng bị xoá, cờ tồn-tại vĩnh-viễn.
  • BÀI-HỌC: cờ chống re-seed chỉ được tin sau khi khởi-động lại thật rồi đếm lại — không tin vào việc đọc code. Và vì appsettings.Production.json bị .gitignore, giá-trị mặc-định phải đặt ở appsettings.json (thứ đi qua git) mới tới được prod.
  • BẤT-NGỜ: chính cái cờ chứng-minh-tốt này về sau nuốt luôn seed hạ-tầng của Plan B (Run #231/#232, gotcha #51) — biện-pháp đúng ở lớp này thành bẫy ở lớp khác.

[cao] D6 — 7 phát-hiện về CÔNG-CỤ ĐO (dễ mất nhất khi nén)

  • VIỆC: gom các bài học về chính phép đo, rải rác trong 6 Run.
  • KẾT-LUẬN: (1) API liệt-kê Run của Gitea là /api/v1/repos/.../actions/**tasks**, /actions/runs trả 404; đọc không cần auth. (2) updated_at trong bảng task trễ ~2 phút — phải đối-chiếu LastWriteTime của .dll/.html trên VPS. (3) đăng-nhập ~5 request/phút là 429 ⇒ cache token ra %TEMP%\*_token.txt, 2 login + 8 lệnh dùng lại (Run #188 dính 429, S22-chốt hết dính). (4) Discovery #5: sqlcmd Windows-auth qua ssh cần escape 4 dấu \\\\SQLEXPRESS — 2 dấu ra rỗng KHÔNG báo lỗi. (5) Discovery #4: ASP.NET Core 10 record + enum đòi số, không có JsonStringEnumConverter (grep Program.cs = 0 hit) ⇒ payload mẫu "Drafter" trong brief là sai, fail 400. (6) 503 giữa lúc IIS recycle (~5-15s) là bình-thường, tự khỏi. (7) route thật là /api/auth/login (không /api/v1/...), field token là accessToken (không token); /api/me + /api/menu-keys 404 vì không tồn-tại, không phải regression.
  • BÀI-HỌC: lệnh đo sai trả về IM-LẶNG (2-backslash ra rỗng; enum string ra 400; endpoint sai ra 404) — mỗi phép đo phải có ca đối-chứng dương, và phải phân-biệt "0 kết-quả" với "đo hỏng".
  • BẤT-NGỜ: brief do người ra lệnh viết lại chính là nguồn sai (payload "Drafter") — và verbatim ghi thẳng "brief example payload was misleading", không đổ cho hệ-thống.

[cao] D7 — MEMORY phình 35→72KB: 8 lần cảnh-báo leo thang mà không ai dừng

  • VIỆC: vai tự theo-dõi kích-thước diary của chính mình sau mỗi entry.
  • KẾT-LUẬN: chuỗi tự khai: ~35KB ("approaching") → ~40 → ~43 ("over 25KB trigger, under 50KB hard") → ~50 ("at hard threshold") → ~58 ("REQUIRED ARCHIVE ... BEFORE next entry") → ~60 ("MANDATORY") → ~62 ("DEDICATED CURATION SESSION PRIORITY NEXT") → ~66→69 ("priority MAX") → ~72 ("PRIORITY MAX REINFORCED"). Chốt chỉ xảy ra khi có phiên curate riêng (chính file này), kéo về mục-tiêu ~25-30KB.
  • BÀI-HỌC: cảnh-báo do chính kẻ đang phình phát ra thì không tự dừng được — cần cổng ngoài (ngưỡng cứng chặn ghi) hoặc việc riêng có chủ; và ngưỡng "mềm 25KB / cứng 50KB" bị vượt gần 3 lần vẫn chỉ sinh thêm chữ in-đậm.
  • BẤT-NGỜ: mức độ khẩn-cấp trong câu chữ leo thang 8 nấc (approaching → REQUIRED → MANDATORY → PRIORITY MAX → REINFORCED) — bản thân nó là dữ-liệu: leo-thang ngôn-từ không thay cho cơ-chế.

[cao] D10 — Tự khai tác-dụng-phụ và giới-hạn phép đo

  • VIỆC: ghi lại thứ phép kiểm-chứng làm hỏng + thứ nó KHÔNG chứng được.
  • KẾT-LUẬN: kiểm-chứng bằng POST thật đã đổi state prod: PE/2026/A/025 phase 10→98 (admin bypass qua if (isAdmin) return dòng 186), khai rõ "admin bypass là thiết-kế, không phải regression", đề bro tự chọn revert hay giữ; PE/2026/A/021 trả 409 ⇒ không đổi state (atomic) — có kiểm lại chứ không đoán. Giới-hạn tự khai: NV Test không đóng vai approver (đã quét 20 PE) nên biến-thể actor không khả-thi; #194 dùng chữ "presumed" 4 lần cho phần không đo được; #219 bỏ qua sqlcmd vì thiếu PROD_DB_PASSWORD, chấp-nhận verify gián-tiếp và nói rõ là gián-tiếp.
  • BÀI-HỌC: báo-cáo verify phải tách 3 mức: đo trực-tiếp / suy ra (inferred, presumed) / không đo được — và ghi luôn phép đo đã làm bẩn dữ-liệu.
  • BẤT-NGỜ: ca 409 lại là bằng-chứng dương mạnh nhất cho Plan O: lỗi 409 "mode mismatch" chứng-tỏ đã qua được cửa actor-check (403 cũ), tức thất-bại đúng chỗ = thành-công.

[vừa] D4 — Chuỗi Mig 28→31 + backfill có kiểm số

  • VIỆC: 5 lượt deploy schema per-NV/per-Level.
  • KẾT-LUẬN: Mig 28 AddAdvancedOptionsToApprovalWorkflows (#186, 6 cờ Allow* mức workflow, allowReturnToDrafter=true mặc-định + 5 false) → Mig 29 RefactorAdvancedOptionsToPerLevelAndDrafterUser (#187): Levels +5 Allow*, Users +1, ApprovalWorkflows 6; backfill 48/48 Levels=1 và 0/13 Users=1 (đúng vì nguồn false) → Plan D/C/E (#188): /api/users +allowDrafterSkipToFinal, PATCH admin 204 / nv.test 403, scope V2 chặt (nv.test 8 PE < admin 17) → Mig 30 AddAllowApproverEditBudgetToLevels (S22-chốt): currentLevelOptions 6 key, AwLevelDto 12 key → Mig 31 RefactorSkipToFinalToApproverLevel (#194): Levels +1, Users 1, endpoint zombie /allow-skip-final trả 404 đúng ý.
  • BÀI-HỌC: backfill phải kiểm cả hai chiều — "48/48 = 1" và "0/13 = 1" đều là kết-quả ĐÚNG cần xác-nhận; số 0 ở đây là bằng-chứng, không phải thiếu-sót. Dọn field cũ thì phải kiểm cả endpoint lẫn key trong DTO đã biến mất.
  • BẤT-NGỜ: cùng một tính-năng bị dời chỗ 3 lần (workflow → user → level) trong ~2 ngày; test-gate suy-ra từ "deploy chạy được" chứ không đọc trực-tiếp (test gate inferred PASS).

[thấp] D8 — Đánh-bóng UX + 1 ca revert trong phiên

  • VIỆC: 4 Run FE thuần: #204 banner mx-5mb-3; #209 sidebar truncate (min-w-0 flex-1 + shrink-0 + title= tooltip); #210 widen w-60 → w-72 xl:w-80 kèm revert Plan U; #214 wrap nhãn dài.
  • KẾT-LUẬN: 4/4 PASS, bundle rotate đúng kỳ vọng mỗi lần; menu Pe_DuyetNcc_WfView Order=2 + họ Pe_DuyetNccPhuongAn Order 6-10, tổng 1-10 liền mạch không hở/không chồng (seed idempotent).
  • BÀI-HỌC: đổi FE-thuần vẫn verify được gián-tiếp bằng bundle-hash làm proxy; nhưng khi một chunk bị revert trong cùng phiên thì hash phản-ánh trạng-thái tích-luỹ, không phải diff của chunk ⇒ đừng đọc hash như chữ-ký của một thay-đổi đơn lẻ.
  • BẤT-NGỜ: phép đo bundle của Plan P bắt nhầm thay-đổi của Run #204 đang bay cùng lúc (QZIPWD-g/DaLTMGcx) — vẫn kết-luận đúng nhờ đối-chiếu diff có 0 file FE, tức dùng nguồn thứ hai để cứu phép đo bị nhiễu.

[cao] D9 — "Key patterns extracted S21-S25" (giữ gần như nguyên)

  • VIỆC: phần (c) đã là bản chưng-cất 8 mục do chính vai viết.
  • KẾT-LUẬN: 8 mục = Discovery #3 · Discovery #4 · Discovery #5 · checklist 10 điểm per-NV (liệt-kê đủ 10) · gotcha #48 + cách vá · "CI test-gate bắt được lỗi mà UAT-skip-test bỏ sót" · FE merge synthetic + userMap · capture pre-call mutation state.
  • BÀI-HỌC: khi nguồn đã có lớp chưng-cất, việc nén nên giữ lớp đó gần như nguyên văn và cắt ở lớp Run bên dưới — nén lại cái đã nén là chỗ dễ mất mã-số (#48, điểm 9/10) nhất.
  • BẤT-NGỜ: checklist 10 điểm ở đây là bản duy nhất liệt-kê đủ 10 trong toàn batch A — mọi chỗ khác chỉ nhắc số "8"/"9"/"10 surface points" mà không kèm nội-dung.

Token-list (verbatim, cicd-monitor/2026-05-runs)

  • gotcha#: #41 (path filter — dẫn ≥6 lần) · #44 (silent 403 — "fix confirmed" ở #210) · #45 (fix Trả lại, Run #186) · #47 (agent-memory — disproven, giữ vai PREVENTIVE) · #48 (NEW multi-Changelog.Add + SQLite frozen-clock tie-break)
  • Discovery#: #1 rate-limit 429 ~5 req/phút · #2 .claude/agent-memory/** không nằm trong paths-ignore (về sau bị bác) · #3 Gitea xét TRỌN push-range (củng-cố 4 lần: #200/#201/#202 + #210 "NOT applicable") · #4 ASP.NET Core 10 record+enum cần số · #5 sqlcmd cần \\\\SQLEXPRESS 4 backslash · (không đánh số) /actions/tasks/actions/runs (#186) · updated_at trễ ~2 phút (#187) · "Discovery 1" 503 giữa deploy + "Discovery 2" /api/auth/login + field accessToken (#221)
  • surprise: CRITICAL FAIL — K3 DTO mirror INCOMPLETE · "AllowApproverSkipToFinal mentioned only in comment line 60, NOT as actual record param" · "em main + Reviewer + Implementer all missed across 3 plan" · "Bug present 2 days prod" / "3-day prod bug latency" · "Spec hypothesis ... disproven for this commit" · "Anomaly is BENEFICIAL — catches verify gate even on docs-only tip" · "PROVES ACTOR VALIDATION SUCCESS ... 409 mode mismatch NOT 403" · "First attempt with string enum \"Drafter\" → HTTP 400 ... Brief example payload was misleading" · "Test 2 HTTP 409 = handler threw exception → no state change (atomic)" · "NV Test actor variant not feasible (scanned 20 PEs)" · "the Budget Adjust entry ... has userName=\"\" empty — this is the EXACT pre-fix Bug 1 evidence" · "Side effect logged: Admin transition on PE/2026/A/025 mutated phase 10→98" · "Run #190 ... CANCELLED by concurrency ... normal not a fail" · "/api/me + /api/menu-keys returned 404 (route names different) — Not regression" · "Memory size ... PRIORITY MAX REINFORCED" · "8 surface points checklist (NOT 6)" · "prophylactic codebase scan is needed"
  • guard: if (isAdmin) return (line 186, admin bypass CỐ Ý) · if (!isAdmin && currentLevel is not null) (line 264) · && l.ApproverUserId == actorId + throw if null (4 site Plan O) · fallback ?? curStep?.Levels.FirstOrDefault(...) cho admin/non-approver (Plan N) · [Authorize] class-level + GetWorkflowsForUserAsync auth filter (fix #44) · if (!demoSeedDisabled) bọc 5 seed demo (Plan T) · .Where(c => c.Summary!.Contains("Chuyển phase")) (vá #48) · HasDefaultValue(false) (điểm 2 checklist) · Migration 3-file rule (Up + Designer + Snapshot — điểm 3) · [FromBody] record param count = Command param count (điểm 10) · seed Order shift idempotent (1-10 liền mạch) · token-cache %TEMP%\*_token.txt chống 429 · test-gate CI chặn trước deploy
  • root-cause: FirstOrDefault(l => l.Order == curLevelOrder) không lọc actor ⇒ luôn lấy Levels[0] theo thứ-tự DB ⇒ cờ per-NV admin tick bị bỏ qua (4 site cùng bệnh) · Controller TransitionPeBody 3 field ⟂ Command 7 field ⇒ ASP.NET default im-lặng 3 field ⇒ F1/F2 không tới handler suốt 2 ngày · AwLevelDto thiếu param + ToDto thiếu ctor-arg ⇒ cột DB có mà API không trả · nhiều Changelog.Add() cùng SaveChangesAsync + SQLite frozen-clock ⇒ OrderByDescending(CreatedAt) tie-break bất-định · Gitea xét paths-ignore trên trọn push-range ⇒ tip docs-only vẫn chạy · thiếu JsonStringEnumConverter ⇒ enum dạng chuỗi fail 400 · \\SQLEXPRESS (2 backslash) ⇒ 0 output, im-lặng · UserName không set ở 9 site Changelog.Add() ⇒ cột người-dùng rỗng
  • file:line / định-danh (BE): ApprovalWorkflowV2AdminFeatures.cs :23-38 (AwLevelDto record), comment :60, ToDto :156-158, vùng :184-238 · PurchaseEvaluationFeatures.cs :765 (per-NV lookup), :314-315 (AdjustBudget) · PurchaseEvaluationWorkflowService.cs :204 (EnsureCanRejectV2Async), :258-260 (ApplyReturnModeAsync), :264 (guard), :186 (admin bypass), :75-103 (nhánh Reject Plan AC), :472 (prefix [Duyệt vượt cấp tới Cấp cuối]), :287-333 (F1 edge Bước 1), :268-275 (F1.Drafter giữ TraLai) · PurchaseEvaluationDetailFeatures.cs :75-76 (EnsureEditableForDetailsAsync) · Controller TransitionPeBody :267 (3 field) → :280-286 (7 param), mediator.Send :76-78, marker Plan P :71-75 · TransitionPurchaseEvaluationCommand :395 · Program.cs (0 hit JsonStringEnumConverter/AddJsonOptions) · DbInitializer.cs · MenuKeys.cs · appsettings.json / appsettings.Development.json / appsettings.Production.json (bị .gitignore)
  • file:line / định-danh (test + FE): test ApplyReturnMode_OneStep_AtStep1 line 350 · ApplyReturnMode_OneLevel_AtStep1Level1 line 308 · GetPurchaseEvaluationCurrentLevelOptionsTests.cs (2 method) · PurchaseEvaluationPerNvLookupRegressionTests.cs (3 test) · PeDetailTabs.tsx (fe-user + fe-admin, mirror §3.9) · PeWorkflowPanel.tsx · types/purchaseEvaluation.ts (WorkflowReturnMode = { OneLevel:1, OneStep:2, Assignee:3, Drafter:4 }) · Layout.tsx (w-60 → w-72 xl:w-80; min-w-0 flex-1 + shrink-0 + truncate + title=) · WorkflowMatrixViewPage.tsx · approvalWorkflowV2.ts · App.tsx · helper extractNextTargetHint(comment, decision) · regex \[Bước (\d+) — Cấp (\d+)\] · resolveActorName/resolveUserName + userMap useMemo
  • Run / sha / bundle: #186 eea86fd (id=300) · #187 c0af9e0 (301) · #188 a74e671 (302) · #189 40f64c6 · #190 8185070 CANCELLED · #191 0e70789 · #192 30d51c8 · #193 b04a11a (307) · #194 098baa6 (308) PARTIAL · #195 0062fcb (309) · #199 da30e27 · #200 f4055a1 (314) · #201 fb3c22c (315) · #202 a1c8386 (316) · #203 1727bd5 (317) · #204 108268a · #207 0b97840 · #208 7b7b28f · #209 86d8806 · #210 ac2c859 (324) · #214 ee0902a (328) · #217 a734bf2 · #218 25837b6 (332) · #219 0aaf2df (333) · #220 9ea62be (334) · #221 506cada (335) · commit lẻ: c2042ef/4dd6f9c/508b17a (Plan M) · 0326458 (N1+N2) · ae01ca5 (O1-O5) · ee776d5/c667802 (AA) · b079b27 (BE Mig 30) · cc8a7d3 (SKIP) · 3d725c4..cc8a7d3 · e23f51c..506cada · bundle-chain admin CzesdXLh→D5l49-70→Cclc8Uwu→CpI5OL8n→CRsX6cFo→D_JENTBi→QZIPWD-g→Dmk--X6w→CZdXQ2eo→CrHpBYFM→B5iZMa7g→CDVnRDe6→DR95zKWg→C8TvDy7r; user DP-gH4LW→B6N5hq3d→d064StNa→X7qb4Zl4→COJhbRxy→DaLTMGcx→Bd4gh3Tp→DCwhhey2→C3bCWZ90→CHJDH3M2→gAFN3NVx→BAj_Yaj5→BvcWrq2z
  • Mig / dữ-liệu prod: Mig 28 20260513114505_AddAdvancedOptionsToApprovalWorkflows · Mig 29 RefactorAdvancedOptionsToPerLevelAndDrafterUser (backfill 48/48 Levels · 0/13 Users) · Mig 30 20260513160703_AddAllowApproverEditBudgetToLevels · Mig 31 20260514160124_RefactorSkipToFinalToApproverLevel · test-count chuỗi 84 → 103 → 104 → 106 → 108 → 111 · Users 33 · Suppliers 19 · Projects 9 · Contracts 7 · PE-ID 3248f2f9-c6e9-43ff-a4ca-067ffecf9f36 (PE/2026/A/032) · 98736f06-... (A/025) · 59176ad5-... (A/027) · 6148ba7a-... (A/026) · f9476dad-... (A/021) · workflow bf31f120 · token len admin 468 / nv.test 477 · ~720 rows wiped
  • 🔐 secret (KHÔNG chép giá-trị): dòng 48appsettings.Production.json tại C:\inetpub\solution-erp\api\, user=vrapp, mật-khẩu 24 ký-tự dạng thô → đề-xuất redact + xoay khoá
  • meta / size-trend: ~35KB → ~40 → ~43 → ~50 → ~58 → ~60 → ~62 → ~66 → ~69 → ~72KB · ngưỡng mềm 25KB / cứng 50KB · FIFO ~8 → ~9 → ~10 → ~11 → ~12 → ~13 entry · token-cost mỗi lượt ~10k-28k · feedback_md_compact_narrative.md (§6.5) · feedback_uat_skip_verify · feedback_per_nv_permission_scope.md

cicd-monitor/2026-08 (5.912 B — "L2 archive, moved byte-exact từ L1 khi vượt soft-cap")

Đặc-điểm file: 4 entry (S166-S167, 08-01) — KHÔNG phải văn-xuôi verbose như 4 file trên. Đây là L2 đã chưng-cất sẵn: 2 entry dạng đầy-đủ + 2 entry dạng _( … )_ in-nghiêng cực-nén, cả 4 đều trỏ verbatim ra runs/…/sub-cicd-verify-*.md.

🔴 KHUYẾN-NGHỊ NGƯỢC cho lead — ĐỀ NGHỊ KHÔNG NÉN FILE NÀY: (a) mật-độ đã ở mức chưng-cất (5.9KB chứa ~20 bài-học phân-biệt được); nén tiếp là mất lớp chưng-cất, đúng khuôn hỏng đã ghi ở S162/F-02. (b) file này mới nhất trong batch A (mtime 08-01, cùng phiên đang chạy) — giá-trị truy-hồi còn nóng, khác hẳn 8 file 2026-05. (c) 🟢 Đã VERIFY con-trỏ, cả 4 đều SỐNG (đo trên đĩa hôm nay): sub-cicd-verify-k7.md 23.745 B · k6.md 12.886 B · k5-k4c.md 10.869 B · k4ab.md 24.451 B — đều ở .claude/workflows/runs/2026-07-31-S164-4gd-khkk-fanout/. ⇒ Rút gọn thêm được phép về mặt an-toàn (nguyên-liệu còn), nhưng không nên vì (a)+(b). Nếu buộc phải chạm: chỉ đề-xuất gỡ 2 entry _( … )_ (K5/K4c + K4a/K4b) vì đã có verbatim sống, GIỮ NGUYÊN 2 entry K7 + K6.

Cụm-dedup

# Cụm Thành-phần Tag
E1 S167 K7 aaed699 — PUSH-ĐÈ NUỐT DEPLOY (đề-xuất gotcha #86) run #441 CANCELLED + ship nhờ MAY + luật ancestry + 4 kỹ-thuật phụ (tiền-đề marker · control-dương tiền-commit · admin-idempotent · appcmd map PID) + nv.test 401 cao
E2 S167 K6 1c6d77a — 0-hit GIẢ 2 lần liên-tiếp do cơ-chế regex backtick-minify + shell nuốt backtick → luật grep -F + trích byte · COUNT-DELTA · log-CI nhân-chứng-4 · frozen-lành-tính · 2-tầng #82 đo bằng số cao
E3 S166 K5+K4c e202393 — marker differential + 2 bẫy đo 4/4 element-wise · recipe đếm Mig false-negative · bar "FE route 200" không có răng (SPA-fallback) cao
E4 S166 K4a+K4b 88e7ecf — phủ 2 run 1 lượt + mốc PRE lão-hoá delta khép kín · đề-bài SAI bắt bằng đo (143⇒192 vs LIVE 151) · perm-row ≠ policy · soi điều-kiện log trước khi đọc im-lặng · marker lead bị bác cao
E5 META xuyên 4/4 entry: "vắng-mặt / 0-hit KHÔNG được đọc thành kết-luận" E1 tiền-đề-marker · E2 0-hit-giả ×2 · E3 false-negative + POS≡NEG · E4 marker-lead-bị-bác cao

Ghi-chú dedup: E5 không phải entry riêng mà là trục chung rút từ cả 4 — nếu lead nén, E5 là thứ phải sống sót nguyên vẹn, vì nó là bài lặp 4/4 lần (bằng-chứng mạnh nhất trong file).

Bản-nén-nháp 4-field

[cao] E1 — K7: push-đè nuốt deploy

  • VIỆC: verify aaed699 (bridge KHKK→HĐ, 13 file cross-stack 4 BE + 6 FE×2 + 3 test, 0-mig).
  • KẾT-LUẬN: PARTIAL 4/6+1 (gate 639 = 45+594, Δ+17; Mig giữ 71; bảng 97; bundle Ig1R5tAh→RgvHZkPH + DFOCQ2ks→D65FJPGd). Run #441 bị CANCELLED ở 3m02s vì lead push 628132c đè lên (Gitea cancel-in-progress); code lên được prod chỉ nhờ may628132c tình cờ chạm fe-*/src/** nên đẻ run #442.
  • BÀI-HỌC: sau 2 push liên tiếp, bắt buộc verify hai điều: run cuối có head_sha == TIP TIP chứa commit code (git merge-base --is-ancestor). Cấm đọc "bảng Actions có run xanh" là xong. Kèm 3 kỹ-thuật rẻ: kiểm tiền-đề của marker trước khi tin 0-hit (nghi \u-escape và nghi code-split — cả hai đều sai, nhưng phải ĐO mới có quyền kết luận: grep -c -F 'Hợp đồng'=4 trên bundle PRE; index.html chỉ 2 asset); control dương = chuỗi bản tiền-commit của chính file đang sửa (4/4); admin-seeder = control idempotent miễn phí (3 role báo 2 upgraded, không phải 3 ⇒ nhánh no-op đã chạy thật).
  • BẤT-NGỜ: kịch-bản chết-người là kịch-bản KHÔNG xảy ra lần này: nếu commit-2 rơi trọn vào paths-ignore (docs/memory-only) thì run-1 bị huỷ + run-2 bị skip ⇒ code không bao giờ lên prod mà mọi bảng đều trông lành. Và appcmd list wp cứu một hiểu-nhầm: PID 7680 khởi cùng cửa-sổ nhưng thuộc vietreport-admindự án khác.

[cao] E2 — K6: 0-hit giả hai lần, cùng một cơ-chế regex

  • VIỆC: verify 1c6d77a (ADMIN_HIDDEN_KEYS 12 key, FE-admin 1 file, 0-mig).
  • KẾT-LUẬN: PASS 5/5 (#440 6m29s; gate 622 = 45+577 delta 0; Mig 71; bảng 97; menu 200 / perm 2221 đứng im). Nhưng marker báo 0-hit sai 2 lần liên-tiếp: (a) rolldown/Vite 8 minify chuỗi thành backtick (new Set([\PurchaseEvaluations`,…])) nên regex neo ["']**không đời nào khớp**; (b) vá xong lại truyền pattern-chứa-backtick qua biến trong"…", shell nuốt ⇒ grep -cE gãy (Unmatched (`) và trả 0 gần như im lặng trong vòng lặp.
  • BÀI-HỌC: marker chuỗi trên bundle phải dùng grep -F fixed-stringluôn trích byte thật .{90}X.{90} trước khi kết-luận vắng-mặt. Thêm COUNT-DELTA: khi literal đã tồn-tại từ trước thì có/không = 0 bit, nhưng số lần xuất hiện PRE→POST vẫn đo được (12/12 key đều +1).
  • BẤT-NGỜ: ngoại-lệ duy nhất Workflows +2 lại giải-thích được (là substring của PeWorkflows) ⇒ chỗ lệch biến thành kiểm-tra nhất-quán miễn phí. Và log CI in thẳng dist/assets/index-<hash>.js <size> = nhân-chứng thứ 4 độc-lập với curl, khớp LM prod tới từng giây ⇒ phân-biệt được FROZEN lành-tính (eoffice LM 11:14→12:00:41, log in cùng hash DFOCQ2ks = rebuild tất-định) với bundle kẹt thật.

[cao] E3 — K5+K4c: marker differential + 2 bẫy đo

  • VIỆC: verify e202393 (FE-only).
  • KẾT-LUẬN: PASS 5/5 (#439 6m16s; gate 622 = 45+577, +1 đúng bằng 1 [Fact] mới). Marker differential 4/4 element-wise (K5 vào cả 2 app · K4c chỉ eoffice) + Δsize cùng chiều = nhân-chứng vuông-góc với grep.
  • BÀI-HỌC: recipe đếm Mig đang nằm trong MEMORY có false-negative: grep -v Snapshot ăn nhầm AddPeApprovedBudgetSnapshot (Mig 67) ⇒ phải neo đuôi Designer\.cs$|ModelSnapshot\.cs$, và ưu-tiên set-diff repo↔prod 2 chiều thay vì khớp tổng.
  • BẤT-NGỜ: thước "FE route trả 200" không có răng với SPA-fallback — ca dương và ca âm giống nhau tới từng byte (876 B); tức một thước đã dùng lâu nay chứng-minh được 0 bit.

[cao] E4 — K4a+K4b: phủ 2 run một lượt, mốc PRE lão-hoá

  • VIỆC: verify 88e7ecf.
  • KẾT-LUẬN: PASS 7/7 (#438; gate 621 = 45+576; menu 151→200; perm 1584→2221). Phủ 2 run trong 1 lượt ⇒ delta khép kín, không hở khoảng giữa. Phân rã 49+588 khớp cơ-chế 2-site skip-existing (588 = 49 × 12 role).
  • BÀI-HỌC: mốc PRE lão-hoá sau MỖI deploy — đề-bài của lead ghi 143⇒192, đo LIVE ra 151; xử đúng là truy phạm-vi, không hô "drift". Và perm-row ≠ policy (đếm row không nói được quyền). Trước khi đọc log im-lặng thành hồi-quy, phải soi điều-kiện in log trong source (if (added>0)).
  • BẤT-NGỜ: marker do chính lead gợi ý bị bác bằng đo — chữ Kết cấu vốn đã có sẵn nên 1/1 = 0 bit; người ra đề cũng là nguồn sai, và cách chữa là đo chứ không phải cãi.

[cao] E5 — META (xuyên 4/4 entry): vắng-mặt không phải kết-luận

  • VIỆC: trục lặp lại ở cả 4 entry của file.
  • KẾT-LUẬN: 4 dạng dương-giả/âm-giả khác nhau, cùng một bệnh: 0-hit do regex sai cơ-chế (E2 ×2) · 0-hit do chưa kiểm tiền-đề (E1) · thước 0 bit vì literal có sẵn (E4) hoặc vì POS≡NEG (E3) · recipe đếm có false-negative (E3).
  • BÀI-HỌC: mỗi phép đo phải kèm control dương (thứ chắc-chắn phải khớp) và trích byte thật; "không thấy" chỉ có nghĩa khi đã chứng được thước còn răng.
  • BẤT-NGỜ: trong cùng một file, suýt FAIL-OAN 3 lần (K6 ×2 + K7 ×1) — nghĩa là kỷ-luật này không phải lý-thuyết mà là thứ vừa cứu 3 bàn thua.

Token-list (verbatim, cicd-monitor/2026-08)

  • gotcha#: #86 (ĐỀ-XUẤT MỚI — push-đè nuốt deploy) · #82 (2 tầng display ⟂ API — đo bằng số ở K6, chưa đo được tầng-2 Drafter ở K7) · Mig 67 AddPeApprovedBudgetSnapshot (nạn-nhân của recipe false-negative) · K6 nhắc K4a
  • surprise: PUSH-ĐÈ NUỐT DEPLOY · "K7 ship được CHỈ NHỜ MAY" · "code KHÔNG BAO GIỜ lên prod, mà bảng Actions trông vẫn lành + git log đã push" · "0-hit marker SAI 2 LẦN LIÊN TIẾP do CƠ-CHẾ REGEX ... suýt FAIL-OAN" · "suýt FAIL-OAN lần 3" · "Cả 2 nghi đều SAI nhưng phải đo mới được quyền kết luận" · "ngoại lệ duy nhất Workflows +2 giải-thích-được (substring ⊂ PeWorkflows)" · "bar 'FE route 200' KHÔNG CÓ RĂNG" (POS ≡ NEG byte-identical 876B) · "recipe đếm mig trong MEMORY có FALSE-NEGATIVE" · "MỐC PRE ĐỀ BÀI SAI, bắt bằng ĐO" · "marker lead gợi ý BỊ BÁC BẰNG ĐO (Kết cấu có sẵn ⇒ 1/1 = 0 bit)" · "PERM row ≠ policy" · "log lần-2 sẽ IM LẶNG — đừng đọc thành hồi-quy" · "PID 7680 ... là vietreport-admin (dự án KHÁC)" · "CẤM lấy Admin-qua-được để tuyên grant đã ăn"
  • guard: git merge-base --is-ancestor + head_sha == TIP (luật 2-push) · grep -F fixed-string + trích byte .{90}X.{90} · control dương = chuỗi bản tiền-commit của chính file đang sửa (4/4) · if(changed) upgraded++ · if(added>0||upgraded>0) (guard làm log im) · if (added>0) · appcmd list wp map PID→pool · neo đuôi Designer\.cs$|ModelSnapshot\.cs$ + set-diff repo↔prod 2 chiều · marker-ÂM display-only (route /purchase-evaluations 68→68) · COUNT-DELTA PRE→POST
  • root-cause: Gitea cancel-in-progress khi push mới đè ⇒ run-1 huỷ; nếu commit-2 trọn paths-ignore thì run-2 skip ⇒ cửa sổ mất deploy im-lặng · rolldown/Vite 8 minify chuỗi thành backtick ⇒ regex neo ["'] không khớp · pattern-chứa-backtick truyền qua biến trong "…"shell nuốt, grep -cE gãy Unmatched ( trả 0 im-lặng · grep -v Snapshot khớp nhầm tên Mig chứa chữ Snapshot · SPA-fallback trả 200 cho mọi route ⇒ thước route mất răng · literal đã tồn-tại từ commit trước ⇒ marker có/không = 0 bit
  • file:line / định-danh: sha aaed699 (K7) · 628132c (commit đè) · 1c6d77a (K6) · e202393 (K5+K4c) · 88e7ecf (K4a+K4b) · run #438 / #439 6m16s / #440 6m29s / #441 3m02s CANCELLED / #442 · gate 639=45+594 (Δ+17) · 622=45+577 (delta 0) · 622=45+577 (+1) · 621=45+576 · Mig 71 · tables 97 · bundle Ig1R5tAh→RgvHZkPH + DFOCQ2ks→D65FJPGd · hash lặp DFOCQ2ks (rebuild tất-định) · ADMIN_HIDDEN_KEYS 12-key · new Set([\PurchaseEvaluations`,…])·grep -c -F 'Hợp đồng'= **4** ·dist/assets/index-.js (log CI) · LM11:14 → 12:00:41· menu **151→200** · perm **1584→2221** · phân rã **49+588 = 49×12 role** · mốc PRE đề-bài143⇒192vs LIVE **151** ·nv.testlogin **401** · PID **7680** / poolvietreport-admin` · seeder 3 role → 2 upgraded
  • evidence-pointer (ĐÃ ĐO, 4/4 SỐNG): runs/2026-07-31-S164-4gd-khkk-fanout/sub-cicd-verify-k7.md 23.745 B · …/sub-cicd-verify-k6.md 12.886 B · …/sub-cicd-verify-k5-k4c.md 10.869 B · …/sub-cicd-verify-k4ab.md 24.451 B
  • tag gốc: [run-442, push-de-nuot-deploy, ancestry-proof, tien-de-marker, control-duong-tien-commit, admin-control-idempotent, appcmd-map-pid] · [run-440, 0-hit-gia-2-lan, grep-F, count-delta, frozen-lanh-tinh, log-CI-nhan-chung-4]

implementer-backend/2026-05-q1 (18.512 B — "Archive Recent Activity Q1, S21 t3 → S24 Plan AA, 12 entry")

Đặc-điểm file: 12 entry. Chia rõ 2 loại: 4 entry "REFUSE" (vai từ-chối nhận việc, em-main tự làm) + 8 entry "PASS" (vai làm thật). Header khai nguồn MEMORY.md 38.8 KB, giữ lại Pattern 1-19.

Cụm-dedup

# Cụm Thành-phần Tag
F1 Nhật-ký TỪ-CHỐI + 7 tiêu-chí phạm-vi S21 t3-t5 (REFUSE 3/3) · S22 (REFUSE 100%) · S23 t4-t11 (8 plan liên-tiếp, 0 spawn) · S24 wrap (REFUSE 4/4, ghi rõ tiêu-chí từng ca) cao
F2 Chuỗi K của Mig 31 (pre-A → K1 → K3 → K5 → K7) UI label · schema swap Users→Levels · checkbox thứ 7 · dọn zombie · test hồi-quy cao
F3 4 "Mismatch" tự khai ở S22 per-NV opt-in vs default · PE.changelogs vắng · Dialog size="xl" · accessTokentoken cao
F4 Plan AA (Chunk B + wrap) — trang matrix read-only cho fe-user 3 file mới · thiếu shadcn Card/Badge · Pattern 13/14/15 mới vừa
F5 Plan M (M2 test + M3 đổi nhãn FE) mở-rộng helper không clone · kỷ-luật phạm-vi hẹp + ngưỡng chống-nghịch vừa

Ghi-chú dedup: F1 gộp 4 entry nằm rải khắp file vì cùng một loại nội-dung (quyết-định không-làm + lý-do theo tiêu-chí); gộp lại mới thấy được tỉ-lệ. F2 giữ 5 mắt-xích riêng trong 1 cụm vì chúng là một lần refactor bị chẻ nhỏ có chủ-đích (mỗi chunk 1 commit, K5 dọn rác của K1).

Bản-nén-nháp 4-field

[cao] F1 — Nhật-ký TỪ-CHỐI: vai này ghi cả việc mình KHÔNG làm

  • VIỆC: phân-loại việc được giao theo 7 tiêu-chí phạm-vi, trả lại việc không hợp.
  • KẾT-LUẬN: S21 t3-t5 từ-chối 3/3; S22 từ-chối 100%; S23 t4→t11 8 plan liên-tiếp em-main tự làm, 0 lần spawn (N+O 5 site lookup · P Controller ~6 LOC · Q CSS 8 LOC · R+S+T5 xoá dữ-liệu prod ~720 dòng qua 4 file .sql · T cờ DemoSeed ~25 LOC · U sidebar 25 LOC); S24 4/4 từ-chối đúng, mỗi ca ghi rõ commit + tiêu-chí (da218f1 #6 vặt <30 phút · 4d60598 #2 luồng UX · fbbd361 #2 · ee0902a #6). Lý-do chính: tiêu-chí #3 (xuyên >2 lớp) + #4 (chuỗi suy-luận sửa lỗi).
  • BÀI-HỌC: ranh-giới "được giao" phải quyết theo độ ràng-buộc chéo lớp, không theo kích-thước diff — và mỗi lần từ-chối phải ghi lại kèm tiêu-chí thì tỉ-lệ mới đọc được về sau.
  • BẤT-NGỜ: cả một quý mà tỉ-lệ từ-chối gần như tuyệt-đối; verbatim tự đối-chiếu: "REFUSE rate 100% match Anthropic warning 'tightly interdependent coding'" — tức vai tự xác-nhận giới-hạn của chính mô-hình chia việc, chứ không cố nhận cho có.

[cao] F2 — Chuỗi K Mig 31: đổi chỗ lưu cờ F2 từ Users sang ApprovalWorkflowLevels

  • VIỆC: 5 chunk nối tiếp trong S23 t1 (pre-A → K1 → K3 → K5 → K7).
  • KẾT-LUẬN: pre-A đổi nhãn slot Designer (ApprovalWorkflowsV2Page.tsx:873, tra fullName từ usersList đã có sẵn ~:500, khuôn .find đã dùng ở :535). K1 Mig 31 ADD-DROP không BACKFILL (Option A) — 6 file BE, cắt -37 LOC nhánh Drafter SUBMIT (PurchaseEvaluationWorkflowService.cs:121-157), 4 chỗ vỡ biên-dịch vá bằng sentinel false + marker K2, giữ tham-số thứ 8 bool skipToFinal để K2 dùng lại. K3 checkbox thứ 7 = 7 tiểu-mục nguyên-tử (type → default → propagate ?? false → vị-trí cuối nhóm → viết lại banner ~:623 → body mutation). K5 dọn zombie: xoá endpoint PATCH /allow-skip-final, xoá field DTO/Command/Handler, viết lại 6 chỗ chú-thích lỗi-thời, xoá cột "Skip cuối" FE — rồi grep 5 từ-khoá ra ZERO toàn src/Backend + fe-admin/src (+42/-94 LOC / 9 file). K7 xoá 3 test Drafter đã hết nghĩa + thêm 3 test Approver, helper mới SeedApproverF2WorkflowAsync (2 Bước × 2 Cấp để chứng skip không rơi sang Bước kế) ⇒ 104 PASS, baseline không đổi vì 3 xoá + 3 thêm triệt tiêu nhau.
  • BÀI-HỌC: refactor đổi chỗ lưu-trữ phải có chunk dọn rác riêng (K5) và kết bằng grep-về-0 trên nhiều biến-thể tên (PascalCase / kebab / camel / nhãn tiếng Việt / tên icon) — không thì cờ chết vẫn còn dấu vết khắp nơi. Test cũng phải xoá thứ đã hết nghĩa, đừng chỉ thêm.
  • BẤT-NGỜ: (i) chấp-nhận mất dữ-liệu prod có chủ-đích — Option A không backfill, khai đích danh 4 tài-khoản mất giá-trị (fin.pp, pm.nv, nv.test, truong.nguyen); (ii) UserConfiguration.cs không tồn-tạiUser được cấu-hình inline trong ApplicationDbContext.OnModelCreating ~:86 nên không có HasDefaultValue, EF vẫn tự nhận đổi prop; (iii) test hỏng do K1 được cố-ý để lại cho K7 (...ReturnModeTests.cs:253), tức nợ kỹ-thuật được đặt lịch chứ không bỏ quên.

[cao] F3 — Bốn "Mismatch" tự khai ở S22

  • VIỆC: ghi lại 4 chỗ hiểu sai giữa ý bro và cách vai định làm.
  • KẾT-LUẬN: (1) "người điều chỉnh cũng là người duyệt" — vai định cho mặc-định Approver luôn được phép, bro chỉnh thành cờ admin bật riêng (thành Mig 30); (2) PE.changelogs không có trong PeDetailBundle ⇒ dựng lịch-sử trong BudgetAdjustSection fail TS2339, phải bỏ và hoãn sang S23 bằng endpoint fetch riêng; (3) Dialog size="xl" không tồn-tại (chỉ sm|md|lg) ⇒ dùng lg cho iframe xem trước; (4) field đăng-nhập là accessToken, không phải tokenseed-test-users-prod.ps1 401 ở lần đầu, sửa thành $authResp.accessToken.
  • BÀI-HỌC: phải chốt "mặc-định vs admin bật riêng" TRƯỚC khi mở rộng phạm-vi quyền — đây là loại nhầm không lộ ra ở compile mà lộ ở nghiệm-thu. Ba cái còn lại chung một gốc: giả-định về hình-dạng API/thư-viện phải kiểm bằng đọc, không bằng trí nhớ.
  • BẤT-NGỜ: vai chủ-động mở mục "Mismatches discovered" để ghi cái mình đoán sai — và mục này về sau là phần giá-trị nhất của entry; nhầm về accessToken còn tái-xuất ở cicd-monitor (Run #221) ⇒ cùng một bẫy cắn hai vai khác nhau.

[vừa] F4 — Plan AA: trang matrix chỉ-đọc cho fe-user

  • VIỆC: dựng bản xem quy-trình V2 đã ghim cho phía user (3 file: types ~55 LOC + page ~215 LOC + route).
  • KẾT-LUẬN: PASS — lọc ở BE bằng ?isUserSelectable=true thay vì lọc ở FE; bảng 10 cột (3 meta + 7 cờ Allow*), rowSpan theo Bước, đủ 3 trạng-thái Loading/Error/Empty, route đặt trước /workspace. Đúc 3 pattern mới: 13 (mirror trang Designer ở dạng chỉ-đọc = bỏ mutation + tái-dùng DTO dạng subset), 14 (Tailwind JIT phải viết chuỗi class đầy đủ trong mảng), 15 (helper dựng hàng phẳng cho rowSpan).
  • BÀI-HỌC: làm bản chỉ-đọc thì đẩy điều-kiện lọc về BE — vừa gọn FE vừa tránh lộ dữ-liệu không được xem. Và phải kiểm kho components/ui/ của đúng app TRƯỚC khi import.
  • BẤT-NGỜ: shadcn của fe-user thiếu hẳn Card/Badge (chỉ có 6 thành-phần) — 2 app tưởng song sinh nhưng kho UI lệch nhau, phải nội-suy bằng <div>/<span> thuần cho khớp mắt với Designer bên admin.

[vừa] F5 — Plan M: mở-rộng helper + đổi nhãn có kỷ-luật

  • VIỆC: M2 thêm 2 test ca-biên "Bước 1 không lùi được"; M3 đổi nhãn hiển-thị Phase 98 "Trả lại" → "Cần chỉnh sửa lại".
  • KẾT-LUẬN: M2 mở-rộng SeedWorkflowAsync thêm 2 tham-số tuỳ-chọn mặc-định false (không clone helper, 4 test cũ không vỡ) ⇒ 106/106; khẳng-định assert đúng chỗ: Summary là chuỗi cố-định "Chuyển phase {from} → {to}" nên câu "không lùi được" phải tìm ở ContextNote. M3 đổi đúng 8 dòng / 4 file × 2 app, và liệt-kê rõ 4 nhóm KHÔNG đụng (nút hành-động ← Trả lạiđộng-từ, nhãn 4 mode, chú-thích lý-do, types/contracts.ts + types/budget.ts ngoài phạm-vi).
  • BÀI-HỌC: phân-biệt "nhãn trạng-thái" ⟂ "động-từ hành-động" khi đổi chữ — cùng một chuỗi "Trả lại" mà một chỗ phải đổi, một chỗ không. Danh-sách KHÔNG-đụng có giá-trị ngang danh-sách đã-đụng.
  • BẤT-NGỜ: vai tự đặt ngưỡng chống-nghịch: "anti-fiddle <20% LOC" và tự biện-hộ vì sao 2 chuỗi inline ngoài spec vẫn được sửa (cùng ngữ-nghĩa "tham-chiếu trạng-thái") — tự ràng mình bằng con-số trước khi bị hỏi.

Token-list (verbatim, implementer-backend/2026-05-q1)

  • gotcha#: #45 (bug Trả lại — lý-do REFUSE) · #44 (Authorize policy — Pattern 10, 5 test ~50 LOC) · "45 gotcha" (mốc S21) / "46 gotchas unchanged" (mốc S22)
  • criteria# (7 tiêu-chí phạm-vi): #2 luồng UX · #3 xuyên >2 lớp · #4 chuỗi suy-luận sửa lỗi · #6 vặt <30 phút
  • Pattern#: 2 EF migration 3-file rule · 3 audit-reuse EXTEND không clone helper · 5 mirror 2 app strict · 7 per-NV admin opt-in · 8 tách endpoint narrow scope · 9 defense-in-depth FE+BE guard pair · 10 Reflection-based Authorize regression · 11 test-infra helper cookie-cutter · 12 InternalsVisibleTo · 13 read-only mirror Designer (MỚI) · 14 Tailwind JIT full class string (MỚI) · 15 rowSpan flat row builder (MỚI) · 16-18 (S25 wrap, chỉ nhắc ở header) · 19 (S26 Plan AG, chỉ nhắc ở header)
  • surprise: "Surprise: shadcn fe-user KHÔNG có Card/Badge" · "UserConfiguration.cs file không tồn tại — User entity configured inline ApplicationDbContext.OnModelCreating ~line 86" · "Dialog size=\"xl\" NOT supported" · "API auth field accessToken không phải token ... FAIL 401" · "PE.changelogs KHÔNG có trong PeDetailBundle ... build FAIL TS2339" · "accept lose 4 prod user value fin.pp + pm.nv + nv.test + truong.nguyen" · "3 deleted + 3 added cancel out, baseline preserved" · "REFUSE rate 100% match Anthropic warning 'tightly interdependent coding'" · "Grep ... ZERO results" · "Test compile error ... left for K7 chunk (spec exclude test scope)" · "Anti-fiddle threshold <20% LOC respected" · "Cookie-cutter 0 (lần đầu pattern)" · "2 pre-existing DocxRenderer warn" (lặp 3 lần)
  • guard: HasDefaultValue(false) (ApprovalWorkflowConfiguration.cs) · sentinel false + marker comment K2 tại 4 site vỡ biên-dịch · tham-số tuỳ-chọn mặc-định false giữ tương-thích 4 test cũ · grep-về-ZERO 5 biến-thể (AllowDrafterSkipToFinal · allow-skip-final · allowDrafterSkipToFinal · Skip cuối · FastForward) · InternalsVisibleTo (Pattern 12) · guard đôi FE+BE (Pattern 9) · dotnet build 0 err + npm run build 0 TS err trước khi khai PASS · ngưỡng anti-fiddle <20% LOC · route đặt trước /workspace
  • root-cause: PeDetailBundle không phơi changelogs ⇒ TS2339 khi dựng lịch-sử tại chỗ · Mig 31 chuyển chỗ lưu ⇒ 4 site Application vỡ biên-dịch + 1 test tham-chiếu prop đã xoá (:253) · EditLevelEntry không có approverFullName (chỉ LevelDto BE có approverUserName) ⇒ phải tra từ usersList · shadcn fe-user là subset tối-thiểu ⇒ thiếu Card/Badge · Summary là chuỗi cố-định ⇒ nội-dung động phải nằm ở ContextNote (service:96-99LogTransition)
  • file:line / định-danh (BE): ApprovalWorkflow.cs (+AllowApproverSkipToFinal; narrative :78-80; docstring :108) · User.cs (1 prop) · ApprovalWorkflowConfiguration.cs (:22-24 narrative, :87 storage-move comment) · PurchaseEvaluationWorkflowService.cs :121-157 (37 LOC), :287-333 (F1 edge), :96-99 (comment → ContextNote) · UserFeatures.cs · SetUserAllowDrafterSkipToFinalCommand(+Handler) · UsersController.cs + SetAllowDrafterSkipToFinalBody · PurchaseEvaluationFeatures.cs :401 · ApprovalWorkflowV2AdminFeatures.cs :58 · IPurchaseEvaluationWorkflowService.cs · PurchaseEvaluationDtos.cs · ApplicationDbContext.OnModelCreating ~:86 · DbInitializer.cs (cờ DemoSeed ~25 LOC)
  • file:line / định-danh (test + FE): PurchaseEvaluationWorkflowServiceReturnModeTests.cs :253 (vỡ, để cho K7), :241 (chèn 2 [Fact] mới) · helper SeedWorkflowAsync / SeedApproversAsync / SeedApproverF2WorkflowAsync (2 Bước × 2 Cấp) / BuildPeAtLevel2 · test xoá: SkipToFinal_DrafterAllowed_SetsPointerToFinalLevel · SkipToFinal_DrafterDenied_NonAdmin_Throws · SkipToFinal_AdminBypass_Succeeds · test thêm: ApproveV2_SkipToFinal_AdminTickFlag_SetsPhaseDaDuyet · ApproveV2_SkipToFinal_FlagOff_NonAdmin_ThrowsConflictException · ApproveV2_SkipToFinal_FlagOff_Admin_BypassesFlagCheck · ApplyReturnMode_OneLevel_AtStep1Level1_ResetsToBuoc1Cap1_KeepsChoDuyet · ApplyReturnMode_OneStep_AtStep1_ResetsToBuoc1Cap1_KeepsChoDuyet · ApprovalWorkflowsV2Page.tsx :873, ~:500, :535, banner ~:623, stale :75 + :504 (hoãn K6) · UsersPage.tsx + types/users.ts · types/purchaseEvaluation.ts (PurchaseEvaluationPhaseLabel[98], PeDisplayStatusLabel.TraLai) · PeWorkflowPanel.tsx · fe-user/src/types/approvalWorkflowV2.ts (~55 LOC, 5 record type AwLevelDto/AwStepDto/AwDefinitionDto/AwTypeSummaryDto/AwAdminOverviewDto) · fe-user/src/pages/pe/WorkflowMatrixViewPage.tsx (~215 LOC) · fe-user/src/App.tsx route /purchase-evaluations/workflow-matrix · seed-test-users-prod.ps1$authResp.accessToken · scripts/plan-r-*.sql + plan-s-*.sql + plan-t5-*.sql + plan-t-backup.sql
  • số-đo: test 84 → 104 → 106 · mig 29 → 30 → 31 · endpoint ~146 (+3) · user prod 33 (13 cũ + 20 mới) · diff K5 +42/-94 (9 file) · K7 +175/-92 (1 file) · K3 +26/-7 · M2 +94 · M3 +4/-4 ×2 = 8 LOC · bundle fe-admin 1395 / 1395.74 KB · fe-user 1275 / 1282 KB (1907 module, 2.61s) · commit S24 7 (a1a910f..ee0902a, 1 spawn + 6 solo) · token/chunk ~5k-14k · MEMORY nguồn 38.8 KB · ~720 rows wiped

implementer-backend/2026-05-q2 (12.442 B — "S25 Plan AB → S29 Plan B Chunk D, 5 entry verbose")

Đặc-điểm file: 5 entry, header khai 38.4KB → mục-tiêu ~21KB. Đậm đặc pattern-numberSHA256 mirror-verify.

🔴 VA-CHẠM SỐ HIỆU PATTERN (fidelity-flag, KHÔNG tự phán — đề-nghị lead định-đoạt): trong cùng file này, nhãn "Pattern 16 NEW" được gán cho hai thứ khác nhau: · dòng 18 (S25 wrap): "Pattern 16 NEW: Preventive systemic batch fix khi audit phát hiện 9 sites cùng bug pattern" · dòng 26 (S27 Plan CA): "Pattern 16 NEW — byte-identical mirror admin → user khi parity confirmed" Chứng-cứ liên-quan (file q4, dòng 53) tự khai đã biết chỗ mờ: "Pattern 16 baseline implied trong recent activity S27 chưa numbered explicit". ⇒ Khi nén, cấm gộp 2 mục này thành một chỉ vì trùng số.

Cụm-dedup

# Cụm Thành-phần Tag
G1 Plan AB Chunk A (cdfd542) — mô-tả 2 LẦN trong file entry "S25 Plan AB Chunk A" (dòng 14, dày) + phần đầu entry "S25 wrap" (dòng 18, tóm) — trùng ~60% cao
G2 S26 Plan AG — cây thư-mục kiểu Outlook cho PE List (Pattern 19) 3 chunk gộp 1 commit 0bf6c7e cao
G3 S27 Plan CA Chunk B — mirror byte-identical + bẫy PowerShell 4 trang master admin→user + gotcha $_ bị nuốt cao
G4 S29 Plan B Chunk D — dropdown V2 cho ContractCreatePage mirror từ PE, kiểm 4-chỗ Pattern 16-bis vừa
G5 META: kỷ-luật "chứng mirror bằng HASH, không bằng mắt" G2 (21001E90…) · G3 (4 SHA256) · G4 (git diff stat) · bộ đếm Pattern 5 7th → 8th → 9th cao

Ghi-chú dedup: G1 là ca trùng rõ nhất batch A — 2 entry cùng tả một commit. Phần chỉ có ở entry wrap mà phải giữ: 6 plan em-main tự làm sau đó (AC→AF) + 3 Pattern mới 16/17/18 + lý-do vì sao vai sẽ từ-chối (tiêu-chí #4). Phần chỉ có ở entry dày: số dòng cụ-thể, chuỗi modeName switch, cách resolve actorName, thời-gian build.

Bản-nén-nháp 4-field

[cao] G1 — Plan AB Chunk A: gộp 4 nhánh về một chỗ ghi log

  • VIỆC: sửa 2 lỗi UAT về nhật-ký duyệt (cdfd542, 3 file, +146/-95).
  • KẾT-LUẬN: BE viết lại ApplyReturnModeAsync (:215-378): bỏ return sớm của nhánh Drafter (~:282-287) → chuyển thành if/else một đường chung, để một Changelog.Add() duy nhất ở cuối phủ cả 4 mode (Summary=$"Trả lại ({modeName}): {summary}", modeName switch 4 giá-trị tiếng Việt); actorName lấy qua userManager.FindByIdAsync theo đúng khuôn LogTransition ~:660-667; không gọi SaveChangesAsync mới vì caller TransitionAsync:100 đã lưu. FE 2 app nới bộ lọc: theo summary chứa "Trả lại" (Workflow) và entityType === PE_ENTITY_HEADER(=1) + chứa "ngân sách". Test bỏ qua theo chế-độ UAT (giữ mốc 111).
  • BÀI-HỌC: khi N nhánh cùng phải ghi một loại log, gỡ return sớm để có đường chung rồi ghi một lần — thay vì rải N lời gọi. Và lọc ở FE bằng chuỗi con của summary (động-từ tiếng Việt) thay vì enum cứng: FE thêm luật lọc mới không cần migrate BE.
  • BẤT-NGỜ: cùng một đoạn được tả 2 lần trong cùng file với số dòng lệch nhau (282-287 ở entry dày vs 280-287 ở entry wrap) ⇒ khi hợp-nhất phải chọn bản dày, đừng trộn số.

[cao] G2 — Plan AG: cây 2 tầng bằng HTML thuần (Pattern 19)

  • VIỆC: bro phản-hồi danh-sách PE phẳng là "đám rừng" → dựng cây Dự-án ▸ Gói-thầu kiểu thư-mục Outlook (0bf6c7e, 2 file, +346/-116).
  • KẾT-LUẬN: gom bằng useMemo 2 tầng (ProjectGroup / GoiThauGroup, khoá chuẩn-hoá trim+toLowerCase, hiển-thị bản gốc đầu tiên), có nhánh dự-phòng "(Dự án đã xoá)" / "(Chưa phân loại)", sắp theo locale vi, lọc trước khi gom để trạng-thái rỗng đúng. UI dùng <details>/<summary> thuần trình-duyệt (fe-user không có Accordion của shadcn) + Tailwind named group group/proj · group/gt + [&::-webkit-details-marker]:hidden. Ghi nhớ trạng-thái mở bằng localStorage (pe_list_expanded_groups, khoá ${projectId}::${normalizedGoiThau}, mặc-định đóng hết) có try/catch phòng chế-độ ẩn-danh. 2 app giống nhau tới SHA256 (21001E90…).
  • BÀI-HỌC: thiếu thư-viện thì dùng thẻ HTML gốc: <details> cho sẵn trạng-thái đóng/mở, bàn-phím Space/Enter, 0 dòng JS quản trạng-thái từng nút. Đổi thước đếm cũng phải đổi đồng-bộ (rows.lengthprojectGroups.length), nếu không trạng-thái rỗng sẽ nói dối.
  • BẤT-NGỜ: anti-pattern được ghi rõ: nếu hai group lồng nhau trùng tên group (không đặt tên) thì con kế thừa trạng-thái cha ⇒ cả hai xoay chevron cùng lúc — một lỗi UI chỉ lộ khi lồng, và named-group là cách chữa.

[cao] G3 — Plan CA Chunk B: mirror nguyên-si + bẫy PowerShell

  • VIỆC: dời 4 trang danh-mục từ fe-admin sang fe-user (06a441c, 6 file, +962 LOC).
  • KẾT-LUẬN: vì Investigator đã xác-nhận 2 app ngang bằng (DataTable/PageHeader/PermissionGuard/usePermission/6 shadcn/types), nên chép nguyên file không sửa, rồi verify SHA256 cả 4 (C1760788…/BDF0529E…/68213D62…/6F482614…) ⇒ an-toàn vì mã bên admin đã qua UAT. Đúc pattern_master_page_mirror.md.
  • BÀI-HỌC: "chép y nguyên" chỉ hợp-lệ khi đã chứng ngang-bằng trước; và bằng-chứng phải là hash sau khi ghi, không phải cảm-giác đã-copy-đúng.
  • BẤT-NGỜ: bẫy công-cụ: biến $_ của PowerShell trong khối ForEach-Object bị Bash tool nuốt khi escape ⇒ phải đổi sang dạng liệt-kê Get-FileHash file1, file2, … | Format-Table thay vì lặp qua pipeline. Tức chính cách gọi shell làm hỏng phép kiểm, không phải lệnh sai.

[vừa] G4 — Plan B Chunk D: dropdown V2 cho ContractCreatePage

  • VIỆC: mirror ô chọn quy-trình V2 từ PE sang HĐ (62b50d1, 2 file, +44 LOC mỗi app).
  • KẾT-LUẬN: dựa nguyên bản PeWorkspaceCreateView.tsx (:80-89 useQuery + :152-172 UI Select), đổi duy nhất trường phân-biệt ApplicableType=3; kiểm tiền-đề BE trước khi wire: CreateContractCommand (ContractFeatures.cs:17-36) đã có Guid? ApprovalWorkflowId = null kèm marker của em-main ⇒ không lệch DTO. Áp Pattern 16-bis 4 chỗ: trang ×2 DONE, còn Routes / menuKeys / Layout staticMap đều N/A có lý-do.
  • BÀI-HỌC: mirror xuyên module thì liệt-kê đủ 4 chỗ rồi ghi N/A kèm lý-do, đừng im lặng bỏ qua — "N/A" có lý-do mới chứng-minh là đã xét.
  • BẤT-NGỜ: vai kiểm tiền-đề phía BE trước khi sửa FE (đọc record của commit em-main làm trước) — nhờ vậy không đẻ ra lỗi lệch hợp-đồng dữ-liệu; và tự khai phần cố-ý không làm (chỉ ContractHeaderForm, không đụng ContractEditForm).

[cao] G5 — META: mirror phải chứng bằng hash

  • VIỆC: trục lặp ở 3/5 entry.
  • KẾT-LUẬN: Pattern 5 (mirror 2 app §3.9) được đếm tích-luỹ lần 7 → 8 → 9; mỗi lần đều kèm bằng-chứng máy: SHA256 khớp (AG, CA) hoặc git diff --stat byte-similar (Chunk D). Verbatim còn đề-xuất biến thành công-cụ: "recommend tooling git diff fe-admin/X fe-user/X after every multi-file edit batch".
  • BÀI-HỌC: với công-việc nhân-bản, đối-chứng máy rẻ hơn review mắt và phát-hiện được thứ mắt không thấy (khác 1 ký-tự).
  • BẤT-NGỜ: vai tự đếm số lần áp-dụng một pattern (7/8/9) — biến "kinh-nghiệm" thành con-số kiểm được, thay vì nói "đã dùng nhiều lần".

Token-list (verbatim, implementer-backend/2026-05-q2)

  • Pattern#: 4 feedback_service_hook_vs_endpoint (log trong service hook, KHÔNG endpoint /return-changelog rời) · 5 mirror 2 app §3.9 (7th/8th/9th cumulative) · 16 (VA-CHẠM — 2 nghĩa, xem cảnh-báo trên) · 16-bis kiểm 4 chỗ cross-app · 17 FE merge synthetic row · 18 FE userMap fallback từ dữ-liệu nhúng · 19 <details>+named group+localStorage · 12-bis cookie-cutter xuyên module · Pattern 7 (per-NV opt-in, nhắc lại)
  • criteria#: #4 (tight coupling BE+FE ⇒ vai sẽ REFUSE Plan AC trở đi)
  • surprise: "Gotcha S27: PowerShell $_ variable in ForEach-Object block bị Bash tool shell-escape eaten" · "fe-user no shadcn Accordion → native browser disclosure widget free" · "Anti-pattern: nested same-name group would inherit parent state → both rotate sync" · "Mirror 2 app §3.9 IDENTICAL post-edit (SHA256 verify match 21001E90...)" · "stash em main WIP ... race condition trick" (nhắc chéo) · "KHÔNG ops git push (em main verify Reviewer rồi mới push)" (lặp 3 entry) · "FE filter qua substring summary keyword chứ KHÔNG enum field strict" · "recommend tooling git diff fe-admin/X fe-user/X after every multi-file edit batch" · số dòng lệch 282-287 vs 280-287 cho cùng đoạn
  • guard: try/catch quanh localStorage (quota / ẩn-danh) · lọc pendingMe TRƯỚC khi gom nhóm · projectGroups.length === 0 thay rows.length === 0 · SHA256 sau khi ghi (4 file) · git diff --stat byte-similar · kiểm tiền-đề BE (Guid? ApprovalWorkflowId = null) trước khi wire FE · [&::-webkit-details-marker]:hidden · named group group/projgroup mặc-định · không gọi SaveChangesAsync mới (caller đã lưu)
  • root-cause: return sớm ở nhánh Drafter ⇒ không có đường chung ⇒ phải rải nhiều lời-gọi log ⇒ gom về if/else + 1 Changelog.Add() · fe-user thiếu Accordion ⇒ chuyển sang <details> gốc · group không đặt tên khi lồng ⇒ con kế-thừa trạng-thái cha · Bash tool escape nuốt $_ForEach-Object gãy
  • file:line / định-danh: PurchaseEvaluationWorkflowService.cs ApplyReturnModeAsync :215-378, Drafter early-return :282-287 (wrap ghi :280-287), userManager.FindByIdAsync mirror :660-667, caller TransitionAsync :100 · PeDetailTabs.tsx ×2 (filter + comment 3-nguồn) · PE_ENTITY_HEADER = 1 · Summary=$"Trả lại ({modeName}): {summary}" ("Người soạn thảo"/"1 Cấp"/"1 Bước"/"Người chỉ định") · ProjectGroup{projectId, projectName, goiThauList[], totalCount} · GoiThauGroup{displayName, normalizedKey, items[]} · pe_list_expanded_groups · __no_project__ · ${projectId}::${normalizedGoiThau} · group/proj · group/gt · group-open/proj:rotate-90 · PeWorkspaceCreateView.tsx :80-89 + :152-172 · ContractCreatePage.tsx ×2 · CreateContractCommand @ ContractFeatures.cs :17-36 (Guid? ApprovalWorkflowId = null, marker [Plan B S29 2026-05-22 Chunk E1]) · ApplicableType=3 · Mig 25 IsUserSelectable · pattern_master_page_mirror.md · feedback_uat_skip_verify
  • sha / số-đo: cdfd542 (3 file +146/-95; BE +83/-49; FE +14/-6 mỗi app) · 0bf6c7e (2 file +346/-116 = +115 mỗi app) · 06a441c (6 file, +962) · 62b50d1 (2 file, +44 ×2 = +88) · SHA256 21001E90… · C1760788… / BDF0529E… / 68213D62… / 6F482614… · build: BE 20.27s · fe-user 1907 module 16.62s / 16.05s / 14.14s / 8.84s · fe-admin 1926 module 6.98s / 6.86s / 16.07s · bundle fe-user 1291.33 KB (gzip 337.00) / 1.32MB (gzip 343KB) · fe-admin 1402.68 KB (gzip 357.51) / 1.40MB (gzip 358KB) · test mốc 111 (bỏ qua theo UAT) · token ~10k-16k · warn nền: CSS @import + INEFFECTIVE_DYNAMIC_IMPORT realtime.ts (lặp 3 entry) · tag [pattern, phase-9, frontend]

implementer-backend/2026-05-q3 (5.353 B — "S34 curate", 6 entry)

Đặc-điểm file: 6 entry NGẮN, phần lớn là wrap / hồi-cứu / meta chứ không phải nhật-ký làm việc: S29 wrap · S28 wrap governance · S27 hồi-cứu REFUSE (có bảng 8 dòng) · log curate · setup baseline 2026-05-11.

🔴 FIDELITY-FLAG (ĐÃ ĐO TRÊN ĐĨA — đề-nghị lead route sang reviewer, vai này KHÔNG tự phán "bịa"): Dòng 16 khai: "Pattern 7 per-NV admin opt-in flag (Mig 29 AllowDrafterEdit + Mig 30 AllowApproverEditSection1 + Mig 31 AllowEarlyApprove + AllowDelegate) đã proven 4×". Phép đo hôm nay (git grep -i … -- src/Backend), có cả 2 control: · control DƯƠNG AllowApproverSkipToFinal54 file có hit (thước còn răng) · control ÂM AllowXyzKhongTonTai (tên tự bịa) → 0 · 4 tên trong claim: AllowDrafterEdit 0 · AllowApproverEditSection1 0 · AllowEarlyApprove 0 · AllowDelegate 0bằng đúng control âm. Tên Mig thật (từ git ls-files, tiền-tố 2026-05-13/14): …114505_AddAdvancedOptionsToApprovalWorkflows (28) · …130144_RefactorAdvancedOptionsToPerLevelAndDrafterUser (29) · …160703_AddAllowApproverEditBudgetToLevels (30) · …160124_RefactorSkipToFinalToApproverLevel (31). Giả-thuyết LÀNH (không tự kết-luận): vai dùng từ-vựng giao-diện thay tên code — "EditSection1/2" ↔ AllowApproverEditBudget/AllowApproverEditDetails (q1 tả checkbox F4 là "Edit Section 2"); cùng lỗi này lặp ở q1 dòng 19 ("Mig 30 AllowApproverEditSection1") ⇒ là trôi từ-vựng có hệ-thống, không phải gõ nhầm một lần. Phần CHƯA giải-thích được: AllowEarlyApprove + AllowDelegate không có đối-ứng nào ở Mig 31 (thật = AllowApproverSkipToFinal). ⇒ khi nén, KHÔNG chép 4 tên này; nếu cần giữ ý thì viết "Pattern 7 đã áp 4 lần qua Mig 29/30/31" bỏ tên cờ. ⚠️ Phụ: dòng 47 khai "5 patterns proven cumulative S1-S20" nhưng liệt-kê 6 mục (per-chunk · 3-file rule · audit-reuse clone · service hook · FE mirror · VND helper).

Cụm-dedup

# Cụm Thành-phần Tag
H1 S29 wrap — 5 spawn, bận nhất; race-condition + 1 ca DỪNG GIỮA CHỪNG 4 chunk PASS + E3 stopped + 3 bài học vận-hành cao
H2 S27 hồi-cứu REFUSE — bảng 8 task, tự chấm 2/8 lẽ ra nhận bảng + tiêu-chí #1/#2/#4/#7 + Pattern 20 mới cao
H3 S28 — governance Layer A + 5 điều tự áp tag schema · source_path · cấm tự-cho-phép luật liên-dự-án · 1 luật bị BỎ vừa
H4 Log curate + setup baseline 12 entry → q1 (38.8 → ~22-24KB) · khởi-tạo 2026-05-11 thấp

Ghi-chú dedup: H1 và H2 cùng nói về "nên/không nên giao việc" nhưng ngược chiều — H1 là ca nhận rồi vỡ (E3), H2 là ca lẽ ra nhận mà không nhận được. Giữ 2 cụm; gộp sẽ mất tính đối-xứng của bài học.

Bản-nén-nháp 4-field

[cao] H1 — S29 wrap: 5 lần được gọi, và bài học về chạy song-song

  • VIỆC: phiên bận nhất — Plan CA Chunk B (~10K) + Plan B 4 chunk (A2 Mig 32 ~25K · C Mig 33 ~25K · D FE ~12K · E3 dừng giữa chừng).
  • KẾT-LUẬN: A2 phải stash phần đang làm dở của em-main (ContractWorkflowService.cs) mới build sạch được — vì em-main và vai cùng sửa BE song song. E3 (FE Section 5 V2) tự dừng đúng chỗ phải phán-đoán ("check ContractDetail type") và trả lại cho em-main. Đúc 3 luật: (1) khi cùng chạm BE thì chunk phải tuần-tự A→B→C, không song-song; (2) tính-năng FE phức-tạp cần mở rộng type + thêm component thì em-main tự làm đáng tin hơn khi độ mơ-hồ của spec >20%; (3) Pattern 16-bis được củng-cố lần 2.
  • BÀI-HỌC: song-song trên cùng một lớp code đẻ ra chi-phí ẩn (mẹo stash) — nhanh trên giấy, chậm khi chạy. Và ngưỡng giao việc nên tính bằng độ mơ-hồ của spec, không bằng số file.
  • BẤT-NGỜ: vai tự dừng giữa nhiệm-vụ thay vì đoán bừa — biến "không đủ dữ-kiện" thành hành-động hợp-lệ, và ghi lại đúng chỗ dừng để người sau nối tiếp.

[cao] H2 — S27 hồi-cứu: tự chấm điểm việc mình KHÔNG được gọi

  • VIỆC: dựng bảng 8 task của S27, đối chiếu từng dòng với tiêu-chí nhận/từ-chối.
  • KẾT-LUẬN: 6/8 xác-nhận "em-main tự làm là ĐÚNG" (curate MEMORY = phán-đoán §6.5 giữ-hay-cắt → #1 · dashboard = #7 chưa có tiền-lệ + #2 · viết docs 421 dòng = #2 · sửa lỗi Qdrant = #4). 2/8 lẽ ra giao được: A3.1 viết 5 script PS (Case 2) và F2 sửa model:inherit ở 4 file agent (Case 1) — nhưng registry không nạp được nên em-main buộc phải tự làm; thiệt-hại ước ~30 phút + mất kỷ-luật mirror. Đúc Pattern 20 (bộ 5 script PS start/stop/status/dashboard/boot: cùng kỷ-luật ASCII, cùng cấu-trúc Write-Host, cùng khuôn try-catch).
  • BÀI-HỌC: hồi-cứu phải chấm từng dòng, không chấm tổng — nhờ vậy mới tách được "quyết đúng" khỏi "quyết đúng nhưng vì lý do sai" (2 ca này em-main đúng kết-quả nhưng nguyên-nhân là hạ-tầng hỏng, không phải phán-đoán).
  • BẤT-NGỜ: cơ-hội bị mất không do ai quyết sai mà do registry rỗng — tức lỗi hạ-tầng lặng-lẽ biến thành lỗi phân-công, và chỉ lộ ra khi có bảng hồi-cứu.

[vừa] H3 — S28: 5 điều tự áp sau khi bị bắt lỗi

  • VIỆC: ghi lại governance Layer A dưới góc nhìn của vai.
  • KẾT-LUẬN: (1) pattern đã chứng ≥2 lần thì đủ tư-cách đề-cử lên Layer B; (2) tag bắt buộc [pattern, phase-<N>, <bc>]; (3) quy-ước source_path = solution_erp/pattern/<topic>-<date>; (4) cấm tự cho phép mình đặt luật xuyên dự-án — đúc từ ca t4 bro bắt tại trận; (5) luật cũ "mọi tương-tác đều phải lưu" BỊ BỎ.
  • BÀI-HỌC: phạm-vi quyền của một vai phải thu về chính dự-án của nó; và luật cũ nên khai tử công-khai ("ABANDONED") thay vì để trôi — luật zombie còn hại hơn không có luật.
  • BẤT-NGỜ: chính vai này ghi nhận mình quên mất luật cũ rồi mới phát-hiện luật đó đã bị bỏ — quên đúng thứ đáng quên, nhưng chỉ biết là "đúng" sau khi tra lại.

[thấp] H4 — Log curate + baseline

  • VIỆC: ghi mốc: dồn 12 entry S21→S24 sang archive/2026-05-q1.md; và mốc khởi-tạo 2026-05-11.
  • KẾT-LUẬN: MEMORY 38.8 KB → mục-tiêu ~22-24 KB, giữ nguyên khối Pattern 1-19; lúc khởi-tạo vai đã nạp sẵn 5 (thực tế liệt-kê 6) pattern nền tích-luỹ S1-S20, chưa làm gì, đã bật sẵn cơ-chế tự từ-chối theo phạm-vi.
  • BÀI-HỌC: mỗi lần dồn kho phải ghi nguồn → đích + kích-thước trước/sau + thứ giữ lại thì lần sau mới truy được.
  • BẤT-NGỜ: vai bật quy-tắc từ-chối ngay từ lúc chưa làm việc nào — ranh-giới được cài trước, không phải rút ra sau khi vỡ.

Token-list (verbatim, implementer-backend/2026-05-q3)

  • Pattern#: 7 per-NV admin opt-in (tên cờ SAI — xem FIDELITY-FLAG) · 12-bis cross-module cookie-cutter · 16-bis 4-place mirror (reinforced 2×) · 20 MỚI (bộ 5 script PS mirror) · nền "5 patterns S1-S20" (liệt-kê 6 mục)
  • criteria#: #1 phán-đoán giữ-hay-cắt (§6.5) · #2 thiết-kế UX / viết docs · #4 chuỗi suy-luận sửa lỗi · #7 lần đầu, chưa tiền-lệ · Case 1 (n file sửa cơ-học giống nhau) · Case 2 (cookie-cutter mirror)
  • surprise: "E3 stopped mid-task ... STOPPED at 'check ContractDetail type' judgment call" · "stash em main WIP ContractWorkflowService.cs để build verify clean (em main + Implementer parallel touch BE → race condition trick)" · "Forward SEQUENTIAL chunks A→B→C khi cùng touch BE, NOT parallel" · "em main solo more reliable than Implementer khi spec ambiguity > 20%" · "2/8 task lẽ ra delegate được ... nhưng registry empty → em main forced solo" · "Net loss ~30 phút" · "registry KHÔNG load (per pitfall VIPIX #1+#2)" · "bro caught self-authorize cross-project rule mistake" · "Quên rule cũ 'mọi tương tác mandatory store' — ABANDONED" · "Implementer = busiest agent S29 với 5 spawn"
  • guard: git stash phần WIP trước khi build verify · chunk tuần-tự khi cùng chạm BE · ngưỡng spec ambiguity 20% để chuyển về em-main · tự-dừng khi gặp judgment call · tag schema bắt buộc [pattern, phase-<N>, <bc>] · cấm tự-cho-phép luật liên-dự-án · pattern phải proven ≥2× mới đề-cử Layer B
  • root-cause: em-main + vai cùng sửa BE song song ⇒ cây làm việc bẩn ⇒ build verify không sạch ⇒ phải stash · registry không nạp ⇒ không spawn được ⇒ 2 việc hợp-lệ bị dồn cho em-main · từ-vựng UI-section dùng thay tên cờ trong code ⇒ 4 tên cờ 0-hit (xem FIDELITY-FLAG)
  • file:line / định-danh: ContractWorkflowService.cs (WIP bị stash) · Mig 32 (+column FK Restrict + IX + Configuration + DbInitializer SeedSampleContractWorkflowV2) · Mig 33 ContractLevelOpinions (entity + Mig + Config + DbSet + Contract.cs +LevelOpinions nav) · ContractCreatePage.tsx ×2 (88 LOC) · 4 master page + App.tsx (+5 route) + menuKeys.ts (+5 key Catalogs*) · pattern_master_page_mirror.md · archive/2026-05-q1.md · script PS start/stop/status/dashboard/boot
  • số-đo: 5 spawn S29 · ~10K + ~25K + ~25K + ~12K token · 948 LOC mirror / 6 file · MEMORY 38.8 KB → ~22-24 KB · 12 entry dồn kho · setup 2026-05-11
  • 🔬 disk-check hôm nay (S170, có 2 control): AllowApproverSkipToFinal = 54 file (control dương) · AllowXyzKhongTonTai = 0 (control âm) · AllowDrafterEdit / AllowApproverEditSection1 / AllowEarlyApprove / AllowDelegate = 0 / 0 / 0 / 0 · Mig thật: 20260513114505_AddAdvancedOptionsToApprovalWorkflows · 20260513130144_RefactorAdvancedOptionsToPerLevelAndDrafterUser · 20260513160703_AddAllowApproverEditBudgetToLevels · 20260514160124_RefactorSkipToFinalToApproverLevel

implementer-backend/2026-05-q4 (6.243 B — "late May, S32-S33 verbose entries")

Đặc-điểm file: 5 khối nội-dung, nhưng thứ-tự bị xáo (xem cảnh-báo). Gồm: S33 Task 5 (HRM scaffold FE) · 2 khối "archived S65 FIFO trim" (S35 G-H2 · S29 Chunk C) · S32 wrap · S32 startup.

🔴 LỖI CẤU-TRÚC — ENTRY BỊ CHẺ ĐÔI (Placement, ưu-tiên cao khi nén): Entry S33 Task 5 bắt đầu ở dòng 7-11, nhưng phần đuôi của nó bị đẩy xuống dòng 23-27 — nằm SAU hai khối không liên-quan (S35 G-H2 và S29 Chunk C, cả hai gắn nhãn "archived S65 FIFO trim", tức được chèn vào giữa ở một đợt dồn kho sau). Bằng-chứng phần đuôi thuộc về S33 Task 5, không thuộc S29 Chunk C: dòng 25 liệt-kê types/employee.ts · EmployeesListPage.tsx · EmployeeCreatePage.tsx · Layout.tsx +4 staticMap **Hrm_HoSo** · "6 fe-user files mirror" — toàn bộ là HRM, khớp dòng 9; trong khi S29 Chunk C là Contract V2 / Mig 33, 8 file +4265 LOC. Dòng 27 còn ghi Tag: [mirror-page, phase-10.1, frontend] = đúng nhãn phase của Task 5. ⚠️ Rủi-ro nếu nén ẩu: khối "Verify all clean / Files touched / Out-of-scope respected" sẽ bị gán nhầm cho S29 Chunk C ⇒ tạo ra một bản ghi sai hoàn-toàn (gán 120/120 test + file HRM cho một việc Contract). ⇒ Đề-xuất: nối lại dòng 23-27 về ngay sau dòng 11 TRƯỚC khi nén.

Cụm-dedup

# Cụm Thành-phần Tag
I1 S33 Task 5 — scaffold HRM FE 2 app (thân dòng 7-11 + ĐUÔI dòng 23-27) 14 file, 3 SHA256 giống hệt, Pattern 16-bis/12-bis lần 4 cao
I2 2 khối digest "archived S65 FIFO trim" S35 G-H2 BE CRUD 4 catalog · S29 Plan B Chunk C Mig 33 vừa
I3 S32 wrap — backlog Plan G + 4 việc chờ + REFUSE trước 11 module / 10 sprint + (a)(b)(c)(d) vừa
I4 S32 startup — tự đo kho, TỪ CHỐI tự dọn, kiểm RAG sống 36.2KB FLAG + 17 pattern + rerank 3 điểm cao

Ghi-chú dedup: I2 gộp 2 khối vì cùng thể loại (digest đã nén sẵn ở đợt S65, mỗi khối 2-3 dòng + tag) — đây là lớp chưng-cất, nén tiếp sẽ mất mã-số kỹ-thuật; đề-nghị giữ gần nguyên.

Bản-nén-nháp 4-field

[cao] I1 — S33 Task 5: scaffold HRM cho 2 app, phạm-vi cực hẹp

  • VIỆC: dựng 3 trang/type HRM (Phase 1 chỉ-đọc) mirror sang cả 2 app — tổng 14 file (3 file MỚI ×2 app + 4 file sửa ×2).
  • KẾT-LUẬN: ACCEPT vì spec xác-định 100%, kiểu ULTRA-MINIMAL (không tách component DetailTabs, 6 mục dùng <details> nội-tuyến, không CRUD vệ-tinh). 3 file mới giống hệt tới SHA256: CCFC70666568 · DC859C897C5C · C796F25D01AC. Kiểm sạch toàn bộ: fe-admin 21.4s / fe-user 9.2s / dotnet build 1.59s 0 warn 0 err / dotnet test 120/120 (58 Domain + 62 Infra) — và "Ambiguities encountered: 0". Pattern 16-bis + 12-bis đều được ghi là lần thứ 4.
  • BÀI-HỌC: phạm-vi hẹp phải ghi kèm danh-sách "cố-ý không làm" (không form vệ-tinh · không sửa nội-tuyến Header · không wire PermissionGuard vì em-main giữ Task 6 · không thêm Bg_*/Catalog*) — nếu không, người đọc sau sẽ tưởng là thiếu sót.
  • BẤT-NGỜ: cả hai "lần thứ 4" đều chỉ liệt-kê 3 lần trước (16-bis: CA HF1 + Chunk D + Task 5; 12-bis: Chunk C + Task 4 + Task 5) ⇒ số đếm không khớp danh-sách; cùng loại lệch với "5 patterns/6 mục" ở q3 ⇒ khi nén nên giữ danh-sách, bỏ số thứ-tự.

[cao] I4 — S32 startup: tự đo kho rồi TỪ CHỐI tự dọn

  • VIỆC: lượt spawn chỉ để kiểm bối-cảnh phiên 32.
  • KẾT-LUẬN: đo Get-Item Length = 36.207 byte (36.2KB) ⇒ vượt ngưỡng 25KB ~45%gắn cờ cho em-main, và cố-ý KHÔNG tự dọn vì việc giữ-hay-cắt là phán-đoán §6.5 thuộc em-main (viện dẫn chính bài học C1-C4 của S27). Xác-nhận còn đủ 17 pattern đánh số (1-12 + 12-bis + 13-15 + 16-bis + 17-19). RAG sống: 2 tool MCP hiện diện, truy-vấn thử trả 3 kết-quả rerank 0.824 / 0.801 / 0.793 — đều > ngưỡng 0.7.
  • BÀI-HỌC: đo bằng byte thật của hệ-điều-hành rồi mới phán "quá ngưỡng"; và phát-hiện ⟂ xử-lý — vai được quyền gắn cờ nhưng không được quyền cắt, đúng ranh-giới đã chốt từ ca trước.
  • BẤT-NGỜ: tự-kiềm-chế được ghi kèm lý-do có dẫn nguồn (bài học S27), không phải "ngại làm" — và chính cái cờ này về sau thành đợt curate S32 (36.2 → 27.5KB).

[vừa] I2 — Hai digest "archived S65 FIFO trim"

  • VIỆC: 2 việc BE cũ được nén còn vài dòng ở đợt dồn kho S65.
  • KẾT-LUẬN: S35 G-H2: CRUD 4 danh-mục HRM (HrmConfigFeatures.cs 372 LOC + Controller 134 LOC, 16 endpoint = 4 tài-nguyên × 4 động-từ), giữ mốc 130 test, spec rõ 95%. S29 Chunk C: mirror Contract V2 (Mig 33), 8 file +4265 LOC nhưng Designer tự sinh 95%, tay chỉ ~232 LOC.
  • BÀI-HỌC: 2 điểm kỹ-thuật đắt nhất nằm ở S35: HRM không có HasQueryFilter ⇒ phải tự viết .Where(!IsDeleted); và độ dài MaxLength lấy EF làm chuẩn, không lấy spec (Code=50, spec ghi 20).
  • BẤT-NGỜ: "+4265 LOC" nghe khổng-lồ nhưng 95% là mã tự sinh — con-số LOC thô không đo được công sức, phải tách phần tay viết (~232) mới so được.

[vừa] I3 — S32 wrap: dựng hàng chờ cho phiên sau

  • VIỆC: đóng phiên 32, lập backlog.
  • KẾT-LUẬN: ghi 11 module Plan G thành 10 sprint nguyên-tử trong migration-todos; nêu 4 việc chờ phiên 33 kèm phân loại sẵn (a) G-H1 scaffold hồ-sơ NS · (b) bộ test BW1-BW7 mirror khuôn test PE · (c) BookingCalendar (FullCalendar = thư-viện mới) · (d) G-O3..G-O6 mirror 4 module Workflow Apps. Kèm REFUSE trước: sẽ nhận scaffold theo spec xác-định, không nhận thiết-kế schema (Mig 34 để em-main).
  • BÀI-HỌC: backlog nên kèm sẵn nhãn nhận/từ-chối cho từng mục — quyết định phân-công xong từ lúc lập kế-hoạch, không phải lúc bị gọi.
  • BẤT-NGỜ: vai từ-chối trước cả khi được giao ("REFUSE forward") — ranh-giới được tuyên trước, giúp em-main khỏi phí một lượt spawn để nhận về lời từ-chối.

Token-list (verbatim, implementer-backend/2026-05-q4)

  • Pattern#: 16-bis 4-place mirror ("4th time", liệt-kê 3 ca: S29 Plan CA HF1 + S29 Plan B Chunk D + S33 Task 5) · 12-bis cross-module ("4th time", liệt-kê 3 ca: Chunk C Mig 33 + G-H1 Task 4 BE + Task 5 FE; riêng S35 ghi "3rd application catalog-mega") · "17 numbered patterns" (1-12 + 12-bis + 13-15 + 16-bis + 17-19) · ghi chú Pattern 16 baseline **implied** ... **chưa numbered explicit**
  • surprise: "Ambiguities encountered: 0 — spec deterministic 100%" · "HRM no HasQueryFilter.Where(!IsDeleted) manual" · "Validator MaxLength = EF source-of-truth (Code=50 not spec 20)" · "8 file +4265 LOC (Designer autogen 95%, handcraft ~232 LOC)" · "MEMORY size 36.2KB ... OVER 25KB threshold ~45% bigger" · "KHÔNG self-curate vì ... reserve cho em main solo judgment call §6.5" · "KHÔNG commit (em main commits)" · "REFUSE forward: ... KHÔNG schema design" · "FullCalendar lib new dep" · "3 NEW file SHA256 verified IDENTICAL" · số "4th time" nhưng chỉ liệt-kê 3 ca (×2 chỗ)
  • guard: SHA256 xác-nhận sau khi ghi (3 file) · .Where(!IsDeleted) thủ-công (không có query filter toàn-cục) · MaxLength lấy EF làm nguồn chân-lý · ngưỡng MEMORY 25KB + đo bằng Get-Item Length · ngưỡng rerank > 0.7 · ranh-giới phát-hiện ⟂ tự-dọn (§6.5 KEEP vs CUT thuộc em-main) · danh-sách out-of-scope khai minh-bạch
  • root-cause: đợt dồn kho S65 FIFO trim chèn 2 digest vào giữa entry S33 Task 5 ⇒ thân và đuôi bị tách rời (xem cảnh-báo cấu-trúc) · HRM thiếu HasQueryFilter ⇒ mọi truy-vấn phải tự lọc soft-delete · spec ghi MaxLength lệch EF ⇒ validator sai nếu tin spec
  • file:line / định-danh: types/employee.ts (NEW ~283 LOC, SHA256 CCFC70666568) · pages/hrm/EmployeesListPage.tsx (~417 LOC, DC859C897C5C) · pages/hrm/EmployeeCreatePage.tsx (~178 LOC, C796F25D01AC) · menuKeys.ts (+3 LOC Hrm+HrmHoSo) · Layout.tsx (+4 LOC staticMap Hrm_HoSo) · App.tsx (+5 LOC) · 6 file fe-user mirror · HrmConfigFeatures.cs 372 LOC + Controller 134 LOC (16 endpoint) · Mig 33 ContractLevelOpinions · Mig 34 (em-main giữ) · migration-todos (11 module / 10 sprint) · PurchaseEvaluationWorkflowServiceReturnModeTests.csContractWorkflowServiceApproveV2Tests.cs (7 kịch-bản, spec D-Bis) · mcp__rag-unified__search_memory + mcp__rag-unified__cross_project_search · "Pattern curate trigger rule line 364" · agent id ab23cc322b5d495c0
  • số-đo: 14 file (S33 Task 5) · build fe-admin 21.4s / 1429KB · fe-user 9.2s / 1345KB · dotnet build 1.59s 0 warn 0 err · dotnet test 120/120 (58 + 62) · test mốc S35 130 · MEMORY 36.2KB (Length=36207) → curate 27.5KB · rerank 0.824 / 0.801 / 0.793 (ngưỡng 0.7) · token ~25k (Task 5) / ~5K (wrap) / ~5k (startup) · tag [mirror-page, phase-10.1, frontend] · [s35, be-crud, hrm, 12-bis-3x] · [s29, plan-b, 12-bis] · [wrap, phase-9-to-phase-10, frontend+backend] · [verify, phase-9, infra]

== HẾT ==