# SPEC v3 — PATCH-SET trên v2 (S119, 2026-07-15)

> 🔴 **CÁCH ĐỌC:** worker đọc **v2** (`spec-…-v2.md`) làm thân + **file này** thay-thế các mục ghi rõ dưới. v3 **KHÔNG** lặp lại v2. **v1 = CẤM CHẠY.**
> **Nguồn:** `/fable-real reviewer` cổng-cuối `wf_cb964f83-331` → **GO-WITH-FIXES** (0 tiêu-chí NO-GO; **8 fix BẮT BUỘC** trước wave). Verdict đầy-đủ: `fable-real-final-gate-verdict.md`.
> **Nấc phiên S119:** anh chốt **dừng tại spec v3** — **KHÔNG chạy wave phiên này**. Wave = phiên sau qua `/tiep`.

---

# 0. 🔴 DISPOSITION 23 FINDING (fix #2 — vá lỗi trung-thực C1)

> **Lỗi đã phạm:** v2 ghi *"R2 (4C+**7M**) · R3 (5C+**2M**) … **19 finding** … v2 vá 19"*. **Đếm thật từ file: R2 = 4C+8M · R3 = 5C+6M ⇒ 23 C+M.** Ngay số tự khai cũng không cộng ra (4+7+5+2 = **18 ≠ 19**).
> **Vì sao NẶNG:** tập "7M/2M" **khớp chính xác** tập v2 có xử-lý ⇒ con-số "19" **đóng vai "đã phủ hết"** trong khi **3 finding STILL-BROKEN**. Lớp S109 (metadata-count) + S81 (honesty-presentation). Bảng này = **bằng-chứng-chống-tái-phạm**, và **đi nguyên vào adap-report**.

| # | Finding | v2 | v3 |
|---|---|---|---|
| R2-C1 | `ls=14` sai số-học | ✅ FIXED | — |
| R2-C2 | anchor số-nhiều | ✅ FIXED (gate tự chạy regex → MATCH `permission-matrix:16` + `form-engine:15`) | — |
| R2-C3 | gate⟂cờ tách wave | ✅ FIXED | **fix #6**: `fable-clone.md` 2-chạm vắng §3.2 |
| R2-C4 | gate W0.2 xanh-sẵn | ✅ FIXED | **fix #9(d)**: dòng 70 ⟂ §3.9 tự-mâu-thuẫn |
| R2-M1 | nửa-(ii) n-a sai | ✅ FIXED | — |
| R2-M2 | lỗ chưa-test precedence | ✅ FIXED | — |
| R2-M3 | 0-hardcode phình scope | ✅ FIXED | — |
| R2-M4 | scheduler mồ-côi + enum | ⚠️ PARTIAL (chủ-sở-hữu ✅ / enum **10/11 SAI**) | **fix #1** |
| R2-M5 | ② + ③d rơi | ✅ FIXED | — |
| R2-M6 | else "vô-hại" | ✅ FIXED | — |
| R2-M7 | thí-nghiệm quyết-định + L3 caveat | ✅ FIXED | — |
| **R2-M8** | **sweep roster sai pattern + file không wave** | 🔴 **STILL-BROKEN** (v2 §2.4(5) = "giữ v1") | **fix #6** |
| R2-m1 | broadcast #7 presence-not-age | ⬜ chưa xử | **fix #9(e)** 1 dòng |
| R2-m3 | — | ✅ FIXED qua PA-2b | — |
| R2-m4 | "n-a ĐÃ THOẢ" = under-report | ⬜ chưa xử | **fix #9(b)** |
| R2-m5 | lịch stamp-mark | ⬜ chưa xử | **fix #9(f)** → W6 |
| R3-C1 | rebase phá thật | ✅ FIXED | **fix #7** (bug shell guard) |
| R3-C2 | K stale | ✅ FIXED (K drift **4→5→6→8** = tự chứng minh luật đúng) | — |
| **R3-C3** | **push deadlock** | ⚠️ **PARTIAL** — v2 **tự tạo** ca wal:-đáy-range | **fix #3** 🔴 |
| R3-C4 | premise stale / renormalize staging | ✅ FIXED | — |
| R3-C5 | gate unscoped bất-khả-giữ | ✅ FIXED | — |
| R3-M1 | ls=15 | ✅ FIXED (trùng R2-C1) | — |
| R3-M2 | STATUS coupling | ✅ FIXED | — |
| R3-M3 | TOTAL≥46 bất-khả | ⚠️ PARTIAL (gate đã GỠ; thiếu capture-stdout) | **fix #9(c)** |
| **R3-M4** | **Sàn-3 thiếu dual-accept** | 🔴 **STILL-BROKEN** + **REGRESSED** (v2 chọn mtime) | **fix #4** 🔴 |
| **R3-M5** | **tripwire vỡ đường sống** | ⚠️ **PARTIAL** (wrapper-list ✅ / điều-kiện ❌) | **fix #5** 🔴 |
| **R3-M6** | sweep pattern + `hmw.js:9` | 🔴 **STILL-BROKEN** (trùng R2-M8) | **fix #6** |
| R3-m5 | mtime không bền | 🔴 **REGRESSED** — v2 chọn mtime làm phương-án CHÍNH | **fix #4** |
| R3-m6 | cấm synthesis giả | ✅ FIXED | — |
| R2-m2, R3-m1/m3/m4 | — | ⬜ chưa xử — **không chặn wave**, ghi để không rơi | defer S120 |

