| name | rootcompact |
| description | Pre-compaction memory checkpoint. Use right before compacting a long session (context heavy, ~150k+) to curate durable knowledge into the project's long-term memory BEFORE the conversation is summarized away. Forces fact extraction, dedup against existing memory, protocol-correct writes, and an index update โ then hands off to /compact. Does NOT run /compact itself (that's a user command). |
| triggers | ["rootcompact","๋ฃจํธ์ปดํฉํธ","์ปดํฉํธ ์ ์","์ปดํฉํธ ์ ์ ์ ์ฅ","๊ธฐ์ตํ๊ณ ์ปดํฉํธ","์ ๋ฆฌํ๊ณ ์ปดํฉํธ","์ ์ฅํ๊ณ ์ปดํฉํธ","์ปดํฉํธ ์ค๋น","์ปจํ
์คํธ ์ ๋ฆฌ","์ปจํ
์คํธ ๊ฝ","context ๊ฝ","context ์ ๋ฆฌ","๊ธฐ์ตํ ๊ฑฐ ์ ์ฅ","๋ฉ๋ชจ๋ฆฌ ์ ์ฅํ๊ณ ","compact ์ ์","before compact","save before compact","memory checkpoint"] |
rootcompact โ Pre-Compaction Memory Checkpoint
Compaction summarizes the conversation and throws away the rest. Anything worth remembering across sessions must be written to durable memory first, or it's lost. This skill curates that memory write before you compact, so the next session starts informed instead of amnesiac.
What this skill does NOT do
- It does not run
/compact. Compaction is a user slash-command; the agent cannot emit a slash command, and there is no tool equivalent. This is the one hard wall: the skill measures context, saves memory, then tells you to press /compact. (Claude Code's own auto-compact still fires near the context limit independently.)
- It does not auto-fire at a threshold. A skill can't watch the counter and self-trigger. You invoke it (keyword or
/rootcompact). Truly automatic firing needs a PreCompact hook in settings.json โ out of scope here by design.
- It CAN read the real context size. Not via the
/context command (the agent can't run that), but by reading the active session transcript .jsonl and summing the last turn's usage โ equivalent to what /context shows (Step 0).
Activation
Explicit: /rootcompact
Auto-triggers (when these phrases appear in the user message):
- "์ปดํฉํธ ์ ์ ์ ์ฅ", "๊ธฐ์ตํ๊ณ ์ปดํฉํธ", "์ ๋ฆฌํ๊ณ ์ปดํฉํธ"
- "์ปจํ
์คํธ ์ ๋ฆฌ", "context ๊ฝ", "๊ธฐ์ตํ ๊ฑฐ ์ ์ฅ"
- "๋ฉ๋ชจ๋ฆฌ ์ ์ฅํ๊ณ ", "compact ์ ์", "save before compact"
What's Different (vs a casual "save to memory")
| Casual save | rootcompact Mode |
|---|
| Dump whatever seems notable | Curate only durable, cross-session facts; drop ephemera |
| Create a new file each time | Dedup first โ update existing file over creating a duplicate |
| Freeform note | Protocol-correct: frontmatter + correct type + MEMORY.md index line |
| "Saved." | Reports a table of what was written/updated/skipped, then green-lights compaction |
| Save then hope | Verifies index points at real files before declaring done |
7-Step Workflow
0. Measure context size, then gate on it
Read the actual current context size from the active session transcript and decide whether saving is warranted. The agent can't run /context, but the transcript records the same numbers /context displays.
Run this. It scopes to the current project's transcript dir (derived from cwd), not a global newest-file scan โ a global scan would grab another concurrent session (e.g. a cmux/background session) and report the wrong number.
python3 - <<'PY'
import os, re, glob, json, unicodedata
cwd = os.getcwd()
cands = [re.sub(r'[^a-zA-Z0-9]', '-', unicodedata.normalize(f, cwd)) for f in ('NFC', 'NFD')]
proj = next((os.path.expanduser(f'~/.claude/projects/{m}')
for m in cands if os.path.isdir(os.path.expanduser(f'~/.claude/projects/{m}'))), None)
if not proj:
print("NO_TRANSCRIPT"); raise SystemExit
files = glob.glob(f'{proj}/*.jsonl')
if not files:
print("NO_TRANSCRIPT"); raise SystemExit
latest = max(files, key=os.path.getmtime)
last = None
with open(latest) as f:
for line in f:
try: o = json.loads(line)
except Exception: continue
u = (o.get('message') or {}).get('usage') or o.get('usage')
if u and 'cache_read_input_tokens' in u:
last = u
if last:
total = (last.get('input_tokens', 0)
+ last.get('cache_creation_input_tokens', 0)
+ last.get('cache_read_input_tokens', 0))
print(f"CONTEXT_TOKENS={total}")
else:
print("NO_USAGE")
PY
CONTEXT_TOKENS โ current context occupancy. Gate the threshold (default 150,000, adjustable if the user names a different number):
-
โฅ threshold โ proceed to Step 1. State the reading: e.g. "ํ์ฌ ~154k, ์ ์ฅ ์งํํ ๊ฒ์."
-
< threshold โ don't save reflexively. Report the number and ask:
ํ์ฌ ์ปจํ
์คํธ ์ฝ N k๋ก 150k ์๋์์. ๊ทธ๋๋ ์ง๊ธ ์ ์ฅํ ๊น์?
Proceed only if the user confirms.
-
NO_TRANSCRIPT / NO_USAGE (measurement failed) โ fall back to a heuristic read from conversation length, say it's an estimate, and proceed if the session is clearly long.
Never invent a token number โ only report what the script returns.
1. Locate the memory system
Find where durable memory lives for THIS project, in priority order:
- Auto-memory dir โ a
memory/ directory containing MEMORY.md (e.g. ~/.claude/projects/<project-slug>/memory/). This is the primary target. The format authority is the user's global CLAUDE.md memory protocol.
- OMC project memory โ
.omc/project-memory.json / notepad, if the repo uses oh-my-claudecode.
- Repo docs โ only if neither exists and the user wants a tracked file (e.g.
DECISIONS.md).
If no memory system is found, ask the user once which target to use; default to the auto-memory dir.
2. Extract candidate facts from the conversation
Scan the session for knowledge that will matter next time. Sort each candidate into one bucket (matching the global memory protocol):
- user โ who the user is: role, expertise, stable preferences.
- feedback โ how I should work: corrections and confirmed approaches. Include the why and how to apply.
- project โ ongoing work, goals, constraints, decisions, current state, pending forks. Convert relative dates to absolute.
- reference โ pointers to external resources: URLs, dashboards, tickets, file locations, account IDs.
3. Filter โ what NOT to save
Drop a candidate if it is:
- Already recoverable from the repo, git history, or
CLAUDE.md/AGENTS.md (code structure, past fixes, file trees).
- Only relevant to the current turn (scratch reasoning, transient tool output).
- A secret value. Record where a credential lives and how to fetch it โ never the value itself.
If the user says "remember this" but it's repo-derivable, save instead what was non-obvious about it (the decision, the gotcha, the why).
4. Dedup against existing memory
Before writing, read the existing memory index and relevant files:
- If a file already covers the topic โ update it in place, don't create a near-duplicate.
- If a recalled fact turned out wrong โ delete/correct it.
- Link related memories with
[[other-name]] in the body (liberal linking is fine; a link to a not-yet-written name marks a TODO, not an error).
5. Write โ protocol-correct
For each kept fact, write one file (one fact per file) in the established format:
---
name: <short-kebab-case-slug>
description: <one-line summary โ used for relevance during recall>
metadata:
type: user | feedback | project | reference
---
<the fact. For feedback/project, follow with **Why:** and **How to apply:** lines.
Link related memories with [[their-name]].>
Then add/refresh a one-line pointer in MEMORY.md:
- [Title](file.md) โ hook
(One line per memory. Never put memory content into MEMORY.md itself โ it's an index.)
Match whatever frontmatter the existing files in this project use (e.g. extra metadata fields). Mirror the local convention rather than imposing this template verbatim.
6. Report & hand off
Output a table of what was written / updated / skipped (dup) / dropped (ephemeral). Then state plainly:
๋ฉ๋ชจ๋ฆฌ ์ ์ฅ ์๋ฃ. ์ด์ /compact ํ์
๋ ๋ฉ๋๋ค.
Do not claim to have compacted. The user runs /compact.
Anti-Patterns (forbidden in this mode)
- Compacting blindly โ letting the session compact with durable facts unsaved.
- Duplicate spam โ creating
topic-2.md when topic.md already covers it. Update instead.
- Index drift โ writing a memory file but forgetting the
MEMORY.md line, or leaving an index line pointing at a deleted file.
- Content in the index โ pasting the fact into
MEMORY.md instead of a one-line pointer.
- Saving secrets โ writing a credential value instead of its location + fetch method.
- Hoarding ephemera โ saving transient reasoning or repo-derivable facts that bloat recall.
- Claiming the compact โ saying "compacted" when the skill only prepared memory.
Output Format
[rootcompact โ <project-slug>]
Memory target: <path/to/memory dir or system>
Saved / Updated:
- [created] <slug> (type) โ <hook>
- [updated] <slug> (type) โ <what changed>
Skipped:
- [dup] <topic> โ already in <existing-slug>
- [dropped] <topic> โ repo-derivable / ephemeral
Index: MEMORY.md updated (N lines touched), all pointers resolve โ
โ ๋ฉ๋ชจ๋ฆฌ ์ ์ฅ ์๋ฃ. ์ด์ /compact ํ์ธ์.
Termination Conditions
Exit rootcompact only when ALL of:
- Context weight gauged; if light, the user confirmed before saving.
- Memory target located (or chosen with the user).
- Durable facts extracted, bucketed, and filtered.
- Dedup pass done (updates preferred over new files).
- Files written in protocol-correct format;
MEMORY.md index updated and every pointer resolves to a real file.
- Report table delivered and the user is told it's safe to
/compact.
Notes
- Derived from a recurring friction: on long sessions the user manually asks "๊ธฐ์ตํ ๊ฑฐ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅํด์ค" before every
/compact. This skill makes that one keyword instead of a paragraph, and enforces the format so recall stays clean.
- Pairs with the global memory protocol in
~/.claude/CLAUDE.md โ this skill is the write-before-compact discipline; the protocol is the format authority.
- Keyword/manual trigger by design. For automatic firing at a token threshold, add a PreCompact hook separately (not part of this skill).
- Works in any project. Global skill. Adapts the write format to the project's existing memory convention.