---
prevention_deferred: null
---

# Telegram-origin 질문에 터미널로만 답하고 reply 툴 호출 누락

- **발생 일자:** 2026-04-20 09:10 KST (추정)
- **해결 일자:** 2026-04-20 09:13 KST
- **심각도:** high (사용자 의사소통 차단)
- **재발 가능성:** high (같은 세션에서 여러 번 반복 확인됨)
- **영향 범위:** WSL Claude Code 세션 전반 (telegram-origin 대화 시)

## 증상
사용자가 텔레그램으로 `/to-iphone` 스킬 설계 질문을 보냄. WSL Claude 가 설계안을 터미널에 길게 출력한 뒤 reply 툴 호출 없이 응답 종료. 사용자 화면(텔레그램)에는 아무것도 뜨지 않아 "또 텔레그램 답변이 안오는데?" 로 인지.

## 원인
긴/구조적 답변을 작성할 때 "대화 턴" 으로 인식해 기본 출력 경로(터미널 텍스트)로 빠짐. reply 툴 호출은 **override 단계**라서 매번 의식적으로 걸어야 하는데, 답변의 길이/복잡도가 올라갈수록 마지막 단계에서 빼먹는 패턴이 반복. 시스템 프롬프트 상단의 "The sender reads Telegram, not this session" 지시를 머리로는 알지만 손이 먼저 터미널로 감.

## 조치
- 즉시 같은 내용을 `mcp__plugin_telegram_telegram__reply` 로 재전송
- 원인 자가분석 (길이 트랩, 질문 모드 방심, forcing function 부재) 텔레그램으로 공유
- 메모리 저장: `feedback_telegram_reply_tool_mandatory.md`
- **Stop 훅 설치**: `~/.claude/hooks/telegram-reply-check.sh`
  - transcript JSONL 파싱 → 마지막 real user prompt (content=string) 검사
  - telegram-origin 이고 이번 turn 에 reply 툴 호출 0회면 `{"decision":"block","reason":"..."}` 반환
  - `stop_hook_active` 플래그로 무한 루프 방지
  - 6개 시나리오 전부 pipe-test 통과
- `~/.claude/settings.json` `hooks.Stop` 배열 첫 entry 로 추가 (기존 훅 3개 보존)

## 예방 (Forcing function 우선)
- **Forcing function 설치 완료.** 다음 세션부터 동일 실수 시 Stop 훅이 자동 감지 → 모델이 다시 깨어나서 reply 툴 호출하게 함.
- 훅은 `exit 0` 기본값이라 오작동해도 세션 안 깨짐.
- 훅 로그: `/tmp/claude-telegram-reply-check.log` — 여기서 재발 여부 관찰 가능.
- **추가 검증(Mac 피드백, 2026-04-20):** 기존 `telegram-stop-ping.sh` 의 race retry 루프(0.5s × 6회)가 유지되는지, Stop 훅 exit 감지 로직에 failure path 로그가 제대로 찍히고 있는지 한 번 점검. 새 훅이 충돌하거나 막지 않도록.
- **(2026-05-15 강화)** 본 hook 은 jq 의존인데 노드에 jq 미설치면 모든 호출이 silent fail → forcing function 자체가 무력화되는 함정 발견. 신규 챗봇 노드 onboarding 절차에 "jq · bash · curl · python3 등 hook 의존성 한 줄 점검" 단계 명시 필요. 추가로 `mcp-spawn-verify.sh` 또는 SessionStart hook 에 `command -v jq >/dev/null || telegram_warn` 한 줄 박아 부재 즉시 감지하는 자동 게이트가 다음 forcing function (후속 구현 TODO).

## 재발 이력
- **2026-04-20 13:10 KST 사후점검:** 훅 설치 후 3시간 운영 결과
  - `/tmp/claude-telegram-reply-check.log` 37건: `BLOCK` 1건(09:12:08 — 설치 직후 자체 트리거로 forcing function 작동 확인), 나머지 `ok` 또는 무한루프 방지 `skip`
  - BLOCK 직후 곧바로 `ok: reply tool called 1 time(s)` — 차단→재호출 플로우 정상
  - **실전 재발 0건** (동일 사고 발생하지 않음)
  - `telegram-stop-ping.sh` race retry 루프(0.5s×6회) 코드에 유지 확인, failure path 로그 `skip: no assistant text ... after retry` 코드 존재 (최근 0건 기록 = retry 로 대부분 해결됨)
  - 새 훅 `telegram-reply-check.sh` 는 retry 루프 없음 → transcript flush race 시 `skip: no transcript ()` 1건(초기 09:11:52)만 관찰, 이후 정상. 필요시 retry 추가 고려하되 현재는 실무 영향 없음.
