virtual-insanity
← 리포트 목록

macro analyst 데이터 신선도 추적·복구

2026-04-24 macro [macro, analyst, freshness, hermes, cron]

결론

원인은 2개였다.

  1. 스케줄 순서 역전: macro_collector.py는 06:50, macro analyst는 07:00에 돌지만 market_indicator_tracker.py 첫 정기 실행은 07:05라서 아침 macro가 최신 market-indicators를 받지 못했다.
  2. latest.json 본문 미동기화: macro_redesign_report.py가 텔레그램 본문은 새로 만들었지만 latest.json.summary/body에 쓰지 않아, Claude가 만든 이전 요약 문구인 2026-04-22 종가 기준이 남았다. 추가로 WTI 헤드라인은 oil_supply_monitor의 가격 provenance 2026-04-17을 우선해 stale 숫자가 노출됐다.

복구 후 상태: latest.json2026-04-24T12:54:13+09:00에 재생성됐고, 본문 첫 줄은 WTI 96.49(2026-04-23 market-indicators) 기준으로 바뀌었다.

데이터 흐름

market_indicator_tracker.py
  -> ~/.hermes/workspace/memory/market-indicators/YYYY-MM-DD.json
  -> macro_collector.py / vault_macro_bridge.load_indicator_data()
  -> ~/.hermes/workspace/memory/analyst-context/context-macro.json
  -> analyst_runner.sh macro
  -> ~/.hermes/workspace/memory/analyst-macro/latest.json
  -> macro_redesign_report.py
  -> Telegram market topic + latest.json summary/body/telegram_msg 동기화

