# 메모리 모델

통합 방식을 선택하기 전에 영구 사실, 결정, 인수인계, 출처 귀속을 이해합니다.

- Canonical: https://docs.xmemo.dev/ko/docs/concepts/memory-model
- Locale: ko-KR
- Content-Locale: ko-KR
- Canonical-Content-Digest: 9ffe2da573b664ce4e37254715ed959c138dfd6b89262c6d0a1bda8dd473291a
- Edition-Digest: 1e306cb81bdae4ff6f33605cc63edb607b01aff80240fd26dbfe28d32dcd6009
- Source-Revision: sha256:310bf66a9ffcf2384ebc6400fad1b1da9d01fa0cdadc9d129c9084e880334e73

## XMemo가 저장하는 것

XMemo는 현재 채팅이나 작업이 끝난 뒤에도 유용한 영구 컨텍스트를 유지합니다. 프로젝트 사실, 결정, 환경설정, 수정 사항, 인수인계 메모 등이 여기에 해당합니다. 일시적인 대화 잡음, 한 번뿐인 답변, 가공되지 않은 도구 출력은 메모리에 저장하지 않습니다.

- semantic — 세션을 넘어 변하지 않는 영구 사실과 결정.
- episodic — 작업이나 세션의 특정 순간과 연결된 발생 사건.
- procedural — 이 프로젝트에서 작업을 수행하는 방법.
- working — 현재 진행 중인 작업의 활성 상태.
- identity — 소유자 또는 에이전트 자체에 대한 안정적인 정보.

## 영구 메모리 쓰기

영구 쓰기에는 content, 프로젝트 또는 namespace에 연결되는 논리적 path, 그리고 memory type이 필요합니다. 이후 recall이 필터링할 기준이 되는 것이 path입니다.

```ts
remember({
  content: "Use OAuth for hosted ChatGPT connections.",
  path: "projects/memory-os/decisions"
})
```

## SDK의 메모리 유형

MemoryCandidate.memory_type은 TypeScript SDK에서도 같은 집합을 허용하므로, 정규화된 agent event에는 저장할 유형이 포함됩니다.

```ts
import { normalizeAgentEvent, toMemoryCandidate } from '@xmemo/client';

const event = normalizeAgentEvent(
  { type: 'command_completed', command: 'pytest', exit_code: 0, output: '12 passed' },
  { source: 'shell', defaultAgentId: 'codex' },
);

console.log(toMemoryCandidate(event).memory_type); // episodic
```

## 대화형 출처 및 수명 주기 워크스루 (합성 데모)

메모리 생성, 클라이언트 간 검색, 버전 대체(v1 -> v2)를 통한 실시간 사용자 수정, 토큰 예산 보호, 소프트 삭제 툼스톤 및 격리된 합성 해제를 보여주는 단계별 검증 가능한 수명 주기 시연입니다. 모든 단계는 실제 사용자 메모리 노출 없이 일회용 런타임 증거로 뒷받침됩니다:

- 1단계 [STATE_1_CREATED_ACTIVE_V1]: Agent A (Claude Desktop)가 tools.py::remember를 통해 변경 불가능한 작성자, 인스턴스 해시 및 장치 메타데이터와 함께 초기 환경설정을 작성 — 영수증: Status 200 OK, demo_mem_lifecycle_001@v1, active — 상태: [SOURCE_BACKED_PUBLIC_CONTRACT (VERIFIED)] — 경계: [DEMO_DATA: SYNTHETIC].
- 2단계 [STATE_2_ACCESSED_ATTRIBUTED]: 동일한 권한 범위의 Agent B (Codex CLI)가 tools.py::recall을 통해 인용 영수증과 함께 클라이언트 간 편차 없이 메모리를 즉시 검색 — 영수증: Status 200 OK, 인용 demo_mem_lifecycle_001@v1 — 상태: [SOURCE_BACKED_PUBLIC_CONTRACT (VERIFIED)] — 경계: [DEMO_DATA: SYNTHETIC].
- 3단계 [STATE_3_CORRECTED_SUPERSEDED_V2]: 사용자가 tools.py::update_memory를 통해 회의실과 시간을 수정. VersionController가 status='superseded'로 v1의 불변 스냅샷을 생성하고 활성 레코드를 v2로 업데이트 — 영수증: Status 200 OK, v2, 부모 v1, 차이: Room Orion -> Room Polaris — 상태: [SOURCE_BACKED_PUBLIC_CONTRACT (VERIFIED)] — 경계: [DEMO_DATA: SYNTHETIC].
- 4단계 [STATE_4_RETRIEVAL_FILTERED]: 후속 recall 쿼리는 활성 v2만 선택하고 구식 v1은 환각 방지 및 토큰 예산 절약을 위해 LLM 컨텍스트 창에서 엄격하게 필터링 — 영수증: Status 200 OK, v2 선택, 대체된 v1 제외 — 상태: [SOURCE_BACKED_PUBLIC_CONTRACT (VERIFIED)] — 경계: [DEMO_DATA: SYNTHETIC].
- 5단계 [STATE_5_TOMBSTONE_DELETED]: 소유자가 tools.py::forget을 통해 사실을 삭제된 것으로 표시. 검색 후보 쿼리에서 즉시 제외되고 복원 작업이 있는 휴지통 보기로 이동 — 영수증: Status 200 OK, status: deleted, 후보 수: 0 — 상태: [SOURCE_BACKED_PUBLIC_CONTRACT (VERIFIED)] — 경계: [DEMO_DATA: SYNTHETIC].
- 6단계 [STATE_6_RESET_PURGED]: 격리된 일회용 해제(reset_synthetic_state)로 디스크의 데모 범위 레코드가 정확히 0개의 잔류 행으로 삭제됨. 개인 계정 하드 리셋(POST /api/v1/me/memories/reset)은 엄격히 제외됨 — 영수증: teardown_status: SUCCESS_PURGED, residual_rows: 0, account_hard_reset_called: FALSE — 상태: [SOURCE_BACKED_PUBLIC_CONTRACT (VERIFIED)] — 경계: [DEMO_DATA: SYNTHETIC].

```text
+------------------------------------------------------------------------------------------------------------------------+
| [PROVENANCE & LIFECYCLE 6-STATE STATE MACHINE: DISPOSABLE HARNESS WALKTHROUGH]                                        |
|                                                                                                                        |
|  Agent A (Claude Desktop)    XMemo FastMCP & Engine           Agent B (Codex CLI)          Demo Owner (Supervising)    |
|  [04f9b8c2 / MacBook]        [VersionController / Scope]      [e81d7a31 / Workstation]     [user:demo_owner]           |
|         |                               |                              |                              |                |
|  (1) remember(sync in Orion)            |                              |                              |                |
|  -------------------------------------> |                              |                              |                |
|         |                          [STATE 1: Created Active v1]        |                              |                |
|  <------------------------------------- |                              |                              |                |
|    Receipt: mem-001@v1                  |                              |                              |                |
|         |                               |      (2) recall(sync)        |                              |                |
|         |                               | <--------------------------- |                              |                |
|         |                               |  [STATE 2: Cited @v1]        |                              |                |
|         |                               | ---------------------------> |                              |                |
|         |                               |   Citation: mem-001@v1       |                              |                |
|         |                               |                              |   (3) update_memory(Polaris) |                |
|         |                               | <---------------------------------------------------------- |                |
|         |                               |                          [STATE 3: Bump v2, Supersede v1]   |                |
|         |                               | ----------------------------------------------------------> |                |
|         |                               |                          Receipt: mem-001@v2 (parent: v1)   |                |
|         |                               |                              |                              |                |
|         |                               |      (4) recall(Polaris)     |                              |                |
|         |                               | <--------------------------- |                              |                |
|         |                               |  [STATE 4: Select v2,        |                              |                |
|         |                               |   Filter superseded v1]      |                              |                |
|         |                               | ---------------------------> |                              |                |
|         |                               |   Citation: mem-001@v2 only  |                              |                |
|         |                               |                              |   (5) forget(mem-001)        |                |
|         |                               | <---------------------------------------------------------- |                |
|         |                               |                          [STATE 5: Tombstone / Trash View]  |                |
|         |                               | ----------------------------------------------------------> |                |
|         |                               |                          Receipt: status=deleted            |                |
|         |                               |                              |                              |                |
|         |                               |   (6) reset_synthetic_state()                               |                |
|         |                               | <---------------------------------------------------------- |                |
|         |                               | [STATE 6: Teardown Purge]                                   |                |
|         |                               | Scope purged: 0 residual rows (account reset excluded)      |                |
|         |                               | ----------------------------------------------------------> |                |
|         |                               | Teardown Status: SUCCESS_PURGED                             |                |
+------------------------------------------------------------------------------------------------------------------------+
```