**Tổng:** 23 C+M ⇒ **16 FIXED · 4 PARTIAL · 3 STILL-BROKEN** (+1 REGRESSED ở lớp m). v3 đóng **3 STILL-BROKEN + 3 PARTIAL + 1 REGRESSED**.

---

# FIX #1 — Enum 11 class (thay §2.4 "enum ĐÓNG" của v2)

**Lỗi:** v2 chép **10** class rồi tuyên *"khớp H24 §2(1) 5+5"* — **SAI cả 2 chiều**: lane D có **11** (tách `carry-dropped`/`carry-aged` **có chủ-đích, đo được caveat (b)**); broadcast H24 `:48-49` liệt **"một việc rớt khỏi khối work-state so với backlog"** = **dấu-hiệu RIÊNG**. v2 **bỏ hẳn** `workstate-item-dropped` để về 10 rồi tuyên khớp.
🔴 **Hậu-quả:** mất **đúng class bắt ca F1 của chính SE** (S118 chạy 7-spawn mà **0 run-folder** = việc rớt khỏi sổ). Enum **ĐÓNG** ⇒ 2 vai mới **VĨNH VIỄN** không được phát class này.

```json
"lead_self_audit": {
  "flag_classes": [
    "view-stale-count", "view-stale-status", "view-stale-header",
    "view-stale-role-desc", "view-residual-asym",
    "gap-workstate-drop",          // ← KHÔI PHỤC (broadcast :48 — dấu-hiệu RIÊNG; bắt ca F1 của SE)
    "gap-carry-dropped", "gap-carry-aged",   // ← tách-đôi = MỞ-RỘNG lane-D (đo được caveat (b)), KHÔNG phải broadcast
    "gap-owner-specifics", "gap-decision-sunk", "gap-underfill"
  ]
}
```
🔴 **XOÁ câu "khớp H24 5+5"** khỏi spec. Nấc đúng: *"5 STALE (khớp broadcast) + **6** GAP = 5 broadcast + **1 mở-rộng lane-D** (carry tách-đôi, lý-do đo-được)"*.
**Acceptance:** `flag_classes` ⊇ `{gap-workstate-drop, gap-carry-dropped, gap-carry-aged, gap-owner-specifics, gap-decision-sunk, gap-underfill}` · `grep "khớp 5+5"` = **0**.

---

# FIX #3 🔴 — Luật fold leading-wal: (thay v2 W0.3 "commit-chốt ở W6" + §2.1 push-guard)

**Lỗi sâu:** v2 **tự tạo** ca chết. W0.3 park nội-dung staged ("commit-chốt ở W6") → `wal-flush.ps1:14-17` commit **pathspec 3 path** ở turn-boundary kế → **toàn bộ nội-dung reset-soft thành 1 `wal:` ĐÁY range** → tại W6 `NONWAL>0` → nhánh B → luật *"todo đầu = pick"* **giữ wal:-đáy sống** → recount=1 → re-squash cùng logic → vẫn 1 → **STOP ngay lần dùng thật ĐẦU TIÊN**.