- **2026-05-15 23:30 KST 메타 재발 발견.** 노트북(💻) 클로드 세션에서 텔레그램 답변이 폰까지 안 가는 사고. 원인은 노트북에 `jq` 미설치라 본 forcing function (`telegram-reply-check.sh`) 자체가 silent fail — 13건 연속 `skip: no transcript ()`. 즉 옛 예방책이 인프라 의존성 부재로 무력화. system jq 설치로 복구. 데스크탑3060Ti(🖥)도 동일 상태였어서 동시 fix (강대종 콘솔 sudo apt 1회씩). WSL은 SSH 타임아웃이라 후속 점검 대기.
- **2026-05-21 00:35~00:42 KST 본진 한 세션 2회 재발.** 🍎 본진에서 (a) 입력중 데몬 원인 설명, (b) 이슈 보고 두 답변을 reply 툴 없이 터미널 평문으로 먼저 작성 → Stop 훅이 둘 다 정상 block → 재전송. **forcing function 은 작동(전달 보장 OK)**, 다만 block→재전송 왕복 latency 로 강대종이 "여보세요?" / "답변이 안와" 2회 대기. 잔여 gap = correctness 아닌 **latency**. 길고 구조적인 답변일수록 마지막 reply 단계를 빼먹는 옛 "길이 트랩" 패턴 그대로. 강화책: 텔레그램 turn 에서는 **reply 툴 호출을 답변의 첫 substantive 출력으로** 두고, 터미널 평문은 보조로만(또는 생략). 메모리 `feedback_telegram_reply_tool_mandatory` 에 "reply-first" 규율 추가. + 같은 턴에 "죄송합니다"만 하고 재발방지(`feedback_apology_triggers_postmortem`) 자율 진행 안 한 2차 누락 동반 — 사과=즉시 postmortem 트리거 재확인.

- **2026-05-22 ~21:42 KST 본진 4차 재발 + 새 증상(중복버블).** 🍎 본진에서 스튜디오 디스플레이 상담 답변을 reply 툴 없이 터미널 평문으로 먼저 작성 → `telegram-stop-ping.sh` 가 그 텍스트를 `💬 터미널 응답` 으로 포워딩(1번째 버블) + `telegram-reply-check.sh` BLOCK → 다음 turn 에 같은 내용 reply 재송(2번째 버블) = 강대종 화면에 **같은 답 2번**. 5/21 에 넣은 telegram-stop-ping in-turn dedup("이번 turn 에 reply 이미 호출했으면 skip")은 reply 가 같은 turn 이 아니라 BLOCK 후 다음 turn 에 나가서 미작동 — 두 turn 에 갈리면 못 막음. 5/21 강화책("reply-first")이 이번에도 안 지켜진 재발. 강대종 결정(msg 22234)=습관 교정으로 기록.

## 예방 강화 (2026-05-22 4차 재발 후)
- 행동 규율("reply-first")만으로 4회 재발 → 사람 의지 의존 FF 의 한계 재확인.
- **더 센 코드레벨 FF (제안, GO 대기):** `telegram-stop-ping.sh` 에 "last_user 가 telegram-origin(`plugin:telegram:telegram` substring 포함)이면 터미널 포워딩 자체 skip" 가드 추가. 그러면 본진이 또 터미널 먼저 써도 중복버블 불가 — telegram-reply-check 가 reply 를 강제하므로 단일 전달만 남음. (substring grep 은 jq 따옴표 이스케이프 무관하게 매칭 → 5/21 의 `source=` 오진단 회피.)
- 단 5노드 md5 공용훅 + 5/21 이 훅 고치다 1차 오진단 전력(`2026-05-21-hook-matching-too-loose-2x.md`) → 양방향 검증(positive: telegram turn skip / negative: /loop·터미널 turn 은 포워딩 유지) + 강대종 GO 후 출하. 현재 GO 대기(msg 22232 질문), 강대종은 이번 라운드 **습관교정** 선택.

## 관련 링크
- 훅 파일: `~/.claude/hooks/telegram-reply-check.sh`, `~/.claude/hooks/telegram-stop-ping.sh`
- 관련 이슈: `2026-05-21-hook-matching-too-loose-2x.md` (in-turn dedup 도입)
- 설정 변경: `~/.claude/settings.json` `hooks.Stop` 첫 번째 entry
- 메모리: `feedback_telegram_reply_tool_mandatory.md`
- 텔레그램 메시지 id: 931 (사용자 지적), 932 (재전송), 933 (원인 요청), 935 (자가분석), 942 (훅 설치 완료)
