# spec — adap đợt-11 (10 broadcast AI_INFRA 2026-07-18 → 07-21)

> **Run:** `2026-07-22-S144-adap-dot-11` · **Phiên:** S144 · **Lead:** Opus 4.8 · **HMW-mode ON**
> **Nguồn:** 10 thư `broadcasts/inbox/` — verify 2 tuyến **10/10 whole-file** + **10/10 `stamp_verify.py` exit 0**
> **Engine:** `/fable-clone investigator-codebase` 5-lane (`wf_491c05a8-6dc`) — **2/5 lane sống**, 3 lane chết vì `maxTurns:20`; lead đọc bù 6 thư trực tiếp ⇒ **phủ 10/10**
> **Pipeline H21:** engine propose → **lead verify + ghi (file này)** → reviewer chấm → worker thực-thi theo spec (bơm qua args)

---

## ① TÍNH-NĂNG / ĐỀ-BÀI

Áp 10 broadcast đợt-11 vào SOLUTION_ERP. Nội dung chia **4 hạng ràng buộc** (phân loại lấy từ chính dấu hiệu văn bản, không suy diễn):

| Hạng | Thư | Neo dấu hiệu |
|---|---|---|
| **BINDING-floor** | `spawn-label` (4 khoản) | `:22` *"Khung sàn (function-floor — 4 khoản bắt buộc)"* |
| **BINDING-floor** | `harness-dong-du-vong` (4 khoản) | `:42` *"Khung sàn (function-floor — 4 khoản)"* |
| **BINDING-floor** | `depth-axis` (4 khoản) | `:38`; điều-kiện `:20` *"Áp cho dự-án nào có ensemble đa-agent/đa-lăng-kính"* → **SE QUALIFY** |
| **BINDING-mixed** | `goi-chot-nam-khoan` — **khoản 3 + 4** binding; khoản 1/2/5 = quyết-định nội-bộ hub + *"floor chuyển được"* | `:44-45`, `:52` vs `:29`, `:37`, `:59` |
| **KHUYẾN NGHỊ** | `eval-quality` · `auto-toan-vong` · `3-khoan` | `:13` *"Khung = sàn chức năng"* · `:43-47` · `:15` *"FYI + khung tự-áp"* |
| **GHI NHẬN** | `cost-lens` · `depth-cost` · `hub-tu-danh-gia` | `:50` · `:63` *"KHÔNG floor mới"* · `:62` *"điểm số và findings là của hub, không áp"* |

### 🔴 Phát hiện lật tiền-đề (phải đọc trước khi làm)

**(1) 0/12 mục treo của SE có đáp án TRỰC TIẾP trong 10 thư — nhưng phần lớn KHÔNG PHẢI NỢ.**
Đây là lỗi **phân loại** của SE, không phải hub im lặng:

| Nhóm | Số mục | Thực chất |
|---|---|---|
| Product-scope | 5 (UAT S133 · UAT S134 · D1 · VC-1/2/3 · close-sweep) | `grep UAT\|lũy kế\|phiếu\|migration` trên 10 thư = **0 hit**. Hub **KHÔNG BAO GIỜ** trả lời. Chờ **owner**. |
| Owner-quyết-SỐ | 3 (`pull_warn_days` · `session_ctx_kb` · hook-vs-budget-cap) | Hub nói **≥3 lần**: `eval:55` *"đừng chép số hub làm chuẩn"* · `auto:19` *"núm-số ngân sách vẫn thuộc chủ dự án"* · `eval:24` *"AI không tự quyết hai cột sau"*. ⇒ SE để trống = **TUÂN THỦ**. |
| Đã có đáp án `[ngoài-10]` | 3 | `58e28bae` (thư đã kéo đợt trước) |
| Còn nợ thật | 1 | ratify ranh `refine ⟂ lead-omission` |

🔴 **Hệ quả vận hành:** bảng "chờ" của SE phải **tách 2 cột chủ-thể** (chờ-owner ⟂ chờ-hub). Gộp chung tạo kỳ vọng sai — 5 mục sẽ nằm đó vĩnh viễn.

**(2) `hmw.js:225` = lỗ ĐANG CHẢY MÁU, và nó vừa cắn CHÍNH RUN NÀY.**
`return results.filter(Boolean)` — lane chết runtime → `null` → **nuốt lặng**. Đối chiếu `depth-cost:53` *"Thử-rồi-chết ≠ chạy-rồi-sạch… tầng tổng-hợp sẽ viết 'tầng-2 không thêm gì' = củng-cố verdict bằng một tầng-2 không tồn tại"*.
**Bằng chứng sống hôm nay:** 3/5 lane chết, lead nhận mảng 2 phần tử **không tín hiệu chết**. Lead chỉ biết nhờ khối `<failures>` của **harness**, KHÔNG nhờ `hmw.js`. Falsifier `depth-cost:59` hỏi *"tầng chết thì tầng sau thấy 'chết' hay 'sạch'?"* → **SE trả lời: thấy SẠCH.**

