Files
solution-erp/.claude/agent-memory/reviewer/MEMORY.md
2026-07-31 15:52:08 +07:00

109 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Reviewer Agent — Persistent Memory
- **S164 (07-31) gate K1 danh mục SP-002 (`ContractCatalogEntries`, Mig 70) — PASS-WITH-FLAGS 9 finding/0 blocker kỹ-thuật:** build 0W/0E + **597 test** (45D+552I) tươi. Lane khai ĐÚNG 100% ở chỗ đo được: seed **86/86** parse-máy khớp transcribe từng dòng (chỉ 8 mismatch = đúng tập lane đã khai), phân bố 5/10/5/23/14/15/13/1, SHA-pair FE `d71a9e3b…` ×2 khớp claim. **Bài thu:** ① 🔴 giá-trị lớn nhất KHÔNG nằm ở mã mà ở **GATE QUY-TRÌNH**: spec đặt PRE-gate owner (`OG-6`) + kế hoạch **tách 2 commit** (code trước, seed sau khi gật) — code đúng hết mà commit gộp là **vượt quyền owner**; seeder per-Code idempotent KHÔNG có nhánh update ⇒ gật muộn = phải UPDATE tay. ② **2 quyết-định hợp-lệ ghép lại đẻ ghost-wire**: lead bắt key vào `MenuKeys.All` (để có menu row) + spec bắt controller mirror khuôn `Roles="Admin"` ⇒ 4 policy `ContractCatalog.*` sinh ra mà **0 endpoint tiêu thụ**; ma trận CRUD chỉ điều-khiển HIỂN-THỊ, tick CanCreate vẫn 403 / bỏ tick CanRead vẫn GET được (lớp #82) — **phải đo `grep policy` chứ đừng suy từ "key đã vào All"**. ③ **default-lấn-ngữ-nghĩa**: spec `IncludeInactive?` (mặc-định-LOẠI) → code `IsActive?` (mặc-định-GỒM) ⇒ cột "ẩn khỏi picker" chỉ ẩn nếu MỌI consumer nhớ truyền tham số. ④ drift DELTA đo được (All=56, policy=224) mà `STATUS.md:6` chưa đổi ⇒ acceptance "khai cùng commit" chưa đóng. Tag `[s164, gate-quy-trinh-owner, ghost-policy-2-quyet-dinh-hop-le, default-lan-ngu-nghia, seed-doc-may]` **Evidence:** `.claude/workflows/runs/2026-07-31-S164-4gd-khkk-fanout/sub-reviewer-gate-k1.md`. ⚠️ Sổ này **18.8KB > 17.1KB** — nợ curate lượt sau.
- **S162 (07-30) cây 4-folder GĐ (FE-only 2 app) — PASS-WITH-FLAGS 8 flag/0 blocker:** 🔴 class **`im-lặng-về-độ-chính-xác-của-con-số`** — 3 ca cùng lớp 1 diff, tsc+build ×2 xanh: hook VỨT `total` khi `pageSize:200` ⇒ không biết mình bị cắt, badge tụt không dấu vết · `pe.ContractId = contracts[0].Id` ⇒ phiếu liên-danh N HĐ chỉ nối 1 mà badge in như thật (**tái phát cardinality S87/S88 — field làm KHOÁ-NỐI phải đi đọc WRITE-SITE của nó**) · fallback `?? '(chưa cấp mã)'` trộn 2 nguyên nhân ⇒ **khẳng định SAI**, không phải degrade. · **#82 ngược chiều:** FE gate OR nhiều menu-key nhưng `MenuPermissionHandler.cs:40` khớp CHÍNH XÁC 1 key ⇒ OR làm gate LỎNG HƠN policy, tự chuốc 403; **gate query = ĐÚNG key policy của endpoint**. 2 endpoint cùng diff kết luận NGƯỢC nhau (`/contracts` `[Authorize]` trần ⇒ KHÔNG 403) ⇒ đo TỪNG cái. · **Nhãn ✓ không có phép đo:** rubric 'responsive ✓' mà harness grep 'grid-cols-[19rem'=0 hit ⇒ 2 trang lưới chưa từng render; **đọc `^import` của harness = cách rẻ nhất biết ảnh CHỨNG được gì**. Tag `[s162, im-lang-do-chinh-xac, total-bi-vut, contracts0-cardinality, or-key-long-hon-policy, nhan-tick-khong-phep-do]` **Evidence:** `.claude/workflows/runs/2026-07-30-S162-cay-4-folder-gd/sub-reviewer-1.md` · lead áp 5/8 flag (F-1/3/4/6/7) + F-8 sửa memory designer TRƯỚC ship `bfc7b79`; F-2 (liên-danh N-HĐ) + F-5 (layout 19rem chưa render thật) = giới-hạn khai thẳng lên HANDOFF slot (56).
- **[→ archive/2026-07.md @S162-curate] S161-W2 (07-29) KHKK CRUD — 2 lane viết SONG SONG:** hợp-đồng FE↔BE VỠ 6 điểm mà tsc+build+574-test đều XANH (route lệch tên · field lệch · 2 lỗi CHE NHAU); lời-khai-lane = GIẢ ĐỊNH ⇒ so ROUTE+FIELD trên ĐĨA; list-bịt-detail-mở ⇒ rào chỉ còn UX; INNER-join global-filter = picker vanish.
- **[→ archive/2026-07.md @S161-curate] S159 đợt-5 (07-29) menu 6-leaf HĐ:** chú-thích-mang-SỐ phải chạy phép đếm · cookie-cutter phải soi CẢ phần bản gốc đã CHẶN · `tsc`+`noUnusedLocals` mạnh hơn grep cho claim 'đã cắt'.
- **[→ archive/2026-07.md @S162-curate] S161 W1 (07-29) KHKK tiền-commit (Mig 69):** HIGH nằm ở `git` chứ không ở mã — 2/3 file mig UNTRACKED mà snapshot tracked ⇒ gate `git status --porcelain -- src tests | grep '^??'` phải RỖNG ngay trước commit; comment 'bên kia lo' = ĐI ĐỌC BÊN KIA (nhãn BE thiếu ⇒ ghi chuỗi Anh vào cột DB); grep bằng TOKEN-SONG-SINH; diff sửa mã phải sửa MỌI số/neo trong chú thích.
- **[→ archive/2026-07.md @S159-curate] S155-đợt2 (07-27) PE delete-approver DIFF #2:** class `hợp-đồng-đứt-giữa-2-bờ` (FE type khai cờ, BE DTO không có ⇒ nút chết mà build+561-test xanh) · policy-gate đo DB 11/13 vai · re-đo đĩa TRƯỚC verdict · đổi-chiều-assert ≠ nới-assert.
- **[→ archive/2026-07.md @S155-curate] S155 ×2 · S155-đợt2 · S146 · S147 · S152-D2 (digest):** `hợp-đồng-đứt-2-bờ` (FE khai cờ, BE DTO không có ⇒ nút chết mà build+test xanh) · HIGH-ở-git (mig untracked) · `ExecuteDelete` ngoài transaction = mất dữ liệu · test đang KHOÁ chiều ngược, CẤM nới assert · xanh-giả bắt bằng phép 2-thế-giới · mã ĐỔI giữa lượt soi ⇒ re-đo đĩa TRƯỚC verdict · decouple 1 gate ⇒ truy prop dùng chung · 3 THƯỚC-HỎNG (md5 CRLF · `grep -c` citation-trap · `grep -iF` MSYS 0-hit im lặng).
- **[→ archive/2026-07.md @S145-curate · @S145b-curate · @S140] S145 4-lane · S145a · S143 · S139·S134b·S133 (digest):** bất-biến chia-đôi giữa 2 axis chỉ cross-cut sweep bắt · 'vai-có-sổ' phải `ls` thật · sweep CẢ numeric LẪN name-enum · `bằng-chứng-tự-huỷ-sau-squash` · re-measure acceptance từ git HEAD + no-self-exempt · insertion-only `grep '^-'`=0 · 'mọi nhánh set X' phải grep assignment-qua-BIẾN (#81).
> **Persistent diary cross-session.** Auto-injected first ~200 lines at spawn (L1 HOT).
> Update BEFORE every stop. Tiered Memory v1: L1 HOT cap ~17KB (hook 24.4KB read-limit) · L2 `archive/` on-demand · L3 RAG `search_memory` just-in-time. Keep entry ≤ 1.5K chars (gotcha #53).
> Full verbatim history pre-S40 → git `d2f52ba` + `archive/2026-05-q1..q2.md`; S51→S76 detail → `archive/2026-06.md` (S69/S70/S71/**S80** curate). Archive map: `archive/_INDEX.md` + per-period `.gist.md`.
- **[→ archive/2026-07.md @S161-curate] S160 (07-29) CHỐT-CUỐI 13-fix:** fix áp NỬA spec = dư-lượng (soi CẢ FILE khi nhận 'đã fix') · anchor-list là artifact RIÊNG phải sync · verify NGƯỢC premise · owner để-mở ⇒ finding MOOT-đúng.
## 📁 Area memory (L2 on-demand — Read khi review vùng tương ứng)
- [S62 PE budget soft-warning](project_s62_pe_budget_soft_warning.md) — PASS: hard-block→soft-warning; submit-guard intact + validator giữ `BudgetPeriodAmount>0`, row8 negative-safe (additive-only). Validator class `PurchaseEvaluationFeatures.cs:317`.
- [Wire/mirror claim verification anchors](feedback_wire_claim_verification_anchors.md) — sha256 twin-file · `git diff -U0` isolate true-adds · `allowNegative` bleed check · guard-still-intact grep.
- **[→ archive/2026-07.md @S161-curate] S160 (07-29) review SPEC-BỘ dry-run KHKK:** review SPEC ≠ review CODE (lỗ ở acceptance + default-lấn-quyền) · seeder-grant kiểu insert = NO-OP 403 im lặng ⇒ acceptance phải đo CỜ không đếm ROW · acceptance 'PASS SẴN' = 0-bit · choke-point 'DUY NHẤT' sai vì gán QUA BIẾN (#81).
- **S89 trio** ([sectionB](project_s89_pe_sectionb_review.md) · [endsBeforeCeo](project_s89_pe_endsbeforeceo_plan_review.md) · [finalize-note](project_s89_finalize_note_plan_review.md)) — adjustMut share race + authz-lens ≠ concurrency-lens · FE 4 render-sites plan-missed-2 · ground-truth-accurate-nhưng-gaps.
- **S101 H18/H19 WF2 + LANE-C — PWC/PASS:** content-hash ≠ commit-SHA (hex strip/no-strip) · exact-token sweep misses paraphrase → widen concept-phrase. → `archive/2026-07.md`.
- [S103 H20+crystallized-backfill review](project_s103_h20_crystallized_backfill_review.md) — WF2 PASS; 6/6 hash recompute MATCH + 4 already-met verified. Lesson: multi-axis warning phải nằm trong OUTPUT của script (reader chạy inline), không chỉ doc.
- [S111 PE sign-off 6-decision design review (schema/history lens)](project_pe_signoff_history_schema_review.md) — GO-WITH-ADJ; D5 opinion-history: append-only table, REJECT version-col (drops UNIQUE + breaks UPSERT).
- **PE per-hạng-mục series ×5** ([cardinality#3](project_pe_multiwinner_perhangmuc_review.md) · [BE-financial](project_s114_pe_multi_ncc_perhangmuc_financial_review.md) · [spec-l3](project_pe_multi_ncc_perhangmuc_specreview.md) · [IMPL](project_s114_multi_ncc_perhangmuc_impl_review.md) · [neg-quote](project_pe_negative_quote_correctness_review.md)) — derived src-of-truth: re-derive MỌI write-path KỂ CẢ Delete · grep field-NGUỒN không chỉ field-đọc · sign-loss: defer-parse tới field-chung mọi mutation.
- [S113 Supplier import v2 close-review (owner anh Kiệt)](project_s113_supplier_import_v2_review.md) — GO-WITH-ADJ 2 must-fix (consumers không pass published=true → drafts leak). Lesson: "filter added" ≠ "drafts hidden" — grep-all-consumer + create write-path.
- [S118 Procurement master-access seeder review](project_s118_procurement_master_access_review.md) — PASS(cond); MAJOR Reports.Read leaks financials + Suppliers.Update grant ≠ edit. Lesson: menu-flag grant ≠ API capability; bare `[Authorize]` GET = open-to-all.
- [S123 governance 4-change review (backtick-guard + H24-3 + retire dạng-3 + mark)](project_s123_governance_4change_review.md) — PASS_WITH_FIXES; CAUGHT H24-3 thiếu enclosure-guard mà cùng diff vừa chứng cần (gen-2 citation-trap) + greedy `.*` lấy `(S<N>` CUỐI≠MAX + lý-do-retire áp cho dạng-2 thì giết C8. Q5 "HOÀN-THÀNH mark" = nguỵ-biện. Q8 ENDORSE không-bump.
- [S147 Project whitespace-dupe merge verify](project_project_dupe_merge_verify.md) — 7/7 PASS(2 FK-terminology corrections); "FK Projects" COMMENT ≠ physical FK (sys.foreign_keys=0 to Projects, all loose-Guid); seed-durability FORCES survivor=no-space blanket; INNER-join+filter=silent-vanish→repoint-before-soft-delete; prod ref-dist unverifiable (Server=localhost+secret).
---
## 🎯 Role baseline
Adversarial pre-commit reviewer SOLUTION_ERP. Read-only verify + live curl prod UAT (`*.solutions.com.vn`). Tools: Read, Grep, Glob, Bash (curl + git diff + sqlcmd read) + 5 RAG MCP. Skills: `dependency-audit-erp` + `contract-workflow` + `permission-matrix`. Output: PASS/FAIL + concrete issues file:line. NEVER write code.
---
## 🚨 Recurring bug patterns (catch priority)
- **#44 Silent 403 class-level Authorize quá strict** — Drafter dropdown empty silent (TanStack catch silent → UI empty). Grep `\[Authorize\(Policy=.*\)\]` class-level + curl non-admin expect 200. Fix: class-level `[Authorize]` only (any authenticated); POST/PUT/DELETE giữ `[Authorize(Policy="X.Create")]`.
- **#43 Step.Order ≠ index 0-based** — `Where(s=>s.Order==i)` wrong row. Fix: EF query → in-memory `OrderBy(Order).ToList()` → index.
- **#42 Dual schema V1/V2 — Service phải branch** — `if (entity.ApprovalWorkflowId is Guid awId) ApproveV2Async else V1Legacy`.
- **Wire BE claim** — grep diff `// Mock`/`alert(`/no POST-PUT-DELETE call + live curl expect 2XX. Severity CRITICAL block.
- **#70 FE absolute-set stale-echo race** — N fields cùng-cột share 1 mutation + echo sibling từ server-snapshot (`bs`) + `invalidate()` fire-and-forget (không await) → lưu 2 ô liên-tiếp đè mất. Window mở SAU `isPending=false` (btn re-enable), KHÔNG lúc in-flight. Catch: đếm field-cùng-cột share mutation + check invalidate awaited; fix = `useIsFetching` gate nút Lưu tới khi refetch land.
- **#71 enum proxy-predicate pollution** — thêm enum value vào entity dùng-chung → UI/guard phân-loại theo PROXY-predicate (`supplierId===null`) thay vì enum tường minh → value mới lẫn nhầm phân-loại + false-pass guard. Catch: grep mọi field-proxy predicate, loại value mới tường minh; build-verify TỪNG app.
- **Cross-module security mirror (S29 Smart Friend)** — khi mirror entity/Command cross-module (PE→Contract→Budget V2), focus data-shape MISS security guard. Pattern: `aw.ApplicableType == ExpectedType` validate ON Create BEFORE instantiation (mirror `PurchaseEvaluationFeatures.cs:62-77`). Attack: Drafter forge POST với `approvalWorkflowId` của module khác → FK Restrict chỉ check Id-existence NOT ApplicableType → wrong-scope pin. Re-verify `IsActive`+`IsUserSelectable` server-side. Password ≥12 chars. Severity MAJOR.
- **#17 EF migration 3-file** — `git diff --name-only | grep Migrations/` expect 3 (target + Designer + Snapshot).
---
## 📋 6-category checklist (EVERY review)
- **Cat 1 Wire BE/feature claim:** grep mock markers diff + `await api\.(post|put|delete|patch)\(` + live curl POST/PUT/DELETE if deploy claim + status matrix.
- **Cat 2 Schema integrity:** 3-file rule Mig + column types vs entity def. Reference `docs/gotchas.md` (71 active).
- **Cat 3 Security:** `[Authorize]` class-level ALL new controllers + per-action policy admin-scoped (gotcha #44) + FE PermissionGuard + menuKeys.ts mirror BE MenuKeys.cs + FluentValidation + EF parameterized.
- **Cat 4 Code quality:** `dotnet build SolutionErp.slnx` 0 err + `npm run build` × 2 app (TS6 strict) + tests baseline **354 PASS** (Phase 9 UAT exception OK) + no `--no-verify` + anti-fiddle (scope drift >20% LOC = FAIL) + mirror 2 FE app §3.9.
- **Cat 5 Test coverage:** new helper → xUnit · new endpoint → integration · bug → regression test-before-fix. Phase 9 UAT test-after default OK (`feedback_uat_skip_verify`). Baseline 354.
- **Cat 6 Writing-quality (Harness-7, S64):** outward text (verdict gửi anh / report) = tiếng Việt câu hoàn-chỉnh đủ dấu đúng ngữ-pháp; describe issue + acceptance criteria, NOT code edits. Escalate disagreement explicit.
---
## ⚠️ Anti-patterns + 🛡️ Smart Friend guard
1. ❌ Recommend code edits (only describe issue+criteria) · 2. ❌ Skip live curl if deploy claim · 3. ❌ Accept "wire" without grep proof · 4. ❌ Defer to em main authority (escalate explicit) · 5. ❌ Skip MEMORY · 6. ❌ **Lower bar match em main** (Smart Friend Cognition anti-pattern).
**Smart Friend (Cognition):** NEVER lower bar. Em main code fine → PASS. Em main issues → FAIL with specifics regardless social pressure. "Quality ceiling set by primary, not escalation." Value = raise quality through catch.
---
## 🧠 SOLUTION_ERP review essentials (S80 verified — re-ground từ docs/STATUS.md canonical)
- **Tests · gotchas · migration · endpoint · bảng = SỐ CANONICAL ở `docs/STATUS.md`** (B1 derived-trỏ-canonical — KHÔNG chép số vào sổ này, chép là stale sau 1 phiên; mốc @S161 để nhận diện độ trôi: test 566 · gotcha 83 · Mig 69 · 96 bảng). Test phải TĂNG khi thêm feature (§7); Phase 9 UAT exception (`feedback_uat_skip_verify`).
- **Identity password ≥12 chars** (reject 11-char). Test creds: admin `admin@solutions.com.vn/Admin@123456` (full) · UAT `nv.test@solutions.com.vn/TestUser@123456` (Drafter CCM).
- **Prod:** api/admin/eoffice.solutions.com.vn. Bundle live admin `CsJetgZH` / user `BVS0ApIm` (Run #330). **Pin:** MediatR `12.4.1` (flag `Version="14`) · Swashbuckle `6.9.0` · Node CI `20.x`.
- **Conventions:** `docs/rules.md` (§1.1 outward writing, §3.9 mirror 2 FE, §5.2 commit, §6.5 docs narrative, §7 test timing, §2.8 pin).
---
## 📅 Recent activity (compressed — full verbatim → `archive/2026-06.md` + `archive/2026-07.md` via `archive/_INDEX.md`)
- **[→ archive/2026-07.md @S126/@S134] S123·S124·S125·S129·S131·S131b (digest):** follow-up phải GIỮ con-số source · số-atomic-đúng vẫn fencepost ⇒ re-derive từ raw · writer-only = NỬA-VÁ · do-token trap ⇒ re-Read full + sibling-test 2-CHIỀU · 🔴 ghi diary TRƯỚC return + vá-1-lớp phải grep MỌI matcher cùng-lớp ([topic](project_s123_governance_4change_review.md)).
- **Digest S93→S117 (verbatim → `archive/2026-07.md`):** code-gate re-derived denom · default-flip byte-mirror SHA ×2 · Windows byte-verify = .NET · HELD stale run-id · persist-claim cần reader-side + tracked + 0-drift · outward-claim 'đã sửa X' phải cat X trước gate · gist meta-count ≠ đĩa · claim-về-code grep lại kể cả reword · nâng-nấc-quên-sync cùng-diff · verify EACH regex-alt by-hand · 2-tier guard compare SUM-EXPRESSION.
- **S92 PROD-security hide 5 menu-groups admin-only — PASS (1 note):** → [project_s92_admin_only_modules_revoke.md](project_s92_admin_only_modules_revoke.md).
- **June-2026 digest — LESSON-ONLY:** merge-distill fabricates false-specificity ⇒ QUALITY gate AFTER presence · sha = self-declared NOT recompute · fail-closed guard BEFORE terminal-state · TRACKED = check-ignore ≠ ls-files · menu-hide ≠ API-lock · single→multi stops at display-layer.
- **[→ archive/2026-07.md @S128/@S134] S112·S126·S127·S128 (digest):** derive guard từ ENDPOINT authz, self-flip ≠ external-accept · AGGREGATE cumulative KHÔNG vào outward artifact · direction-of-error quyết mức lỗi outward + brute-force sha-variant TRƯỚC phán tamper · hedge broadcast bằng MỞ config THẬT.
---
## 🔄 Curate trigger
- Hook-cap **>17.1KB** (24.4KB read-limit — đổi từ ~30KB cũ, S109) → archive recent → L2 `archive/<period>.md` (append additive) + `_INDEX.md` substring pointer. Stale >3mo → remove.
- **S162-curate (self, 2026-07-30, 23.9KB→<17.1KB):** move VERBATIM 2 entry S161-W2 + S161-W1 `archive/2026-07.md` @S162-curate (probe moved-not-cut 2/2 TRƯỚC khi xoá khỏi L1, bài S102) + nén 10 dòng digest đã-archive-sẵn. KHÔNG cut-without-move.
- **Prev curates (digest):** S145 (4 verbatim @S145-curate, residual 17.7KB defer) · S140 · S134 (8 verbatim, seal 6/6+2) · S128 · **S102 recovery: cut-not-moved ×5 @`f229b07` ⇒ L1-shrink kèm '→archive' BẮT BUỘC grep moved-not-cut trước khi trust** · S116·S113·S109·S80·S71·S70·S40.
## S152 (2026-07-25) — R1 retention-note ranh NEVER [M9 on-behalf lead]
- **NEVER Edit/Write vào code-tree, NEVER commit, NEVER push** vai = verdict-only (PASS/FAIL + issue file:line), sửa việc em-main/implementer. KHAI THẬT 2 nấc: (a) ranh commit/push/code-tree **chưa từng vỡ**; (b) Write/Edit runtime cấp ĐÃ dùng hợp lệ cho sub-file run-folder + diary-self-write (AS-10 VERIFY-KEEP, nhân-chứng S143) tức "NEVER" áp cho ĐÍCH (code/commit/push), không phải cho tool-tồn-tại; containment thật = git-diff lead. Tag `[s152, r1-retention, never-edit-write-commit-push-target-scoped]`
## S159 (2026-07-29) — review diff tổng-quan pipeline (đợt-1, run tong-quan-pipeline-menu) [LEAD SEED ON-BEHALF @S164 — H2 P2 @S163; run bị owner chốt "bỏ mạch" @S163 nhưng lane review ĐÃ chạy thật, distill giữ bài]
- {nấc: verified (lead đọc lại sub-file 16.761B) · evidence: `runs/2026-07-29-S159-tong-quan-pipeline-menu/sub-reviewer-diff-tongquan.md`}
- **7 FLAG (2M+5L), 4 bài giữ:** [M] a11y AA 2-3 `<button>` TRÙNG tên đọc được "Chờ tôi duyệt" dẫn 3 đích khác (`UserDashboardPage.tsx:449/:495/:538`); ngữ-cảnh phân-biệt chỉ tồn tại THỊ GIÁC (`<h3>` không link chương-trình với nhóm nút) spec AA = nợ thật không phải thẩm-mỹ. [M] lọt tiếng Anh: rút TOÀN BỘ chuỗi hiển-thị MỚI từ diff (`git diff | grep '^+' | grep -oE '>..<|label=|title='`) rồi soi từng chuỗi ra đúng 2 ("Pipeline"…) = phương-pháp đo 100%-tiếng-Việt tái-dùng được. [L] 2 khoá cache cho CÙNG resource (`['pipeline-pe-inbox']` mới vs `['pe-inbox']` sẵn cùng endpoint cùng params) 2 bản cache độc-lập, 2 màn 2 ảnh-chụp khác thời-điểm check "khoá mới không đè khoá " PASS vẫn nợ nhất-quán: 2 câu hỏi KHÁC nhau. [L] báo lỗi 2 lần cùng sự-cố.
- Kỹ-thuật BÁC-claim giữ: *"queryKey mới đè cache list"* BÁC bằng liệt-kê key thật 2 phía (không giao) bác cũng phải chứng.