**v3:**
- **(a)** W0.3 **BỎ** "commit-chốt ở W6". **Commit-chốt `[CLAUDE]` NGAY CÙNG TURN** với `reset --soft` (gộp luôn `wal-flush.ps1` interlock + `.gitattributes`) ⇒ **đáy range = commit thường**.
- **(b)** Mọi push **sau push#1** ở W6 (adap-report…) = **write → commit → squash → count → push CHAINED cùng 1 lượt**.
- **(c) Luật tổng-quát:** `wal:` ở **đáy range** ⇒ **`reset --soft origin/main` re-commit**, **KHÔNG rebase**.

**Acceptance:** fault-inject cây tạm shape `base + wal + [CLAUDE] + wal×2` ⇒ chained block ra **n=0**, **tree-identical**, **KHÔNG STOP**.

---

# FIX #3-bis 🔴 — Điều-kiện rẽ nhánh W0.3 test SAI THỨ (S120 `/tiep` — lead tự bắt @đóng S119, +1 ca mới)

**Lỗi:** v2 W0.3 (`:92`) rẽ nhánh bằng `if [ "$NONWAL" -eq 0 ]`. Nhưng luật **fix#3(c)** ở trên nói điều-kiện là *"`wal:` ở **ĐÁY range**"* — **hai thứ khác nhau**. `NONWAL>0` **không** hàm ý đáy là commit-thường: shape `base + wal + [CLAUDE]` có `NONWAL=1` **và** đáy = `wal:` ⇒ v2 đẩy sang **nhánh-B rebase** ⇒ todo đầu = `pick wal:` ⇒ `wal:` **sống sót** ⇒ `n>0` tại §5.2 ⇒ **đúng deadlock mà fix#3 sinh ra để đóng**.

**+ ca (0) MỚI (S120 đo thật):** S119 đã commit-chốt `4727d16` **và push** ⇒ `K=0`, range **RỖNG** ⇒ **không có đáy để test**. v2/v3 **không liệt ca này**; `NONWAL=0` sẽ đẩy vào nhánh-A ⇒ `git reset --soft HEAD~0` = **no-op vô hại nhưng vô-nghĩa**, và assert `HEAD~K == origin/main` vẫn PASS (vacuous). Không chết, nhưng **che mất** việc W0.3 lúc đó chỉ còn là *commit thẳng*.

**⇒ Điều-kiện đúng = 4 ca, test ĐÁY range (KHÔNG test NONWAL):**

```bash
K=$(git rev-list --count origin/main..HEAD)
BOTTOM=$(git log --format='%s' origin/main..HEAD | tail -1)   # rỗng khi K=0

if [ "$K" -eq 0 ]; then
  :                                    # ca (0) RỖNG → NO-OP. Không reset, không rebase. Commit thẳng.
elif printf '%s' "$BOTTOM" | grep -q '^wal:'; then
  [ "$(git rev-parse HEAD~$K)" = "$(git rev-parse origin/main)" ] || { echo "ABORT: HEAD~K != origin/main"; exit 1; }
  git reset --soft "HEAD~$K"           # ca (1) NONWAL=0 · ca (2) NONWAL>0 — CÙNG một xử-lý, CẤM rebase
else
  trap 'git rebase --abort' ERR        # ca (3) đáy = commit-thường → rebase+fixup an-toàn
  GIT_SEQUENCE_EDITOR=<script> git rebase -i origin/main
fi
if [ -d .git/rebase-merge ] || [ -d .git/rebase-apply ]; then   # fix #7 — guard đúng cú-pháp
  echo "STOP: rebase state left behind"; exit 1
fi
```
🔴 **Ca (1) và (2) GỘP:** một khi đáy là `wal:`, `reset --soft` tới `origin/main` là đúng cho **cả hai** — `NONWAL` không đổi cách xử-lý, nên nó **không được** là biến rẽ nhánh. Đây là chỗ v2 lạc.