**(3) SE đang ĐI TRƯỚC hub đúng một khoản** — `eval:31` *"Bộ kiểm-tra-đặc-tả của hub có 17/18 check không có positive-control"*; SE đã fault-inject 2 chiều nhiều đợt (13/13 @S138 · 7 ca @S143). Đây là chất liệu báo nấc **bằng SỐ**.

**(4) Bẫy over-apply khoản 2 gói-chốt.** `goi-chot:37` retire resume **chỉ cho mục-đích giữ-model/giữ-context**; *"hội-thoại tiếp-diễn trong cùng lượt làm việc"* **vẫn hợp lệ** ⇒ path-2 `SendMessage-resume` cứu #53 **KHÔNG bị retire**. Áp sai = mất lưới #53 (đã dùng 2 lần thành công hôm nay).

---

## ② CÁCH IMPLEMENT

### P0 — lỗ SỐNG (làm trước, có repro hôm nay)

**P0-1. `hmw.js` — lane chết phải KÊU, không được nuốt.**
- Thay `return results.filter(Boolean)` bằng: giữ nguyên mảng có `null`, **đếm** `died = results.filter(r => !r).length`; `died > 0` → `log()` **LOUD** dạng `hmw: 🔴 <died>/<total> lane CHẾT (null) — KHÔNG phải "sạch"` + trả kèm marker để P3 thấy.
- 🔴 **CẤM** sửa thành `throw` — `hmw.js:124-125` đã tự khai đúng: *"per-lane throw có thể bị nuốt thành null = STOP-SILENT, tệ hơn"*.
- **Neo lineage:** ghi lý do tại chỗ wire (khuôn `auto:35` — giữ vết, thêm chú thích có ngày + chủ-ký).

**P0-2. `maxTurns` vs khối lượng lane — chống tái diễn.**
- Nguyên nhân đo được: `investigator-codebase` `maxTurns: 20`; lane sống dùng 21/23 tool-use, lane chết dùng 28/34/35 ⇒ **cháy lượt khi đang đọc, chưa tới bước ghi**.
- 🔴 Fix **KHÔNG** phải nâng `maxTurns` (sửa frontmatter cần restart). Fix = **kỷ luật đóng gói lane**: ≤3 file/lane + **ép ghi khung rỗng ở lượt đầu** rồi append, thay vì dặn "ghi sớm".
- Ghi thành luật trong `.claude/commands/fable-clone.md` (mục mới: *"đóng gói lane theo trần lượt"*).

### P1 — BINDING floor (bắt buộc adopt)

**P1-1. Spawn-label 4 khoản** (`spawn-label:22-27`)
- Khuôn SE (form tự quyết, function là sàn): `{Vòng-N|Core|Gate|WF} {vai} {pha/wave} s<N>` — vd `Vòng-3 harness-eval w1 @start s144`.
- Áp **MỌI** kênh spawn: `Agent` tool `description`, `hmw` `label`, monitor 2-đầu-phiên, cổng review.
- Áp **từ phiên kế** (`:51`); spawn trước đó giữ nguyên làm vết, **KHÔNG sửa lùi** (`:43` khuôn hub).
- 🔴 SE hiện **FAIL rõ**: label phiên này (`"Probe harness-eval alive"`, `"H1 tooling-freshness re-report"`) thiếu pha + mã phiên.

**P1-2. Đóng đủ vòng — mỗi vòng-ĐO có vai-KIỂM** (`harness-dong-du-vong:42-47`)
- Trạng thái SE: **chỉ vòng-3 (trio) có con KIỂM**. Vòng tooling/harvest (H1+H2), vòng soi-lead (2 vai H24), vòng nén-ngủ = **0 con soi**.
- 🔴 **Hình thức tự quyết** (`:51` *"gộp hay tách audit (1 con kiểm nhiều vòng hay mỗi vòng 1 con)"*) ⇒ SE **KHÔNG cần đẻ 3 vai mới**. Đề xuất: **1 vai `harness-audit` mở rộng phạm vi** sang cả 3 vòng còn lại (rẻ hơn, khớp `:51`).
- Bắt buộc kèm **thách-CLEAN** (`:44`): vòng nào báo sạch phải re-check mẫu ≥1 lens.
- Khoản ① *"có thể adopt dần từng vòng — báo nấc theo vòng"* (`:59`) ⇒ **làm dần được, không phải all-or-nothing**.

