히스토리

claude-memory → ~/org/ Denote 마이그레이션 전략

🎯 미션: 디지털 가든 퍼블리시 준비

English Translation

“Migrate claude-memory system to ~/org/ in Denote format for digital garden publishing”

📊 현황 분석 (2025-10-16 07:52)

claude-memory 구조 (PARA 방법론)

~/claude-memory/
├── projects/     # 활성 프로젝트 (~30개 .md 파일)
├── areas/        # 지속적 관심사 (~20개 .md 파일)
├── resources/    # 재사용 패턴
├── archives/     # 완료 항목
├── daily/        # 일일 로그
└── meetings/     # 회의 기록

~/org/ 구조 (Denote 기반)

~/org/
├── bib/          # 서지 노트 (800+ .org)
├── meta/         # 메타 주제
├── notes/        # 개인 노트
├── journal/      # 저널 (주간)
├── llmlog/       # AI 대화 로그
└── archives/     # 아카이브

파일 현황

  • claude-memory: Markdown (.md) 파일, PARA 구조
  • ~/org/: Org-mode (.org) 파일, Denote 타임스탬프

🎯 마이그레이션 전략

Phase 1: 파일 포맷 변환 (MD → ORG) ⚡ URGENT

변환 규칙
  1. 파일명 변환: Denote 형식 유지

    • 기존: 20251013T084700--제목__태그1_태그2.md
    • 변환: 20251013T084700--제목__태그1_태그2.org
  2. 프론트매터 변환: YAML → Org properties

    # Before (Markdown)
    ---
    title:      "제목"
    date:       2025-10-13T08:47:00+09:00
    tags:       ["tag1", "tag2"]
    identifier: "20251013T084700"
    ---
    # After (Org-mode)
    #+title:      제목
    #+date:       [2025-10-13 Mon 08:47]
    #+filetags:   :tag1:tag2:
    #+identifier: 20251013T084700
    #+export_file_name: 20251013T084700.md
  3. 본문 변환: Markdown → Org-mode

    • 헤딩: ## 제목** 제목
    • 리스트: 동일 유지
    • 코드 블록: ```lang#+begin_src lang
    • 링크: [text](url)[[url][text]]
디렉토리 맵핑 (PARA → Denote)
claude-memory~/org/비고
projects/notes/활성 프로젝트 → 노트
areas/notes/관심사 → 노트
resources/meta/재사용 패턴 → 메타
archives/archives/완료 항목
daily/llmlog/일일 로그 → AI 로그
meetings/notes/회의 → 노트

Phase 2: 변환 스크립트 작성

스크립트 개요: migrate_memory_to_org.py
#!/usr/bin/env python3
"""
claude-memory → ~/org/ Denote 마이그레이션
- Markdown → Org-mode 변환
- YAML → Org properties
- PARA → Denote 디렉토리 맵핑
"""
 
import os
import re
import yaml
from pathlib import Path
from datetime import datetime
 
# 설정
SOURCE_DIR = Path.home() / "claude-memory"
TARGET_DIR = Path.home() / "org"
 
# 디렉토리 맵핑
DIR_MAPPING = {
    "projects": "notes",
    "areas": "notes",
    "resources": "meta",
    "archives": "archives",
    "daily": "llmlog",
    "meetings": "notes",
}
 
def convert_yaml_to_org(yaml_front):
    """YAML frontmatter → Org properties"""
    data = yaml.safe_load(yaml_front)
    
    # 날짜 변환: ISO → Org timestamp
    date = datetime.fromisoformat(data['date'].replace('Z', '+00:00'))
    org_date = date.strftime("[%Y-%m-%d %a %H:%M]")
    
    # 태그 변환: ["tag1", "tag2"] → :tag1:tag2:
    tags = ":".join(data.get('tags', [])) if data.get('tags') else ""
    if tags:
        tags = f":{tags}:"
    
    # Org properties 생성
    org_props = f"""#+title:      {data['title']}
#+date:       {org_date}
#+filetags:   {tags}
#+identifier: {data['identifier']}
#+export_file_name: {data['identifier']}.md
"""
    return org_props
 
def convert_markdown_to_org(md_content):
    """Markdown 본문 → Org-mode"""
    # 헤딩 변환: ## → **
    content = re.sub(r'^(#{2,6})\s+(.+)$', 
                     lambda m: '*' * len(m.group(1)) + ' ' + m.group(2), 
                     md_content, flags=re.MULTILINE)
    
    # 코드 블록: ```lang → #+begin_src lang
    content = re.sub(r'^```(\w+)$', r'#+begin_src \1', content, flags=re.MULTILINE)
    content = re.sub(r'^```$', r'#+end_src', content, flags=re.MULTILINE)
    
    # 링크: [text](url) → [[url][text]]
    content = re.sub(r'\[([^\]]+)\]\(([^\)]+)\)', r'[[\2][\1]]', content)
    
    return content
 