**Acceptance:** fault-inject 4 cây tạm (`K=0` · `base+wal×2` · `base+wal+[CLAUDE]` · `base+[CLAUDE]+wal`) ⇒ chọn đúng **ca 0/1/2/3**; ca (2) **KHÔNG** được chạm `git rebase`; mọi ca `ls .git/rebase-merge` **absent**; `.git` **tree-identical** ở ca (0).

---

# FIX #4 🔴 — Sàn-3 dual-accept + W0.5 bỏ mtime (thay v2 §2.1 Sàn-3 + W0.5)

**Lỗi kép:**
1. Văn-bản canonical Sàn-3 (sẽ re-author vào `tiep.md` §0) **KHÔNG mang mệnh-đề dual-accept** — nó đang sống ở `workflows/README.md:19-20` (*"close-gate chấp nhận CẢ HAI dạng"*, C8 migration S71). Wire xong = **bão 5 dương-giả**. Đo: naive = **13** orphan · dual-accept = **8** (7 tồn-đọng + S119) — 5 folder h10/h910 **đều có** `harvest/<stage>-synthesis.md`.
2. **REGRESSED:** v2 chốt W0.5 scope theo **mtime** — đúng phương-án R3-m5 đã chứng minh **không bền** (**Dropbox resync ghi đè mtime**; "closeout cuối" không đo được).

**v3:**
- **Chép VERBATIM** mệnh-đề C8 (`workflows/README.md:19-20`) vào Sàn-3 canonical @`tiep.md` §0.
- W0.5: **mtime → `git log -1 --format=%cI -- <folder>`** so mốc **`3fde8af`** (`2026-07-14T16:29:55+07`).

**Acceptance:** scan mới trên cây hiện tại ⇒ đúng `{S119}` sau khi đóng 7 tồn-đọng · **5 folder h10/h910 IM**.

---

# FIX #5 🔴 — Tripwire mirror `hmw.js:116` (thay v2 §2.1 Sàn-1 điều-kiện)

**Lỗi:** v2 giữ điều-kiện v1 `!(A.run?.dir && A.run?.name)`. Thật (`hmw.js:116`): `const wave = (A.run && A.run.dir) ? A.run : ((A.wave && A.wave.dir) ? A.wave : null)` + `:19` *"[legacy alias: args.wave]"*.
⇒ điều-kiện v2 **GIẾT lời-gọi `wave:` hợp-lệ** + **đòi `.name` vượt contract** `.dir`-only.

```js
const w = (A.run && A.run.dir) ? A.run : ((A.wave && A.wave.dir) ? A.wave : null)
if (A.taskList.length >= 3 && !w) throw new Error('H22 Sàn-1: run ≥3 task PHẢI đăng-ký marker (args.run.dir) TRƯỚC khi phóng')
```
(hoặc **nâng contract `:116`** trong **CÙNG edit** — chọn 1, không nửa vời.)
**Acceptance (thêm §3.9):** ≥3-task kiểu `wave:{dir}` **VẪN CHẠY** · thiếu **cả hai** → **throw**.

---

# FIX #6 — Roster-sweep pattern + file chủ-quản (thay v2 §2.4(5) "giữ v1")

**Lỗi:** pattern sweep của v1/v2 = `grep "12-agent|12 sub"` — nhưng stale THẬT ghi **"9-agent"** ⇒ **pattern không bao giờ bắt được**. Lead tự verify:
- `hmw.js:9` = `'HMW P2 execute (SOLUTION_ERP) — fan-out **9-agent** roster…'` ← stale **từ trước S119** (roster 12, VALID_ROLES 12 từ S110)
- `ultra-on.md:24` = `'## VALID_ROLES (roster SOLUTION_ERP — **12 sub**, đủ roster từ S110)'` ← sẽ stale khi →14
- `fable-real.md` + `fable-real-runbook.md` = **không thuộc wave nào**

