It's a mixture of RAG and okf storage system. It has made to MCP to attach it with any type of LLM.

Hippocampus(해마) — Personal RAG 지식저장소

이름: 2026-09-13 okf-mcp에서 hippocampus로 개명했다 — MCP 서버 키 hippocampus, 도구 hippo_*, 환경변수 HIPPO_*, 컨테이너 hippocampus·hippo-*.이전 문서의 "OKF"는 이 프로젝트의 옛 이름이다(Google Cloud의 Open Knowledge Format과는 별개). 이미 저장된 데이터 형식 — 볼트 frontmatter okf_* 키, 문서 ID okf:vault:, DB 파일 okf.db — 은 그대로 둔다.

개인 지식의 축적·편찬과 근거 검색을 지원하는 개인 RAG 시스템입니다. 지속적 LLM 편찬은 설계 목표이며, 현행 운영 상태는 현행 운영 안내에서 확인합니다.

핵심 아이디어는 "질문할 때마다 원본 조각을 다시 찾는 단순 RAG"가 아니라, LLM이 지속적으로 편찬하는 persistent Markdown wiki(Karpathy LLM Wiki 패턴)를 중심에 두는 것이다. 원본은 불변의 사실 근거로 보존되고, 위키는 요약·개념·문답이 누적되는 복리(compounding) 산출물이며, Obsidian은 사람이 탐색하는 IDE, LLM은 편찬자다.

📐 현행 운영: 현행 운영 안내 · 2026-10-03 업그레이드 기록과 검증. 설계 이력: v3 — 자립 스택 재설계 · v4 — 근거·검증·갱신 설계와 실행 계획 · v5 · v6 · ADR 0001~0007.공유 에이전트 기억·능력 연결 설계(2026-09-10): 작업 요약 + 대화 전체의 누적 요약. 저장·변경 조회 구현, 자동 클라이언트 연결은 다음 단계.

이 리포에 담긴 것: 시스템 코드(MCP 게이트웨이 app/, 편찬 파이프라인 pipeline/, 평가 하네스 eval/, 배포 compose.yaml)와 이 아키텍처 문서.담기지 않은 것: 지식 데이터(Obsidian 볼트), 파생 인덱스·백업(backups/), 시크릿(.env), 모델 가중치(models/) — 전부 로컬 전용이며 .gitignore로 차단된다.

1. 한눈에 보기

2026-10-03 운영 스냅샷에서 MCP·두 임베딩 서비스와 호스트 Hermes는 실행 중이며, 결정론 cron은 dry-run으로 등록되어 있습니다. LLM 편찬·승인·리서치 잡은 미등록/주석 상태입니다. 코드·운영 상태·검증 범위를 분리해 기록한 현행 운영 안내를 기준으로 봅니다.

2026-09-20부터 편찬 잡은 호스트 Hermes의 wiki_manager 프로필에서 실행합니다. 이는 다중 프로필 gateway systemd 유닛의 별도 cron 프로필이지, 독립 wiki_manager 서비스가 아닙니다.setup/provision.sh는 ~/hermes/bin/hermes-cli를 사용하며, 상태·venv는 ~/hermes/hermes-home/pipeline-data에 둡니다.환경 설정은 ~/hermes/hermes-home/service.env를 사용합니다. MCP·임베딩 컨테이너와 공유 볼트 위치는 유지합니다.현재 운영 배치는 ../claude-workspace/aios/SYSTEM-DESIGN.md의 "현재 실행 배치"를 따릅니다.

2026-10-03부터 이 저장소도 AGENTS.md는 안내, CLAUDE.md는 @AGENTS.md 참조만 둡니다.핵심 지침은 instructions/local/hippocampus.md, 이전 상세 원문은instructions/lane/hippocampus-repository.md가 정본입니다. instructions/manifest.json에서Hermes를 포함한 클라이언트의 시작 지침을 조립하고 setup/sync-agent-policy.py로setup/bootstrap.json을 생성합니다. 시작 훅은 핵심과 프로젝트 기록을 확인하며,상세 지침·스킬·기억은 해마 MCP로 필요한 것만 읽습니다.

선택적 RAG — 관련성 재정렬만 (2026-09-23 현행 계약)

hippo_route는 ACL 적용 기본 검색의 짧은 후보를 Jev로 관련성만 재정렬합니다(needs_context·후보별 fit).난이도·위험도·필요 기능·reasoning effort는 묻지 않으며 execution_policy는 항상 null입니다.공급자가 요청하지 않은 작업 라벨을 돌려줘도 무시하고, 모델·effort·권한을 바꾸지 않습니다.Jev 실패(401/403/429/529·타임아웃·응답 오류·워커 스레드 시작 실패)는 status=degraded와 원인을 표시하고ACL 적용 기본 검색 순서를 반환합니다. 해마 자체 인증/ACL 오류는 이 경로로 우회하지 않습니다.정본: ../claude-workspace/aios/SYSTEM-DESIGN.md "공통 정책·선택적 RAG 계약". Hermes의 과거plugins.hippocampus.adaptive_effort 플래그는 Jev를 강제하지 않습니다.