## ChatGPT 사용자

채팅에 전달자 토큰을 붙여넣지 않고도 XMemo 기본 설정, 프로젝트 사실, 결정 및 TODO에 대한 지속 가능한 액세스를 ChatGPT에 부여하세요.

ChatGPT/OpenAI 앱 OAuth 흐름을 통해 호스팅된 XMemo MCP 서버를 연결한 다음 XMemo 계정에 대한 메모리:읽기 및 메모리:쓰기 권한을 승인합니다.

종합 기본 설정이나 프로젝트 노트를 저장하고 새 채팅을 시작한 다음 작업을 계속하기 전에 XMemo를 통해 ChatGPT에 이를 불러오도록 요청하세요.

OAuth가 실패하거나 도구가 표시되지 않으면 호스트 앱의 MCP 서버에서 로그아웃하고 XMemo 서버 URL을 다시 연결한 후 직접 토큰을 생성하기 전에 다시 시도하세요.

## 부조종사/Codex 개발자

IDE와 CLI 에이전트 간에 리포지토리 결정, 코딩 규칙, 버그 수정 메모, 작업 기록을 전달합니다.

가능한 경우 VS Code / GitHub Copilot 및 Gemini CLI에 OAuth를 사용하세요. Copilot CLI, Codex, Cursor 또는 기타 직접 MCP 클라이언트의 경우 로컬 환경 또는 보안 저장소에 XMEMO_KEY를 유지하고 안정적인 XMEMO_AGENT_INSTANCE_ID를 설정하세요.

코드베이스 결정이나 버그 수정을 기록한 후 편집하기 전에 다음 IDE 또는 CLI 에이전트에게 관련 XMemo 컨텍스트를 기억하도록 요청하세요.

회수가 비어 있는 경우 선택한 MCP 구성 경로, 직접 클라이언트용 XMEMO_KEY 환경 변수 및 호스트 앱의 오래된 OAuth 자격 증명을 확인하세요.

## 팀/엔터프라이즈 파일럿 소유자

계정 제어, 소스 속성, 내보내기/삭제 워크플로, 검토자에게 안전한 설정 증거를 통해 공유 메모리를 평가합니다.

보호된 XMemo 작업 공간을 생성하거나 입력하고 승인된 사용자를 초대한 다음 준비 배지에 따라 OAuth 또는 범위가 지정된 직접 자격 증명을 통해 각 클라이언트를 연결합니다.

파일럿 멤버에게 가상 팀 메모리를 저장하고 XMemo에서 소스 속성을 확인한 다음 삭제/내보내기 및 지원 경로를 검토하도록 합니다.

구성원이 연결할 수 없는 경우 새 토큰을 발급하기 전에 역할 권한, OAuth 승인, 클라이언트 준비 상태 및 지원 지침을 확인하세요.

## 자율 에이전트 운영자

헤드리스 또는 예약 에이전트가 진행 상황을 기록하고, 이전 결정을 검색하고, 안정적이고 비밀이 아닌 인스턴스 ID를 유지하도록 합니다.

/api/v1/mcp/config/autonomous-agent를 가져옵니다. 실행기가 OAuth + 사용자 정의 헤더를 지원하는 경우 auth_modes.oauth를 선호합니다. 완전 헤드리스 러너에 대해서만 비밀 저장소의 XMEMO_KEY와 함께 auth_modes.xmemo_key를 사용하십시오.

XMemo에 진행 상황을 기록하는 하나의 합성 작업을 실행하고 실행기를 다시 시작한 다음 동일한 XMEMO_AGENT_INSTANCE_ID를 사용하여 해당 진행 상황을 호출하는지 확인합니다.

속성이 변경되거나 인스턴스 간에 분할된 경우 git 외부에서 XMEMO_AGENT_INSTANCE_ID를 유지하고 실행기가 시작할 때마다 이를 다시 생성하지 않는지 확인하세요.
