[CLAUDE] Docs: S148 — session-model port form hub + /check-email 4 cửa + Sàn-3 dual-accept

Session-model (owner chốt "đối ứng đúng chính xác như hub"):
- Form hub: _context-s-<N>.md (STOCK-map + FLOW append-only + STOCK-touched)
  + _pause-<i>/_tiep-<i> marker 5-trường + _snapshot-<i> + _end (thay closed.md)
- Port /snapshot + scripts/session_scaffold.py (near-verbatim)
  + scripts/session_ctx.py TRIMMED CÓ KHAI (chỉ machine-block + secrets-sweep;
    KHÔNG port jsonl/overhead/cap-getter vì chưa có caller = ghost-wire)
- session-2 migrate sang form hub; session-1 giữ legacy (FROZEN)

Sàn-3 ORPHAN-L:
- DUAL-ACCEPT hub + legacy; glob pause-* KHÔNG khớp _pause-1.md nên không đếm đôi
- VÁ bug có sẵn từ S146: chốt-kết ĐÓNG TRỌN thư-mục (bản cũ c=1 chỉ tha 1 pause,
  lệch chính câu session-end §6.3-bis vẫn nói "mọi pause")
- Fault-inject 10/10 hai chiều + anti-Goodhart

/check-email:
- Wire 4 CỬA phiên (session-start/tiep/session-end/pause), 2 CHẾ-ĐỘ:
  DÒ ~5ms ở cửa dừng-nối (ràng buộc BINDING hub goi-chot §3) ⟂ KÉO ở bookend
- DÒ quét 2 kênh + định tuyến: outbox/se -> /check-email · outbox/all -> /adap-apply
- STAGE-2: 10 thư fan-out verify 2 tuyến 10/10 -> inbox/ai_infra/; backlog root = 0

HANDOFF re-stamp: #1 ĐÓNG (trio đã chạy S144) · #2 đổi trục · #3 anh chốt (a)
+ 4 mục mới (13)-(16); carry #15/#17 đóng, #16 đóng nửa (khai rõ vế còn hở)

H24 tick S147->S148: counter 21->22 CLEAN

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
pqhuy1987
2026-07-24 18:03:16 +07:00
parent 6da7c8898d
commit 24483935cb
23 changed files with 676 additions and 28 deletions

View File