**v3:**
- **Pattern (Grep tool):** `(12|9)[- ](agent|sub)|roster 12|12 vai|VALID_ROLES[^0-9]*12`
- **Vào W2 (1-EDIT):** `hmw.js:9` meta + `ultra-on.md:24` danh-sách VALID_ROLES 12→14 (**routing-doc ⇒ CÙNG COMMIT**)
- **Vào W3:** `fable-real.md` + `fable-real-runbook.md`

**Acceptance:** ~~sau W3, pattern trên = **0 hit sống** (ngoài lịch-sử/archive).~~

## 🔴 ACCEPTANCE FIX#6 — SỬA @S122 (bản gốc BẤT-KHẢ-THI; tiền-lệ WAL:29 lead sửa acceptance cơ-học rồi báo)

**Lỗi:** *"0 hit sống"* đo **TOÀN BỘ** bề mặt khớp pattern — **kể cả phần CỐ Ý khớp**. Một implementation **ĐÚNG** vẫn trượt. **Cùng họ R2-C1 (`ls=14` sai số-học) + R3-M3 (`TOTAL≥46` bất-khả)** — lần thứ **BA** trong cùng spec: **acceptance viết bằng LITERAL thì đo cái TRÔNG GIỐNG, không đo cái ĐÁNG ĐỔI.**

**Bằng-chứng (sweep thật sau W3):** 14 hit còn sống, **0 cái là stale-cần-vá**:
| Nhóm | Hit | Vì sao KHÔNG được "vá" |
|---|---|---|
| **Ví-dụ CÓ CHỦ-ĐÍCH** | `lead-view-auditor.md:47` | Nó **minh-hoạ** class `view-stale-role-desc` bằng đúng chuỗi đó. Vá = **phá tài-liệu của chính vai đi bắt stale** |
| **Trích lịch-sử** | `agents/README:3` · `sleep-recovery-memory-l2:43` · `ACTIVE-MARKS:23` | Do W3 **vừa viết** để **giải-thích** cái đã vá |
| **Bản ĐÃ KÝ** | `ACTIVE-MARKS:19` | **Anh chốt @S122: giữ nguyên** (P4/P8) + chú-thích |
| **Sổ tạm** | `WAL:15/:29/:38` | Nhật-ký làm-việc, không phải doc |
| **Chưa tới lượt** | `harness-11-engine.md:269/:322/:332/:345` | = **W5**, KHÔNG phải W3 |
| **Canonical + history-delta** | `STATUS.md:25` `VALID_ROLES 12→14` | Mô-tả **đúng** sự thay-đổi |

**⇒ Acceptance MỚI (đo cái ĐÁNG ĐỔI, không đo cái TRÔNG GIỐNG):**
> Sau W3, **mọi hit sống của pattern PHẢI rơi vào đúng 1 trong 6 nhóm trên** — **0 hit** thuộc nhóm *"doc dẫn-xuất đang khai số roster SAI như thể đó là sự-thật hiện-hành"*. Nhóm *"chưa tới lượt"* **PHẢI rỗng sau W5**.
> **Cách kiểm = disposition TỪNG DÒNG** (không phải 1 con-số tổng — bài học §0: *con-số tổng đóng vai "đã phủ hết"*).

**🔴 3 điều tự-bắt trong lúc chạy acceptance này (→ adap-report):**
1. **`STATUS.md:25` có stale THẬT** mà pattern **suýt bỏ sót**: row canonical ghi `| Sub-agents | **14** |` nhưng **narrative CÙNG DÒNG** ghi ``cả 12 sub `model: inherit` `` ⇒ **mâu-thuẫn nội-tại NGAY TRONG nguồn chuẩn** (W2 sửa row, bỏ sót narrative). Vá @S122 bằng cách **bỏ số khỏi narrative**, không phải đổi số.
2. **Bẫy mega-line TÁI HIỆN ĐƯỢC:** `STATUS.md:25` — `grep -c` = **1**, `grep -o | wc -l` = **2**. Ai dùng `grep -c` sẽ vá 1 chỗ rồi tưởng xong. (WAL:13 đã ghi bẫy này; nó **vẫn suýt ăn** lần nữa.)
3. **Lead ĐẾM SAI ×2 trong cùng phiên** — cả hai đều ở trục *đếm-về-việc-mình*: (a) báo *"`fable-real-runbook.md` **8 hit**"* — thật là **14** (lấy output `head -40` **đã bị cắt** làm số tổng); (b) báo *"đo lại tái-hiện CHÍNH XÁC dự-báo FIX#4"* rồi lấy trùng-khớp làm chỗ dựa, trong khi **cả FIX#4 lẫn lead đều đang đo TÊN FILE**. Khớp `feedback_meta_count_selfcoverage_blindspot`: **lead ĐO tốt, lead ĐẾM VỀ MÌNH thì sai.**

