GEODE 운영레퍼런스
라이프사이클
Bootstrap, serve, shutdown. 주입 순서와 cold-start lazy arc를 다룹니다.
GEODE는 두 프로세스로 삽니다. 사용자가 만지는 thin CLI와 모든 런타임을 소유한 serve 데몬입니다. 데몬이 부트되는 순서, 호스팅하는 것, 내려가는 순서를 코드 기준으로 따라갑니다.
부트: thin CLI에서 데몬까지
geode (thin CLI)
│ 1. 소켓 probe: ~/.geode/cli.sock 살아 있나
│ 2. 없으면 cli.startup.lock flock 잡고
│ "geode serve"를 detached로 spawn (최대 30초 대기)
│ 3. client_capability 핸드셰이크 (TTY 여부, 터미널 폭)
▼
geode serve (데몬) ← 하나의 GeodeRuntime이 전부 소유자동 시작은 start_serve_if_needed(core/cli/ipc_client.py)가 담당합니다. pidfile flock으로 동시 실행된 thin CLI 여러 개가 데몬을 중복으로 띄우지 않게 막습니다. 데몬은 시작 직후 상속받은 환경에서 모델 선택류 behavior 키를 떨어뜨립니다 (core/cli/bootstrap.py의 load_daemon_env). 그래서 /model의 toml 쓰기가 데몬 수명 내내 이깁니다.
주입 순서
데몬 안에서 GeodeRuntime(core/runtime.py)이 인프라 싱글톤을 만들고, 구현은 core/wiring/으로 위임됩니다. 무거운 모듈 트리는 해당 컴포넌트가 실제로 쓰일 때 lazy하게 로드됩니다.
| 단계 | 만드는 것 | 코드 |
|---|---|---|
| 1 | RuntimeEventBus + SQLite sink + 공개 훅·미들웨어 registry. 프로세스 단위로 한 번 구성됩니다. | core/wiring/bootstrap.py, core/server/supervised/services.py |
| 2 | PolicyChain, ToolRegistry, LaneQueue, 인증 스토어 | core/wiring/container.py |
| 3 | TriggerManager + SchedulerService | core/wiring/scheduling.py |
| 4 | MCP, 알림, 캘린더, 게이트웨이 어댑터 | core/wiring/adapters.py |
세션 생성은 SharedServices.create_session(mode)(core/server/supervised/services.py) 한 곳으로 수렴합니다. REPL, IPC, DAEMON, SCHEDULER 네 모드가 같은 배선의(ToolExecutor, AgenticLoop) 쌍을 받고, 모드는 HITL 레벨과 time budget 같은 기본값만 바꿉니다.
배선 불변식 하나가 이 단계 전체를 지배합니다. 핸들러가 존재한다고 발화하지 않습니다. 훅 핸들러는 bootstrap에 등록되어야 하고, 프로세스 서비스는 그룹형 설정·생성자·ToolContext로 명시적으로 주입되어야 합니다. ContextVar는 요청 식별, 진단, 요청 로컬 상태와 캐시에만 사용합니다.
생성 중 실패하면 그 단계까지 만든 자원을 정리하고 원래 오류를 전달합니다. 물리적 turn의 세션 식별과 어댑터 사용량 상태는 최종 관측을 마친 뒤 이전 바인딩으로 복원되며, 실패나 취소에도 같은 정리 경로를 거칩니다.
데몬이 호스팅하는 것
- CLI IPC 서버 (
core/server/ipc_server/poller.py). thin CLI의 자유 텍스트와 슬래시 명령 처리. - 메신저 poller와 게이트웨이 (
core/server/supervised/,core/messaging/binding.py). - SchedulerService. 부팅 시 저장 작업 로드와 놓친 발화 복구, serve 루프에서 drain.
- gateway와 webhook이 모두 활성일 때의 HTTP 엔드포인트.
종료 순서
순서가 곧 안전입니다. 새 요청을 먼저 끊고, 하던 일을 마치게 하고, 상태를 저장한 뒤 연결을 닫습니다 (core/cli/typer_serve.py).
1. RuntimeEvent.SHUTDOWN_STARTED 발화
2. IPC 신규 연결 차단 + 게이트웨이 입력 정지
3. 활성 세션 drain (최대 30초)
4. CLI poller + webhook 종료
5. 런타임 소유 작업·watcher·스케줄러·MCP 종료
6. 훅과 이벤트 저장소 닫기스케줄러 저장 실패도 나머지 자원 정리를 막지 않습니다. 런타임은 불완전한 종료를 재시도할 수 있게 유지하고, 데몬은 종료 실패를 표시합니다. 실행 자체가 정상 반환했어도 정리가 끝나지 않으면 종료 코드는 1입니다. 기존 실행 오류나 취소가 있다면 그 원인이 정리 오류로 바뀌지 않습니다.
각 런타임은 별도 MCP manager를 만들고 알림·캘린더·게이트웨이에 같은 인스턴스를 전달합니다. 다른 런타임의 생성 실패나 종료가 이 연결을 닫지 않으며, 런타임 manager는 프로세스 신호 핸들러를 변경하지 않습니다. 종료에 실패한 연결은 재시도를 위해 보존합니다. 연결 생성 중 실패해도 같은 소유자가 정리하며, 자식 프로세스의 종료를 확인한 뒤 파이프와 작업 디렉터리를 해제합니다.
실패 모드
| 증상 | 원인 | 해법 |
|---|---|---|
| 업데이트했는데 옛 동작이 계속됨 | 오래된 데몬이 살아남아 소켓을 점유 | pkill -f "geode serve" 후 재진입합니다. geode update로 재시작할 수도 있습니다. |
| 외부 채널이 동작하지 않음 | gateway_enabled 꺼짐 | CLI IPC는 계속 동작합니다. 외부 채널이 필요할 때만 GEODE_GATEWAY_ENABLED=true를 켭니다. |
| 기능이 조용히 동작하지 않음 | 핸들러 미등록 또는 서비스 구성 누락 | bootstrap 등록과 composition root의 명시적 서비스 주입을 확인합니다. core/wiring/bootstrap.py의 get_plugin_status()가 플러그인별 등록 상태를 보고합니다. |
다음
- 데몬으로 실행. 운영 관점의 시작과 정지.
- Serve와 게이트웨이. 데몬이 호스팅하는 메신저 경로.
- 훅 등록. bootstrap 등록이 필수인 이유.
GEODE 저장소의 문서 사이트에서 옮겨 온 문서입니다. 원문 커밋 de077a4 · GitHub에서 원문 보기