증상
Telegram 채팅에서 응답을 받을 때마다 ⏳ Working — 5h 09m 형태의 하트비트 상태줄이 계속 떠 있음(사용자 체감: "말할 때마다 떠서 거슬린다"). 값이 42m → 5h+로 계속 증가. gongyung(Android/Termux) 노드에서 관찰.
왜 버그인가
⏳ Working — {elapsed}는 core/heartbeat.py:compose_heartbeat_text()가 생성, core/project_chat.py:_maybe_update_heartbeat()에서 elapsed = now - req.started_at로 매 틱 갱신됨 (not req.future.done() 조건).
req.started_at은 요청마다 loop.time()로 세팅됨(core/project_chat_process.py:79), 완료 시 하트비트 메시지는 heartbeat_delete_on_done=True(기본) 로 삭제되어야 함(core/bot_status.py:18).
- 그런데
CLAUDE_PROCESS_TIMEOUT 기본 600s(=10분) 를 훨씬 초과한 5시간+ 동안 하트비트가 살아있음 → 요청 future가 정상적으로 완료/취소/타임아웃되지 않거나, 완료 시 하트비트 cleanup이 실패해 좀비 상태로 남는 결함. 어떤 경우든 하트비트 수명이 요청 타임아웃으로 bound 되지 않는 것이 문제.
관찰 근거 (gongyung, 2026-07-05)
- OS 레벨 stuck 프로세스는 없음(정상 데몬만). 즉 브리지 프로세스(PID 9851) 내부의 미완료
_PendingRequest/삭제 실패 하트비트 메시지로 추정.
- 재현 맥락: 장시간(수 시간) 이어진 세션 중, 중간에 SSH로 띄운 별도 blocking 루프/컴팩션 등 이벤트가 있었음. (동일 세션에서 후속 응답은 정상 전달됨 → 좀비는 별개 슬롯)
기대 동작
- 하트비트/typing 인디케이터 수명은 반드시 요청 lifecycle(완료·취소·
CLAUDE_PROCESS_TIMEOUT)로 bound 되어야 함. future가 어떤 경로로 끝나든 finally에서 하트비트 message 삭제 보장.
heartbeat_delete_on_done 삭제가 Telegram API 오류 등으로 실패해도, 다음 완료/주기 tick에서 재시도하거나 최소한 무한 갱신되지 않도록 방어.
- (선택) 하트비트 자체에 상한(max elapsed) 두어 요청 타임아웃 초과 시 자동 종료/에러 표기.
관련 이슈
임시 조치 (gongyung)
- 브리지 재시작으로 좀비 상태 클리어.
.env에 CCC_HEARTBEAT_ENABLED=false로 하트비트 표시 비활성(사용자 요청).
관련 코드: bridge/core/heartbeat.py, bridge/core/project_chat.py (_maybe_update_heartbeat/_cleanup_heartbeat), bridge/core/project_chat_process.py, bridge/core/bot_status.py.
증상
Telegram 채팅에서 응답을 받을 때마다
⏳ Working — 5h 09m형태의 하트비트 상태줄이 계속 떠 있음(사용자 체감: "말할 때마다 떠서 거슬린다"). 값이 42m → 5h+로 계속 증가. gongyung(Android/Termux) 노드에서 관찰.왜 버그인가
⏳ Working — {elapsed}는core/heartbeat.py:compose_heartbeat_text()가 생성,core/project_chat.py:_maybe_update_heartbeat()에서elapsed = now - req.started_at로 매 틱 갱신됨 (not req.future.done()조건).req.started_at은 요청마다loop.time()로 세팅됨(core/project_chat_process.py:79), 완료 시 하트비트 메시지는heartbeat_delete_on_done=True(기본) 로 삭제되어야 함(core/bot_status.py:18).CLAUDE_PROCESS_TIMEOUT기본 600s(=10분) 를 훨씬 초과한 5시간+ 동안 하트비트가 살아있음 → 요청 future가 정상적으로 완료/취소/타임아웃되지 않거나, 완료 시 하트비트 cleanup이 실패해 좀비 상태로 남는 결함. 어떤 경우든 하트비트 수명이 요청 타임아웃으로 bound 되지 않는 것이 문제.관찰 근거 (gongyung, 2026-07-05)
_PendingRequest/삭제 실패 하트비트 메시지로 추정.기대 동작
CLAUDE_PROCESS_TIMEOUT)로 bound 되어야 함. future가 어떤 경로로 끝나든 finally에서 하트비트 message 삭제 보장.heartbeat_delete_on_done삭제가 Telegram API 오류 등으로 실패해도, 다음 완료/주기 tick에서 재시도하거나 최소한 무한 갱신되지 않도록 방어.관련 이슈
임시 조치 (gongyung)
.env에CCC_HEARTBEAT_ENABLED=false로 하트비트 표시 비활성(사용자 요청).관련 코드:
bridge/core/heartbeat.py,bridge/core/project_chat.py(_maybe_update_heartbeat/_cleanup_heartbeat),bridge/core/project_chat_process.py,bridge/core/bot_status.py.