메모리 인덱스를 정리한다 — 중복 병합·만료 정리·설명 압축. "메모리 정리·기억 정리·메모리 중복·인덱스가 너무 커·메모리 압축·비슷한 기억 합쳐" 류 요청, 그리고 인덱스가 캡에 닿았을 때. ★자동으로 합치지 않는다: 제안하고 사람이 고른다. 지우지 않는다: 아카이브(검색으로 계속 찾히고 되돌릴 수 있다).
Installs into .claude/skills of the current project.
Are you the author of Memory Tidy?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/tigu77-memory-tidy)
---
name: memory-tidy
description: 메모리 인덱스를 정리한다 — 중복 병합·만료 정리·설명 압축. "메모리 정리·기억 정리·메모리 중복·인덱스가 너무 커·메모리 압축·비슷한 기억 합쳐" 류 요청, 그리고 인덱스가 캡에 닿았을 때. ★자동으로 합치지 않는다: 제안하고 사람이 고른다. 지우지 않는다: 아카이브(검색으로 계속 찾히고 되돌릴 수 있다).
reach: main
---
# 메모리 정리
## 0. 왜 필요한가
상시 규범은 **계속 늘어난다** — 사용자가 계속 입력하고, 비서도 관측을 적는다. 오래 쓴
설치에서는 메모리 인덱스가 매 턴 실리는 상수 중 **가장 큰 조각**이 되고 캡에 닿는다
(개발 인스턴스 실측: 3주에 약 4배). ★네 설치의 값은 `/status` 와 아래 §1 로 직접 재라 —
이 숫자를 그대로 옮겨 적지 마라.
★**캡을 내리는 건 답이 아니다.** 같은 날 재보니 캡을 반으로 내리면 사람이 쓴 **77건**이
잘리고 그 안에 상시 행동 규칙이 있었다(`style-never-auto-push-…` 등). 경계도 촘촘했다 —
잘리는 것 최대 access 19 / 남는 것 최소 20.
★**진짜 여유는 중복에 있다.** 같은 실측에서 나온 것:
- 「답글 형식」이 **3건**(access 287·278·257 — 상위 3개가 전부 한 주제다)
- 「스킬화」 3건 · 「위임」 3건 · 「위키 커밋·푸시」 2건(거의 같은 문장) · 「system-reminder」 2건
- 자동 생성 `feedback_growth_*` **24건 5.1KB**(15%) — 기계 해시 이름
- **만료된 것** — 지나간 일정·끝난 작업처럼 **시효가 있는 사실**이 아직 매 턴 실린다
## 1. 하드룰 (여기부터 읽어라)
- **물리 삭제하지 않는다.** `delete_memory` 대신 `archive_memory`를 사용한다.
아카이브분은 자동 회수에서 제외된다. `search_memory`로 찾을 수 있지만 검색만으로
인덱스에 복귀하지 않는다. 복귀에는 `archive_memory({names: [...], restore: true})`가 필요하다.
- ★**한 판은 한 호출이다.** `archive_memory` 는 `names` **배열**을 받는다 — 승인받은
묶음을 한 번에 넘겨라(건별로 20번 부르지 마라: 왕복도 승인도 스무 배고, 중간에 턴이
끊기면 «절반만 정리된» 상태가 남는다).
- ★**자동으로 합치지 않는다.** 「이건 중복이다」가 틀리면 규칙이 **조용히** 사라지고, 다음
사고 때야 알게 된다. 제안까지가 이 스킬의 일이고, 고르는 건 사람이다.
- ★**재고 나서 말한다.** "많다"·"중복이다"는 숫자를 대고 하는 말이다(§2 가 그 숫자다).
- ★★**내린 것은 스스로 돌아오지 않는다.** 아카이브분은 매 턴 자동 회수에서 빠지고,
«읽히면 다시 올라온다» 는 회복 경로는 **없다**. 그러니 내리는 판단은 되돌릴 수 있을 뿐
저절로 고쳐지지 않는다 — 규범은 §4의 이관·도달 확인 전에는 내리지 마라.
- ★**그래도 규범과 사실은 다르게 다룬다** — 규범은 애초에 여기 있으면 안 된다(`add_memory`
도구 설명과 헌법 §4를 따른다).
§4 가 이관을 다룬다. 이관과 도달 확인 전 규범은 **내리지 마라** — 「자동 푸시 금지」는
push 얘기가 나와야 살아나는데 그때는 **이미 늦다**.
## 2. 먼저 잰다
**`list_memories` 도구를 쓴다.** 이름·종류·설명·읽힌 횟수·인덱스 바이트 + 총량·캡을 한 번에
준다(읽기 전용, 본문 제외).
`list_memories`의 바이트 값을 사용한다. SQLite `length(TEXT)`는 문자 수이므로
한국어 인덱스의 바이트로 보고하지 않는다.
읽고 나서 적을 것: **총 건수 · 총 인덱스 바이트 · 캡 대비 %** — 아래 모든 판단이 이 세
숫자 위에 선다.
## 3. ★한 번에 하는 일을 **바운드**한다 (전수 훑기 금지)
목록 집계와 내용 검토를 구분한다. `list_memories` 기본 반환은 비아카이브 목록이며,
실제 프롬프트에 실린 항목만을 뜻하지 않는다. 내용 검토는 아래 상한을 지킨다.
그래서 **한 번의 실행은 크기가 정해져 있다:**
- **상위 N건만.** `list_memories` 의 `indexBytes` 내림차순으로 **최대 25건**. 인덱스를
차지하는 건 큰 것들이고, 작은 것 170건을 훑어야 얻는 건 몇 백 바이트다.
- **본문을 읽지 마라.** 판단은 **이름 + 설명**으로 한다(그게 인덱스에 실리는 전부다).
본문이 꼭 필요한 건 «합쳤을 때 잃는 문장이 있나» 를 확인하는 **최종 후보 몇 건**뿐이다.
첫 판이 느렸던 진짜 이유가 197건 본문 읽기였다.
- **한 번에 끝내려 하지 마라.** 반복 실행이 전제다. 이번에 상위 25건을 정리하면 다음
실행의 상위 25건은 다른 것들이다 — 매번 **같은 시간**이 들고 매번 앞줄부터 줄어든다.
- `all` 또는 생략은 모든 부류를 후보로 삼되 최대 25건이다. `dupes`·`expired`·`obs`도 같은 상한을 적용한다.
- 자동 생성 `feedback_growth_*`는 self-growth 소유이므로 변경 후보에서 제외하고 개수·바이트만 보고한다.
## 4. ★먼저 «여기 있으면 안 되는 것» 을 가른다 (승격·이관)
정리의 첫 질문은 «합칠까 지울까» 가 아니라 **«이게 애초에 이 자리인가»** 다.
헌법이 이미 정해뒀는데(§1·§4) 지켜지지 않은 것들이 쌓인다 — `add_memory` 는 도구 한 번이고
문서 편집은 손이 가서, **저항이 낮은 쪽으로 흐르기 때문**이다. 규칙을 어긴 게 아니라
비탈이 그쪽이다.
판정의 근거는 헌법 §4, 도구 사용 시 기준은 `add_memory` 설명이다.
검색할 낱말의 유무나 중요도로 가르지 않고 **사실인가, 행동 규범인가**를 먼저 본다.
- 취미·기기·일정 등 회수할 사실은 메모리에 둔다.
- 전역 상시 규범은 `<home>/AGENT.md`, 프로젝트 지침은 해당 `PROJECT.md`로 이관한다.
- 조건부 절차의 상세는 스킬로 옮기고 적용 지점에서 찾을 포인터를 남긴다.
- 사실과 규범이 섞였으면 분리한다. 범위가 불명확하면 이관 후보로만 제시한다.
이관은 §7에서 목적지와 내용을 함께 승인받는다. 목적지에 조건·예외를 보존하고
해당 작업에서 실제로 읽히는 경로를 확인한 뒤에만 원본을 아카이브한다.
파일을 만들었다는 이유만으로 도달이 보장됐다고 판단하지 않는다. 도달을 확인하지 못한 규범은 유지한다.
## 5. 후보를 뽑는다 (셋을 가른다 — 다루는 법이 다르다)
셋은 **처방이 다르다.** 섞어서 한 무더기로 다루면 병합해야 할 것을 지우게 된다.
- **중복** — 같은 사실이 두 건 이상. 판정은 *«한쪽을 지우면 잃는 문장이 있나»* 다.
없으면 중복, 있으면 별개다. → **병합**(§6), 삭제가 아니다.
- **만료** — 그때는 참이었고 지금은 아닌 것(끝난 작업·바뀐 경로·없어진 기능).
판정은 *«이 문장이 가리키는 것이 아직 있나»* — 코드·파일로 확인한다. → **아카이브**.
- **관측(obs)** — 한 번의 사건 기록인데 규칙으로 승격되지 않은 것.
판정은 *«이걸 읽고 다음에 달라질 행동이 있나»* 다. 없으면 관측이다. → **아카이브**.
★어느 쪽인지 **모르겠으면 두어라.** 잘못 지운 것은 사용자가 모르고, 남겨 둔 것은
인덱스 한 줄일 뿐이다.
## 6. 병합안을 만든다
- **하나로 합칠 때 잃는 문장이 없어야 한다.** 세 건을 한 건으로 줄이면서 각각이 담고 있던
*조건·예외·근거*가 빠지면 그건 압축이 아니라 손실이다. 합친 뒤 원본을 나란히 놓고 읽어라.
- **이름은 남는 것 중 가장 많이 읽힌 것**을 쓴다(access 가 그 이름으로 쌓여 있다).
- 설명은 **한 줄**로. 인덱스에 실리는 건 `name: description` 뿐이고 본문은 `read_memory`
로 간다 — 설명에 본문을 우겨넣지 마라(그게 인덱스가 큰 진짜 이유다).
## 7. 사람에게 보이고 승인받는다
```
합침: style-always-reply-to-current-message (287)
style-reply-like-thread-context (278)
feedback-obs-reply-style-misunderstood (257)
→ style-always-reply-to-current-message: "<합친 한 줄>"
잃는 것: 없음 / 아카이브 2건 (검색으로 계속 찾힘, 되돌릴 수 있음)
```
**승인 뒤에만** `update_memory`(합친 내용) + `archive_memory`(원본들 — `names` 에 **한꺼번에**)
를 실행한다.
## 8. 끝나고
- 인덱스 바이트를 **다시 재서** 전후를 적는다(줄었다는 말은 숫자를 대고 한다).
- ★**캡을 내리자는 결론으로 가지 마라** — 이 스킬의 목적은 «같은 캡 안에 더 잘 담기» 다.
캡 조절은 `settings.json` 의 `memory.indexCapBytes` 이고, 그건 사용자 결정이다.