# H1 tooling-auditor — bookend @open S159 (phiên-LOGIC L8)

- run-id: `2026-07-29-S159-bookend-open`
- vai: tooling-auditor (H1 tooling/docs freshness) — read-only, propose-only
- ngày: 2026-07-29
- model self-report: claude-opus-5
- trạng thái file: ĐANG GHI (mỗi finding append ngay khi đo xong)

## ĐO ĐĨA — số thô (ghi trước, luận sau)

### ② roster — đếm phần-tử trên ĐĨA
```
$ ls -1 .claude/agents/*.md | grep -v README | wc -l
23
$ ls -1 .claude/agents/*.md | wc -l          # glob thô (kèm README) = bẫy thừa-1
24
```
⇒ roster đĩa = **23** (khớp số lead đưa, nhưng đo ĐỘC LẬP — không chép).
Còn phải đối chiếu 4 bề-mặt kia: `docs/STATUS.md` · `hmw.js` VALID_ROLES · `agents/README.md` · `.claude/agent-memory/` dir-count.

**Đối chiếu 5 bề-mặt — ĐẾM PHẦN-TỬ, không grep-theo-số (luật S143):**

| bề-mặt | phép đo | kết quả |
|---|---|---|
| ① đĩa `.claude/agents/*.md` trừ README | `ls \| grep -v README \| wc -l` | **23** |
| ② `.claude/agent-memory/*/` | `ls -1d \| wc -l` | **23** |
| ③ `hmw.js` VALID_ROLES | awk `/^const VALID_ROLES = \[/,/^\]/` + `sed 's#//.*##'` + đếm literal | **23** |
| ④ `docs/STATUS.md:458` (ô canonical §Sub-agents) | cột giữa row | **23** |
| ⑤ `.claude/agents/README.md:3` | B1-pointer, CỐ Ý 0 số | n/a — đúng thiết kế |

`diff` tập-TÊN ③ vs ① ⇒ **IDENTICAL**, 0 tên thừa/thiếu. Anchor `^\]` dùng đúng (bài S153: regex naive lấy `]` đầu tiên bị dấu `]` trong comment cắt ⇒ đếm hụt).

⇒ **② ROSTER = PASS** (23 khớp 5 bề-mặt, 0 vai thừa/idle/mất).

## ① SKILL

**Inventory (đếm phần-tử):** `.claude/skills/` = **6** skill-dir (contract-workflow · dependency-audit-erp · ef-core-migration · form-engine · iis-deploy-runbook · permission-matrix) + `README.md` · `~/.claude/skills/` = **23** standalone · `.claude/commands/*.md` = **19**.
Diff vs S153 baseline (6 / 23 / 19): skill 0-đổi · standalone 0-đổi · command 0-đổi.

> 🔻 **ĐÍNH CHÍNH tự-bắt (bản đầu dòng này ghi "command 18 → 19 (+1) — cần soi tên").** Số 18 là **baseline TRONG TRÍ NHỚ, chưa chạm đĩa**. Đo git: `git ls-tree .claude/commands/` = **19** tại `2448393`(07-24) · `5197ce2`(07-26/S153) · `33e7f68`(S158) · `bbc39be`(HEAD) ⇒ **19 đứng yên ≥5 ngày, KHÔNG có command mới, 0 ghost**. `comm` tập-TÊN S153-era vs nay = 0 thêm / 0 xoá. Tự tao vừa dính đúng anti-pattern #1 của mình (tin số trong đầu thay vì đo đĩa) — ghi lại thay vì lặng lẽ xoá.

### 🟢 KHÔNG-PHẢI-DRIFT — ca `ef-core-migration` × Mig 68 (lead nghi stale, ĐO RA NGƯỢC)

Đo đĩa: `Persistence/Migrations/*.cs` trừ `.Designer.cs` + trừ **đúng** `ApplicationDbContextModelSnapshot.cs` ⇒ **68** migration; cái mới nhất `20260727033522_AddPeAllowApproverDelete.cs`. Khớp `STATUS.md:6` "Mig **68**". ⇒ số canonical ĐÚNG.