macro_series_collector.py
  -> ~/.hermes/workspace/memory/macro-timeseries/*.json
  -> macro_collector.py real_economy/FRED block

oil_supply_monitor.py
  -> ~/.hermes/workspace/memory/oil-supply-monitor/state.json
  -> macro_collector.py oil_supply block

조사 증거

Before

  • ~/.hermes/workspace/memory/analyst-macro/latest.json
  • mtime: 2026-04-24 07:00:27
  • as_of: 2026-04-24
  • generated_at: 2026-04-24T07:00:27+09:00
  • summary: 2026-04-22 종가 기준...으로 시작
  • Hermes cron:
  • ocRESTORE-vault-macro-bridge: 50 6 * * 1-5
  • analyst-macro: 07:00 실행 경로
  • ocRESTORE-market-indicator-tracker: 5 7,9,11,13,15,17 * * 1-5
  • 즉, 06:50/07:00 macro가 07:05 market 수집보다 먼저 실행됨.

입력 파일 상태

수동 재수집 후 확인값:

market-indicators/2026-04-24.json
  collected_at: 2026-04-24T12:42:29
  indicators_count: 87

context-macro.json
  date: 2026-04-24
  market.date: 2026-04-24
  WTI:   96.49 / data_date 2026-04-23
  BRENT: 105.8 / data_date 2026-04-23
  DXY:   98.91 / data_date 2026-04-23
  US10Y: 4.32 / data_date 2026-04-23
  VIX:   19.31 / data_date 2026-04-23

oil_supply_monitor는 별도 참고 입력으로 남아있지만 가격 provenance가 더 낡았다.

oil-supply-monitor/state.json
  mtime: 2026-04-24 06:07:56
  last_run: 2026-04-23T21:07:56
  wti: 97.19 / provenance date 2026-04-17 / source yfinance CL=F

수정 내용

1) macro_redesign_report.py 패치

파일: /Users/ron/.hermes/workspace/scripts/macro_redesign_report.py 백업: /Users/ron/.hermes/workspace/scripts/macro_redesign_report.py.bak-macro-freshness-20260424

변경 라인:

  • 137-144: context_market_date() 추가 — context의 market snapshot date를 latest.json data_date로 사용.
  • 160-164: html_to_plain_text() 추가 — Telegram HTML 본문을 latest.json용 plain text로 변환.
  • 230-257: oil_indicator() 수정 — WTI/Brent는 oil_supply_monitor보다 market-indicators가 최신이면 최신값을 우선.
  • 528-560: atomic_update() 수정 — 발송 성공 시 summary, body, telegram_msg, data_date, macro_redesign.data_date를 함께 갱신.
  • 606: atomic_update(..., ctx) 호출로 context 전달.

2) 사전 market 수집 크론 추가

파일: /Users/ron/.hermes/cron/jobs.json 백업: /Users/ron/.hermes/cron/jobs.json.bak-macro-freshness-20260424T124157

신규 job:

{
  "id": "ocRESTORE-macro-market-precollector",
  "name": "macro-market-precollector",
  "enabled": true,
  "schedule": "40 6 * * 1-5",
  "command": "PYTHONPATH=/Users/ron/.hermes/workspace/scripts /usr/bin/python3 /Users/ron/.hermes/workspace/scripts/pipeline/market_indicator_tracker.py"
}

의도: 06:40에 무알림 market 수집을 먼저 돌려 06:50 macro_collector.py와 07:00 macro analyst가 최신 전일 종가를 받게 함. 기존 07:05/09/11/13/15/17 알림용 job은 그대로 유지.

3) 04-25 새벽 모니터 등록

신규 파일: /Users/ron/.hermes/workspace/scripts/pipeline/macro_freshness_monitor.py

생성 산출물:

  • /Users/ron/knowledge-agent/600-data/20260424_macro_freshness_monitor.json
  • /Users/ron/knowledge-agent/600-data/20260424_macro_freshness_monitor.md

Hermes one-time monitor job:

{
  "id": "ocRESTORE-macro-freshness-monitor-260425",
  "name": "macro-freshness-monitor-260425",
  "enabled": true,
  "schedule": "30 7 25 4 *",
  "command": "PYTHONPATH=/Users/ron/.hermes/workspace/scripts /usr/bin/python3 /Users/ron/.hermes/workspace/scripts/pipeline/macro_freshness_monitor.py --date 2026-04-25 --min-data-date 2026-04-23"
}

백업: /Users/ron/.hermes/cron/jobs.json.bak-macro-monitor-20260424T125521

수동 재실행 결과

실행한 순서

cd /Users/ron/.hermes/workspace
PYTHONPATH=/Users/ron/.hermes/workspace/scripts /usr/bin/python3 /Users/ron/.hermes/workspace/scripts/pipeline/market_indicator_tracker.py
PYTHONPATH=scripts:scripts/pipeline python3 scripts/pipeline/macro_collector.py

cd /Users/ron/.hermes/workspace/scripts
ANALYST_COMMON_PRINT_BODY=1 ./analyst_common_wrapper.sh macro
ANALYST_COMMON_PRINT_BODY=1 python3 macro_redesign_report.py \
  /Users/ron/.hermes/workspace/memory/analyst-macro/latest.json \
  /Users/ron/.hermes/logs/analyst_macro_last_telegram.tsv \
  /Users/ron/.hermes/logs/analyst_macro_common_wrapper.log

검증값

latest.json
  as_of: 2026-04-24
  generated_at: 2026-04-24T12:54:13+09:00
  data_date: 2026-04-24
  macro_redesign.message_id: 2788
  macro_redesign.summary_synced_from_body: true
  data_vintage_by_source.WTI: 2026-04-23
  data_vintage_by_source.US10Y: 2026-04-23

본문 prefix:

🌍 매크로 브리핑
📌 헤드라인 WTI 96.49(2026-04-23 market-indicators) 기준...
📊 데이터 기준: WTI=04-23 / DXY=04-23 / US10Y=04-23 / latest=04-24 12:53

Telegram 도달 로그:

2026-04-24T12:54:13 OK message_id=2788 sector=market chat_id=-1003522748967 topic_id=5

모니터 드라이런:

{"ok": true, "json": "/Users/ron/knowledge-agent/600-data/20260424_macro_freshness_monitor.json", "md": "/Users/ron/knowledge-agent/600-data/20260424_macro_freshness_monitor.md", "stale_hits": 0}

Hermes 확인:

ocRESTORE-macro-market-precollector [active]
ocRESTORE-macro-freshness-monitor-260425 [active]
Gateway is running — cron jobs will fire automatically

Before → After

항목 Before After
latest.json mtime 2026-04-24 07:00:27 2026-04-24 12:54:13
latest.json summary 시작 2026-04-22 종가 기준... WTI 96.49(2026-04-23 market-indicators) 기준...
context market.date 2026-04-23 2026-04-24
WTI data_date 2026-04-23 available but summary stale 2026-04-23 explicitly shown
summary/body 저장 summary만 stale summary/body/telegram_msg 동기화
사전 수집 없음 06:40 무알림 market precollector

잔존 리스크

  • oil_supply_monitor의 가격 provenance는 여전히 2026-04-17로 낡다. 이번 패치로 macro 헤드라인은 최신 market-indicators 가격을 우선하므로 사용자 노출 문제는 막았지만, oil monitor 자체 freshness는 별도 점검 대상이다.
  • 04-25는 토요일이라 weekday macro 정기 job은 돌지 않을 수 있다. 그래서 one-time monitor는 “stale 문구 재발 여부”를 확인하도록 등록했다.
  • 이번 수동 재실행 과정에서 검증용 market topic 메시지 2건이 추가 발송됐다: 2787, 2788. 최종 유효본은 2788이다.

자체평가

  • 정확성: 4.6/5 — stale 원인 2개를 실측으로 분리했고, latest.json 본문과 입력 데이터 기준을 실제 갱신했다.
  • 완성도: 4.5/5 — 스케줄 보정, 코드 패치, 수동 재실행, 모니터 등록까지 완료. oil monitor 자체 freshness는 별도 리스크로 남김.
  • 검증: 4.7/5 — py_compile, 수동 수집, context 확인, analyst 재발송, TSV message_id, monitor dry-run 확인.
  • 최소 변경: 4.4/5 — macro 출력 동기화와 freshness 선택 로직에 국한. 신규 precollector/monitor는 운영 재발 방지 목적.

종합: 4.55/5