선택 엔진은 HIPPO_SELECTOR(jev 기본, laya)로 고릅니다. 2026-10-01 실제 질의 40개로 비교한 결과로컬 Laya(휴면 프로파일 select의 hippo-select)는 정답 적중이 Jev의 절반 수준이라 쓰지 않고 Jev를 유지합니다(측정 결과). 훅 전용 hippo_suggest는 스킬 레인만 검색해 스킬·MCP 후보 3개를600바이트 안으로 돌려주며, 예산(HIPPO_SUGGEST_BUDGET_MS, 기본 1500ms)을 넘기거나 엔진이 실패하면 빈 목록을 줍니다.엔진을 따로 둘 때는 HIPPO_SUGGEST_SELECTOR를 씁니다.

역사(폐기): 2026-09-20의 요청별 effort 판정 설계와 검증 기록은../audits/task-policy-2026-09-20/README.md에 있습니다. 현재 동작 설명이 아닙니다.

flowchart LR
    subgraph IN["지식 입력 (3+1 경로)"]
        A1["에이전트 세션 캡처<br/>hippo_capture_session"]
        A2["사용자 투입<br/>00-inbox / 00.init"]
        A3["리서치 토픽 신청<br/>05-todo 체크박스"]
        A4["웹 보강<br/>딥리서치 (무료/로컬)"]
    end

    subgraph VAULT["Obsidian 볼트 (정본, git 저장소, 로컬 전용)"]
        V1["10-sources<br/>원본 사본 (불변)"]
        V2["30-reviews/staging<br/>승인 대기 카드"]
        V3["20-wiki/&lt;섹터&gt;/&lt;유형&gt;<br/>정본 위키 (분야별)"]
        V4["HOME.md · index.md · 섹터 허브<br/>대시보드·카탈로그·목차"]
    end

    subgraph PIPE["편찬 파이프라인 (hermes wiki_manager 크론, setup/jobs.yaml)"]
        P1["인박스 스캔 (10분)"]
        P2["재니터 01:30"]
        P3["편찬 그래프 01:45<br/>정제→심판→인용검증 (LLM)"]
        P4["사람 승인 → 승격<br/>(결정론 게이트 5종) 09/21시"]
        P5["index/HOME/허브 재생성 03:25"]
        P6["큐레이터 (주기 점검)<br/>섹터·중복·노후 제안"]
    end

    subgraph MCP["해마 MCP 게이트웨이 (이 리포, read-only 사서)"]
        M1["SQLite 파생 인덱스<br/>FTS5 + trigram + bge-m3 벡터"]
        M2["하이브리드 검색 (RRF)<br/>+ 거버넌스·신선도 부스트"]
        M3["evidence bundle<br/>정답 캐시 · 감사 로그"]
        M4["gap 레이더<br/>지식 공백 추적"]
    end

    subgraph OUT["소비자"]
        C1["Claude Code / Desktop"]
        C2["hermes · opencode 에이전트"]
        C3["사람 (Obsidian, WebDAV 동기화)"]
    end

    A1 & A2 & A3 --> P1 --> V1 & V2
    A4 --> V1
    V2 --> P3 --> P4 --> V3
    P2 -.정리.-> V2
    P5 -.재생성.-> V4
    V3 -.점검.-> P6 -. "이동 제안 → 사람 승인" .-> V3
    VAULT -- "read-only 마운트" --> M1 --> M2 & M3 & M4
    M2 & M3 --> C1 & C2
    M2 & M3 -.읽기 도구.-> P6
    V4 --> C3
    M4 -. "공백 → 새 토픽" .-> A3

닫힌 루프: 축적 → 정제 → 정본화 → 검색/즉답 → 공백 발견 → 재축적. 사람은 승인 지점에만개입한다 — 정본 승격과 섹터 이동은 볼트의 체크박스 하나로 결정되고, 그 밖에는 Obsidian에서읽고 토픽을 신청한다. 에이전트가 쓰기 도구를 가진 적이 없다는 것이 이 그림의 핵심이다:LLM은 초안·판정·제안까지만 만들고, 볼트를 바꾸는 것은 승인 뒤의 결정론 코드다.

2. 설계 원칙

