# sub-reviewer-0 — SETUP-REVIEW đội STYLE 3 vai (commit 090ab1c, S176)

**Engine:** /fable-real · vai `reviewer` · chấm THIẾT KẾ đội sub-agent, KHÔNG phải review code sản phẩm.
**Dòng-1: `SETUP-REVIEW: SỬA-6`** — nền ĐỨNG VỮNG (production-làm-chuẩn đo bằng TREE + 3 địa-phận rời + trục STYLE ⟂ reviewer), KHÔNG BÁC; nhưng 6 điểm phải sửa, trong đó **SỬA-1 là lỗ nặng nhất: thước dispatch mù working-tree ⇒ đội có thể KHÔNG BAO GIỜ NỔ ở đúng use-case chính (review trước commit)**.

## Vật đã đọc thật (không suy)
- 3 persona: `front-end-reviewer-style.md` (122d) · `back-end-reviewer-style.md` (101d) · `database-reviewer-style.md` (97d)
- `hmw.js` :43 VALID_ROLES + :245 writeGuard + :161 WIDTH_CAP=20 · `agents/README.md` :56-79 + :190-192 · `docs/STATUS.md:476` · khuôn `reviewer.md`/`ring1-audit.md`/`ctx-verifier.md` · `run.md` (6 điểm lead tự nghi)
- Đo đĩa: `git show 090ab1c --stat` (6 file, +338/−3 khớp run.md) · `deploy.yml:20-27` paths-ignore · `git log` (revert thật `3f339c0`; wal "deploy VERIFIED" ab5e42a/4f327c3; HEAD ahead-2) · `ls .claude/agent-memory/` (23 dir — THIẾU 3 vai mới) · `ls .claude/agents/*.md`=27 (=26+README khớp canonical) · `measure-agent-memory.ps1:10` (enumerate theo DIR) · `governance-detectors.ps1:1076-1083` (roster động) · `spawn-model-audit.ps1:400-405` (disk-cross-check động) · `mfe-eval.ps1:243` (agents/*.md động) · `.editorconfig` KHÔNG tồn tại + CI 0 hit `dotnet format|eslint` · `fe-*/package.json` react `^19.2.5` vs root `CLAUDE.md` "React 18" · `BaseEntity.cs:5-9`+`AuditableEntity.cs:5-7` · `rules.md` heading thật `## 3. Frontend — React 19 + Vite 8 + TS 6` / `## 2. Backend — .NET 10` · anchor FE tồn tại ×2 app (`KhkkListPanel` · `PipelineTreePanel` · `PurchaseEvaluationsListPage`)

---

## (1) LUẬT LÕI CÓ RĂNG? — thước ĐÚNG VỀ HÌNH, SAI 1 CHỖ CHÍ MẠNG + thiếu 1 câu lùi-mốc

**Phần ĐÚNG:** đo bằng **TREE** của `origin/main` (không phải history) nên ca *revert* TỰ LÀNH — bằng chứng revert thật `3f339c0` ("REVERT cot da chen nham vao man PE"): sau revert, code sai KHÔNG còn trong tree ⇒ không bao giờ bị lấy làm chuẩn. **Lo-nghi "revert" của lead = lo hão vì thước là tree.**

**SỬA-1 (NẶNG NHẤT — đội có thể im lặng không bao giờ nổ):** cả 4 chỗ dùng ba-chấm `git diff --name-only origin/main...HEAD` (README:68 · fe:30 · be:27 · db:26). Ba-chấm chỉ thấy phần **ĐÃ COMMIT**; nó **MÙ working-tree + MÙ file untracked**. Mà đội này là gate **review TRƯỚC commit** (README:67 "MỖI LƯỢT REVIEW", khuôn `reviewer` = "pre-commit gate"). Lúc đó thay đổi chưa commit ⇒ lệnh trả **RỖNG** ⇒ tầng dispatch README:68 kết luận "diff không chạm" ⇒ **KHÔNG GỌI CON NÀO** — và vì không con nào được spawn, không có cả `SKIP-CO-KHAI` để lộ. Đội chết câm ở đúng ca nó sinh ra để bắt (thùng rác KHKK là file sửa CHƯA commit lúc đáng lẽ được soi). Hậu-quả nếu để nguyên: đội chỉ nổ khi lead lỡ commit trước review — tức "làm đi làm lại" y như cũ, thêm chi phí nuôi 3 persona.
**Câu chữ thay:** ở cả 4 chỗ, đổi phép đo phần-MỚI thành: *"phần MỚI = `git diff --name-only origin/main` (phủ đã-commit + đã-sửa-chưa-commit) **∪** `git status --porcelain` lọc `??` (file mới chưa track). Ba-chấm `...HEAD` CẤM dùng làm thước dispatch — nó mù working-tree."*

**SỬA-2 (vừa):** câu "mọi thứ CÒN LẠI trên origin/main = ĐÃ PRODUCTION = CHUẨN" (fe:31 · be:28 · db:27) **quá rộng ở 2 vế**:
- (a) `deploy.yml:20-27` paths-ignore: `docs/**` · `**/*.md` · `.claude/**`(skills/agent-memory/runs) · `scripts/**.md` — các path này trên main **CHƯA TỪNG deploy**. Trong 3 glob sản-phẩm của đội thì vô hại, nhưng câu chữ nên tự giới hạn: *"= CHUẨN **trong địa-phận glob của mày**"*.
- (b) **cửa sổ deploy-FAIL:** commit lên main mà CI fail ⇒ prod đứng ở bundle cũ; tip main lúc đó CHƯA chạy thật. Repo ĐÃ CÓ cơ-chế biết commit nào deploy thật — wal ghi `deploy VERIFIED` (ab5e42a, 4f327c3) + bundle-hash trong STATUS (Run #432/#426/#419, "lead tự re-curl KHỚP TỪNG BYTE") + `cicd-monitor` — nhưng persona KHÔNG nối vào. Thêm 1 câu: *"nếu wal/cicd của lần push gần nhất KHÔNG có `deploy VERIFIED` ⇒ lùi mốc chuẩn về commit VERIFIED gần nhất"*. Tần suất thấp (mỗi ship đều verify) ⇒ mức VỪA, nhưng 0 tốn kém để vá.

## (2) VẾ MIỄN-TRỪ — dấu-cao-su THẬT nếu để nguyên (SỬA-3)

Ba nguồn bằng-chứng (fe:49-52 · be:47 · db:43): lời anh trong prompt/`_context` `> anh:` · **commit message** · WAL. Vấn đề: **commit message + WAL đều do LEAD tự viết** — đúng người mà đội sinh ra để kèm. Lead lười chỉ cần viết `"anh yêu cầu bỏ banner"` vào commit message là vai thấy "bằng-chứng chỉ được ra" ⇒ không FLAG ⇒ đội thành dấu-cao-su đúng như lead tự nghi. Format report hiện chỉ đòi **CON TRỎ** (`bằng-chứng owner cho phép lệch: <có, trỏ đâu>` fe:108) — không đòi RUỘT.
**Câu chữ thay (khép vòng qua mắt owner):** *"bằng-chứng miễn-trừ PHẢI kèm **TRÍCH NGUYÊN VĂN lời anh ≤1 dòng** + con trỏ. Xếp hạng nguồn: lời anh trong prompt/`_context` `> anh:` (mạnh) > WAL entry có ngày (vừa — lead chép nhưng bền) > commit message (**yếu nhất — chỉ nhận khi chính nó chứa trích nguyên văn; câu 'theo yêu cầu anh' trống = KHÔNG TÍNH, vẫn FLAG**)."* Trích nguyên văn nằm trong report ⇒ anh đọc là tự bác được câu bịa — vòng kiểm khép bằng owner-visibility, không cần thêm vai.
Ghi nhận điểm THIẾT KẾ ĐÚNG sẵn có: default hướng-sai-về-phía-FLAG ("sai về phía hỏi thừa" fe:54) là đúng chiều. Tension nhỏ: đề bài nói "chính lượt này" nhưng nguồn WAL là xuyên-phiên — hướng lệch này chỉ đẻ FLAG thừa (an toàn), không đẻ lọt ⇒ note, không bắt sửa.

## (3) SCOPE 3 VAI — ranh BE⟂DB SẠCH; vùng mù CÓ nhưng phải KHAI (SỬA-5b)

- Ranh BE⟂DB (be:96 · db:90-92): ca "property Domain đặt tên xấu ⇒ cột DB xấu theo convention" = **double-flag cùng gốc** (chồng lấn lành, không phải lỗ). Loose-Guid (property ở Domain nhưng là quyết-định DB) — db:62 ĐÃ xử lý tường minh tiền-lệ loose-Guid. `DbInitializer` nằm `Persistence/**` ⇒ DB, db:63 nhận seed/backfill. **Không tìm thấy ca lưỡng-nghĩa vô chủ.**
- **Vùng mù THẬT #1 — đường nối FE↔BE:** trùng lặp/lệch tên CHÉO stack (DTO⟂type, route string, `MenuKeys.cs`⟂`menuKeys.ts`) — FE dừng ở `fe-*/src/**`, BE dừng ở `src/Backend/**` ⇒ style-seam không con nào soi. `reviewer` Cat-3 phủ trục AN NINH của seam (menuKeys mirror), không phủ trục STYLE. Ca châm ngòi (KHKK vs PE) nằm TRONG FE nên 3-vai khớp bài toán gốc — nhưng seam phải được KHAI là của `reviewer`/lead, không phải "đã có người lo".
- **Vùng mù THẬT #2 — ngoài cả 3 glob:** `tests/**` · `scripts/**` · `.gitea/workflows/**` · `docs/**` · `.claude/**` = 0 vai style. `tests/**` đáng nói nhất (test-specialist viết, reviewer Cat-5 đếm coverage chứ không soi khuôn).
- Bỏ `clean-code-reviewer-style`: quyết định ĐÚNG — trục clean-code không viết nổi câu scope-rời (chính run.md ghi lý-do), gộp vào từng con là cách duy nhất giữ luật scope-rời của roster. Không phải vùng mù MỚI: 4-con cũng không phủ seam/ngoài-glob.
**Fix:** +1 dòng vào README §RULE: *"Ngoài 3 glob (tests/ scripts/ docs/ .claude/ .gitea/) + đường nối FE↔BE: đội STYLE KHÔNG soi — lỗ CHỌN CHỦ ĐÍCH, seam thuộc `reviewer`/lead."* Lỗ được khai ≠ lỗ câm.

## (4) THÁCH-CLEAN — yếu hơn khuôn ring1 ở tính BẺ-ĐƯỢC (SỬA-4)

So khuôn: `ring1-audit.md:40-42` đòi (a) TỰ TÁI-DỰNG ≥1 số load-bearing, (b) mở artifact CỤ THỂ kiểm được bằng máy (mtime), (c) falsify-log HELD/BROKE ≥2. Đội STYLE: format LECH **có răng tốt** (bắt buộc neo bản-production đối-chiếu — mạnh); nhưng nhánh **DAT**: fe:111/be:90 chỉ đòi *"nêu đúng 1 khối/slice đã đi tìm và tìm thấy thật là khớp"* — **KHÔNG bắt neo `file:line`**, và **không có vai nào kiểm vòng này** (khác vòng H1/H2/H24/nén-ngủ đều có ring; nhưng đòi đẻ ring5 = quá tay — `reviewer` cũng không có ring, vòng review được kiểm bằng UAT/prod). db:85 MẠNH HƠN 2 con kia vì kèm số đếm 3-file rule (con số sai được).
**Bịa được không?** CÓ: vai trả `DAT + "đã đối chiếu KhkkListPanel với màn PE, khớp"` không cần mở file — không ai bắt được vì không có neo để mở lại, và lead (người muốn DAT để đi tiếp commit) không có động cơ đào.
**Câu chữ thay (áp cả 3, theo mẫu db):** *"dòng thách-CLEAN PHẢI có: cặp neo `file:line ⇄ file:line` (bản mới ⇄ bản production) + 1 chi-tiết khớp CỤ THỂ nhìn-thấy-được (tên prop/banner/badge/cột). Thiếu neo = coi như CHƯA SOI, lead từ chối nhận DAT."* Bẻ-được trong 30 giây mở 2 neo = đủ răng, chi phí 0.

## (5) WIRING — 3/5 lo của lead LÀ LO HÃO (script động tự phủ); 2 lỗ thật (SỬA-5)

ĐO TỪNG ĐƯỜNG:
- `hmw.js`: VALID_ROLES :43 ✓ · writeGuard :245 liệt đủ 3 tên trong nhánh read-only ✓ · comment :238 ✓.
- `spawn-model-audit.ps1:400-405`: **KHÔNG hardcode roster** — đếm đĩa `agents/*.md` trừ README (=26) so canonical STATUS (=26) ⇒ TỰ KHỚP. Lo hão.
- `governance-detectors.ps1:1076-1083`: enumerate roster **ĐỘNG từ đĩa** ⇒ 3 vai tự vào, sẽ hiện `inert(defined-not-run)` tới lần chạy đầu — đúng thiết kế. Lo hão.
- `mfe-eval.ps1:243`: enumerate `agents/*.md` động ⇒ tự phủ. Lo hão.
- **LỖ THẬT (a):** `ls .claude/agent-memory/` = **23 dir, THIẾU cả 3 vai mới**; mà `measure-agent-memory.ps1:10` enumerate **theo DIR tồn tại** ⇒ 3 vai **vô hình câm** trong đo/budget — đúng class "vắng-mặt trông giống ổn" (S146). Persona khai `memory: project` nhưng chỗ chứa chưa đẻ; harvest C4 đầu tiên của lead sẽ phải tự tạo. **Fix:** seed 3 dir + `MEMORY.md` mồi + chạy lại measure.
- **LỖ THẬT (b):** registry Agent-tool KHÔNG hot-reload ⇒ 3 vai **chưa spawn được tới khi restart CLI** — STATUS:476 khai nấc `verified-pending-restart` ĐÚNG, nhưng **README:67 ra lệnh "MỖI LƯỢT REVIEW gọi THÊM" không kèm nhãn hiệu-lực** ⇒ lead vâng lời ngay trong phiên này sẽ ăn spawn not-found (lỗi to, không câm — nhưng vẫn là kẽ giữa 2 doc). **Fix:** +"(hiệu-lực sau restart CLI — nấc xem STATUS)" vào README:67. Nhân tiện: decision-tree :87-155 chưa có nhánh style (RULE :67 có) — thêm 1 nhánh cho người tra bằng tree.
- **roster 26 > WIDTH_CAP 20** (hmw.js:161): hậu-quả CỤ THỂ = full-roster-sweep cắt 6 lane CUỐI theo thứ tự taskList, **LOUD-skip có log :165-169, không câm**; use-case thường (spawn theo diff 1-3 lane) không đụng trần. Pre-existing từ 23>20 @S153, số cap = quyền anh (O-7 treo). ⇒ phần "hậu quả mới" = lo hão; chỉ cần biết: nếu xếp 3 vai style CUỐI taskList sweep thì chúng là nhóm bị cắt.

## (6) DƯ-LƯỢNG + TỰ-MÂU-THUẪN — CÓ THẬT, đo được (SỬA-6)

- **"BE 0 máy style gác" sẽ tự lão-hoá:** hiện ĐÚNG (đo lại: `.editorconfig` 0 tồn tại, CI 0 hit `dotnet format|eslint`) nhưng claim bị **chép ra 4 site** (be:4 · be:55 · README:71 · STATUS:476) — cắm `.editorconfig` là 4 chỗ sai cùng lúc. Cơ-chế bắt hiện tại = ghi-chú tự giác be:59 ("nếu về sau... cập nhật lại mục này") — dựa trí nhớ người cắm máy = không răng; detector C2/B3 chỉ so SỐ derived-vs-canonical, không so claim-tồn-tại-file ⇒ KHÔNG bắt được. **Fix có răng — biến claim thành PHÉP ĐO tại mỗi lượt:** thêm vào be §1: *"TRƯỚC khi tin mục này, re-đo 10 giây: `ls .editorconfig; grep -rn 'dotnet format\|EnforceCodeStyleInBuild' .gitea/workflows/ src/Backend/*/*.csproj` — có hit ⇒ mục này HẾT HẠN, FLAG lead cập-nhật persona, KHÔNG tự gánh tiếp lớp cơ-học."* + rút README:71 thành câu trỏ ("hiện trạng máy đo tại persona từng con"), STATUS:476 giữ như lineage có ngày (hợp lệ).
- **Lead CÓ chép luật vào persona — vi phạm chính B1 mình viết cùng file:** db:32 ("PascalCase tiếng Anh, số nhiều") · db:34-35 (liệt đủ field `BaseEntity`/`AuditableEntity` — hiện khớp `BaseEntity.cs:5-9`/`AuditableEntity.cs:5-7` nhưng là bản chép sẽ drift khi entity mở rộng) · db:61 (PK `Id`/FK `{Entity}Id`) — trong khi db:71 CẤM chép quy-ước; be:63 (mũi tên 4-layer chép từ CLAUDE.md §Backend) trong khi be:74 CẤM; fe:4 chép **con số version** "React 19 + Vite 8 + TS 6" — class này ĐÃ CHỨNG drift ngay trong repo: root `CLAUDE.md` ghi "React 18" vs `package.json` `^19.2.5`; fe:67 (danh sách "máy BẮT" = chép config ESLint hiện tại). **Fix:** đổi các Ô-CHÉP thành CON-TRỎ + LỆNH-ĐO (vd db:34-35 → "mở `Domain/Common/BaseEntity.cs` + `AuditableEntity.cs` đọc field thật"; fe:4 bỏ digits version → "stack đọc `package.json`/`rules.md §3`"). Riêng tên 3-file migration lặp ở db:4+db:51+skill = rule bất biến EF, chấp nhận (note-only). Chú thích công bằng: các bảng "anh em đối chiếu" đa số là CON-TRỎ ("bảng cùng họ PE·Contract·KHKK") — đúng B1; chỉ các ô nêu trên là ruột-luật bị chép.

## Điểm nền GIỮ NGUYÊN (không khen suông — có đo)
- Trục STYLE(đồng-nhất) ⟂ reviewer(đúng-sai): tách thật, chạy song song không giẫm — đối chiếu 5-category của `reviewer.md` không có trục đồng-nhất-khuôn.
- Format LECH bắt buộc neo bản-production (fe:103-108) = răng chính của đội, mạnh hơn khuôn "mô tả lệch" thường gặp.
- "Bê HÌNH đừng bê LỜI KHAI" (fe:56, ca 'lũy kế' 0-hit) = bài học thật được codify — chống đúng lỗi copy-khuôn-thành-overclaim.
- SKIP-CO-KHAI + CẤM ĐẠT-ảo + fail-toward-FLAG: khớp chuẩn ring-family.
- Anchor FE persona trỏ đều TỒN TẠI trên đĩa (KhkkListPanel/PipelineTreePanel/PurchaseEvaluationsListPage ×2 app) — 0 con trỏ chết.

## Verdict cuối
`SETUP-REVIEW: SỬA-6` — SỬA-1 (thước dispatch mù working-tree, TRUNG-CAO, sửa 1 câu ×4 chỗ) · SỬA-2 (scoping "còn lại trên main" + câu lùi-mốc deploy-FAIL) · SỬA-3 (miễn-trừ phải TRÍCH NGUYÊN VĂN + hạ cấp commit-message) · SỬA-4 (thách-CLEAN bắt neo cặp file:line) · SỬA-5 (seed 3 dir agent-memory + re-measure; nhãn hiệu-lực-sau-restart vào README; tree-nhánh style) · SỬA-6 (gỡ 4-site "BE 0 máy" thành 1 canonical + lệnh re-đo per-spawn; đổi ô-chép-luật thành con-trỏ+lệnh-đo). Sau 6 sửa: thiết kế đạt để chạy thật.
