# task-1478.1 완료 보고서: 메모리 시스템 강화 Phase 2 - SQLite FTS5 인덱싱

## SCQA

**S**: Phase 1(task-1477.1)에서 diary/reflect 패턴이 도입되어 세션별 다이어리가 자동 생성되고 있으며, 아누 메모리 시스템에 27개 메모리 파일이 축적되어 있다.

**C**: 축적된 diary + 메모리 파일을 키워드/의미 기반으로 검색하는 기능이 없어, 과거 패턴이나 피드백을 찾으려면 수동으로 파일을 열어봐야 했다.

**Q**: SQLite FTS5 인덱싱으로 diary + 메모리 파일의 전문 검색을 구현하여 검색 정확도를 3-5배 향상시킬 수 있는가?

**A**: memory_indexer.py(MemoryIndexer 클래스) + memory_search.py(CLI)를 구현하여 27개 문서를 FTS5 인덱싱 완료. 한국어 검색 정상 동작 (FTS5 MATCH + LIKE fallback). pytest 12/12 TC 통과, pyright 0 에러. /diary 실행 시 자동 인덱스 업데이트, /reflect에서 FTS5 검색 보조 활용 연동 완료.

## 구현 내용

### 1. SQLite FTS5 인덱서 (`utils/memory_indexer.py`)
- MemoryIndexer 클래스: DB 생성, FTS5 가상 테이블 + 트리거 자동 동기화
- YAML frontmatter 수동 파싱 (외부 의존성 없음)
- SHA256 해시 기반 증분 인덱싱 (indexed/updated/skipped/error)
- 한국어 검색: FTS5 MATCH 우선 → 결과 없으면 LIKE fallback

### 2. CLI 검색 도구 (`utils/memory_search.py`)
- `query "검색어" [--type TYPE] [--team TEAM] [--limit N]`
- `reindex` — 전체 재인덱싱
- `stats` — 인덱스 통계

### 3. /diary 및 /reflect 연동
- /diary: 5단계에 FTS5 인덱스 자동 업데이트 추가
- /reflect: 2.5단계에 FTS5 검색 보조 활용 추가

### 4. 스펙 문서 업데이트
- memory-enhancement-spec.md Phase 2 섹션 "완료" 상태로 업데이트
- Phase 3 연결 포인트: `search()` 메서드에 `summary_only` 파라미터 추가 가능

## 산출물 파일

- `/home/jay/workspace/utils/memory_indexer.py` (신규 생성)
- `/home/jay/workspace/utils/memory_search.py` (신규 생성)
- `/home/jay/workspace/tests/test_memory_indexer.py` (신규 생성)
- `/home/jay/.claude/commands/diary.md` (수정: 5단계 FTS5 인덱스 추가)
- `/home/jay/.claude/commands/reflect.md` (수정: 2.5단계 FTS5 검색 추가)
- `/home/jay/workspace/memory/specs/memory-enhancement-spec.md` (수정: Phase 2 완료 표기)
- `/home/jay/.claude/memory/memory_index.db` (런타임 생성, git 비추적)

## 테스트 결과

```
tests/test_memory_indexer.py::test_TC01_db_creation PASSED
tests/test_memory_indexer.py::test_TC02_parse_diary_file PASSED
tests/test_memory_indexer.py::test_TC03_parse_memory_file PASSED
tests/test_memory_indexer.py::test_TC04_index_single_file PASSED
tests/test_memory_indexer.py::test_TC05_incremental_indexing PASSED
tests/test_memory_indexer.py::test_TC06_update_on_change PASSED
tests/test_memory_indexer.py::test_TC07_fts5_search_korean PASSED
tests/test_memory_indexer.py::test_TC08_search_with_filter PASSED
tests/test_memory_indexer.py::test_TC09_reindex_all PASSED
tests/test_memory_indexer.py::test_TC10_stats PASSED
tests/test_memory_indexer.py::test_TC11_index_directory PASSED
tests/test_memory_indexer.py::test_TC12_search_empty_db PASSED
12 passed in 0.17s
```

- pyright: 0 errors, 0 warnings
- 실제 인덱싱: 27개 문서 (diary 1, feedback 16, project 2, reference 2, unknown 5, user 1)

## 발견 이슈 및 해결

### 자체 해결 (3건)
1. **Pyright Optional 타입 에러** — `self._conn`을 `sqlite3.Connection`으로 고정 + `_closed` 플래그 패턴 적용
   - 수정: `memory_indexer.py:35-41` (init) + `memory_indexer.py:473-478` (close)
2. **FTS5 한국어 토큰화 한계** — CJK 토크나이저 없이 한국어 형태소 분리 불가
   - 해결: FTS5 MATCH 우선 시도 → 결과 없으면 LIKE '%query%' fallback (memory_indexer.py:415-434)
3. **외부 콘텐츠 테이블 동기화** — FTS5 content= 사용 시 수동 동기화 필요
   - 해결: INSERT/UPDATE/DELETE 트리거 3개로 자동 동기화 (memory_indexer.py:70-88)

### 범위 외 미해결 (0건)
없음.

## Phase 3 연결 포인트

Progressive Disclosure 구현을 위한 인터페이스 설계:
- `search()` 메서드에 `summary_only: bool = False` 파라미터 추가
- `summary_only=True` 시: title + type + tags만 반환 (토큰 절감)
- `summary_only=False` 시: 전체 content + snippet 반환 (상세 조회)
- 이를 통해 "요약만 반환 → 상세 요청 시 전체 반환" 패턴 구현 가능

## 모델 사용 기록

- 팀원: 모리건 / 작업 내용: 테스트 12TC 작성 (TDD RED) / 사용 모델: sonnet
- 팀원: 루 / 작업 내용: memory_indexer.py + memory_search.py 구현 (GREEN) / 사용 모델: sonnet
- 팀장(다그다): Pyright 수정, 연동, 스펙 업데이트, 보고서 / 사용 모델: opus (설계/검토/통합)