---

# FIX #7 — Bug shell guard W0.3 (thay v2 W0.3 dòng guard)

**Lỗi lead tự viết:** `[ -d .git/rebase-merge ] || [ -d .git/rebase-apply ] && { echo …; exit 1; }` ⇒ happy-path (**không có dir nào**) trả **exit 1** (status chuỗi `||`) ⇒ caller check exit-code **báo hỏng GIẢ**.

```bash
if [ -d .git/rebase-merge ] || [ -d .git/rebase-apply ]; then
  echo "STOP: rebase state left behind"; exit 1
fi
```
**Acceptance:** chạy block trên repo sạch ⇒ **exit 0**.

---

# FIX #8 — 2 ack tường-minh (🔴 QUYỀN ANH — chờ ký)

## (a) PA-2 hình-thức — **cần anh duyệt trước khi W2 land `TIER2_EXPECTED_FULL_ID`**
Gate bắt đúng: bullet *"param `model:` chỉ nhận enum alias"* trong `owner-decisions` **dán nhãn "Đo" nhưng KHÔNG nêu phép đo**. 2 bullet kia gate tự verify được (`hmw.js:44` ✓ · grep full-id = 5 hit / 3 file ✓); **riêng bullet này là tiền-đề** biến PA-2-nguyên-bản thành "bất-khả-thi" ⇒ **đổi hình-thức một quyết-định anh đã chốt**.
🔸 **Hạ nấc trung-thực:** *"theo tài-liệu harness (Agent-tool `model` enum = `sonnet|opus|haiku|fable`), **CHƯA thử truyền full-id để xem có bị từ-chối không**"*.
**⇒ Cần anh xác nhận:** PA-2 thực-thi bằng **PA-2a (hằng-số `TIER2_EXPECTED_FULL_ID`) + PA-2b (`spawn-model-audit.ps1` so resolved-vs-expected)** — thay vì neo-tại-spawn (chưa thử). ⚪ **CHỜ**

## (b) Hook-interlock vs floor N.2 — **phân loại khung**
v2 xếp R3-side-ref = **VƯỢT KHUNG phải request** (đúng nguyên-tắc anh S119), **nhưng chính v2 sửa `wal-flush.ps1`** (thêm skip khi rebase-state) mà **không phân loại** vs floor N.2 (`harness-11-engine.md:406` — hook *"ĐƯỢC làm đúng 2 việc"*). Nguyên-tắc anh nói rõ **"dù lý-lẽ tốt"**.
**Đề-xuất phân loại (lead):** **TRONG KHUNG** — interlock **KHÔNG thêm hành-vi** cho hook; nó **chặn hook tự-hủy** (commit lên detached HEAD = phá chính floor N.2 nó phục-vụ). = **thu hẹp**, không mở rộng. ⇒ khai ở adap-report, **không cần request**.
⚪ **Chờ anh ack** (nếu anh muốn chặt hơn → chuyển thành request).

---

# FIX #9 — Nhóm nhỏ (không chặn, gộp 1 pass)

