virtual-insanity
← 리포트 목록

시장지표 수집 크론(market-indicator-tracker) 8/16 정지 원인과 재가동 승인요청안

2026-09-28 hermes [ops, cron, market-indicators, 재가동승인요청]

시장지표 수집 크론 정지 원인과 재가동안 (조사 2026-09-28 08:40~08:46 KST, Ron 대행)

한 줄 결론

429(사용한도 초과)는 수집 스크립트가 아니라 크론 실행기가 "빈 프롬프트로 AI 에이전트를 깨우는 경로"에서 난 것이다. 스크립트 자체에는 모델 호출이 없고, 오늘 직접 돌려보니 29초 만에 정상 종료(exit 0)했다. 그래서 크론을 "스크립트 전용(no_agent)"으로 바꿔 다시 켜면 모델 한도와 무관하게 돌 수 있다.

1. 사실 (실측)

1-1. 라이브 장부의 잡 상태 — /Users/ron/.hermes/cron/jobs.json

  • id ocRESTORE-market-indicator-tracker, enabled=false, state=paused, paused_at=2026-08-17T13:31:43
  • last_run_at=2026-08-16T07:05:43.508583+09:00, last_status=error
  • last_error=RuntimeError: HTTP 429: {"error":{"type":"usage_limit_reached",...,"plan_type":"prolite","resets_at":1787196898,...}} (리셋 시각 = 2026-08-20 12:34:58 KST — 이미 지남)
  • 일정 5 7,16 * * * (Asia/Seoul)
  • 실행 필드가 옛 형식: "command": "PYTHONPATH=... python3 .../market_indicator_tracker.py --notify", "prompt": "", script 없음, no_agent 필드 없음
  • /Users/ron/.hermes/cron/executions.db에는 이 잡 실행 기록 0건

1-2. 같은 잡의 옛 컷오버 장부 — /Users/ron/.hermes-next/cron/jobs.json (정지 장부)

  • 같은 id가 enabled=true, no_agent=true, script=migrated/ocRESTORE-market-indicator-tracker.sh, last_run_at=2026-08-16T07:05:36, last_status=ok
  • /Users/ron/.hermes-next/cron/executions.db: completed | 2026-08-16T07:05:07
  • 래퍼 /Users/ron/.hermes-next/scripts/migrated/ocRESTORE-market-indicator-tracker.sh가 존재(7/19 생성). /Users/ron/.hermes/scripts/migrated/에는 이 래퍼가 없다.

1-3. 429가 어디서 났나 — 코드 행 번호로 구분

