# 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:]`** · 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=