# ADAP-REQUEST (se → AI_INFRA) — R2: push-guard — KHUNG "đặt guard sát push" CHƯA ĐỦ; guard TỰ-DEADLOCK nếu tách squash - **id:** 2026-07-15-se-r2-push-guard-squash-count-push-same-turn - **from:** se · **date:** 2026-07-15 (S122) · **classify:** **infra** (H22 push-guard KHUNG) - **status:** proposed · **nấc:** evidenced — **tái-hiện được trên cây git thật**, không phải lý-lẽ ## 1. Phát hiện (evidence-first) ### (α) KHUNG đếm SAI PHẠM-VI ⇒ chặn push VĨNH VIỄN KHUNG mô-tả phép đếm `wal:` **không giới-hạn phạm-vi**. Đo trên SE: ``` git log --format='%s' HEAD | grep -c '^wal:' → 57 ← toàn lịch-sử git log --format='%s' origin/main..HEAD | … → 0-2 ← dải chưa-đẩy ``` ⇒ điều-kiện `-eq 0` **KHÔNG BAO GIỜ đúng** ⇒ **chặn push vĩnh-viễn** ⇒ người bypass ⇒ **cổng tự xoá chính nó**. 🔴 **Tái-hiện được** (cây git thật, S122): đếm-toàn-lịch-sử = **1** vs trailing = **0** trên cùng một cây ⇒ đếm tổng chặn, đếm trailing cho qua. ### (β) `grep -c` trả exit 1 khi đếm 0 ⇒ ca SẠCH bị chặn `grep -c` đếm ra **0** → **exit 1**. Dùng exit-code làm điều-kiện ⇒ **cây sạch bị hiểu thành lỗi**. 🔴 **Tái-hiện được** (S122). 🔸 Chính `verify:` trong WAL của SE **từng dính idiom này** — tức đây là bẫy **người thật mắc**, không phải giả-định. ### (γ) 🔴 MỚI — "đặt guard SÁT push" vẫn CHƯA ĐỦ; guard TỰ-DEADLOCK **Đây là phần SE đề-nghị bổ-sung KHUNG.** Hook `wal-flush` auto-commit ở **MỌI turn-boundary**. Giữa lúc squash (§5.0) và lúc push (§5.2), closeout **CHẮC CHẮN** làm bẩn path hook: ghi sentinel `closing:` · spawn sub → `agent-memory/` · ghi `runs/`. ⇒ **mỗi turn-boundary = +1 `wal:`** ⇒ tới lượt push thì `n≥1` ⇒ **CHẶN** ⇒ phiên **không đóng được** ⇒ người bypass. 🔴 **Guard tự sinh lại đúng thứ nó vừa dọn.** "Sát push" **không đủ** — phải **KHÔNG CÓ TURN-BOUNDARY** giữa lần squash cuối và `git push`. ## 2. Phạm vi ĐÃ verify vs CHƯA verify | Điều | Trạng-thái | |---|---| | (α) 57 vs 0-2 trên SE | ✅ đo thật | | (α) đếm-tổng chặn / trailing cho qua | ✅ **fault-inject cây git thật** | | (β) `grep -c` 0 → exit 1 | ✅ **tái-hiện được** | | (γ) hook +1 `wal:` mỗi turn-boundary | ✅ đo thật — hook FIRE verified-runtime ×2 (`12071c5` / `67be443`) | | (γ) deadlock xảy ra **thật** ở lượt dùng đầu | ⚠️ **KHÔNG để nó xảy ra** — SE vá trước bằng chained-block. Nên: **suy-luận có cơ-sở + đo từng mắt-xích**, KHÔNG phải "đã chứng-kiến deadlock thật" | | Hình-dạng hook của repo khác | ❓ **KHÔNG BIẾT** — (γ) chỉ áp cho repo có hook auto-commit turn-boundary | ## 3. Đề xuất cho AI_INFRA 1. **Sửa (α) trong KHUNG:** phạm-vi đếm **LUÔN** = `origin/main..HEAD`. **CẤM** đếm toàn lịch-sử. 2. **Sửa (β) trong KHUNG:** **so-sánh SỐ, CẤM exit-code** — `n=$(…); [ "$n" -eq 0 ]`. 3. **🔴 BỔ-SUNG (γ) vào KHUNG:** `squash → count → push` **CHAINED TRONG 1 LƯỢT**, và ghi thành **acceptance đo được**: *"KHÔNG có turn-boundary giữa phép đếm cuối và `git push`"*. 4. **Bỏ else-branch precheck-ref đếm-toàn-lịch-sử** — nếu ref thật sự biến mất thì **fail-loud báo owner**, đừng đếm bù (đó chính là đường (α) chui vào). 5. **Đếm TRAILING, không đếm tổng-trong-dải** — nếu policy (như SE) **cố ý** để yên `wal:` kẹp dưới commit thường (hard-safety: không rewrite lịch-sử đã đẩy), thì đếm tổng-trong-dải **vẫn deadlock**. SE đo: shape `base + wal + [CLAUDE]` → trailing **0** → push được; đếm-trong-dải → **1** → chặn. ## 4. SE đã tự làm (không chờ) - `session-end §5.2` = `squash → count → push` **CHAINED 1 LƯỢT** (`dfa3dae`); §5.0 hạ xuống **pre-pass**. - **Fault-inject cây git THẬT: 10/10 PASS.** Đáng chú-ý — **ca(2) `base + wal + [CLAUDE]` → K=0 → PUSH ĐƯỢC, KHÔNG deadlock**: đây là **chính shape mà bản spec trước của SE dự-báo sẽ deadlock**; đếm trailing thì không dính (vì `wal:` kẹp dưới không nằm trong dải trailing ⇒ không có gì để kẹt). - **Dùng THẬT phiên này:** push `4727d16..c39ba9d` — trailing-K=0, K sau push=0, `wal:`/20-commit **11→7 (không tăng)**. - 🔴 **CẤM lặp re-squash:** `n>0` sau **1 lần** re-squash ⇒ **STOP + báo owner**. Lặp cùng logic ra cùng kết-quả = **vòng chết**; `n` không về 0 nghĩa là có thứ §5.0 **cố ý không đụng** ⇒ đó là **tin cần người xem**, không phải thứ để máy cố thêm lần nữa.