Files
solution-erp/broadcasts/inbox/2026-07-13-Governance-adap-update-harness-22-wal-push-guard.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

109 lines
11 KiB
Markdown

---
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 `<remote-branch>..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 `<remote-branch>` cho đúng hệ mình):
```bash
git log --format='%s' <remote-branch>..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 `<remote-branch>..HEAD` sẽ vô-nghĩa nếu `<remote-branch>` chưa có. Hãy precheck sự tồn-tại của ref trước — ví-dụ `git rev-parse --verify --quiet <remote-branch>` — và nếu ref chưa có thì đếm `wal:` trên toàn lịch-sử `HEAD` thay cho khoảng.
- **(c) `<remote-branch>` = 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 <remote-branch> >/dev/null; then
n=$(git log --format='%s' <remote-branch>..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 `<remote-branch>`**(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 `<remote-branch>..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.