**P1-3. Eval 2 phía — thêm phía DÙNG** (`harness-dong-du-vong:47`)
- SE hiện chỉ đo **presence** (MFE coverage/FIT). Thiếu **use**: cross-session, evidence-based.
- Nhãn bắt buộc 3 loại: `APPLIED` · `DORMANT` (**≠ MISS**) · chờ judge.
- `%` phải mang caveat **NẰM TRONG payload**: *"% = FLOOR theo evidence, không phải ceiling"*.
- **negative-control BẮT BUỘC** trong test (bơm id giả → phải 0-hit; trả APPLIED = matcher rác = test đỏ).

**P1-4. Gói-chốt khoản 4 — cửa-duyệt lời-hứa-máy** (`goi-chot:52`, hub chấm *"áp cho MỌI dự-án"*)
- LUẬT: câu dạng *"máy sẽ chặn/quét/bắt X"* / *"detector đảm-nhiệm Y"* ⇒ **BẮT BUỘC existence-proof tại chỗ** {đường-dẫn máy + lệnh chạy được + test/positive-control}. Thiếu mảnh nào → **phải viết dạng dự-định**. **Cấm viết dạng đang-có.**
- Việc: sweep doc governance SE tìm câu hứa-máy chưa có proof → viết lại 1 trong 2 dạng.
- Reviewer hỏi đúng 1 câu: *"mã nào làm việc đó?"*

**P1-5. Gói-chốt khoản 3 — điểm dừng phải RẺ** (`goi-chot:44-46`, ràng buộc **thiết-kế CỨNG**)
- *"bất kỳ van/gate/phép-đo nào về sau cũng KHÔNG ĐƯỢC chặn hoặc làm chậm các cửa dừng–nối–checkpoint"*.
- Việc: **audit `/pause` + `/tiep` + `/session-end`** — bước nặng (spawn agent · đo lớn · quét rộng) nằm trong đường pause = **vi phạm ranh** → dời về closeout.
- `goi-chot:74` *"Đo wall-clock một lần"*.
- 🔴 **Đè lên carry #7 và NEXT#3**: mọi hardening SE định thêm vào `/pause`–`/tiep` (kể cả hook chặn sub-write) phải qua câu hỏi *"có làm điểm dừng đắt lên không"* **TRƯỚC** khi bàn giá trị.

### P2 — BINDING-conditional (SE có ensemble ⇒ áp)

**P2-1. depth-axis 4 khoản** (`depth-axis:38-43`) — điểm sàn adopt `:55` = **có trục sâu bật-được + escape width-only**.
- F1 owner-gated + **clamp trần cứng** + assert tổng-lượt ≤ trần. 🔴 SE hiện `hmw.js:114-117` *"KHÔNG cap cứng (soft notice only)"* ⇒ **FAIL**.
- F2 đào điểm-nóng KHÔNG đào-tất; worker tầng-2 **KHÔNG** tổng-hợp.
- F3 con **TƯƠI** + prompt-floor *"tầng-1 là VẬT-LIỆU không phải đáp-án; đồng-ý-lại = 0 điểm"*. 🔴 SE hiện refute do **em-main** làm (đã đọc tầng-1) = **dính mỏ-neo**.
- F4 **cận-ngân-sách LOUD** (bỏ đào + báo RÕ, không lặng-thầm).
- Tiên quyết: `depth-cost:54` *"Phát-hiện chưa-qua-kiểm không được quyền đè"* · `:55` *"con thử-phá tầng-2 phải THẤY vòng-1"*.
- 🔴 Ép cơ học: `hmw.js` `parallel()` **không tuần-tự-hoá** ⇒ tầng-2 = **invocation hmw THỨ HAI** (cùng bài trio S141).

**P2-2. Bảng cost re-ground** (`agents/README.md:249-257`)
- Đóng băng thời **7 sub-agent**, roster nay **17**; đơn-vị *"Effective tokens billed (after caching)"* = **đơn-vị THỨ BA**, không so được hub ⇒ falsifier `depth-cost:59` **CHƯA ĐO ĐƯỢC**.
- Việc: đo lại theo roster hiện hành + khai rõ đơn-vị + thêm cột *"đốt đơn-vị NÀO"* (`cost-lens:28`).

### P3 — khuyến nghị giá trị cao

