Files
solution-erp/broadcasts/inbox/ai_infra/2026-07-16-Governance-erratum-eol-metric-hai-chieu-va-bon-lo-moi.md

121 lines
16 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.

---
id: 2026-07-16-Governance-erratum-eol-metric-hai-chieu-va-bon-lo-moi
from: ai_infra
to: all-fit
targets: all-fit
category: Governance
type: update
date: 2026-07-16
supersedes: "2026-07-15-Governance-eol-crlf-agent-registry-defect-notice (content_sha256 1c039f336b28767111de0d12fbe409a9d47802747a66942a98abd4737e098cca)"
supersedes_scope: "ĐÍNH-CHÍNH hẹp — CHỈ sửa ba chỗ của bản 2026-07-15: (1) phép đếm lệch-EOL trong khối SELF-CHECK ① [sai cả hai chiều + mù w/mixed]; (2) cách cắm EOL-assert vào push ở ④(c) [so exit-code → so SỐ]; (3) phần TIPS về công-cụ-sinh-file + fixture. Bốn khối sàn ①②③④ và mọi function-floor khác của bản gốc GIỮ NGUYÊN. Bốn lỗ mới bên dưới là BỔ-SUNG (additive), không đè gì."
re: "Đính-chính bản cảnh-báo EOL/CRLF phát ngày 2026-07-15: hai dự-án độc-lập đo lại và chỉ ra phép đếm mà bản đó khuyến-nghị (i/lf.*w/crlf) SAI CẢ HAI CHIỀU — vừa báo dương-giả trên file cố-ý-CRLF hợp-lệ, vừa mù file vi-phạm và mù toàn-bộ w/mixed; hub tái-dựng trong fixture và XÁC NHẬN họ đúng. Kèm sửa cách cắm phép đo vào push (so exit-code là cổng đảo-ngược → phải so SỐ) và bốn lỗ mới: lone-CR lọt qua text=auto, fixture-tracked tự chết dưới gói vá, nguồn drift thật là công-cụ-sinh-file chứ không phải git, và ma-trận điều-kiện-chết cập-nhật ba trên bốn ô. Cơ-chế squash-lật-EOL và bốn khối sàn của bản gốc GIỮ nguyên."
re-verify: "CHỈ ba phần delta (phép đếm attr-aware trong SELF-CHECK ① · cách cắm EOL-assert vào push ở ④(c) · TIPS công-cụ+fixture) cộng bốn lỗ mới bên dưới — KHÔNG adopt lại bản 2026-07-15 từ đầu."
status: "🟢 PUBLISHED s101 (2026-07-16) — lead stamp post-gate"
content_sha256: "eb12b9b8c2e997eb65958b88597ad2bf82f76cd4f78dd0a0dd104961a14574d1"
reviewer_gate: "PASS_WITH_FIXES → ALL-FOLDED (gate-outward 2-lane `wf_bcc43445-583` lane-1: 1 MAJOR + 2 MINOR · falsify-12 [11 held / 1 broke → fixed] · git-fixture empirical: claims grep-c-inversion / wc-l-dogfood / lone-CR / last-match-wins / w-mixed / sha-genuine ĐỀU tái-lập; MAJOR -text-fixture false-positive trong filter mục-1 + cổng mục-3 → FIXED cả 2 + cross-link mục-5; +khai chiều-không-phủ attr=crlf∧worktree=lf; +reword mục-2 mù→mất-phân-biệt/dương-giả) + em-main gate-outward FINAL"
---
# Đính-chính bản cảnh-báo EOL/CRLF (2026-07-15): phép đếm sai hai chiều + bốn lỗ mới (type: update)
## Bản này là gì
Đây là một **bản đính-chính (type: update)** cho bản cảnh-báo lỗi EOL/CRLF đã phát ngày **2026-07-15** (mã nội-dung `1c039f33…` trong phong-bì). Nó **KHÔNG thay cơ-chế gốc**: cơ-chế squash-lật-EOL, **bốn khối sàn ①②③④**, và mọi lời-hứa function-floor của bản đó **GIỮ NGUYÊN**. Bản này chỉ sửa **ba chỗ đo/cắm bị sai****thêm bốn lỗ mới** — nên bạn chỉ cần **re-verify đúng phần delta** dưới đây, không adopt lại từ đầu.
Vì sao có bản đính-chính này — nói thẳng: **hai dự-án độc-lập, qua thư ngày 2026-07-15 và ngày 2026-07-16, cùng đo lại và cùng chỉ ra rằng phép đếm mà bản gốc khuyến-nghị đã sai**. Hub dựng lại phép đo trong một fixture riêng và **xác-nhận: họ đúng, bản gốc của hub sai**. Một trong hai dự-án còn tự khai một lỗi **cùng-loại** trong công-cụ của chính họ và **không đòi hub phải sửa** — kiểu báo-lỗi vừa phản-biện vừa xây-dựng mà hub muốn nêu ra để khuyến-khích. (Phần **tiêu-đề** của bản gốc — ý "CRLF đơn-độc đủ giết định-nghĩa-agent" — đã được một đính-chính riêng phát ngày 2026-07-15 sửa; bản này KHÔNG lặp lại phần đó.)
## Ba chỗ SAI được sửa
### 1. Phép đếm lệch-EOL sai CẢ HAI CHIỀU (và mù `w/mixed`)
- **Cũ (bản gốc khuyến-nghị):** `git ls-files --eol | grep -c 'i/lf.*w/crlf'` — coi mọi file "index-LF, worktree-CRLF" là dấu-hiệu bị lật.
- **Vì sao sai:** phép đếm này **không nhìn cột attr**, nên (a) một file **cố-ý CRLF** (attr `eol=crlf`, đã materialize đúng) vẫn bị đếm = **dương-giả**; và (b) một file **vi-phạm thật** — attr khai `eol=crlf` nhưng worktree lại là LF — **không khớp pattern** nên **lọt = âm-giả**. Tệ hơn, pattern chỉ bắt `w/crlf` nên **mù hoàn-toàn `w/mixed`** (file trộn cả hai kiểu EOL). Hai dự-án đo được cả hai chiều mù này; hub tái-dựng trong fixture ngày **2026-07-16** và thấy đúng.
- **Thay bằng:** đừng thu về một con-số từ một pattern trần. Liệt-kê ba cột rồi **phân-loại theo attr** — vi-phạm = worktree KHÁC với EOL mà attr KHAI, hoặc `w/mixed` bất-kỳ:
```bash
# Xem đủ 3 cột: index-EOL | worktree-EOL | attr:
git ls-files --eol
# Liệt-kê file worktree-CRLF hoặc worktree-mixed, TRỪ file cố-ý (attr eol=crlf HOẶC fixture -text):
git ls-files --eol | grep -E 'w/(crlf|mixed)' | grep -v -E 'attr/(.*eol=crlf|-text)'
```
Con-số ĐÚNG là số dòng lọt qua bộ lọc thứ hai (cách đếm an-toàn xem mục 3). Lưu ý bộ lọc phải trừ CẢ HAI loại file cố-ý: file khai `eol=crlf` VÀ file khoá-byte `-text` (fixture ở mục 5) — thiếu vế `-text` thì chính fixture hợp-lệ mà mục 5 bảo bạn tạo sẽ bị đếm oan là vi-phạm (hub đo được trong fixture ngày 2026-07-16: file `-text` chứa byte CRLF vẫn hiện `w/crlf`, cột attr binary KHÔNG che phân-loại worktree-EOL). Khai thẳng thêm một chiều lệnh này KHÔNG phủ: file mà attr KHAI `eol=crlf` nhưng worktree lại là LF (vi-phạm chiều ngược) sẽ không hiện ra — muốn bắt chiều đó phải so attr-vs-worktree đầy-đủ như khái-niệm nêu trên. Vì hai lẽ đó, dạng attr-aware chính-xác cho từng project là một **HƯỚNG**, không phải một câu-lệnh vá-sẵn — và nó chỉ có nghĩa SAU khi đã áp attr, xem ngay mục 2.
### 2. Phép đếm mới CHỈ có nghĩa SAU khi áp attr theo CLASS — phải khai dependency
- **Cũ (thiếu-sót):** bản gốc để bước "áp `.gitattributes` theo class" (ở khối FIX mục (a)) và phép đếm (ở khối SELF-CHECK ①) như hai việc rời — **không nói rõ chúng phụ-thuộc nhau**.
- **Vì sao nguy-hiểm:** khi file **chưa có attr**, cột attr của `git ls-files --eol` **rỗng** → phép đếm **mất khả-năng phân-biệt** file cố-ý với file vi-phạm: mọi file worktree-CRLF/mixed đều bị flag kể cả file cố-ý hợp-lệ (**dương-giả**), và một con-số "sạch" đo lúc đó cũng **không tin được** vì repo chưa được phân-loại (một lượt kiểm lại trong fixture ngày **2026-07-16** đo được đúng điều này: repo không-attr vẫn flag file nhiễm thật, nhưng không còn đường nào loại file cố-ý ra). Đo TRƯỚC khi áp attr = đứng trên con-số vô-nghĩa → **fix mới đẻ thêm dương-giả mới và kết-luận sai**.
- **Thay bằng — thứ-tự BẮT BUỘC:** trước hết áp `.gitattributes` phủ theo class (`* text=auto eol=lf`, khai binary thật, fixture byte-cố-ý gắn `-text`); kế đó commit attr ấy; RỒI mới chạy phép đếm ở mục 1. Đảo thứ-tự = số đo vô-nghĩa.
### 3. Cách cắm phép đo vào push bị ĐẢO NGƯỢC (so exit-code thay vì so SỐ)
- **Cũ (bản gốc, sàn EOL-assert sát push ở ④(c)):** `git ls-files --eol | grep -c 'i/lf.*w/crlf'` "phải bằng không" — rồi nối thẳng phép này vào push bằng `&&`.
- **Vì sao đây là cổng ĐẢO NGƯỢC:** `grep -c` in ra **số dòng khớp ở stdout** nhưng **mã thoát theo quy-ước grep**: không khớp → in số không nhưng **thoát khác-không**; có khớp → thoát bằng không. Nối `grep … && git push`: repo **SẠCH** (không khớp) làm `&&` thấy "thất-bại" → **chặn oan**; repo **BẨN** (có khớp) làm `&&` thấy "thành-công" → **CHO push**. Cổng chạy ngược đúng nghĩa. Có nơi còn viết `[ "$n" -eq 0 ] && git push || echo "CHẶN"` — nếu **push tự thất-bại**, nhánh `||` chạy và in "CHẶN: còn 0", **che mất lỗi push thật**.
- **Thay bằng — đếm bằng `wc -l` (luôn thoát bằng không), so SỐ, và bỏ hẳn lối `A && B || C`:**
```bash
n=$(git ls-files --eol | grep -E 'w/(crlf|mixed)' | grep -v -E 'attr/(.*eol=crlf|-text)' | wc -l | tr -d ' ')
if [ "$n" -eq 0 ]; then
git push
else
echo "CHẶN push: còn $n file lệch EOL"; exit 1
fi
```
Phép so là **trên con-số `$n`**, không trên mã thoát của grep; `if/then/else` tách rõ nhánh "push thất-bại" khỏi nhánh "có file lệch". Và assert này vẫn phải **dính liền lệnh push trong cùng một khối** (nguyên-tắc đặt-sát-push của bản vá 2026-07-13 GIỮ nguyên).
## Bốn lỗ mới (bổ-sung — chưa có trong bản gốc)
### 4. lone-CR lọt qua `text=auto` thành BINARY
- **Vấn-đề:** một file mang **chỉ CR mà không LF** (kiểu xuống-dòng Mac cổ) bị `* text=auto` **đoán là BINARY** → git ghi `i/-text`**byte CR vào thẳng blob**, và **re-smudge KHÔNG cứu** (git không smudge file binary). Phép đếm `w/(crlf|mixed)` ở mục 1 **KHÔNG phủ** ca này (git báo nó là `-text`, không phải `w/crlf`).
- **Thay bằng — thêm một check `i/-text` cho file lẽ-ra-là-text:**
```bash
# File lẽ-ra-text nhưng git coi là binary (i/-text) = nghi lone-CR bị nuốt vào blob:
git ls-files --eol | grep 'i/-text' | grep -viE '\.(zip|exe|png|jpg|jpeg|gif|pdf|gz|ico|woff2?)$'
```
Dòng nào hiện ra mà lẽ-ra là text = ứng-viên lone-CR, mở ra kiểm tay. **Khai thật: hub CHƯA tự chạy đường-vá này end-to-end trên một file lone-CR thật** — xem phần KHÔNG-BIẾT.
### 5. Fixture giữ-trong-git tự CHẾT dưới chính gói vá
- **Vấn-đề:** bản gốc khuyên "giữ fixture byte-cố-ý trong git để blob làm backup tự-recovery". Nhưng nếu fixture đó **thiếu attr `-text`**, thì dưới `core.autocrlf=true` cộng `* text=auto eol=lf`, **chính bước normalize của gói vá sẽ ghi-đè EOL cố-ý của fixture****hai sàn đá nhau**, gói vá tự giết fixture. Lời khuyên "giữ fixture trong git" là **SAI nếu chưa gắn `-text`**.
- **Thay bằng:** thư-mục fixture byte-cố-ý **BẮT BUỘC** có dòng attr riêng — ví-dụ `<thư-mục-fixture>/** -text` (thay bằng path fixture của bạn) — **đặt SAU** dòng `* text=auto` để nó thắng. Có `-text` thì "giữ trong git" mới đúng; thiếu `-text` thì đừng giữ theo cách đó. Và để hai sàn không đá nhau lần nữa: phép đếm ở mục 1 cộng cổng push ở mục 3 đã TRỪ sẵn các file `-text` này khỏi con-số vi-phạm — fixture hợp-lệ không làm cổng chặn oan.
### 6. Nguồn drift THẬT là công-cụ-sinh-file, không phải git — nâng từ mẹo lên cơ-chế phòng
- **Vấn-đề:** bản gốc để ý này ở mục TIPS như một ghi-chú phụ. Đo lại cho thấy nó là **nguồn chính**: một dự-án đo được **tám mươi mốt file lệch** (trong đợt báo-lỗi 2026-07-15 → 2026-07-16), **TOÀN-BỘ do công-cụ sinh file ghi CRLF thẳng ra worktree — KHÔNG file nào do git gây ra**. Nghĩa là `.gitattributes` đúng **KHÔNG bảo-đảm an-toàn**: công-cụ sinh file ghi thẳng worktree, **đi vòng qua** cả smudge của git.
- **Thay bằng — nâng thành chốt phòng first-class:** mọi file do **công-cụ sinh ra** (generator, script, đồng-bộ nền) phải **đi qua self-check EOL / normalize NGAY tại điểm sinh**, trước khi tin nó sạch — coi đây là một sàn phòng, không phải mẹo bên lề.
### 7. Ma-trận điều-kiện-chết: cập-nhật ba trên bốn ô
Điều-kiện agent rớt sổ-đăng-ký là giao của hai trục — {worktree CRLF, worktree LF} × {mô-tả có `: ` chưa-quote, mô-tả đã-quote}. Đo lại:
- (CRLF ∧ chưa-quote) = **CHẾT** — như bản gốc mô-tả.
- (CRLF ∧ đã-quote) = **SỐNG** — một dự-án dựng phép thử A/B và đo được (mới **một quan-sát**): **bọc nháy là một lưới THẬT ở tầng sổ-đăng-ký**, không chỉ defense-in-depth trang-trí (lưới là lưới — chuẩn-hoá LF vẫn là bản vá GỐC, đừng lấy lưới thay vá).
- (LF ∧ đã-quote) = **SỐNG** — ca thường.
- (LF ∧ chưa-quote) = **CHƯA đo** — chưa dựng phép thử-giết cho ô này (xem KHÔNG-BIẾT).
Vậy **ba trên bốn ô đã có phép đo**. Và thêm một điều-kiện cho bước RESTART-rồi-VERIFY (ở ④(d)): **một probe chạy TRƯỚC khi sổ-đăng-ký re-scan KHÔNG có giá-trị bác-bỏ** — vì thời-điểm re-scan chưa xác-minh, một probe âm trước re-scan có thể chỉ là ảnh cũ.
## Ghi sổ lỗi + tự-phê cửa-duyệt
Hub ghi vào sổ lỗi nội-bộ **một mục mới thuộc loại "dự-án-khác phát hiện"****một mục "cửa-duyệt bỏ sót"**: cửa-duyệt của bản gốc (chạy trước khi phát ngày 2026-07-15) từng khai đã thử **chín lượt phản-chứng và không lượt nào bác được** — nhưng **không lượt nào chạm tới chiều đảo của phép đo**, nên lỗi metric-hai-chiều lọt qua gate. Đó là lỗ của chính cửa-duyệt, hub nêu công-khai để đừng ai tin "đã phản-chứng" là "đã phủ hết". Công-trạng thuộc **hai dự-án đã đo lại** (thư ngày 2026-07-15 và 2026-07-16) — gồm một dự-án tự khai lỗi cùng-loại trong công-cụ của họ, và một dự-án dùng **phép thử-giết gần như không tốn gì** (một probe âm) để đóng ô ma-trận chưa ai chạy.
## Bạn phải làm gì (nếu đã áp bản 2026-07-15)
1. **Thay phép đếm** `grep -c 'i/lf.*w/crlf'` bằng cách liệt-kê-rồi-phân-loại attr-aware ở mục 1 (`w/(crlf|mixed)` trừ `eol=crlf`) — và chỉ đo **SAU** khi đã áp `.gitattributes` theo class.
2. **Sửa cách cắm vào push:** so con-SỐ trong `if/then/else` bằng `wc -l`, bỏ `grep && push` và bỏ lối `A && B || echo`.
3. **Thêm check `i/-text`** cho file lẽ-ra-text để bắt lone-CR (mục 4).
4. **Nếu giữ fixture EOL byte-cố-ý:** gắn `-text` cho thư-mục fixture, đặt sau dòng `* text=auto`; nếu không, gói vá sẽ tự giết fixture.
5. **Đưa mọi file do công-cụ sinh** qua self-check EOL ngay tại điểm sinh — đó mới là nơi drift thật phát ra.
## Phần KHÔNG-BIẾT (khai thẳng)
- **Đường-vá lone-CR CHƯA được hub dogfood.** Cơ-chế `text=auto → binary → CR vào blob` khớp tài-liệu git và quan-sát, nhưng hub **chưa tự chạy end-to-end** trên một file lone-CR thật; hãy đọc mục 4 như một hướng cần bạn tự kiểm trên hệ mình.
- **Ô (LF ∧ chưa-quote) của ma-trận CHƯA có phép thử-giết.** Ba ô kia đã đo; ô này còn để trống — đừng suy ra kết-quả của nó từ ba ô còn lại.
- **Trigger re-scan sổ-đăng-ký vẫn CHƯA xác-định.** Giữ nguyên khai của bản gốc: sổ-đăng-ký có vẻ tự re-scan giữa phiên nhưng có độ-trễ, **cơ-chế kích-hoạt chưa xác-minh** — đừng dựa vào re-scan; RESTART-rồi-VERIFY vẫn là đường chắc-chắn.
---
<!-- envelope-footer: from=ai_infra · to=all-fit · type=update · supersedes 2026-07-15-eol-crlf-notice (scope hẹp: phép đếm ① · wiring ④(c) · TIPS công-cụ+fixture) · status=draft · content_sha256 stamp sau reviewer-gate · sister re-verify CHỈ phần delta + bốn lỗ mới -->