@ -9,10 +9,58 @@ argument-hint: <from_project | all>
## Tham số
- `$1` = from_project (BẮT BUỘC) ∈ 6 others, hoặc `all` = quét cả 6.
## Nhịp chạy — 🔴 4 CỬA PHIÊN (owner chốt S148, 2026-07-24)
> 🔴 **Đây là NHÀ CANONICAL của "khi nào chạy `/check-email`".** 4 file lệnh cửa **chỉ TRỎ vào đây** rồi gọi lệnh; **CẤM chép luật sang** (B1 — chép 4 nơi = 4 nguồn sự-thật).
**Anh chốt @S148:** *"mỗi session end/start luôn — vì 1 session giờ có thể kéo dài 2-3 phiên qua 2-3 ngày."*
⇒ nhịp neo vào **SỰ-KIỆN PHIÊN**, **KHÔNG** vào đồng-hồ ngày. Lý-do anh nêu là lý-do kỹ-thuật đúng: một phiên-LOGIC trải nhiều cửa-sổ nhiều ngày ⇒ ngưỡng-theo-ngày **không map** được vào nhịp làm việc thật.
🔴 **Vì sao 4 cửa chứ không 2 — lead MỞ RỘNG từ câu chữ, khai thẳng để anh bác được:** cửa VÀO có 2 và cửa RA có 2.
| | cửa-1 | cửa-2 |
|---|---|---|
| **VÀO** | `/session-start` (phiên mới) | `/tiep` (nối phiên-logic) |
| **RA** | `/session-end` (đóng sổ) | `/pause` (dừng chủ-động) |
Chỉ cắm 2 cửa `session-start`/`session-end` thì **đúng ca anh đang lo VẪN LỌT**: phiên S148 vào bằng `/tiep`, phiên trước ra bằng `/pause`**cả hai lần đều không check**. Mà chính câu *"1 session kéo 2-3 phiên"* hàm ý các phiên GIỮA vào bằng `/tiep`**phần lớn cửa nằm ở nhánh `/tiep`**, không ở `/session-start`. Phủ 4 cửa mới đạt được điều anh nói.
### 🔴 HAI CHẾ-ĐỘ — sửa @S148 sau khi đọc thư `goi-chot-owner-nam-khoan` khoản 3 (BINDING)
> **Lead tự bắt vi-phạm của chính mình:** bản đầu @S148 cắm **PULL đầy-đủ** vào cả 4 cửa. Thư hub `2026-07-19-Governance-goi-chot-owner-nam-khoan` §3 là **ràng-buộc thiết-kế CỨNG**, verbatim: *"bất kỳ van/gate/phép-đo nào về sau cũng **KHÔNG ĐƯỢC** chặn hoặc làm chậm các cửa **dừngnốicheckpoint**"*, floor: *"bước nào nặng (spawn agent, đo đạc lớn, **quét rộng**) đang nằm trong đường pause-tương-đương là **vi-phạm**: dời nó về **closeout/bookend**"*. ⇒ `/pause` + `/tiep` **là đúng 2 cửa đó**.
> 🔴 **Hub bắt ĐO chứ không đoán** (SELF-CHECK: *"Đo wall-clock một lần — điểm dừng phải rẻ"*). **Đo @S148, 3 lượt:** **dò** (list 6 repo + so id) = **66ms lạnh / 45ms nóng**; **kéo** (copy + hash + `python stamp_verify.py`) = python-startup **~200500ms × số thư**. ⇒ **dò KHÔNG nặng, kéo MỚI nặng.** Nên vá đúng là **tách 2 chế-độ**, KHÔNG phải bỏ cửa — bỏ cửa sẽ mất đúng thứ anh cần (phiên giữa vào bằng `/tiep`).
| chế-độ | cửa | làm gì | chi-phí |
|---|---|---|---|
| **DÒ** (detect-only) | `/tiep` · `/pause` | list + so id → in `thu-moi: se=X all=Y`. 🔴 **KHÔNG copy · KHÔNG hash · KHÔNG python.** X hoặc Y > 0 ⇒ nêu **1 dòng** rồi đi tiếp, để bookend kéo | ~5ms |
| **KÉO** (đầy-đủ) | `/session-start` · `/session-end` | `se>0`**`/check-email`** STAGE 1 (copy + verify 2 tuyến + log `_index`) · `all>0`**`/adap-apply`** | theo số thư |
🔴 **DÒ PHẢI QUÉT CẢ HAI KÊNH — đây là kẽ thật, và nó nằm ở NHỊP chứ không ở tool:** `outbox/se` (directed, → `/check-email`) **VÀ** `outbox/all` (fan-out, → `/adap-apply`). Không có nhánh `all` thì **10 broadcast đợt adap-11 nằm im 5 ngày** (07-18→07-23) — ca đã xảy ra thật, không phải giả-định. **DÒ chỉ ĐẾM và ĐỊNH TUYẾN, không kéo** ⇒ vẫn rẻ.
🔸 **Watermark cho `outbox/all`:** bỏ qua id ≤ **`2026-07-15`** — 51 file mốc 06-02→07-15 là lớp *đã-adopt-đọc-tại-chỗ* (`/adap-apply` đọc thẳng bên AI_INFRA, **KHÔNG đòi copy** ⇒ vắng mặt trong inbox là **BÌNH THƯỜNG**, không phải nợ). Không có watermark thì mỗi lượt DÒ kêu 51 cái rồi tự bị bỏ qua.
🔒 **Bất-biến:** việc NẶNG chỉ sống ở **bookend**. Ai thêm bước vào đường `/pause`·`/tiep` sau này **phải đo wall-clock trước**, đúng câu hỏi hub đặt: *"có làm điểm dừng đắt lên không"***TRƯỚC** khi bàn giá-trị của bước đó.
**Cách chạy ở mỗi cửa — `/check-email all`:**
- 🟢 **Không có thư mới ⇒ 1 dòng, im lặng đi tiếp.** KHÔNG báo-cáo dài, KHÔNG chờ anh.
- 🔴 **FAIL-SOFT, CẤM chặn nghi-thức:** lỗi bất-kỳ (repo bên kia không có trên máy · path đổi · thiếu python) ⇒ in `check-email loi (khong chan)` rồi **ĐI TIẾP**. Cùng khuôn `nhip-no-probe.ps1`: một bước MỚI **không bao giờ được phép** làm hỏng nghi-thức đã chạy tốt.
- Có thư ⇒ chạy trọn **STAGE 1** (copy + verify hash). **STAGE 2** (move → `processed`) đi theo việc xử-lý, **KHÔNG ép** trong cùng lượt.
**Quan-hệ với vế-4 `pull-cach` (`nhip-no-probe.ps1`) — ĐỔI VAI:** trước định làm **chuông báo** (cần ngưỡng `pull_warn_days`). Nay 4 cửa là cơ-chế CHÍNH ⇒ `pull-cach` thành **chỉ-báo sức-khoẻ của chính nghi-thức**: số ngày cứ leo trong khi phiên vẫn mở/đóng đều đặn ⇒ **nghi-thức đang bị chạy tắt**, chứ không phải hub im. 🔒 **`pull_warn_days` CỐ Ý để TRỐNG** — anh không đặt số @S148, và script cấm tự chế mặc-định.
🔸 **Giới-hạn giữ khai (đo @S148):** vế-4 mạnh với **quãng im DÀI**, yếu với **trễ-kéo NGẮN** — ca hub-gửi-giục 07-18 chỉ `N=2` mới bắt, mà `N=2` nằm ngay trên trung-vị ⇒ kêu gần như liên-tục. Đừng kỳ vọng `pull-cach` chặn tái-diễn ca đó; **4 cửa mới là thứ chặn nó.**
## Quy trình 2-STAGE (audit qua folder)
**STAGE 1 — Nhận (đọc → inbox root, PENDING):**
1. Validate `$1`.
2. READ `<from>/broadcasts/outbox/se/*.md` (message gửi cho se).
2. READ `<from>/broadcasts/outbox/se/*.md` (message gửi **đích danh** se).
🔴 **CHỈ `outbox/se` — ĐÚNG, đừng "sửa" thành đọc cả `outbox/all`.** Hai kênh, hai tool, hai sổ:
| kênh | nội dung | tool kéo | sổ theo dõi |
|---|---|---|---|
| `outbox/se/` | thư **directed** (`to: se`) | **`/check-email`** (file này) | `broadcasts/_index.md` §INBOUND |
| `outbox/all/` | **fan-out** (`to: all-fit`) | **`/adap-apply`** ([`adap-apply.md:14`](adap-apply.md) đọc **thẳng tại chỗ**) | **KHÔNG** vào `_index` — xem header `_index.md` dòng 7 |
🧊 **Vết sai @S148 — giữ làm bài học:** lead đọc `C14-disposition-per-khoan.md:21` (@S144) khai *"kẽ đã bịt: `/check-email` bước 2 chỉ đọc `outbox/se`, không nhắc `outbox/all`"***tin bản tóm-tắt** → sửa bước này thành đọc cả 2 kênh. **Sai:** `outbox/all` chưa bao giờ là việc của `/check-email`. Kiểm ngược bằng máy: **22/22** thư `outbox/se` đều có dòng `_index`, **thiếu 0** ⇒ tool này vốn **không hề thủng**. 🔴 **Hai lỗi chồng nhau, cả hai đều là *tin chữ thay vì đo*:** C14 tuyên "đã bịt" một kẽ **không tồn tại**, rồi lead vá một tool **không hỏng**.
🔴 **Kẽ THẬT nằm ở NHỊP, không ở tool:** không cửa phiên nào **dò** `outbox/all` ⇒ 10 broadcast fan-out nằm im **5 ngày**. Vá đúng = **DÒ 2 kênh ở cửa phiên rồi ĐỊNH TUYẾN** (§"Nhịp chạy" trên), KHÔNG phải nhét kênh này vào STAGE 1 của tool kia.
3. Mỗi file CHƯA có trong inbox (so id): **COPY VERBATIM**`broadcasts/inbox/<id>.md` (**root = pending**). [repo MÌNH §J2]
4. **Verify đối chứng:** (a) **whole-file** `Get-FileHash` copy == nguồn (byte-identical = tuyến CHÍNH); (b) **body** recompute `SHA256(body)` == `content_sha256` khai ở frontmatter.

View File