**P3-1. Eval-của-eval, khung 4 câu** (`eval:15-24`) — áp cho **TỪNG thước** của SE (~10 script/detector):
(1) đã bắt lỗi THẬT chưa (trích dòng sổ)? · (2) đo **KẾT QUẢ** hay đếm **HOẠT ĐỘNG**? · (3) có **tự nói chuyện với mình** không (4 dạng: token-hoá-thạch · đếm-chính-dòng-định-nghĩa · nhãn-hứa-không-ép · chú-thích-tự-mâu-thuẫn)? · (4) bỏ thì **lỗi nào lọt**?
- Verdict `{GIỮ/SỬA/BỎ/THÊM}` + thẩm quyền `{AI-tự-sửa · owner-quyết-SỐ · owner-quyết-LUẬT}`.
- Gậy phân loại quý cho close-sweep: `eval:22` **dormant-đúng-thiết-kế** (máy báo khói) ⟂ **thừa-thật** (cấu trúc không thể kêu).

**P3-2. Distill trigger = ĐẾM VẬT THẬT, bỏ ngày-lịch** (`auto:21-27`)
- 🔴 SE hiện dùng **sleep-check 7 NGÀY** = đúng proxy giả hub vừa bác, **và trái chính mark Active-High `RC-…10-29-11`** của SE (age = false-proxy).
- Đổi sang đếm shard chưa-gist. Tham số hub (đính chính `3-khoan:47-51`): `min_pending_shards: 1` = **kích hoạt** · `bulk_note_shards: 10` = **báo-to** — **đếm SỐ FILE chưa-nén, KHÔNG phải số agent** (hub tự khai đã đọc nhầm 1 lần).
- 🔴 **Số là của owner** — SE đặt số riêng, không chép.

**P3-3. discoverability-home** (`3-khoan:31-41`)
- Phân biệt **implement-home** (máy chạy ở đâu) ⟂ **discoverability-home** (phiên mới NHÌN THẤY ở đâu).
- Chỉ-thị đổi hành vi mặc-định mọi phiên ⇒ **1 dòng vào file luật luôn-được-load + bump masthead**.
- Ứng dụng SE: `HMW-mode ON` là operating-posture — `CLAUDE.md` (file đọc đầu tiên) **có nói không?**

**P3-4. Masthead sweep** (`3-khoan:19-27`) — sửa body doc nào ⇒ **đọc lại dòng-1 + masthead của CHÍNH doc đó** trước khi tuyên sweep xong.

### P4 — đóng sổ / dọn (rẻ, làm kèm)

| # | Việc | Neo |
|---|---|---|
| P4-1 | **Nhãn model-flip** — `settings.json:11` pin Opus từ 07-20, canonical `STATUS §Sub-agents` còn ghi "Fable 5" ⇒ outage-recipe `session-start.md:43` thành **no-op**. `goi-chot:28` nay cho luật đóng: boot-default = Opus, Fable qua **2 cửa owner-chủ-động** | `goi-chot:23-30` |
| P4-2 | **`/check-email` bước 2 thiếu `outbox/all`** — chỉ ghi `outbox/se`; `outbox/all` = **90 file**, nguồn thật của cả 10 thư đợt này | đo hôm nay |
| P4-3 | **Sổ garble** đĩa `×25` vs STATUS/HANDOFF `×23` + phiên này **+2** ⇒ `×27`. Chốt **CUỐI phiên** | `auto-memory:13` |
| P4-4 | H1 `F-1` `/sleep-recovery-memory-l2` 4 site lệch roster · `F-2` `ef-core-migration/SKILL.md` sót Mig 67 · `F-6` `.gitignore` thiếu `scheduled_tasks.lock` | S144 H1 |
| P4-5 | **Tách 2 cột chủ-thể** trong bảng chờ (chờ-owner ⟂ chờ-hub) | ① (1) |

### 🔒 OWNER-GATED — em KHÔNG tự quyết

| # | Khoản | Vì sao cần anh |
|---|---|---|
| O-1 | Số `min_pending_shards` / `bulk_note_shards` cho SE | `auto:19` núm-số thuộc chủ dự án |
| O-2 | Posture trục-sâu: trần+dial-down **hay** opt-in-off; giá trị clamp | `depth-axis:55` *"KHÔNG bắt buộc default nào"* |
| O-3 | Gộp hay tách vai-KIỂM cho 3 vòng còn thiếu | `harness-dong-du-vong:51` |
| O-4 | ratify ranh `refine ⟂ lead-omission` (đã wire TRƯỚC ratify) | mục treo #10, hub không trả |
| O-5 | Nhãn model-flip (P4-1) | quyền owner |