`SKILL.md`: `grep -n "68\|AllowApproverDelete"` = **0 hit**; bảng history dừng ở row **67**. Nhìn thô = stale lần-4.
🔴 **Nhưng KHÔNG phải drift** — `33e7f68` (S158 closeout) đã vá **CẤU-TRÚC** thay vì thêm row, diff frontmatter `:3`:
> cũ: "…số hiện tại + mới nhất → docs/STATUS.md canonical **+ row cuối bảng history trong skill này**"
> mới: "…CHỈ đọc từ 2 nguồn SỐNG - docs/STATUS.md canonical HOẶC `ls …/Migrations/*.cs`. **Bảng history bên dưới là KHO LỊCH SỬ, KHÔNG phải nguồn 'mới nhất'**"

Skill **thôi tự nhận** là nguồn "mới nhất" ⇒ bảng dừng ở 67 là **đúng thiết kế**, không phải nợ. Đây đúng luật "vá bằng BỎ tuyên-bố, không ĐỔI số" (B1) và đúng anti-pattern #3 của tao (đừng vá dòng cho vừa detector).
⇒ **①-a PASS.** Nếu tao chép lời lead mà không đọc diff thì đây là **dương-giả**, và là loại tệ nhất: ép lead thêm row = **hoàn tác** đúng cái vừa sửa-gốc lần-3.

### F-1 (LOW) — `skills/README.md:20` nhãn "Updated" tụt 3 đời

Row `ef-core-migration` cột trạng-thái ghi `✅ Updated S117`. `git log -- .claude/skills/ef-core-migration/SKILL.md` = `1b8b065`(S117) → `1b85713`(S151) → `c2d01f0`(S152) → `33e7f68`(S158). ⇒ nhãn khai S117 trong khi đĩa có **3 lần sửa sau đó**, gồm chính lần vá-cấu-trúc S158. Nhãn-đời = derived, không phải số canonical ⇒ LOW, nhưng nó khiến người đọc tưởng skill chưa được sờ từ S117.

## ③ PLUGIN — báo ĐÚNG NẤC (installed → enabled → assigned → used)

Nguồn: `~/.claude/settings.json` (**user-global**, áp mọi project — KHÔNG phải `.claude/` của SE) + marketplace `~/.claude/plugins/marketplaces/claude-plugins-official/plugins`.

| nấc | phép đo | số |
|---|---|---|
| **available** (marketplace) | `ls …/claude-plugins-official/plugins \| wc -l` | **37** |
| **installed/registered** | `grep -c "@claude-plugins-official" settings.json` | **18** |
| **enabled** | `grep "…: true" \| wc -l` | **15** |
| **disabled** | `grep "…: false"` | **3** — `pr-review-toolkit` · `code-modernization` · `hookify` |
| **assigned** (vai nào dùng) | bảng doc `agents/README.md:214` | 18 registered / 15 enabled — **khớp** |
| **used** (auto-trigger phiên này) | KHÔNG đo được từ đĩa | **không khai** |

