--- description: Nén verbatim L2 cũ (agent-memory archive/.md) thành gist ADDITIVE (.gist.md file MỚI, KHÔNG đè). CHỈ P1 gist-compress — KHÔNG build index. SCOPE = repo SOLUTION_ERP-only. argument-hint: (vd — implementer-backend · reviewer · all) --- # /sleep-recovery-memory-l2 — Giấc ngủ L2 (sleep-compress, P1-only) · SE > Trigger nén L2 dark-matter. **CHỈ** xử lý `.claude/agent-memory//archive/.md` (verbatim cũ) → sinh `.gist.md` (**FILE MỚI, additive**). KHÔNG đụng L1 (`MEMORY.md`) · KHÔNG đụng RAG/L3 · KHÔNG build `_INDEX.md` (đó = P2 archival-event, không nằm trong command này). > 🔴 **Scope:** CHỈ repo **SOLUTION_ERP** (self=`se`). KHÔNG đụng repo khác / corpus federated. > 🔴 **Phân-vai (Cách-B):** lead = em-main single-writer (B3) · `harvest-curator` PROPOSE-ONLY (charter cấm-ghi → substring:"KHÔNG ghi/sửa BẤT KỲ file") · `reviewer` gate Fidelity (lead KHÔNG tự chấm, G-001). > > 📌 **NOTE — provenance:** Command này **port từ AI_INFRA** `/sleep-recovery-memory-l2` (`D:/Dropbox/CONG_VIEC/AI_INFRA/.claude/commands/sleep-recovery-memory-l2.md`) + design (AI_INFRA repo — KHÔNG có bản SE-local) `D:/Dropbox/CONG_VIEC/AI_INFRA/docs/architecture/MEMORY-SLEEP-RECOVERY-L2-DESIGN-v3.md` §4 + §10-P1. Bản gốc gate **§J2 = AI_INFRA-only (no-sister)**; ở đây anh yêu-cầu port để **parity** → scope tailor thành **SE-repo-only** (KHÔNG đụng sister/corpus khác). KHUNG federated giữ nguyên (function-floor), CHỈ tailor form theo SE (roster · path · 4-field tiếng Việt · pointer-style · gotcha#). **Tham số:** `$ARGUMENTS` — 1 agent (vd `implementer-backend`) HOẶC `all`. Trống → hỏi anh chọn, **KHÔNG mặc-định `all`**. ## 📋 BƯỚC 0 — Show command body (visibility, no wait) Em main PHẢI echo **TOÀN BỘ nội dung command body này** (đầy đủ Phase 0-5 + tất cả guard rule) trong response đầu tiên ĐỂ ANH USER ĐỌC LẠI. **Quy trình (KHÔNG wait confirm):** 1. Em echo full content command (raw markdown, KHÔNG tóm tắt, KHÔNG cắt) 2. Em proceed execute Phase 0 → 5 sequential ngay 3. Anh user điều chỉnh **cuối** nếu cần (KHÔNG mid-flow interrupt) ## 🎯 Mục đích (function-floor) Nén **verbatim L2 cũ** thành **gist súc-tích** mà KHÔNG mất signal-quan-trọng: - **ADDITIVE (B3/§F1/G-009):** gist = ghi ra **file MỚI** `archive/.gist.md`. **KHÔNG đè** `.md` (verbatim) → verbatim ở-lại-đĩa (git history giữ nguyên). Đây là cách giải B3-data-loss: nén KHÔNG phá nguồn. - Kết quả: 1 verbatim file dài + 1 gist file ngắn cùng kỳ. Lookup sâu vẫn Read verbatim; đọc nhanh đọc gist. - 🔴 **KHÔNG ép L1 nhỏ hơn 30KB** (design BỎ — rotation L1→L2 là function per-project; L1-cap-audit của SE đã sống ở `/session-start §2.1.2` + `memory-budget.json`, KHÔNG phải việc của command này). ## 👥 SE roster — target hợp-lệ 🔴 **`all` = MỌI sub product/quality có-ký-ức — DẪN-XUẤT TỪ ĐĨA, KHÔNG hardcode danh-sách** (B1; roster canonical → [`docs/STATUS.md`](../../docs/STATUS.md) §Sub-agents): ```bash # monitor-set DERIVE TỪ NGUỒN (vá H1-FLAG-1 @S150 — bản hardcode 4 tên đã stale khi roster monitor lên 10): # vai INFORM-only = mô-tả agent chứa 'INFORM-only'; loại README (bẫy glob .claude/agents/*.md — luật ring1 @S150, không ngoại-lệ). MON=$(grep -il 'INFORM-only' .claude/agents/*.md | xargs -n1 basename | sed 's/\.md$//' | grep -v '^README$' | paste -sd'|' -) ls -1d .claude/agent-memory/*/ | xargs -n1 basename | grep -vE "^($MON)$" ``` Hiện-hành (báo-cáo RUNTIME đo 2026-07-25 — KHÔNG chép thành hằng-số) = `investigator-codebase · investigator-api · implementer-backend · implementer-frontend · test-specialist · reviewer · cicd-monitor · frontend-designer · database-agent · office-document`. > 🟡 **MỌI vai monitor INFORM-only KHÔNG vào `all` mặc-định** — tập = **derive từ lệnh trên**, KHÔNG liệt-kê cứng (hiện gồm nhóm H1 · H2 · 2×H24 · 3×trio-memory · 3×round-KIỂM; số & tên = runtime-scan. Vá @S150: bản cũ "4 monitor" sót 6 vai mới — tái-phát ĐÚNG class mà ghi-chú S122 ngay dưới đã cảnh-báo ⇒ lần này vá bằng BỎ hardcode, không thêm tên). CHỈ xử-lý nếu chúng **thật-sự có** `archive/.md` verbatim (Phase 0.2 phát-hiện) — **gọi tay đích-danh tên**. > ⚠️ **Vá @S122 — danh-sách này TỪNG STALE:** nó cứng-hoá "9 sub" và **rớt `office-document`** (vai thêm **S107**, có ký-ức thật, là product/quality **chứ không phải monitor**) suốt từ đó. Trớ-trêu: chính doc này đã ghi *"luôn quét đĩa thật"* cho con-số `4/9` ngay dưới, nhưng lại **hardcode danh-sách roster** phía trên ⇒ nay **quét cả hai**. > ℹ️ **Số sub CÓ archive-content = báo-cáo RUNTIME, luôn quét đĩa** (đo S71: 4 — `cicd-monitor · implementer-backend · investigator-codebase · reviewer`; số còn-lại archive rỗng/chưa-có → `all` tự skip qua Phase 0.2 guard-rỗng). **KHÔNG chép con-số này thành hằng-số.** > 🧹 **Ghi-chú S122:** trước đó `agent-memory/` còn **2 dir RỖNG** `_crlf-probe` + `_lf-probe` (tàn-dư probe W0.6) ⇒ lệnh quét trên **đếm 16 thay vì 14**. Đã `rmdir`. Bài học: **git MÙ với thư-mục rỗng** ⇒ `git status` sạch **KHÔNG** chứng-minh đĩa sạch. Con-số này = báo-cáo runtime, KHÔNG hardcode: luôn quét đĩa thật. ## Trigger (2 đường) | Đường | Cơ chế | |---|---| | **Tay** | Anh gõ `/sleep-recovery-memory-l2 ` bất kỳ lúc nào | | **Auto-check (AUTO-khi-KÊU @S152)** | 🔄 **ĐỔI @S144** — `/session-start §2.1.2` + `/session-end §L.b(c)` chạy `scripts/distill-shard-probe.ps1` → đếm **shard chưa-gist** (loại trừ `_INDEX.md` + `*.gist.md`), so ngưỡng đọc-live `memory-budget.json → distill_trigger.min_pending_shards`. KÊU → **🔄 AUTO chạy** command trong phiên (owner @S152 *"các vòng 1→5 auto luôn"* — 🧊 INFORM-consent S144 superseded; vết M4: in dòng trạng-thái + WAL `sleep: skipped` nếu KÊU-mà-không-chạy). 🧊 **Dòng cũ `today − last_sleep_at ≥ 7 (ngày)` nay là GHI-CHÚ PHỤ, KHÔNG còn quyết-định** — owner đảo có chủ đích @S144 2026-07-22 (O-6 cơ-chế + chốt số 7 shard); trước đó `:52` giữ 7-ngày là **quyền owner cục-bộ DP-5**, và chính owner gỡ, không phải AI. 🔸 **Kèm hiển-thị byte (M-10 / DP-5):** khi probe KÊU, 2 site runtime (`/session-start §2.1.2` + `/session-end §L.b(c)`) in kèm **tổng byte `archive/.md` chưa có `.gist.md`** (match PREFIX kỳ; baseline 17-07: kỳ `2026-07` ≈ 183KB/5 file [ví-dụ-lịch-sử — đã gist @S140→~0]) để anh nhìn số **rồi tự đặt ngưỡng byte** nếu muốn chuyển hẳn (không bịa số) — **INFORM 7-ngày GIỮ** (quyền owner cục-bộ, B1 §3.4; cấm-là-cấm-hub-phát-chuẩn). ⚠️ Việc **WIRE** byte nằm ở 2 site đó (**LANE-A**), **KHÔNG** ở command này — dòng này chỉ là **MÔ-TẢ** (tránh ghost-wire "defined-but-unread", H18). | > 🔴 **State-file `last_sleep_at` có 1 home DUY NHẤT:** `.claude/agent-memory/memory-budget.json` (root-key `last_sleep_at`, cạnh `tiers`/`measured`). KHÔNG ghi ở `_INDEX.md` / nơi khác. *(SE đặt budget-file trong `agent-memory/`, KHÁC AI_INFRA gốc đặt `.claude/memory-budget.json` — đây là tailor path SE.)* Field `last_sleep_at` **đã thêm** (null baseline, S72) vào budget-file SE — auto-check **đã wired** ở `/session-start §2.1.2` + `/session-end §L.b(c)` (đọc field → INFORM gợi-ý nếu null/≥7d). Lần sleep đầu lead set `= today` (Phase 4.4). Lead = single-writer field này (B3). ## Phase 0 — Prep (em main / lead) 1. Parse `$ARGUMENTS` → list agent target. `all` → 9 sub có-ký-ức SE (xem roster ở trên). Agent lạ (không có dir `.claude/agent-memory//`) → cảnh-báo + skip. `harvest-curator`/`tooling-auditor` chỉ chạy nếu gọi tay đích-danh **và** có archive thật. 2. Mỗi agent: liệt-kê `archive/.md` (verbatim) **đủ cũ** (per-project aging, size-driven — KHÔNG federated-time). **Guard-rỗng:** agent KHÔNG có `archive/` hoặc 0 file `.md` → skip (0 token). Bỏ qua file nào Đà có `.gist.md` tương-ứng (tránh nén lại). 3. 🛡️ **double-distill guard (đọc header TRƯỚC khi làm):** nếu **gist nguồn/đối-tượng** đã chứa counter `distill-gen: N` với `N ≥ 1` → đã là sản-phẩm distill → **REFUSE pass-2 tự-động** (skip, log lý-do). Chỉ nén nguồn **verbatim gen-0** (file `.md` chưa-từng-distill). *(SE thực-tế: có gist đã ở `distill-gen: 2` — investigator-codebase 2026-06 — guard PHẢI bắt; KHÔNG nén `.gist.md`, chỉ nén `.md` verbatim.)* 4. Đọc `.claude/agent-memory/memory-budget.json` lấy `last_sleep_at` (xác-nhận đủ 7-ngày nếu đường auto). Field vắng → coi như "chưa từng sleep" (đường tay vẫn chạy bình-thường). ## Phase 1 — GATHER + DEDUP (harvest-curator PROPOSE-ONLY) > `harvest-curator` charter **cấm-ghi-file** → output = **proposal MD** (text trả-về), KHÔNG Write. Spawn `harvest-curator` đọc từng verbatim file target → đề-xuất **bản nén nháp**: - Gom entry trùng/liên-quan (dedup spawn-record cùng-chủ-đề across nhiều ngày/session). - Đánh **importance-tag** mỗi cụm: `{cao · vừa · thấp}` (khớp nhãn giá-trị-tái-dùng SE đang dùng trong gist hiện-có). - Trả proposal (KHÔNG ghi đĩa). Lead nhận → Phase 2 distill + verify. ## Phase 2 — DISTILL (method) Lead distill proposal thành gist theo 4 bước: 1. **4-field giữ-khung (SE):** mỗi entry gốc = spawn-record **`VIỆC · KẾT-LUẬN(+commit/file:line) · BÀI-HỌC · BẤT-NGỜ`**. Nén = rút-gọn câu-chữ, **KHÔNG bỏ field**. *(Đây là form SE — tương-đương `task · verdict · learned · surprise` bản gốc.)* 2. **GỘP:** cụm entry cùng-chủ-đề → 1 entry tổng-hợp (cite ngày/session gốc + **pointer back-resolve** vào verbatim). 3. **reflection-synthesis (đặt ĐẦU tệp, viết TRƯỚC chi-tiết):** rút **3 tới 5 ý tổng-hợp mỗi file** (meta-insight cấp cao hơn liệt-kê thô, KHÔNG vượt 5) → đặt khối **TỔNG-HỢP 3–5 ý ở ĐẦU gist**, viết **TRƯỚC** phần chi-tiết/phụ-lục (đọc-nhanh thấy meta-insight trước, không phải lội hết liệt-kê thô). 🔴 **grep-ngược:** mọi **số/mốc** (ngày · S-nnn · Mig-N · commit-SHA · gotcha#) nêu trong khối tổng-hợp **PHẢI** grep-ngược được về **phụ-lục/nguyên-bản** (trong CÙNG gist hoặc verbatim nguồn) — tổng-hợp KHÔNG chứa số/mốc không truy được về nguồn (chống bịa-số ở lớp meta). 4. **importance-tag drop:** **drop `thấp` TRƯỚC** khi cần cắt độ-dài. `cao`/`vừa` giữ. ratio nén = **báo-cáo KHÔNG phải target** (KHÔNG cắt để đạt con-số). 🔴 **Pointer-style SE (khớp gist hiện-có):** mỗi dòng kết bằng back-resolve `→ substring:""` grep-UNIQUE vào verbatim file đã-tên — git-SHA / Mig-name / Run#NNN / unique-phrase keyed (ngày bị collide). **NO line-hint** (additive append làm xê dòng). 🔴 **Header gist file BẮT BUỘC** có counter `distill-gen: 1` (sản-phẩm distill thế-hệ-1 → chặn pass-2 sau này per Phase 0.3) + ghi rõ `source-verbatim` (tên file + #record) + `pointer-style: substring`. *(Nếu hiếm-hoi distill từ gist gen-1 — chỉ khi anh ép tay đè guard — stamp `distill-gen: 2`.)* ## Phase 3 — GATE (coverage-diff DETERMINISTIC + Fidelity) > Gate = chốt-chặn mất-signal. 2 lớp. **(a) coverage-diff DETERMINISTIC (lead scan, rẻ, LUÔN chạy):** - Mọi **`{surprise · guard · file:line · root-cause · gotcha#}`** xuất-hiện trong verbatim **PHẢI** xuất-hiện (hoặc đánh `N/A` có-chủ-đích) trong gist. *(SE thêm `gotcha#` so với 4-token gốc — khớp rule `memory-budget.json` l2_gist: "every surprise/guard/file:line/root-cause/gotcha# in verbatim must survive".)* - Cơ-chế: grep các loại token trên ↔ đối-chiếu gist (Grep tool). Thiếu bất-kỳ → **FAIL** → bổ vào gist TRƯỚC khi tiếp. - 🔴 **cross-file bleed guard (nén NHIỀU tệp cùng lượt):** khi 1 lượt xử >1 verbatim (vd `all`, hoặc nhiều `.md` của cùng agent) → mỗi token trích-dẫn trong một gist **PHẢI** grep về **ĐÚNG verbatim CỦA TỆP ĐÓ** — token của tệp A **KHÔNG** được trôi sang gist tệp B. Cơ-chế: coverage-diff chạy **per-file đóng-kín** (gist kỳ X của agent Y ↔ **CHỈ** verbatim kỳ X của agent Y), KHÔNG gộp chung 1 pool token liên-tệp. Bleed = **FAIL** (signal gán nhầm nguồn còn tệ hơn thiếu signal — đọc-lại sẽ tin sai xuất-xứ). - **ratio nén = báo-cáo** (đo để biết), KHÔNG phải target/floor — KHÔNG ép gist nhỏ-đi để đạt ratio đẹp. **(b) Fidelity gate (reviewer escalate):** - `harvest-curator` Fidelity-FLAG → escalate `reviewer` chấm **keep-vs-drop** (entry nào nén/drop có đúng không, gist có bịa / lệch nghĩa không). - Lead KHÔNG tự chấm Fidelity (G-001). reviewer PASS → ghi. FAIL → re-distill đúng sự-thật. *(reviewer no-StructuredOutput / chết ×2 → self-gate-fallback bằng evidence-checklist hợp-lệ, ghi rõ trong report — feedback agent-kill-recovery.)* ## Phase 4 — WRITE (lead single-writer, B3) 1. **Tool-ghi:** `Write` (file mới) / `Edit` — 🔴 **G-009: KHÔNG** PowerShell `Add-Content` / bash here-string. UTF-8 no-BOM. 2. Ghi `archive/.gist.md` (file MỚI). **KHÔNG** chạm `.md` verbatim (additive). - 🔴 **assert additive per-file (n-9, chuẩn `291550ff` hai-assert):** sau ghi, mọi verbatim nguồn phải **byte-identical trước/sau** — `git diff --stat` trên các `.md` verbatim = **RỖNG** (chỉ `.gist.md` MỚI + `memory-budget.json` `last_sleep_at` được phép hiện trong diff). Hai-assert = (1) verbatim byte-identical (chỗ này) + (2) gist coverage-diff PASS (Phase 3a). Verbatim khác 1 byte → **DỪNG**, điều-tra (đã lỡ đè nguồn = vi-phạm B3/§F1). 3. **G-009 post-scan (BẮT BUỘC sau ghi):** Grep mojibake (`§` · `â†` · `ðŸ` · `KHÃ` — seq cụ-thể, né bare-`Ã`) + dollar-expansion (`/usr/bin/bash`) trên file vừa ghi → **phải sạch**. Bẩn → de-corrupt qua Write tool. 4. Cập-nhật `.claude/agent-memory/memory-budget.json` field `last_sleep_at = ` (root-key; **thêm mới nếu chưa có**). B3 single-writer, Write/Edit. 🔴 KHÔNG hand-edit `measured_bytes` (chỉ script `scripts/measure-agent-memory.ps1` được sửa số đo) — chỉ chạm `last_sleep_at`. ## Phase 4.5 — 🔬 ring4-audit AUTO (KIỂM vòng nén-ngủ, C4/C4b vai #3/3, land S145) Gist + Fidelity-gate xong (Phase 3+4) ⇒ spawn `ring4-audit` NGAY — **AUTO, KHÔNG consent** (owner S145). Đọc `.gist.md` mới + Fidelity verdict + claim giảm-byte → verdict per-claim + **tự đo lại byte** archive gốc vs gist (đối-chứng claim) + **thách-CLEAN** (Fidelity 5P/0F ⇒ mở 1 gist đối-chứng `.md` gốc xem trung-thực, không mất 4-field load-bearing). 🔴 no-self-exempt độc-lập lượt nén (m-3). 🔴 Fail-safe: 0 `.gist.md` tươi phiên này ⇒ **NO-OP im-lặng**. Verdict gộp vào Phase 5 report. Propose-only → em main VERIFY→APPEND (git-diff backstop). Contract canonical `.claude/agents/ring4-audit.md` (B1). ## Phase 5 — REPORT + COMMIT 1. **Report:** mỗi agent xử-lý → `{verbatim-file · gist-file MỚI · #entry trước→sau · ratio (báo-cáo) · importance-drop thấp=N · coverage-diff PASS/FAIL · Fidelity PASS/self-gate}`. 2. **Commit** (anh OK): `[CLAUDE] Memory: sleep-compress L2 .gist.md additive` - Scope = `Memory`. 🔴 `git add` **file cụ-thể** (KHÔNG `-A`/`.` — secret-leak risk; feedback rag-mcp). - verbatim KHÔNG đổi → KHÔNG trong diff (chỉ `.gist.md` mới + `memory-budget.json` `last_sleep_at`). - 🔴 docs-only path → CI skip (`paths-ignore`, gotcha #41) — commit này 0s. --- ## ⚠️ Guards (đọc kỹ) - 🔴 **Additive-only:** gist = file MỚI. TUYỆT-ĐỐI KHÔNG đè/sửa/xóa verbatim `.md` (B3 · §F1 · G-009 data-loss). - 🔴 **CHỈ P1 gist-compress:** command này KHÔNG build `_INDEX.md` (= P2 archival-event riêng, sub tự-ghi lúc rời L1→L2) · KHÔNG inject read-side · KHÔNG đụng L1/RAG/L3. - 🔴 **double-distill refuse:** `distill-gen ≥ 1` ở đối-tượng → skip (Phase 0.3). Gist mới luôn stamp `distill-gen: 1`. Chỉ nén verbatim `.md` gen-0 (KHÔNG nén `.gist.md`). - 🔴 **coverage-diff = deterministic gate:** surprise/guard/file:line/root-cause/**gotcha#** thiếu → FAIL, KHÔNG ship. ratio = metric KHÔNG target. - 🔴 **Phân-vai cứng (Cách-B):** lead Write+commit (B3 single-writer) · harvest-curator PROPOSE-ONLY (charter cấm-ghi) · reviewer gate Fidelity (G-001 lead-không-tự-chấm). - 🔴 **KHÔNG ép L1 < 30KB** (design BỎ — không phải scope command này; L1-cap-audit sống ở `/session-start §2.1.2`). - 🔴 **Scope SE-repo-only:** CHỈ agent-memory `.claude/agent-memory/**` của SOLUTION_ERP. KHÔNG đụng repo/corpus khác (port-từ §J2-AI_INFRA, tailor parity — xem NOTE đầu file). - 🔴 **G-009 tool-ghi:** Write/Edit only + post-scan mojibake/dollar-exp. - 🔴 **last_sleep_at single home:** chỉ `.claude/agent-memory/memory-budget.json` root-key — KHÔNG nơi khác.