context-engine-audit.ko.md
docs/i18n/context-engine-audit.ko.md
Tesserae를 컨텍스트 엔진으로 — 격차 분석
<!-- translations:start -->
English · 한국어 · 中文 · 日本語 · Русский · Español · Français · Deutsch
<!-- translations:end -->
미션 (2026-06-02): Tesserae는 *컨텍스트 엔진*입니다. 세 가지 기둥을 통해 자기 개선형 지식 기반을 재구성하여 에이전트가 바로 쓸 수 있는 컨텍스트를 생성합니다: (1) 세션 모니터링, (2) 자율적·능동적 수집, (3) 온디맨드 문서. 지식은 실시간으로 진화하며 에이전트에게 곧바로 넘길 준비가 되어 있어야 합니다.
이 문서는 현재 코드베이스를 그 미션에 비추어 감사합니다. 네 갈래로 나눈 병렬 리뷰(수집/세션, 자기 개선, 출력/에이전트 대면, 오케스트레이션/생애주기)의 결과물입니다.
v0.5.0 기준 상태 (2026-06-06): 이 문서는 시점 감사(2026-06-02 스냅샷)이며 기록을 위해 그대로 보존됩니다. 교차 절단(cross-cutting) 발견 사항 대부분은 이제 해결되었습니다: 누락되었던 슈퍼바이저 데몬과 인프로세스 파이프라인 오케스트레이터가 출시되었고(엔진 스파인,
tesserae/engine/), 라이브 세션 테일링이 사후 스캔을 대체하며(기둥 1), 자기 개선 패스들이node_memory사이드카를 통해 활성화·영속화되었고(슈퍼시드 기본 활성화+억제, 수치 재발 신뢰도 — 기둥 2), 해시 버킷 기본 임베딩이 실패 시 명시적으로 알리는 진짜 백엔드로 대체되었으며(기둥 3), 기둥 3의 온디맨드 컨텍스트 컴파일러가 이제 존재합니다(compile_context).GraphStore포트를 통한 설계된 증분 레이어는 인프라로 도착했지만 플래그 OFF/실험적으로 유지되고, serve+watch+deploy 통합(빌드 순서 7단계)은 여전히 미해결입니다. 단계별 상태는 단계별 로드맵, 변경 사항 요약은 v0.5.0 릴리스 노트를 참조하세요. 아래 발견 사항은 원본 스냅샷 그대로 편집 없이 남겨둡니다.
한 줄 평결
오늘의 Tesserae는 기계적으로 건강하고 테스트가 잘 된 배치 CLI 컴파일러입니다. 컨텍스트 엔진 비전에 비추어 보면 세 기둥 모두에서 수동 트리거 + 사후 처리 + git-HEAD에 묶인 상태입니다. 엔진을 구성할 기계 장치는 이미 프리미티브로 존재합니다. 빠진 것은 그것들을 조합하는 연속적·자율 구동 계층입니다.
모든 단면에서 가장 크게 빠진 한 조각: 하나의 이벤트 루프를 소유하고 세션 추적, 수집, 증분 컴파일, 발행을 자율적으로 구동하는 장기 실행 슈퍼바이저/데몬. 나머지는 모두 그 위에 얹는 증분 작업입니다.
기둥 1 — 세션 모니터링 → 라이브가 아닌 사후 처리
| 상태 | 발견 | 필요한 것 |
|---|---|---|
| 격차 | 세션 캡처는 사후 스캔입니다. discover_harness_sessions()는 사람이 sessions discover --import 또는 compile을 실행할 때만 완료된 트랜스크립트를 훑습니다. compile은 의도적으로 ~/.claude/projects/ 스캔을 거부합니다(지연 문제). | 세션이 진행되는 동안 하네스 JSONL 파일을 감시하고 턴을 수집하는 테일러(tailer). |
| 격차 | 유일한 진짜 워처(watch.py WatchLoop)는 소스 마크다운을 다루며 2초마다 폴링하고 전체 compile을 발화합니다. 세션도 코드도 감시하지 않습니다. | 하나의 슈퍼바이저 아래에서 세션 + 소스 도구 트리거로 확장. |
| 격차 | vault_watch.py의 "라이브" 루프는 수집이 아니라 출력(Obsidian 역동기화)에 대한 것입니다. | 라이브 지식 풀의 대체물이 아님. |
| 거침 | 세션 재추출은 session_id별로 캐시 키가 매겨지지만 세션 전체 단위입니다. 새 턴 하나가 캐시 전체를 무효화하고 전체 LLM 패스를 다시 돌립니다. | 라이브 테일링을 위한 턴 단위 증분성. |
| 거침 | harness_sessions 스토어는 평면 glob이며 매 list/write마다 전체 재스캔합니다. | 끊임없이 증가하는 캡처 집합을 위한 인덱스/추가형 스토어. |
| 누락 | 노드별 신선도/출처 타임스탬프가 없음. 통화성은 아티팩트 수준(git HEAD)에서만 추적됩니다. | "이것은 얼마나 신선한가?"를 위한 사실별 신선도. |
기둥 2 — 자기 개선형 지식 기반 → 일회성 재추출, 덧붙인 진화
"진화하는" 패스는 존재하지만 단일 compile 안에서만(처음부터 다시 추출) 실행되며, 대부분 환경 플래그 또는 수동 CLI로 옵트인입니다. 사실은 컴파일마다 다시 계산되며, 제자리에서 수정되지 않습니다.
| 상태 | 발견 | 필요한 것 |
|---|---|---|
| 격차 | 감쇠(Decay)(memory/decay.py, Ebbinghaus 14일 반감기)는 *쿼리 시점*에만 계산되며 컴파일 시 절대 영속화·재기록되지 않습니다. | 컴파일 시점 감쇠 기록 + 영속 점수. |
| 격차 | 감쇠의 접근 루프가 죽어 있음: last_accessed_at == first_seen_at, access_count는 절대 증가하지 않음. "계속 들여다본다 → 중요하다" 신호가 아무 일도 안 함. | 접근 기록 표면(MCP 읽기 → 증가). |
| 격차 | 대체(Supersede)(memory/supersede.py)는 TESSERAE_SUPERSEDE_PASS=true로 게이트(기본 꺼짐)되며 엣지를 *추가*만 할 뿐 — 노후 콘텐츠를 강등/숨기지 않습니다. 믿음 수정이 겉치레일 뿐. | 기본 켜짐 + 출력에서 대체된 사실을 억제하는 소비자. |
| 격차 | 모순(Contradictions)은 *탐지*되지만(lint.py, info 심각도, 취약한 문자열 매칭) 절대 *해결*되지 않습니다. 신뢰도 중재 없음. | 단순 탐침이 아닌 해결 패스. |
| 격차 | 스키마 드리프트(schema_drift.py)는 수동 schema-drift 하위 명령으로 제안만 작성할 뿐, 스키마가 스스로 정제되지 않습니다. | 적용 경로 + 파이프라인 통합. |
| 격차 | 정규화(Canonicalization)는 고신뢰 별칭만 자동 병합하고 나머지는 사람의 CLI 승인을 위해 대기시킵니다. | 시간이 지나며 LLM이 중재하는 자동 병합. |
| 격차 | 피드백 루프가 반쯤 닫힘: 결정론적 베이스라인 추출기가 *지침을 완전히 무시*합니다(selective_extractor.py:43). 선택적 LLM 경로만 교정을 소비합니다. LLM이 꺼져 있으면 사람의 교정이 추출에 다시 들어오지 않습니다. | 결정론적 경로의 지침 준수, 또는 기본 LLM 사용. |
| 격차 | 반복 인사이트 강화 없음: 인사이트가 여러 세션에서 다시 나타나도 신뢰도를 강화하는 것이 없음. temporal.infer_confidence는 거친 문자열 휴리스틱입니다. | 교차 세션 빈도 → 수치 신뢰도. |
| 거침 | 대체 후보 짝짓기가 어휘적 자카드(0.55)입니다. 어휘 중복이 적은 의미적 재진술은 절대 후보가 되지 못합니다. | 임베딩 기반 후보 생성. |
| 누락 | 자기 개선 단면 전체가 테스트되지 않음(decay/supersede/feedback/drift/canonical/temporal 테스트 없음). | 이곳을 변경할 때 함께 붙는 테스트. |
기둥 3 — 온디맨드 문서 → 아직 존재하지 않음
쿼리/검색 배관은 성숙합니다(하이브리드 RRF, PPR, ~20개 MCP 도구, 페이지별 ask, AI 내보내기). 그러나 모든 아티팩트는 정적 전체 코퍼스 투영이거나 단일 노드 조회입니다. "사용자가 'X에 대한 컨텍스트를 달라' → 맞춤 문서"는 구현되어 있지 않습니다. 이를 구축할 프리미티브는 모두 존재하지만 조합되지 않았습니다.
| 상태 | 발견 | 필요한 것 | |
|---|---|---|---|
| 누락 | 온디맨드 문서 생성(핵심 기둥 3 격차). 요청으로부터 맞춤·쿼리 범위 문서를 만드는 모듈이 없음. report.py는 컴파일 시점 린트 요약이지 지식 아티팩트가 아님. | 새 context_compiler: 검색 → PPR → 이웃 탐색 → 본문 조립 → 선택적 LLM 종합. | |
| 격차 | wiki_page는 미리 컴파일된 노드 본문 하나를 반환할 뿐, 다중 노드·쿼리 범위 조립 도구가 없음. | `compile_context(query | seeds, depth, budget)` MCP 도구. |
| 격차 | ask는 산문이나 결과 목록을 반환할 뿐, 다운로드 가능/넘김용 컨텍스트 아티팩트는 절대 아님. | 구조화·인용된 컨텍스트 번들을 내보내는 응답 모드. | |
| 격차 | agent_harness.py는 정적 핸드오프(하드코딩된 상위 12개 노드 + 고정 목록)이지 쿼리 범위나 작업별이 아님. | 토픽/시드를 받아 → 범위 한정 브리프 렌더링. | |
| 격차 | node_context는 1-홉, 순위 없음. 에이전트 컨텍스트 프리미티브로 약함. | 순위가 매겨진 k-홉 컨텍스트를 위해 PPR을 거치도록. | |
| 격차 | 내보내기(llms.txt, graph.jsonld)는 전체 코퍼스 덤프이며 토픽별 슬라이스가 없음. | 토픽 범위 서브그래프 → llms-txt 슬라이스. | |
| 거침 | 기본 임베딩 레인이 결정론적 해시 버킷 의사 임베딩(blake2b, 128차원)입니다. sentence-transformers가 설치된 경우에만 진짜 의미 백엔드를 쓰며, auto는 조용히 강등됩니다. 박스에서 꺼낸 "의미" 검색은 가짜입니다. | 진짜 기본 임베딩, 또는 해시 레인에 대한 큰 경고. | |
| 거침 | query.answer()는 노드 인용 정규식 매칭이 없으면 유효한 LLM 답변을 버립니다. | 답변을 유지하되, 빠진 인용을 표시. | |
| 거침 | 정적 호스트 ask 위젯은 통조림 DEMO_QA를 제공합니다. 진짜 ask는 serve 하에서만 동작합니다. 공개 Pages "ask"는 연극입니다. | 데모용으로는 허용 가능하나, 발행된 사이트에서는 에이전트가 소비할 수 없음. | |
| 거침 | ask의 auto 백엔드는 예외를 삼키고 보이지 않게 BM25로 강등됩니다. | 어떤 백엔드가 답했고 왜 폴백이 발생했는지 드러내기. |
횡단 관심사 — 오케스트레이션 & 생애주기 → 배치 CLI, 엔진 없음
| 상태 | 발견 | 필요한 것 | |
|---|---|---|---|
| 격차 | 데몬/엔진 프로세스 없음. 평면 일회성 argparse 디스패처. 각 하위 명령 후 프로세스가 종료됨. signal/SIGTERM/pidfile/launchd 처리 전무. 워처는 맨 KeyboardInterrupt에서 죽음. | 하나의 이벤트 루프 + 우아한 종료를 소유하는 감독형 장기 실행 데몬. | |
| 격차 | "연속" = while True: time.sleep(interval) 마크다운 폴러. 파일시스템 이벤트, 백프레셔, 스트리밍 없음. | 단일 스케줄러를 갖춘 이벤트 구동 코어. | |
| 격차 | "Refresh"가 코드가 아니라 슬래시 명령 마크다운 스킬에 존재 — sessions discover --import → compile → obsidian-sync를 순서화함. | 데몬/CLI/MCP가 공유하는 일급 인프로세스 파이프라인 오케스트레이터. | |
| 거침 | changed_only 증분 컴파일이 취약하며 스스로 임시방편이라 명시: 매니페스트는 {path: sha256}. 이전 그래프를 다시 로드하고, 프로젝터/종합 노드를 벗기고, 재추출된 소스 노드를 축출한 뒤 병합해야 함 — 안 그러면 21파일 편집이 2400노드를 1700노드로 무너뜨림. | GraphStore 포트를 흐르는 설계된 증분/스트리밍 계층. | |
| 거침 | cli.py는 ~2000줄 갓-디스패처(if args.command == ... 사다리). ask/wiki는 별도 수작업 파서를 가짐. | 명령 레지스트리 / 하위 명령 모듈. | |
| 거침 | 단계 게이트 플래그가 반쯤 완성된 표면을 출하: --sessions-llm 도움말이 *"Phase 5가 도착하면 적용됨"*이라 말함. | 완성하거나 숨기기. | |
| 거침 | graph_stores/url_resolver.py는 비동기 스토어를 호출마다 asyncio.run으로 감쌈 — upsert마다 새 이벤트 루프. 스트리밍에 병적임. | 엔진이 라이브가 되면 영속 비동기 런타임. | |
| 거침 | ports/ 헥사고날 프로토콜이 정의되어 있으나 독립형 파이프라인은 이를 우회하여 JSON 아티팩트로 직행. HypePaper만 포트를 사용. | 코어 파이프라인을 일관되게 GraphStore로 흐르게 하기. | |
| 거침 | 세 가지 영속 포맷(JSON 아티팩트, SQLite 스토어, Kuzu)에 단일 진실원이 없음. Kuzu 어댑터는 0.16 손상 버그를 피하려고 모든 필드를 base64로 감쌈. | 하나의 진실원으로 수렴. | |
| 거침 | serve(TCPServer.serve_forever)와 watch는 별도의 블로킹 프로세스 — serve + 자동 재컴파일을 함께 할 수 없음. deploy는 수동 git push로 분리됨. | 연속 발행을 위해 serve + watch + deploy를 슈퍼바이저 아래로 통합. | |
| 누락 | frontend.py는 tesserae/site/를 중복하는 사용 중단된 죽은 모듈인데도 여전히 출하됨. | 삭제하거나 호출자 마이그레이션. | |
| 거침 | review_workflow.py 사람 검토 루프는 손편집용으로 문자열 타입 `"action": "TODO: merge | keep_separate"` JSON을 내보냄. 프로그램적 적용 경로 없음. | 컴파일에 연결된 통합 검토 큐. |
| 참고 | TODO/FIXME 마커는 정말로 드뭅니다 — 진짜 부채는 주석으로 문서화된 임시방편(changed-only 병합, Kuzu base64, asyncio-per-call)이지 흩어진 TODO가 아님. | — |
권장 구축 순서 (아키텍처 델타 → 비전)
- 슈퍼바이저 데몬 + 인프로세스 파이프라인 오케스트레이터. 하나의 이벤트 루프, 시그널/종료, 마크다운 스킬 refresh 체인 대체. 다른 모든 기둥을 잠금 해제.
- 라이브 세션 모니터. 하네스 JSONL 테일 → 턴 단위 증분 추출 → 루프에 공급. (수동
sessions discover --import대체.) - 진짜 증분/스트리밍 컴파일을
GraphStore포트를 통해, 취약한changed_only축출 패치를 은퇴시키기. - 자기 개선 패스를 기본으로 활성화 + 영속화: 컴파일 시점 감쇠 기록, MCP 읽기 시 access-count 증가, supersede 켜짐(억제 포함), 모순 해결, 반복 인사이트 신뢰도.
- 온디맨드 컨텍스트 컴파일러(
compile_contextMCP 도구 + CLI): 쿼리 → PPR/하이브리드 → 이웃 탐색 → 조립·인용된 에이전트용 문서. - 진짜 기본 임베딩(또는 큰 강등 경고)으로 박스에서 꺼낸 의미 검색이 해시 스텁이 아니게.
- serve + watch + deploy 통합으로 연속 발행. 생애주기 테스트 추가 (비전이 가장 의존하는 계층이 현재 가장 덜 커버됨).
보존할 가치가 있는 강점
결정론적 바이트 동일 컴파일; 배치 기계 장치에 대한 폭넓은 테스트 커버리지; 깔끔한 하이브리드 RRF 검색 + 사려 깊은 PPR 엣지 가중치; 폭넓고 올바르게 분할된(공개/비공개) MCP 도구 표면; 견고한 정적 내보내기(llms.txt, JSON-LD, RSS)와 보안을 의식한 ask 위젯. 토대는 튼튼하며, 할 일은 그 위에 동적·자기 구동 계층을 더하는 것입니다.