Files
solution-erp/.claude/workflows/runs/2026-07-15-S119-adap-6-broadcast/spec-adap-6-broadcast-15-07-2026-v2.md
pqhuy1987 4727d16178 [CLAUDE] Docs: S119 adap 6 broadcast AI_INFRA - dieu tra chieu rong + spec v3 (dung truoc wave)
check-email 6 broadcast moi (H23 model-at-spawn / H24 lead-self-audit / H22 wal-defect-fix
5-san / H22 push-guard / EOL-CRLF agent-registry / owner-sign) - hash 7/7 + tamper 4/4 MATCH.

Pipeline H21: fable-clone invest 5-lane (wf_1f6bd5e2-478, 5/5 clean) -> spec v1 ->
fable-clone reviewer 4-lane (wf_78a84f9b-03e: R2 FAIL 4C+8M, R3 FAIL 5C+6M, R1/R4 chet #53)
-> v2 -> fable-real reviewer cong-cuoi (wf_cb964f83-331: GO-WITH-FIXES + 8 fix + 2 honesty-C)
-> v3 (STILL-BROKEN = 0). Anh chot B: dung tai spec, wave chay phien sau qua /tiep.

Do that: 57 wal: da lot origin/main (hub do duoc 1 -> SE = 57x); nguyen nhan KHONG phai
turn-seam ma la session-end.md:113 SE tu viet "kep sau -> GIU NGUYEN". K troi 3->10/buoi.
v1 SE GAY MAT VIEC (R3 fault-inject: NONWAL=0 -> 0 commit de fixup -> detached HEAD ->
hook fail-open -> abort -> mat worktree = E-029 bang cua sau).

Owner 6 chot: nguyen-tac moi (vuot-khung = request anh + AI_INFRA) / PA-2 = PA-2a hang-so +
PA-2b audit / 6-15-3 / [carry:slug] / KHONG don 57 / fix#8 (a)(b).

0 prod-code, 0 migration, 0 FE. Test 509 giu nguyen (45D + 464I).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 11:20:29 +07:00

284 lines
27 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# SPEC v2 — SE đối ứng 6 broadcast AI_INFRA (S119, 2026-07-15)
> **SUPERSEDES v1** (`spec-adap-6-broadcast-15-07-2026.md` — giữ làm audit-trail, **KHÔNG chạy v1**).
> **Lý do v2:** `/fable-clone reviewer` 4-lane (`wf_78a84f9b-03e`) → **R2 FAIL** (4C+7M) · **R3 FAIL** (5C+2M) · R1/R4 **chết giữa chừng** (#53). **19 finding**, đa số loại "chạy là hỏng". v1 sẽ **gây mất việc**.
> **Owner-decision:** `owner-decisions-15-07-2026.md` — Q1=**PA-2** · Q2=**6/15/3** · Q3=**`[carry:<slug>]`** · Q4=**KHÔNG dọn 57**.
> **Trạng thái:** chờ `/fable-real reviewer` chốt → HMW wave.
---
# ① ĐỀ-BÀI
Giữ nguyên v1 §1 (phơi-nhiễm + 4 cú lật L1-L4 + 2 class + GAP#6 + 3 phát-hiện F1-F3 + positive-control + bẫy mega-line). **Δ v2 với ①:**
## 1.A Số ĐO LẠI lúc viết v2 (v1 đã stale khi mực chưa khô)
| Trục | v1 ghi | **v2 ĐO LIVE** | Ghi-chú |
|---|---|---|---|
| `K` = `git rev-list --count origin/main..HEAD` | **4** | **6** | WAL ghi 3 · v1 ghi 4 · R3 đo 5 · nay **6**. Hook fire **mỗi turn-boundary** ⇒ K **tăng đơn-điệu** |
| `origin/main` | — | **`3fde8af`** | |
| non-`wal:` trong range | — | 🔴 **0** (6/6 đều `wal:`) | ⇒ **KHÔNG có commit nào để `fixup` VÀO** |
| `wal:` trên `origin/main` | 57 | **57** ✓ | |
| `git status --porcelain` | "sạch, dirty=0" | 🔴 **KHÔNG SẠCH**`M .claude/WAL.md` + 7 untracked broadcast + 6 untracked run-folder | v1 §2.0 tiền-đề **SAI** |
| `ls .claude/agents/*.md \| wc -l` | (suy 12) | **13** = 12 roster + **README.md** | ⇒ +2 vai = **15**, KHÔNG phải 14 |
| gate scope EOL (`agents`+`commands`+`skills`) | — | 🔴 **0 — ĐÃ XANH SẴN** | repo-wide = 188 (131 Migrations) |
🔴 **LUẬT SỐ ĐỘNG (v2):** **CẤM hardcode `K`/`n` ở bất-kỳ đâu** trong spec/§5.0/script. Mọi nơi PHẢI tính runtime. Số trong bảng này = **ảnh chụp để reviewer đối chứng**, **KHÔNG phải hằng-số để worker dùng**.
## 1.B Δ L2 — v1 sai một nửa (R1 nhặt được trước khi chết)
v1 L2: *"188 = `dotnet ef`/VS sinh"*. R1 đo: *"CRLF clusters in exactly the S112 `sub-*`/`review-L*` files — **lead-written sub-returns**"*.
⇒ **L2 đúng phần Migrations (131/188), SAI phần "toàn bộ"** — một phần 188 do **chính lead ghi ra** (sub-return files trong `runs/`). **Nấc: PARTIAL.** Không đổi kết-luận (vẫn KHÔNG do squash — §5.0 = `reset --soft` = worktree-neutral), nhưng **đổi nguồn** ⇒ ảnh hưởng scope (§2.2).
## 1.C Δ L3 — HẠ NẤC xuống **CHƯA VERIFY** (R1 chết đúng trước câu quyết-định)
R1 đi được: *"strings exist"* ✓ → *"extracting the actual `^---` regex variants with context"* ✓ → *"**The context is decisive. Let me confirm which site is the actual fs-backed frontmatter reader**"* → **CHẾT**.
⇒ 🔴 **CHƯA VERIFY (bắt buộc khai):** *"đường đọc frontmatter `.claude/agents/` là nhánh CR-tolerant (`\s*` / `\r?\n`) hay nhánh LF-only (`[ \t]*\n`)"* — **chưa ai xác nhận**.
⇒ **Hệ-quả bắt buộc (R2-M7):** v1 **giữ kết-luận L3** ("KHÔNG tuyên miễn-nhiễm") mà **bỏ độ-bất-định** khỏi sổ trung-thực = **lệch đúng chiều có lợi**. v2 **khôi phục**: giữ kết-luận (thận-trọng = đúng) **VÀ** giữ caveat.
⇒ **adap-request R4 HẠ NẤC:** không được gửi hub dưới dạng *"chúng tôi đọc mã-nguồn"*. Nấc đúng = *"grep-chuỗi trong binary minified thấy 2 dạng regex cùng tồn tại; **CHƯA xác định** dạng nào trên đường đọc thật; đề-nghị hub (chủ mã-nguồn) xác nhận"*.
---
# ② CÁCH IMPLEMENT (v2)
## 2.0 🔴 W0 — PRE-FLIGHT (em-main SOLO)
### W0.0 — RE-MEASURE trước mọi thao-tác (R3-C4) 🆕
Worker **KHÔNG được tin số trong spec** (spec bơm qua args, số đã stale khi tới tay).
```bash
git status --porcelain # PHẢI phân-loại TỪNG dòng; chưa phân-loại → ABORT
K=$(git rev-list --count origin/main..HEAD)
NONWAL=$(git log --format='%s' origin/main..HEAD | grep -vc '^wal:' || true)
```
**Acceptance:** in ra `{K, NONWAL, porcelain-count}`; mọi entry porcelain **được phân-loại**; chưa phân-loại ⇒ **ABORT loud**.
### W0.1 — `.gitattributes` theo CLASS
Thêm `* text=auto eol=lf` + khai binary THẬT (`*.zip *.exe *.dll *.docx *.xlsx *.pptx *.pdf *.png *.jpg *.jpeg *.ico *.woff *.woff2` binary) + **giữ 2 rule cũ**. 🔴 CẤM vá theo đuôi-file-vừa-cắn.
**Acceptance:** `git check-attr text eol -- .claude/agents/reviewer.md` ⇒ `text: auto`, `eol: lf` (nay: unspecified).
### W0.2 — EOL: **SCOPED-ONLY** (R3-C4/C5 — v1 SAI cơ-chế lẫn gate)
🔴 **3 đính-chính bắt buộc:**
1. **`git add --renormalize` KHÔNG rewrite worktree** (R3 đo: file vẫn `i/lf w/crlf` sau renormalize; **chỉ `rm` + `git checkout --`** mới ra `w/lf`) ⇒ **cơ-chế v1 sai từ gốc**.
2. **`--renormalize` âm-thầm STAGE nội-dung dirty**; acceptance v1 `git diff --stat` = rỗng **PASS giả** (vì mọi thứ chuyển sang index). ⇒ dùng **`git diff --cached --stat`** + **`--dry-run`** trước.
3. **Gate unscoped BẤT-KHẢ-GIỮ:** W1/W2 spawn agent ghi `agent-memory/*/MEMORY.md` ⇒ **CRLF lại** ⇒ gate **vỡ ngay sau khi "pass"**. Cộng: unscoped đòi `rm`+`checkout` **188 file incl. 131 EF migration + 6 file sống** (`STATUS.md`, `HANDOFF.md`, `docs/CLAUDE.md`, `agent-memory/{implementer-backend,reviewer}/MEMORY.md`, `.mfe-state.json` — R3 confirm cả 6 nằm trong 188).
**⇒ v2 QUYẾT:**
- **GATE = SCOPED** `.claude/agents` + `.claude/commands` + `.claude/skills` ⇒ **0**.
- **188 repo-wide = INFORM-only.** 🔴 **CẤM mass `rm`+`checkout`.**
- **KHAI THẲNG:** *"gate scoped **ĐÃ XANH SẴN 0 việc làm** (R2-C4). Giá-trị W0.1/W0.2 = **materialize theo attr mới cho file MỚI/ghi-lại**, KHÔNG phải sửa 188 file cũ."* ⇒ **W0.2 KHÔNG vào §3.9** (gate vacuous).
- Nếu **thật sự** muốn sửa 188 ⇒ **việc riêng, phiên riêng, worktree sạch tuyệt-đối** — KHÔNG phải phiên này.
**Acceptance:** `git add --renormalize --dry-run .` liệt đúng tập dự-kiến, **0 file dirty**; `git diff --cached --stat` sau thao-tác = rỗng; scope-gate = 0 **và vẫn 0 sau W2**.
### W0.3 — 🔴 **VIẾT LẠI HOÀN TOÀN** — squash **KHÔNG REBASE** (R3-C1: v1 phá thật)
**R3 fault-inject cây tạm chứng minh v1 phá:**
```
origin/main..HEAD = 6/6 wal:, NONWAL=0 ⇒ mọi todo-line thành `fixup`
→ error: cannot 'fixup' without a previous commit ×6
→ REBASE-EXIT=1 ; .git/rebase-merge LEFT ; HEAD DETACHED
→ hook wal-flush.ps1 (fail-open, exit 0, KHÔNG guard rebase-state) commit LÊN detached HEAD
→ git rebase --abort → WORKTREE CONTENT GONE ; commit ORPHANED (reflog only)
```
= **`E-029` tới bằng cửa sau** — đúng lỗi v1 trích làm cảnh-báo.
**⇒ v2 — 2 NHÁNH RUNTIME, quyết TRƯỚC khi chạm git:**
```bash
K=$(git rev-list --count origin/main..HEAD)
NONWAL=$(git log --format='%s' origin/main..HEAD | grep -vc '^wal:' || true)
if [ "$NONWAL" -eq 0 ]; then
# ── NHÁNH A (ĐANG FIRE HÔM NAY: NONWAL=0, K=6) ──
# reset --soft ONLY. 🔴 TUYỆT ĐỐI KHÔNG invoke rebase.
[ "$(git rev-parse HEAD~$K)" = "$(git rev-parse origin/main)" ] || { echo "ABORT: HEAD~K != origin/main"; exit 1; }
git reset --soft "HEAD~$K"
# → nội dung 6 wal: gộp vào staging; commit-chốt ở W6
else
# ── NHÁNH B (có commit thường trong range) ──
# rebase+fixup; script PHẢI để dòng todo ĐẦU TIÊN là `pick`, KHÔNG BAO GIỜ emit leading `fixup`
trap 'git rebase --abort' ERR
GIT_SEQUENCE_EDITOR=<script> git rebase -i origin/main
fi
# 🔴 HARD RULE mọi nhánh: nếu .git/rebase-merge hoặc .git/rebase-apply TỒN TẠI → STOP, CẤM để hết lượt
[ -d .git/rebase-merge ] || [ -d .git/rebase-apply ] && { echo "STOP: rebase state left"; exit 1; }
```
**+ HOOK INTERLOCK (bắt buộc):** thêm vào `wal-flush.ps1` đầu file:
```powershell
if ((Test-Path .git/rebase-merge) -or (Test-Path .git/rebase-apply)) { exit 0 }
```
⇒ chặn hook ghi lên detached HEAD. *(Hook hiện: `exit 0` fail-open, **0 guard** — đã verify.)*
**Acceptance:** chạy lại fault-inject cây tạm ⇒ chọn **nhánh A**, `REBASE-EXIT` **không bao giờ** non-zero, `ls .git/rebase-merge` **absent** sau bước; `HEAD~K == origin/main` assert PASS trước reset.
### W0.4 — `workflows/README.md:52` gỡ claim STALE (giữ v1)
### W0.5 — baseline 7 orphan-folder (giữ v1) — 🔴 chọn **scope theo `mtime > closeout cuối`**, **KHÔNG** tạo `*-synthesis.md` giả (Goodhart — R3 flag)
### W0.6 🆕 — **THÍ-NGHIỆM QUYẾT-ĐỊNH EOL** (R2-M7 — lane B xếp ưu-tiên #1, v1 làm rớt)
> Lane B nguyên-văn: *"thí-nghiệm quyết-định **DUY NHẤT**... nó quyết SE dính CRLF thật hay không; **mọi thứ khác phụ-thuộc kết-quả này**"*.
> v1 rút xuống "validator FAIL trên copy-CRLF" = kiểm **validator của mình**, KHÔNG kiểm **bộ-đọc THẬT**.
**Làm:** copy `reviewer.md` → `.claude/agents/_crlf-probe.md` (đổi `name:`) → **CRLF-hoá byte** → **RESTART CLI** → **spawn-probe**.
- Spawn **được** ⇒ SE **CRLF-tolerant** ⇒ L3 nhánh "LF-only regex trên đường đọc" **BỊ BÁC** ⇒ R4 request **rút** hoặc hạ mạnh.
- Spawn **KHÔNG được** ⇒ L3 **XÁC NHẬN** ⇒ R4 request **giữ nguyên nấc mạnh** + SE có **positive-control THẬT** (thay synthetic).
- Xong ⇒ **XOÁ `_crlf-probe.md`**.
**Acceptance:** verdict `{CRLF-tolerant | CRLF-fatal}` ghi ra file; `_crlf-probe.md` đã xoá; kết-quả **cập-nhật ngược** §1.C + R4-nấc.
🔴 **Đây là bảo-đảm falsifiable DUY NHẤT** — broadcast ④(d): *"mọi kiểm static-text đều KHÔNG falsifiable; chỉ spawn-probe / assert-registry mới thật-sự chứng-minh"*.
## 2.1 Sàn H22 — Δ v2
| Sàn | Δ so v1 |
|---|---|
| **1** | 🔴 **R2-C3 + R3:** (a) đồ-thị wrapper THẬT = **4** (`fable-clone.md` · `fable-real.md` · `ultra-on.md` · raw-invoke em-main) — **`/hmw` KHÔNG tồn tại dưới dạng file** (`ls .claude/commands/` = 18, không có `hmw.md`) ⇒ bỏ khỏi danh-sách. (b) Grep-tool `args.run` trong `.claude/commands/` = **0 hit** ⇒ **cả 4 wrapper đều CHƯA có cờ**. (c) 🔴 **gate + 4 cờ PHẢI CÙNG 1 WAVE / 1 COMMIT** — v1 để gate ở W2, cờ ở W3 ⇒ mọi `/fable-clone` ≥3 lane (**chính run này = 5 lane**) + `/ultra-on` auto-HMW **THROW ngay** trước khi W3 kịp vá = **vỡ đường đang chạy** (đúng broadcast §4). (d) **nửa-(ii) = ÁP, KHÔNG n-a** (R2-M1: broadcast nói *"**wrapper** gọi xuống engine dùng-chung"*, KHÔNG phải engine→engine — v1 đọc sai). (e) Khai thật: chỉ phủ `hmw.js`; **raw Workflow/Agent = kẽ CÒN-LẠI KHÔNG gate được** (F2 — chính run này đi đường đó) |
| **2** | giữ v1 |
| **3** | giữ v1 (3-bậc SE-tailored + 🆕 bậc-MẠNH-④ path-trong-wal-commit) |
| **4** | giữ v1 |
| **5** | giữ v1 |
| **push-guard** | 🔴 **R3-C3:** v1 chuyển **phép đếm** vào lượt push nhưng **KHÔNG chuyển squash** ⇒ giữa §5.0 và §5.2, closeout **chắc chắn** làm bẩn path hook (Sàn-2 ghi `closing:` · W4 spawn reviewer→agent-memory · W4/W5 ghi `runs/`) ⇒ mỗi turn-boundary = +1 `wal:` ⇒ n≥1 tại §5.2 ⇒ **CHẶN PUSH → phiên không đóng được** ⇒ người bypass ⇒ **cổng tự xoá chính nó**. **⇒ v2: §5.2 = `squash → count → push` CHAINED TRONG **1 LƯỢT**; §5.0 = **pre-pass**, §5.2 **RE-EXECUTE** phép tính. Recount >0 ⇒ re-squash 1 lần ⇒ recount ⇒ push; vẫn >0 ⇒ **STOP + report**.** Acceptance thêm: **KHÔNG có turn-boundary giữa squash cuối và `git push`**. **(b) else-branch = 🔴 MÌN NGỦ, KHÔNG "vô-hại"** (R2-M6): else = `git log --format='%s' HEAD \| grep -c '^wal:'` = **đếm toàn lịch-sử = 57** ⇒ `-eq 0` fail ⇒ **chặn push VĨNH VIỄN** nếu ref biến mất/đổi tên ⇒ **bỏ hẳn else** (ref EXISTS, đã verify) **hoặc** đổi thành **fail-loud báo owner** |
## 2.2 EOL — Δ v2
| Δ | Nội-dung |
|---|---|
| **② SYMPTOM khôi phục** (R2-M5) | roster ↔ VALID_ROLES ↔ file-count = **14/14/14** (post-W2). v1 làm rớt ② |
| **③(d) RESTART+VERIFY khôi phục** (R2-M5) | BƯỚC 0.6 = **model-probe**, KHÔNG phải **registry-probe** ⇒ thêm **0.6b registry-probe**. Broadcast ③(d): *"RESTART rồi VERIFY danh-sách agent"* |
| **④(a) control** | 🔴 phụ-thuộc **W0.6**: probe ra `CRLF-fatal` ⇒ dùng **byte file-đã-chết THẬT** làm control (snapshot TRƯỚC fix); ra `CRLF-tolerant` ⇒ validator **hạ giá-trị** (chỉ còn hygiene) + khai thật |
| **SCOPE** | như W0.2: gate scoped; 188 INFORM-only; **L2 = PARTIAL** (131 Migrations + phần lead-written sub-returns — §1.B) |
## 2.3 H23 — **PA-2** (anh chốt) — Δ v2
Giữ v1 PA-1 (a)(b)(c)(d) + **PA-2a/PA-2b** (`owner-decisions` §Q1). **Δ:**
| # | Δ |
|---|---|
| **M2 🔴 LỖ CHƯA-TEST** (R2-M2) | H23 §2(2) **BẮT BUỘC khai**: *"thứ-tự ưu-tiên giữa 'tham-số tại spawn' và 'pin ở tệp định-nghĩa' khi **CẢ HAI cùng hiện-diện** — rất có thể **chưa từng được test**"*. Ở SE **cả hai HIỆN-DIỆN**: `hmw.js:44` trả alias → `agent(…,{model:…})` **trong khi** frontmatter 12/12 = `inherit`. **Chưa ai test bên nào thắng.** 🔴 **Nếu frontmatter THẮNG ⇒ toàn bộ fix GAP#6 = NO-OP**, floor-2 vẫn thủng khi Fable UP = đúng lỗi reviewer S108 đã bắt. ⇒ (i) khai vào §Nấc-trung-thực + §3.7; (ii) **acceptance NÂNG**: chạy 1 lane `tier:'opus'` **khi lead=Fable** → **đọc model-thực-tế resolve** (H23 §6 phép-thử-phá #3) → lệch ⇒ báo owner. *(Hôm nay lead=Opus ⇒ **không phân-biệt được** ⇒ acceptance này **defer tới phiên lead=Fable**; khai thẳng, KHÔNG giả-vờ đã test.)* |
| acceptance v1 | `Grep tier:'opus' ≥1 hit` = **chỉ đo CHỮ trong file**, không đo runtime ⇒ **Goodhart-able 100%** ⇒ giữ làm **điều-kiện cần**, KHÔNG phải đủ |
## 2.4 H24 — Δ v2
| # | Δ |
|---|---|
| **(1) 2 vai** | 🔴 **acceptance `ls .claude/agents/*.md = 14` SAI SỐ-HỌC** (R2-C1 + R3-M1): glob bắt luôn `README.md` ⇒ nay **13** = 12+README ⇒ +2 = **15**. Gate cũ **FAIL trên implementation ĐÚNG**, hoặc ép worker **xoá `agents/README.md`** = catastrophic-Goodhart. **⇒ v2: bất-biến trên ROSTER, không trên glob:** `VALID_ROLES.length == 14` **AND** `(ls .claude/agents/*.md \| grep -v README.md \| wc -l) == 14`. 🔴 **+ acceptance FALSIFIABLE (R2-M5):** static-check **KHÔNG đủ** ⇒ **RESTART → spawn-probe 14/14 agent SỐNG** |
| **(2) detector** | 🔴 **C2 (R2): `anchor_patterns[]` PHẢI SỐ NHIỀU.** v1 nén còn 1 regex `\*\*Last updated:\*\*` — mà `permission-matrix/SKILL.md` **KHÔNG có anchor đó** (nó dùng `**Status (post Session 6 — 2026-04-30):**`; Grep `Last updated` trong `.claude/skills/` = **0 hit**) ⇒ cộng luật *"không anchor ⇒ BỎ QUA"* ⇒ **detector loại thẳng chính positive-control của nó** ⇒ **W4 bất-khả-thi** ⇒ "xanh từ commit đầu" = đúng thứ H24 bảo phải nghi. **⇒ v2: `anchor_patterns[]` gồm ≥2 dạng**, bắt buộc có `\*\*Status \(post Session \d+ — (\d{4}-\d{2}-\d{2})\)\:\*\*`. **+ M3:** thu hẹp acceptance về **đúng nguyên-văn broadcast** = *"**số nhịp** đọc từ config; **0 số NHỊP** hardcode"* — **KHÔNG** "0 số hardcode trong .ps1" (v1 phình scope: `governance-detectors.ps1:419 $walLineCount -gt 40` = **số ANH ĐÃ KÝ** mark `RC-…12-07-2026-11-43-45`; `:256`, `:295`, `:399` = số detector cũ **ngoài scope H24**). **+ M2 (R3): detector KHÔNG disjoint** — `Get-StatusValue:154-157` resolve canonical **từ `docs/STATUS.md`** ⇒ ⚠️ **KHÔNG có row `Policies`** ⇒ nửa `policy` của GAP-3 **không thể fire** nếu chưa thêm `\| Policies \| **216** \|` vào STATUS.md. ⚠️ `\| Sub-agents \| **12** \|` = **row canonical**; W2 nâng 14 ⇒ **PHẢI update STATUS.md CÙNG LANDING**, nếu không C2/B3 **flag mọi derived-doc ghi "14" là stale-vs-12** ⇒ **detector BÃO trên chính thay đổi của H24** ⇒ acceptance "TOTAL ≥ 46" **được thoả bằng RÁC** |
| **(3) scheduler** | 🔴 **M4 (R2): v1 để MỒ CÔI** — rà 7 wave: `memory-budget.json` **không ở wave nào**; `.session-counter.json` **không ở wave nào**; logic tick/idempotent/fail-loud/fire-guard/cap = net-new **không chủ**. **⇒ v2: W2 sở-hữu** (gộp cùng `hmw.js` owner). Key `lead_self_audit` trong `memory-budget.json` (đo live: keys hiện = tiers/archive_gate/mfe/crystallized_backfill/harness_floor/token_governor/measured ⇒ **chưa có**) |
| **(4) positive-control** | phụ-thuộc **C2-fix**. Chuỗi fire→chứng-kiến→vá→hết-fire **giữ**. 🔴 **CẤM vá `permission-matrix` trước** |
| **(5) 3 việc** | giữ v1 (rút gọn (a) = `inherit`) |
| **enum ĐÓNG** 🆕 | 🔴 **M4:** v1 đòi "class ∈ enum ĐÓNG trong config" nhưng **không liệt enum** + **không nêu config key** ⇒ enum chỉ sống ở lane D ⇒ mà spec **bơm qua args, worker KHÔNG tự Read** ⇒ worker **không bao giờ thấy** ⇒ **tự chế class** = loãng thống-kê = đúng thứ H24 §2(1) cấm. **⇒ v2 CHÉP enum vào THÂN spec:** `lead_self_audit.flag_classes` = `["view-stale-count","view-stale-status","view-stale-header","view-stale-role-desc","view-residual-asym","gap-carry-dropped","gap-carry-aged","gap-owner-specifics","gap-decision-sunk","gap-underfill"]` (**10 class** — 5 STALE + 5 GAP, khớp H24 §2(1) 5+5 dấu-hiệu) |
## 2.5 owner-sign — giữ v1 (0 adopt, chỉ báo nấc)
---
# ③ CHECKLIST + WAVE (v2)
## 3.1 Δ đồ-thị phụ-thuộc
```
[W0.0] RE-MEASURE ──PHẢI TRƯỚC── mọi thao-tác git 🆕 (R3-C4: spec-số stale khi tới tay worker)
[W0.3] NONWAL==0 → reset --soft ONLY ──CẤM rebase── 🔴 (R3-C1: rebase = detached HEAD + mất việc)
[W0.3] hook-interlock rebase-guard ──CÙNG COMMIT── W0.3 🆕
[W0.6] spawn-probe CRLF ──PHẢI TRƯỚC── ④(a) chọn control + R4 nấc 🆕 (R2-M7: thí-nghiệm quyết-định)
[Sàn1] gate + 4 cờ wrapper ──CÙNG 1 COMMIT── 🔴 (R2-C3: tách = vỡ đường đang chạy)
[W2] STATUS.md `Sub-agents` 12→14 ──CÙNG LANDING── roster 14 🔴 (R3-M2: không thì detector bão)
[W2] `| Policies | **216** |` thêm vào STATUS ──PHẢI TRƯỚC── GAP-3 nửa policy 🆕
[§5.2] squash→count→push ──CÙNG 1 LƯỢT── 🔴 (R3-C3: tách = deadlock, gate tự xoá)
```
## 3.2 Δ bảng xung-đột
| File | v1 | **v2** |
|---|---|---|
| `hmw.js` | 3 hạng-mục | **5** (+PA-2a hằng-số +Sàn-1 gate) — vẫn **GỘP 1 EDIT** |
| `docs/STATUS.md` | ❌ **VẮNG** | 🆕 **2** (Sub-agents 12→14 · +row Policies) — **PHẢI cùng landing W2** |
| `.claude/hooks/wal-flush.ps1` | ❌ **VẮNG** | 🆕 **1** (rebase-state guard) — cùng commit W0.3 |
| `.claude/commands/ultra-on.md` | ❌ **VẮNG** | 🆕 **1** (cờ `args.run`) — cùng commit Sàn-1 |
| `.claude/commands/fable-real.md` | ❌ **VẮNG** | 🆕 **1** (cờ) — cùng commit Sàn-1 |
| `memory-budget.json` | 2, mồ-côi | **2, chủ = W2** |
| `.session-counter.json` | ❌ mồ-côi | 🆕 **chủ = W2** |
## 3.3 WAVE v2
| Wave | Song-song | Task | File |
|---|---|---|---|
| **W0** SOLO | 🔴 không | W0.0 re-measure → W0.1 gitattributes → W0.2 **scoped-only** (KHÔNG mass-checkout) → **W0.3 reset--soft nhánh-A + hook-interlock (1 commit)** → W0.4 README:52 → W0.5 orphan-scope → **W0.6 spawn-probe CRLF (RESTART)** | `.gitattributes` · `session-end.md:111-115` · `wal-flush.ps1` · `README.md:52` · probe |
| **W1** | ✅ 3 lane | ① detector +2 (**anchor_patterns[] số-nhiều**) · ② `agent-frontmatter-eol-check.ps1` · ③ `wal-recovery-test.ps1` 4-ca | 3 file disjoint |
| **W1b** 🆕 | ✅ cùng W1 | `scripts/spawn-model-audit.ps1` (PA-2b) | disjoint |
| **W2** GỘP | 🔴 1 owner | `hmw.js` **1 EDIT** (Sàn-1 gate + VALID_ROLES→14 + H23 note + **PA-2a hằng-số**) **+ 4 cờ wrapper CÙNG COMMIT** + 2 agent MỚI + `memory-budget.json` (`h24_cadence` 6/15/3 + `lead_self_audit` enum) + `.session-counter.json` + **STATUS.md Sub-agents 12→14 + row Policies** | 🔴 **1 commit** |
| **W3** SERIAL | 🔴 | `tiep.md` §0 → `session-start.md` (0.7-trỏ + **0.6b registry-probe** + counter + 2 vai + H23 note) → `session-end.md` **1 PASS** (§5.2 squash→count→push 1-lượt + sentinel + Sàn-5 + validator + counter) → `fable-clone.md` GAP#6 → `agents/README.md` | 5 file |
| **W4** | 🔴 sau W1① | fire detector ⇒ **PHẢI in** `permission-matrix/SKILL.md` → reviewer chứng-kiến → **RỒI MỚI** vá | skill |
| **W5** | 🔴 cuối | `harness-11-engine.md` | engine |
| **W6** | 🔴 | **§5.2 squash→count→push 1 LƯỢT** → adap-report → adap-request → email | broadcasts/ |
## 3.4 Owner-decision — ✅ CHỐT (`owner-decisions-15-07-2026.md`)
| | Chốt |
|---|---|
| **O1** | ✅ **PA-2** — hình-thức: **PA-2a hằng-số + PA-2b audit** (neo-tại-spawn **bất-khả-thi**: param chỉ nhận alias; SE 0 full-id vì H8) |
| **O2** | ✅ **6/15/3** → `memory-budget.json:h24_cadence` |
| **O3** | ✅ `[carry:<slug>]`; "dòng-carry" = **đoạn LOGIC** `NEXT anh`/`NEXT em` trong mega-line |
| **O4** | ✅ **KHÔNG dọn 57** |
## 3.5 Δ n-a (v1 SAI ×3 — R2)
| Mục | v1 | **v2** |
|---|---|---|
| Sàn-1 nửa-(ii) | "≈n-a — không có engine→engine" | 🔴 **SAI — ÁP.** Broadcast: *"**wrapper** gọi xuống engine dùng-chung"*. SE có **4 wrapper** ⇒ deliverable = cờ ở 4 chỗ |
| push-guard (b) else | "n-a — giữ else **vô-hại**" | 🔴 **SAI — MÌN NGỦ.** else đếm toàn lịch-sử = **57** ⇒ chặn vĩnh-viễn ⇒ **bỏ else** hoặc fail-loud |
| H23 §2(4) bộ-soát | "n-a: chưa dựng" | ✅ **GỠ** — PA-2b **dựng thật** |
## 3.6 adap-request v2
| # | Δ nấc |
|---|---|
| **R1** H8⟂pin-simple⟂H23 | **GIỮ** evidenced (hub tự pin 17/17 trong khi broadcast all-inherit) |
| **R2** push-guard KHUNG sai | **GIỮ** evidenced (57 vs 1) **+ MẠNH THÊM**: R3-C3 chứng minh KHUNG *"đặt guard sát push"* **CHƯA ĐỦ** — phải **squash+count+push CÙNG LƯỢT**, nếu không hook chen giữa ⇒ **guard tự-deadlock** ⇒ đề-xuất (γ) bổ-sung KHUNG |
| **R3** side-ref | **GIỮ** — 🔴 **VƯỢT KHUNG (lệch N.2) ⇒ PHẢI request, CẤM tự làm** (nguyên-tắc anh S119). Khai **CHƯA VERIFY thực-nghiệm** |
| **R4** EOL | 🔴 **HẠ NẤC** (§1.C): **KHÔNG** gửi *"đọc mã-nguồn"*. Nấc đúng = *"grep-chuỗi binary thấy 2 dạng regex cùng tồn tại; **CHƯA xác định** dạng nào trên đường đọc thật (lane verify chết giữa chừng); **W0.6 spawn-probe** sẽ trả lời — báo hub sau"*. **Vẫn GIỮ** phần đo được: nhân-quả *squash lật EOL* **SAI với SE** (§5.0=reset--soft, worktree-neutral; nguồn = Migrations **+ lead-written sub-returns** §1.B) + acceptance `count==0` toàn-repo = **dương-giả factory** |
## 3.7 §3.9 GATE v2
```
[ ] W0.0 in {K, NONWAL, porcelain-count} ; mọi entry porcelain ĐƯỢC PHÂN LOẠI ; chưa → ABORT
[ ] W0.1 git check-attr text eol -- .claude/agents/reviewer.md → text:auto eol:lf
[ ] W0.2 scoped gate = 0 (ĐÃ XANH SẴN — KHAI vacuous, KHÔNG tính là thành-tựu)
git add --renormalize --dry-run . → 0 file dirty ; git diff --cached --stat sau = rỗng
🔴 CẤM mass rm+checkout 188
[ ] W0.3 NONWAL==0 → chọn nhánh reset--soft ; REBASE-EXIT không bao giờ non-zero
ls .git/rebase-merge → absent ; assert HEAD~K == origin/main PASS
wal-flush.ps1 có rebase-guard (Test-Path .git/rebase-merge → exit 0)
[ ] W0.6 spawn-probe CRLF → verdict {tolerant|fatal} ghi file ; _crlf-probe.md đã xoá
[ ] Sàn1 gate + 4 cờ CÙNG 1 COMMIT ; Grep args.run trong commands/ ≥ 3 (nay 0)
phóng 3-task thiếu args.run → throw
[ ] §5.2 squash→count→push CHAINED 1 LƯỢT ; KHÔNG turn-boundary ở giữa
sau push: wal: trên origin/main = 57 (KHÔNG tăng, KHÔNG giảm)
[ ] H23 Grep tier:'opus' trong fable-clone.md ≥1 (điều-kiện CẦN, không đủ)
TIER2_EXPECTED_FULL_ID ≥1 hit = claude-opus-4-8
spawn-model-audit fault-inject (expected giả) → PHẢI FLAG
🔸 precedence spawn-param⟂frontmatter = CHƯA TEST → defer phiên lead=Fable (KHAI, không giả-vờ)
[ ] H24 VALID_ROLES.length == 14 AND (ls agents/*.md | grep -v README | wc -l) == 14
🔴 RESTART → spawn-probe 14/14 SỐNG (static-check KHÔNG đủ — broadcast ④d)
STATUS.md | Sub-agents | **14** | CÙNG LANDING ; + row | Policies | **216** |
detector in 2026-07-14 trên STATUS.md:6 (KHÔNG 2026-08-01 / 1987-03-07 / 2026-20-42)
anchor_patterns[] ≥2 dạng ; PHẢI in permission-matrix/SKILL.md TRƯỚC vá
h24_cadence đọc từ config (0 số NHỊP hardcode — KHÔNG đòi 0-số-hardcode toàn file)
/session-start 2× cùng HEAD → +1 ; counter lùi → fail-loud ; bỏ phiên → OVERDUE
[ ] EOL ② roster↔VALID_ROLES↔file = 14/14/14 ; ③(d) 0.6b registry-probe tồn tại
[ ] cicd CI PASS (scripts/*.ps1 + .json + .gitattributes CÓ trigger; agent-memory/runs KHÔNG — AS-6)
```
---
## Nấc trung-thực v2
- **Provenance:** invest `wf_1f6bd5e2-478` (5/5 clean) → spec v1 → review `wf_78a84f9b-03e` (**R2 FAIL 4C+7M · R3 FAIL 5C+2M · R1/R4 chết #53**) → **v2 vá 19 finding**.
- 🔴 **v1 SẼ GÂY MẤT VIỆC** — R3 fault-inject chứng minh: rebase→detached HEAD→hook fail-open commit→abort→mất worktree. **v1 KHÔNG ĐƯỢC CHẠY.**
- 🔴 **CHƯA VERIFY (khôi phục — v1 bỏ, R2-M7):** đường đọc frontmatter `.claude/agents/` là nhánh CR-tolerant hay LF-only ⇒ **W0.6 quyết**. **Kết-luận L3 giữ (thận-trọng), độ-bất-định GIỮ CÙNG.**
- 🔴 **CHƯA TEST:** precedence spawn-param ⟂ frontmatter (H23 §2(2) bắt buộc khai). Hôm nay lead=Opus ⇒ **không phân-biệt được** ⇒ defer, **không giả-vờ đã test**.
- **L2 = PARTIAL** (§1.B): 131/188 Migrations ✓ nhưng phần còn lại có **lead-written sub-returns** ⇒ v1 "toàn bộ do dotnet ef" **SAI**.
- **R1/R4 chết giữa chừng** ⇒ **2/4 trục review KHÔNG có verdict**. Recover: L3 hạ nấc (từ transcript R1) + em-main tự đo. 🔸 **Trục R4 (honesty) CHƯA có lane độc-lập** ⇒ `/fable-real reviewer` PHẢI phủ trục này.
- **KHÔNG overclaim:** Sàn-1 chỉ phủ `hmw.js`; raw Workflow/Agent = **kẽ CÒN-LẠI** (chính run này đi đường đó). Validator **PHÁT-HIỆN** không **NGĂN-CHẶN**. H24 = **quy-ước lead-executes, KHÔNG hook, KHÔNG enforce**. Gate scoped EOL **ĐÃ XANH SẴN****không tính là thành-tựu**.
- **H24 hub dogfood n=1 (mốc-0), chưa chu-kỳ-2** ⇒ cấm bán "đã chứng-minh hiệu-quả". Flag tăng = **mở-rộng-thiết-bị** (caveat d).
- **E-030: hub defer EXECUTE CRLF sang s95** ⇒ SE đi **TRƯỚC** hub; không có mẫu chạy sẵn.