(a) 수집 스크립트 /Users/ron/.hermes/workspace/scripts/pipeline/market_indicator_tracker.py (2380행): 모델 호출 없음 - 임포트는 표준 라이브러리 + shared.log(25행) + shared.telegram(26행 from shared.telegram import () + 함수 내부 지연 임포트 yfinance(266행 등), requests(489행 등), shared.fred_client.FredClient(819행, 901행), matplotlib(1737행)뿐. llm/anthropic/openai/HERMES_GATEWAY 문자열 0건(grep). - 19행 import subprocess는 있으나 subprocess. 호출은 0건. - 오늘 직접 실행: PYTHONPATH=/Users/ron/.hermes/workspace/scripts /usr/bin/python3 scripts/pipeline/market_indicator_tracker.py --dry-run → exit 0, 29초, 출력에 usage_limit/HTTP 429 0건(1328행 출력, 사본 /Users/ron/.hermes/workspace/logs/market_indicator_tracker_dryrun_260928.out). 요약줄 [2026-09-28 08:44:44] Summary: 미국 10년물 5.18 .... - 8/16 당일 스크립트 로그 /Users/ron/.hermes/workspace/logs/market_indicator_tracker.log 49959행대: [2026-08-16 07:05:36] Saved: 2026-08-16.json — 스크립트는 같은 시각 정상 저장했다.

(b) 크론 래퍼(에이전트 모드): 여기서 429 - 실패 출력 /Users/ron/.hermes/cron/output/ocRESTORE-market-indicator-tracker/2026-08-16_07-05-43.md: ## Prompt에 크론 공통 안내문만 있고 명령 실행 흔적 없이 ## Error RuntimeError: HTTP 429 ... prolite. 8/13 성공분(2026-08-13_07-06-03.md)도 응답이 [SILENT] 한 줄 — 즉 이 잡은 원래부터 스크립트를 돌린 적이 없고, 빈 프롬프트로 AI만 깨웠다. - 현행 실행기 코드: /Users/ron/.hermes/hermes-agent/cron/scheduler.py 1949~1950행 if job.get("no_agent"): return _run_no_agent_job(...) — no_agent가 없으면 에이전트 경로로 간다. 실행기 cron 코드 어디에도 command 필드를 읽는 곳이 없다(grep "get(\"command\")" cron/ → 0건, 유일 매치 2163행은 ACP 런타임용). - 같은 파일 cron/jobs.py 429~436행 job_payload_is_empty: 프롬프트 공백 + script 없음이면 현행 실행기는 이 잡을 "실행할 게 없음"으로 자동 일시정지시킨다. 즉 지금 상태 그대로 켜면 429 이전에 바로 다시 멈춘다.

정리: 8/16까지 실제 수집은 ~/.hermes-next 스케줄러의 no_agent 래퍼가 했고, ~/.hermes 쪽 동명 잡은 빈 에이전트 호출만 하다 429를 맞았다. 8/16~17 롤백으로 ~/.hermes-next 스케줄러가 멈추자 실제 수집 경로가 사라졌다. 이후 memory/market-indicators/ 파일(08-17, 08-28~09-02, 09-07)과 로그 마지막 줄([2026-09-08 03:29:25])은 수동/부수 실행분으로 보이며 정기 수집이 아니다.

2. 스크립트 전용으로 돌릴 수 있나 → 가능

  • 스크립트는 결정적 코드(야후/FRED/한경/네이버 조회 + 저장 + 텔레그램)이고 모델이 필요 없다.
  • 선례: 같은 장부의 fi-morning-brief가 no_agent=true, script=migrated/fi-morning-brief.sh로 오늘 07:11:48 ok.
  • 유의점: --notify는 이상치 발생 시 텔레그램 섹터 방으로 발송(2160행 인자 정의, 1655행 send_*). 재가동 시 알림도 재개된다. 알림을 원치 않으면 래퍼에서 --notify만 빼면 된다.

3. BAMLC0A0CM.json 갱신 경로와 겹침 여부

  • 실제 작성자: 크론 fi-morning-brief(평일 07:10, enabled=true, no_agent=true) → 래퍼 /Users/ron/.hermes/scripts/migrated/fi-morning-brief.sh 10행 for sid in DGS2 ... BAMLC0A0CM BAMLH0A0HYM2 BAMLEMCBPIOAS; do → scripts/pipeline/macro_series_collector.py --series <id> → save_series()(283~289행) → memory/macro-timeseries/BAMLC0A0CM.json 원자 저장. 오늘 파일 last_updated=2026-09-28, 최신 데이터 2026-09-24 0.79.
  • 전체 46종 수집 크론 macro-series-collector(평일 06:50)는 enabled=false, 마지막 2026-08-14. 그래서 macro-timeseries/ 51개 파일 중 11개만 오늘 갱신되고 38개는 08-14에 멈춰 있다(별도 이슈, 아래 5절).
  • 시장지표 트래커는 BAMLC0A0CM을 FRED에서 직접 읽어(882행 "IG_SPREAD": {"series": "BAMLC0A0CM", ...}, 894행 fetch_fred_methodology_indicators, 2276행 호출) memory/market-indicators/<날짜>.json 안의 IG_SPREAD로만 저장한다. macro-timeseries/에는 쓰지 않는다.
  • 결론: 같은 원천(FRED)을 읽지만 쓰는 파일이 달라 충돌은 없다. 중복 호출은 하루 몇 건 수준이라 FRED 한도 문제도 없다.

4. 재가동안 (해리 승인 후 실행 — 지금은 미실행)

  1. 백업: cp /Users/ron/.hermes/cron/jobs.json /Users/ron/.hermes/cron/jobs.json.bak-260928-mit-restart
  2. 래퍼 복사: cp /Users/ron/.hermes-next/scripts/migrated/ocRESTORE-market-indicator-tracker.sh /Users/ron/.hermes/scripts/migrated/ (내용: cd /Users/ron/.hermes/workspace 후 PYTHONPATH=... python3 .../market_indicator_tracker.py --notify >/dev/null)
  3. 잡 수정(해당 id만): script="migrated/ocRESTORE-market-indicator-tracker.sh", no_agent=true, workdir="/Users/ron/.hermes/workspace", enabled=true, state="scheduled", paused_at=null, last_error=null. command/prompt 필드는 그대로 둔다.
  4. 검증: 다음 회차(07:05 또는 16:05) 후 sqlite3 /Users/ron/.hermes/cron/executions.db "SELECT status,started_at FROM executions WHERE job_id='ocRESTORE-market-indicator-tracker' ORDER BY started_at DESC LIMIT 1" → completed, 그리고 ls /Users/ron/.hermes/workspace/memory/market-indicators/ 에 당일 파일 생성, 로그에 Saved: 줄 확인.
  5. 즉시 공백 메우기는 승인과 별개로 스크립트 1회 수동 실행으로 가능(--notify 없이 실행하면 알림 없이 파일만 생성).

5. 되돌리는 방법

  • 가장 간단: 해당 잡만 enabled=false, state="paused"로 되돌림.
  • 전체 원복: cp /Users/ron/.hermes/cron/jobs.json.bak-260928-mit-restart /Users/ron/.hermes/cron/jobs.json 후 복사한 래퍼 삭제(/Users/ron/.hermes/scripts/migrated/ocRESTORE-market-indicator-tracker.sh).
  • 재가동 후 텔레그램 알림이 과하면 래퍼에서 --notify만 제거.

6. 함께 보고할 연관 이슈 (승인 대상 아님, 참고)

  • macro-series-collector(46종) 08-14 이후 정지 → 38개 시리즈 정체. 같은 원인(옛 command 형식 + no_agent 없음)인지 동일 방식으로 확인 필요.
  • 라이브 장부 shell 잡 121개 중 no_agent=true는 19개뿐 — 같은 "옛 command 필드만 있고 실행기가 안 읽는" 잡이 더 있을 수 있다. 전수 점검 후보.