- [ ]🔴🔴CHỜ-ANHMỚI@S170:XOAYpasswordSQLprod`vrapp`—2secretTHÔtrongagent-memory(cicd-runs:48+reviewer-note:22,2giá-trịKHÁCnhau)đãredact`[đã che 71b7740a/4c3c67d5]`NHƯNGnằmtronggitremotetừ~13-05→rotatelàbắtbuộcthực-chất;+A4low-water0-sàn(refineE1)+đổi-chữ/matcherMFEimpl-fe(auditCHẶN-A1)
- **Root cause:** manual Project Create/Update store Code raw (no trim) + dupe-check EXACT equality (`ProjectFeatures.cs:95,138``x.Code==request.Code`). No Project import exists. Trim-only INSUFFICIENT (embedded space survives) — needs whitespace-collapse on BOTH paths, ideally + normalized-key unique index (app-check races under concurrency).
## Prod-access constraint (stress v)
`appsettings.Production.json`: `Server=localhost;...User Id=vrapp;Password=__SET_VIA_SECRETS__`. Prod SQL bound to localhost on VPS (not network-exposed) + secret creds + S134 SSH-crash gotcha ⇒ NO read-only path from dev. Prod ref-distribution (which row holds refs per pair) UNVERIFIABLE pre-execution — the plan's single biggest residual unknown.
`appsettings.Production.json`: `Server=localhost;...User Id=vrapp;Password=[đã che 4c3c67d5 — ROTATE REQUIRED]`. Prod SQL bound to localhost on VPS (not network-exposed) + secret creds + S134 SSH-crash gotcha ⇒ NO read-only path from dev. Prod ref-distribution (which row holds refs per pair) UNVERIFIABLE pre-execution — the plan's single biggest residual unknown.
## Dev DB snapshot (2026-07-23)
70 live projects, 0 soft-deleted. ONE whitespace anomaly `[FLOCK 01]` (D680DB3D, 0C/0PE/0budget). `[FLOCK01]` (F1B311EE) = 2C/2PE/0budget. ONE collision group (flock01). CAL01/FLOCK03 exist no-space only; FLOCK 03/CAL 01 space = prod-only.
> **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ờ**.
> 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.
-**VIỆC:**phiênbậnnhất—PlanCAChunkB(~10K)+PlanB4chunk(A2Mig32~25K·CMig33~25K·DFE~12K·**E3 dừng giữa chừng**).
-**KẾT-LUẬN:**A2phải**`stash`phầnđanglàmdởcủaem-main**(`ContractWorkflowService.cs`)mớibuildsạchđược—vìem-mainvàvai**cùng sửa BE song song**.E3(FESection5V2)**tự dừng**đúngchỗphảiphán-đoán("check`ContractDetail`type")vàtrảlạichoem-main.Đúc3luật:(1)khicùngchạmBEthìchunkphải**tuần-tự A→B→C, không song-song**;(2)tính-năngFEphức-tạpcầnmởrộngtype+thêmcomponentthì**em-main tự làm đáng tin hơn**khiđộmơ-hồcủaspec**>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ỡ.
- **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)
> 🔴 **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.**
| 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.
- **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.
- **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.
## implementer-frontend/2026-H2 (22.215 B — "verbatim L2, dựng @S166 2026-08-01")
**Đặc-điểm file:****TOÀN BỘ file là nội-dung moved-not-cut**củađợtdrain08-01(header:"Chuyểnverbatimtừ`MEMORY.md`khiL1chạmtrầnđọc.Con-trỏ1dòngở`MEMORY.md`;Ctrl-Ftagđểnhảy"),thứtựmới→cũ,**14 mục**,mỗimụccó**tag Ctrl-F riêng**=danh-tínhtra-cứu.
**⚠️Ràngbuộcnén(lệnhlead):**mọimụcmoved =**load-bearing**,tagtối-thiểu{cao}chomụcauto-refuse(dòng78)và**KHÔNG được nén mất danh-tính**⇒đề-xuấtdướiđây**giữ 1 khối riêng cho từng mục**,tuyệtđốikhônggộp2mụcthành1dòng,và**giữ nguyên chuỗi tag Ctrl-F**(nếumấttagthìcon-trỏở`MEMORY.md`trỏvàohư-không).
> Ghi-chú dedup: file này **gần như không có trùng-lặp để gộp** — mỗi mục là 1 lượt việc riêng có tag riêng. Giá-trị dedup thật nằm ở **FE-M**: cùng một bài học lặp 5 lần trong 3 phiên ⇒ lead có thể viết **1 dòng luật** ở L1 và để 5 mục chi-tiết ở L2, thay vì lặp bài học 5 lần.
-**KẾT-LUẬN:****(a)Việc<30phút/vặt**(sửa1dòngCSS,chỉnhnhãn)=em-maintựlàmcònnhanhhơnchi-phíspawn⇒**TỪ CHỐI nhận, đúng vai, ghi vào role-file**;nhậnviệcvặtlàđốtspawnvôích.**(b)KHÔNGhạchuẩnkiểu"Smart-Friendnể-nang"**:dùbịgiục"làmnhanh"vẫngiữsàn**mirror-SHA × 2 app + `npm build` × 2 PASS**;thiếu1trong2thì**trả lại, không ship**.
-**BÀI-HỌC:**hairanhnàybảovệhaithứkhácnhau—(a)bảovệ**ngân-sách token**,(b)bảovệ**sàn chất-lượng**;vàcảhaiđềulàquyền**tự từ chối**củavai,khôngcầnxinphéptừnglần.
-**BẤT-NGỜ:**mộtghi-chú"khônglàmgìcả"lạilàmụcđánggiữnhấtnhóm—vìnóđịnh-nghĩa**cái vai này KHÔNG nhận**,thứmàmọimụccònlại(toànlàviệcđãlàm)khôngnóiđược.
-**KẾT-LUẬN:****BÀI TO NHẤT — suýt kết-luận NGƯỢC**:gọi`setState`**trong lúc render**khiếnReact**huỷ render đó và render lại với state mới TRƯỚC khi commit**;harnessbản1chỉchạy1lượtnênđọcra`phase=3`(giá-trịcủarenderđãbịvứt)—**và control-âm cũng ra 3 ⇒ hai nhánh giống hệt nhau ⇒ phép đo mất khả-năng phân-biệt, trông y như PASS**.Vá =lặptớikhistateđứngyên→Ara`phase=2`,control-âmgiữ`3`.Giảibàichính:**override 3 trạng-thái**`chipPhase: T|null|undefined`(`undefined`="ngheURL"≠`null`="userchọnTấtcả")+reset**trong render theo `navKey`**,KHÔNGdùng`useEffect`(effectvẽmộtlượtdữ-liệucũrồimớisửa =nháy).
-**BẤT-NGỜ:**BE`/deleted`**thiếu tham số `group`**(`Controller:61-66`sovới`List:42`)⇒khônglọcđượcởclient(serverđếm`total`trêntậpchưalọc⇒**số trang nói dối**)⇒xửbằngcách**không cho UI tuyên nhóm ở màn đã-xoá**(đổisai-thầm-lặngthànhthiếu-nhìn-thấy-được)+gắncờcholaneBE;vàstaticMaplệch**có chủ đích**(fe-user6/6mang`group=1`,fe-admin5/6vìWfViewadmintrỏDesigner).
-**KẾT-LUẬN:**①đềbàibảoexport`KHKK_GROUP_LABELS`**mới**,nhưngđĩa**đã có**`KHKK_APPROVAL_GROUP_LABELS`(`types/khkk.ts:129`,landtừK2,**5 call-site**)⇒đẻmapthứ2chínhlà**phá đúng cái acceptance-5 (single-source) mà nó phục vụ**;đothêmthấynhãnBE≡`` `${n}.${short}` `` cho **8/8** ⇒ giải bằng **DERIVE `khkkGroupMenuLabel(n)`**, 0 call-site cũ bị đụng (hardcode lần 2 sẽ ra "N2 - 2. …" đánh số kép ở select). ② comment vá-8 bảo "phải nới regex trước vì sắp gỡ `KeHoachKyKet` khỏi ẩn-admin", nhưng `isAdminHidden:194` = `key.startsWith('Ct_')` ⇒ **KHKK chưa bao giờ bị ẩn** ⇒ viết comment theo ĐĨA + gắn cờ "7 nhóm rỗng" (`MenuGroup` chỉ xét `children.length>0`, không xét con có resolve được ⇒ header hiện, thân rỗng).
- **BÀI-HỌC:** **chứng regex bằng `new Function()` chạy CHÍNH khối text đã ship** (`indexOf('const khkkMatch')` → slice → eval), key sinh từ `KhkkGroupNumbers`/`KhkkLeafActions`**đọc thẳng `MenuKeys.cs`** ⇒ 42/42 resolve, 0 drop, **+3 control-âm** (G9→null · action rác→null · `Khkk_List` nhóm-1-không-infix→null vì bị chặn ở staticMap trước). Nhãn cũng kèm control-âm (chèn 'x' vào N4 ⇒ phép so phải FLAG) — **0-hit trần là vô nghĩa**.
- **BẤT-NGỜ:** `Khkk_G1` + 6 leaf **KHÔNG có infix** (S159, cấm đổi kẻo mồ côi permission-row) ⇒ 42 leaf infix chỉ thuộc nhóm **2..8**; giữ `[1-8]` rộng hơn tập seed một nấc là **cố ý**; và Layout 2 app **cố ý KHÔNG mirror** (user +34 dòng regex · admin +13 dòng comment).
**[cao] FE-D — S166 K5: "chuẩn bị sẵn cho sau" nghĩa là đổi hình dạng, không phải bịa field**
- **VIỆC:** mở 8 ngăn nhóm ở GĐ2 của cây toàn-trình. Artifact `…/sub-implfe-k5.md`.
- **KẾT-LUẬN:** đề bài đòi GĐ3/4 đi qua `lines[].contractId ∪ pe.contractId`; đo **4 nơi đều ÂM** (`PeListItem` 0 hit chữ `lines` · `PurchaseEvaluation.cs:31` chỉ có `Guid? ContractId` đơn · `ContractListItem` không có `purchaseEvaluationId` · `Contract.cs` 0 khoá ngược). Bằng-chứng đắt nhất là **BE tự khai**: `CreateContractFromEvaluationFeatures.cs:143-145``pe.ContractId = contracts[0].Id` + comment "N HĐ liên-danh truy qua changelog" — endpoint TRẢ `contractIds[]` (`PeDetailTabs.tsx:2186`) nhưng **chỉ HĐ đầu được ghi ngược ⇒ HĐ thứ 2 trở đi VÔ HÌNH**. ⇒ chỉ wire vế làm được: `contractIdsOfPackage = new Set<string>()` (hợp) thay vì đọc 1 ô, đánh dấu sẵn chỗ cắm nguồn-2 + trích nguyên văn BE; FLAG 2 đường cho lead.
- **BÀI-HỌC:** `stage.leaves` giữ vai **danh sách PHẲNG canonical (nguồn đếm duy nhất)**, `groups` chỉ **chia lại chính nó** ⇒ bất-biến tổng là chuyện **CẤU TRÚC**, không phải kỷ-luật nhớ-cộng-cho-khớp. Hiện đủ 8 ngăn kể cả rỗng = `.map` trên hằng chứ **không `.filter`**; ngăn "(chưa phân nhóm)" **chỉ mọc khi thật có phiếu lạc** (8 nhóm là khung nghiệp-vụ cố định ⟂ ngăn kia là chỗ chứa bất thường).
- **BẤT-NGỜ:** **CA4 control-âm tiêm lỗi nhân-đôi ⇒ `console.warn` NỔ** — không có CA4 thì "0 cảnh báo" ở CA1-3 vô nghĩa (**im-vì-đúng ⟂ im-vì-câm**); và **2 hash ĐỨNG YÊN** (`PipelineTreePanel``d70ac315`, `PePipelineStrip``6fb7337e`) được dùng làm **đối chứng dương** cho phép đo SHA.
**[cao] FE-E — S153 T5: `writeGuard` là 2 điểm, chỉ một điểm có răng**
- **VIỆC:** T2 dựng template `session-mind-template.md` + T5 sửa `hmw.js`. Lead seed on-behalf @closeout M9 (**T2 return mất schema-fail — #53 +1**, phải derive-from-body; template VẪN LAND 8.819 B).
- **KẾT-LUẬN:** `VALID_ROLES` 20→21 (sau T10/T11 = **23**); 🔴 **`writeGuard` nằm ở 2 CHỖ**: `:228` là comment JS (tài-liệu) **và**`:235` là template-literal **ĐI VÀO PROMPT của sub**. Chỉ sửa `:235` ⇒ tài-liệu lệch trong chính file đó; **chỉ sửa `:228` ⇒ prompt runtime KHÔNG đổi ⇒ vai read-only bị hướng-dẫn như vai được ghi ⇒ Bash-write MD ⇒ mojibake G-009**. `:235` = **điểm có RĂNG**. Vùng cấm đo bằng diff: `WIDTH_CAP` 0 hit · `TIER2_EXPECTED_FULL_ID` 0 hit.
- **BÀI-HỌC:** T2 — `ts` sống trong HEADING sau em-dash nên **0 dòng key `ts:`** (không phạm rào-2); placeholder `<k>` trong schema-comment để parser không khớp nhầm; kiểm `_SECRET_RES` để ví-dụ của rào-3 không tự khớp mẫu của chính nó.
- **BẤT-NGỜ:** 2 kẽ báo lead — ① **va tên cùng-vai 2 lần gọi** (chỉ số `i` reset mỗi lần gọi ⇒ đợt 2 suýt đè `sub-implementer-frontend-1.md` của đợt 1) = kẽ CÒN LẠI sau S134; ② `node --check` trên file thô **LUÔN** SyntaxError (top-level await) ⇒ acceptance phải là **parse-sau-khi-bọc + đối chứng HEAD**.
**[vừa] FE-F — S166 K4c: rỗng-vì-lọc phải khác câu với rỗng-vì-chưa-có-gì**
- **VIỆC:** lọc trang WfView theo nhóm (đóng FLAG-3 của K4b: `?group=` chưa có ai tiêu-thụ ⇒ 8 leaf mở ra 8 trang y hệt). fe-user ONLY, 1 file (+68/−5), `git diff -- fe-admin`**RỖNG**.
- **KẾT-LUẬN:** đo trước 4 thứ, không đoán cái nào — ① `AwDefinitionDto.code` là tên field THẬT (`types/approvalWorkflowV2.ts:41`, đang render `:165`) ② trang tải trọn bộ theo type rồi đọc `summary.history` ⇒ **lọc CLIENT-side, KHÔNG thêm trục `group` vào queryKey** (thêm = 8 lần gọi mạng cho cùng payload + 8 ô cache trùng) ③ `DbInitializer.cs:609``code = $"KHKK-N{n}"` + `:623``IsUserSelectable = true` ⇒ 8 workflow **thực sự lọt** bộ lọc của trang (seed `false` thì lọc kiểu gì cũng trắng trang) ④ `PageHeader` bản đang import CÓ `actions` (repo có ≥2 bản khác chữ ký — **lặp bài S37**).
- **BÀI-HỌC:** chốt chặn **KÉP**`typeInt === 10 && /^[1-8]$/` — `group` là khái-niệm riêng của KHKK, type khác hoặc rác thì **bỏ qua hoàn toàn** (thà hiện đủ còn hơn lọc theo số vô nghĩa ra trang trắng); regex trên chuỗi bắt được `"03"` mà `Number()` sẽ nuốt; lọc giữ **đủ VERSION cùng code** (nghĩa là "quy trình của nhóm", không phải "1 bản ghi").
- **BẤT-NGỜ:** dùng chung một câu cho hai loại rỗng thì user nhóm N5 tưởng **cả module chưa cấu hình** trong khi 7 nhóm kia đang chạy — cùng họ bài "sai-thầm-lặng → thiếu-nhìn-thấy-được"; chứng 21/21 kèm **2 control-âm** (gỡ vị-ngữ lọc ⇒ ra 8 = phép đo phân-biệt được · helper sai khuôn `KHKK_N3` ⇒ 0 wf, không âm thầm khớp).
**[vừa] FE-G — S166 K6: đếm bằng cách DỰNG LẠI CÂY THẬT rồi chạy chính bộ lọc đã ship**
- **VIỆC:** thu gọn menu admin về đúng vai "nơi cấu-hình". fe-admin ONLY, **1 file** (+52/−19), fe-user 0-diff.
- **KẾT-LUẬN:** spec treo ẩn-số "N = 7 hay 8 tuỳ `AwV2_Contract` có tồn tại"; đo ra **0 HIT toàn repo** ⇒ 2 seed leaf + 8 designer ⇒ chốt **N = 1 Dashboard + 4 System-leaf + 2 AwV2 + 8 designer = 15** (spec **tự quên cộng 8 designer** vào công thức của chính nó). Phép đếm: parse 72 tuple literal từ `DbInitializer` + sinh 128 key từ vòng lặp (hằng đọc thẳng `MenuKeys.cs`) = 200 node → chạy `ADMIN_HIDDEN_KEYS` + `isAdminHidden` + `filterForAdmin`**cắt từ chính file** → **166 lá → 15 lá**. **CONTROL-ÂM:** bỏ `'KeHoachKyKet'` khỏi Set ⇒ 15→**63** (+48 = đúng 8 nhóm × 6 leaf).
- **BÀI-HỌC:** `filterForAdmin` lọc **ĐỆ QUY** ⇒ ẩn 1 ROOT là cả cây con chết theo ⇒ tập chỉ cần liệt 12 ROOT (thêm `Workflows`/`PeWorkflows` vì chúng là CON của `System`); liệt từng leaf = thừa và phải bảo trì mỗi lần BE thêm key. Vá-14 có **2 lần đảo** (S29 ẩn → S57 bỏ ẩn → QĐ7 S164 ẩn lại rộng hơn) ⇒ comment cũ đang nói NGƯỢC luật đang chạy, phải gỡ và viết lại kèm câu "cả hai đều từng đúng, mốc sau thắng mốc trước".
- **BẤT-NGỜ:** **cây dựng lại tự kiểm chính nó** — đối chứng "113 key trong `MenuKeys.All` → 0 key thiếu menu-row (invariant T6)", dựng sai thì chỉ số này vỡ ngay; và **bẫy suýt lẫn**: `resolvePath:173` CÓ nhánh nhận code `'Contract'` nhưng **route-resolver có nhánh ≠ menu-row tồn tại**.
**[vừa] FE-H — S164/S165 K2: tiền-đề lead sai, việc thật chỉ ≈ 1/4 mô tả**
- **VIỆC:** relaunch p2 sau khi p1 chết vì #53 — nhóm duyệt N1-N8 cho KHKK.
- **KẾT-LUẬN:** lead khai CreatePage "mid-wire, 8 khai báo chưa vào JSX" (nghĩa là TS6133 sẽ đỏ); **đo `git diff` trước khi gõ** thì **8/8 ĐÃ có call-site**, Detail cũng đã land ⇒ **việc thật ≈ 1/4 mô tả**, chỉ ListPage còn dở. p2 sửa đúng 3 điểm: badge `N{g}`**nhét vào ô "Mã kế hoạch"** (không đẻ cột — bảng đã cuộn ngang @1366 do cây GĐ 19rem) · thêm cột "Tổng duyệt" (BE trả **0** cho phiếu chưa duyệt ⇒ ép hiển thị `—` kẻo đọc nhầm "đã duyệt 0 đ") · **`colSpan` 7→8 ở hai chỗ** (loading + empty row).
- **BÀI-HỌC:** khuôn "WRITE-lane garble ≠ mất code" (S114) đúng thêm một lần: lead đọc transcript dở-dang nên kết-luận theo **Ý ĐỊNH đang chạy**, không theo đĩa ⇒ **viết lại phần đã đúng chính là phá**. `npm run build` = `tsc -b && vite build` với `noUnusedLocals:true` ⇒ **build LÀ phép thử TS6133 thật**, không cần tin IDE (#68).
- **BẤT-NGỜ:** quên `colSpan` là **lỗi CÂM cho tới lúc bảng rỗng** — thứ chỉ lộ ở trạng-thái ít ai test; và SHA-pair **5/5 IDENTICAL** với Panel không sửa (hash `2B64144EF6E8` BẰNG baseline) làm đối-chứng dương.
- **VIỆC:** 3 lượt FE cho KHKK (Designer type-10 · 3 page + types · panel workflow). **Mọi lượt đều #53, đĩa cứu trọn.**
- **KẾT-LUẬN:** W1 — containment phải **2 LỚP render + payload** (`levelFlagsPayload(e, lock)` ép false ở **2/2** call-site; chỉ dùng `disabled` là **containment GIẢ** vì `copyFromDefinition` tuồn state ra); 2 tiền-đề đề-bài sai tự bẻ (FE không có bảng nhãn — nhãn đến từ BE `applicableTypeLabel`; khuôn type-9 **không tồn tại** ⇒ soi gương `Contract:3`). W2 — types **theo ENTITY** khi BE chạy song song; header types = **HỢP-ĐỒNG 12 endpoint** (reviewer đối chiếu ra **6 chỗ đứt** → lead vá). W3đ1 — `KhkkWorkflowPanel` soi gương PE-panel 1063 dòng theo **bảng GIỮ/BỎ tường minh**; cây workflow THÔ nên **FE tự suy ✓/●/○ từ con-trỏ đôi** (StepIndex 0-based vs `Level.Order` là giá-trị).
- **BÀI-HỌC:** hợp-đồng giữa 2 lane phải do **LEAD định-nghĩa literal** — để mỗi lane tự suy thì đứt ở chỗ không ai nhìn; và "place-3 menuKeys SKIP-có-khai (0 consumer)" cho thấy **bỏ qua có khai** là hành-vi hợp lệ, khác hẳn bỏ sót.
- **BẤT-NGỜ:** W2 khai **thiếu `approverUserId`** trong opinion, tới W3đ1 mới bổ — lỗ hổng hợp-đồng chỉ lộ ra ở lượt tiêu-thụ, không lộ ở lượt định-nghĩa.
- **VIỆC:** 5 lượt FE 2-app: J1 S134 lũy-kế tạm tính · J2 S133 badge budget-frozen · J3 S117 radio thứ 5 ProMinMax · J4 S116 cho nhập số ÂM (**cao**) · J5 S113 import v2 + publish.
- **KẾT-LUẬN:** **J1**`sub?: ReactNode` cắm vào `BudgetSharedNumCell:1184` + `BudgetColValue:1197` ⇒ chèn sub-dòng amber vào N chỗ render **không nhân bản markup**; gate `showPending = !bs.budgetFrozen && (...)`; hmw đánh chỉ-số sub-file **GLOBAL theo taskList** ⇒ hết va tên khi 2 vai KHÁC nhau cùng một lần gọi. **J2** badge `🔒` ở `PeBudgetSummaryTable :1350-1359`, 🔴 className header **lặp 2 chỗ** (`:1350` budget và `:1931` winners) ⇒ anchor của Edit **phải kèm text nhìn thấy được** ("Tổng hợp ngân sách trình ký") mới unique. **J3** entry mảng có điều-kiện phải **spread TRƯỚC `as T[]`** (né suy-diễn sai); `?? undefined` = cách bỏ key chuẩn của axios; Max **không cần state riêng** (derive từ selectedCandidate) ⇒ 0 chỗ phải reset. **J4** 🔴 2 dialog POST **commit thẳng `form.thanhTien`** (`:2247`/`:2906`, không có nút "Lưu") ⇒ nút đổi dấu **phải ghi giá CÓ DẤU NGAY**, chỉ lật cờ là **MẤT DẤU thầm lặng**; `parseVnd/formatVndInput :51-52` là hàm dùng chung (chia với ngân sách) nên **không sửa**, bọc `Math.abs`; gate đổi thành `!== 0` (không phải `> 0`) và **2 gate FE cùng đổi, không phải 1** (`missingForApproval:212` + `submitChecklist:243` → helper `hasRealSelectedQuote`). **J5** nút "Công bố/Ẩn" gọi `POST /suppliers/{id}/publish` — **KHÔNG qua UpdateSupplier (#73)**; badge dùng full-class-literal (P14).
- **BÀI-HỌC:** ba khuôn tái dùng được: **slot-prop** (J1) để mở rộng cell dùng chung, **anchor theo chữ nhìn thấy** (J2) khi className lặp, **spread trước cast** (J3). Và J4 dạy cái đắt nhất: khi form **không có nút Lưu** thì mọi thay đổi hiển-thị phải commit ngay, nếu không thì UI và payload lệch nhau trong im lặng.
- **BẤT-NGỜ:** J4 — báo giá nằm ở `details[].quotes`**chứ không phải**`suppliers[].quotes` (đi nhầm nhánh là đo nhầm), và công thức cũ SUM `winnerQuoteTotal` chặn oan ca net-zero `+100/−100=0`; J5 — mục "3.d disabled" hoá ra **đã đúng sẵn ⇒ NO change**, kèm một **DEVIATION có khai** ("Tải file mẫu" chỉ đặt trong dialog trong khi parent 2.d có nhắc thêm nút ở page).
**[cao] FE-M — [CHỈ-MỤC] sợi chỉ "tiền-đề sai ⇒ đo đĩa trước khi gõ" ×5**
- **VIỆC:** đánh dấu chỗ lặp để lead viết **1 dòng luật** thay vì 5 lần kể lại.
- **KẾT-LUẬN:** K2 (lead khai mid-wire, thật ra 8/8 đã land — việc thật ≈1/4) · K4a (**2 tiền-đề sai trong 1 đề bài**: "chưa có map" thật ra có 5 call-site · "sắp gỡ ẩn" thật ra chưa từng bị ẩn) · K4b (**lần 3 liên-tiếp**, làm đúng nguyên văn sẽ giết 6 chip) · K5 (đề bài đòi đường dữ-liệu **không tồn tại**, đo 4 nơi đều âm) · K6 (spec **tự quên** 8 designer trong công thức của chính nó).
- **BÀI-HỌC:** luật rút gọn: **đo đĩa trước khi gõ, và khi đĩa cãi đề bài thì đĩa thắng — nhưng phải KHAI ra chỗ cãi** (cả 5 lượt đều khai, nên lead sửa được spec).
- **BẤT-NGỜ:** 5 lần sai đều **không phải lỗi cẩu thả**, mà là lead đọc transcript dở-dang hoặc spec viết trước khi code land ⇒ nguyên-nhân nằm ở **độ trễ giữa lúc viết đề bài và lúc đọc đĩa**, không nằm ở người viết đề bài.
- **gotcha#:** `#82` ("**Display-only #82**: route+quyền còn nguyên, deep-link vẫn 200, thu gọn = bớt lối đi menu KHÔNG phải thu hồi quyền") · `#68` ("build LÀ phép thử TS6133 thật, không cần tin IDE (#68)") · `#73` ("`POST /suppliers/{id}/publish` (**KHÔNG qua UpdateSupplier** #73)") · `#53` (×4: "Relaunch p2 sau p1 chết #53" · "mọi lượt #53, đĩa cứu trọn" · "T2 return mất schema-fail (#53 +1)" · hàm ý ở S161) · `G-009` (mojibake — mã governance, không phải gotcha số) · `P14` (badge full-class-literal) · `403 S89` (N9 KHÔNG link)
- **surprise (nhãn 🔴/BÀI/BẪY nguyên-văn):** "🔴 **BÀI TO NHẤT — HARNESS ĐO NHẦM CÁI RENDER BỊ REACT VỨT, suýt kết luận NGƯỢC**" · "**control-âm cũng ra 3 ⇒ 2 nhánh giống nhau = phép đo mất khả năng phân biệt, trông y như PASS**" · "🔴 **Tiền-đề đề-bài sai lần 3 liên tiếp** (S164→K4a→K4b)" · "🔴 **Khuôn S164 'đo đĩa TRƯỚC khi gõ' ăn tiếp 2 lần trong CÙNG 1 đề bài**" · "🔴 **BÀI CHÍNH — tiền-đề lead SAI, đo `git diff` TRƯỚC khi gõ** … Việc thật ≈ **1/4** mô tả … **Viết lại phần đã đúng = phá**" · "🔴 **BÀI: forward-provision đúng nghĩa = đổi HÌNH DẠNG, KHÔNG bịa field**" · "🔴 **Bẫy suýt lẫn: `resolvePath:173` CÓ nhánh nhận code `'Contract'` — nhưng route-resolver có nhánh ≠ menu-row tồn tại**" · "(spec tự quên cộng 8 designer vào công thức của chính nó)" · "🔴 **Rỗng-vì-lọc ⟂ rỗng-vì-chưa-có-gì phải khác câu**" · "🔴 **writeGuard là 2 ĐIỂM không phải 1**" · "🔴 2 dialog POST commit `form.thanhTien` THẲNG … chỉ flip cờ = **MẤT DẤU thầm lặng**" · "🔴 GOTCHA quote ở `details[].quotes` KHÔNG `suppliers[].quotes`" · "🔴 Gotcha: className header LẶP 2 chỗ … Edit anchor PHẢI kèm text visible" · "**2 hash đứng yên = đối chứng dương**" (K5) · "Panel không sửa = đối chứng dương" (K2) · "types `7a99b865` không đổi = đối chứng dương" (K4b) · "**im-vì-đúng ⟂ im-vì-câm**" (CA4) · "**0-hit trần vô nghĩa**" (K4a) · "chỉ `disabled` = containment GIẢ" (W1) · "DEVIATION flagged" (S113) · "3.d disabled ĐÃ đúng SẴN → NO change" (S113) · "**2 kẽ báo lead**" (S153) · "reviewer đối chiếu ra 6 đứt → lead vá" (W2)
## Ghi-chú liên-file (FLAG-only cho lead — KHÔNG gộp, giữ nguyên tắc đóng-kín từng file)
> Phần này KHÔNG phải bản nén. Đây là các quan-hệ **giữa** file mà lead cần biết trước khi hợp nhất, để không đếm 2 lần hoặc nén mất một bên.
1.**Bản sao nguyên-văn cùng vai:**`investigator-codebase/2026-05-q1`(mục"2026-05-11(setup)")và`…/2026-05-q3`(mục"2026-05-11—Setupbaseline")cónội-dung**trùng**("44gotchas+14memoryentries+6skills+27mig+81testpasscumulative…AwaitingfirstSendMessage").Đề-xuất:giữ1bản,bảnkiathànhcon-trỏ.
2.**Cùng sự-kiện, 2 độ dài:**audit2bugchangelogS25cóbảnDÀI(q2,5Qđầyđủ)vàbảnNGẮN(q3,wrap+kếtquảCI`#215`FAIL→`#216-#221`PASS).Nénmấtbảndàithìmấtfile:line;nénmấtbảnngắnthìmấtkết-cụcCI.
3.**Cùng sự-kiện, 2 VAI (rủi-ro đếm đôi khi hợp nhất):**①buglookupper-NV—`investigator-q1`B1-A(chẩn-đoán`:765`)↔`reviewer-q1`B5-B(PlanNvá1/5site→PlanOcascade4site).②PlanP—`investigator-q1`B1-B(phát-hiệnbody3field)↔`reviewer-q1`B5-B("rootcause2ngàyprodbugF1+F2").③PlanAA—`investigator-q1`B1-E↔`reviewer-q1`B5-D.Đề-xuất:giữ**cả hai**nhưngghirõvai,vìgócnhìnkhácnhau(chẩn-đoán⟂nghiệm-thu).
4.**Một tên, hai nghĩa:**trong`investigator-q2`,"**Mig32**"xuất-hiệnvới2nghĩa(PlanAGđề-xuất`AddProjectPackageTable`·PlanBthực-tế`AddApprovalWorkflowToContract`).Nénẩusẽtạomâu-thuẫngiả.
5.**Một gotcha, hai cách chú-giải:**`#48`đượcchú"SQLitefrozenclocktie-break"ở`reviewer-q2`+`investigator-q3`+`test-specialist`(dùnglàmlý-dolọctheo`ContextNote`),nhưngởbatchA(`sub-harvest-curator-sleep-batchA-S170.md:43`)`#48`đượcchúlà"refactor>100 LOC Service chạm changelog/audit". Hai chú-giải nằm cạnh nhau trong cùng dòng từ-khoá gốc của `reviewer-q2` — **đề-nghị lead chốt 1 chú-giải canonical** khi hợp nhất (đây là quan-sát, KHÔNG phải phán một bên sai).
6.**3 mục liên-quan trực-tiếp tới sức-khoẻ HARVEST (H2 lưu ý riêng):** ① `investigator-q4` header — MEMORY trỏ file **vắng đĩa**, nội-dung git-only `d2f52ba`, và **lô S29-S37 tới nay vẫn khai là chỉ nằm trong git** (nếu lead muốn kéo về đĩa thì đây là đầu mối; tôi **chưa kiểm** trạng-thái hiện tại). ② `test-specialist` S133 — **2 lần gọi cùng vai trong 1 run-folder ghi đè sub-file của nhau**, nội-dung sống nhờ journal + diary (rủi-ro mất nguyên-liệu harvest tại nguồn). ③ `investigator-q3` S27 — vai **tự nghi-ngờ lịch-sử spawn của chính mình** ("agent type NOT FOUND", "trust prior memory entries but FLAG uncertainty"); đây là token loại Fidelity, **giữ nguyên, không tự phán**.
7.**Ràng buộc nén đã tuân:**`test-specialist` giữ **đủ 16 mốc chuỗi gốc + 12 mốc hậu-chuỗi** (xem TS-A) và gắn cờ **4 lỗ + 2 mâu-thuẫn nội-tại**; `implementer-frontend` giữ **14/14 mục moved-not-cut ở khối riêng, kèm nguyên chuỗi tag Ctrl-F**, mục auto-refuse (dòng 78) tag **cao**.
---
## Tự-kiểm (harvest-curator, propose-only)
- **Phạm-vi ghi:** DUY NHẤT file này. 0 chạm `.claude/agent-memory/**`, 0 `store_memory`, 0 sửa canonical. Viết bằng Write/Edit tool (KHÔNG Bash-append) theo rào chống mojibake của chính vai.
- **Anti-#53:** file được bồi **5 lượt ghi tăng dần** (header+§1 → §2-3 → §4-5 → §6-7 → §8+kết), mỗi lượt tự đứng được nếu lượt sau chết.
- **Tự bắt 1 lỗi trong lúc làm:** lượt ghi §1 lỡ kéo `:379-387` (thuộc q2) vào token-list của q1 ⇒ đã gỡ ngay bằng Edit — đúng loại **cross-file bleed** mà lệnh đóng-kín nhắm chặn.
- **Giới hạn hiệu-lực:** mọi con số/verdict ở trên là **trích từ verbatim**, KHÔNG phải phép đo mới của tôi. Cụ-thể: tôi **không chạy `dotnet test`**, **không chạy `git log/show`** để xác-minh commit, **không mở** các artifact `runs/…/sub-implfe-*.md` được dẫn. Mâu-thuẫn nêu ở TS-A là mâu-thuẫn **nội-tại của văn bản**.
- **Trạng-thái:** Phase 1 (GATHER + DEDUP) — **đề-xuất**, chờ lead VERIFY rồi mới APPEND (B3). Bản nén 4-field đủ field ở **100% cụm** (không cụm nào thiếu VIỆC/KẾT-LUẬN/BÀI-HỌC/BẤT-NGỜ).
== HẾT ==
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.