증상
Slack에서 오래 걸리는 요청이 실제 실행 상태와 다르게 응답 없음으로 먼저 보이면, 사용자는 작업이 중간에 끊겼거나 실패했다고 판단한다.
2026-09-10 KST의 #squad_hellobot_product_b 사례에서 같은 스레드에 다음 순서가 관찰됐다.
요청 수신: 이 스레드에서 이수지가 언급한 내용만 모아서 요구사항 빠지지 말고 모아봐.
두 번째 동일 요청 수신
jaw:kill reason=steer ...
jaw:main exited code=143, text=0 chars
slack:out ... 응답 없음
이후 재개된 Claude 실행이 계속 tool call/thinking을 수행
result: $3.1547 / 35 turns / 498.2s
jaw:main exited code=0, text=1712 chars
Slack 화면에는 뉴 [오후 12:08] 응답 없음이 남아, 실제로는 재개된 실행이 결과를 만들고 있었던 사실이 보이지 않는다. 이후 다른 주체가 결과를 올리면서 원래 요청이 실패한 것처럼 보인다.
이 사례 자체는 300초 watchdog 발화로 단정할 수 없다. 첫 실행은 약 70초 뒤 새 요청의 steer로 중단됐고, 재개 실행은 498.2초 뒤 정상 종료했다. 다만 300초 이상 걸릴 수 있는 실행에서 동일한 표시가 발생하면 같은 오해를 만든다. 현재 워치독 기본 absoluteMs는 600초이며, 설정에서 별도 값을 주지 않은 현장 인스턴스에서는 300초 초과가 곧 watchdog 발화라는 뜻도 아니다.
문제
응답 없음이 terminal outcome인지, steer로 이전 실행이 교체된 것인지, watchdog timeout인지 Slack에서 구분되지 않는다.
- 실행이 재개되거나 최종 결과가 뒤따를 수 있는데도
응답 없음이 최종 실패 메시지처럼 노출된다.
- 300초 이상 걸리는 조사형 요청은 정상 범위일 수 있어, 시간 경과와 현재 상태를 보여주지 않으면 실행 중인 작업을 재요청하게 된다.
관련 구현:
src/agent/error-classifier.ts:79-86은 stall reason을 사용자 메시지 ⏱️ 응답 없음 — ...으로 변환한다.
src/agent/lifecycle-handler.ts:719-762는 부분 출력이 watchdog으로 잘린 경우를 별도로 표시하려는 경로를 둔다.
src/agent/lifecycle-handler.ts:816-847는 watchdog kill을 오류 결과로 전달한다.
제안
- Slack의 중간 상태와 terminal outcome을 분리한다.
- 300초 경과 시에는
⏳ 5분째 작업 중 — 아직 실행 중입니다처럼 진행 중임을 표시하고, 실제 중단 시에만 terminal 메시지를 보낸다.
- 실제 watchdog timeout은
⏱️ 5분 제한으로 중단했습니다처럼 원인을 직접 표시한다.
- steer/requeue/resume은
↪️ 새 요청으로 전환해 이전 실행을 중단했습니다처럼 timeout과 구분한다.
- 부분 답변이 있으면 답변 끝에 중단 사실과 경과 시간을 붙이고, Slack에서 잘린 답변처럼 보이지 않게 한다.
- 동일 실행에서
응답 없음을 먼저 보낸 뒤 나중에 성공 결과를 보내는 상태 전이를 금지하거나, 기존 상태 메시지를 갱신해 단일 최종 상태로 보이게 한다.
완료 조건
- 300초를 넘긴 실행이 정상적으로 계속되는 동안
응답 없음이 terminal 실패처럼 보이지 않는다.
- timeout, steer, resume, provider error가 Slack에서 서로 다른 문구로 구분된다.
- 부분 출력이 있는 watchdog 종료는 부분 답변과 중단 이유를 함께 보인다.
- no-output timeout은 실행 중 상태와 최종 timeout 상태를 혼동하지 않는다.
- 위 상태 전이에 대한 lifecycle/Slack forwarding 테스트가 추가된다.
참고
증상
Slack에서 오래 걸리는 요청이 실제 실행 상태와 다르게
응답 없음으로 먼저 보이면, 사용자는 작업이 중간에 끊겼거나 실패했다고 판단한다.2026-09-10 KST의
#squad_hellobot_product_b사례에서 같은 스레드에 다음 순서가 관찰됐다.Slack 화면에는
뉴 [오후 12:08] 응답 없음이 남아, 실제로는 재개된 실행이 결과를 만들고 있었던 사실이 보이지 않는다. 이후 다른 주체가 결과를 올리면서 원래 요청이 실패한 것처럼 보인다.이 사례 자체는 300초 watchdog 발화로 단정할 수 없다. 첫 실행은 약 70초 뒤 새 요청의
steer로 중단됐고, 재개 실행은 498.2초 뒤 정상 종료했다. 다만 300초 이상 걸릴 수 있는 실행에서 동일한 표시가 발생하면 같은 오해를 만든다. 현재 워치독 기본absoluteMs는 600초이며, 설정에서 별도 값을 주지 않은 현장 인스턴스에서는 300초 초과가 곧 watchdog 발화라는 뜻도 아니다.문제
응답 없음이 terminal outcome인지, steer로 이전 실행이 교체된 것인지, watchdog timeout인지 Slack에서 구분되지 않는다.응답 없음이 최종 실패 메시지처럼 노출된다.관련 구현:
src/agent/error-classifier.ts:79-86은 stall reason을 사용자 메시지⏱️ 응답 없음 — ...으로 변환한다.src/agent/lifecycle-handler.ts:719-762는 부분 출력이 watchdog으로 잘린 경우를 별도로 표시하려는 경로를 둔다.src/agent/lifecycle-handler.ts:816-847는 watchdog kill을 오류 결과로 전달한다.제안
⏳ 5분째 작업 중 — 아직 실행 중입니다처럼 진행 중임을 표시하고, 실제 중단 시에만 terminal 메시지를 보낸다.⏱️ 5분 제한으로 중단했습니다처럼 원인을 직접 표시한다.↪️ 새 요청으로 전환해 이전 실행을 중단했습니다처럼 timeout과 구분한다.응답 없음을 먼저 보낸 뒤 나중에 성공 결과를 보내는 상태 전이를 금지하거나, 기존 상태 메시지를 갱신해 단일 최종 상태로 보이게 한다.완료 조건
응답 없음이 terminal 실패처럼 보이지 않는다.참고
응답 없음이 표시되는 상태 전이 UX를 별도로 다룬다.