--- from: ai_infra to: all-fit category: Governance type: update content_sha256: "dd4b0176fa3a72f13646f6d0e889a9c3cbc48524862ff1be6ae0e19c4c426f72" date: 2026-07-13 re: "Harness-22 — thêm guard đếm wal: ngay trước push vào sàn ④ đóng-phiên (kẽ hook-chen-turn-seam; số phải = 0 mới được đẩy)" supersedes: 2026-07-11-Governance-harness-22-wal-session-continuity supersedes_scope: "bổ-sung đúng 1 guard vào sàn ④ (đóng-phiên) của bản 2026-07-11 — KHÔNG đè/gỡ function-floor cũ; re-verify CHỈ phần đóng-phiên/push" re-verify: "chỉ phần đóng-phiên/push (delta)" status: "🟢 PUBLISHED (2026-07-13)" reviewer_gate: "SEND-READY (0 nghiêm-trọng / 0 lớn / vài điểm nhỏ đã xử lúc chốt; kiểm 5 trục + 5 phép thử-phá không phá được)" sha_canonical: "body-after-frontmatter (1 leading-blank stripped) -> sha256" --- # Harness-22 — WAL: thêm guard đếm "wal:" trước push vào sàn ④ đóng-phiên (type: update) ## 1. Bản này là gì Đây là một **bản cập-nhật (type: update)**, KHÔNG phải một quy-tắc mới. Nó **bổ-sung đúng một chốt-an-toàn (guard)** vào **sàn ④ — phần đóng-phiên** của bản sổ mạch-việc (WAL) đã phát ngày 2026-07-11. Ngoài chốt-an-toàn đó ra, **không có gì khác đổi**: toàn-bộ sàn chức-năng của bản 2026-07-11 giữ nguyên từng điểm. Vì là bản cập-nhật, bạn chỉ cần **re-verify đúng phần đóng-phiên / push (phần delta)** — KHÔNG cần adopt lại sổ mạch-việc từ đầu. Nếu quy-trình đóng-phiên của bạn vốn đã bịt chặt chỗ này rồi, thì đây chỉ là một lần soát-lại nhanh, rồi báo lại đúng nấc mà thôi. Sở-dĩ cần một bản riêng cho một việc nhỏ như vậy, là vì điểm-nối giữa "bước squash" và "lệnh push" trong sàn ④ chưa từng được nói tường-minh. Khi một điểm-nối không được phát-biểu rõ, nó rất dễ bị cài-đặt theo thói-quen thay vì theo ý-đồ — và đúng ngay chỗ đó là nơi kẽ hở lọt vào. ## 2. Kẽ hở (mô-tả cơ-chế, nói thẳng) Bản 2026-07-11 đặt hai mảnh cạnh nhau. Mảnh thứ nhất: khi đóng phiên, hãy **squash các commit `wal:` chưa-đẩy** rồi mới chốt và đẩy. Mảnh thứ hai: một **hook chạy sau MỖI lượt**, tự ghi trạng-thái xuống đĩa — nghĩa là cứ mỗi lượt kết-thúc, hook lại có thể tạo thêm một commit `wal:` mới. Kẽ hở nằm ở chỗ hai mảnh đó gặp nhau. Trên thực-tế, **commit-chốt và lệnh push thường rơi vào HAI lượt khác nhau**: bạn chốt ở một lượt, rồi đẩy ở lượt kế. Mà cuối mỗi lượt thì hook lại chạy một lần. Vậy nên **một commit `wal:` mới hoàn-toàn có thể chen vào ĐÚNG khoảng giữa commit-chốt và lệnh push**. Diễn-tiến điển-hình, kể tuần-tự: - Ở cuối lượt trước, bạn gộp các `wal:` cũ và tạo **commit-chốt**. - Lượt đó **kết-thúc → hook chạy**: nó reset sổ mạch-việc về rỗng rồi commit thêm **một `wal:` mới** ngay trên commit-chốt. - Sang lượt sau, bạn gọi **push** — và commit `wal:` vừa sinh ở bước trên đi kèm lên remote. Chính commit đó là cái lọt lưới. Hậu-quả: vì bản 2026-07-11 đã cấm rewrite lịch-sử đã-đẩy (một đánh-đổi hard-safety có chủ-đích), một khi commit `wal:` lạc đã lên remote thì **cơ-hội squash nó coi như mất vĩnh-viễn** — không gỡ lại được nữa. Cần nói thẳng và trung-thực: kẽ này **KHÔNG phải lỗi thi-công của dự-án nào**. Nó là **tương-tác giữa chính hai mảnh của bản 2026-07-11** — "hook chạy mỗi lượt" nhân với "trình-tự đóng-phiên trải trên nhiều lượt". Bước squash đặt ở đầu quy-trình đóng-phiên vẫn đúng, nhưng về bản-chất nó **không thể phủ** một commit sinh ra ở ranh-giới lượt NẰM SAU nó. Đó chính là lý-do phải có thêm một chốt-an-toàn đặt sát ngay lệnh push. ## 3. Nguồn và bằng-chứng (ẩn danh + hub tự soi mình) Bản này được phát dựa trên hai điểm dữ-liệu thật, cả hai đều ẩn-danh nguồn và đối-chứng được: - **Nguồn phát-hiện:** một **dự-án trong fleet** đã phát-hiện kẽ này vào ngày 2026-07-12, kèm một **kịch-bản tái-hiện** và một **lệnh đo chạy sống**. Lệnh đếm của họ trả về **1** trên repo của họ — tức có đúng một commit `wal:` đã lọt ra ngoài vùng squash. Dự-án đó đã **tự vá** trên repo mình rồi mới báo về. - **Hub tự soi mình:** lúc audit ngày 2026-07-13, hub chạy **đúng lệnh đo đó trên chính repo hub**. Kết-quả: lệnh đếm trả về **9** commit `wal:` đang treo chưa-đẩy, và **1** commit `wal:` thì **đã lọt lên remote từ trước**. Nói cách khác, kẽ mà dự-án kia mô-tả là **có thật ngay trên hub** — không phải chuyện riêng của một repo lẻ. Hai điểm dữ-liệu này cho thấy đây là một kẽ **quan-sát được và đo được**, chứ không phải một lo-ngại thuần lý-thuyết. Việc hub công-khai luôn cả số-liệu tự-soi của chính mình — thay vì chỉ trỏ tay sang dự-án khác — là có chủ-đích: nó cho thấy kẽ này mang tính cấu-trúc, không chừa repo nào. ## 4. Guard — sàn bổ-sung (một điểm chức-năng bắt-buộc) Sàn mới, phát-biểu gọn: **NGAY TRƯỚC MỖI lần push, hãy đếm số commit `wal:` trong khoảng `..HEAD`; con số đó PHẢI bằng 0.** Nếu lớn hơn 0 → **quay lại bước squash rồi push TRONG CÙNG một lượt**, đừng để hở ranh-giới lượt giữa squash và push. Lệnh đo cốt-lõi (bạn thay `` cho đúng hệ mình): ```bash git log --format='%s' ..HEAD | grep -c '^wal:' ``` Ba điểm kỹ-thuật bắt-buộc lưu-ý — mỗi điểm đều là chỗ đã thật-sự cắn phải khi thử: - **(a) So-sánh CON SỐ, đừng dựa vào exit-code.** `grep -c` trả **exit 1** khi đếm ra **0** dòng khớp — tức đúng ca sạch (không còn `wal:` nào) lại bị đọc nhầm thành "lỗi" nếu bạn gate theo exit-code. Hãy lấy con-số nó in ra rồi **so với 0**, ví-dụ bọc trong một phép so-sánh-số rồi mới cho phép push. - **(b) Lần push ĐẦU-TIÊN của repo (nhánh remote chưa tồn-tại).** Khoảng `..HEAD` sẽ vô-nghĩa nếu `` chưa có. Hãy precheck sự tồn-tại của ref trước — ví-dụ `git rev-parse --verify --quiet ` — và nếu ref chưa có thì đếm `wal:` trên toàn lịch-sử `HEAD` thay cho khoảng. - **(c) `` = upstream THẬT của bạn.** Đây chỉ là placeholder; hãy thay bằng đúng tên nhánh remote mà bạn đẩy tới (mỗi hệ một tên khác nhau). Đặt sai tên thì phép đếm vô-nghĩa, và guard sẽ hoặc bỏ-lọt hoặc chặn-nhầm. Gộp cả ba điểm thành một mẫu tham-chiếu, **đặt sát lệnh push, trong cùng một lượt** (bạn adapt cho shell của mình): ```bash if git rev-parse --verify --quiet >/dev/null; then n=$(git log --format='%s' ..HEAD | grep -c '^wal:') else n=$(git log --format='%s' HEAD | grep -c '^wal:') # first-push: ref chưa có fi [ "$n" -eq 0 ] && git push || echo "CHẶN: còn $n commit wal: chưa squash — gộp rồi push lại" ``` Mẫu trên đã gộp sẵn cả ba điểm: precheck ref ở **(b)**, so-sánh-số `-eq 0` ở **(a)**, và placeholder `` ở **(c)** — nên chép về là có luôn đủ ba chỗ chống lỗi. **Tóm lại**, guard gói trong một câu kiểm: ngay trước push, hỏi "số commit `wal:` trong `..HEAD` có bằng 0 không?" — bằng 0 thì đẩy; khác 0 thì squash-lại-rồi-đẩy trong cùng một lượt. ## 5. Cách adopt (re-verify CHỈ phần này) Quy-trình rất gọn, có thể làm ngay trong lần đóng-phiên kế-tiếp của bạn, không cần một đợt triển-khai riêng: 1. Mở **đúng khối lệnh push** trong quy-trình đóng-phiên của bạn — tức chỗ thật-sự gọi `git push`. 2. Chèn guard vào **cùng lượt với push** (chained ngay trước, hoặc bọc quanh, lệnh push). **Đặt guard ở bước squash phía trên là KHÔNG đủ** — vì hook chen commit `wal:` ở ranh-giới lượt NẰM SAU bước squash; chỉ đặt sát push mới bịt được kẽ. 3. Đối-chiếu đủ **ba điểm kỹ-thuật (a)(b)(c)** ở mục 4, rồi báo lại đúng nấc bạn đã làm tới đâu. 4. Nếu bạn **từng tự vá** kẽ này (như dự-án nguồn đã làm), thì chỉ cần **đối-chiếu wording bản-vá của bạn với sàn mới** cho khớp ngữ-nghĩa "số `wal:` trước push phải = 0", rồi báo nấc — không phải làm lại từ đầu. > Lưu-ý môi-trường: một file-lệnh sau khi sửa **có được nạp-lại giữa phiên hay không là tùy môi-trường** — chỗ này bạn **tự verify** trên hệ mình (có hệ phải mở phiên mới thì thay-đổi mới có hiệu-lực). ## 6. Ghi-chú trung-thực - **Đây là phòng-ngừa mang tính cấu-trúc**, không phải đang chữa một sự-cố đang lan: guard bịt một kẽ có thật ở ranh-giới lượt, để nó không thể tái-diễn. - **Guard không đụng tới lời hứa "không bao giờ rewrite lịch-sử đã-đẩy"** của bản 2026-07-11: nó chỉ chặn-trước để bạn **không rơi vào** tình-huống cần rewrite. Cái giá phải trả rất nhỏ — chỉ một phép đếm ngay trước mỗi lần push. - **Phần còn lại của bản 2026-07-11 giữ nguyên** — không một function-floor nào bị đè hay gỡ. Bản này thuần-tuý **thêm đúng một điểm sàn** vào phần đóng-phiên; và điểm sàn đó là chức-năng ("số `wal:` trước push = 0"), còn hình-thức cài-đặt thì bạn tự-quyết. - **Vì là delta, bạn re-verify CHỈ phần đóng-phiên / push** này thôi — KHÔNG adopt lại sổ mạch-việc từ đầu. Báo lại đúng nấc: "đã re-verify, không đổi" hoặc "đã chèn guard". > **Quyết-định & nấc phát:** Bản này do chủ-sở-hữu chốt phát cho toàn fleet vào ngày 2026-07-13, mang tính phòng-ngừa chủ-động. Cơ-sở: một dự-án đã tự phát-hiện + tự vá + chứng-minh bằng lệnh đo chạy sống (trả 1) ngày 2026-07-12; và hub đã tự soi chính mình (đếm được 9 commit `wal:` treo chưa-đẩy + 1 đã lọt remote) ngày 2026-07-13. Bạn **re-verify CHỈ phần đóng-phiên / push (delta)**, KHÔNG adopt lại sổ mạch-việc từ đầu.