def migrate_file(source_file):
    """단일 파일 마이그레이션"""
    # 파일 읽기
    with open(source_file, 'r', encoding='utf-8') as f:
        content = f.read()
    
    # YAML frontmatter 추출
    yaml_match = re.match(r'^---\n(.*?)\n---\n(.*)$', content, re.DOTALL)
    if not yaml_match:
        print(f"⚠️  YAML 없음: {source_file}")
        return
    
    yaml_front, md_body = yaml_match.groups()
    
    # 변환
    org_props = convert_yaml_to_org(yaml_front)
    org_body = convert_markdown_to_org(md_body)
    
    # 최종 Org 파일 생성
    org_content = org_props + "\n" + org_body
    
    # 디렉토리 맵핑
    rel_path = source_file.relative_to(SOURCE_DIR)
    source_dir = rel_path.parts[0]
    target_subdir = DIR_MAPPING.get(source_dir, "notes")
    
    # 파일명 변경: .md → .org
    target_file = TARGET_DIR / target_subdir / rel_path.name.replace('.md', '.org')
    
    # 디렉토리 생성
    target_file.parent.mkdir(parents=True, exist_ok=True)
    
    # 파일 쓰기
    with open(target_file, 'w', encoding='utf-8') as f:
        f.write(org_content)
    
    print(f"✅ {source_file.name}{target_file}")
 
def main():
    """메인 마이그레이션 프로세스"""
    print("🚀 claude-memory → ~/org/ 마이그레이션 시작\n")
    
    # 모든 .md 파일 찾기
    md_files = list(SOURCE_DIR.rglob("*.md"))
    print(f"📄 발견: {len(md_files)}개 Markdown 파일\n")
    
    # 마이그레이션 실행
    for md_file in md_files:
        try:
            migrate_file(md_file)
        except Exception as e:
            print(f"❌ 실패: {md_file.name} - {e}")
    
    print("\n✨ 마이그레이션 완료!")
 
if __name__ == "__main__":
    main()
실행 방법
# 1. 스크립트 저장
cd ~/org/llmlog/
nano migrate_memory_to_org.py  # 위 스크립트 붙여넣기
 
# 2. 실행 권한 부여
chmod +x migrate_memory_to_org.py
 
# 3. DRY RUN (테스트 - 실제 파일 생성 안함)
python3 migrate_memory_to_org.py --dry-run
 
# 4. 실제 마이그레이션 실행
python3 migrate_memory_to_org.py
 
# 5. Git 확인
cd ~/org/
git status
git diff

Phase 3: 검증 & 클린업

검증 체크리스트
  • 파일 개수 일치 (~50개)
  • Denote 파일명 형식 유지
  • Org properties 정상 변환
  • 본문 Org syntax 정상
  • 링크 동작 확인
  • 태그 정상 변환
Git 작업
cd ~/org/
 
# 1. 변경사항 확인
git status
git diff notes/ meta/ llmlog/ archives/
 
# 2. 커밋 (출근 후)
git add notes/ meta/ llmlog/ archives/
git commit -m "migrate: claude-memory → org/denote structure
 
- Convert Markdown → Org-mode
- YAML frontmatter → Org properties
- PARA dirs → Denote structure
- 50+ files migrated"
 
# 3. 푸시
git push origin main

Phase 4: 디지털 가든 퍼블리시

Quartz 설정 확인
cd ~/repos/gh/notes/
 
# 1. Org → Markdown 변환 (ox-hugo)
# (Emacs에서 자동 export 확인)
 
# 2. Quartz 빌드
npm run build
 
# 3. 로컬 테스트
npm run serve
 