@ -22,7 +22,33 @@ Thực-hiện **tuần-tự 5 bước** sau; trong lúc chạy **KHÔNG nhận v
## 2.6 Ghi context-block vào thư-mục phiên-LOGIC (S146 — lane CỘNG-DỒN, cặp với `/tiep §2.6`)
- **Append MỘT khối mới** vào `.claude/sessions/session-<N>/pause-S<nn>-<yyyyMMddTHHmm>.md` (`<N>` = phiên-LOGIC **đang mở** — xem [`session-start.md`](session-start.md) BƯỚC 0.8).
🔴 **FORM HUB (owner chốt @S148 "đối ứng đúng chính xác như hub") — TÁCH marker ⟂ narrative, KHÔNG gộp 1 file như form SE cũ:**
**(A) Marker `_pause-<i>.md`** — `<i>` = số TUẦN TỰ trong thư-mục (`max(_pause-*)+1`), **KHÔNG** nhãn `S<nn>`, **KHÔNG** timestamp trong tên. Đúng **5 trường, ~200B**, không thêm bớt:
```
ts: <ISO-8601 +07:00>
head-sha: <full sha, git rev-parse HEAD>
window-ordinal: <thứ mấy trong phiên-logic>
jsonl-hint: <project-dir>/<session-uuid>
account-label: none
```
**(B) Narrative → APPEND vào `_context-s-<N>.md`** (một file DUY NHẤT/phiên-logic, cộng dồn) — thêm đúng 1 entry `### PAUSE-<k> <ts>` dưới `FLOW-START`:
- 🔴 **Dòng đầu entry = `> anh: <tin-nhắn anh VERBATIM>`** — chép **nguyên văn**, CẤM paraphrase. Không có tin-nhắn ⇒ ghi `(THIẾU — lý do)`, **CẤM dựng lại từ trí nhớ**.
- Rồi 3 mục cũ: **(1) quyết-định đã CHỐT** · **(2) delta còn SỐNG** · **(3) con-trỏ**.
- 🔴 **FLOW append-only, entry cũ IMMUTABLE** — CẤM rewrite, CẤM tự-tóm (chống self-summary lossy). Vượt `session_ctx_kb` ⇒ distill **SECTION CŨ** thành pointer, KHÔNG sửa entry verbatim.
**(C) Máy-derive `§(c) STOCK-touched`** — `python scripts/session_ctx.py machine-block --session <N> --json` → điền bảng §(c) của `_context-s-<N>.md`. **KHÔNG điền tay** (template ràng "máy-derive @pause/snapshot").
🔸 **Khai giới-hạn:** `changed_files` = `git diff anchor..HEAD`**chỉ phần ĐÃ COMMIT**; việc còn dirty không hiện. Đừng đọc thành "toàn bộ việc đã làm".
**(D) AUTO-SNAPSHOT — chạy `/snapshot` §2→§4 ngay trước bước 3** *(đóng `[carry:pause-autosnap]` #17, anh chốt @S148)*:
-**Đo trước khi wire, đúng câu hub bắt hỏi** (`goi-chot` §3 — *"có làm điểm dừng đắt lên không"* phải hỏi TRƯỚC khi bàn giá-trị): `machine-block` **~140ms** · `secrets-sweep` **~64ms** (3 lượt, tb).
- 🔴 **Chi-phí RÒNG của auto-snap chỉ là ~64ms + 1 write**, KHÔNG phải 204ms: `machine-block` **vốn đã phải chạy** ở (C) cho §(c) STOCK-touched. `/pause` cũng vốn đã commit sẵn ở bước 4.
- 🔸 **Ranh giữ khai:** hub **KHÔNG** ràng 1 pause = 1 snapshot (đo đĩa hub: `session-102` pause=3/snap=5 · `session-107` pause=2/snap=1). SE chọn auto-snap-tại-pause là **quyết-định SE**, không phải floor hub — ai thấy đắt thì gỡ, đã có số để cãi.
🧊 **Form SE cũ `pause-S<nn>-<ts>.md` (gộp marker+narrative) = LEGACY, CẤM viết mới.** Sàn-3 ⑤ vẫn **nhận** nó (dual-accept, `tiep.md §0`) vì `session-1` còn dùng — đúng luật retire: *gỡ nhánh legacy khi tập di-sản RỖNG, giữ khi CÒN người thụ-hưởng*.
- `<N>` = phiên-LOGIC **đang mở** — xem [`session-start.md`](session-start.md) BƯỚC 0.8.
- 🔴 **Scaffold idempotent (owner chốt @S146 "giống hub"):** thư-mục chưa có ⇒ **TẠO**; đã có ⇒ **DÙNG LẠI, CẤM đè**. Chạy lại nhiều lần vô hại.
- 🔴 **NHƯNG `/pause` KHÔNG BAO GIỜ tự tăng `<N>`** — cấp-số là **độc-quyền `/session-start`** (BƯỚC 0.8, canonical; B1 — mục này chỉ TRỎ). `/pause` chỉ tạo thư-mục cho số **đang mở**. Không có số nào đang mở (vào thẳng bằng `/tiep` rồi `/pause`, chưa từng `/session-start`) ⇒ dùng `max+1` **và ghi 1 dòng khai** trong khối: `N-cap-ngoai-session-start: <N> (ly-do: <...>)` — để `<N>` không bao giờ xuất-hiện mà không ai biết nó ở đâu ra.
- 🔴 **ACCUMULATE — CẤM ghi đè, CẤM sửa khối cũ.** Mỗi `/pause` = **một file mới**. (Ghi đè = mất chính thứ mà lane này sinh ra để giữ.)
@ -31,6 +57,14 @@ Thực-hiện **tuần-tự 5 bước** sau; trong lúc chạy **KHÔNG nhận v
- **CẤM secret** (thư-mục này sẽ được commit — cùng kỷ-luật WAL bước 3).
- 🔸 Hook `wal-flush.ps1` đã phủ `.claude/sessions/` (path thứ-4, S146) ⇒ khối này **tự vào `wal:` commit** ở turn-boundary. Vẫn **PHẢI add đích-danh** ở bước 4 (đừng dựa vào hook để chốt điểm dừng — hook là lưới, không phải nghi-thức).
## 2.7 Kéo thư cross-project (cửa RA 2/2 — owner chốt S148)
**DÒ 2 kênh** (`outbox/se` + `outbox/all` × 6 repo) — **TRƯỚC** khi ghi WAL (bước 3), để `thu-moi: se=X all=Y` kịp vào `carry:`/context-map nếu có.
🔴 **CHỈ list + so id. KHÔNG copy · KHÔNG hash · KHÔNG python**`/pause`**cửa dừng**, ràng-buộc BINDING của hub (`goi-chot` §3) cấm làm nó đắt lên. Kéo thật = việc của bookend.
> 🔗 **Luật nhịp đầy-đủ = canonical [`check-email.md`](check-email.md) §"Nhịp chạy — 4 CỬA PHIÊN".** 🔴 **B1 — CHỈ TRỎ + GỌI, CẤM chép luật.**
> 🔴 **KHÔNG chặn điểm dừng:** lỗi ⇒ `check-email loi (khong chan)` → đi tiếp bước 3. `/pause` tồn-tại để **dừng an-toàn**; một bước kéo thư hỏng **không được phép** giữ anh lại.
## 3. Cập-nhật `.claude/WAL.md` đúng schema
- **`chain:`** — đầy-đủ mọi mục trạng-thái (`[x]` đã-xong · `[!]` đang-dở · `[ ]` chưa-làm), **KÈM BẰNG-CHỨNG** là một lệnh / đường-dẫn / hash chứng-minh trạng-thái đó (KHÔNG mô-tả suông).
- **`next:`** — đúng **một mệnh-lệnh cụ-thể**: làm gì tiếp theo.

View File

@ -21,6 +21,14 @@ Em main PHẢI echo **TOÀN BỘ nội dung command body này** (đầy đủ Ph
> **Vì sao ở BƯỚC 0, không muộn hơn:** phiên bị cắt **giữa lúc đóng** là ca nguy-hiểm nhất — WAL đã flush một phần, chưa push, trông như sạch. Đặt dấu TRƯỚC mọi flush ⇒ phiên kế **thấy `closing:` treo** và biết là bị cắt (Sàn-3 bậc-MẠNH ③, `tiep.md` §0.b).
> **Net-zero:** §6.4 vốn **LUÔN chạy** ⇒ thêm 1 dòng xoá = 0 chi-phí. Acceptance: chạy no-op trọn-vẹn ⇒ `grep -c '^closing:' .claude/WAL.md` = **0**; cắt giữa chừng ⇒ phiên kế **thấy** dấu.
## 📋 BƯỚC 0.5 — Kéo thư cross-project (cửa RA 1/2 — owner chốt S148)
**DÒ 2 kênh** rồi **KÉO đầy-đủ** theo định-tuyến (`se>0``/check-email all` · `all>0``/adap-apply`) — **TRƯỚC Phase 1 FLUSH**.
> 🔗 **Luật nhịp đầy-đủ = canonical [`check-email.md`](check-email.md) §"Nhịp chạy — 4 CỬA PHIÊN".** 🔴 **B1 — CHỈ TRỎ + GỌI, CẤM chép luật.**
> 🔴 **Vì sao TRƯỚC flush, không sau:** closeout **ghi sổ** (STATUS · HANDOFF · session-log · carry). Thư về sau khi sổ đã ghi thì **lỡ mất kỳ này** và nằm chờ tới cửa vào kế. Kéo trước ⇒ thư mới kịp vào đúng bản ghi của phiên.
> 🔴 **KHÔNG chặn closeout:** lỗi ⇒ `check-email loi (khong chan)` → đi tiếp Phase 1. Sàn-2 sentinel ở BƯỚC 0 đã đặt TRƯỚC bước này ⇒ cắt giữa chừng vẫn phát-hiện được.
## Phase 1 — FLUSH (sub-agent memory)
**Điều kiện:** Chỉ xử lý con đã spawn trong session. KHÔNG spawn mới chỉ để flush (agent đã update MEMORY khi return).
@ -360,13 +368,16 @@ git push origin main # → git.baocaogiaoduc.vn/vietrep
### 6.3-bis 🔒 Chốt-kết `_end` — đóng băng phiên-LOGIC (owner chốt @S146 "giống hub")
> Floor manifest `101e69d6` §1: dấu-mốc thứ-4 = **"Chốt-kết (`_end`) — dấu đóng băng khi phiên-LOGIC thực sự khép lại"**. SE form = `closed.md`. Chân này **trước S146 CHƯA wire** ⇒ cân-sổ ORPHAN-L chỉ có nửa vào, không có nửa khoá (kêu oan ca *"pause rồi đóng thẳng không qua `/tiep`"*). Nay đóng.
> Floor manifest `101e69d6` §1: dấu-mốc thứ-4 = **"Chốt-kết (`_end`) — dấu đóng băng khi phiên-LOGIC thực sự khép lại"**. 🔴 **SE form = `_end` kể từ S148** (owner chốt *"đối ứng đúng chính xác như hub"*); form cũ `closed.md` = **LEGACY, CẤM viết mới** — `session-1` còn dùng nên Sàn-3 vẫn nhận. Chân này **trước S146 CHƯA wire** ⇒ cân-sổ ORPHAN-L chỉ có nửa vào, không có nửa khoá (kêu oan ca *"pause rồi đóng thẳng không qua `/tiep`"*). Nay đóng.
- **Ghi `.claude/sessions/session-<N>/closed.md`** cho `<N>` đang mở — **FROZEN, ghi MỘT lần, CẤM sửa về sau**. Nội dung tối-thiểu **4 trường**:
`phien-logic: L<N>` · `cua-so: S<a>..S<b>` (các nhãn vật-lý thuộc phiên-logic này) · `closeout-commit: <sha>` · `ket-qua: <1-3 dòng arc đã đóng>`.
- **Cân-sổ (khoá vòng ORPHAN-L):** sau khi ghi, **mọi `pause-*.md` trong thư-mục coi như ĐÃ ĐỐI-ỨNG** — `closed.md` đóng vai đối-ứng cho khối `pause` cuối chưa có `resume-*`. ⇒ [`tiep.md §0`](tiep.md) block **⑤ ORPHAN-L** hết kêu oan.
- 🔴 **Idempotent:** `closed.md` đã tồn-tại ⇒ **NO-OP, CẤM ghi đè** (phiên-logic đã khép; closeout chạy lại không được "mở lại rồi khép lại").
- 🔴 **Thư-mục `session-<N>/` KHÔNG tồn-tại ⇒ NO-OP im-lặng** — phiên này không mở phiên-logic nào (vd vào thẳng bằng `/tiep`, chưa từng `/session-start`). **CẤM tự tạo thư-mục chỉ để ghi `closed.md`** — tạo-rồi-đóng-ngay là **sổ rỗng giả**, đúng loại ĐẠT-ảo mà fail-safe NO-OP khắp harness đang cấm.
- **Ghi `.claude/sessions/session-<N>/_end`** cho `<N>` đang mở — 🔴 **TÊN `_end`, KHÔNG đuôi `.md`** (form hub, owner chốt @S148 *"đối ứng đúng chính xác"*). **FROZEN, ghi MỘT lần, CẤM sửa về sau**. Khuôn `key: value`, tối-thiểu:
`summary-frozen-s<N>:` (1 dòng arc đã đóng) · `pointer:` (session-log/SUMMARY) · `carry:` (`a · b · c`) · `pending-anh:` · `pointers:` (run-folder) · `h24-tick: counter=<n>` · `markers: _pause=<p> · _tiep=<t> · _snapshot=<s>`.
🔴 **Trường `markers:` không phải trang-trí** — nó là **bản chụp cân-sổ tại lúc đóng**; sau khi đóng, detector bỏ qua thư-mục nên đây là **chứng duy nhất** còn lại về số lần dừng/nối.
🧊 Form SE cũ = `closed.md` (4 trường prose) — **LEGACY, CẤM viết mới**; `session-1` còn dùng nên Sàn-3 vẫn nhận (dual-accept).
- **Cân-sổ (khoá vòng ORPHAN-L):** ghi xong ⇒ **thư-mục ĐÓNG TRỌN, MỌI pause coi như đã đối-ứng** — [`tiep.md §0`](tiep.md) ⑤ **bỏ qua hẳn** thư-mục đã chốt-kết.
🔴 **Vá @S148 (fault-inject bắt):** bản cũ code `c=1` rồi so `p > r + c` ⇒ chỉ tha **ĐÚNG MỘT** pause chưa khớp ⇒ phiên đã đóng mà có **≥2** pause dư vẫn **KÊU OAN** — lệch đúng câu doc này vẫn luôn nói ("mọi pause"). Lệch sống từ S146, không lộ vì SE mới có `p=1`.
- 🔴 **Idempotent:** `_end` (hoặc `closed.md` legacy) đã tồn-tại ⇒ **NO-OP, CẤM ghi đè** (phiên-logic đã khép; closeout chạy lại không được "mở lại rồi khép lại").
- 🔴 **Thư-mục `session-<N>/` KHÔNG tồn-tại ⇒ NO-OP im-lặng** — phiên này không mở phiên-logic nào (vd vào thẳng bằng `/tiep`, chưa từng `/session-start`). **CẤM tự tạo thư-mục chỉ để ghi `_end`** — tạo-rồi-đóng-ngay là **sổ rỗng giả**, đúng loại ĐẠT-ảo mà fail-safe NO-OP khắp harness đang cấm.
- **Add đích-danh** ở §5.1 (thư-mục phiên nằm trong hook-4-path nên hook cũng nuốt, nhưng **đừng dựa hook để chốt** — cùng lý-lẽ `pause.md §2.6`).
🔸 **Meld-forward (floor hub, miếng nền thứ-3) — CHƯA kiểm tại SE:** hub ràng *"commit mang thư-mục phiên được **nhập-tiến về trước** khi squash, KHÔNG bị bỏ rơi"*. §5.0/§5.2 của SE squash `wal:`-trailing bằng `reset --soft` ⇒ nội-dung **ở lại INDEX** nên **về lý là không mất**; nhưng **chưa có phép đo riêng** cho `.claude/sessions/`. ⇒ khai **CHƯA-ĐO**, không claim kín.

View File

@ -89,6 +89,20 @@ Em main đọc `.claude/WAL.md` (sổ mạch-việc-dở H22 — ghi-đè ≤40
- 🔴 **Ai cấp `<N>` (khác "ai tạo thư-mục" — đừng lẫn):** **CHỈ `/session-start`** mới **MỞ SỐ MỚI** (`max(<N> hiện có) + 1`). `/pause` · `/tiep` **KHÔNG BAO GIỜ tự tăng `<N>`** — chúng chỉ **tạo thư-mục cho `<N>` ĐANG MỞ** nếu nó chưa có trên đĩa (ca "cửa đầu chưa kịp scaffold"). Không có `<N>` nào đang mở ⇒ dùng `<N> = max+1` **và ghi 1 dòng khai** trong khối đó là số được cấp ngoài `/session-start`.
- 🧊 **Vá mâu-thuẫn @S146:** bản trước ghi *"Ai mở `<N>` mới: **CHỈ** `/session-start`"* trong khi [`pause.md §2.6`](pause.md) ghi *"chưa có thì đây là cửa đầu ⇒ **tạo** `session-<N>/`"* ⇒ **hai file nói ngược nhau về quyền tạo**. Gốc lỗi = **gộp hai khái niệm khác nhau** (*cấp SỐ* ⟂ *tạo THƯ-MỤC*) vào một câu. Nay tách đôi: **cấp số = độc-quyền `/session-start`** · **tạo thư-mục = idempotent, ai gặp trước thì tạo**. Hub chỉ ràng vế thứ hai.
**(a-bis) 🔴 DANH-MỤC FILE trong thư-mục — form HUB, owner chốt @S148 (*"đối ứng đúng chính xác như này"*, ảnh `session-109`; đối-chứng đĩa hub `AI_INFRA/.claude/sessions/session-102..109`):**
| file | vai | ai ghi (canonical — B1, KHÔNG chép schema về đây) |
|---|---|---|
| `_context-s-<N>.md` | **narrative durable**, 1 file/phiên-logic · §(a) STOCK-map pointer + §(b) **FLOW append-only** (`### PAUSE-<k>` + dòng `> anh:` VERBATIM) · 🔴 CẤM rewrite/tự-tóm | append @[`pause.md §2.6`](pause.md) · đọc @[`tiep.md §2.6`](tiep.md) |
| `_pause-<i>.md` | **marker máy** ~200B, 5 trường (`ts`·`head-sha`·`window-ordinal`·`jsonl-hint`·`account-label`) | [`pause.md §2.6`](pause.md) |
| `_tiep-<i>.md` | marker máy, **cùng 5 trường** | [`tiep.md §2.6`](tiep.md) |
| `_snapshot-<i>.md` | chụp-nhanh không-dừng | ⏳ **CHƯA CÓ ở SE** — cần lệnh `/snapshot` `[carry:snapshot-cmd]` + `[carry:pause-autosnap]` |
| `_end` | **chốt-kết, KHÔNG đuôi `.md`** · `markers:` chụp cân-sổ lúc đóng | [`session-end.md §6.3-bis`](session-end.md) |
- 🔴 **`<i>` đánh số TUẦN TỰ** trong thư-mục (`max+1`) — **KHÔNG** nhãn `S<nn>`, **KHÔNG** timestamp trong tên. Thứ-tự đọc được từ tên, ts nằm *trong* file.
- 🔴 **TÁCH marker ⟂ narrative** là điểm khác lớn nhất so với form SE cũ (gộp cả hai vào `pause-S<nn>-<ts>.md`). Marker cho MÁY đọc, narrative cho NGƯỜI/phiên-sau đọc.
- 🧊 **Form cũ = LEGACY, CẤM viết mới**; Sàn-3 ⑤ vẫn **nhận** (dual-accept, [`tiep.md §0`](tiep.md)) vì `session-1` còn dùng — đúng luật retire *"giữ khi CÒN người thụ-hưởng"*.
**(b) Đo TRƯỚC khi tin — `.gitignore` (đo @S146, KHÔNG suy):**
```bash
git check-ignore -q .claude/sessions/session-1 ; echo "exit=$?" # → exit=1
@ -103,6 +117,13 @@ git check-ignore -q .claude/sessions/session-1 ; echo "exit=$?" # → exit=1
-**`session_ctx_kb` (trần ngân-sách context-phiên) = 64 — OWNER CHỐT TƯỜNG-MINH @S146.** Canonical = [`memory-budget.json`](../agent-memory/memory-budget.json) → `session_ctx_kb` (+ `_session_ctx_kb_owner_set`); **B1 — KHÔNG chép số ra đây**, dòng này chỉ TRỎ. Đơn-vị **KB**, code đọc **nhân 1024**.
🔴 **Vẫn là GHOST-WIRE, đừng đọc thành "đã wire":** đo @S146 **0 script đọc khoá** (hit duy-nhất trong `scripts/`**comment** `nhip-no-probe.ps1:42`; đối-chứng `pull_warn_days` **có** reader thật `:190`). Có số ≠ có hành-vi. Ai wire sau phải **đọc khoá**, không hardcode.
## 📋 BƯỚC 0.9 — Kéo thư cross-project (cửa VÀO 1/2 — owner chốt S148)
**DÒ 2 kênh** rồi **KÉO đầy-đủ** theo định-tuyến: `se>0``/check-email all` · `all>0``/adap-apply`.
> 🔗 **Luật nhịp đầy-đủ (4 cửa · fail-soft · quan-hệ với `pull-cach`) = canonical [`check-email.md`](check-email.md) §"Nhịp chạy — 4 CỬA PHIÊN".** 🔴 **B1 — mục này CHỈ TRỎ + GỌI, CẤM chép luật sang đây.**
> 🔴 **KHÔNG chặn bootstrap:** không có thư ⇒ 1 dòng đi tiếp; lỗi ⇒ `check-email loi (khong chan)` rồi đi tiếp. Kéo **TRƯỚC Phase 1 READ** là cố ý — thư mới có thể đổi chính kế-hoạch phiên mà Phase 1 sắp dựng.
## Phase 1 — READ (load context)
Đọc theo thứ tự, KHÔNG skip:

View File

@ -0,0 +1,70 @@
---
description: Checkpoint KHÔNG-dừng-phiên — ghi _snapshot chốt trạng-thái + commit, KHÔNG stop/bookend (session-model, adopt S148)
---
# /snapshot — chụp-nhanh không-dừng (SE port của hub `snapshot.md`, adopt S148 2026-07-24)
Checkpoint **NHẸ** giữa phiên (**≤1 turn**): **1 Write + 1 commit**. **KHÔNG stop · KHÔNG bookend · KHÔNG flush agent-memory · KHÔNG hỏi thêm.** Xong là làm việc tiếp ngay.
> 🔗 Cặp với `/pause` (dừng hẳn) và `/tiep` (nối lại). `/snapshot` **KHÔNG** phải điểm dừng — nó là **dấu mốc giữa đường**.
> 🧭 Đóng `[carry:snapshot-cmd]` (#15) — anh chốt @S148 *"làm đi không cần hỏi hub"*.
## 0. GUARD — thư-mục có thể CHƯA activate
Resolve sID `<N>`: đọc field `session:` trong `.claude/WAL.md` → mất thì lấy `.claude/sessions/session-*/` **mtime max** → vẫn mù thì **hỏi anh 1 dòng**.
🔴 `.claude/sessions/session-<N>/` **CHƯA tồn-tại****SKIP ÊM**: in đúng 1 dòng `sessions/ chua activate — /snapshot no-op` rồi DỪNG. **KHÔNG mkdir, KHÔNG chết.** *(Cấp số `<N>` là độc-quyền `/session-start` — [`session-start.md` BƯỚC 0.8](session-start.md).)*
## 1. KHI NÀO fire (3 trigger — AI tự phán)
- **(i)** Có quyết-định/kết-luận vừa chốt **chưa nằm file nào** (còn trong transcript).
- **(ii)** **NGAY TRƯỚC** một workflow-launch diện-WAL: `taskList ≥ 3` **hoặc** ước > 5 phút — chốt state trước khi fan-out.
- **(iii) accumulation-gate:** đếm commit **substantive** tích-luỹ, bỏ qua nhiễu hook.
- **anchor = `{subject·ts}` của mốc NON-`wal:` gần nhất** mà `_snapshot` TRƯỚC đã pin (đọc `anchor` trong `_snapshot-<k-1>.md`). 🔴 **CẤM lấy HEAD trần** — HEAD lúc snapshot thường là commit `wal:` do hook flush mỗi turn, và closeout-squash sẽ **rewrite chính sha đó** ⇒ neo vào nó là neo vào thứ sắp biến mất. Neo `{subject·ts}` sống sót squash.
- `count = git log --format=%s <anchor-sha>..HEAD | grep -vc '^wal:'`
- **fire khi `count ≥ K`.** `K` đọc **LIVE** từ `.claude/agent-memory/memory-budget.json` key `snapshot_trigger_k`.
🔸 **Khai thật @S148: key này CHƯA có trong file SE** ⇒ áp **default-if-absent = 6** đúng theo spec hub. Đây là **số của hub**, không phải anh chốt — anh muốn khác thì đặt key, đừng sửa số ở đây (B1).
- **fallback** (anchor không resolve được sau rewrite / chưa có `_snapshot` nào): `git log --since=<mtime(_snapshot-* mới nhất)>`; **0 `_snapshot` nào** ⇒ snapshot ĐẦU do trigger (i)/(ii) lái, **KHÔNG** do (iii) — chống đếm-quá lúc folder vừa sinh.
## 2. Ghi `_snapshot-<k>.md`
`k = (số file `_snapshot-*.md` hiện có trong `session-<N>/`) + 1`.
🔴 `_snapshot` **tự chứa essence****KHÔNG** double-write vào `_context` FLOW (FLOW = **@pause-only**).
Derive machine-block TRƯỚC: `python scripts/session_ctx.py machine-block --session <N> --json`
````
# _snapshot-<k> — SESSION-MODEL checkpoint (sID <N>)
ts: <ISO-8601 — ưu tiên git-anchored `git log -1 --format=%cI`, tránh wall-clock tuỳ tiện>
head-sha: <git rev-parse HEAD>
head-subject: <git log -1 --format=%s>
head-ts: <git log -1 --format=%cI>
label: <1 dòng — checkpoint này chốt cái gì>
snapshot-ordinal: <k>
## essence (≤3 dòng — chốt cái CHƯA nằm file)
- <dòng 1>
- <dòng 2>
- <dòng 3>
## machine-block
```json
<paste nguyên JSON của: python scripts/session_ctx.py machine-block --session N --json>
```
````
**Trường BẮT BUỘC đủ:** `ts` · `head-sha` · `head-subject` + `head-ts` · `label` · `snapshot-ordinal` · `essence ≤3 dòng` · `machine-block`.
🔴 `head-subject`+`head-ts` = **chống sha-rewrite-rot**: sau squash sha đổi, `{subject·ts}` vẫn resolve lại được.
🔸 **Giới-hạn giữ khai (đo @S148):** `machine-block.changed_files` derive từ `git diff anchor..HEAD` ⇒ **chỉ thấy phần ĐÃ COMMIT**. Việc đang dirty trong cây (vd `docs/` chưa commit) **KHÔNG** hiện ra. Giữ đúng ngữ-nghĩa hub để sau này re-pull bằng diff; đừng đọc `changed_files` thành "toàn bộ việc đã làm".
## 3. Secrets-sweep gate (TRƯỚC commit — BẮT BUỘC)
`python scripts/session_ctx.py secrets-sweep --session <N>`
- **exit 1 ⇒ CHẶN commit**: in `file:line` mọi hit, xử-lý/redact rồi mới commit.
- ✅ **Đã fault-inject @S148 2 chiều:** CHẶN đúng ca có `sk-…` · cho qua ca sạch · **0 dương-giả** với `ask-me`/`task-list` (token-anchored `\b`).
- ⚠️ **ACCEPTED-GAP khai thẳng:** sweep **pattern-bounded** (4 mẫu `voyage·sk-·gitea_pat·cfut_`) ⇒ **KHÔNG** phủ secret lớp khác (vd mật-khẩu DB trong tin-nhắn verbatim). Đây là **BLOCK bảo-thủ trước commit**, KHÔNG phải chứng-minh sạch tuyệt-đối.
## 4. Commit (1 commit)
- `git add .claude/sessions/session-<N>/_snapshot-<k>.md` — 🔴 **CHỈ file đích danh, CẤM `git add -A`/`.`** (rủi ro rò secret).
- `git commit -m "wal: snapshot s<N> _snapshot-<k>"` — ASCII-clean (tránh em-dash mangle dưới PowerShell). **KHÔNG `--no-verify`. KHÔNG push.**
- 🔸 **Meld-forward @closeout — CHƯA ĐO tại SE:** hub ràng commit mang `.claude/sessions/` phải được **nhập-tiến** vào mốc non-`wal:` liền sau khi squash, KHÔNG bị DROP như `wal:` thuần. SE squash bằng `reset --soft` ⇒ **về lý không mất**, nhưng **chưa có phép đo riêng** — trùng `[carry:meld-forward-unmeasured]` (#19). Đừng claim kín.
## 5. Xong
Báo **1 dòng**: `snapshot-<k> ghi @<ts> (count=<n>/K, trigger-<i|ii|iii>) — committed, tiếp việc`
rồi **1 dòng nhịp-nợ**: `powershell.exe -ExecutionPolicy Bypass -File scripts/nhip-no-probe.ps1` (lỗi → `probe-loi (khong chan)`).
🔴 **KHÔNG stop · KHÔNG bookend · KHÔNG DỪNG HẲN** — quay lại việc đang làm ngay.

View File

@ -86,21 +86,32 @@ done
git log --name-only --format='%s' origin/main..HEAD | grep -q '.claude/sessions/'
# (b) cửa ĐĨA — git-independent, miễn-nhiễm hook (mirror ①: đọc đĩa, KHÔNG đọc git)
# Cân-bằng-sổ: mỗi `pause-*` phải có ĐÚNG một đối-ứng (`resume-*` do /tiep ghi, hoặc closed.md do đóng-L).
# Cân-bằng-sổ: mỗi pause phải có ĐÚNG một đối-ứng (tiep do /tiep ghi, hoặc chốt-kết do đóng-L).
# 🔴 DUAL-ACCEPT 2 FORM (S148) — cùng khuôn dual-accept của ① ở trên:
# HUB (chuẩn từ S148, owner chốt "đối ứng đúng chính xác"): _pause-<i>.md · _tiep-<i>.md · _end (KHÔNG đuôi)
# LEGACY (di-sản ≤S147): pause-*.md · resume-*.md · closed.md
# 🔴 TÍNH-CHẤT CỨU MẠNG: glob `pause-*` KHÔNG khớp `_pause-1.md` (tên bắt đầu bằng `_`)
# ⇒ 2 form KHÔNG đè nhau ⇒ cộng thẳng là an-toàn, không đếm đôi. Đã fault-inject 2 chiều @S148.
for d in .claude/sessions/session-*/; do
[ -d "$d" ] || continue
p=$(ls "$d"pause-*.md 2>/dev/null | wc -l); [ "$p" -eq 0 ] && continue
r=$(ls "$d"resume-*.md 2>/dev/null | wc -l)
c=0; [ -f "$d/closed.md" ] && c=1
[ "$p" -gt $((r + c)) ] && echo "ORPHAN-L: $d (pause=$p resume=$r closed=$c)"
# 🔴 CHỐT-KẾT ĐÓNG TRỌN THƯ-MỤC, không phải "+1" (vá @S148 — fault-inject bắt).
# session-end.md §6.3-bis nói rõ: sau khi ghi chốt-kết thì MỌI pause "coi như ĐÃ ĐỐI-ỨNG".
# Bản cũ viết `c=1` rồi `p > r + c` ⇒ chỉ tha ĐÚNG MỘT pause chưa khớp ⇒ phiên đã đóng mà
# có ≥2 pause dư vẫn KÊU OAN. Doc và máy lệch nhau từ S146; dữ-liệu SE quá nhỏ (p=1) nên chưa lộ.
{ [ -f "$d/_end" ] || [ -f "$d/closed.md" ]; } && continue
p=$(( $(ls "$d"_pause-*.md 2>/dev/null | wc -l) + $(ls "$d"pause-*.md 2>/dev/null | wc -l) ))
[ "$p" -eq 0 ] && continue
r=$(( $(ls "$d"_tiep-*.md 2>/dev/null | wc -l) + $(ls "$d"resume-*.md 2>/dev/null | wc -l) ))
[ "$p" -gt "$r" ] && echo "ORPHAN-L: $d (pause=$p tiep=$r, chua chot-ket)"
done
```
-**Đối-ứng `resume-*` CÓ người ghi thật**`/tiep` §2.6 dưới (cùng file này) ⇒ vòng `pause ↔ tiep` **tự đóng**, không phải cơ-chế treo.
-**`closed.md` ĐÃ WIRE @S146** (owner chốt *"giống hub"*`_end` chốt-kết của manifest `101e69d6`): nghi-thức ghi nằm ở [`session-end.md`](session-end.md) **§6.3-bis** (FROZEN · 4 trường · idempotent NO-OP · NO-OP im-lặng nếu 0 thư-mục). ⇒ **cân-sổ nay ĐỦ CẢ HAI vế**: `pause` đối-ứng bằng `resume-*` (`/tiep §2.6`) **hoặc** `closed.md` (đóng-L) ⇒ ca *"pause rồi đóng thẳng không qua `/tiep`"* **hết kêu oan**.
-**Đối-ứng `_tiep-<i>.md` CÓ người ghi thật**`/tiep` §2.6 dưới (cùng file này) ⇒ vòng `pause ↔ tiep` **tự đóng**, không phải cơ-chế treo. *(legacy `resume-*` vẫn được đếm — dual-accept ở máy trên.)*
-**Chốt-kết `_end` ĐÃ WIRE** (owner chốt @S146 *"giống hub"*, đổi tên `closed.md``_end` @S148 cho khớp form hub — manifest `101e69d6`): nghi-thức ghi ở [`session-end.md`](session-end.md) **§6.3-bis** (FROZEN · idempotent NO-OP · NO-OP im-lặng nếu 0 thư-mục). ⇒ **cân-sổ đủ CẢ HAI vế**: `pause` đối-ứng bằng `_tiep-<i>` (`/tiep §2.6`) **hoặc** `_end` (đóng-L) ⇒ ca *"pause rồi đóng thẳng không qua `/tiep`"* **hết kêu oan**.
🔴 **@S148 mạnh thêm một nấc:** `_end` nay **ĐÓNG TRỌN thư-mục** (detector `continue` hẳn), không còn là "+1". Fault-inject bắt: phiên đã đóng mà dư ≥2 pause thì bản cũ **vẫn KÊU OAN** — lệch đúng câu *"MỌI pause coi như đã đối-ứng"*`session-end §6.3-bis` vẫn luôn nói. Doc đúng, máy sai, sống từ S146.
🧊 *Nấc cũ (tới S145): "`closed.md` CHƯA wire — VC-2 còn chờ anh duyệt", kèm hệ-quả "chỉ ca pause-rồi-đóng-thẳng mới thiếu đối-ứng". **Cả hai nay SAI** — giữ 1 dòng làm vết.*
🔴 **Bài học lấy từ chính chỗ này (H24 `lead-view-auditor` bắt @S146):** MÁY ở ngay trên (`:89` `:94` `:95`) **đã đọc `closed.md` thật** từ lúc block này ra đời, mà **PROSE vẫn khai "chưa wire"** ⇒ đây là **lật-ngược của ghost-wire**: **wired-but-declared-unwired** — và nó nằm đúng dưới nhãn *"chống ghost-wire H18"*. ⇒ **Ghost-wire soi được 2 CHIỀU**: khai-có-mà-không-chạy **và** chạy-thật-mà-khai-chưa.
- 🟢 **Hướng hỏng = AN-TOÀN:** quên ghi `resume-*` ⇒ sổ lệch ⇒ **KÊU ⇒ HỎI LẠI ANH**. Sai về phía *hỏi thừa*, không về phía *im lặng bỏ việc* — đúng thiên-hướng của Sàn-3.
- 🟢 **Hướng hỏng = AN-TOÀN:** quên ghi `_tiep-<i>.md` ⇒ sổ lệch ⇒ **KÊU ⇒ HỎI LẠI ANH**. Sai về phía *hỏi thừa*, không về phía *im lặng bỏ việc* — đúng thiên-hướng của Sàn-3.
### 🟡 BẬC TRUNG-BÌNH — nhiều file bẩn **NGOÀI** 4 path hook persist
@ -143,10 +154,20 @@ Tín-hiệu **YẾU NHẤT**, dùng cuối. 🔴 **`porcelain` rỗng KHÔNG ph
- **Dòng-nợ (SAU tick — n-3):** gọi `powershell.exe -ExecutionPolicy Bypass -File scripts/nhip-no-probe.ps1` in dòng-nợ 4-vế (vế-1 nhịp-kiểm đọc post-tick). 🔴 **probe KHÔNG chặn điểm dừng**: lỗi → in `probe-loi (khong chan)` → đi tiếp.
> 🔗 **Predicate C7 đầy-đủ (probe được phép chạy ở điểm dừng) = canonical [`harness-11-engine.md`](../../docs/governance/harness-11-engine.md) §N.8.** 🔴 **B1 — dòng này CHỈ TRỎ, CẤM chép predicate sang đây** (chép 2 nơi = 2 nguồn sự-thật, đúng thứ B1 sinh ra để chặn).
## 2.6 Đọc context-map phiên-LOGIC + ghi biên-nhận `resume-*` (S146 — cặp với `/pause` bước 2.6)
## 2.5b Kéo thư cross-project (cửa VÀO 2/2 — owner chốt S148)
- **Đọc:** nếu có `.claude/sessions/session-<N>/` → đọc **TẤT CẢ** `pause-*.md` theo thứ-tự thời-gian = **bối-cảnh cộng-dồn** của phiên-logic (quyết-định đã chốt · delta còn sống · con-trỏ run/commit). 🔴 **Đây là lane CỘNG-DỒN, khác WAL** — WAL là sổ **mạch-sống ghi-đè ≤40 dòng** (liếc-một-cái-là-biết); context-map là **tích-luỹ, không ghi đè**. Đọc context-map **KHÔNG** thay việc chạy `verify:` — ground-truth vẫn thắng (§3).
- **Ghi biên-nhận — 🔴 THỰC-HIỆN SAU §3** (đọc ở đây, ghi sau khi reconcile xong; **bắt buộc**): tạo `.claude/sessions/session-<N>/resume-S<nn>-<yyyyMMddTHHmm>.md`**1 khối ngắn**: nối từ `pause-*` nào · lệch gì so `chain:` (nếu có) · `next:` đang thực-thi.
**DÒ 2 kênh** (`outbox/se` + `outbox/all` × 6 repo) — **NGAY SAU dòng-nợ** (vế-4 `pull-cach` vừa in xong ⇒ đọc số rồi dò là đúng thứ-tự nhân-quả). In `thu-moi: se=X all=Y`.
🔴 **CHỈ list + so id. KHÔNG copy · KHÔNG hash · KHÔNG python** (đo @S148: dò ~5ms · kéo ~200500ms/thư). `X|Y > 0` ⇒ nêu **1 dòng** rồi đi tiếp §2.6; **kéo thật để bookend làm** (`se``/check-email` · `all``/adap-apply`).
> 🔗 **Luật nhịp đầy-đủ = canonical [`check-email.md`](check-email.md) §"Nhịp chạy — 4 CỬA PHIÊN".** 🔴 **B1 — CHỈ TRỎ + GỌI, CẤM chép luật.**
> 🔴 **KHÔNG chặn recovery:** lỗi ⇒ `check-email loi (khong chan)` → đi tiếp §2.6. **Cửa này quan-trọng NHẤT trong 4** — *"1 session kéo 2-3 phiên"* nghĩa là các phiên GIỮA đều vào bằng `/tiep`, nên bỏ cửa này là bỏ phần lớn lưu-lượng.
## 2.6 Đọc `_context-s-<N>.md` + ghi marker `_tiep-<i>.md` (S146 · form hub @S148 — cặp với `/pause §2.6`)
- **Đọc (form HUB, chuẩn @S148):** có `.claude/sessions/session-<N>/` → đọc **`_context-s-<N>.md`** — đó là **bối-cảnh cộng-dồn** (§(a) STOCK-map pointer + §(b) FLOW append-only: mọi entry `### PAUSE-<k>` theo thứ-tự, kèm dòng `> anh:` verbatim). Marker `_pause-*.md`/`_tiep-*.md`**5 trường máy**, đọc để biết `window-ordinal` + `head-sha`, KHÔNG chứa narrative.
🧊 **Legacy ≤S147:** thư-mục không có `_context-s-<N>.md` ⇒ đọc **TẤT CẢ** `pause-*.md` theo thứ-tự thời-gian (form cũ gộp marker+narrative). Nhận-để-đọc, **CẤM viết mới** kiểu đó. 🔴 **Đây là lane CỘNG-DỒN, khác WAL** — WAL là sổ **mạch-sống ghi-đè ≤40 dòng** (liếc-một-cái-là-biết); context-map là **tích-luỹ, không ghi đè**. Đọc context-map **KHÔNG** thay việc chạy `verify:` — ground-truth vẫn thắng (§3).
- **Ghi biên-nhận — 🔴 THỰC-HIỆN SAU §3** (đọc ở đây, ghi sau khi reconcile xong; **bắt buộc**): tạo **`_tiep-<i>.md`** (`<i>` = `max(_tiep-*)+1`) — đúng **5 trường ~200B**, y khuôn `_pause-<i>.md` (xem [`pause.md §2.6`](pause.md)): `ts` · `head-sha` · `window-ordinal` · `jsonl-hint` · `account-label`.
🔴 **Marker là MÁY, không phải bài luận** — kết-quả reconcile (lệch gì so `chain:`, `next:` đang chạy) thuộc về **`_context-s-<N>.md`**, không nhồi vào marker. *(Bản S148 đầu ghi `resume-S<nn>-<ts>.md` 2,5KB narrative — sai form, đã gỡ.)*
- 🔴 **Vì sao bắt buộc:** biên-nhận này là **đối-ứng cân-sổ** của tín-hiệu **ORPHAN-L ⑤** (§0). Thiếu nó ⇒ sổ lệch ⇒ lần sau **KÊU** ⇒ hỏi lại anh. Hỏng về phía *hỏi thừa* = an-toàn; nhưng ghi đủ thì sàn mới **im đúng**.
- 🔸 `session-<N>` **KHÔNG mở mới ở `/tiep`**`/tiep` **nối** phiên-logic đang mở. Mở `<N>` mới = việc của `/session-start` (xem `session-start.md` BƯỚC 0.8).