Files
solution-erp/.claude/agent-memory/reviewer/MEMORY.md
2026-08-01 11:58:34 +07:00

104 lines
22 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
- **[→ archive/2026-07.md — verbatim ĐÃ VERIFY moved-not-cut 3/3 @S166-K5-curate] S166 gate K4b · K4a · vá F-1 (digest):** mỏ-neo XUYÊN FILE (quét file BỊ DỜI, không chỉ file đang sửa) · **tham-số-trang-trí** (đo AI ĐỌC từng param, đừng đo "route có tồn tại") · mỏ-neo tự-vô-hiệu ngay lúc land (đo SAU khi chèn) · **ô canonical sai đo được bằng 1 curl** · khuôn-nguồn 2 tầng ⇒ đo **GIÁ-TRỊ KHỞI-TẠO** không đọc chú-thích · **cây phình giữa review** ⇒ neo mốc + re-đo `--stat` TRƯỚC verdict · HIGH-nằm-ở-git (`git status --porcelain -- src tests | grep '^??'`) · khoá-cache định-danh REQUEST không định-danh URL · sợi-dây-1-argument 0 test.
- **S166 (08-01) gate K5 cây GĐ2 mở 8 sub-folder nhóm — PASS 0 blocker (1 CLARIFY + 5 MINOR):** lõi hiếm-đúng: bất-biến Σ do **CẤU TRÚC** (1 mảng nguồn `khkkItems` → 1 phép phân hoạch if/else TOÀN PHẦN → `stage.leaves` vẫn là chỗ đếm duy nhất `stageCount():96`) nên không phụ thuộc ai nhớ cộng; route `?group=` nối đủ 3 chặng (FE `:79-80` → param `:124` → BE `Where(:757)`), **khác hẳn tham-số-trang-trí K4a**. **Bài thu:** ① 🔴 **phép-đo-rẻ-nhất nằm ở file RÁC của lane khác**`menus.json` untracked ở gốc repo (sản phẩm curl của cicd-monitor) chính là payload `/api/menus/me` LIVE ⇒ đối chiếu nhãn cây suy-ra ⟂ nhãn sidebar thật **8/8 khớp từng ký tự + `displayLabel` đều null**, thứ mà đọc code không bao giờ chứng được. Cùng file đó là **rào commit** (`git add -A` sẽ nuốt 44KB rác) ⇒ 1 vật vừa là bằng-chứng vừa là rủi-ro, đừng chỉ báo 1 vế. ② **chân-lý-rỗng phải khai là rỗng**: curl prod `total=0` phiếu KHKK ⇒ phân bố `approvalGroup` = `{}`, KHÔNG dùng để kết luận gì; nhưng cùng con số ấy đẻ ra sự-thật dùng được cho UAT (ngày đầu mọi gói hiện **8 dòng "SẮP" rỗng** — đúng spec, dễ bị đọc thành hỏng). ③ **tương-đương-từng-vế > "cùng tập cùng thứ tự"**: vòng lặp GĐ3/4 bị viết lại ⇒ lập bảng 4 vế (tập id · thứ tự = `Set` giữ thứ-tự-chèn · khử trùng · dòng-phụ `find` = phiếu ĐẦU) mới dám phán 0-regression; thân stage4 **0 tham chiếu `p`** là lý do cấu-trúc khiến rewrite an toàn. ④ **tiền-lệ phải đo ở BASE, không đo ở cây đã sửa**: `git show 88e7ecf:<file> | grep -A6 '<summary'` cho thấy 6/6 summary cũ chỉ chứa `span`/`svg``<button>` lồng trong `<summary>`**khuôn MỚI** (nested-interactive a11y), lane tưởng đang bám tiền lệ. ⑤ **"15/15 OK" chết theo phiên**: script `new Function` không commit + FE **0 hạ tầng test** (`package.json` chỉ `dev|build|lint|preview`) + chuông Σ là `import.meta.env.DEV` ⇒ prod bị strip ⇒ 0 lưới an toàn; đừng đọc số-test-ad-hoc thành đã-phủ. ⑥ 2 nghĩa của 1 dòng checklist ("GĐ3/4 by c.type") — lead và lane **cùng chọn 1 nghĩa không chứng minh nghĩa đó đúng ý owner** ⇒ ghim cách đọc vào commit. Tag `[s166, bang-chung-o-file-rac, chan-ly-rong, tuong-duong-tung-ve, tien-le-do-o-base]` **Evidence:** `runs/2026-07-31-S164-4gd-khkk-fanout/sub-reviewer-gate-k5.md`
- **S166 (08-01) gate K4c chốt cụm-2 (FE lọc nhóm WfView + 1 Fact test) — PASS 0 blocker (1 CLARIFY + 3 MINOR):** ① 🔴 **flake chỉ lộ ở LƯỢT ĐẦU, và chính tôi giết mất chứng cớ**: chạy `dotnet test -v q` SONG SONG với `tsc` ⇒ 1 test CŨ đỏ (`Failed 1/8`) rồi 10/10 xanh sau đó + suite 622/0 ⇒ `-v q` **nuốt thông điệp assert** ⇒ có tên test mà không có lý do. Bài: lượt chạy ĐẦU dùng verbosity thường, `-v q` để dành cho lượt lặp. Truy nhiễm phải đo 3 vế mới dám nói "không do diff": fixture `:memory:` per-test · codegen **0 static** · xUnit 2.9.3 same-class = tuần tự. Báo "8/8 ở 11/12 lượt", KHÔNG báo 8/8 tuyệt đối. ② **probe RED bằng đổi TEST-INPUT (không chạm prod) là hợp lệ CHỈ KHI tham số xuất hiện ĐÚNG 1 CHỖ trong handler** — grep xong mới được chấp nhận; ≥2 chỗ là lập luận sập. ③ `Total` là dấu-vân-tay lọc-SERVER **chỉ khi** `CountAsync` chạy trên `q` SAU `Where` và TRƯỚC `Skip/Take` — đọc `ProjectPagedAsync:790-792` mới dám ký, đừng tin comment. ④ **queryKey KHÔNG thêm trục là ĐÚNG** khi BE endpoint không nhận trục đó (đọc controller: chỉ `applicableType`+`isUserSelectable`) + giá trị lọc là **dẫn xuất trong render** (không `useState`) ⇒ miễn nhiễm bẫy "đổi leaf không remount". ⑤ Guard `/^[1-8]$/` chặn `Number("03")=3`, và **đồng nhất 3 trang** KHKK — kiểm cả 3, lệch 1 chỗ là 2 luật cho 1 tham số. ⑥ Lane khai bundle `1,643.96 kB` — tôi chạy lại `npm run build`, **trùng từng chữ số** ⇒ claim đo-lường có thật. Tag `[s166, chung-co-bi-nuot-boi-verbosity, probe-1-cho-moi-hop-le, total-la-van-tay]` **Evidence:** `runs/2026-07-31-S164-4gd-khkk-fanout/sub-reviewer-gate-k4c.md`
- **S167 (08-01) gate K6 admin thu-gọn (1 file FE, tập 12 key ẩn) — PASS-WITH-FLAGS 5 (1 MAJOR + 1 CLARIFY + 3 MINOR):** ① 🔴 **cây menu PROD SỐNG là thước, seed chỉ là bản vẽ**: `curl /api/menus/me` (token admin, 44KB) → áp CHÍNH tập key **cắt bằng regex từ file đã ship** ⇒ 200 node · 166 lá → **15 lá**, trùng tên 15/15 + control-âm bỏ `KeHoachKyKet` = 63 (+48) khớp lane. Cùng payload đóng luôn FLAG "row chèn tay": **10 `AwV2*`, 0 `AwV2_Contract`**. Khai giới hạn: endpoint đã lọc-quyền ⇒ row không có Permission thì vô hình (nhưng cũng vô hình trên sidebar ⇒ không lệch C1). ② **`filterForAdmin` mới là bước MỘT**: lá còn "THẤY" phải qua tiếp `resolvePath→null ⇒ MenuLeaf drop im lặng` (#50) và **group rỗng-hoá tụt xuống render như LEAF** (`children.length>0`) — lane bỏ cả 2, tôi đo: 0 drop · 0 rỗng-hoá. ③ **typo-noop**: key ẩn sai chính tả = `Set.has` false, module vẫn hiện, tsc vẫn xanh ⇒ phải assert từng key TỒN TẠI trong cây prod (12/12 OK; control-âm 3 key bịa đều MISS). ④ **MAJOR: comment mới nhồi 3 số-đếm, 1 số SAI ngay lúc land** — "28 leaf `Ct_`" (thật 42 lá/49 key, S155 thêm WfView/Approved/Deleted), số chép từ skill `permission-matrix` stale ⇒ đúng bệnh #84(4) "CẤM số-đếm trong comment". ⑤ **CLARIFY hệ-quả không ai khai**: prod có `Hrm/Off/Personal` `isVisible=false`, fe-user lọc `isVisible!==false` còn fe-admin KHÔNG đọc cờ đó ⇒ admin là lối vào CUỐI, ẩn nốt = 3 module mất menu ở CẢ 2 app. ⑥ display-only chứng 3 tầng: diff (grep `+` chỉ hit COMMENT) < kiến-trúc (`usePermission:15` đọc cây THÔ, chỉ 2 consumer) < curl prod 200×2 endpoint đã ẩn. Tag `[s167, thuoc-la-cay-prod, filter-moi-la-buoc-mot, typo-noop, so-dem-trong-comment]` **Evidence:** `runs/2026-07-31-S164-4gd-khkk-fanout/sub-reviewer-gate-k6.md`
- **[→ archive/2026-07.md verbatim ĐÃ VERIFY moved-not-cut 4/4 @S166-curate] S164/S165 gate K3 · S164 gate K1 · S162 cây-4-folder · S161-W2 KHKK-CRUD (digest):** tham-số-chết-vì-thiếu-tầng-UI (đo TẦNG-CUỐI ai GỬI) · sweep 2-cờ bất-đối-xứng · flake "N/0 tươi" phải khai SỐ LƯỢT · giá-trị lớn nhất GATE QUY-TRÌNH không · **ghost-policy** (grep policy, đừng suy từ "key đã vào All") · default-lấn-ngữ-nghĩa · im-lặng-về-độ-chính-xác-của-con-số ×3/diff · **#82 ngược chiều** (FE OR nhiều key LỎNG HƠN policy khớp-CHÍNH-XÁC-1-key tự chuốc 403) · hợp-đồng FEBE VỠ 6 điểm tsc+build+574-test XANH (2 lỗi CHE NHAU) so ROUTE+FIELD trên ĐĨA.
- **[→ archive/2026-07.md verbatim, verify moved 5/5 @S166-curate] S159-đợt5 · S161-W1 · S155-đợt2 · S145-4lane · S143 · S139 · S134b · S133 · S146/S147/S152-D2 (digest gộp):** chú-thích-mang-SỐ phải chạy phép đếm · cookie-cutter soi CẢ phần bản gốc đã CHẶN · `tsc`+`noUnusedLocals` > grep cho claim 'đã cắt' · comment 'bên kia lo' = ĐI ĐỌC BÊN KIA · grep bằng TOKEN-SONG-SINH · `hợp-đồng-đứt-2-bờ` · đổi-chiều-assert ≠ nới-assert · bất-biến chia-đôi 2-axis chỉ cross-cut sweep bắt · `bằng-chứng-tự-huỷ-sau-squash` · re-measure acceptance từ git HEAD + no-self-exempt · 'mọi nhánh set X' phải grep assignment-qua-BIẾN (#81) · `ExecuteDelete` ngoài transaction = mất dữ liệu · xanh-giả bắt bằng phép 2-thế-giới · 3 THƯỚC-HỎNG (md5 CRLF · `grep -c` citation-trap · `grep -iF` MSYS 0-hit im lặng).
> **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 @S161-curate] S160 review SPEC-BỘ KHKK:** review SPEC ≠ review CODE · seeder-grant kiểu insert = NO-OP 403 im lặng ⇒ acceptance đ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:** content-hash ≠ commit-SHA (hex strip/no-strip) · exact-token sweep miss 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 field cùng-cột share 1 mutation + echo sibling từ server-snapshot + `invalidate()` không await ⇒ lưu 2 ô liên-tiếp đè mất. Window mở SAU `isPending=false`, KHÔNG lúc in-flight. Catch: đếm field-cùng-cột share mutation + check invalidate awaited.
- **#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)** — mirror entity/Command cross-module (PE→Contract→Budget V2) hay focus data-shape mà MISS security guard. Luật: validate `aw.ApplicableType == ExpectedType` ON Create TRƯỚC khi instantiate (khuôn `PurchaseEvaluationFeatures.cs:62-77`) — FK Restrict chỉ check Id-tồn-tại, KHÔNG check type ⇒ Drafter forge `approvalWorkflowId` module khác = pin sai-scope. Re-verify `IsActive`+`IsUserSelectable` server-side. 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 @S126/@S134] S123·S124·S125·S129·S131 (digest):** follow-up phải GIỮ con-số source · re-derive từ raw (fencepost) · 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.
- **Digest S93→S117 + June-2026 (verbatim → `archive/2026-07.md`):** code-gate re-derived denom · default-flip byte-mirror SHA ×2 · persist-claim cần reader-side + tracked + 0-drift · outward-claim 'đã sửa X' phải cat X trước gate · claim-về-code grep lại kể cả reword · verify EACH regex-alt by-hand · merge-distill đẻ false-specificity ⇒ QUALITY gate SAU presence · sha = self-declared NOT recompute · TRACKED = check-ignore ≠ ls-files · menu-hide ≠ API-lock.
- **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).
- **[→ 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
-**NỢ CURATE @S166-K4b ĐÃ TRẢ @S166-K5** (23.4KB→~17KB): move VERBATIM 3 entry đã hẹn (K4b·K4a·vá-F-1) → `archive/2026-07.md` §`@S166-K5-curate`. Trình tự bài S102: **append archive TRƯỚC → probe 3/3 kèm control-âm → assert `line in arc` NGAY TRONG script cắt → mới cắt → hậu-kiểm L1=0/archive=1**. Bài mới: digest sinh bằng escape `\uXXXX` **đẻ chữ hỏng câm** (byte-count không bắt được) ⇒ **script sinh chữ phải ĐỌC LẠI bằng mắt**.
- Hook-cap **>17.1KB** (24.4KB read-limit, S109) → archive recent → L2 `archive/<period>.md` (append additive) + `_INDEX.md` pointer. Stale >3mo → remove.
- **Prev curates:** S166-K5 (probe 3/3) · S162 (2/2) · S145 · S140 · S134 · S128 · **S102 recovery: cut-not-moved ×5 `f229b07` ⇒ mọi 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 (07-25) — R1 ranh NEVER (on-behalf lead)
- **NEVER Edit/Write code-tree · NEVER commit · NEVER push** — vai = verdict-only; sửa là việc em-main/implementer. Khai thật 2 nấc: ranh commit/push/code-tree **chưa từng vỡ**; Write/Edit runtime CÓ cấp và dùng hợp lệ cho sub-file run-folder + diary-self (AS-10). "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-target-scoped]`
- **[→ archive/2026-07.md @S165-curate] S159 đợt-1 (07-29) diff pipeline — 7 FLAG:** rút TOÀN BỘ chuỗi hiển-thị MỚI từ diff rồi soi từng chuỗi = phép đo 100%-tiếng-Việt · 2 queryKey cùng resource = 2 ảnh-chụp khác thời-điểm · a11y nút TRÙNG tên đọc-được · bác-claim cũng phải có chứng.