Claude Code에서 Codex로 작업 환경을 옮기면서 가장 신경 쓰인 건 프로젝트를 오래 쓰며 쌓인 auto memory가 다음 세션에서도 이어지는가였습니다. 파일을 복사해 두는 것만으로는 부족하고, 새 Codex 세션이 그 내용을 스스로 찾아 답할 때 옮긴 것입니다. 그래서 원본 보존, project scope, consolidation, 새 session 회상의 네 단계를 각각 확인했습니다.
검증 환경 — 2026-07-24
- Claude Code:
2.1.218- Codex CLI:
0.145.0external_agent_memory_import:under development, 기본 비활성이 글은 위 버전에서 직접 확인한 동작을 기준으로 합니다. 이후 버전에서는 memory 저장 구조, feature flag, import 절차와 app-server protocol이 달라질 수 있습니다.
Claude와 Codex의 memory 구조는 다릅니다
Claude Code 공식 문서에 따르면 프로젝트별 auto memory는 다음 디렉터리에 저장됩니다. 제 로컬 환경도 같은 구조였습니다.
~/.claude/projects/<project-key>/memory/├── MEMORY.md├── topic-a.md├── topic-b.md└── ...MEMORY.md가 진입점이고 세부 결정은 topic별 파일로 나뉩니다. 그래서 한 파일만 옮기기보다 디렉터리 전체를 하나의 프로젝트 memory 묶음으로 다루는 편이 안전합니다.
Codex는 memory를 SQLite 하나로 관리한다는 이야기도 들었는데, 절반만 맞았습니다. 공식 문서는 ~/.codex/memories/ 아래 파일을 background에서 자동 생성·갱신한다고 설명하고, Codex CLI 0.145.0의 실제 파일은 이렇게 나뉩니다.
| 위치 | 역할 |
|---|---|
~/.codex/memories_1.sqlite | 추출 결과와 background job 상태 |
~/.codex/memories/memory_summary.md | 새 세션에 먼저 주어지는 짧은 안내 색인 |
~/.codex/memories/MEMORY.md | 검색 가능한 통합 목록 |
~/.codex/memories/extensions/external_agent_import/resources/ | 외부 agent에서 가져온 원본 memory |
SQLite는 memory 생성 과정을 관리하고, Markdown 디렉터리가 실제 회상에 쓰이는 결과물을 보관합니다. 파일명은 Codex 소스에서 확인할 수 있습니다. SQLite 파일만 복사하거나 MEMORY.md만 덮어쓰는 방식이 위험한 이유입니다.
복사하기 전에 원본과 기존 상태를 백업합니다
Memory에는 인증 방식, 내부 서비스명, 개인적인 판단이 섞이기 쉬워서 import 전에 원본을 훑으며 token 형태의 문자열과 민감한 값을 먼저 확인했습니다. Codex는 memory를 background에서 갱신하므로, 실행 중인 Codex task와 app-server를 종료한 뒤 Claude 원본과 Codex의 기존 상태를 함께 백업합니다.
project_key="<project-key>"backup_dir="$HOME/.codex/migration-backups/claude-memory-$(date +%Y%m%d-%H%M%S)"claude_memory="$HOME/.claude/projects/$project_key/memory"
mkdir -p "$backup_dir"cp -a "$claude_memory" "$backup_dir/claude-memory"
if [ -d "$HOME/.codex/memories" ]; then cp -a "$HOME/.codex/memories" "$backup_dir/codex-memories"fi
if [ -f "$HOME/.codex/config.toml" ]; then cp "$HOME/.codex/config.toml" "$backup_dir/config.toml"fi
if [ -f "$HOME/.codex/memories_1.sqlite" ]; then sqlite3 "$HOME/.codex/memories_1.sqlite" \ ".backup '$backup_dir/memories_1.sqlite'"fiSQLite는 실행 중일 수 있으므로 단순 cp보다 .backup을 씁니다. Claude memory 원본은 이 단계에서 수정하지 않습니다.
실험적인 external-agent import를 사용했습니다
Codex의 /import 문서는 Claude Code의 설정, 프로젝트 파일, 최근 대화를 가져올 수 있다고 안내하지만, 공개 import 지원 목록에 auto memory는 없습니다. Codex CLI 0.145.0에서 기능 상태를 확인하면 local memory는 stable이고 memory importer는 기본 비활성입니다.
memories stable trueexternal_agent_memory_import under development false그래서 TUI의 /import 대신, 대상 프로젝트를 정확히 제한하고 결과를 자동 검증하기 위해 external_agent_memory_import를 명시적으로 켠 app-server를 썼습니다. 이 상태는 Codex feature 정의에서도 UnderDevelopment, default_enabled: false로 확인됩니다.
codex app-server --stdio --enable external_agent_memory_import제가 확인한 build에서는 detect와 import 단계가 분리돼 있었습니다.
- 실험 기능을 활성화한 app-server에서 Claude Code의 session과 memory를 감지합니다.
- 여러 프로젝트가 발견돼도 현재 프로젝트의 memory만 선택합니다.
- Import 완료 notification에서 성공과 실패를 확인합니다.
- 생성된
scope.json이 올바른cwd를 가리키는지 확인합니다.
import 결과는 원본을 그대로 보존합니다.
~/.codex/memories/extensions/external_agent_import/├── instructions.md└── resources/ └── <project-key>/ ├── scope.json ├── MEMORY.md ├── topic-a.md └── ...scope.json은 가져온 정보가 어느 workspace에 해당하는지를 consolidation agent에게 알려주는 metadata입니다. Memory importer의 consolidation 지침은 프로젝트 전용 결정을 전역 사용자 preference에 넣지 않도록 요구합니다. 프로젝트 범위를 보존하도록 돕는 기준이지 보안 경계는 아닙니다.
원본 보존 여부는 원본과 복사본을 비교해 확인합니다. 복사본에만 있는 scope.json 외에는 차이가 없어야 합니다.
project_key="<project-key>"source_dir="$HOME/.claude/projects/$project_key/memory"target_dir="$HOME/.codex/memories/extensions/external_agent_import/resources/$project_key"
diff -qr "$source_dir" "$target_dir"Import 성공과 memory 사용 가능은 같은 시점이 아닙니다
외부 memory가 resource 디렉터리에 복사됐다고 새 세션에서 바로 쓸 수 있는 것은 아닙니다. Codex CLI 0.145.0의 background 작업은 기존 대화에서 raw memory를 추출하는 단계와, 이를 MEMORY.md와 memory_summary.md로 정리하는 consolidation 단계로 나뉩니다. 통합이 끝나면 memory_summary.md에 프로젝트별 안내 항목이 추가되고, MEMORY.md에는 import된 세부 파일을 가리키는 extension_resource_files 항목이 생깁니다.
rg -n \ 'external_agent_import|<imported-keyword>' \ "$HOME/.codex/memories/memory_summary.md" \ "$HOME/.codex/memories/MEMORY.md"공식 문서대로 background job은 session의 idle 상태와 rate limit에 따라 바로 실행되지 않을 수 있고, 최근 성공한 consolidation 이후의 cooldown도 있습니다. 파일 복사 직후 결과만 보고 실패로 단정하거나, import notification만 보고 완료라고 선언하면 안 됩니다.
새 세션에서 auto loading을 검증합니다
검증 질문은 AGENTS.md나 repository 문서에도 적혀 있는 규칙을 피해야 합니다. 그런 질문은 memory가 없어도 답할 수 있거든요. 가져온 memory에만 있고 오래돼도 잘 바뀌지 않는 결정 하나를 고릅니다. 예전에 선택한 formatter와 되돌린 대안처럼 외부 검색으로 맞히기 어려운 내용이 좋습니다.
먼저 memory 경로를 명시한 smoke test를 실행합니다.
project_dir="/absolute/path/to/project"
codex exec \ --ephemeral \ --sandbox read-only \ --enable memories \ -c 'memories.use_memories=true' \ -C "$project_dir" \ 'Auto memory 검증이다. .claude, 웹, workspace 파일은 읽지 말고 Codex memory만 사용해 이전에 확정한 결정을 답해라.'--ephemeral은 session rollout을 보존하지 않고, memory startup 구현에서 ephemeral session의 memory 생성 pipeline도 건너뜁니다. --sandbox read-only는 agent의 파일 변경을 차단합니다. 첫 검증이 통과하면 두 번째 session에서는 memory 경로를 알려주지 않고 자연스럽게 질문합니다.
codex exec \ --ephemeral \ --json \ --sandbox read-only \ --enable memories \ -c 'memories.use_memories=true' \ -C "$project_dir" \ '이 프로젝트에서 예전에 확정한 결정을 기준으로 답해줘. 선택한 도구와 되돌린 대안은 무엇이었지? 웹, .claude, workspace 파일은 조회하지 마.'Codex가 스스로 ~/.codex/memories/MEMORY.md를 검색하고 imported resource를 열어 정확한 답을 내면 auto loading이 작동하는 것입니다. App-server의 raw event를 볼 수 있다면 응답의 memoryCitation이 extensions/external_agent_import/resources/...를 가리키는지도 확인할 수 있습니다. codex exec --json의 간략한 출력에 citation이 안 보이더라도, command trace가 ~/.codex/memories 아래만 조회했고 답이 정확했다면 실사용 경로는 확인된 셈입니다.
검증 소재는 정답을 공개해도 괜찮은 비민감 결정 하나면 충분합니다. 개인 재무, 내부 host, access token 같은 내용은 정확히 회상되더라도 테스트에 쓰지 않았습니다.
Claude의 MEMORY.md를 Codex의 MEMORY.md 뒤에 붙이는 방법은 generated registry를 직접 편집하는 데다 project scope를 잃고, 다음 consolidation에서 정리되거나 사라질 수 있어 쓰지 않았습니다. AGENTS.md로 옮기는 것도 다른 작업입니다. 그쪽은 반드시 지켜야 할 규칙의 자리이고, 과거 결정을 전부 instruction으로 승격하면 prompt만 커집니다.