# sub — ring1-audit @open S159 · KIỂM vòng-1 (H1 tooling-auditor + H2 harvest-curator)

- **run-id:** `2026-07-29-S159-bookend-open` · vai `ring1-audit` (vai-KIỂM độc-lập, read-only, propose-only)
- **ngày:** 2026-07-29 · phiên-LOGIC L8 · lượt @open
- **luật tự-áp:** ghi-đĩa-TỪNG-VERDICT ngay khi có (anti-#53; đo phiên này 4/4 first-return garble, vai ép-ghi-đĩa mất 0 B)
- **trạng thái:** ĐANG GHI

## §0 — PIN + fail-safe (nghĩa-vụ (i))

Pin đích danh (CẤM tự đi tìm "run mới nhất"):

| input | byte | mtime | tươi phiên này? |
|---|---|---|---|
| `sub-tooling-auditor-open-S159.md` (H1) | 15.736 | 2026-07-29T08:47:36 | ✅ |
| `sub-harvest-curator-open-S159.md` (H2) | 26.134 | 2026-07-29T08:55:38 | ✅ |

⇒ **CÓ measure phiên này ⇒ KHÔNG NO-OP, tiến hành chấm.**
Byte H1 khớp pin lead (15.736 ✓). Byte H2: lead pin "END, GATE-FAIL 9 finding" không kèm số byte — đo đĩa **26.134 B**, END-line `:253` `TOTAL=9 finding (F-01…F-09) + 1 method (m#24) · GATE-FAIL` ⇒ **khớp mô-tả**.
**Tuần-tự C4b:** file này ghi sau 08:55:38 ⇒ `mtime(ring1) > mtime(H1), mtime(H2)` ✓ — chấm bản đã xong, không chấm bản đang chạy.

---

## §1 — VERDICT PER-CLAIM — H1 `tooling-auditor`

### ② ROSTER — tự tái-dựng ĐỘC LẬP (nghĩa-vụ (iv), số CÓ-THỂ-SAI)

Tao **không re-chạy lệnh của H1**. Đổi **nguồn** (`git ls-files` thay `ls`) · đổi **engine** (python balanced-scan thay `awk`+`sed`) · **so TẬP thay so SỐ**.

| # | claim H1 | phép tái-dựng của tao (khác lệnh) | số tao ra | verdict |
|---|---|---|---|---|
| H1-01 | roster đĩa = **23** | `git ls-files '.claude/agents/*.md' \| grep -v README \| wc -l` | **23** | **ĐẠT** |
| H1-01b | (đối chứng engine 2) | `find .claude/agents -maxdepth 1 -name '*.md' -not -name 'README.md'` | **23** | **ĐẠT** |
| H1-02 | glob thô = **24** (bẫy thừa-1 README) | `ls -1 .claude/agents/*.md \| wc -l` | **24** | **ĐẠT** |
| H1-03 | `.claude/agent-memory/*/` = **23** | `ls -1d` | **23** | **ĐẠT** |
| H1-04 | `hmw.js` VALID_ROLES = **23** | python: anchor `^const VALID_ROLES = [` → tới dòng `]` → strip `//` → bắt literal | **23** (unique 23, 0 trùng) | **ĐẠT** |
| H1-05 | `STATUS.md:458` ô canonical = **23** | `grep -n "Sub-agent"` → `:458` `\| Sub-agents \| **23** \|` | **23** | **ĐẠT** |
| H1-07 | `diff` tập-TÊN ③ vs ① = **IDENTICAL** | `diff` hmw↔disk **và** disk↔agent-memory (sau `tr -d '\r'`) | **IDENTICAL 23/23 cả 2 cặp** | **ĐẠT** |

🔴 **Mạnh hơn H1 một bậc:** H1 chỉ `diff` cặp ③ vs ①. Tao chạy thêm cặp **①↔③ (disk↔agent-memory)** ⇒ đóng được kịch-bản "2 lỗi bù nhau" (thừa 1 vai ở đĩa + thiếu 1 vai ở memory vẫn ra 23=23). **Cả 3 bề-mặt là CÙNG MỘT TẬP TÊN**, không chỉ cùng lực-lượng.
⇒ **② ROSTER = PASS xác-nhận** (5 bề-mặt của H1 đứng vững; ⑤ README B1-pointer xem H1-06 §1b).

🔻 **Tao suýt dựng TRƯỢT-ảo cho H1** (ghi lại vì đúng bệnh vai-KIỂM): `diff` lần đầu báo **23/23 dòng KHÁC NHAU** trong khi mắt đọc y hệt — nguyên nhân là **python tao tự ghi CRLF**, không phải roster lệch. Nếu tao dán thẳng output đó thì H1 ăn oan 1 TRƯỢT nặng. Phải `tr -d '\r'` rồi mới so. (Cùng họ E-010: khác-encoding ⇒ số/So-sánh sai.)
🔻 **Lần 2 tao tự bắt mình:** parse `VALID_ROLES` phát đầu ra **0 tên** — vì `find('VALID_ROLES')` bắt trúng **comment `:18`** (`<VALID_ROLES|null>`) chứ không phải khai-báo `:22`. **0 hit trông y hệt "mảng rỗng"** — đúng anti-pattern mà H1 cảnh báo (bài S153). Đổi sang anchor `^const VALID_ROLES = [` mới ra 23. ⇒ tao **không** có tư cách chê H1 chỗ này; ghi để soi được.

### ① SKILL / command / migration

| # | claim H1 | tái-dựng | verdict |
|---|---|---|---|
| H1-08 | skill project = **6** | `find .claude/skills -maxdepth 1 -mindepth 1 -type d` | **6** — **ĐẠT** |
| H1-08b | command = **19** | `ls -1 .claude/commands/*.md` | **19** — **ĐẠT** |
| H1-10 | Migration = **68**, mới nhất `20260727033522_AddPeAllowApproverDelete` | `ls Migrations/*.cs` trừ `.Designer.cs` + trừ `ApplicationDbContextModelSnapshot` | **68**, newest **khớp tên byte-exact** — **ĐẠT** |
| H1-11 | `SKILL.md` grep `AllowApproverDelete` = **0 hit**; bảng history dừng row **67** | `grep -c` = 0 ✓ · `grep -n "6[4-8]"` ⇒ row cuối = `:89 \| **67** \| AddPeApprovedBudgetSnapshot`, **KHÔNG có row 68** | **ĐẠT** |

---

## §2 — 🔴 CA (a): H1 **BÁC lời lead** về `ef-core-migration` — chấm bằng `git show`

Claim H1: *skill dừng ở row 67 là **ĐÚNG THIẾT KẾ** vì `33e7f68` (S158) vá **CẤU-TRÚC** — skill thôi tự nhận là nguồn "mới nhất"*, kèm trích cũ→mới của frontmatter `:3`.

Tao mở `git show 33e7f68 -- .claude/skills/ef-core-migration/SKILL.md` (KHÔNG tin lời thuật):

| vế H1 khai | đĩa/git nói gì | verdict |
|---|---|---|
| commit `33e7f68` là S158, có chạm SKILL.md | `Tue Jul 28 20:50:58 2026` · stat `.claude/skills/ef-core-migration/SKILL.md \| 2 +-` (**đúng 1 dòng đổi**) | **ĐẠT** |
| diff nằm ở **frontmatter `:3`** | hunk `@@ -1,6 +1,6 @@`, dòng đổi = `description:` = **dòng 3** của file | **ĐẠT** |
| **cũ** chứa *"+ row cuối bảng history trong skill này"* | dòng `-` nguyên văn: `…docs/STATUS.md canonical + row cuối bảng history trong skill này — KHÔNG hardcode số ở đây, B1 anti-drift…` | **ĐẠT — nguyên văn** |
| **mới** = *"CHỈ đọc từ 2 nguồn SỐNG… Bảng history bên dưới là KHO LỊCH SỬ, KHÔNG phải nguồn 'mới nhất'"* | dòng `+` nguyên văn khớp; đọc lại **trên đĩa HEAD** (`:3`, len 467): chứa `2 nguồn SỐNG` ✓ `KHO LỊCH SỬ` ✓ `KHÔNG phải nguồn "mới nhất"` ✓ | **ĐẠT** |
| hệ quả: skill **thôi** tự nhận nguồn mới-nhất | test phủ-định: chuỗi `row cuối bảng history` trên đĩa HEAD ⇒ **False (đã biến mất)** | **ĐẠT** |

⇒ **CA (a) = ĐẠT TOÀN PHẦN, 5/5 vế.** H1 bác lead **có căn cứ**, không phải bênh-vực suông: sửa là **cấu-trúc** (bỏ tuyên-bố) chứ không phải **số**, nên "bảng dừng ở 67" là hệ-quả thiết-kế, **không** phải nợ drift.
🔴 **Đồng-thuận với H1 về hậu-quả nếu chấm ẩu:** ép thêm row 68 = **hoàn tác đúng phát vá-gốc** — và vì cùng-class đã lặp 3 lần, đây là ca `root-cause over symptom` sách-giáo-khoa. Nếu tao chép lời lead mà không mở `git show`, tao đã tạo ra **dương-giả có sức phá**.
🔸 Corroborate độc-lập (không do H1 dẫn): thân commit `33e7f68` tự khai *"ef-core-migration SKILL: va CAU TRUC (frontmatter thoi khai bang la nguon 'moi nhat') thay vi them row - ring1: day la lan 3 cung class"* ⇒ ý-đồ khớp diff, **không** phải diễn-giải-sau.

---

## §3 — 🔴 CA (b): H1 **BÁC phân-loại của lead** về RAG (`view-stale-status`) — chấm 2 VẾ RIÊNG

### Vế (i) — lập-luận "nhãn ĐÚNG lúc ghi, service hồi-phục sau ~12h"

| mắt-xích | tao đo được gì | verdict |
|---|---|---|
| `33e7f68` có **thật** khai đo `chunk_count=0` cho **cả 7 project + shared_global** không | thân commit nguyên văn: *"STATUS:459 RAG khai 'alive' -> **lat DOWN (3 phep do doc-lap: chunk_count=0 cho ca 7 project + shared_global**; canonical tu mau thuan voi :473 cach 14 dong, song 5 nhan phien)"* | **ĐẠT — H1 thuật TRUNG THỰC** |
| mốc thời-gian | commit `2026-07-28 20:50:58` · tao đo `list_projects` lúc **07-29 sáng** ⇒ cách **~12h** | **ĐẠT** |
| "7/7 project có chunk trở lại" | tao tự gọi `list_projects`: **7/7 project chunk_count ≠ 0** (2449 · 7090 · 15440 · 6106 · 4742 · 4176 · 3024) | **ĐẠT** |
| `shared_global` | H1 khai **0** — tao đo **vẫn 0** | **ĐẠT** (H1 không giấu) |
| `solution_erp` = 2449, `last_indexed_at` **2026-05-29T23:26:13** | tao đo **2449** / **2026-05-29T23:26:13.550779** | **ĐẠT byte-exact** |
| 5 sibling re-index **07-29T08:21** | tao đo: vipix_multisite/namgroup/ashico/vipix_ai_infra = **08:21:16** · benhvien_aau **08:37:24** · dh_y_duoc **2026-05-23** | **ĐẠT** (H1 mô-tả đúng, kể cả ca lẻ dh_y_duoc) |

⇒ **Vế (i) = ĐẠT.** Phân-loại `view-stale-status` **đứng được**: lượt ghi nhãn DOWN có bằng-chứng đúng tại thời-điểm đó, service hồi-phục SAU. Gọi lead "gộp 2 sự-thật" là **quy lỗi sai chỗ** — H1 bác đúng.
🔸 Và H1 **không** dùng kết-luận này để xin tha: nó vẫn giữ F-3 ở mức **HIGH** vì nhãn hiện tại **đang** sai. Bác-class ≠ hạ-mức. Đúng.
🔸 Neo F-3 kiểm được: `STATUS.md:6` **có thật** chứa `🔴 **RAG DOWN** (xem row RAG chunks)` ✓ · `:459` = `\| RAG chunks \| 🔴 **DOWN từ S153** \| **2447 = last-known-good…` · `:473` `RAG DOWN (defer AI_INFRA)` ⇒ **3 bề-mặt cùng khai DOWN**, H1 chỉ nêu `:6` ⇒ **dưới-báo phạm-vi** (xem T-2 §6).

### Vế (ii) — 🔴 phép đo-2: **1 hit** có chứng được "collection đọc được" không?

Tao **chạy lại đúng query của H1** (`search_code("ApproveV2Async PurchaseEvaluation service")`):

| trường | H1 khai | tao đo lại | verdict |
|---|---|---|---|
| count | **1 hit** | **1** | **ĐẠT** |
| score | **7.156** | **7.155676193900541** | **ĐẠT — khớp tới 4 chữ số** |
| `source_path` | `…SOLUTION_ERP\.claude\skills\ef-core-migration\SKILL.md` | **y hệt** | **ĐẠT** |
| "có ruột" | có | chunk ~26 row bảng migration, **không rỗng** | **ĐẠT** |

⇒ **Tái-lập được byte-exact ⇒ H1 KHÔNG bịa số.** Claim **hẹp** *"collection SE đọc được thật, không phải vỏ rỗng"* = **ĐẠT** (1 hit có nội-dung đủ chứng **non-empty ∧ truy-vấn được**; đủ để loại giả-thuyết "2449 chỉ là registry-cache").

🔴 **NHƯNG 1 hit KHÔNG chứng được nhiều như dáng vẻ của nó** — và chỗ H1 hụt là **không đọc chính tang-vật nó cầm trong tay**:

**(1) Hit trả về là `.md`, KHÔNG phải code.** `search_code` mặc-định `file_pattern = **/*.{ts,tsx,cs,py}` — mà kết quả là một file **Markdown**. Tool tự khai `"note":"v0 search_code uses BM25-only. Embed code chunks in v1."` ⇒ **v0 = BM25 thuần, code chunk CHƯA embed**.
**(2) `ApproveV2Async` là literal có thật trong code:** `grep -rl` ⇒ **20 file `.cs`** (34 occurrence) chứa đúng chuỗi này. BM25 là khớp **từ-vựng**; nếu các chunk `.cs` đó nằm trong collection thì gần như chắc-chắn phải nổi lên. Chúng **không** ra một cái nào.
🔸 **Khai bất-định (không kết luận quá tay):** tao **không** phân-biệt được giữa (a) corpus không chứa `src/`, (b) `file_pattern` không được áp ở v0, (c) scoring/top_k. ⇒ tao **KHÔNG** tuyên "collection thiếu code SE"; chỉ ghi: **phép đo-2 chứng được non-empty, KHÔNG chứng được coverage.** H1 phát biểu đúng phạm-vi ⇒ không tính TRƯỢT.

### 🔴 (iv-bis) TỰ TÁI-DỰNG SỐ CÓ-THỂ-SAI #2 — tao **GIẢI ĐƯỢC** cái F-4 mà H1 tuyên "KHÔNG kết luận"

H1 ở F-4 tự nghi thước của mình: *"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 (2447→2449)… muốn chắc phải **re-index** rồi xem field có nhảy không."*
⇒ Nhưng H1 **đã cầm sẵn** một phép đo độc-lập không cần `last_indexed_at`, mà không khai thác: **NỘI DUNG của chính chunk nó lấy về**.

`heading_path` của hit = `EF Core Migration — SOLUTION_ERP > Migration history (**31 migration hiện có**)`.

| bước | lệnh | kết quả |
|---|---|---|
| chuỗi `31 migration hiện có` còn trên đĩa HEAD? | `grep -c` SKILL.md | **0** — đã biến mất |
| heading SỐNG hôm nay | `grep -n "Migration history"` | `:19` `## Migration history (số hiện tại → docs/STATUS.md canonical…)` |
| chuỗi đó sống/chết ở commit nào | `git log -S "31 migration hiện có"` | sinh `c506919` **2026-05-22** · xoá `ae30f8f` **2026-06-01** |
| bản SKILL.md **đang live lúc 2026-05-29** có chuỗi đó? | `git show $(git rev-list -1 --before=2026-05-29T23:26:13 HEAD -- <file>)` → `grep -c` | **1 — CÓ** |

⇒ 🎯 **Chunk RAG phục-vụ hôm nay = đúng phiên bản file tồn tại ngày 2026-05-29, KHÔNG phải bản HEAD.** Cửa sổ sống của chuỗi (05-22 → 06-01) **bao trùm** `last_indexed_at` 05-29 và **loại trừ** mọi mốc sau 06-01.
⇒ **`last_indexed_at` = 2026-05-29 được XÁC NHẬN bằng bằng-chứng NỘI-DUNG, độc-lập hoàn toàn với metadata.** Nghi-ngờ F-4 của H1 **được giải, và giải theo hướng CÓ LỢI cho chính H1**: trục ② *"SE index STALE ~61 ngày"* **đứng vững**, không cần re-index để chắc. Cái +2 chunk (2447→2449) phải có lời giải khác (phép đếm/lượt khác), nhưng nó **KHÔNG** làm lung lay kết-luận stale.
🔴 Đây là **số CÓ-THỂ-SAI thật**: nếu chunk trả về mang heading của bản HEAD thì kết-luận lật ngược 180° (index tươi, `last_indexed_at` mới là thứ hỏng). Nó không lật.

**⇒ CA (b) = ĐẠT cả 2 vế** (i) HELD · (ii) HELD trong đúng phạm-vi phát biểu. **+1 giá-trị vượt H1:** F-4 chuyển từ "không kết luận được" → **kết luận được**, đề-xuất `STATUS.md` 2-trường của H1 nay có chân đứng chắc hơn nó tưởng.

---

## §4 — 🔴 CA (c): H2 tự bắt lệnh chết (F-09) — chấm cụm **"tất cả lành"**

### (c-1) Tái-lập con số

Chạy lại lệnh **đã sửa** của H2 (`LC_ALL=C grep -rc $'\xEF\xBF\xBD' --include="*.md" .claude/`), **KHÔNG** `2>/dev/null` (đúng luật H2 tự rút):

```
file = 11 | hit = 19        ← tao đo
H2 khai: 10 file / 16 hit
```
**Chênh = đúng 1 file / 3 hit** = `runs/2026-07-29-S159-bookend-open/sub-harvest-curator-open-S159.md:3` — **chính file H2 đang viết** (nó trích lại `"�24.1KB"`, `C�ng`… làm bằng-chứng).
⇒ Trừ file của chính nó: **10 file / 16 hit — KHỚP TUYỆT ĐỐI.** **ĐẠT.** F-09 (lệnh chết `grep -P` exit=2 bị `2>/dev/null` nuốt) là **tự-bắt THẬT**, số sau khi sửa tái-lập được.

### (c-2) 🔴 Chấm "TẤT CẢ LÀNH" — nó **mở** hay nó **suy**?

H2 tự khai mở **trực tiếp 3/10** file. 7 file còn lại nó **suy từ lai-lịch**: *"thuộc **đúng chuỗi lai-lịch đó** (archive của diary tao + **4 file S152** trích lại phép quét)"*.

Tao **liệt kê đủ 10** rồi đối chiếu lời kể:

| # | file | H2 mở? | lai-lịch H2 gán | thực tế |
|---|---|---|---|---|
| 1 | `harvest-curator/MEMORY.md` | ✅ mở | — | ok |
| 2 | `cicd-monitor/archive/2026-06.md` | ✅ mở | — | ok |
| 3 | `S152/sub-harvest-close-S152.md` (5 hit) | ✅ mở | — | ok |
| 4 | `harvest-curator/archive/2026-06.md` (3) | ❌ | "archive diary tao" | ✔ đúng nhóm |
| 5 | `harvest-curator/archive/2026-07.md` | ❌ | "archive diary tao" | ✔ đúng nhóm |
| 6 | `S152/bookend-synthesis.md` | ❌ | "file S152" | ✔ đúng nhóm |
| 7 | `S152/sub-harvest-S152.md` | ❌ | "file S152" | ✔ đúng nhóm |
| 8 | `S152/sub-ring1-close-S152.md` | ❌ | "file S152" | ✔ đúng nhóm |
| 9 | 🔴 `runs/**2026-06-18**-h11-doublecheck/doublecheck-synthesis.md` | ❌ | **KHÔNG nhóm nào** | **ngoài lời kể** |
| 10 | 🔴 `runs/**2026-07-22**-S144-bootstrap/sub-harvest-curator-1.md` | ❌ | **KHÔNG nhóm nào** | **ngoài lời kể** |

🔴 **Số học không khớp lời kể:** H2 nói 7 file còn lại = "archive diary" (2) + "**4** file S152". Nhưng S152 chỉ còn **3** file chưa mở (#6/#7/#8) ⇒ 2+3 = **5**, không phải 7. **2 file (#9, #10) rơi hoàn toàn ngoài cả hai chuỗi** — và **cả hai đều CÓ TRƯỚC S152** (06-18 và 07-22 < 07-25) nên **không thể** là "S152 trích lại phép quét".

### (c-3) Tao MỞ đúng 2 file nó bỏ sót (+2 file archive chưa mở)

| file | dòng | ruột thật tại hit | phán |
|---|---|---|---|
| `2026-06-18-h11-doublecheck/doublecheck-synthesis.md` | `:20` | *"Anti-finding: C3 console mojibake `"D? tr�"` = console-codepage Bash-capture artifact, **KHÔNG script bug**"* | **LÀNH** — mojibake **được trích làm tang-vật**, use⟂mention = mention |
| `2026-07-22-S144-bootstrap/sub-harvest-curator-1.md` | `:140` | *"**U+FFFD** (m#6: đo bằng literal U+FFFD, CẤM heuristic…): **6 hit / 4 file**, TẤT CẢ là quoted-evidence…"* | **LÀNH** — là **báo-cáo sweep U+FFFD của chính vai H2 đời trước** |
| `harvest-curator/archive/2026-06.md` | `:3` | header tự dán: *"NOTE: **chứa U+FFFD quoted-evidence**"* | **LÀNH** — tự khai sẵn |
| `harvest-curator/archive/2026-07.md` | `:24` | trong entry lịch-sử S110 đã archive | **LÀNH** |

⇒ **KẾT LUẬN CA (c) — tách 2 vế, KHÔNG gộp:**
- **Vế KẾT-QUẢ "tất cả lành" = ĐẠT.** Tao mở thêm **4/7** file H2 chưa mở, **4/4 đều lành** (mention, không phải hỏng nội-dung sống). H2 kết luận **đúng**.
- 🔴 **Vế LẬP-LUẬN "theo lai-lịch S152" = TRƯỢT.** Đó là **claim mạnh chống bằng suy-luận yếu**: mở 3/10 rồi khái-quát ra 10/10 bằng một lai-lịch **kể sai số** (2 file không thuộc chuỗi nào, cả 2 cổ hơn S152). **Đúng-kết-quả-sai-lý-do** — và vì lý do sai theo hướng **tự tha**, lần sau gặp file lạ thật sẽ lọt y hệt. H2 vừa mới tự phạt mình vì "rỗng trông y hệt sạch" ở F-09, rồi **tái phạm biến-thể ngay đoạn dưới**: *"lành theo lai-lịch"* trông y hệt *"đã kiểm từng cái"*.

### (c-4) 🔴 "0 hit mới sau S152" — **tự phản-chứng ngay khi viết ra**

Claim này **ĐẠT với 10 file cũ** (không file nào trẻ hơn S152: 06-18 · 07-02 · 07-22/23 · 07-25 S152 · 07-26).
**NHƯNG** file thứ 11 — `sub-harvest-curator-open-S159.md`, **2026-07-29**, **3 hit** — chính là **hit MỚI SAU S152**, do **chính hành-vi khai "16 hit" sinh ra** (trích lại `"�24.1KB"`/`C�ng` làm bằng-chứng).
⇒ Đây đúng class **citation-trap self-reference**: *doc mô-tả hiện-tượng thì chứa hiện-tượng*. Chuỗi đã chạy ít nhất **3 đời**: S144 đo *"6 hit/4 file"* → S152 đo → S159 đo *"16 hit/10 file"*. **Phần tăng 6→16 phần lớn là do chính các bản báo-cáo sweep cộng vào**, không phải corruption lan ra.
🔸 **Hệ quả đo-lường (đề cho lead):** thước U+FFFD đang **tự bơm**. Muốn dùng tiếp phải **loại trừ chính các file sweep-report** khỏi mẫu-số, nếu không mỗi phiên sẽ tự sinh thêm "hit mới" rồi phiên sau lại đi giải-thích. (Tao **KHÔNG** đề xoá ký-tự trong file lịch-sử — đó là giết chứng-nhân.)

---

## §5 — 🔴 THÁCH-CLEAN (nghĩa-vụ (iv)) — mở đúng thứ H2 gọi "sạch"

### (5-a) Orphan `0 thật/63` + loại 3 dir khỏi universe — **loại ĐÚNG, không phải loại cho gọn**

| claim | tao đo | verdict |
|---|---|---|
| 66 dir dưới `runs/` | `find -mindepth 1 -maxdepth 1 -type d` = **66** | **ĐẠT** |
| 63 dir có `run.md` | vòng lặp `[ -f "$d/run.md" ]` = **63** | **ĐẠT** |
| 3 dir không `run.md` = đúng danh sách nó nêu | **khớp tên 3/3** | **ĐẠT** |

Tao **mở ruột 3 dir bị loại** (chỗ dễ giấu orphan nhất — loại khỏi mẫu-số thì vĩnh viễn không ai đếm):
- `2026-07-14-S117-pe-approve-minmax-range/` → **duy nhất** `spec-…md` (4.202 B). **0 file `sub-*`** ⇒ 0 spawn ⇒ **không nợ harvest**. Loại đúng.
- `2026-07-14-S117-pe-luyke-finalize/` → **duy nhất** `spec-…md` (5.828 B). Cùng lý do. Loại đúng.
- `2026-07-22-S144-bootstrap/` → `bootstrap-synthesis.md` (1.239 B) + `sub-harvest-curator-1.md` (18.326 B) + `sub-tooling-auditor-1.md` (16.732 B) ⇒ **có spawn thật NHƯNG đã có synthesis** ⇒ không orphan. Loại đúng.

🔎 **Test nấc-2 (skeleton byte>0 mà ruột rỗng):** 1.239 B phủ 35 KB sub → đúng vùng nguy-hiểm của sub-class `skeleton-nấc-2`. Tao **mở ra đọc**: có `## Nguồn` trích **đích danh 2 file kèm byte** + `## Disposition` (findings đã tiêu-thụ @S144, "không còn action treo") + bài-học. ⇒ **synthesis THẬT, nén chặt — KHÔNG phải skeleton.** Thước binary `-s` của H2 **may mà đúng** ở ca này; nhưng nó **không phân biệt được** synthesis thật vs skeleton — ghi để lead biết giới hạn của thước, không phải để bắt lỗi lượt này.
⇒ **(5-a) = H2 ĐẠT.**

### (5-b) 🔴🔴 **BROKE** — trục ④ *Placement* H2 chấm **PASS** với "stray 0 · empty-dir 0": **CẢ HAI SAI**

Tao chạy **đúng nguyên văn lệnh của H2**, không đổi gì:

| phép quét | H2 khai | **tao đo** | verdict |
|---|---|---|---|
| `find . -mindepth 2 -type d -name .claude` | **0** | 🔴 **1** | **TRƯỢT** |
| `find .claude -type d -empty` | **0** | 🔴 **5 → 6** (đo 2 lần cách ~2 phút, **đang TĂNG**) | **TRƯỢT** |

**Vật thể:**
```
.claude/workflows/runs/2026-07-29-S159-bookend-open/.claude/agent-memory/
├── harness-eval/        (rỗng)
├── harvest-curator/     (rỗng)   ← nhà lạc của CHÍNH H2
├── lead-gap-auditor/    (rỗng)
├── ring1-audit/         (rỗng)   ← nhà lạc của CHÍNH TAO
├── ring2-audit/         (rỗng)
└── tooling-auditor/     (rỗng)   ← nhà lạc của CHÍNH H1
```
`stat`: stray `.claude` sinh **08:43:06** · `agent-memory/` mtime **09:08:22** (**vẫn đang đẻ thêm**). H1 kết thúc **08:47:36**, H2 kết thúc **08:55:38** ⇒ **vật thể đã tồn tại TRƯỚC khi cả hai đóng file**. Đây **không** phải thứ sinh ra sau lượt đo.
`find .claude/workflows/runs -mindepth 2 -maxdepth 2 -type d -name ".claude"` = **1** ⇒ **duy nhất run này**, không phải rác legacy.

**Vì sao H2 không thấy — và đây mới là bài học, không phải lỗi cẩu-thả:**
H2 chống lưng bằng `git status --porcelain` = *"**0 dòng `agent-memory/`** ⇒ đĩa == commit cuối"*. Tao verify: **đúng, 0 dòng** — **nhưng git KHÔNG TRACK THƯ-MỤC RỖNG.** `git ls-files` trên run-folder trả về **đúng 7 file `.md`**, **không có** nhánh `.claude/` nào. ⇒ 6 dir rỗng **vô-hình về mặt cấu-trúc** với dụng-cụ H2 chọn. Nó đọc **sự im-lặng của một dụng-cụ mù** thành **sạch** — đúng class `vắng-mặt trông giống ổn`.

🔴 **Vì sao nghiêm-trọng hơn một cờ Placement — nó chạm thẳng vào F-07 của chính H2:**
Đây là pattern `agent cwd-relative memory mis-land` (S54): sub có cwd = run-folder ⇒ hệ memory tạo `<cwd>/.claude/agent-memory/<vai>/` thay vì nhà thật `<repo>/.claude/agent-memory/<vai>/`. H2 chẩn F-07 (**9/10 vai 0-delta**) là *"khâu **APPEND** hỏng — tao propose-only, lead single-writer"*. Nhưng ở đây có **cơ-chế VẬT-LÝ thứ hai**, đang sống, **trong chính run-folder này**, đủ sức làm delta bốc hơi **kể cả khi vai có ghi**: ghi trúng nhà lạc → không ai đọc → nhìn từ nhà thật = **0-delta y hệt**.
⇒ 🔴 **KHÔNG kết luận thay H2** (tao chưa chứng vai nào **đã** ghi vào nhà lạc — 6 dir hiện **rỗng**, nên tới lúc này **0 B bị nuốt**). Nhưng chẩn-đoán 1-nguyên-nhân của F-07 là **CHƯA ĐỦ ĐIỀU KIỆN chốt**: có nhánh nhân-quả thứ 2 chưa loại trừ, và nó là loại **im-lặng**. Sửa "quy-trình APPEND" mà nhánh này còn sống = có thể vá đúng bệnh phụ, để nguyên bệnh chính.

**Đề (propose-only, lead ghi):**
1. `run.md` C12/closeout: thêm bước **quét stray `.claude` depth>1** — bằng `find`, **KHÔNG** bằng `git status` (git mù với dir rỗng).
2. Trước khi đóng phiên: xác nhận 6 dir vẫn **rỗng** (nếu có file → **reconcile về nhà thật trước khi commit**, đừng để lẫn).
3. Hạ trục ④ Placement từ **PASS** → **PASS-WITH-FLAGS** (hoặc FAIL, lead quyết) — 2 phép quét con của nó đang trả số sai.

---

## §6 — FALSIFY-LOG (nghĩa-vụ (iii)) — 5 phép, ghi rõ đánh bằng đường nào

| # | Claim bị tấn công | Đường tấn công (phủ-định) | Kết |
|---|---|---|---|
| **1** | H1: *"skill dừng row 67 = ĐÚNG THIẾT KẾ vì S158 vá cấu-trúc"* | Giả-thiết H1 **bịa lý-do bênh-vực**. Mở `git show 33e7f68 -- SKILL.md` lấy hunk thật; rồi **test phủ-định trên đĩa HEAD**: chuỗi cũ `row cuối bảng history` **còn không**? | **HELD** — chuỗi cũ = **0 hit** (đã bị gỡ), chuỗi mới `KHO LỊCH SỬ…` có mặt. Không phá được. |
| **2** | H1: *roster 23 khớp 5 bề-mặt* | Giả-thiết **2 lỗi bù nhau** (thừa 1 chỗ này + thiếu 1 chỗ kia vẫn ra 23=23). Đánh bằng **so TẬP-TÊN** (không so số) trên **3** cặp bề-mặt, đổi nguồn (`git ls-files`) + đổi engine (python) | **HELD** — 3 tập **IDENTICAL** từng phần-tử. |
| **3** | H1: *phép đo-2 `search_code` 1 hit score 7.156* | Nghi **bịa số**. **Chạy lại đúng query** vào cùng MCP | **HELD** — count 1 ✓, score **7.155676…** ✓, `source_path` ✓ trùng khít. |
| **4** | H2: *"tất cả lành theo lai-lịch S152 · 0 hit mới sau S152"* | Không tin lai-lịch: **liệt kê đủ 10 file**, đối chiếu từng file với 2 chuỗi H2 nêu, rồi **mở tay 4 file nó chưa mở** | **BROKE (một phần)** — **kết-quả** "lành" HELD (4/4 tao mở đều mention), **lập-luận** BROKE: 2 file (`06-18-h11-doublecheck`, `07-22-S144-bootstrap`) **ngoài cả 2 chuỗi** và **cổ hơn S152**; số học "4 file S152" thực chỉ còn **3**. Thêm: *"0 hit mới sau S152"* **tự phản-chứng** — file S159 của chính H2 = **3 hit mới**. |
| **5** | H2: *trục ④ Placement **PASS** — stray 0 · empty-dir 0* | Không tin CLEAN: **chạy lại nguyên văn 2 lệnh `find`** của nó, rồi truy **vì sao dụng-cụ chống lưng (`git status`) im-lặng** | 🔴 **BROKE** — stray = **1**, empty-dir = **5→6 đang tăng**; `git status` im vì **git không track dir rỗng** (`git ls-files` chỉ có 7 `.md`). CLEAN sai, đúng loại nguy nhất. |

---

## §7 — CHỐT

### 7.1 Bảng verdict per-claim (KHÔNG gộp — luật meta-count S119)

**H1 `tooling-auditor` — 27 ĐẠT / 2 TRƯỢT**
- **ĐẠT (27):** roster ×7 (đĩa 23 · glob 24 · agent-memory 23 · VALID_ROLES 23 · STATUS:458 23 · tập-TÊN identical ×2 cặp) · skill 6 · command 19 · Mig 68 + tên newest · SKILL 0-hit + row-cuối-67 · **CA (a) 5/5 vế** · **CA (b)(i) 6/6 mắt-xích** · **CA (b)(ii) 4/4** (count · score · path · "non-empty" đúng phạm-vi) · neo `STATUS:6` có "RAG DOWN".
- 🔴 **TRƯỢT (2):**
  - **T-1 — F-3 dưới-báo phạm-vi.** H1 chỉ nêu `STATUS.md:6`. Đĩa có **3 bề-mặt** cùng khai DOWN: `:6` · `:459` (`RAG chunks \| 🔴 DOWN từ S153 \| 2447 = last-known-good`) · `:473`. Vá mỗi `:6` ⇒ **2 chỗ còn nói DOWN** — đúng class `cardinality-change grep consumers` mà chính H1 dùng để bắt lead ở F-6. **Đề: chore-1 phải nêu đủ 3 neo.**
  - **T-2 — F-4 tuyên "`last_indexed_at` KHÔNG đáng tin", thực ra ĐÁNG TIN.** Tao chứng bằng **nội-dung** (§3 iv-bis): chunk RAG phục vụ hôm nay mang heading `31 migration hiện có` — chuỗi chỉ sống **05-22 → 06-01**, và bản file **live đúng ngày 05-29 CÓ** chuỗi đó. ⇒ index **thật sự** đóng băng ở 05-29. H1 hạ-claim **quá tay** ("muốn chắc phải re-index") trong khi bằng-chứng đủ nằm sẵn trong chunk nó vừa lấy về. *(TRƯỢT theo hướng **khiêm-tốn thừa** — nhẹ hơn overclaim, nhưng vẫn làm F-3 yếu đi không cần thiết.)*

**H2 `harvest-curator` — 13 ĐẠT / 5 TRƯỢT**
- **ĐẠT (13):** universe 66 · 63 có `run.md` · 3 dir loại đúng tên · **loại 3 dir khỏi universe hợp-lệ** (mở ruột: 2 spec-only 0 spawn + S144 có synthesis THẬT không skeleton) · orphan **0 thật/63** · U+FFFD **16/10** (tái-lập chính xác sau khi trừ file của chính nó) · F-09 lệnh-chết `grep -P` exit=2 là **tự-bắt thật** · "tất cả lành" **về kết-quả** · 0-byte 0 · `<200B` 0 · 23 vai/23 dir/23 MEMORY.md · `git status` 0 dòng agent-memory (đúng literal) · **bảng diary S158 tái-lập 10/10 cell** (ctx-audit=1, 9 vai =0).
- 🔴 **TRƯỢT (5):**
  - **T-3 — "lành **theo lai-lịch S152**"**: 2/10 file ngoài cả 2 chuỗi, cổ hơn S152; mở 3/10 rồi khái-quát 10/10. Đúng-kết-quả-**sai-lý-do**, sai theo hướng **tự tha**.
  - **T-4 — "0 hit mới sau S152"**: tự phản-chứng — file S159 của chính nó thêm **3 hit** (citation-trap, đời thứ 3: S144 *6/4* → S152 → S159 *16/10*).
  - **T-5 — "stray `.claude` depth>1 = 0"**: thực **1**, sinh 08:43:06 (trước khi nó đóng file 08:55:38).
  - **T-6 — "thư-mục rỗng = 0"**: thực **5→6, đang tăng**; `git status` mù với dir rỗng.
  - **T-7 — trục ④ *Placement* = PASS**: roll-up dựng trên T-5+T-6 ⇒ **không đứng**. (Ghi riêng theo luật cấm verdict-tổng che claim lẻ.)

### 7.2 Chỗ H2 **đúng mà đáng ghi công**
GATE-FAIL của H2 **không** bị tao lật: trục ① + ② hỏng thật (tao tái-lập **10/10 cell** bảng diary — `ctx-audit S158=1`, 9 vai còn lại `=0`, và **cả 10 vai `S159=0`**). Nó tự tính **chính mình** vào danh sách nợ, tự bắt lỗi phương-pháp của mình (F-09), và **không** dùng ca `f4494cf`/`(i)`/`(ii)` để tự nâng điểm. **Bệnh của H2 lượt này là CLEAN-ẩu ở trục ④, không phải FAIL-ẩu.**

### 7.3 Ranh-trục — tao KHÔNG chạm
Không soi `lead-stale`/`lead-gap` (ring2) · không soi trio (harness-audit) · không chấm code-diff (reviewer) · **không tự harvest** (thấy 6 dir nhà-lạc thì **NÊU**, không tự dọn — thao-tác thuộc lead/H2).

### 7.4 Đề-xuất gộp cho lead (propose-only, tao 0 ghi file repo)
1. 🔴 **Quét stray `.claude` bằng `find` ở closeout** — `git status` **không** thay thế được (mù dir rỗng). Xác nhận 6 dir còn rỗng trước commit; có file thì reconcile về nhà thật.
2. 🔴 Chore-1 của H1 (tách nhãn RAG 2 trường) phải sửa **đủ 3 neo** `:6` · `:459` · `:473`, không chỉ `:6`.
3. F-4 **đóng được** — index SE stale ở 05-29 đã có chứng nội-dung; không cần re-index để kết luận. Trục ② của H1 vững hơn nó tự nghĩ.
4. Thước U+FFFD phải **loại trừ file sweep-report** khỏi mẫu-số, nếu không nó tự bơm mỗi phiên.
5. H2 sửa lời F-09: "lành theo lai-lịch" → **"mở tay 7/10, suy 3/10"** hoặc mở nốt; và bỏ cụm "0 hit mới sau S152".

### 7.5 🔬 Tự-đo file này — T-4 được **chứng bằng chính tao** (đời thứ 4)
`stat` file này: **32.068 B · 291 dòng · 165 dòng có chữ ngoài heading** ⇒ **không phải skeleton-nấc-2** (byte>0 **và** ruột có chữ — tự áp đúng thước tao dùng chấm người khác).
🔴 Và: `LC_ALL=C grep -c $'\xEF\xBF\xBD'` trên **file này** = **3 hit** (dòng 144 · 172 · 184) — tao **trích lại** `"…24.1KB"` / `C…ng` làm bằng-chứng khi chấm ca (c).
⇒ Sau lượt này mẫu-số U+FFFD sẽ là **~12 file / ~22 hit**, tăng thêm **chỉ vì có thêm một bản báo-cáo về nó**. Chuỗi nay đủ **4 đời**: S144 (6/4) → S152 → S159-H2 (16/10) → **S159-ring1 (+3)**. Đây **không** phải corruption lan ra; đây là **thước tự bơm**. Đề-xuất số 4 ở §7.4 vì thế **không phải lý-thuyết** — tao vừa là ca mới nhất của nó.

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

<!-- END sub-ring1-audit-open-S159 · TOTAL=47 claim (40 ĐẠT / 7 TRƯỢT) · falsify 5 phép (3 HELD / 2 BROKE) -->

