virtual-insanity
← 리포트 목록

analyst-technical wrapper 오탐 수정 및 4개 analyst 상태 점검

2026-04-15 fix [phase17, launchd, analyst, wrapper, telegram]

결론

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. resultis_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=resultsubtype/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 실행 중 다음 두 가지다.

  1. Hermes 내부에서 send_sector import 경로가 흔들림.
  2. 그 뒤 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