10 KiB
sub-task-1 — LANE W1-② — scripts/agent-frontmatter-eol-check.ps1
Role: implementer · Run: 2026-07-15-S119-adap-6-broadcast · Lane: W1-② (WRITE-lane)
File tạo (DUY-NHẤT): scripts/agent-frontmatter-eol-check.ps1 (NEW, 335 dòng)
VERDICT: ✅ DONE — script live, PS 5.1 parse sạch, fault-inject 5 ca CÓ RĂNG, exit 0.
🔴 Nấc trung-thực: gate trên repo thật = GREEN-BUT-VACUOUS (0 CR / 37 file). KHÔNG tính là thành-tựu.
1. Tiền-đề: lý-do tồn-tại của script này VỪA BỊ HẠ CẤP
W0.6 spawn-probe @S121 ra verdict CRLF-TOLERANT: file agent CRLF hoàn-toàn (276 byte CR) spawn ĐỦ 4 tầng (discovery/parse/spawn/execute), token 45248 (LF) vs 45240 (CRLF) — lệch 8 = chênh chữ trong prompt, KHÔNG do EOL. ⇒ Giả-thuyết "LF-only reader giết registry" BỊ BÁC bằng thực-nghiệm. ⇒ Spec v2:159 ra lệnh: "ra CRLF-tolerant ⇒ validator HẠ GIÁ-TRỊ (chỉ còn hygiene) + KHAI THẬT".
Đã tuân: header .SYNOPSIS/.DESCRIPTION khai thẳng verdict + số đo + phạm-vi-hẹp. Grep xác nhận 0 hit
fatal / kill / break the registry theo nghĩa khẳng-định. Trần severity = MED (HIGH chỉ dành cho self-broken).
Phạm-vi CÒN LẠI của refutation (= lý-do script vẫn sống, nói đúng cỡ):
behaviour-level only · .claude/agents/ only · 1 build win32. KHÔNG phủ: commands/, skills/, hook .ps1.
2. Thiết-kế — 4 quyết-định neo vào bài-học đã có
| # | Quyết-định | Neo |
|---|---|---|
| 1 | Byte-reader [System.IO.File]::ReadAllBytes, đếm 0x0D |
Get-Content (kể cả -Raw) nuốt/chuẩn-hoá CR ⇒ check text-level KHÔNG BAO GIỜ fail được = vacuous BY CONSTRUCTION. Phụ: không decode text ⇒ gotcha #30 không với tới phép đo |
| 2 | Structural, KHÔNG grep-chuỗi — đếm 0x0D trong vùng cắt theo byte-offset |
Bài-học W0.4 #1 tự-tham-chiếu: gate grep-chuỗi trích claim cũ vào file ⇒ FAIL trên bản SỬA ĐÚNG. Structural ⇒ không thể self-match. Cộng: script ở scripts/, quét .claude/{agents,commands,skills} ⇒ path-disjoint |
| 3 | Mọi nhãn PASS/GREEN TÍNH TỪ SỐ ĐO, count bằng glob | Bài-học W0.4 #2 meta-count + spec v3 fix #9h ("validator W1② chạy glob thay hardcode 12") |
| 4 | Scope CHẶT 3 thư-mục, CẤM repo-wide | repo-wide i/lf w/crlf = 188 file (131 EF Migrations) ⇒ acceptance count==0 toàn-repo = đường-giá factory; mass rm+checkout CẤM phiên này (v2 W0.2). 188 = INFORM-only |
Severity ladder (hệ-quả CÓ CHỦ-ĐÍCH của refutation):
HIGH— chỉ self-broken (synthetic control fail ⇒ scan vô-nghĩa). KHÔNG dùng cho CR finding.MED— CR trong frontmatter (bề-mặt parser đọc; đúng bề-mặt W0.6 đã probe trên agents/).LOW— CR chỉ ở body (cùng policyeol=lf, xa hot-path hơn).exit 0LUÔN LUÔN.
agents/README.md CỐ Ý nằm TRONG scope — R2-C1 loại README khỏi ROSTER count (nó không phải agent), nhưng EOL policy là per-file ⇒ README bị quản như mọi file khác. 2 luật khác nhau CÓ CHỦ-ĐÍCH; đã ghi comment cấm "sửa cái này bằng cách copy cái kia".
SYNTHETIC CONTROL (khai rõ trong header — v2 ④(a)): vì W0.6 bác CRLF-fatality ⇒ KHÔNG còn file-đã-chết THẬT
làm positive-control tự-nhiên ⇒ dùng 2 buffer in-memory chạy TRƯỚC mỗi lần quét:
(+) CRLF synthetic → BẮT BUỘC FmCr>0 · (-) LF synthetic → BẮT BUỘC FmCr=0. Fail ⇒ HIGH + UNTRUSTWORTHY.
Header khai đúng giới-hạn: control chứng-minh READER chạy đúng; KHÔNG chứng-minh CRLF gây hại.
3. FAULT-INJECT — 5 ca trên cây tạm %TEMP%\eol-fi-w1a (-RepoRoot)
Vật-liệu: copy .claude/agents/reviewer.md. Phẫu-thuật byte qua ISO-8859-1 round-trip (bảo-toàn byte tuyệt-đối).
| Ca | Inject | Kỳ-vọng | Số đo THẬT | Kết |
|---|---|---|---|---|
| A | all-LF (baseline) | 0 flag | TOTAL FLAGS: 0 (scoped files=1, CR=0) |
✅ |
| B | all-CRLF (mandated) | MED trên đúng file | [EOL] MED | .claude/agents/reviewer.md | eol-frontmatter-cr: 14 CR ... 262 more in body; CR=276 |
✅ FLAG |
| C | FM-CRLF + body-LF | MED, BodyCr=0 | 14 CR ... 0 more in body; CR=14 |
✅ |
| D | FM-LF + body-CRLF | LOW (không MED) | [EOL] LOW | ... eol-body-cr: ... 262 CR; CR=262 |
✅ |
| A2 | gỡ lỗi → LF | hết FLAG | TOTAL FLAGS: 0 (CR=0) |
✅ HẾT FLAG |
Boundary/anti-Goodhart — C+D chứng-minh region-attribution là THẬT, không phải đếm CR toàn-file:
FmCr(C)=14 + BodyCr(D)=262 = 276 = TotalCr(B). Số-học khớp chéo 3 lần inject.
Độc-lập: driver tự cắt báo frontmatter = 14 lines ⇒ khớp FmCr=14.
Round-trip integrity: SHA256 bản tạm sau A2 == bản repo gốc
(4EAF7D3E...07EB cả 2) ⇒ 4 lần inject lossless ⇒ "0 flag" ở A2 KHÔNG phải do file bị nát.
🔴 Ca E — chứng-minh chính SYNTHETIC CONTROL có răng (meta-test):
Lập-luận "green có nghĩa vì control PASS" vô-giá-trị nếu control không bao giờ fail được.
⇒ copy script ra temp, sabotage 1 chỗ duy-nhất (if ($Bytes[$i] -eq 0x0D) → 0x00, needle occurrences=1 = phẫu-thuật
chính-xác), chạy trên cây SẠCH:
(+) CRLF synthetic : fm=True FmCr=0 BodyCr=0 expect fm=True,FmCr>0 -> FAIL
(-) LF synthetic : fm=True FmCr=0 BodyCr=0 expect fm=True,FmCr=0 -> PASS
[EOL] HIGH | scripts/agent-frontmatter-eol-check.ps1 (self) | self-broken: synthetic control FAILED ...
RESULT: UNTRUSTWORTHY - the synthetic control FAILED, so the scan above proves nothing.
⇒ Reader mù CR trên cây sạch KHÔNG ra green mà ra UNTRUSTWORTHY. Không có control, script hỏng sẽ in
"GREEN, 0 flags" không phân-biệt được với script chạy đúng. Repo script KHÔNG bị đụng (sabotage trên bản copy;
final run xác nhận lại). Cây tạm đã xoá (Test-Path = False).
4. Chạy trên REPO THẬT — stdout thật
(+) CRLF synthetic : fm=True FmCr=4 BodyCr=1 expect fm=True,FmCr>0 -> PASS
(-) LF synthetic : fm=True FmCr=0 BodyCr=0 expect fm=True,FmCr=0 -> PASS
.claude/agents scanned=13 frontmatter-CR-files=0 body-only-CR-files=0 CR-bytes=0
.claude/commands scanned=18 frontmatter-CR-files=0 body-only-CR-files=0 CR-bytes=0
.claude/skills scanned=6 frontmatter-CR-files=0 body-only-CR-files=0 CR-bytes=0
TOTAL FLAGS: 0 (scoped files=37, CR bytes measured=0)
RESULT: GREEN-BUT-VACUOUS - 0 CR bytes existed in the scoped set, so this run had nothing to catch.
EXITCODE=0
🔴 KHAI VACUOUS (đúng lệnh, không tính công): 37/37 file = 0 CR ⇒ gate XANH SẴN, 0 việc làm (v2 W0.2 / R2-C4).
Đối-chứng độc-lập TRƯỚC khi viết script: tr -dc '\r' < f | wc -c = 0 trên cả 37 file ⇒ 2 nguồn khớp.
Script tự in nhãn GREEN-BUT-VACUOUS + "Do NOT bank this as an achievement" ⇒ nấc trung-thực nằm trong tooling,
không chỉ trong report. Giá-trị thật = bắt regression về sau, KHÔNG phải lần chạy này.
files with no parseable frontmatter block: 1 = .claude/agents/README.md (đo, không đoán) — không flag; body-CR vẫn đếm.
5. Acceptance
| # | Tiêu-chí | Số đo | Kết |
|---|---|---|---|
| 1 | fault-inject CÓ RĂNG | 5 ca A/B/C/D/A2 + E meta; B flag đúng file, A2 hết flag | ✅ |
| 2 | repo thật 0 flag ở agents/ + khai vacuous | scanned=13, CR-bytes=0; nhãn VACUOUS in tự-động |
✅ |
| 3 | grep non-ASCII = 0 · PS 5.1 parse sạch | LC_ALL=C tr -d '\000-\177' = 0 byte; AST ParseFile = 0 error (PS 5.1.26100.8737) |
✅ |
| 4 | header khai đúng nấc W0.6, không bàn 'fatal' | verdict+45248/45240+phạm-vi-hẹp có trong header; trần MED | ✅ |
Chứng non-ASCII check có răng (chống vacuous): cùng lệnh chạy trên .gitattributes (có tiếng Việt) = 868 byte
non-ASCII ⇒ phép đo phân-biệt được, không phải luôn-luôn-0.
⚠️ grep -P '[\x80-\xff]' (lệnh trong gotcha #37) CHẾT trên môi-trường này: -P supports only unibyte and UTF-8 locales, exit 2 = lỗi, KHÔNG phải "sạch" — suýt đọc nhầm exit-code thành PASS. Dùng LC_ALL=C tr thay.
Self-consistency: file tự nó CR = 0; git check-attr ⇒ text: auto, eol: lf ⇒ chính nó nằm dưới policy nó rao.
6. Containment
git status --porcelain sau khi xong:
?? scripts/agent-frontmatter-eol-check.ps1 <- CỦA TAO
?? scripts/wal-recovery-test.ps1 <- lane W1-③, KHÔNG phải tao
✅ Đúng 1 file code + 1 file sub-task-1.md. KHÔNG git add/commit/push · KHÔNG đụng WAL/agent-memory/CLAUDE/STATUS/spec/run.md
· KHÔNG store_memory/RAG. Cây tạm ngoài repo (được spec lệnh) đã xoá.
7. Đọng lại
- Học: khi thực-nghiệm BÁC lý-do tồn-tại của một cái gate, đường đúng không phải xoá gate cũng không phải giữ nguyên
giọng cũ — mà hạ trần severity + khai verdict NGAY TRONG header + thu scope về đúng phần thực-nghiệm CHƯA phủ.
Tooling tự khai
GREEN-BUT-VACUOUSthì nấc trung-thực sống-sót qua tay người đọc sau, report thì không. - Bất-ngờ 1: CRLF-hoá
reviewer.mdra đúng 276 CR = con số W0.6 báo ⇒ đối-chứng độc-lập vật-liệu probe (cùng file, cùng byte-delta) — không chủ-đích, rơi ra từ fault-inject. - Bất-ngờ 2:
grep -Pcủa gotcha #37 không chạy được ở đây (locale) và exit 2 trông như "0 match" nếu chỉ liếc — một gate hygiene chống-mojibake tự nó có thể vacuous-fail-open. Đã đổi sangLC_ALL=C tr+ positive control. - Bất-ngờ 3: sandbox chặn
Remove-Itemvới path biến (báo nhầmsystem path 'A:'); phải-LiteralPathchuỗi tường-minh mới xoá được cây tạm.