**Diff vs baseline `agents/README.md:214`** ("18 plugin registered (15 enabled / 3 disabled) … + ~23 standalone skill"): **0 THÊM / 0 ĐỔI / 0 XOÁ**. Tập 3 disabled cũng y nguyên.
⇒ **③ PASS, 0 new-allocation cần đề-xuất phiên này.**
🔴 Khai theo luật: tao chỉ chứng tới nấc **enabled** + **assigned-trong-doc**. Nấc **used** KHÔNG có bằng-chứng đĩa ⇒ CẤM đọc "15 enabled" thành "15 đang dùng" (anti-pattern #4).

**F-2 (INFORM) — `~/.claude/settings.json:11` `"model": "claude-opus-5[1m]"`.** Đây là vá của một nợ CŨ: S143 từng khai *"settings.json pin nay = `claude-opus-4-8[1m]` trong khi ô canonical §Sub-agents ghi Fable 5 ⇒ recipe hồi-phục thành no-op"*. Nay pin = `claude-opus-5[1m]`, khớp `STATUS.md:458` "lead **DEFAULT Opus 5 MAX**" ⇒ **nợ S143 ĐÃ ĐÓNG**, ghi để đóng sổ chứ không phải cờ mới. (`effortLevel: xhigh` `:37`.)

## ④ DOCS-FRESHNESS

### 🔴 F-3 (HIGH) — `docs/STATUS.md:6` "🔴 RAG DOWN" nay SAI. Nhưng **KHÔNG phải** class lead đoán.

Lead giả-thuyết: *"STATUS đang gộp service-chết với SE-không-được-re-index"*. Tao đo độc lập ⇒ **bác một nửa**.

**Phép đo 1 — `list_projects` (metadata):** service trả lời; `solution_erp` → `chunk_count` **2449**, `last_indexed_at` **2026-05-29T23:26:13**. 5 repo khác `last_indexed_at` **2026-07-29T08:21** (vipix_multisite 7090 · namgroup 6106 · ashico 4742 · vipix_ai_infra 4176) + benhvien_aau **08:37** 3024; dh_y_duoc 2026-05-23 15440; `shared_global` **0**.
**Phép đo 2 — query THẬT vào collection SE** (metadata một mình KHÔNG đủ — có thể là registry-cache): `search_code("ApproveV2Async PurchaseEvaluation service")` → **1 hit CÓ RUỘT**, score 7.156, `source_path` = `…\SOLUTION_ERP\.claude\skills\ef-core-migration\SKILL.md`. ⇒ collection SE **đọc được thật**, không phải vỏ rỗng.

**Xếp class — 🔴 KHÔNG phải "gộp 2 sự-thật", mà là `view-stale-status` (nhãn đúng lúc ghi, chết sau ~12h):**
`33e7f68` (S158, 07-28 20:50) khai đã lật DOWN bằng **3 phép đo độc lập, `chunk_count=0` cho CẢ 7 project + shared_global**. Vậy lúc viết, "DOWN" **ĐÚNG**. Đến giờ (07-29) 7/7 project có chunk trở lại ⇒ đây là **service hồi-phục sau khi nhãn được ghi**, không phải lead ghi sai. Bác cách gọi "STATUS gộp/nhầm" — nó quy lỗi cho lượt viết vốn có bằng-chứng đúng.

**Cái ĐÁNG lo mà nhãn nhị-phân DOWN/alive che mất — 2 trục ⟂ nhau:**
① *service-liveness* = **UP** (chứng: 2449 + query hit) · ② *index-freshness của SE* = **KÉM**: `last_indexed_at` 05-29 trong khi 5 sibling re-index 07-29 08:21 cùng một lượt. Lật thẳng DOWN→"alive" sẽ **chôn** trục ②.
⇒ **Đề-xuất (propose-only): tách 1 nhãn thành 2 trường** — `RAG service: UP (2449 chunk, query-verified S159)` · `SE index: STALE 61 ngày (05-29) — 5 sibling đã re-index 07-29`. KHÔNG đề-xuất viết lại văn-xuôi cho gọn detector (anti-pattern #3).

**F-4 (INFORM, kèm bất-định KHAI RÕ) — `last_indexed_at` có dấu hiệu KHÔNG đáng tin làm thước freshness.**
`STATUS.md:12` (S151, 07-25) ghi "RAG **2447**"; nay đo **2449** (+2). Nếu SE thật sự đứng im từ 2026-05-29 thì con số không có lý do nhúc nhích. ⇒ hoặc có ghi incremental mà `last_indexed_at` không cập-nhật, hoặc 2447 đo bằng phép khác. 🔴 Tao **KHÔNG kết luận** — chỉ cảnh báo: **chẩn-đoán "SE cũ 2 tháng" đang tựa vào đúng cái field vừa lộ mâu-thuẫn**. Muốn chắc phải re-index rồi xem field có nhảy không. (Re-index = lãnh-địa `cicd-monitor`, không phải tao.)

### F-5 (LOW) — `.claude/skills/ef-core-migration/SKILL.md:91` range tụt 2
Dòng Total ghi *"Mig 51-**66** đều AddColumn/index/data-only… không đổi số bảng"* + *"§16+ Mig 27-**66** chi tiết pending"*, trong khi canonical Mig = 68. Mig 67/68 **cũng** không đổi số bảng ⇒ **kết luận "89 bảng" VẪN ĐÚNG**, chỉ dải liệt-kê hụt. LOW, sửa lúc tiện; KHÔNG đáng mở lại file vừa vá-cấu-trúc S158.

### Các bề-mặt docs còn lại — SẠCH
- `CLAUDE.md` (root): số Mig/test/bảng đều **trỏ** `docs/STATUS.md` canonical, 0 hardcode ⇒ đúng B1, không thể drift. Row skill = 6, khớp đĩa.
- `.claude/agents/README.md`: `:3` B1-pointer **cố ý 0 số** · `:27`/`:242` liệt-kê **TÊN** (23 tên, khớp đĩa) · `:253` folder = "ĐO ĐĨA, KHÔNG enumerate". ⇒ PASS. (Còn nợ cosmetic tự-khai `:27`: "Diagram dưới = 7 core lane, ASCII chưa vẽ lại" — đã tự-flag từ trước, không tính finding mới.)
- `docs/STATUS.md:458` §Sub-agents = **23**, khớp 5 bề-mặt (mục ② trên).

### F-6 (MEDIUM) — `docs/HANDOFF.md:10` khai H6 là **"vá 1 phía"**, đĩa nói **3 site**

HANDOFF:10 nguyên văn: *"**H6** — §2.4 dòng 224 vẫn giữ "Dark-launch được bằng `IsVisible=0`" trong khi dòng 289-290 **cùng file** đã đo-đĩa bác cơ-chế đó ⇒ spec tự mâu thuẫn, **vá 1 phía**."*
Đo đĩa `runs/2026-07-28-S157-ke-hoach-ky-ket-hd/spec-ke-hoach-ky-ket-hd-28-07-2026.md`, `grep -n IsVisible` ⇒ **3 cụm ĐỘC LẬP**, không phải 1:
- `:225-228` §2.4 thượng-nguồn (bản sai gốc)
- `:298-299` §③ WAVE 1 (chỗ đo-đĩa bác cơ-chế)
- `:313-316` **WAVE 2** — *"bật `IsVisible=1`"*, cụm mà chính spec ghi là **suýt lọt**: *"Lọt vì grep `IsVisible` CÓ trả về dòng này nhưng nó nằm ở W2 và trông như bước dữ-liệu vô hại"*
⇒ chỉ-thị "vá 1 phía" **dưới-báo khối lượng**: vá 2 phía đầu mà bỏ W2 thì spec vẫn bảo người thực thi "bật `IsVisible=1`" cho một cơ-chế đã bị bác. Đây đúng class `cardinality-change grep consumers` (sửa write-site, sót read-site).
🔸 **Số dòng lead đưa (224/252/443) KHÔNG khớp đo của tao (225-228/298-299/313-316)** — vì file đang bị sửa trong working-tree, dòng trôi. **Kết luận "3 site" thì KHỚP**; tao neo bằng NỘI-DUNG, không neo số dòng (bài S158 mồi-ngầm neo-theo-số-dòng).
🔸 **Trạng thái hiện tại:** `git status` = ` M …/spec-…md` (**uncommitted**), và trong file đã có dấu vá `*(vá H6 @S159…)*` `:226` + `*(vá H5 @S159…)*` `:367` với `N ≥ 6` đã pin (`:367`) — tức **cả 2 lỗ HANDOFF:10 nêu đã được xử trong phiên này, chưa commit**. ⇒ HANDOFF:10 là **stale-in-flight**, CHƯA phải drift; thành drift THẬT nếu phiên đóng mà không cập-nhật. **CHORE @session-end.**

### F-7 (LOW/INFORM) — `docs/governance/README.md` mốc thử-nghiệm RAG đã hết hạn 36 ngày
File = *"RAG Governance — SOLUTION_ERP"*, last-commit **2026-06-02** (`72bbfa5`, 4.852 B). §Adoption state `:70` ghi *"Trial milestones ✅ 4-week **2026-05-26 → 2026-06-23**"* — **cửa sổ đóng 2026-06-23**, nay 07-29, không có dòng kết-luận/gia-hạn. `:77` còn treo *"⚠️ `eval/trial-state-lock.json` baseline still cites old number → AI_INFRA to reconcile"* (mở từ S41) và neo Qdrant **2.406** trong khi đo nay **2449**.
🔸 **KHÔNG flag "README không index 6 file mới trong `docs/governance/`"** — tao đã định flag rồi tự bác: file này là **doc chuyên-đề RAG + delegation-stub**, chưa bao giờ tự nhận là mục-lục thư-mục ⇒ bắt nó làm việc nó không nhận = dương-giả (anti-pattern #3).
🔸 Lane: RAG corpus/eval thuộc **AI_INFRA + cicd-monitor**, KHÔNG phải tao ⇒ chỉ INFORM, không đề-xuất hành-động kỹ-thuật.

---

## 📤 CHỐT — bảng 4 mặt

| mặt | trạng-thái | cần-update |
|---|---|---|
| ① skill | **PASS** — 6 project + 23 standalone + 19 command, 0 THÊM/ĐỔI/XÓA vs S153 | F-1 nhãn README:20 · F-5 range `:91` (đều LOW) |
| ② vai sub-agent | **PASS** — 23 khớp **5 bề-mặt**, tập-TÊN IDENTICAL, 0 thừa/idle/drift | — |
| ③ plugin | **PASS** — 37 available / 18 installed / 15 enabled / 3 disabled / assigned-khớp-doc; `used` KHÔNG khai | 0 new-alloc |
| ④ docs | **PASS_WITH_FLAGS** | 🔴 **F-3 STATUS:6** · F-6 HANDOFF:10 · F-4/F-7 INFORM |

**DIFF vs phiên trước (S158):** THÊM 0 skill/vai/plugin/command · ĐỔI: `settings.json` model pin → `claude-opus-5[1m]` (đóng nợ S143, F-2) · XÓA 0 · STALE MỚI: `STATUS:6` "RAG DOWN" (service hồi-phục sau S158) + `HANDOFF:10` (việc đã làm, chưa phản-ánh).

**Chore đề-xuất cho em main (propose-only, KHÔNG tự ghi):**
1. 🔴 `STATUS.md:6` — **tách 1 nhãn RAG thành 2 trường** (service UP 2449 query-verified ⟂ SE index STALE 61 ngày vs 5 sibling 07-29). ĐỪNG lật thẳng DOWN→alive: chôn mất trục ②.
2. `HANDOFF.md:10` — sau khi commit spec, hạ 2 mục H5/H6 khỏi NEXT-em; sửa "vá 1 phía" → **3 site** kẻo phiên sau lặp lại thiếu W2.
3. F-1 `skills/README.md:20` đổi nhãn `Updated S117` → trỏ git (hoặc bỏ nhãn-đời, theo B1 "vá bằng BỎ số").
4. F-5 `ef-core-migration/SKILL.md:91` dải `51-66` → `51-68` (kết luận 89 bảng KHÔNG đổi) — gộp vào lần sửa kế, đừng mở file riêng.

**2 lần tao TỰ BÁC mình / bác lead (ghi để soi được):**
- ①-a: bác giả-thuyết "skill ef-core stale thiếu Mig 68" — S158 đã vá **cấu-trúc**, bảng dừng ở 67 là **đúng thiết kế**. Ép thêm row = hoàn-tác đúng phát sửa-gốc lần-3.
- ③/command: tự bác con số "+1 command" của chính mình — 19 đứng yên ≥5 ngày.
- F-3: bác **class** lead gán ("gộp 2 sự-thật") → thật ra `view-stale-status` do service hồi-phục SAU khi ghi nhãn; lead ghi DOWN lúc đó là **có bằng-chứng đúng**.

🔒 Read-only · propose-only · 0 file repo bị sửa bởi vai này (chỉ ghi file run của mình) · KHÔNG `store_memory` · KHÔNG chạm harvest-memory (H2).

<!-- END sub-tooling-auditor-open-S159 · TOTAL=7 finding -->
