name: prune-memory description: | Use when .claude/memory/ registries grow too large or noisy — superseded entries verbose, similar entries cluttering, journal stale, caveman style drifted. Curates the 5 registries via mark-superseded + merge + inline caveman compression. Append-only safe (no hard delete). Git is the backup. Triggers: "prune memory", "compact memory", "clean memory", "memory hygiene", "trier memoire", "nettoyer memoire", "registres trop longs", "compresse les memoires". argument-hint: [optional: decisions|learnings|blockers|journal|evals — default all 5] disable-model-invocation: false allowed-tools:
Operates on .claude/memory/ in the current project (CWD). Curates the
5 registries: decisions.md, learnings.md, blockers.md, journal.md,
evals.md.
status: superseded by <new-ID>
or status: deprecated instead of deleting. Body of old entry stays
for history.| When | Use |
|---|---|
| Add new entry this session | /close |
| Token-compress one file (not curating) | /caveman:compress <file> |
| Curate: obsolete + merge + caveman | /prune-memory (this skill) |
test -d .claude/memory/ || { echo "no .claude/memory/ in $(pwd)"; exit 1; }
git status --short .claude/memory/ 2>/dev/null
If working tree is dirty on any registry file → STOP with: "Commit or
stash pending changes in .claude/memory/ first. Skill writes in-place.
Git is the only backup."
For each target registry (filter by $ARGUMENTS or all 5):
Read file. Classify candidates into A/B/C/D below. Use today's date for age comparisons. Today's date is in the system context.
status: proposed older than 90 days → propose
status: deprecated (no follow-up).accepted → propose Index row fix to
superseded by <that-ID>.
status: open whose root cause matches a commit in last 30
days (grep git log --since=30.days --grep=<keyword>) → propose
status: resolved with commit ref.## YYYY-MM heading replaces detail).pandoc,
client-handover, CSS overlay).**Reference**: lines.\b(the|a|an|just|really|basically|actually|simply)\b
matches; if > 5% of word count → bloated.## (BDR|LRN|BLK|EVAL)-NNN heading exists but no matching row
in ## Index table → propose Index backfill.status: deleted
(orphaned) tombstone or removal of Index row (user decides).Print one block per registry. Example:
PRUNE PLAN — decisions.md (N entries → M after if approved)
[A. Obsolete — mark superseded]
BDR-003 — Gitignore wildcard pattern — status: proposed since 2026-03-12
→ mark: status: deprecated (no follow-up after 90 days)
BDR-011 — Client handover 4-chapter — body says superseded by BDR-013
→ fix Index: status = "superseded by BDR-013"
[B. Similar — merge]
LRN-014 + LRN-016 — both pandoc rendering quirks
→ propose: merge into NEW LRN-017 ("Pandoc rendering quirks")
with both bodies appended + caveman pass; sources marked
status: superseded by LRN-017
[C. Bloated — inline caveman rewrite]
BDR-011 — body 612 words, filler density 7.2% → ~380 expected (-38%)
[D. Index drift]
(none)
Approve per category? (all / a / b / c / d / edit <ID> / skip)
Wait for user input. Default = nothing applied.
Order: safe → destructive.
status: superseded by <new-ID> in Index (body kept verbatim for
history). Merged body:
**Reference**: lines (dedupe identical paths).a, an, the).just, really, basically, actually, simply).big not extensive, fix not implement a solution for).After each write, regenerate Index from body when rows changed.
# All body entries have Index rows; no orphans
for f in .claude/memory/decisions.md .claude/memory/learnings.md .claude/memory/blockers.md; do
prefix=$(basename "$f" .md | tr a-z A-Z | cut -c1-3)
/usr/bin/grep -oE "^## (${prefix})-[0-9]+" "$f" | while read marker; do
id="${marker##\#\# }"
/usr/bin/grep -q "^| ${id} " "$f" || echo "MISSING INDEX: $id in $f"
done
/usr/bin/grep -oE "^\| (${prefix})-[0-9]+ " "$f" | while read row; do
id=$(echo "$row" | awk '{print $2}')
/usr/bin/grep -q "^## ${id} " "$f" || echo "ORPHAN INDEX: $id in $f"
done
done
wc -l .claude/memory/*.md
Report:
PRUNE COMPLETE
decisions.md : 226 → 184 lines (-19%)
learnings.md : 190 → 165 lines (-13%)
blockers.md : no candidates
journal.md : 88 → 62 lines (-30%)
evals.md : no candidates
INDEX SANITY: OK
NEXT: review `git diff .claude/memory/`, then `/commit-change`
status: accepted in the current session.journal.md
tail to identify them).| Mistake | Fix |
|---|---|
| Renumbering IDs after a merge | IDs are stable. Sources keep their ID + status: superseded. New merged entry gets next-free ID. |
| Hard-deleting "obsolete" entries | Forbidden by append-only rule. Use status: deprecated. Body stays. |
| Compressing code blocks / URLs / error messages | Caveman compression touches PROSE only. Code, URLs, IDs, error quotes stay verbatim. |
| Running on a dirty working tree | PRECHECK blocks this. Commit first. |
| Compressing the current session's journal entry | Excluded by "What NOT to prune" — current session capitalization is still useful. |
| Merging complementary entries that cover different angles | Merge only when same concept, same scope. Different angles = keep separate. |
| Situation | Behavior |
|---|---|
.claude/memory/ missing |
STOP: no .claude/memory/ in current directory; run from project root |
| Working tree dirty on registry files | STOP per PRECHECK; tell user to commit/stash first |
User says skip at STEP 2 |
Exit cleanly, no writes |
| Merge produces an entry > 600 words | Re-split — merge was too greedy. Re-prompt user to keep separate. |
| Index sanity FAILED at STEP 4 | Print exact missing/orphan IDs. Do NOT auto-fix — user re-runs or hand-edits. |
| Caveman compression result < 20% of original AND original had code blocks | Revert that entry's compression — flag as needing manual rewrite (likely stripped technical detail). |
Same file already compressed in same session (e.g. via /caveman:compress) |
Skip C-category for that file; warn user that double-pass risks technical drift. |
v1 ships without baseline test scenarios per superpowers:writing-skills Iron Law. Recommended before relying on the skill in production:
.claude/memory/ snapshot, ask
"prune obsolete entries". Document what it does naturally./prune-memory on the same snapshot. Verify it
follows STEP 0–4 + respects append-only rule.Until TDD is done, the skill is v1-untested. STEP 2 approval gate is the human safety net.