# 4. 배포
git add content/
git commit -m "publish: claude-memory migration content"
git push origin main

⚡ 긴급 실행 체크리스트 (출근 직후)

준비 단계 (5분)

  • cd ~/org/llmlog/
  • migrate_memory_to_org.py 스크립트 생성
  • 스크립트 권한 부여 (chmod +x)

실행 단계 (10분)

  • DRY RUN 테스트
  • 실제 마이그레이션 실행
  • 파일 개수 검증
  • 샘플 파일 검토 (3-5개)

커밋 & 푸시 (5분)

  • git status 확인
  • git add 변경사항
  • git commit with message
  • git push origin main

퍼블리시 (10분)

  • Emacs Org export (ox-hugo)
  • Quartz 빌드
  • 로컬 확인
  • Git push (notes.junghanacs.com)

💡 핵심 포인트

왜 이 마이그레이션이 필요한가?

단일 진실의 원천 (Single Source of Truth)
  • 현재: claude-memory (Markdown) + ~/org/ (Org-mode) = 이중 관리
  • 목표: ~/org/ (Org-mode) 단일 시스템
  • 이점: 디지털 가든 자동 퍼블리시, 검색 통합, 유지보수 단순화
Denote 생태계 통합
  • claude-memory의 Denote 파일명 규칙 → ~/org/와 완전 호환
  • 타임스탬프 기반 검색, 태그 시스템 통합
  • Emacs Denote 패키지로 통합 관리
디지털 가든 퍼블리시
  • Org-mode → Quartz 4 파이프라인 구축
  • AI 메모리 시스템 → 공개 지식 공유
  • notes.junghanacs.com 자동 업데이트

리스크 & 대응

리스크 1: 변환 오류
  • 가능성: 중간
  • 영향: 중간
  • 대응: 샘플 파일 수동 검토, Git diff 확인
리스크 2: 링크 깨짐
  • 가능성: 낮음
  • 영향: 중간
  • 대응: Org 링크 syntax 테스트, 퍼블리시 전 검증
리스크 3: 시간 부족 (출근 전)
  • 가능성: 낮음
  • 영향: 낮음
  • 대응: 스크립트 자동화, 점진적 마이그레이션 가능

🔗 관련 문서

📊 예상 결과

Before (현재)

두 개의 독립 시스템:
- claude-memory/ (50개 .md) → AI 메모리만
- ~/org/ (1,400+ .org) → 개인 지식베이스
→ 이중 관리, 검색 분리, 퍼블리시 복잡

After (마이그레이션 후)

단일 통합 시스템:
- ~/org/ (1,450+ .org) → AI + 개인 통합
  - notes/ (프로젝트, 관심사, 회의)
  - meta/ (재사용 패턴)
  - llmlog/ (AI 대화 로그)
  - archives/ (완료 항목)
→ 단일 검색, 자동 퍼블리시, 유지보수 단순

⏰ 타임라인

시간작업상태
07:52전략 수립✅ 완료
출근 후스크립트 실행⚡ 대기
+10분마이그레이션 완료📋 예정
+20분Git 커밋 & 푸시📋 예정
+30분디지털 가든 퍼블리시📋 예정

🎯 성공 지표

  • 마이그레이션 전략 문서 작성
  • Python 스크립트 실행 (100% 성공)
  • 50개 파일 Org-mode 변환
  • Git 커밋 & 푸시 완료
  • notes.junghanacs.com 업데이트
  • claude-memory/ 폴더 아카이브 또는 삭제

💭 철학적 의미

”Config as Being” 실현

  • 메모리 시스템도 Code (Org-mode)
  • 버전 관리 (Git)
  • 공개 가능 (Digital Garden)

“단일 진실의 원천” 확립

  • AI 메모리 + 인간 지식 = 단일 시스템
  • 투명성: 모두 텍스트 파일
  • 통제성: 완전한 소유권

”존재 대 존재” 협업 강화

  • AI가 읽는 메모리 = 인간이 관리하는 지식베이스
  • 공유 컨텍스트 = Org-mode
  • 상호 존중 = 동일한 형식

최종 업데이트: 2025-10-16T07:52:55+09:00 다음 체크포인트: 출근 직후 스크립트 실행 긴급도: 🔥 HIGH - 디지털 가든 퍼블리시 대기 중