게이트웨이는 serve 데몬 안에서 메신저 메시지를 받아 GEODE 실행으로 넘기는 라우터입니다. Slack Socket Mode와 플랫폼 poller가 메시지를 받고, binding이 어느 채널을 받을지 결정하며, lane queue가 동시성을 제한합니다. 라우팅에는 LLM 대신 정적 규칙만 씁니다.
동작 구조
| 구성 요소 | 역할 | 코드 |
|---|---|---|
| 메신저 receiver | Slack은 Socket Mode push를 바운드 큐에 넣은 뒤 ACK하고 처리합니다(큐가 가득 차면 unACK로 Slack 재전송). Discord와 Telegram은 주기적으로 조회합니다. 공통 스레드 수명주기는 BasePoller가 가집니다. | core/server/supervised/ |
| ChannelManager | binding 규칙으로 인바운드 메시지를 라우팅합니다. channel과 channel_id가 정확히 일치해야 통과합니다. | core/messaging/binding.py |
| LaneQueue | 세션 키 단위 직렬화와 전역 동시성 상한입니다. 모든 실행 경로가 SessionLane과 global lane을 차례로 통과합니다. | core/orchestration/lane_queue.py |
| CLIPoller | thin CLI의 IPC 요청을 받는 데몬 쪽 서버입니다. 메신저 receiver와 같은 lane 규칙을 따릅니다. | core/server/ipc_server/poller.py |
데몬 모드 세션은 headless이므로 승인을 받을 사용자가 없습니다. 그래서 run_bash와 delegate_task는 게이트웨이 경로에서 차단됩니다 (core/server/supervised/services.py).
시작과 종료
geode serve는 gateway_enabled가 꺼져 있으면 시작을 거부합니다. ~/.geode/.env에 GEODE_GATEWAY_ENABLED=true를 추가해야 합니다. 대화만 한다면 serve를 직접 띄울 필요가 없습니다. bare geode가 데몬을 자동으로 시작합니다.
# 게이트웨이 켜기 echo 'GEODE_GATEWAY_ENABLED=true' >> ~/.geode/.env geode serve # 포그라운드, --poll은 poll 기반 receiver 주기 # 살아 있는지 확인 pgrep -f "geode serve" # 재시작 (설정 변경 후) pkill -f "geode serve" geode serve &
종료는 단계적입니다. SHUTDOWN_STARTED 훅 발화, 신규 연결 차단, 활성 세션 30초 drain, 스케줄러 저장과 정지, MCP 종료, 게이트웨이 정지 순서입니다 (core/cli/typer_serve.py).
binding 설정
어느 채널이 GEODE를 깨울 수 있는지는 binding 규칙이 결정합니다. 규칙 작성법은 바인딩 설정 가이드에서 다루고, 형식만 요약하면 이렇습니다.
# .geode/config.toml [gateway] pollers = ["slack"] # 띄울 receiver 등록명 time_budget_s = 120 # 메시지당 wall-clock 기본값 [[gateway.bindings.rules]] channel = "slack" channel_id = "C0ABCDEF1" # 필수. 비어 있으면 규칙이 건너뜀 require_mention = true
실패 모드
| 증상 | 원인 | 해법 |
|---|---|---|
geode serve가 즉시 종료 | gateway_enabled 꺼짐 | GEODE_GATEWAY_ENABLED=true를 ~/.geode/.env에 추가합니다. |
| 메시지에 반응이 없음 | binding 불일치, 앱 토큰 누락, 또는 채널 멤버십 없음 | geode doctor slack으로 점검하고, 출력된 링크의 채널에서 /invite @geode를 실행합니다. |
| 배너 모델과 응답 모델이 다름 | 데몬이 둘 이상 떠서 소켓을 두고 경합 | pkill -f "geode serve"로 전부 내린 뒤 하나만 다시 띄웁니다. ps aux | grep은 경로가 잘려 빈 결과가 나오므로 pgrep -f를 씁니다. |
| 같은 채널 요청이 밀림 | 같은 세션 키는 의도적으로 직렬화 | 정상 동작입니다. 다른 스레드나 채널로 보내면 병렬로 처리됩니다. |
데몬 로그는 ~/.geode/logs/serve.log에 10MB 단위 5개 파일로 로테이션됩니다 (core/observability/logging_config.py).