---

## ③ CHECKLIST (vai · deliverable · acceptance ĐO ĐƯỢC)

| # | Vai | Deliverable | Acceptance **ĐO ĐƯỢC** |
|---|---|---|---|
| C1 | em-main | `hmw.js` lane-chết-kêu (P0-1) | Fault-inject: ép 1 lane trả null → output **PHẢI** chứa chuỗi `lane CHẾT`; lane sạch → **KHÔNG** chứa. 2 chiều PASS. `node --check` exit 0 |
| C2 | em-main | Luật đóng-gói-lane vào `fable-clone.md` (P0-2) | `grep -c 'trần lượt'` ≥1; run kế ≤3 file/lane; **0 lane chết vì cháy lượt** |
| C3 | em-main | Khuôn label 4 thành-phần (P1-1) | Chọn ngẫu nhiên **3** task trên panel, **chỉ đọc label** nói được {ai·gì·nhịp·phiên} → 3/3. 0 label bị cắt chữ |
| C4 | em-main + `harness-audit` | Mở rộng vai-KIỂM sang 3 vòng (P1-2) | Mỗi vòng: chỉ ra **ai ngoài con đo** đã re-check **con số nào** bằng tay. Vòng báo CLEAN có ≥1 lens re-check mẫu |
| C5 | `test-specialist` | Eval phía DÙNG + negative-control (P1-3) | Bơm id giả → **0-hit** (trả APPLIED = test ĐỎ). Payload chứa literal `FLOOR theo evidence` |
| C6 | `reviewer` | Sweep lời-hứa-máy (P1-4) | Mọi câu *"máy sẽ…"* còn lại **đều** có {đường-dẫn + lệnh + positive-control}, hoặc đã đổi sang dạng dự-định. Đếm trước/sau |
| C7 | em-main | Audit điểm-dừng rẻ (P1-5) | **Đo wall-clock** `/pause` 1 lần, ghi số. 0 bước spawn-agent/quét-rộng trong đường pause |
| C8 | em-main | Clamp cứng + budget-gate `hmw.js` (P2-1) | `taskList.length > <trần>` → **THROW**, không phải `log`. Fault-inject 2 chiều |
| C9 | `investigator-codebase` | Bảng cost re-ground (P2-2) | Số đo theo roster **hiện hành** (không phải 7); cột đơn-vị hiện diện; trả lời được falsifier `depth-cost:59` |
| C10 | `harness-eval` + `harness-refine` + `harness-audit` | Eval-của-eval 4 câu (P3-1) | Mỗi thước có verdict + cột thẩm-quyền. **Phép thử 2**: bịa input sai cho 1 detector bất kỳ → nó **ĐỎ**. Không đỏ = xanh-vì-mù |
| C11 | em-main | Distill trigger đếm-thật (P3-2) | `grep 'ngày\|7 day'` trong trigger = **0**; trigger đọc số shard. Lineage retire cũ **giữ vết** + chú thích có ngày |
| C12 | em-main | discoverability-home + masthead (P3-3/4) | `CLAUDE.md` có dòng nêu posture đang hiệu lực. Doc governance sửa body → dòng-1 khớp |
| C13 | em-main | P4-1…P4-5 | Từng mục có diff hoặc lý-do-không-làm. **CẤM** báo số tổng thay bảng từng dòng (bài `meta-count` S119) |

### 🔴 Luật chung áp cho MỌI mục

1. **Existence-proof tại chỗ** (P1-4) áp cho chính spec này: mục nào nói "máy sẽ bắt" mà chưa có máy → viết **dự-định**.
2. **Đo trước khi tuyên** — mọi số trong report phải re-đo, cấm chép từ spec.
3. **Bảng disposition TỪNG DÒNG**, không báo số tổng (`meta-count blind-spot`).
4. **Ghi đĩa TRONG lúc làm**; return chỉ là bản sao.
5. **Điểm-dừng phải rẻ** (`goi-chot:44`) — đè lên mọi đề xuất thêm việc.
6. **Số của owner** — O-1…O-5 **CẤM** tự đặt.

### Nấc báo hub (sau khi xong)

6/10 thư đòi `/adap-apply` + báo nấc per-khoản `sent→ACK→agreed→executed→verified`.
🔴 **Bất-đối-xứng đáng ghi:** `goi-chot-nam-khoan` — **thư binding nhất** — **KHÔNG** có mục "Nấc adopt", **0** câu `/adap-apply`. Báo nấc cho nó = tốt nhưng **không có mandate văn bản**; đừng để bảng nấc lệch vì chuyện này.