| | Việc |
|---|---|
| (a) | ~~"4 cú lật"~~ → **"4 phát-hiện: 2 ĐO CHẮC (L1/L4-diễn-giải) · 1 PARTIAL (L2) · 1 CHƯA-VERIFY (L3)"** — v2 đã tự hạ L2/L3 nhưng **giữ nguyên nhãn "4 cú lật"** |
| (b) | `"H23 §2(5) n-a ĐÃ THOẢ"` → **`"đã thoả"`** — dán PASS thành n-a = **under-report nấc tuân-thủ** khi gửi hub |
| (c) | W4 capture-stdout detector ra `runs/<id>/` = bằng-chứng time-anchored (thay "reviewer chứng-kiến" làm neo **duy-nhất**) |
| (d) | v2 dòng 70 *"W0.2 KHÔNG vào §3.9"* ⟂ §3.9:245 vẫn có ⇒ **chốt 1** (giữ ở §3.9 + chú "vacuous") |
| (e) | +1 dòng: **broadcast #7 `presence-not-age` ĐÃ adopt S115** (R2-m1 — kẻo hub tưởng SE bỏ sót) |
| (f) | Lịch **stamp-mark** vào **W6** (R2-m5) |
| (g) | W0.6 verdict **nhét thẳng** vào R4-request (thay *"báo hub sau"* — vì W0.6 chạy **TRƯỚC** W6) |
| (h) | Validator W1② chạy **glob** thay hardcode 12 |
| (i) | +acceptance: W0.4 · EOL-assert-scoped cạnh push · W6 |
| (j) | 🔴 **Ghi rõ: W0.6 + post-W2 đều cần RESTART ⇒ wave trải ≥3 phiên CLI ⇒ nối bằng `/tiep`** (H22 — chính cơ-chế phiên này adopt) |

---

# Nấc trung-thực v3

- **Verdict cổng-cuối:** **GO-WITH-FIXES** — **0 tiêu-chí NO-GO**. Mọi đường **mất-việc / rewrite-pushed-history** đã đóng (mass rm+checkout cấm · nhánh-A + assert `HEAD~K==origin/main` chặn tụt dưới remote · interlock+trap+hard-rule chặn detached-HEAD · 0 force-push · O4 giữ 57). Deadlock **hạ cấp** thành STOP fail-loud — **nhưng STOP gần-như-chắc-chắn xảy ra ở W6 nếu không có fix #3**.
- **W0 SOLO = ĐÚNG phải SOLO** (phẫu-thuật index + reset + restart; fan-out ⇒ hook commit agent-memory **giữa lúc mổ**).
- **Owner-decision:** gate xác nhận **không có chỗ nào v2 tự quyết CON-SỐ/policy của anh**; 2 chỗ cần ack = **fix #8**.
- 🔴 **Tỷ-lệ claim (gate re-đo ~30 claim rời):** **~80% ĐO ĐƯỢC-và-đúng** · **~13% SAI — tập trung TRỌN ở lớp meta-count/coverage** (finding-count ×3, enum-"khớp" ×1) · ~7% suy-diễn/chưa-verify.
  **Điểm sáng:** 4/5 chỗ CHƯA-VERIFY khai **đúng nấc** (L3 · precedence · side-ref · hot-reload `hmw.js`).
  **Điểm tối:** **2 chỗ SUY DIỄN trình như ĐO** (enum-"khớp" · param-alias).
  ⇒ **Bài học tự-soi:** *lead ĐO tốt; lead ĐẾM VỀ CHÍNH MÌNH thì sai.* Lỗi **không** nằm ở dữ-liệu — nằm ở **tự-tổng-kết độ-phủ**. Đây là lý-do bảng §0 tồn tại.
- **CHƯA VERIFY (giữ nguyên):** đường đọc frontmatter CR-tolerant hay LF-only (**W0.6 quyết**) · precedence spawn-param ⟂ frontmatter (**defer phiên lead=Fable**) · side-ref R3 (lập-luận plumbing) · hot-reload `hmw.js` · **+ MỚI:** param `model:` có từ-chối full-id không (fix #8a).
- **STILL-BROKEN sau v3 = 0** (3 cái đã có fix #3/#4/#5/#6). **PARTIAL còn:** R3-M3 (fix #9c) · R2-m2/R3-m1/m3/m4 (**defer S120, không chặn**).
- **Số trong v2/v3 = ẢNH CHỤP, KHÔNG phải hằng-số.** K đã trôi **3→4→5→6→8** trong 1 buổi ⇒ **LUẬT SỐ ĐỘNG** (W0.0 re-measure) là bắt-buộc, không phải khuyến-nghị.
