GEODE . 문서
GitHub
핵심 개념
레퍼런스

훅과 관측성

핸들러가 구독하는 라이프사이클 이벤트입니다. 하나의 이벤트 위에 observe, react, decide, act가 어떻게 쌓이는지 설명합니다.

HookSystem(core/hooks/system.py)은 런타임의 모든 의미 있는 경계에서 이벤트를 발화하는 단일 버스입니다. HookEvent enum은 정확히 56개의 라이프사이클 이벤트를 정의합니다. 새 동작은 루프 코드를 고치는 대신 이 이벤트들 위에 핸들러로 쌓입니다.

하나의 이벤트, 네 가지 쌓기

같은 이벤트라도 핸들러가 무엇을 하느냐에 따라 네 층위로 쌓입니다.

층위호출 방식의미
Observetrigger()fire-and-forget 관찰. 핸들러 오류는 로깅 후 격리됩니다
Reacttrigger() 구독 핸들러이벤트를 계기로 부수 작업을 실행 (알림, 저널, 메트릭)
Decidetrigger_with_result()핸들러 반환값을 호출자가 수집해 전략을 결정 (예: CONTEXT_OVERFLOW_ACTION)
Acttrigger_interceptor()핸들러가 실행 자체를 차단하거나 수정 (인터셉터 패턴)

비동기 변형으로 trigger_async가 있습니다.

이벤트 카테고리

56개 이벤트는 enum 안의 섹션 주석으로 분류됩니다. 대표만 추리면 이렇습니다.

카테고리대표 이벤트
agentic 턴 / 세션TURN_COMPLETED, SESSION_STARTED, SESSION_ENDED
LLM 호출LLM_CALL_STARTED/ENDED/FAILED/RETRIED, ADAPTER_DISPATCH_ATTEMPT, MODEL_SWITCHED
도구 실행 / 승인TOOL_EXEC_STARTED/ENDED/FAILED, TOOL_RESULT_TRANSFORM, TOOL_APPROVAL_REQUESTED, APPROVAL_TRANSITION, TOOL_RECOVERY_ATTEMPTED/SUCCEEDED/FAILED
컨텍스트 / 오프로드CONTEXT_CRITICAL, CONTEXT_OVERFLOW_ACTION, TOOL_RESULT_OFFLOADED
프롬프트 / 메모리PROMPT_ASSEMBLED, PROGRAM_MD_UNREADABLE, MEMORY_SAVED, RULE_CHANGED
비용 / 인터셉터USER_INPUT_RECEIVED, COST_WARNING, COST_LIMIT_EXCEEDED, EXECUTION_CANCELLED
서브에이전트 / 핸드오프SUBAGENT_STARTED/COMPLETED/FAILED, HANDOFF_TRIGGERED/COMPLETED/FAILED
자기개선 루프MUTATION_PROPOSED/APPLIED/REJECTED/REVERTED, BASELINE_PROMOTED, SELF_IMPROVING_AUTO_TRIGGER
인프라TRIGGER_FIRED, CONFIG_RELOADED, SHUTDOWN_STARTED, MCP_SERVER_CONNECTED/FAILED

등록

from core.hooks.system import HookSystem, HookEvent

hooks.register(
    HookEvent.TURN_COMPLETED,
    my_handler,
    name="my-plugin",
    priority=100,   # 낮을수록 먼저 실행, 안정 정렬
)
hooks.register_prefix("*", mirror_everything)  # 와일드카드 구독

부트스트랩 등록이 필수

핸들러가 존재한다는 사실과 핸들러가 발화한다는 사실은 다릅니다. 프로덕션 핸들러는 전부 core/wiring/bootstrap.py에서 등록됩니다. 거기 없는 핸들러는 코드로 존재해도 영원히 호출되지 않습니다. 이 규칙은 저장소의 wiring 검증 인바리언트로 핀 고정되어 있습니다.

부트스트랩에는 priority 50의 "*" prefix 핸들러가 하나 있어, 모든 트리거를 활성 RunTranscript의 activity log 행으로 미러링합니다. 훅 버스 자체가 관측 파이프라인의 입구입니다.

실패 모드

증상원인해법
핸들러를 만들었는데 한 번도 안 불림부트스트랩 미등록core/wiring/bootstrap.py에 등록을 추가합니다
핸들러 실행 순서가 뒤섞임priority 미지정 (기본 100)순서가 중요하면 명시적 priority를 부여합니다. 낮은 값이 먼저입니다
observe 핸들러의 예외가 보이지 않음trigger()는 오류를 격리하고 로깅만 합니다로그를 확인합니다. 흐름을 막아야 하는 로직이면 인터셉터로 옮깁니다

Activity row 스키마와 에러 정책

모든 trigger*() 호출은 활성 RunTranscript에 타입이 지정된 Activity row 한 줄로 미러링됩니다. 56개 이벤트 전부 구체 타입의 row를 가집니다 (19 lifecycle + 37 K-group). action필드가 discriminator이고, GenericActivityRow는 정상 경로 목적지가 아니라 fail-soft 폴백 전용입니다.

정책내용
커버리지56/56 타입 지정. 37 K-group은 선언적 spec 테이블 + 단일 빌더로 구성
details 스키마23 공유 모델, frozen + extra=forbid. 모든 row에 schema_version
silent fallback 금지강제 generic 폴백은 _fallback_reason을 동봉해 timeline에서 구분 가능. 미러링 / dispatch / 학습 저장 실패는 이벤트당 한 번만 WARNING
프라이버시 드롭raw user_input, cognitive-state 스냅샷, 전체 tool result는 적재 금지. input_len 같은 파생 스칼라만

다음