analyst-technical wrapper 오탐 수정 및 4개 analyst 상태 점검
결론
analyst-technical은 실제 분석과 market 섹터 텔레그램 발송이 성공했지만, wrapper가 latest.json 존재만 성공 조건으로 보면서 실패 DM을 보낸 오탐이었다.
수정 완료:
- /Users/ron/.hermes/workspace/scripts/analyst_runner.sh
- 백업: /Users/ron/.hermes/workspace/scripts/analyst_runner.sh.bak-technical-wrapper-20260415163642
- analyst-technical/latest.json도 실제 성공 산출물인 2026-04-14.json에서 복구 완료.
1. wrapper 기존 판정 로직
기존 로직은 실행 후 다음 순서로 판단했다.
RESULT_FOUND=$(grep -q '"type":"result"' "$LOG_FILE" && echo yes || echo no)
HISTORY_FILE="$MEMORY_DIR/latest.json"
if result 있음 && latest.json 있음 -> 성공
elif latest.json 있음 -> 경고
else -> 실패 DM 발송
문제점:
1. $LOG_FILE은 누적 로그라 과거 result가 섞인다.
2. result의 is_error / subtype을 보지 않는다.
3. 성공 산출물이 날짜 파일만 있고 latest.json이 없으면 실패로 오판한다.
4. 반대로 latest.json이 있으면 Claude가 error_max_budget_usd로 끝나도 성공으로 오판한다.
2. analyst-technical 실패 마커의 실제 원인
마지막 실패 DM 기록:
1776238230 ⚠️ Analyst technical 실행 실패 (exit: 0). 로그 확인 필요.
실제 technical 로그 근거:
[SECTOR_TRACE] send_sector(market) ... '<b>📊 테크니컬 | 4월 14일</b> ...'
sent: True
최종 Claude result도 성공이었다.
subtype=success, is_error=False
result='테크니컬 애널리스트 v4.0 실행 완료 ... 텔레그램: market 섹터 발송 완료'
그런데 산출물은 아래 파일만 있었다.
/Users/ron/.hermes/workspace/memory/analyst-technical/2026-04-14.json
latest.json이 없어서 wrapper가 exit: 0인데도 실패로 판단했다.
3. 수정 내용
수정 파일:
/Users/ron/.hermes/workspace/scripts/analyst_runner.sh
핵심 변경:
- 실행 시작 시각 기록: RUN_START_EPOCH
- 누적 로그가 아니라 이번 실행의 analyst_<type>_output.log만 파싱
- type=result의 subtype/is_error로 성공·실패 판단
- 성공 result가 있고 실행 중 새 날짜 JSON이 생성되면 latest.json으로 동기화
- error_max_budget_usd 같은 result error는 latest.json 존재와 무관하게 실패로 기록
Diff 요약:
+RUN_START_EPOCH=$(date +%s)
+
+# 이번 실행의 result 이벤트만 판정한다. 누적 로그는 과거 성공/실패가 섞여 오탐을 만든다.
+RUN_RESULT_STATUS=$(python3 - "$CLAUDE_OUTPUT" <<'PY'
+...
+ if obj.get("is_error") is False and subtype == "success":
+ status = "success"
+ elif obj.get("is_error") is True or subtype.startswith("error"):
+ status = "error"
+...
+PY
+)
+
+RECENT_HISTORY_FILE=$(python3 - "$MEMORY_DIR" "$RUN_START_EPOCH" <<'PY'
+...
+ for path in memory_dir.glob("*.json"):
+ if path.name == "latest.json" or path.name.endswith(".critic.json"):
+ continue
+ if path.stat().st_mtime >= start_epoch:
+ files.append(path)
+...
+PY
+)
+
+if [ "$RUN_RESULT_STATUS" = "success" ]; then
+ if [ -n "$RECENT_HISTORY_FILE" ] && [ -f "$RECENT_HISTORY_FILE" ]; then
+ cp -p "$RECENT_HISTORY_FILE" "$HISTORY_FILE"
+ log "Synced latest.json from $(basename "$RECENT_HISTORY_FILE")"
+ fi
+ ... success ...
+elif [ "$RUN_RESULT_STATUS" = "none" ] && [ -f "$HISTORY_FILE" ]; then
+ ... warning only ...
+else
+ ... failure ...
+fi
4. 검증 결과
구문 검증
bash -n /Users/ron/.hermes/workspace/scripts/analyst_runner.sh
=> 통과
판정 로직 재적용 검증
실제 오늘 실행 로그의 마지막 result에 새 판정 로직을 적용했다.
| analyst | result subtype | is_error | 새 wrapper 판정 |
|---|---|---|---|
| technical | success | false | success |
| macro | success | false | success |
| fundamental | error_max_budget_usd | true | error |
| pm | success | false | success |
technical 최신 산출물 탐색도 정상이다.
technical_recent_history=2026-04-14.json
technical latest 복구
/Users/ron/.hermes/workspace/memory/analyst-technical/latest.json
검증값:
exists=True
date=2026-04-14
executed_at=2026-04-15T16:30:00+09:00
telegram_sent=True
로그에 복구 기록 추가:
[2026-04-15 16:38:47] Reconciled latest.json from 2026-04-14.json after wrapper false-positive
실제 전체 analyst 재실행은 하지 않았다. 이유는 이미 16:25~16:32에 실제 launchd 실행이 완료됐고, 재실행하면 같은 market 섹터 리포트가 중복 발송될 수 있기 때문이다. 대신 실제 실행 로그의 result JSON을 새 판정 로직으로 재적용해 오탐이 제거되는 것을 확인했다.
5. 4개 analyst 상태
| analyst | launchd 상태 | Claude 결과 | 산출물 | 텔레그램 증거 | 최종 판단 |
|---|---|---|---|---|---|
| macro | not running, last exit 0 | success, is_error=false |
2026-04-15.json, latest.json 갱신 |
latest.json.telegram_sent=true, 결과 로그에 텔레그램 보고 완료 기록 |
정상 완료 |
| fundamental | not running, last exit 0 | error_max_budget_usd, is_error=true, exit 1 |
2026-04-15.json, latest.json 생성됐지만 telegram_sent=false |
발송 완료 증거 없음. 중간에 shared.telegram import 경로 실패 후 예산 초과 |
실패/부분 산출. 별도 복구 필요 |
| technical | not running, last exit 0 | success, is_error=false |
2026-04-14.json, latest.json 복구 |
send_sector(market) ... sent: True |
wrapper 오탐 수정 완료 |
| pm | not running, last exit 0 | success, is_error=false |
2026-04-15.json, latest.json 갱신 |
send_sector(market) ... sent: True, telegram_sent updated |
정상 완료 |
6. 추가 발견
fundamental은 이번 수정으로 다음 실행부터 실패로 제대로 판정된다. 현재 남은 실제 문제는 wrapper가 아니라 fundamental prompt 실행 중 다음 두 가지다.
- Hermes 내부에서
send_sectorimport 경로가 흔들림. - 그 뒤 MCP/재시도 중
max_budget_usd초과로 종료됨.
이 작업 범위에서는 wrapper 오탐 수정과 4개 상태 판정까지만 수행했고, fundamental prompt/텔레그램 경로 수정은 별도 작업으로 분리하는 것이 안전하다.
7. 변경 파일
수정:
/Users/ron/.hermes/workspace/scripts/analyst_runner.sh
복구/갱신:
/Users/ron/.hermes/workspace/memory/analyst-technical/latest.json
/Users/ron/.hermes/logs/analyst_technical.log
백업:
/Users/ron/.hermes/workspace/scripts/analyst_runner.sh.bak-technical-wrapper-20260415163642
자체평가
- 정확성: 4.6/5 — technical 오탐 원인과 fundamental 반대 오탐을 모두 확인하고 wrapper 판정을 result 기반으로 수정.
- 완성도: 4.4/5 — technical은 복구 완료. fundamental 자체 실패는 별도 복구 필요.
- 검증: 4.3/5 — bash 구문 검증, 실제 로그 기반 판정 재적용, latest 산출물 검증 완료. 중복 발송 리스크 때문에 전체 재실행은 생략.
- 최소 변경: 4.8/5 — wrapper 판정 블록과 technical latest 복구만 수행.
종합: 4.5/5