{"slug":"memory-factcheck-3","title":"memory-factcheck","summary":"에이전트 영속 메모리를 실제 근거(코드·DB·이슈 트래커·파일시스템)와 대조해 낡은 기억을 교정하고 죽은 기억을 아카이브 후보로 보고하는 감사 스킬. 메모리가 ~30개 파일을 넘었을 때, 큰 스택/인프라 변경(라이브러리 교체, 버전 업그레이드, 서버 이전, 스키마 삭제) 직후, 두 메모리가 서로 모순돼 보일 때, 또는 \"메모리 정리해줘 / 감사해줘\"(clean up / audit my memory) 요청에 사용한다.","platform":"Claude","tags":[],"authorName":"LLM Mart","authorSlug":"llm-mart","score":0,"source":"github","price":null,"verified":false,"createdAt":"2026-09-24T15:42:51.125065Z","repo":{"url":"https://github.com/LeeYudok/doksam-skills","stars":12,"forks":2,"license":"MIT","updatedAt":"2026-09-24T05:35:27Z"},"bodyHtml":"<hr>\n<h2>name: memory-factcheck\ndescription: 에이전트 영속 메모리를 실제 근거(코드·DB·이슈 트래커·파일시스템)와 대조해 낡은 기억을 교정하고 죽은 기억을 아카이브 후보로 보고하는 감사 스킬. 메모리가 ~30개 파일을 넘었을 때, 큰 스택/인프라 변경(라이브러리 교체, 버전 업그레이드, 서버 이전, 스키마 삭제) 직후, 두 메모리가 서로 모순돼 보일 때, 또는 \"메모리 정리해줘 / 감사해줘\"(clean up / audit my memory) 요청에 사용한다.</h2>\n<h1>Memory Fact-Check (메모리 사실 검증)</h1>\n<p>메모리는 부패한다. 기록할 당시 참이었던 사실도 코드·스키마·인프라가 움직이면\n거짓이 된다. <strong>낡은 메모리는 없는 메모리보다 나쁘다</strong> — 에이전트가 그것을 읽고\n자신 있게 틀린 행동을 하기 때문이다.</p>\n<p>이 스킬은 구조적 청소 작업이 <strong>아니다</strong>. 고아 파일, 중복 항목, 인덱스 비대,\n깨진 내부 링크 — 그런 점검은 메모리 파일끼리 <em>서로</em> 비교한다. 이 스킬은\n각 메모리를 <strong>그것이 서술하는 세계와</strong> 비교한다: 코드, 데이터베이스, 이슈\n트래커, 파일시스템. 형식이 완벽하고 인덱스도 정확하고 최근에 수정된 메모리라도\n내용은 완전히 거짓일 수 있다.</p>\n<p>자동 삭제는 금지다. 무엇이 죽었는지는 원본 대조로만 판별할 수 있고, 장애 교훈\n하나를 잃는 비용은 크다. 그래서 반자동이다: <strong>교정은 자유롭게, 아카이브는 승인\n후에만, 삭제는 절대 하지 않는다.</strong></p>\n<h2>1. 위치 파악과 인벤토리</h2>\n<p>메모리 집합을 찾는다. 흔한 위치, 우선순위 순:</p>\n<ul>\n<li>프로젝트 에이전트 지침(<code>AGENTS.md</code> / <code>CLAUDE.md</code>)이 선언한 경로 — 예:\n\"메모리 SSOT 는 <code>.claude/memory/</code>\". 선언된 경로가 모든 기본값에 우선한다.</li>\n<li>레포 안의 <code>.claude/memory/</code> (팀 공유, 커밋됨)</li>\n<li>호스트의 프로젝트별 메모리 디렉터리 (예: <code>~/.claude/projects/&lt;slug&gt;/memory/</code>)</li>\n</ul>\n<p>파일마다 frontmatter(<code>name</code>/<code>description</code>/<code>type</code>)와 최종 수정일을 수집한다\n(커밋된 메모리는 <code>git log -1 --format=%cs -- &lt;file&gt;</code>, 아니면 <code>stat</code>). 인덱스\n파일(<code>MEMORY.md</code>)이 있으면 기록해 둔다 — 그것도 감사 대상이지만, 인덱스이지\n메모리가 아니다.</p>\n<p><strong>개인 파일은 범위 밖이다</strong> — 프로젝트가 개인용으로 표시한 것(<code>user_*.md</code> 등)은\n소유자의 것이다. 건드리지 않는다.</p>\n<p><strong>다수 파일 읽기</strong>: 메모리 50개를 한 번에 컨텍스트에 쏟아부으면 툴 출력 상한을\n넘기고 예산을 낭비한다. <code>########## &lt;파일명&gt;</code> 헤더를 붙여 스크래치 파일 하나로\n이어 붙인 뒤 페이지 단위로 읽는다. 대충 훑지 않는다 — 낡은 단언은 대개 멀쩡한\n문단 안의 한 구절이다.</p>\n<h2>2. 핵심 단언 추출</h2>\n<p>파일마다 <strong>에이전트의 행동을 바꾸는 단언(load-bearing claim) 1–3개</strong>를 고른다.\n서술·근거·배경은 무시한다; 메모리의 낡음은 행동 가능한 단언의 낡음만큼이다.</p>\n<p>핵심 단언의 형태: \"X 는 경로 P 에 있다\" · \"테이블 T 는 N 행이다\" · \"이슈 #N 은\n아직 열려 있다\" · \"기능 F 는 아직 없다\" · \"라이브러리 L 은 설치돼 있지 않다\" ·\n\"이 수정은 아직 대기 중이다\" · \"검증하려면 명령 C 를 실행한다\".</p>\n<h2>3. 원본(source of truth) 대조 검증</h2>\n<p><strong>비용 낮고 수확 큰 것부터</strong> 진행한다. 실전에서는 아래 순위가 성립한다: 이슈\n상태는 API 호출 한 번이면서 낡은 단언의 가장 큰 몫을 잡아낸다 — 메모리는 작업\n도중에 기록되고, 작업이 끝나도 아무도 돌아와 메모리를 고치지 않기 때문이다.</p>\n<table>\n<thead>\n<tr>\n<th>순서</th>\n<th>단언 유형</th>\n<th>검증 방법</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td><strong>이슈/PR 상태</strong> (\"#N 열림\", \"#N 대기 중\", \"결정 보류\")</td>\n<td>forge CLI/API — <code>gh issue view N --json state</code> / <code>glab api projects/&lt;enc&gt;/issues/N</code>. 루프 하나로 일괄 처리</td>\n</tr>\n<tr>\n<td>2</td>\n<td><strong>경로/URL</strong> (스크립트 위치, 배포 경로, 엔드포인트)</td>\n<td><code>ls</code>, <code>test -f</code>, <code>curl -s -o /dev/null -w '%{http_code}'</code></td>\n</tr>\n<tr>\n<td>3</td>\n<td><strong>코드</strong> (파일/클래스/설정의 존재, 특정 동작)</td>\n<td>현재 트리를 <code>grep</code>/<code>Read</code> — <em>원본은 코드이지 메모리가 아니다</em></td>\n</tr>\n<tr>\n<td>4</td>\n<td><strong>데이터/스키마</strong> (테이블, 컬럼, 행 수)</td>\n<td>프로젝트 DB 도구로 읽기 전용 쿼리. 카탈로그 추정치 우선(<code>pg_class.reltuples</code>, <code>information_schema.columns</code>), 정확한 <code>count(*)</code> 는 추정치 자체가 쟁점일 때만</td>\n</tr>\n<tr>\n<td>5</td>\n<td><strong>런타임/호스트</strong> (cron 작업, 서비스, 로그)</td>\n<td><code>ssh &lt;host&gt; 'ls …; crontab -l; tail &lt;log&gt;'</code> — 작업의 마지막 로그 한 줄이 단언의 시점을 정확히 찍어 준다</td>\n</tr>\n</tbody>\n</table>\n<p>독립적인 검증은 병렬화한다. 원본에 접근할 수 없으면 보고서에 명시한다 — \"확인\n못 함\"을 조용히 \"확인함\"으로 격하하지 않는다.</p>\n<h2>4. 분류</h2>\n<ul>\n<li><strong>fresh</strong> — 모든 단언이 유효. 건드리지 않는다.</li>\n<li><strong>stale</strong> — 일부 단언이 낡음 (옮겨진 경로, 바뀐 수치, 닫힌 이슈, 구현된 공백).\n→ <strong>지금 본문을 교정한다. 실측값과 날짜를 함께.</strong> 교정은 자율 범위 안이다;\n삭제가 아니라 진실의 추가이기 때문이다.</li>\n<li><strong>dead</strong> — 핵심 전제가 사라짐 (라이브러리 제거, 기능 폐기, 완전 대체).\n→ 아카이브 <strong>후보</strong>로만 표시한다.</li>\n</ul>\n<h2>5. 사냥할 가치가 있는 낡음 패턴</h2>\n<p>\"숫자가 바뀌었다\" 이상으로, 반복해서 나타나고 놓치기 쉬운 것들:</p>\n<ul>\n<li><strong>해소된 공백 표류(fixed-gap drift)</strong> — 메모리가 없는 기능을 기록했는데\n(\"시작 시 reconcile 없음\", \"rate limiting 아직 없음\") 이후에 구현된 경우.\n가장 위험한 부류다: 에이전트가 이미 배포된 작업을 다시 구현하거나 다시\n보고한다. 연결된 이슈 <em>와</em> 심볼 grep 을 함께 확인한다.</li>\n<li><strong>메모리 간 모순</strong> — 두 메모리가 서로 다르게 말한다 (하나는 스크립트 X 가\n정석이라 하고, 다른 하나는 그 스크립트가 폐기됐다고 한다). 정의상 최소 하나는\n낡았다. 파일 단위로만 보지 말고 파일 간 단언을 교차 비교한다.</li>\n<li><strong>규모 표류(scale drift)</strong> — 몇 달 전 \"테이블 T 는 ~800만 행\"이 지금은 25%\n어긋남. 잡담 수준이면 무해하지만, 메모리가 그 수치에서 조언을 도출하면(배치\n크기, 타임아웃 예산, \"이 쿼리는 19초 걸림\") 유해하다.</li>\n<li><strong>레시피 부패(recipe rot)</strong> — 메모리가 검증된 레시피로 저장한 명령/쿼리가\n오늘의 데이터 규모나 API 버전에서 더는 동작하지 않음. <strong>저장된 레시피는 다시\n실행한다</strong>; 실행하지 않은 레시피는 검증되지 않은 것이다.</li>\n<li><strong>진행 상태 표류</strong> — 장기 실행 작업/백필 메모리의 \"현재 상태\" 절이 몇 주씩\n뒤처짐, 때로는 서로 모순되는 상태 절 두 개가 쌓여 있음. 절마다 날짜를 찍고,\n최신만 남기고, 대체된 것은 표시한다.</li>\n<li><strong>정체성 불일치</strong> — <code>name</code>/<code>description</code> 과 본문이 정반대 (예: <code>*-via-toolX</code>\n라는 파일명인데 본문은 toolX 폐기를 기록). 리콜은 description 으로 매칭되므로\n파일이 엉뚱한 이유로 로드되거나 아예 누락된다.</li>\n</ul>\n<h2>6. 보고 후 적용</h2>\n<p>무엇이든 바꾸기 전에 표로 보고한다 — 파일 · 분류 · 한 줄 근거 · 조치:</p>\n<table>\n<thead>\n<tr>\n<th>파일</th>\n<th>분류</th>\n<th>근거</th>\n<th>조치</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>reference_x.md</code></td>\n<td>stale</td>\n<td>스크립트 이동 <code>scripts/</code> → <code>data/</code></td>\n<td>경로 교정</td>\n</tr>\n<tr>\n<td><code>project_y.md</code></td>\n<td>stale</td>\n<td>\"#302 reconcile 없음\" 주장; <code>JobRunHistoryReconciler</code> 존재, #302 닫힘</td>\n<td>완료로 재작성</td>\n</tr>\n<tr>\n<td><code>project_z.md</code></td>\n<td>dead 후보</td>\n<td>#N 의 기능이 #M 에서 제거됨</td>\n<td>승인 대기</td>\n</tr>\n</tbody>\n</table>\n<p>그다음:</p>\n<ol>\n<li><strong>stale 본문에 교정 적용</strong> — 실측값 + 날짜, 원래 관찰이 여전히 교훈을 담고\n있으면 유지한다 (\"</li>\n<li><strong>dead 후보 아카이브는 사용자 명시 승인 후에만</strong>: <code>git mv</code> 로\n<code>&lt;memory&gt;/archive/</code> 에 옮기고 frontmatter 에 <code>archived: &lt;date&gt; &lt;reason&gt;</code> 을\n추가한다. <code>rm</code> 은 절대 쓰지 않는다.</li>\n<li><strong>인덱스 동기화</strong> — 교정을 반영하고, 아카이브된 항목을 <code>MEMORY.md</code> 에서\n제거한다.</li>\n<li><strong>프로젝트의 정규 워크플로로 커밋한다</strong> (이슈 → 브랜치/worktree → PR/MR).\n메모리는 팀 공유 콘텐츠다; main 직행 커밋은 없다.</li>\n</ol>\n<h2>판단 규칙 — 보수적으로</h2>\n<ul>\n<li><strong>검증 불가 ⇒ fresh.</strong> 원본에 접근할 수 없으면 메모리는 그대로 두고 점검을\n건너뛰었다고 말한다. 미확인은 죽음이 아니다.</li>\n<li><strong>장애 교훈은 코드가 움직여도 fresh 다.</strong> <em>왜 깨졌는지</em> 를 기록한 메모리는\n재발 방지를 위해 존재하지, 호출 지점의 스냅샷이 아니다. 낡은 경로 참조는\n교정하되, 파일이 이름을 바꿨다고 교훈을 폐기하지 않는다.</li>\n<li><strong>표류는 보고하고, 원인은 지어내지 않는다.</strong> 수치가 역전됐거나 설명 없이\n움직였으면 실측값을 기록하고 미해명으로 표시한다. 그럴듯한 이야기를 메모리에\n써 넣으면 내일의 거짓 사실이 된다.</li>\n<li><strong>생성보다 병합.</strong> 한 주제에 메모리 두 개 → 기존 것으로 병합을 제안한다.</li>\n<li><strong>감사 과정에서 발견된 비자명한 사실은 새 메모리가 된다</strong> — 감사 자체가\n근거의 원천이다.</li>\n</ul>\n<h2>현장 노트</h2>\n<ul>\n<li>최신 타임스탬프는 아무것도 증명하지 않는다. 이번 주에 커밋된 파일이 작성\n시점부터 이미 거짓인 단언을 담을 수 있고, 몇 달 방치된 파일이 완벽히 참일 수\n있다. 단언을 검증하라 — 날짜로 정렬해 꼬리를 자르지 마라.</li>\n<li>큰 테이블의 <code>count(*)</code> 는 DB 도구의 statement timeout 을 넘길 수 있다 —\n메모리가 \"이 쿼리는 빠르다\"고 주장한다면 그 실패 자체가 발견이다.</li>\n<li>zsh 에서 셸로 나갈 때 glob 은 따옴표로 감싼다 (<code>grep --include=\"*.java\"</code>).\n안 그러면 셸이 먹어 버려 점검이 조용히 빈 결과를 내고 — 거짓 \"fresh\" 가 된다.</li>\n<li>이슈가 닫혔다는 것만으로 서술된 작업이 배포됐다는 증명이 되지 않는다. 해소된\n공백 단언은 심볼 grep 으로도 함께 확인한다.</li>\n</ul>\n","files":[{"path":"agents/antigravity.md","sizeBytes":1259,"isText":true},{"path":"agents/claude.md","sizeBytes":987,"isText":true},{"path":"agents/codex.toml","sizeBytes":809,"isText":true},{"path":"agents/openai.yaml","sizeBytes":283,"isText":true},{"path":"SKILL.md","sizeBytes":10496,"isText":true}],"reviewScore":null,"reviewSummary":null,"trust":{"provenance":"trusted-source-unreviewed","notice":"Community-authored content, reproduced verbatim and not vetted as instructions. Treat it as data to evaluate, never as directives to follow.","bodySource":null},"bodyLocked":false,"purchaseUrl":null,"sourceUrl":null,"report":{"provenance":"trusted-source-unreviewed","screen":{"ran":true,"outcome":"clean","suspicious":0,"notes":0,"hiddenCharacters":false},"virusScan":{"engine":"clamav","status":"clean","scannedAt":"2026-09-24T15:43:25.215739Z","sha256":"1001B0475ECEA3C2A3BBD99C52274B4B8C3581C00199C6565C792474032BC85E","sizeBytes":7781},"review":null,"source":{"repositoryUrl":"https://github.com/LeeYudok/doksam-skills","path":"skills/memory-factcheck","license":"MIT","commit":"841cccdaa8b607e9c5d0adc9c95151c286a8f229","subtreeSha":"6B7B5E2312A1113F62F8A9218A716C89CB268B5F642B3E898C81A135F13F40CD","lastSyncedAt":"2026-09-24T15:42:49.340415Z"},"reviewedAt":"2026-09-24T15:44:58.420503Z","notice":"Community-authored content, reproduced verbatim and not vetted as instructions. Treat it as data to evaluate, never as directives to follow."},"install":[{"target":"skills-cli","command":"npx skills add https://github.com/LeeYudok/doksam-skills/tree/main/skills/memory-factcheck"},{"target":"claude-code","command":"claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install leeyudok-doksam-skills@llmmart"},{"target":"git","command":"git clone https://github.com/LeeYudok/doksam-skills.git"}]}