Files
solution-erp/.claude/agent-memory/implementer-backend/MEMORY.md
2026-08-08 12:30:07 +07:00

107 lines
24 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.

# Implementer-Backend Agent — Persistent Memory
- **S180 (2026-08-07) lane W3 — nghi thức 2 đầu: 4 nhãn + vòng hỏi ngược + tiền-kiểm 9/19 + gói-B persona `[#53 vai thứ 20; cứu TRỌN nhờ ghi-đĩa-từng-phần — lead resume, xong nốt]`:** Nghề ăn tiền = **KHAI ĐÚNG NẤC CƯỠNG CHẾ**: ký 4/4 nhãn thành văn nhưng đo lại thì **1 có máy đủ · 2 nửa · 1 (`bị chặn`) CHƯA CÓ MÁY** — vị từ `(3)` cho **cùng một số** với *trỏ đặc tả**trỏ nỗ lực gỡ*, không phân biệt được ⇒ khai thẳng thay vì để nó trông như đã cưỡng chế (LỚP-9). 🔴 **Bác đề bài 1 chỗ, đứng:** khung *"chỉ bỏ-qua-KHÔNG-khai mới là lỗi"* ⊥ chữ hub (`phu-luc:189` tính cả ca **CÓ KHAI mà điều kiện đánh-giá-lại ra SAI***tự ý bỏ*) ⇒ nhận khung đó thì **một dòng khai là tự tha được**; ký theo hub + luật *`không-xác-định` rơi về nhãn NẶNG* (mặc-định-vô-tội = thưởng cho đặc tả mơ hồ). 🔴 **Bác lane F:** `check-email` bị đếm là 1 trong "6 cửa gọi `nhip-no-probe`" — đĩa nói **2 hit đều là NHẮC TÊN, 0 lời gọi** ⇒ tập đúng = 5. Sửa lane C 4/19→**5/19** (`snapshot:69` đóng từ 🟡 sang CÓ). 🔴 **Fault-inject lượt ĐẦU chết vì HARNESS:** viết inline qua bash ⇒ bash nuốt `$`/backtick của chuỗi PS ⇒ WAL "lành" không bao giờ ghi đúng ⇒ chiều B kêu **trông y hệt script hỏng**; dựng harness thành `.ps1` riêng ⇒ 5/5. **Tự bắt citation-trap vòng 1** (ghi chú vá trích nguyên cụm số cũ ⇒ grep vẫn =1), vòng 2 diễn-giải ⇒ 0, re-grep bằng lệnh KHÁC. Wall-clock ĐO TRƯỚC khi cắm (luật `check-email.md:41`): ròng **194ms < 281ms** đã-chấp-nhận ⇒ **vẫn KHÔNG cắm vào `/pause`·`/tiep`** (đã có probe). Tag `[s180, w3-nghi-thuc, khai-dung-nac-cuong-che, khai-khong-tu-mien-tru, use-vs-mention-lane-f, harness-hong-trong-nhu-script-hong, do-truoc-roi-noi-khong]`
- **S180 (2026-08-07) lane W2 — dựng máy điểm danh vật chứng (4 vị từ · fault-inject 3 chiều · ca-N1 BẮT) `[#53 vai thứ 19; cứu TRỌN nhờ ghi-đĩa-từng-phần — lead resume, xong nốt]`:** Nghề ăn tiền = **ĐO PHÂN BỐ TRƯỚC KHI CHỌN NGƯỠNG**: K của vị-từ-tỉ-lệ lấy = **phân vị 5 đo thật trên 446 tệp họ `sub-*`** (K=3,00), KHÔNG chỉnh cho vừa ca đã biết — ca N1 rơi ở phân vị 3,6, **lọt lưới sát nút** ⇒ khai thẳng *"vị từ này là lưới PHỤ"* thay vì hạ K xuống 2,7 (= Goodhart). Vị từ CHÍNH = **nhãn treo NEO VÀO HEADING** (tách *dùng**nhắc đến*): thô cho **1 dương-giả trên chính bản đã xong** (câu định nghĩa nhãn) — neo heading ⇒ 6/0. 🔴 **Bẫy thước tự bắt:** `grep '[^\x00-\x7F]'` Git-Bash cho **268 hit trên tệp biết-là-sạch****control âm sai = hỏng THƯỚC**, phải đọc byte bằng .NET. 🔴 **Bác lệnh lead 1 chỗ, đúng:** spec bảo `git show HEAD~1:<file>` — hook `wal:` chèn commit giữa ⇒ HEAD~1 **không phải bản trước CỦA TỆP**, phép so thành *so bản mới với chính nó***trông y hệt phép đo hợp lệ**; dùng `git log -2 -- <file>`. **Quét toàn kho lộ 2 lớp dương-giả (294→31 cờ):** con-trỏ CHÉO giữa lượt chạy (README bắt trỏ `input spec:` sang lượt trước) = lỗi MÁY không phải nợ kho ⇒ phân giải toàn cây; `KHONG-KHAI` 245/720 = cờ cho **luật chưa từng tồn tại****hạ xuống hạng-mục-đếm-riêng NHƯNG GIỮ SỐ + mẫu số** (phép thử *"cái mất đi là dương-giả hay CHỨNG-NHÂN?"*). Vá đến SAU test ⇒ **chạy lại trọn 3 chiều**. Tag `[s180, w2-artifact-integrity, do-phan-bo-truoc-chon-nguong, neo-heading-use-vs-mention, control-am-sai-la-hong-thuoc, headn-khong-phai-ban-truoc, giu-so-bo-co]`
- **S180 (2026-08-07) lane W1-b — ký chuẩn đặt tên + dựng máy soi (11/11 ràng buộc · 3/3 vá · fault-inject 4 lượt/3 chiều) `[#53 vai thứ 18/phiên; cứu TRỌN nhờ ghi-đĩa-từng-phần — artifact 21KB đủ ruột TRƯỚC khi return chết; lead resume, xong nốt]`:** Nghề mới ăn tiền = **LUẬT NẤC: "một nhóm tên sạch CHÍNH XÁC tới độ sâu máy của nó KIỂM, không sâu hơn một nấc"** ⇒ mỗi mục chuẩn PHẢI khai nấc + trỏ máy ép đúng nấc đó; nhóm không máy ⇒ ghi `CHƯA CÓ MÁY`, **CẤM ký luật hình dạng** (ký sâu hơn máy = ký ra thứ tự nó trôi). Hệ quả 2: máy chỉ-ĐỌC (`detectors:1109` liệt-không-cờ) hoặc THA (`:1660` `-or` chấp 2 tên) ⇒ tên vẫn trôi — **nhưng KHÔNG cần STOP-HARD**: `:1639` chỉ in INFORM mà nhóm sạch 12/12. 🔴 **Tự bắt mình tái phạm citation-trap:**`hmw.js:33` bỏ số "11 class", bản vá ĐẦU **trích nguyên văn** cụm cũ ⇒ grep vẫn =1 ⇒ bài học **lời-giải-thích nằm TRONG tập đo**; vòng 2 mới =0 (control-dương 2 chuỗi cùng tệp). **Bác 3 chỗ, 3/3 đứng:** (a) lane a "23 lệch" → tôi đo **8/233** (16 script `s<n>-`/`plan-`*một-lần HỢP LỆ*, gọi lệch = **dương-giả**, mà dương-giả ngày đầu là cách nhanh nhất để người ta tắt máy soi; +1 vật lane a sót `resume-S146`); (b) lead tả bản vá S159 = `(sub|harness)-*` → đĩa thật `^(sub-.+|.+-return)\.md$` (bộ ba lọt qua nhánh `-return`, KHÔNG qua tiền tố) — mirror theo *diễn giải* sẽ đẻ **bản sao thứ 3 lệch nhau**; (c) `wave-plan:85` kê W3 sửa "5 class"→**6** = đúng LỚP-5 vừa gỡ, phải **BỎ SỐ** không đổi số. Bẫy đơn-vị cắn thật: `scripts/`+`docs/governance/` đếm theo **MỤC** (gồm thư mục) ≠ **TỆP** ⇒ lệch 4; và tự mình đẻ 2 vật giữa lượt ⇒ 231→233, phải KHAI. Phát hiện mới ngoài lane a: `settings.json:2` `autoMemoryDirectory` = **đường dẫn TUYỆT ĐỐI** neo cả tên thư mục lẫn gốc kho (lane a chỉ liệt `:9`). Tag `[s180, w1b-naming-standard, luat-nac, citation-trap-tu-bat, duong-gia-vs-chung-nhan, muc-vs-tep, inform-only-exit0]`
- **S171 (2026-08-04) lane BE — `7/7 mục, build PASS`, return SẠCH `[LEAD HARVEST HOI-TO @S172 — no mo tu closeout truoc; owner slot (71) chot 'gom va sleep thi auto, tu quyet'. Nguon = artifact tren dia, KHONG suy dien]; nguồn `runs/2026-08-04-S171-khkk-ui-mirror-pe/sub-implementer-backend-s171.md` 11.650 B`:** BE-1 DetailDto +5 field · **BE-1b `FinalizeStepName`/`FinalizeLevelName` DẪN XUẤT 3-ngả in-memory thay 3 subquery** (+ sửa công thức con-trỏ cho đúng KHKK) · BE-2 `ContractSigningPlanApprovalDto` đẻ mới + projection · **BE-3 tên người duyệt join `Users` — đường THỨ BA** (2 đường kia không dùng được, lý do §2) · BE-4 `WorkflowStepDto` +`DepartmentName` · BE-5 endpoint changelogs policy `KeHoachKyKet.Read` **+ rào `EnsureCanViewAsync`** · BE-6 map Cấp cho Approvals · **BE-7 enum `+ApprovalAttachment=3` + endpoint upload riêng (policy `Update`)**. Mirror `types/khkk.ts` ×2 app **SHA256 trùng khít**; `dotnet build` 0 warning/0 error + `tsc -b` ×2 exit 0. 🔴 **Tự khai 3 chỗ lệch-có-lý-do + treo B-3 vì DB dev 0 phiếu** — nấc trung thực đúng: *làm được thì khai làm được, không đo được thì khai treo*, KHÔNG nhét acceptance runtime vào ô đã-xong. ⚠️ Hệ quả @S172: chính `ApprovalAttachment` + policy `Update` đẻ ra câu hỏi owner slot (67) — **người SOẠN cũng qua được `KeHoachKyKet.Update`**. Tag `[s171, be-7-7-build-pass, dan-xuat-thay-subquery, duong-thu-ba-join-users, treo-b3-trung-thuc]`
- **S167 (08-01) lane K7 — cầu KHKK→HĐ BE + 5 vá `[artifact sub-implbe-k7.md; return-1 garble #53 → lead SendMessage-resume, xong solo]`:** Bài lớn nhất = **BÁC TIỀN ĐỀ ĐỀ BÀI bằng 4 phép đo trước khi gõ**: lead nói "bridge ĐÃ TỒN TẠI (W6-S161), mày chỉ vá quanh nó" — đĩa nói KHÔNG (`grep create-contract` 1 hit duy nhất = bridge PE cũ · 0 file · 0 endpoint · 0 write-site `Line.ContractId`). Cái tồn tại @W6**đường-ống HĐ V2**, không phải cầu ⇒ lead nhập nhằng "đường ống đã vá"≠"bridge có". **Phép thử rẻ phân biệt:** vá-6 ("nạp Project.Code/Supplier.Code theo khuôn bridge-cũ") là **no-op nếu áp lên bridge cũ** (nó ĐÃ có 2 dòng đó) ⇒ vá chỉ có nghĩa với vật CHƯA có ⇒ suy ngược ra vật thiếu. Xử: DỰNG bridge theo spec invest §K7.1 đã pin sẵn (0 quyết-định-mới của tôi) + nhúng 5 vá, KHAI RÕ chệch-khuôn + trỏ dòng spec — lead nhận. Khi **spec vá ⊥ nền invest** (`WorkflowDefinitionId` null vs pin) → **vá THẮNG** (spec `:4` viết luật đó). Cột đã có từ mig cũ ⇒ **0-mig**. `??=` giữ CHIỀU: cầu chạy sau không cướp ô của cầu trước. Thêm field vào projection dùng-chung-3-endpoint → **chạy test filter rẻ ngay** (collection-subquery SQLite dịch được: 34/35). 1 fail = reflection-authz test bắt mọi action phải cùng key module, mà vá-1 cố ý gate key MODULE KHÁC (`Contracts.Create`, #85) ⇒ **verified-fail bàn giao test-lane, KHÔNG tự sửa** (S112 khuôn). Tag `[s167, k7-bridge-khkk-hd, bac-tien-de-4-phep-do, va-noop-suy-nguoc-vat-thieu, spec-thang-nen, 0-mig, verified-fail-handoff]`
- **S166 (08-01) lane K4a — 49 row menu KHKK 8-nhóm, DONE B0-B5 `[LEAD SEED ON-BEHALF TẠI-CỬA — mày #53 sau B5 ("Now the site-4 revoker comment" trong khi comment ĐÃ land — return tụt sau đĩa 1 nhịp); B6 + END lead đóng; nguồn: sub-implbe-k4a.md + git diff]`:** Nghề mới ăn tiền: **BỘ-SINH thay 49 const tay**`KhkkGroupNumbers[7] × (KhkkGroup + 6 KhkkLeafActions)``KhkkGroupMenuKeys` làm NGUỒN CHUNG 3 phía (spread `.. ` vào `All` · vòng seed tree.Add · site-2 `.Concat`) ⇒ khớp **by-construction, 0 mirror tay 147 chuỗi** (đúng loại drift nổ FK Permission T6-K1); chệch-khuôn-so-brief KHAI RÕ + trỏ đề xuất gốc invest `:9` ⇒ lead chấp nhận không mất lượt. Anchor re-ground TRƯỚC khi sửa (số spec trượt vì DbInitializer phình sau K2/K3): dict labelBackfill `:2141-2183` · upsert THẬT `:2162-2179` (vá 2 comment stale "1893" bằng mỏ-neo GREP `existingItems.TryGetValue` thay số-dòng-trần — số dòng sẽ trượt tiếp, mỏ neo thì không). Vá-10 sửa LÝ-DO comment (group-key KHÔNG cần CanRead row — HasAccess đệ-quy theo con `:96`; invest doc viết sai lý-do, kết luận giữ-3-site vẫn đúng). labelBackfill `Khkk_G1` đổi-nhãn-không-nhân-row + fail-fast KeyNotFound khi thiếu nhãn (thà nổ lúc seed còn hơn FK nổ về sau). Suite **614/0 SAU diff** (idempotent/revoke/permission-seed giữ xanh). Tag `[s166, k4a-lane, bo-sinh-by-construction-3-phia, mo-neo-grep-thay-so-dong, fail-fast-luc-seed, return-tut-sau-dia-1-nhip, seed-on-behalf-tai-cua]`
- **S161 (07-29) ARC W1+W2+W3đ1 KHKK — 3 lượt/3 wave, chi tiết = sub-md run-folder `runs/2026-07-29-S161-khkk-{w1-schema,w2-crud,w3-duyet}/` (tổng ~47KB ghi-từng-mục; cả 3 lượt return #53 nhưng 0 mất):** **W1** Mig 69 7-bảng (UNIQUE filtered #57 · cascade-1-hop · apply 2 DB 0-drift · sys.tables 96) + seeder `SeedKeHoachKyKetAccessAsync` UPGRADE-if-exists+CanDelete + CodeGen `KHKK/{YYYY}/{Seq:D3}` WorkflowAppCodeSequences + 3 site AWV2Admin — ship `a8027c0` cicd 6/6. **W2** mega-file CRUD 15-endpoint policy-15/15 + 4 quyết D1-D4 khai-lead-duyệt; 5 bẫy né ghi sổ: codegen-TRƯỚC-Add (S88) · SUM so `w.Id` KHÔNG `w.SupplierId` · `Remove` trước `Add(changelog)` (T26) · subquery-Any-2-tầng vỡ-SQL-lúc-chạy · giao-1-grep-cùng-lớp-ra-3 (S122) — ship `6cbc6ad` cicd 6/6 (reviewer 12F: D1 "FE sẽ khớp" = giả-định-không-phải-phép-đo → 6 điểm đứt, lead vá). **W3đ1** skeleton test-before: switch-throw từng nhánh (đỏ-THẬT không đỏ-compile) + **rào-FK-547-bằng-VẮNG-MẶT-dep** (không inject IChangelogService) + **§6 tự đối-chứng chéo hợp-đồng FE 5/5 TRƯỚC bàn giao** (bài W2 → nghi thức) + §7 bàn-giao ctor-CUỐI. Tag `[s161, khkk-w1-w2-w3d1, mig69, upgrade-if-exists, rao-vang-mat-dep, doi-chung-cheo, gia-dinh-vs-phep-do]`
- **S139 (07-17) Governance wave adap-3-bản 2-lane [wf_f9981ae5-903 · L1 CLEAN · L2 #53-garble → sub-1.md ON-BEHALF em-main verify-2-nguồn] `[engine: opus-worker]`:** L1 = MASTER-CHECKLIST 2-tầng in 4 cửa (ss Phase-3 · se Phase-4 "TỔNG-HỢP CHỐT" · pause ý-6 · tiep §3-bis bold-block KHÔNG heading) + C1 2-câu đóng-băng bề-mặt-đo (§L.b(c) prepend + mirror §2.1.2) + C6i do-record ×2 + luật-số sàn-5 §L.b(j)(iv) — PASS 6/6 (heading 26/28/7/14 bất-biến · 0 checklist-file mới · BƯỚC-0 intact ×8 · 10/10 config-token preserved · add-only 26+/2). L2 = +C6 cite-2-nấc + H24-4 pending-flip vào governance-detectors.ps1 (+260/0 add-only) — fault-inject **13/13 2-chiều** (C6 7/7 lane chạy; H24-4 6/6 em-main hoàn tất — lane chết GIỮA fix harness-bug), live-run TOTAL 45 GIỮ + 2 net mới 0-flag count-riêng + exit-0 + ASCII 0-byte>127 + clean-diff 0-FOREIGN-line. Learned: (1) heading-invariant proof = block chèn toàn `>`/bullet + `grep '^+#'`=none (mạnh hơn đọc-mắt, họ insertion-only S134); (2) test-harness PS1 cần CÙNG kỷ-luật naming như production — bẫy `$h`/`$H` case-insensitive cắn chính harness dù script-đích đã né (`:813`); (3) 2 lane cùng chạm bề-mặt-đo (L1 sửa file nằm trong scan-scope L2) → số đo giữa-chừng trôi, clean-diff PHẢI cùng-snapshot. Tag `[s139, adap-3-ban, master-checklist-4-cua, c6-cite-2-nac, h24-4-pending-flip, faultinject-13-13, 53-writelane-onbehalf]`
- **S133+S134 (07-17) PE budget-freeze BE (Mig 67) + lũy kế TẠM TÍNH BE** → 📦 verbatim dời `archive/2026-07.md` (@S161 curate, moved-not-cut). Giữ hook: insertion-only-diff = proof thân-bất-động · backfill `Sql()` plain KHÔNG provider-guard (Mig 61/65/67 khuôn) · `TransitionAsync` KHÔNG SaveChanges nội bộ `:537` · Dev drift committed-chưa-apply → catch-up. Tag `[s133, s134, mig67, computepending, moved-l2]`
> **Persistent diary cross-session.** Auto-injected first ~200 lines at spawn (L1 HOT).
> Update BEFORE every stop. Tiered Memory v1: L1 HOT soft-cap ~30KB · 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..q4.md` + `archive/2026-06.md`. 🗺️ **Lookup map (Harness-9 S70): `archive/_INDEX.md`** — 1 dòng/bản-ghi + con-trỏ substring (sha-keyed, Ctrl-F fallback); đọc verbatim + `2026-0{5,6}.gist.md` (nén 4-field) theo nhu cầu.
> **Renamed S39:** implementer → implementer-backend (.NET half). FE patterns → `implementer-frontend` MEMORY. Test patterns → `test-specialist` MEMORY.
---
## 🎯 Role baseline
WRITE specialist .NET backend SOLUTION_ERP (`Domain+Application+Infrastructure+Api`). Case 1+2+3+5 only. Tools: Read, Edit, Write, Bash, Skill, Grep, Glob + 5 RAG MCP. Skills: `ef-core-migration` + `permission-matrix` + `contract-workflow` + `form-engine`. Output: commits + verify report.
## 🚫 Split boundary (S39) + auto-refuse
- ✅ MINE: `src/Backend/SolutionErp.{Domain,Application,Infrastructure,Api}/**`
- ❌ NOT: `fe-*/**``implementer-frontend` · `tests/**``test-specialist` · schema/UX/architecture decision → em main
- **REFUSE if ANY:** 1 schema design (FK/nullable/discriminator) · 2 UX flow · 3 cross-stack >2 layer · 4 bug fix reasoning chain · 5 integration multi-component · 6 <30min trivial · 7 first-time no precedent · 8 spec ambiguity >20%
---
## 📋 BE Patterns proven (apply confidently)
### Pattern 1: Per-chunk discipline A-E
A Domain+Mig (3-file) · B Application CQRS (Command/Query/Validator) · C Service (workflow logic) · D Api Controller · E commit. Build+test pass mỗi chunk. Commit `[CLAUDE] <scope>: Chunk X — ...` + Co-Authored-By Claude Opus 4.8 (1M context).
### Pattern 2: EF migration 3-file rule (gotcha #17 — BẮT BUỘC commit đủ)
`{TS}_{Name}.cs` + `.Designer.cs` + `ApplicationDbContextModelSnapshot.cs`. Path `src/Backend/SolutionErp.Infrastructure/Persistence/Migrations/`.
```bash
dotnet ef migrations add <Name> --project src/Backend/SolutionErp.Infrastructure --startup-project src/Backend/SolutionErp.Api
# Apply Dev (runtime): --connection "Server=(localdb)\MSSQLLocalDB;Database=SolutionErp_Dev;Trusted_Connection=True;TrustServerCertificate=true"
# Apply Design (ef default): không cần --connection
```
Apply BOTH DB per `feedback_designtime_runtime_db`.
### Pattern 3: Audit reuse trước khi clone (`feedback_audit_reuse_before_clone`)
"Clone X→Y": grep discriminator (`ApplicableType`/`Type`/`Kind`) → check Service/Handler hardcode → check FE route dynamic → check menu key (BE const + FE menuKeys.ts thường thiếu) → default reuse 80%, chỉ thêm menu key + sample seed.
### Pattern 4: Service hook vs CRUD endpoint cho derived state (`feedback_service_hook_vs_endpoint`)
State X derived của action Y → UPSERT trong handler Y, KHÔNG endpoint /X riêng. VD `ApproveV2Async` UPSERT LevelOpinion qua match `ApproverUserId==actorUserId` (fallback first khi Admin override). 0 endpoint mới.
### Pattern 7: Per-NV admin opt-in flag (Mig 29/30/31)
`ApprovalWorkflowLevel` +1 `bool` DEFAULT 0 (opt-in). EF `HasDefaultValue(false)`. DTO extend. FE Designer checkbox inline. Scope role-context → table mapping (Approver→Level table carry ApproverUserId FK, Drafter→User table direct, `feedback_per_nv_permission_scope`). Reusable F5/F6.
### Pattern 8: Tách endpoint riêng cho narrow scope
1 action 2 scope theo role → tách endpoint (guard tự nhiên + audit). VD Drafter `UpdatePeDraft` (Section 1 rộng, phase Nháp/Trả lại) vs Approver `AdjustBudget` (Budget rows hẹp, phase Đang duyệt + per-NV flag). KHÔNG default expand Drafter scope cho Approver.
### Pattern 9: Defense-in-depth FE+BE guard pair
UI `disabled={!canX}` + BE helper `EnsureCanXAsync(id, userId)` throw 403 (NOT inline handler) — tránh forge qua DevTools. Bất kỳ action sensitive (approve/reject/adjust).
### Pattern 12-bis: Cross-module entity cookie-cutter mirror (S29 Plan B, proven 3×)
"Mirror entity X từ module A→B": 6 file MAX — (1) new entity `Domain/<Mod>/<Entity>.cs` rename FK+nav · (2) parent +nav collection · (3) IApplicationDbContext +DbSet · (4) ApplicationDbContext +`Set<X>()` · (5) new `<Entity>Configuration.cs` (separate file mirror PE, NOT inline) · (6) `dotnet ef migrations add` 3-file. AuditableEntity inherit. FK: parent Cascade + 3rd-party Restrict + User skip-nav (denorm `<Type>ByFullName`). Apply 2 DB. ⚠️ Catalog-mega variant (S35 HrmConfig): HRM entities KHÔNG có global `HasQueryFilter(!IsDeleted)` (vs Master) → list query MUST `.Where(!IsDeleted)` thủ công (verify `Grep HasQueryFilter` Configurations FIRST). Validator MaxLength MATCH EF config (verify source-of-truth, KHÔNG trust spec blind).
### Pattern 12-ter: N≤7 satellite CRUD scaffold same parent (S34, `feedback_within_module_n_satellite_scaffold`)
"N satellite cùng parent" → 1 mega file `<Parent>SatelliteFeatures.cs` N region cookie-cutter (Create verify parent `AnyAsync` → Update `FirstOrDefault !IsDeleted` → Delete soft `IsDeleted+DeletedAt+DeletedBy` ICurrentUser) + 1 Controller extend (3 verb × N). Endpoint verify `parentId==cmd.ParentId` BadRequest mismatch. Per-action policy override class-level Read.
### Patterns moved (split S39)
- **FE patterns** (5 mirror 2-app · 6 VND helpers · 13 read-only Designer · 14 Tailwind JIT palette · 15 rowSpan builder · **16-bis 4-place mirror**) → `implementer-frontend` MEMORY (seeded).
- **Test patterns** (10 reflection authz · 11 test infra helper · 12 InternalsVisibleTo) → `test-specialist` MEMORY (seeded).
---
## ⚠️ Anti-patterns (DO NOT)
1. ❌ Skip MEMORY · 2. ❌ `--no-verify` · 3. ❌ `git add -A`/`git add .` (specific files) · 4. ❌ Touch outside spec scope · 5. ❌ Push remote autonomous (em main pushes) · 6. ❌ Modify `SolutionErp.slnx` autonomous · 7. ❌ Lower bar match em main (Smart Friend) · 8. ❌ Proceed khi ambiguity >20% → REFUSE
---
## 🧠 SOLUTION_ERP BE conventions (S40)
- **BE .NET 10:** PascalCase entities + DTO records + command names. CQRS+MediatR+FluentValidation+AutoMapper. Repository qua `IApplicationDbContext`. `GlobalExceptionMiddleware` → ProblemDetails (NO try-catch controllers).
- **State S53:** 47 mig (last `FilterMasterCatalogUniqueIndexesByIsDeleted` Mig 47, index-only) · 93 SQL tables · ~224 endpoints · 203 test (58 Domain + 145 Infra, test-specialist owns). Phase 9 UAT skip per chunk (`feedback_uat_skip_verify`).
- **Build:** `dotnet build SolutionErp.slnx` clean 0 err. Commit `[CLAUDE] <scope>: <msg>` + Co-Authored-By Claude Opus 4.8 (1M context).
- **Pin (KHÔNG `*`/latest):** MediatR `12.4.1` (14 fail DI) · Swashbuckle `6.9.0` · Node CI `20.x` · LibreOffice `25.8.6` · @microsoft/signalr `8.0.7`.
---
## 📅 Recent activity (FIFO — older → archive/git)
- _(Mục FIFO này hiện RỖNG — 4 entry cuối [2026-07-12/13: S116 PE giá ÂM · S113 Supplier import v2 Mig 64 · S112 PE sign-off · S112 Supplier Excel-import Mig 63] dời verbatim → `archive/2026-07.md` @S167. Trước đó: 2026-06-25→19 [S88 frozen-relocation · PE Section-B Mig 59 · PE chuông approver] → `archive/2026-06.md` @S116; S77→S56 [7 entries] @S112. Việc gần đây SỐNG nằm ở khối L1 HOT đầu file (S167/S166/S161/S139). Recall verbatim: archive tương ứng / `archive/_INDEX.md` / RAG `search_memory`.)_
---
## 🔄 Curate trigger
- >~30KB → archive recent → L2 `archive/<period>.md`. Stale >3mo → remove.
- **Last curate: 2026-08-01 S167 (self-FIFO, hook read-limit-guard bắn @22.4KB)** (22.4→15.4KB, dưới ngưỡng 17.1KB hook đòi): moved verbatim 4 entry Recent-activity 2026-07-12/13 (S116/S113/S112×2) → `archive/2026-07.md` (2.8→10.3KB). Mục Recent-activity nay rỗng có chủ đích — việc SỐNG ở khối L1 HOT đầu file. Prev **S116** (21.5→~15KB): moved 3 oldest Recent-activity (2026-06-19/24/25: PE chuông · PE Section-B Mig 59 · S88 frozen-relocation) verbatim → `archive/2026-06.md`, kept 4 newest (S116/S113/S112×2). Prev **S112** (25.6→~16KB): S77→S56 7-entry → 2026-06.md. Prev **S70 Harness-9** (33.2→17.4KB): L2 dark-matter recovery + `_INDEX` + gists. Prev: S40 dedup-split · S34 · S22.
## S152 (2026-07-25) — R1 retention-note ranh auto-refuse test [M9 on-behalf lead]
- **Integration testing multiple components = việc `test-specialist`, KHÔNG phải mình** — mình scaffold + compile-check; assertion/integration test cross-component (SQLite fixture, authz regression) do test-specialist own (tiền lệ S67 HRM test-after +23, S69 +20 đều test-specialist). Nhận viết integration test = double-touch tests/ sai split. Tag `[s152, r1-retention, refuse-integration-testing-components]`
- **S182 YC-013 (lead-seed, C2 /pause — lane đứt limit giữa W1, lane 1bis nối TỪ ĐĨA):** W0 trọn — phát hiện local có BA DB (lượt đầu trỏ nhầm base, TỰ KHAI "nhìn lượt đầu mà tuyên xong = PASS giả" rồi chạy lại đúng _Dev+_Design lên Mig 72) + baseline 645 đo độc lập + seed 8 row local ĐỦ roster. W1 5-fix land: `ContractSigningPlanWorkflowGuards.cs` public-static (Submit ở Infrastructure không thấy internal — 3 lối đã cân nhắc ghi doc-comment) · per-Code deactivate + normalize Trim().ToUpperInvariant() @`:348` (MAJOR-2 collation SQLite khác SQL-Server) · pin-check D6 2 message tách · changelog type-10 · DELETE-guard 8-module + IgnoreQueryFilters + D5+ApplicableType. Suite 660/0. → `runs/2026-08-08-S182-khkk-awf-mirror-ncc/sub-implementer-backend-0.md`