GEODE의 관측성은 목적별 저장소를 사용합니다. query/filter/aggregate가 필요한 훅 이벤트는 SQLite, 순서대로 읽고 내보내는 실행 artifact는 JSONL, 프로세스 진단은 rotating log입니다. raw prompt와 tool 결과를 운영 event table에 복제하지 않습니다.
저장소 지도
| 렌즈 | 저장소 | 용도 |
|---|---|---|
| Hook events | sessions.db:hook_events | 세션/이벤트/status/action 조회와 보존 정책 |
| Run transcript | transcript.jsonl | 활성 autoresearch timeline과 tail |
| Dialogue | dialogue.jsonl / session transcript | 사용자·assistant·tool 대화 artifact |
| Session metrics | 메모리 + run summary | 토큰, 비용, latency percentile |
| Usage ledger | ~/.geode/usage/YYYY-MM.jsonl | LLM 호출별 비용 time series |
| Scheduler job tail | .geode/scheduler_logs/*.jsonl | job별 portable bounded history |
| Process logs | ~/.geode/logs/ | traceback과 외부 시스템 진단 |
한 trigger, 한 durable row
HookSystem은 handler chain이 끝난 뒤HookDispatch를 sink에 한 번 보냅니다. 그래서 sync/async, feedback/interceptor 경로마다 writer를 반복하지 않습니다. legacy 실패나 승인 이벤트처럼 canonical 이벤트와 의미가 겹치는 신호는 외부 handler에는 전달하지만 SQL과 transcript에는 중복 기록하지 않습니다.
이벤트 조회
from core.observability.event_store import HookEventStore
store = HookEventStore()
try:
for row in store.read(limit=50, event_filter="tool_exec_ended"):
print(row.session_key, row.status, row.action, row.occurred_at)
finally:
store.close()row는 event, dispatch mode, status, handler error count, actor/action/entity, bounded payload hash를 가집니다. payload의 문자열·collection·깊이·전체 bytes에 상한이 있고 secret pattern을 redaction합니다.
보존과 수명주기
- high-volume 7일, standard 30일, audit 180일
- project database 전체 100,000행 상한
- append 중 incremental prune + 명시적
prune_events() - runtime shutdown이 producer를 멈춘 뒤 hook sink와 SQLite connection을 닫음
- latency percentile sample과 model cardinality도 bounded
실패 가시성
handler 실패는 다른 handler를 막지 않으며 row의handler_error_count에 반영됩니다. sink 실패는 event 종류별로 한 번 WARNING하고 agentic loop는 계속합니다. 멈춘 실행의 조사 순서는 멈춘 실행 디버깅을 따릅니다.