원칙 구현
도서관·사서·이용자 분리 볼트(도서관)는 정본, MCP(사서)는 read-only 검색·번들링, 에이전트(이용자)는 push된 컨텍스트만 소비 — 토큰 절약 + prompt injection 표면 축소
staging-first 편찬 AI 산출물은 반드시 30-reviews/staging/을 거치고, 정본 진입은 결정론 게이트 통과분만
파생층 재생성 가능 인덱스·그래프·Graphify 층은 언제든 볼트에서 재생성. 예외는 Error Book/감사 로그뿐
데이터는 지시가 아니다 볼트에서 검색된 텍스트 안의 지시문은 실행하지 않는다(서버 instructions에 명시)
모든 주장에 앵커 검색 결과·번들은 path#heading 단위로 인용 — 답변 검증 가능성 확보
롤백 보증 파이프라인의 볼트 변경은 1실행 = git 커밋 1개 — git revert로 원복

3. 지식 볼트 (정본 저장소)

Obsidian 볼트는 로컬 git 저장소다(이 리포에는 포함되지 않음). WebDAV(wsgidav)로 사용자 기기의 Obsidian과 동기화된다.

LLM-Wiki/
├── HOME.md            ← 야간 자동 생성 대시보드 (정본 수·대기 큐·최근 승격·리뷰 우선순위)
├── index.md           ← 정본 카탈로그 (20-wiki 실물 기준 야간 재생성)
├── log.md             ← append-only 연대기 (## [날짜] action | subject)
├── AGENTS.md·SCHEMA.md ← 편찬자 규율·스키마 계약
├── 00-inbox/          ← 지식 투입구 (세션 캡처·사용자 파일). 처리 후 .processed/로 이동
├── 05-todo/           ← 개인 실행 목록 + research-topics.md (리서치 토픽 신청)
├── 10-sources/        ← 원본 사본 — 불변의 사실 근거 (raw-source)
├── 15-graph-imports/  ← Graphify 파생 참고층 (재생성 가능)
├── 20-wiki/           ← 정본. 섹터 폴더 아래 주제별 하위 폴더는 허용, 유형별 폴더는 강제하지 않음
│   └── <섹터>/...     ← 유형은 frontmatter `type`, 분야는 실제 경로가 기준
├── 30-reviews/        ← staging/ (승인 대기 카드) · approvals/ · gap-queue.md
├── 40-skills/         ← 공유 skill library 읽기 전용 투영
├── 45-instructions/   ← 생성된 로컬 지침 투영
├── 47-memory/         ← agent-stack 프로젝트 기억 투영
├── 50-ops/            ← 공유 작업 기억(worklog·handoff)
└── 90-system/         ← 승격 원장·게이트 판정·재니터 원장·리포트

유형 폴더가 없는 flat 레이아웃은 분야 아래 모든 하위 폴더를 금지한다는 뜻이 아닙니다. WebDAV 사람층은 정본·원천·todo·ops·inbox만 보이며, review/system/graph import는 기계층에 둡니다. 세부 노출 경계는 현행 운영 안내를 따릅니다.

섹터(분야) — lane이 '수명주기'라면 섹터는 '분야'다. 정본의 섹터는 경로가 정본이고(sector_of()), frontmatter의 sector:는 사본이다. 사람이 옵시디언에서 폴더를 옮기면그게 곧 진실이 되고, FM과 어긋나면 hippo_validate가 알린다. 등록부는 폴더 자체이며 별도목록 파일은 없다. 새 섹터는 정제기가 제안하고 승격 승인과 함께 폴더가 생긴다(ADR 0005).

Frontmatter 계약 (모든 문서 공통):

type:   concept | entity | comparison | query | map | source-summary | graph-import
status: draft | canonical | needs-review | archived | reference | raw-source
trust:  source | human_edit | llm_summary | llm_context | web_staging
# + title/created/updated/tags/sources/confidence/contested

status와 trust는 검색 랭킹·검색 범위·편찬 규칙이 모두 참조하는 거버넌스 축이다. human_edit 페이지는 AI가 직접 고치지 않고 staging 제안만 만든다. alpha/트레이딩 시그널은 저장 금지.

4. MCP 게이트웨이 (사서) — 이 리포의 코드

FastMCP 기반 Streamable HTTP 서버. 볼트를 read-only로 마운트해 SQLite 파생 인덱스를 만들고, 20개 도구를 제공한다. 독립 compose 스택으로 편찬 파이프라인과 완전히 분리되어 있다.

4.1 하이브리드 검색 파이프라인

질의
 ├─ lexical: FTS5 unicode61 BM25 + trigram(오타·부분일치) + 구문/AND 부스트 + 2자 한국어 폴백
 ├─ semantic: bge-m3 1024d 코사인 (후보 풀 HIPPO_SEM_CANDIDATES=30, 단독 매칭 하한 SIM_SOLO=0.55, v24 재보정)
 ▼
정규 RRF 병합(w/(k+rank), 가중치는 RankingParams로 외부화) → 거버넌스 부스트(canonical·human_edit·source ↑, archived 제외)
        → 신선도 보정(updated 완만 감쇠)
        → [옵션·기본 off] cross-encoder 리랭크 (사이드카, 실패 시 무손실 폴백)
 ▼
질의어 커버리지가 가장 큰 섹션(동률이면 semantic heading) + anchor(path#heading)
        + 그 섹션 안의 snippet + match 근거(fts/semantic/title)
  • 인덱스는 5분 주기 증분 재스캔(콘텐츠 해시 기반), 임베딩은 content-addressed 증분(변경 섹션만 재임베딩, 삭제분 GC). 재임베딩 트리거인 embed_hash는 실제로 프로바이더에 보내는 문자열의 해시라 입력이 같으면 재계산이 없고 다르면 반드시 갱신된다(v24).
  • 스캔은 문서 단위 쓰기 트랜잭션, 검색은 스레드별 read-only 커넥션(WAL) — 전체 스캔 중에도 검색이 막히지 않는다.
  • 임베딩 사이드카(hippo-embed, llama.cpp /v1/embeddings)가 죽어도 FTS-only로 무손실 폴백 — 큐는 유지되어 복구 시 재개.
  • 모델 선정 근거: nomic-embed-v1.5는 한국어 판별력 없음(관련≈무관≈0.7), bge-m3는 관련 ~0.5 vs 무관 ~0.3 (2026-07-05 실측).
  • 레인·경로를 지정한 검색(lanes·path_prefix)은 FTS·제목·의미 검색 후보를 처음부터 그 범위에서 뽑는다(2026-10-01). 전에는 전체에서 뽑고 걸러 스킬 레인 질의의 의미 검색 결과가 0개가 되곤 했다. 지정하지 않은 기본 검색은 그대로다.
  • 스킬 후보(hippo_route·hippo_suggest, 각 16개)는 스킬 레인에서 25개를 본 뒤 하위 문서(references/ 등)와 스킬 카드(40-skills/cards/)를 원래 SKILL.md로 모은다. 목록·조사 문서는 후보가 아니다. 카드는 스킬마다 한국어 한 줄을 담은 짧은 문서로 claude-workspace/skills/make_cards.py가 만든다. hippo_suggest는 검색어 임베딩을 0.7초만 기다리고 넘기면 문자열 검색으로 진행한다. 측정: docs/skill-search-2026-10.md.
  • 색인기가 읽지 못한 파일(권한 등)은 개수를 hippo_status의 index.unreadable_files에, 경로 예시를 감사 기록 index_unreadable에 남긴다.

4.2 MCP 도구

도구 역할
hippo_search 하이브리드 검색. mode: hybrid|lexical|semantic, lane/type/trust 필터
hippo_suggest 훅 전용 스킬·MCP 후보 3개(이름·경로·한 줄 설명, 600바이트). 실패·예산 초과 시 빈 목록
hippo_read 문서 + frontmatter + outline + outlinks/backlinks. section=으로 정밀 인용
hippo_traverse 위키링크 그래프 BFS. target= 지정 시 A→B 최단 경로(≤6 hop)
hippo_map 코퍼스 지형: lane/status 분포, 허브, 연결 컴포넌트, 진입점, 최근 갱신
hippo_evidence_bundle ① 정답 캐시: 승인된 20-wiki/queries와 유사 질의면 앵커 단위 즉답(answer_mode: cached, 충분성 동봉, 인덱스가 낡았으면 자동 무효화) ② 근거 번들: 발췌 예산(6000자)+토큰 추정+충분성 판정, 근거가 약하면 결정론 재작성으로 1회 재검색(Corrective)
hippo_probe WiCER-lite: 과거 gap·피드백을 현재 인덱스에 재생 → compile_next 열린 공백 + compile_candidates staging 우선순위
hippo_validate 볼트 린트 + stale canonical + 최근 gap 수
hippo_status 분포·인덱스·임베딩 coverage·거버넌스 정책·열린 피드백
hippo_capture_session [write: 00-inbox 한정] kind=session 세션 요약 / kind=qa 재사용 문답 — qa는 사람 승인으로 정답 캐시가 됨
hippo_feedback Error Book 기록(지식 즉시 수정 없음 — 승인 기반 병합)
hippo_audit evidence bundle 재조회·최근 이벤트(감사 추적)
hippo_reindex 증분/전체 재인덱스 + 임베딩 재개
hippo_worklog [write: 50-ops 한정] 프로젝트 작업 로그 append(결정·변경·검증 결과)
hippo_handoff [write: 50-ops 한정] 세션 인수인계 — 직전 핸드오프를 자동 supersede
hippo_resume 이어받기 번들: 최근 공유 요약 + 핸드오프 + 작업 로그 + 참조 정본 브리프 + 열린 공백
hippo_checkpoint [write: 공유 기억 DB] 작업 요약(work)·누적 대화 요약(conversation), 이벤트 ID로 중복 저장 방지
hippo_sync 프로젝트의 모든 에이전트가 남긴 요약을 마지막 읽은 cursor 이후부터 순서대로 조회

4.3 지식 공백(gap) 레이더

0건 검색(zero_hit)과 근거 빈약 번들(bundle_weak)은 자동으로 gap에 기록된다. hippo_probe가 주기적으로 "이후 편찬으로 채워졌는가"를 재생 점검하고, 안 채워진 것은 compile_next로 남긴다. 같은 질의를 실제 선택 범위 30-reviews/staging/*.md에서 찾고 충분성 문턱을 넘은 compile_candidates는 야간 select가 oldest-first보다 먼저 뽑는다(사서 장애·후보 0건이면 기존 순서로 폴백) — 검색 실패가 곧 다음 축적 대상이 되는 자기교정 루프.

4.4 보안

  • 볼트는 read-only 마운트. 쓰기는 Error Book·공유 요약 원장(자체 DB), 00-inbox 세션 캡처(draft 고정), 50-ops 작업 기억(worklog/handoff)으로 제한한다. 정본(20-wiki)은 승인 뒤 파이프라인만 쓴다(HIPPO_AUTO_APPROVE=1이면 approvals 잡이 대기 제안을 자동 승인 — 결정론 게이트·심판·지문 검사는 유지, 사람 눈만 빠진다). inbox→sources 사본은 원문의 유효한 trust를 보존해 이동만으로 신뢰가 상승하지 않는다.
  • Bearer 토큰 인증, 127.0.0.1 바인드 → tailscale serve로 tailnet 전용 HTTPS 노출.
  • 컨테이너 하드닝: cap_drop: ALL, no-new-privileges, 비루트(uid 10000), 리소스 상한.
  • 시맨틱 단독 매칭 유사도 하한(환각성 매칭 방지), 시크릿 형태 문자열·저장형 인젝션 패턴은 토픽·캡처·작업 기억 단계에서 거부.

5. 편찬 파이프라인 (야간 자동화)

아래 일정은 파이프라인 설계 및 과거 잡 정의를 설명합니다. 현재 운영에서 LLM compile·approvals·research는 비활성이고, 결정론 6개 cron만 HIPPO_DRY_RUN=1로 등록되어 있습니다. 자동 승인은 HIPPO_AUTO_APPROVE=0입니다. 현행 실행 스케줄과 범위는 운영 안내를 확인하십시오.

agent-stack hermes의 wiki_manager 크론이 볼트에 쓰는 유일한 주체다(2026-08-20 컷오버, 2026-09-13 전용hippo-hermes 컨테이너에서 이관 — 이 리포의 app·pipeline·setup을 ro로, pipeline-data를 rw로 마운트한다). 스케줄의정본은 **setup/jobs.yaml**이고 setup/provision.sh가 크론에 등록한다 — 잡은 전부--no-agent 스크립트이고, LLM이 필요한 잡도 프롬프트 주입이 아니라 잡 코드가 직접 부른다(모델 핀은 코드·설정에, 기동 시 preflight로 검증).

5.1 야간 타임라인

시각 잡 역할
10분 주기 (0-5·20-23시) inbox_scan 00-inbox → 10-sources 사본 + staging 카드 생성, 처리분 .processed/ 이동
매시 :20 topic_bridge 05-todo/research-topics.md 체크박스 → 리서치 큐 투입
01:30 janitor 만기·중복 카드 결정론 archived (§5.3) + 인박스 고착 화해
01:45 compile LangGraph 편찬: select → refine(LLM) → gate(LLM 심판) → merge → web_verify → 게이트 5종 → 사람 승인 대기
02:00 preflight 볼트 쓰기·git·게이트웨이·LLM 핀 전제 확인(fail-closed)
03:25 index_home index.md 섹터별 카탈로그 + 섹터 허브 + HOME.md 대시보드
03:40 research 토픽 큐 1건 딥리서치(DeepAgents, 빈 큐면 LLM 미기동) → 10-sources + staging 패킷
08:45 inbox_scan 새벽 정밀화 산출물 당일 재수록
09:00 / 21:00 approvals 볼트 체크박스를 읽어 멈춘 런을 이어가거나 섹터 이동을 적용(제안서 kind로 분기)

수동 실행 전용(스케줄 없음): sector_migrate(레거시 정본 → 섹터 분류 제안, 일회성),curate(큐레이터 점검), agent_smoke(에이전트 경로 점검).curate는 섹터 이전 승인 뒤 시각을 정해 setup/jobs.yaml의 주석을 풀어 등록한다.

5.2 정본 승격 게이트 (결정론 5종)

LLM 판정(gatekeeper)을 그대로 믿지 않고, 승격 시점에 기계로 재검증한다:

  1. ## 승격 메타 존재 (정밀화를 거쳤는가)
  2. 동일 제목 정본 부재 (중복 방지)
  3. 10-sources/ 원본 사본 존재 (근거 실물)
  4. 본문에 살아있는 [[wikilink]] (그래프 연결 — 고아 정본 방지)
  5. 인용 앵커 존재 (path#heading 또는 URL — 출처 없는 정본 방지)

전부 통과해야 정본이 되고, 같은 커밋에서 index/log가 갱신되며, 승격 원장(90-system/promotions/*.jsonl)에 기록된다.

5.3 staging 재니터 (큐 수렴 장치)

유입(~7건/일)이 승격(~0.4건/일)보다 많아 대기 큐는 방치하면 발산한다. 재니터가 결정론 규칙으로 수렴시킨다 — 파일 삭제가 아니라 status: archived 전환이라 링크·검색(옵션) 모두 보존된다:

규칙 대상 기준
R1 agent-os 일일 제안서 최신 3개만 유지, 로테이션
R2 일일 회고 프롬프트 7일 경과
R3 근거 소실 카드 source_refs 전멸 + 14일 경과
R4 일반 카드 30일 경과 + 정밀화 미선정 (원본 사본은 10-sources에 보존)
R5 deep-research 일일 재실행 슬러그별 최신 1개만 유지

부가로 스캐너가 해시 불일치로 영구 스킵하는 00-inbox 고착 파일을 화해한다(소스 사본 보장 후 .processed/ 이동 — 내용 소실 0 보장).

6. 사람의 자리 — Obsidian 연동

  • 보기: 볼트가 WebDAV(:8090)로 기기의 Obsidian과 동기화된다. 진입점은 HOME.md(대시보드) → index.md(카탈로그) → 분야별 20-wiki/<섹터>/<섹터>.md(섹터 허브) → log.md(연대기).
  • 넣기: 아무 마크다운이나 00-inbox/에 떨어뜨리면 10분 스캔이 수록한다.
  • 시키기: 05-todo/research-topics.md에 - [ ] 궁금한 주제를 적으면 매시 브리지가 큐에 넣고, 딥리서치가 조사해 축적한다. 처리되면 체크박스가 [x] … ← queued로 바뀐다.
  • 승인하기: 사람이 결정하는 모든 것이 30-reviews/approvals/의 체크박스 하나다 — 정본 승격도, 섹터 이동도. 켜 두면 다음 틱(09/21시)이 반영하고, 텔레그램은 "지금 볼 차례"일 때만 알린다. 제안 내용을 고치면 지문이 어긋나 자동 거부되므로, 고치고 싶으면 승인하지 말고 원본을 편집한다(단 섹터 이동 제안의 to는 예외 — 고쳐도 된다).
  • 분류 고치기: 옵시디언에서 정본을 다른 섹터 폴더로 직접 옮겨도 된다. 경로가 정본이라 그게 곧 반영이고, frontmatter의 sector:가 남아 어긋나면 다음 hippo_validate가 알려 준다.

7. 배포·운영

docker compose up -d --build          # 기동 (볼트 경로는 compose.yaml의 바인드 마운트 수정)
curl -s http://127.0.0.1:8787/health  # 헬스체크 (인증 불필요)
docker compose --profile rerank up -d # [옵션] 리랭커 사이드카

7.1 클라이언트 연결 키트 (어느 기기·어느 에이전트든 같은 지식)

서버 하나 · 인덱스 하나 · 볼트 하나다. 모든 클라이언트가 같은 URL을 보므로 기기마다지식 데이터를 복제할 필요가 없다. 실행 중인 에이전트의 문맥은 클라이언트가 새 변경을조회해 반영해야 하며, MCP 연결 자체가 실시간 문맥 주입을 수행하지는 않는다.

# Claude Code
claude mcp add --transport http hippocampus https://<tailnet-호스트>:8443/mcp \
  --header "Authorization: Bearer $HIPPO_MCP_TOKEN"
# Codex CLI — ~/.codex/config.toml
[mcp_servers.hippocampus]
url = "https://<tailnet-호스트>:8443/mcp"   # 같은 호스트면 http://127.0.0.1:8787/mcp
bearer_token_env_var = "HIPPO_MCP_TOKEN"      # 토큰 값은 셸 env에 두고 파일에 쓰지 않는다

컨테이너 안의 에이전트는 tailscale을 거치지 않고 http://hippocampus:8787/mcp(agentnet).

공유 기억 흐름 — 시작은 hippo_resume('<프로젝트>'), 작업 실행 전에는hippo_sync(project, since=마지막_읽은_cursor)를 has_more=false까지 조회한다.작업 요약과 누적 대화 요약은 각각 hippo_checkpoint(kind='work'|'conversation')로 기록한다.session_id, event_id는 재전송 시 유지하고, base_cursor에는 마지막으로 읽은 순번을 넣는다.쓰기 응답의 seq로 읽기 cursor를 바꾸지 않는다. 기존 Markdown 로그·핸드오프는hippo_worklog·hippo_handoff, 재사용 문답은 hippo_capture_session(kind='qa')로 유지한다.자동 연결(2026-09-13, M2): Claude Code·Codex는 agent-stack bin/hippo-hook(SessionStart 재개·주입 / SessionEnd work·conversation 기록), hermes는 메모리 프로바이더가 같은 계약을 쓴다 — 공용 클라이언트agent-stack/claude-workspace/aios/hermes-plugins/hippocampus/hippo_rpc.py, 계약·예산은 agent-stack SYSTEM-DESIGN.md §4.3~4.5.

  • 검색 인덱스 재생성: hippo_reindex(full=True). 공유 요약·Error Book·감사 로그는 볼트에서 재생성할 수 없으므로 DB 볼륨을 지우지 않는다. **일일 DB 스냅샷(요일 로테이션 7개, backups/)**에 원장을 함께 보존한다.재생성 불가 테이블은 workspace_checkpoints·feedback·audit·gaps·bundles·meta다. 이 중 JSONL 사본(backups/*.jsonl, 7일 밖까지 남음)은feedback·gaps·audit뿐이고 checkpoint·bundle은 7일 DB 스냅샷에만 있다. 복원은 스냅샷을 /data/okf.db로 되돌리면 되고(2026-09-13 임시 위치복원 훈련: quick_check ok, checkpoint·Error Book·감사가 MCP로 그대로 조회됨), 복원 뒤 클라이언트 cursor는 invalid_cursor로 무효가 돼 0부터 다시 읽는다.같은 순번이 다른 이력에서 다시 생긴 경우까지는 가리지 못한다(세대 ID는 M4).
  • 임베딩 모델 교체: .env의 HIPPO_EMBED_MODEL 변경 → 전량 자동 재임베딩 + 임계값 2종(SIM_BOOST/SIM_SOLO) 재보정 필수(eval 하네스의 calibrate).

8. 평가 하네스 (eval/)

검색 품질을 감으로 조정하지 않기 위한 골든셋 회귀 체계:

  • golden.jsonl — 질의→기대 문서 골든셋(lexical/semantic/hybrid 카테고리).
  • run_eval.py validate — 질문 ID·정답 경로·검색 범위·앵커를 검색 전에 검사. 하나라도 틀리면 exit 3이고 성능 수치를 내지 않는다(측정 불가 ≠ 오답).2026-09-13 현재 골든셋은 라이브·보관 DB 어느 것과도 짝이 맞지 않아 수치가 없다 — eval/README.
  • run_eval.py run — Document Hit@k·MRR을 스로어웨이 DB 복사본에서 측정. 문서 내용·경로·라벨의 dataset_fingerprint가 다르면 비교를 거부하고 코드·모델·랭킹은 별도 run_signature로 기록한다.
  • run_eval.py calibrate — 임베딩 임계값 재보정(모델/입력 스킴 교체 시 필수).
  • sweep_ranking.py — 랭킹 파라미터(RRF 상수·플랜 가중치·거버넌스 배수)를 재기동 없이 골든셋 위에서 스윕. v3에서 상수를 데이터클래스로 뺐기 때문에 가능해졌다.
  • 진단 도구: 랭킹 진단(rank_diag), 임베딩 처리량 벤치(embed_bench). 후보 풀 스윕은 sweep_ranking sem_candidates 30 60 100.
  • selector_bench.py — 선택 엔진 비교(freeze로 후보 고정 → run --engine order|jev|laya → decide). 평가 세트 selector-golden.jsonl, 결과 docs/selector-bench-2026-10.md.

9. 리포 구성

app/            MCP 게이트웨이 (읽기 전용 사서)
  config.py   설정 단일 정의처 (Config.from_env — 주입 가능)
  core/       I/O 없는 순수 모듈: chunking(청킹·임베딩 입력 해시) / ranking(RankingParams,
              정규 RRF) / governance(lane·status·trust 어휘) / frontmatter / safety(시크릿·인젝션)
  infra/      db(읽기/쓰기 커넥션 분리) / embedder / reranker
  services/   answer_cache(정답 캐시 v2) / workspace(worklog·handoff·resume)
  store.py    파사드 — 조립·트랜잭션·검색 조율
  server.py   MCP 도구 20종
eval/       평가 하네스 + 골든셋 + 베이스라인 + 랭킹 파라미터 스윕
tests/      단위·계약 테스트
docs/       설계서(design-v3.md) + ADR
pipeline/       편찬 파이프라인 (hermes wiki_manager 크론이 실행 — 볼트에 쓰는 유일한 주체)
  run.py        잡 엔트리포인트 · settings.py · budget.py · llm.py · notify.py
  jobs/         preflight / janitor / inbox_scan / index_home / topic_bridge /
                compile(그래프) / approvals / research
  nodes/        그래프 노드: select · refine · gate · web_verify · promote · approval
  graphs/       LangGraph 편찬 그래프(SqliteSaver 체크포인트)
  research/     DeepAgents 러너 + 게이트웨이 MCP 클라이언트
  vaultio/      볼트 파일 I/O · git(1실행 = 커밋 1개)
setup/          jobs.yaml(스케줄 정본) · provision.sh(멱등 등록) · env.example
compose.yaml, Dockerfile, requirements.txt
backups/    [git 제외] 일일 DB 스냅샷 — 개인 데이터
models/     [git 제외] 리랭커 가중치(수동 배치)
.env        [git 제외] HIPPO_MCP_TOKEN 등 시크릿

10. v3 재설계

docs/design-v3.md — 자립형 스택으로의 재설계 확정본 (2026-08-14)

v2 전수 감사에서 드러난 것(Graphify 47회 전부 no-op, LLM 편찬 체인 라이브락으로 월 정본 3편, 임베딩 해시 정의 불일치로 제목 변경 시 벡터 영구 stale)과 2026년 RAG 최신 조사를 근거로, 다음을 설계했다:

  • 한 지붕 스택 — 게이트웨이 + 전용 hermes(크론·텔레그램·프로바이더) + WebDAV + 리랭커를 이 저장소의 compose 하나로. 남의 스택 의존 해소
  • 편찬 재작성 — LangGraph 그래프(빈 큐면 LLM 미기동, 라이브락 자동 archive, 승인은 interrupt→텔레그램→resume) + 리서치만 DeepAgents
  • RAG 코어 정비 — 해시 정의 통일, 정규 RRF + 파라미터 외부화(eval 스윕), 리랭커 사이드카(옵션 — 실측 후 기본 off), 정답 캐시 v2, 비동기 우선
  • 핸드오프 레이어 — hippo_worklog / hippo_handoff / hippo_resume: 어떤 에이전트든 새 세션에서 한 번의 호출로 이전 작업 맥락을 이어받는다
  • 볼트 이전 — 호스트 계정 소유의 전용 위치로 (Obsidian 주소는 불변)

진행 상태 (2026-08-23)

Phase 상태
0 비용 차단 완료 — LLM 편찬 크론 11개 pause
1 RAG 코어 완료 — 설정 단일화, core/infra/services 분리, 정규 RRF+파라미터 외부화, ctx1 제거, embed_hash 통일(v24), 읽기/쓰기 커넥션 분리
1b 캐시·리랭커 정답 캐시 v2·Corrective 루프 완료. 리랭커는 실측 결과 기본 비활성 유지(이 CPU에서 문서당 3.7초, 풀 5에서 MRR 0.7765→0.7467)
2 자립 스택 완료 — 컷오버 실행 2026-08-20, 이제 볼트에 쓰는 것은 편찬 실행기뿐(2026-09-13부터 hermes wiki_manager)
3 편찬 그래프 완료 — LLM 경로 개통(ADR 0003), 섀도가 드러낸 결함 수정, 승인 왕복 동작
4 리서치·에이전트 개통 2026-08-23 — langchain-openai + ChatOpenAI(Responses) + system→instructions 변환(ADR 0005 §3). agent_smoke로 도구 왕복·핀 확인
섹터 차원 완료 — 정본이 20-wiki/<섹터>/<유형>/. 이전 제안 생성됨(사람 승인 대기)
큐레이터 완료 — 읽기 전용 DeepAgents 점검 → 승인 제안. 스케줄은 시각 확정 후 등록
5 볼트 이전 / 6 정리 런북 준비 완료(runbook §3·§4), 사람이 실행

결정 근거: ADR 0001 · ADR 0002 ·실행 절차: 런북

MCP Server · Populars

MCP Server · New