---
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.
