virtual-insanity
← 리포트 목록

Hermes 시스템 구조 전수조사 (인수인계)

2026-04-24 handover [hermes, system, handover, cron, pipeline, vault]

Hermes 시스템 구조

1. 전체 구조도 (ASCII)

~/hermes-repo/                    # GitHub source of truth
  cron/jobs.json                  # 크론 정의 (72개)
  workspace/scripts/pipeline/     # 파이프라인 소스 (250개+)
  workspace/scripts/shared/       # 공용 유틸 (telegram.py 등)
  workspace/configs/              # 설정 파일
  hermes-agent/                   # 게이트웨이 코어
  skills/                         # 스킬 정의
  scripts/deploy_to_runtime.sh    # 배포 도구
        │
        │  ./scripts/deploy_to_runtime.sh
        │  (rsync, 상태 디렉터리 제외)
        ▼
~/.hermes/                        # 크론 실행 런타임
  cron/jobs.json                  # 실행 중인 크론 (repo와 거의 동일, next_run_at만 차이)
  workspace/scripts/pipeline/     # 배포된 파이프라인 (374개, .bak 포함)
  hermes-agent/                   # 실행 중인 게이트웨이
  config.yaml                     # 런타임 설정
  gateway.pid / gateway_state.json
  data/, logs/, sessions/, memory/, cache/   # 런타임 상태 (배포 시 보존)
        │
        ▼
  hermes gateway (launchd: ai.hermes.gateway, PID 55997)
     └── cron_ticker (jobs.json 자동 리로드)
           ├── 데이터 수집 잡 (16개)
           ├── 채권 잡 (13개)
           ├── 볼트 운영 잡 (11개)
           ├── 분석 잡 (8개)
           ├── 시장 데이터 잡 (5개)
           ├── 원유/에너지 잡 (5개)
           ├── 펀더멘털 잡 (3개)
           ├── 시스템 운영 잡 (2개)
           └── 기타 (9개) — 총 72개

2. 레포 ↔ 런타임 관계

항목
레포 경로 ~/hermes-repo/
런타임 경로 ~/.hermes/
배포 명령 ./scripts/deploy_to_runtime.sh (또는 --dry-run)
동기화 대상 workspace/scripts, workspace/configs, cron, hermes-agent, skills
보존 대상 memory/, logs/, sessions/, reports/, cache/, state/, .env, *.db
현재 차이 next_run_at 타임스탬프만 다름 — 실질적으로 동일
launchd 서비스 ai.hermes.gateway (활성), com.openclaw.hermes-tailer
게이트웨이 기본 모델 gpt-5.4 via codex-proxy (localhost:18642)

배포 절차: hermes-repo에서 수정 → commit → ./scripts/deploy_to_runtime.sh 실행 → launchd 게이트웨이가 변경 감지 후 자동 적용 (cron은 jobs.json 자동 리로드).


3. 크론 카탈로그 요약

카테고리 활성 비활성 대표 잡
데이터 수집 16 0 blog_monitor, twitter_collector, channel_collector, gmail_newsletter
채권/크레딧 13 0 bond_daily_report, bond_market_close, bond_morning_quiz
볼트 운영 9 2 vault120-sync, note-atomizer, vault-architect, vault-flow-health
분석/인텔리전스 7 1 sector_news_scorer, discovery_enricher, signal_synthesizer, hypothesis_lifecycle
시장 데이터 5 0 price_history, market_indicator_tracker, fnguide_snapshot
원유/에너지 5 0 oil_supply_monitor(3회/일), tanker_tracker, refining_tracker
펀더멘털 1 2 dart_edgar_disclosure, (dart/edgar raw financials 비활성)
시스템 운영 2 0 ops_syncer(10분), cron_watchdog
기타 7 2 daeju_trigger(3회), awesome_scout, urea_price_tracker 등
합계 65 7

3.1 주요 잡 디테일 (20개)

bond-daily-report-real-notify

  • 스케줄: 0 9 * * 2-6 (화~토 09:00 KST)
  • 역할: 황대진 채권 메일 파싱 → 3페이지 트레이더 브리핑 생성 → DM 전송
  • 스크립트: bond_daily_report.py

bond-morning-poll-real-gmail-collector

  • 스케줄: 3,33 7-9 * * 1-5 (평일 07~09시 30분 간격)
  • 역할: Gmail에서 채권 메일 폴링 수집 → 119-크레딧메일/ 저장
  • 스크립트: bond_report_parser.py 연동

bond-market-close-briefing

  • 스케줄: 40 15 * * 1-5 (평일 15:40 KST)
  • 역할: bond-briefing/latest.json 읽어 장마감 커브·스프레드 요약 DM (신선도 가드 포함)
  • 스크립트: bond_market_close.py

bond-morning-quiz

  • 스케줄: 30 7 * * 1-5 (평일 07:30)
  • 역할: 어제자 bond-briefing 기반 4지선다 퀴즈 1개 → DM 전송
  • 스크립트: bond_morning_quiz.py

bond-morning-quiz-retry

  • 스케줄: 0 14 * * 1-5 (평일 14:00, 미확인 답변 재발송)
  • 스크립트: bond_morning_quiz.py

bond-evening-concept

  • 스케줄: 0 21 * * * (매일 21:00)
  • 역할: concept_progress 큐에서 pending 개념 1개 → DM
  • 스크립트: bond_evening_concept.py

bond-evening-report-notify

  • 스케줄: 37 22 * * 1-5 (평일 22:37)
  • 역할: 저녁 채권 보고 DM
  • 연동: bond-evening-poll-1900/2030/2200-gmail-collector 3단계 폴링 후 취합

bond-weekly-review / bond-weekly-score

  • 스케줄: 금 19:00 / 월 09:00
  • 역할: 주간 채권 복습 + 퀴즈 성적 집계

글로벌 석유 공급망 모니터 (3회)

  • 스케줄: 0 6,14,21 * * * (일 3회)
  • 역할: 이충재(한투증권) 세미나 기반 임계값으로 글로벌 석유 공급망 체크리스트 실시간 추적
  • 스크립트: oil_supply_monitor.py

tanker-tracker / refining-tracker

  • 스케줄: 매일 06:35 / 06:40
  • 역할: VLCC/클린탱커 해운 프록시 주가 + 정유 가동률 수집, 이상치 감지
  • 스크립트: tanker_tracker.py, refining_tracker.py

batchM-intelligence-blog-monitor

  • 스케줄: 360분 간격 (6시간마다)
  • 역할: 네이버 블로그 RSS 다중 수집 → 인사이트 추출 → 텔레그램
  • 스크립트: blog_monitor.py

twitter-collector

  • 스케줄: 20 6 * * * (매일 06:20)
  • 역할: twikit으로 팔로잉 계정 트윗 수집 → 인게이지먼트 스코어링 → LLM 분석 → 리포트
  • 출력: ~/knowledge-agent/100-inbox/112 twitter-reports/

channel-collector (118 텔레그램)

  • 스케줄: 17 3,9,15,21 * * * (일 4회)
  • 역할: 루팡·인포마켓·승도리 채널 수집 → 볼트 노트
  • 스크립트: channel_collector.py

analyst-channel-collector

  • 스케줄: 45 7,13 * * 1-5 (평일 2회)
  • 역할: 증권사 애널리스트 텔레그램 채널 → 116 croned_data/섹터/ 마크다운
  • 스크립트: analyst_channel_collector.py

macro-series-collector

  • 스케줄: 50 6 * * 1-5 (평일 06:50)
  • 역할: FRED 46개 시리즈 수집 (크레딧 스프레드, 금융조건지수, 금리, 인플레이션, 고용 등)
  • 출력: memory/macro-timeseries/{SERIES_ID}.json

fed-liquidity-aggregator

  • 스케줄: 0 7 * * * (매일 07:00)
  • 역할: 연준 순유동성 = WALCL - RRPONTSYD - WTREGEN 계산·국면 판단
  • 스크립트: fed_liquidity_aggregator.py

gmail-newsletter-collector

  • 스케줄: 47 6 * * * (매일 06:47 KST)
  • 역할: 구독 뉴스레터 Gmail 수집 → LLM 요약 → 121 뉴스레터/ 저장
  • 스크립트: gmail_newsletter_collector.py

vault120-sync

  • 스케줄: */30 * * * * (30분마다)
  • 역할: ~/knowledge/120 지식사랑방/~/knowledge-agent/100-inbox/ 단방향 싱크

note-atomizer (phase-200)

  • 스케줄: 37 2,14 * * * (하루 2회)
  • 역할: 100-inbox 노트 → 200-atomic 분해·구조화

ops-syncer

  • 스케줄: */10 * * * * (10분마다)
  • 역할: 게이트웨이 운영 상태 동기화

4. 파이프라인 스크립트 그룹

총 250개 (레포 기준), 374개 (런타임, .bak 포함)

4.1 채권/크레딧 교육

파일 용도
bond_daily_report.py 황대진 채권 메일 → 3페이지 브리핑 생성 + DM
bond_market_close.py 장마감 커브·스프레드 요약 DM
bond_morning_quiz.py 아침 퀴즈 4지선다 생성 + 발송
bond_evening_concept.py 채권 개념어 큐에서 1개씩 저녁 발송
bond_report_parser.py Gmail 메일 HTML → 구조화 JSON (정규식, LLM 없음)
bond_weekly_review.py 주간 채권 복습 리포트
bond_weekly_score.py 퀴즈 성적 집계 DM
bond_monthly_exam.py 월말 종합 시험

4.2 원유/에너지

파일 용도
oil_supply_monitor.py 글로벌 석유 공급망 체크리스트 (임계값 기반)
mideast_oil_collector.py popular_posts DB에서 중동 지정학/에너지 메시지 수집
tanker_tracker.py VLCC/클린탱커 해운 프록시 주가 + 이상치 감지
refining_tracker.py 정유 가동률 + EIA 데이터 수집
urea_price_tracker.py 요소 가격 주간 추적
copper_market_collector.py 구리 선물 커브 + 상하이 재고 수집

4.3 데이터 수집 (외부 소스)

파일 용도
blog_monitor.py 네이버 블로그 RSS 다중 수집 → 인사이트 추출
twitter_collector.py X/Twitter 팔로잉 계정 수집 → 인게이지먼트 스코어링
channel_collector.py 텔레그램 투자 인사이트 채널 수집 (공개+비공개)
nepcon_collector.py 네이버 프리미엄 콘텐츠(네프콘) 산업 뉴스
ingest_telegram_realtime.py 텔레그램 채널 실시간 수집 → 볼트 저장
gmail_newsletter_collector.py Gmail 뉴스레터 수집 → LLM 요약 → 볼트
analyst_channel_collector.py 증권사 애널리스트 텔레그램 채널 수집

4.4 거시/시장 데이터

파일 용도
macro_series_collector.py FRED 46개 시리즈 수집
fed_liquidity_aggregator.py 연준 순유동성 계산·국면 판단
macro_collector.py 매크로 수집 + 정량 계산 → context JSON
price_history_collector.py yfinance 주요 자산 OHLCV + 기술지표
market_indicator_tracker.py 핵심 시장 지표 수집 + 이상치 감지
strategy_flow_collector.py 한국 시장 투자자별 순매수·프로그램 매매·신용잔고
fnguide_snapshot.py FnGuide 컨센서스 (반도체6사+석화6사)

4.5 분석/인텔리전스

파일 용도
sector_news_scorer.py 섹터별 뉴스 LLM 중요도 채점
discovery_enricher.py score 7+ 발견 아이템 → 볼트 적용 힌트 생성
signal_synthesizer.py 4축 시그널(매크로/섹터/기업/기술) 합성
daily_intelligence_report.py 7+ 파이프라인 출력 취합 → 통합 데일리 리포트
vault_analyst_feedback.py 분석 에이전트 결과 → 볼트 환류
analyst_evolution_tracker.py 분석 방법론 피드백 추적
morning_briefing.py 모닝/이브닝 브리핑 생성 (한국장·미국장)

4.6 시스템 운영

파일 용도
cron_watchdog.py 크론 잡 지연·실패 감지
cron_stall_detector.py 크론 정지 감지
auto_healer.py 자동 복구
data_freshness_watcher.py 데이터 신선도 감시

5. 볼트 구조

5.1 ~/knowledge/ (해리 고유 볼트, AI 쓰기 제한)

~/knowledge/
  000 선언/          — 시스템 선언·스키마 (편집 절대 금지)
  100 수신함/        — 해리 직접 수집물
  120 지식사랑방/    — 커뮤니티 공유 (vault120-sync가 agent로 복사)
  200 아토믹/        — 원자 노트
  300 지식망/        — 해리 활용 지식망
  400 판단/          — 해리 투자 판단 (420~442 하위)
  500 시그널/        — 시그널
  600 데이터/        — 데이터
  700 실험실/        — 실험 공간
  800 운영/          — 운영 메모
  900 프롬프트/      — 프롬프트 저장

규칙: AI 에이전트 읽기만 가능. 해리 지정 분석 결과만 직접 저장 허용 (staging 불필요).

5.2 ~/knowledge-agent/ (AI 작업 공간, 자유 읽기/쓰기)

~/knowledge-agent/
  100-inbox/         — 에이전트 수집 결과
    110 blog-insights/
    112 twitter-reports/
    113 popular-posts/
    114 filtered-ideas/
    117 macro-series/
    118 텔레그램/
    119-크레딧메일/    — 황대진 채권 메일 파싱 결과
    120 지식사랑방/    — vault120-sync 복사본
    121 뉴스레터/
    122 price-history/
    123 fed-liquidity/
    124 dart-edgar/
    125 sector-news/
    126 hypotheses/
  200-atomic/        — 원자 노트 (note-atomizer 출력)
  300-connected/     — 연결된 노트망
  400-reports/       — 에이전트 작성 리포트 (본 문서 포함)
  500-signals/       — 4축 시그널 합성 결과
  600-data/          — 수집 데이터
  700-lab/           — 실험 공간
  _staging/          — 해리 검토 후 ~/knowledge/ 승격 대기
  cowork/            — Claude Code ↔ Hermes 공유 공간

공유 프로토콜: - Claude Code → Hermes: 400-reports/에 저장 → Hermes가 agent-vault MCP로 읽음 - Hermes → Claude Code: 100-inbox/에 저장 → Claude Code가 agent-vault MCP로 읽음 - 파일명 규칙: YYMMDD_{source}_{topic}.md - frontmatter 필수: title, date, source(claude-code/hermes/pipeline), tags


6. 텔레그램 봇 역할

chat_id 용도
@openclaw_harybot 492860021 (해리 DM) Claude Code ↔ 해리 직접 대화
@RONforMAC_Bot 492860021 (해리 DM) Hermes 시스템 알림 (CRITICAL/INFO)
@ronclawBot 해리 DM Codex 직접 소통

알림 등급 정책 (shared/telegram.py의 등급 게이트):

등급 목적지 조건
CRITICAL 해리 DM 위기·승인 요청만. 5줄 이내
INFO 알림센터(ops_multiagent.db) 정보·보고·루틴. DM 금지
LOG 로그만 디버그·내부 (전송 없음)

규칙: @RONforMAC_Bot 채널 설정 절대 변경 금지. send_dm(text) 호출 시 level 미지정이면 INFO→알림센터.


7. 인수인계 체크리스트

  • [ ] GitHub 레포 접근: ~/hermes-repo/.git/ (remote 확인 필요)
  • [ ] .env 재구성: ~/hermes-repo/.env.example 참조
  • [ ] 배포 도구 실행 환경: bash ~/hermes-repo/scripts/deploy_to_runtime.sh
  • [ ] launchd 서비스 등록: ai.hermes.gateway.plist (현재 활성)
  • [ ] codex-proxy 가동: localhost:18642 (gateway 기본 모델 라우팅)
  • [ ] Gmail API OAuth 토큰: ~/.hermes/credentials/ 확인
  • [ ] 텔레그램 봇 토큰 3종: ~/.hermes/bot_tokens.json 참조
  • [ ] Telethon API 인증: ~/.hermes/auth.json (채널 수집용)
  • [ ] FRED API 키: ~/.hermes/fred_api_key 확인
  • [ ] DART API 키: ~/.hermes/dart_api_key 확인
  • [ ] 볼트 경로 마운트: ~/knowledge/, ~/knowledge-agent/ 접근 확인
  • [ ] sector-group.json: ~/.hermes/sector-group.json (섹터 라우팅 설정)

N1. .env.example 전문 (변수명 + 설명)

실측 기준: ~/.hermes/.env에서 변수명만 추출 (값 노출 없음).

# ── Hermes 게이트웨이 ──────────────────────────────────────────
HERMES_GATEWAY_PORT=         # 게이트웨이 HTTP 포트 (기본 18789). config.yaml과 일치 필요.
HERMES_GATEWAY_TOKEN=        # 게이트웨이 API 인증 토큰. 외부 호출 시 Bearer 헤더에 사용.
HERMES_INFERENCE_PROVIDER=   # LLM 공급자 선택 (openai / anthropic / codex-proxy 등). 16개 스크립트 참조.
HERMES_CODEX_BASE_URL=       # codex-proxy 엔드포인트 (기본 http://localhost:18642/v1). 5개 스크립트 참조.

# ── API 서버 (MCP / 외부 노출) ────────────────────────────────
API_SERVER_ENABLED=          # API 서버 활성화 여부 (true/false). 13개 스크립트 참조.
API_SERVER_HOST=             # API 서버 바인드 주소 (예: 0.0.0.0). 10개 스크립트 참조.
API_SERVER_PORT=             # API 서버 포트. 11개 스크립트 참조.
API_SERVER_KEY=              # API 서버 접근 키. 26개 스크립트 참조.

# ── Telegram ─────────────────────────────────────────────────
TELEGRAM_BOT_TOKEN=          # 기본 DM 봇 @RONforMAC_Bot 토큰. 91개 스크립트 참조 (핵심).
TELEGRAM_ALLOWED_USERS=      # 봇 명령 허용 user_id 목록 (쉼표 구분). 31개 스크립트 참조.
TELEGRAM_BLOCKED_CHATS=      # 수신 차단 chat_id 목록. 2개 스크립트 참조.
TELEGRAM_REQUIRE_MENTION=    # 그룹 채팅에서 봇 언급 필요 여부 (true/false). 6개 스크립트 참조.

# ── Anthropic / OpenAI ────────────────────────────────────────
# (Hermes는 codex-proxy 경유가 기본. 직접 호출 시 아래 키 사용)
# 해당 변수가 .env에 없으면 HERMES_INFERENCE_PROVIDER 설정 확인.

# ── DART (공시) ──────────────────────────────────────────────
DART_API_KEY=                # open.dart.fss.or.kr 공시 API 키. 24개 스크립트 참조.

# ── Minimax (이미지/음성 생성) ────────────────────────────────
MINIMAX_API_KEY=             # Minimax 멀티모달 API 키. 43개 스크립트 참조.

# ── Browser / Browserbase ────────────────────────────────────
BROWSERBASE_ADVANCED_STEALTH= # Browserbase 고급 스텔스 모드 (true/false). 6개 스크립트 참조.
BROWSERBASE_PROXIES=         # Browserbase 프록시 설정. 4개 스크립트 참조.
BROWSER_SESSION_TIMEOUT=     # 브라우저 세션 타임아웃 (초). 1개 스크립트 참조.
BROWSER_INACTIVITY_TIMEOUT=  # 브라우저 비활동 타임아웃 (초). 5개 스크립트 참조.

# ── Terminal / 실행 환경 ─────────────────────────────────────
TERMINAL_TIMEOUT=            # 명령 실행 타임아웃 (초). 21개 스크립트 참조.
TERMINAL_LIFETIME_SECONDS=   # 터미널 세션 최대 수명. 9개 스크립트 참조.
TERMINAL_MODAL_IMAGE=        # 터미널 Docker 이미지 이름. 9개 스크립트 참조.

# ── Obsidian / 볼트 ──────────────────────────────────────────
OBSIDIAN_VAULT_PATH=         # Obsidian 볼트 절대 경로. 6개 스크립트 참조.
                             # 보통 ~/knowledge 또는 ~/knowledge-agent

# ── 디버그 플래그 ────────────────────────────────────────────
IMAGE_TOOLS_DEBUG=           # 이미지 도구 상세 로그 (true/false). 5개 스크립트 참조.
MOA_TOOLS_DEBUG=             # MoA(Mixture of Agents) 도구 디버그. 4개 스크립트 참조.
VISION_TOOLS_DEBUG=          # 비전 도구 디버그. 4개 스크립트 참조.
WEB_TOOLS_DEBUG=             # 웹 도구 디버그. 8개 스크립트 참조.

비고: Gmail OAuth, FRED, KIS, Telethon 인증은 별도 credential 파일로 관리 (~/.hermes/credentials/, ~/.hermes/auth.json, ~/.hermes/fred_api_key 등). .env에 직접 포함하지 않음.


N2. 크론 72개 전체 목록

~/hermes-repo/cron/jobs.json 실측 기준 (2026-04-22). enabled=false는 비활성.

id (앞 12자) name schedule enabled
41c2736f0527 vault-analyst-feedback 50 7 * * * true
ocPH-SPY-pri price-history SPY refresh 0 7,12,18 * * 1-5 true
ocAK-AK000-b bond-daily-report-real-notify 0 9 * * 2-6 true
ocAO-AO003-b bond-morning-poll-real-gmail-collector 3,33 7-9 * * 1-5 true
macro-series macro-series-collector FRED macro timeseries collector 50 6 * * 1-5 true
fed-liquidit fed-liquidity-aggregator Fed liquidity aggregator 0 7 * * * true
ocM-M019-blo batchM-intelligence-blog-monitor (interval 360m) true
ocAQ-AQ004-g gmail-newsletter-collector 47 6 * * * true
ocRESTORE-in intelligence-cluster Hermes data chain 0 1 * * * true
ocRESTORE-se sector-news-scorer Hermes S-code scoring 30 2,8,14,20 * * * true
ocRESTORE-di discovery-enricher Hermes vault hints 35 1 * * * true
ocRESTORE-ke keyword-tuner Hermes query evolution 30 4 * * 1,4 true
ocRESTORE-hy hypothesis-lifecycle Hermes state maintenance 45 3 * * * true
ocRESTORE-an analyst-channel-collector Hermes market inputs 45 7,13 * * 1-5 true
ocRESTORE-an analyst-quality-tracker Hermes PM QA 10 8 * * * true
ocRESTORE-no notion-analyst-sync Hermes research log sync 20 8 * * 1-5 true
ocJ-J000-nep nepcon-collector 37 1,7,13,19 * * * true
fundamental- fundamental DART financial statement collector 0 6 * * * false
fundamental- fundamental EDGAR overseas financial statement collector 10 6 * * * false
fundamental- fundamental Twitter collector 20 6 * * * false
ocFUND-dart- DART/EDGAR disclosure collector for fundamental analyst 20 6 * * 1-5 false
ocTC-twitter twitter-collector X/Twitter following collector 20 6 * * * true
ocFUND-dart- fundamental DART disclosure collector 0 6 * * * true
ocFUND-edgar fundamental EDGAR disclosure collector 10 6 * * * true
oc118-channe channel-collector 118 텔레그램 수집 17 3,9,15,21 * * * true
ocRESTORE-po popular-posts-collect restored cron 20 7,13 * * 1-5 true
ocRESTORE-va vault-macro-bridge restored cron 50 6 * * 1-5 true
ocRESTORE-va vault-fundamental-bridge restored cron 0 7 * * 1-5 true
ocRESTORE-va vault-technical-bridge restored cron 10 7 * * * true
ocRESTORE-pr price-history-universe Hermes full price refresh 0 7,13,18 * * 1-5 true
ocRESTORE-an analyst-evolution-tracker methodology feedback 15 8 * * * true
ocRESTORE-no note-atomizer phase-200 37 2,14 * * * true
ocRESTORE-in inbox-health-auditor 100-inbox health audit 30 0 * * * true
ocRESTORE-kn knowledge-promoter 15 4 * * * false
ocRESTORE-kn knowledge-connector 40 2 * * * false
ocRESTORE-pr promotion candidates reporter 0 5 * * * true
ocRESTORE-pr promotion auto mover 30 5 * * * false
ocRESTORE-va vault120-sync Harry vault to agent inbox sync */30 * * * * true
oc-goal-alig goal-alignment 일일 평가 43 12 * * * true
oc-vault-arc vault-architect 구조 최적화 27 4 * * * true
oc-vault-flo vault-flow-health 볼트 건강도 13 5 * * * true
kr-research- kr-research-collector 한국 리서치 수집 15 4 * * * true
ocRESTORE-mo moat-scorer 기업별 Moat 정량 스코어 17 3 * * * true
ocRESTORE-si signal-synthesizer 4축 시그널 합성 27 3 * * * true
ocRESTORE-se sector-research 섹터 6단계 분석 집계 37 3 * * * true
ocCRIT-oil-s 글로벌 석유 공급망 모니터 0 6 * * * true
ocRESTORE-oi 석유 공급망 모니터 (오후 14시) 0 14 * * * true
ocCRIT-oil-s 석유 공급망 모니터 (저녁 21시) 0 21 * * * true
fd0119a08cc4 bond-morning-quiz 30 7 * * 1-5 true
bc3a02bc769c bond-morning-quiz-retry 0 14 * * 1-5 true
0a258438a36e bond-evening-concept 0 21 * * * true
35dac8a246ff bond-weekly-review 0 19 * * 5 true
1659adf98d3b bond-weekly-score 0 9 * * 1 true
2c2062c4ec67 bond-monthly-exam 0 10 28-31 * 6 true
ocAO-AO100-b bond-evening-poll-1900-gmail-collector 3 19 * * 1-5 true
ocAO-AO101-b bond-evening-poll-2030-gmail-collector 33 20 * * 1-5 true
ocAO-AO102-b bond-evening-poll-2200-gmail-collector 7 22 * * 1-5 true
ocAK-AK100-b bond-evening-report-notify 37 22 * * 1-5 true
oc119-trilli Trillion_labs 텔레그램 수집 0 6,14,21 * * * true
aasf-scout-1 awesome-agent-frameworks-scout 7 9 * * 1 true
daeju-trigge daeju-trigger-0930 078600 대주전자재료 트리거 30 9 * * 1-5 true
daeju-trigge daeju-trigger-1100 078600 대주전자재료 트리거 0 11 * * 1-5 true
daeju-trigge daeju-trigger-1500 078600 대주전자재료 트리거 0 15 * * 1-5 true
1d04396f15ec bond-market-close-briefing 40 15 * * 1-5 true
ops-syncer ops-syncer */10 * * * * true
ocRESTORE-ma market-indicator-tracker 5 7,9,11,13,15,17 * * 1-5 true
ocRESTORE-st strategy-flow-collector 0 16 * * 1-5 true
ocRESTORE-ta tanker-tracker 35 6 * * * true
ocRESTORE-re refining-tracker 40 6 * * * true
ocRESTORE-fn fnguide-snapshot 0 17 * * 1-5 true
ocRESTORE-co copper-market-collector 30 7 * * 5 true
ocRESTORE-ur urea-price-tracker 0 9 * * 1 true

합계: 72개 (활성 65, 비활성 7)


N3. jobs.json 스키마

~/hermes-repo/cron/jobs.json 최상위 구조:

{
  "jobs": [ ... ],
  "updated_at": "ISO-8601"
}

잡 객체 필드

필드 타입 필수 설명
id string 필수 12자 고유 식별자 (uuid hash 또는 custom prefix)
name string 필수 사람이 읽는 잡 이름 (중복 방지 기준)
command string 필수 실행 명령 전체 경로 (/usr/bin/python3 /path/script.py)
schedule object 필수 {"kind": "cron", "expr": "40 15 * * 1-5", "display": "..."}
enabled bool 필수 false면 크론 틱커가 건너뜀
type / job_type / kind string 필수 "shell" (현재 단일 타입)
cwd string 선택 실행 디렉터리 (기본 ~/.hermes/workspace)
timeout_seconds int 선택 잡 최대 실행 시간 (기본 300)
silent bool 선택 true면 stdout 억제
description string 선택 잡 설명
state string 자동 "scheduled" / "running" / "failed"
last_run_at ISO-8601 자동 마지막 실행 시각
next_run_at ISO-8601 자동 다음 실행 예정 시각
last_status string 자동 "ok" / "error"
last_error string|null 자동 마지막 에러 메시지
repeat.completed int 자동 누적 완료 횟수
migration object 선택 잡 마이그레이션 이력 메타

새 잡 추가 방법 (파이프라인 스크립트 내부)

# workspace/scripts/shared/cron_store.py의 add_or_update_job 사용
# 중복 방지: 같은 name이 있으면 schedule/payload만 갱신하고 "updated" 반환
from shared.cron_store import add_or_update_job

new_job = {
    "id": "my-job-id-12",          # 12자 고유 ID
    "name": "my-new-job",          # 중복 방지 기준 필드
    "command": "/usr/bin/python3 /Users/ron/.hermes/workspace/scripts/pipeline/my_script.py",
    "schedule": {
        "kind": "cron",
        "expr": "0 9 * * *",       # cron 표현식 (KST 기준)
        "display": "0 9 * * *"
    },
    "enabled": True,
    "type": "shell",
    "job_type": "shell",
    "kind": "shell",
    "timeout_seconds": 300,
    "silent": False
}

action, job_id = add_or_update_job(new_job)
# action: "added" / "updated" / "skipped"

주의: add_or_update_jobname 기준으로 중복 감지. 같은 이름이 이미 있으면 새로 만들지 않고 schedule/payload만 갱신. 직접 jobs.json을 편집하면 크론 틱커 리로드 타이밍에 따라 충돌 가능 — 항상 add_or_update_job을 사용할 것.


N4. 파이프라인 의존성 체인

체인 1: 채권 브리핑 (황대진 메일 → 장마감 DM)

Gmail 수신함 (황대진 메일 07:00~09:00 도착)
    ↓ [bond-morning-poll-real-gmail-collector: 3,33분 07~09시]
    bond_report_parser.py → HTML 파싱 → 구조화 JSON
    ↓
~/.hermes/workspace/memory/bond-briefing/latest.json
    ↓ [bond-daily-report-real-notify: 09:00 화~토]
    bond_daily_report.py → LLM 3페이지 브리핑 → DM 전송
    ↓
~/.hermes/workspace/memory/bond-briefing/latest.json (date 필드 갱신)
    ↓ [bond-market-close-briefing: 15:40 평일]
    bond_market_close.py → 신선도 가드(date 오늘인지 확인) → 커브·스프레드 요약 DM

신선도 가드: latest.jsondate 필드가 오늘이 아니면 "stale data" 경고 DM 발송 후 종료. (2026-04-20 사고 교훈 반영)

체인 2: 블로그 → 인텔리전스 리포트

네이버 블로그 RSS (6시간마다)
    ↓ [batchM-intelligence-blog-monitor: interval 360m]
    blog_monitor.py → 인사이트 추출 → 섹터 채널 텔레그램 발송
    ↓
~/knowledge-agent/100-inbox/110 blog-insights/YYYY-MM-DD/{파일}.md
    ↓ [intelligence-cluster: 01:00]
    daily_intelligence_report.py → blog_count 집계 + LLM 취합
    ↓
~/.hermes/workspace/memory/blog-insights/ (MEMORY 경로 미러)
    → 통합 데일리 인텔리전스 리포트 DM

체인 3: 트위터 → 인텔리전스

X/Twitter 팔로잉 계정 (매일 06:20)
    ↓ [twitter-collector-X/Twitter: 20 6 * * *]
    twitter_collector.py → twikit 수집 → 인게이지먼트 스코어링 → LLM 분석
    ↓
~/knowledge-agent/100-inbox/112 twitter-reports/YYYY-MM-DD/{파일}.md
    + ~/.hermes/workspace/memory/twitter-reports/ (MEMORY 미러)
    ↓ [intelligence-cluster: 01:00]
    daily_intelligence_report.py → social_data 집계 → 통합 리포트

체인 4: 볼트 동기화 체인

~/knowledge/120 지식사랑방/ (해리 직접 수집)
    ↓ [vault120-sync: */30 * * * *]
    → ~/knowledge-agent/100-inbox/120 지식사랑방/ (단방향 복사)
    ↓ [note-atomizer: 37 2,14 * * *]
    → ~/knowledge-agent/200-atomic/ (원자 노트 분해)
    ↓ [knowledge-connector: 40 2 * * * — 현재 비활성]
    → ~/knowledge-agent/300-connected/ (연결망 구성)

체인 5: 시그널 합성 체인

macro-series-collector (06:50) → memory/macro-timeseries/
fed-liquidity-aggregator (07:00) → memory/fed-liquidity/
sector-news-scorer (02/08/14/20시) → 125 sector-news/
signal-synthesizer (03:27) ─────────────────────────────┐
    ← macro bridge (06:50)                               │
    ← fundamental bridge (07:00)                         │
    ← technical bridge (07:10)                           │
    ↓                                                    │
~/knowledge-agent/500-signals/ (4축 시그널 합성 결과) ───┘
    ↓ [daily_intelligence_report: 01:00]
    최종 통합 리포트 + DM

N5. 장애 런북

장애 1: Gateway down

  • 증상: 텔레그램 봇 응답 없음, curl localhost:18789/health 불통, 크론 전체 중단
  • 진단: bash launchctl list | grep ai.hermes.gateway # PID 0이면 죽음 cat ~/.hermes/gateway.pid # PID 확인 tail -50 ~/.hermes/logs/gateway.log # 마지막 에러 확인
  • 복구: bash launchctl unload ~/Library/LaunchAgents/ai.hermes.gateway.plist launchctl load -w ~/Library/LaunchAgents/ai.hermes.gateway.plist # 검증 (30초 후) curl -s localhost:18789/health launchctl list | grep ai.hermes.gateway # PID 확인
  • 원인 후보: Python 예외 uncaught / 포트 18789 충돌 / 메모리 스파이크 / .env 누락 변수
  • 로그: tail -100 ~/.hermes/logs/gateway.log

장애 2: 크론이 stale 데이터 반복 발송

  • 증상: bond_market_close 등이 어제 데이터로 DM 발송 (4-20 사고 패턴)
  • 진단: bash cat ~/.hermes/workspace/memory/bond-briefing/latest.json | python3 -c \ "import json,sys; d=json.load(sys.stdin); print(d.get('date','없음'))" # date 필드가 오늘이 아니면 upstream 수집 실패
  • 복구: bash # 1. upstream 크론 수동 실행 /usr/bin/python3 ~/.hermes/workspace/scripts/pipeline/bond_report_parser.py /usr/bin/python3 ~/.hermes/workspace/scripts/pipeline/bond_daily_report.py # 2. latest.json date 확인 후 재실행 /usr/bin/python3 ~/.hermes/workspace/scripts/pipeline/bond_market_close.py --dry
  • 원인 후보: Gmail OAuth 만료 / 메일 미도착 / 파서 에러 / 신선도 가드 미구현 버전
  • 로그: tail -100 ~/.hermes/logs/bond_daily_report.log

장애 3: Telegram 봇 409 Conflict

  • 증상: 봇이 409 Conflict: terminated by other getUpdates request 에러 반복
  • 진단: 같은 토큰으로 두 개 이상의 프로세스가 getUpdates 폴링 중 bash ps aux | grep hermes | grep -v grep # gateway 프로세스가 2개 이상 → 충돌
  • 복구: bash # 1. 모든 hermes 프로세스 종료 pkill -f "hermes-agent" # 2. gateway 재시작 launchctl unload ~/Library/LaunchAgents/ai.hermes.gateway.plist launchctl load -w ~/Library/LaunchAgents/ai.hermes.gateway.plist
  • 원인 후보: 수동 python 실행 후 종료 안 함 / launchd가 두 번 실행 / 배포 중 중복 기동
  • 로그: grep "409" ~/.hermes/logs/gateway.log | tail -20

장애 4: OAuth 만료 (Gmail / Google Drive 재인증)

  • 증상: gmail_newsletter_collector / bond_report_parser 에러. Token has been expired or revoked 로그
  • 진단: bash ls -la ~/.hermes/credentials/ # token.json 확인 python3 -c " import json with open('/Users/ron/.hermes/credentials/token.json') as f: t = json.load(f) print('expiry:', t.get('expiry','없음')) "
  • 복구: bash # 1. 기존 토큰 삭제 rm ~/.hermes/credentials/token.json # 2. 수동 인증 실행 (브라우저 열림) cd ~/.hermes/workspace python3 scripts/pipeline/gmail_auth.py # 또는 bond_report_parser.py --auth # 3. token.json 재생성 확인 후 크론 재검증
  • 원인 후보: 6개월 미사용 / 보안 정책 변경 / 계정 비밀번호 변경
  • 로그: grep -i "token\|oauth\|credential" ~/.hermes/logs/bond_report_parser.log | tail -20

장애 5: codex-proxy 죽음

  • 증상: Hermes 게이트웨이가 LLM 호출 실패. Connection refused localhost:18642 에러
  • 진단: bash curl -s localhost:18642/v1/models | head -5 # 응답 없으면 죽음 ps aux | grep codex-proxy | grep -v grep cat ~/.openclaw/workspace/logs/codex-proxy.log | tail -30
  • 복구: bash # 1. codex-proxy 재시작 (launchd 방식) launchctl list | grep codex-proxy launchctl stop [codex-proxy 서비스명] launchctl start [codex-proxy 서비스명] # 2. 직접 실행 방식 (임시) cd ~/.openclaw python3 workspace/codex-proxy/main.py & # 3. 검증 curl -s localhost:18642/v1/models
  • 원인 후보: ChatGPT 세션 만료 (재로그인 필요) / 포트 충돌 / Python 예외
  • 로그: ~/.openclaw/workspace/logs/codex-proxy.log
  • 추가: ChatGPT 브라우저 로그인 확인 필요. 로그인 만료면 stealth-browser로 재인증.

N6. 볼트 frontmatter 실제 예시

~/knowledge-agent/100-inbox/119-크레딧메일/260422_황대진_...md 실측:

---
title: "전달: 금일 (4/23 목) 입찰 및 수요예측 안내 (DS증권 황대진)"
date: 2026-04-22
source_platform: gmail
source_channel: 황대진
category: 자금수급
tags:
  - 크레딧
  - 픽스드인컴
---

400-reports/ 에이전트 리포트 예시 (Claude Code 작성):

---
title: "Hermes 시스템 구조 전수조사 (인수인계)"
date: 2026-04-24
source: claude-code
tags: [hermes, system, handover, cron, pipeline, vault]
---

110 blog-insights/ 블로그 인사이트 예시 (pipeline 작성):

---
title: "..."
date: 2026-04-23
source: blog_monitor
source_channel: ranto28
tags: [bridge/blog_monitor, source/ranto28, status/fleeting]
---

필수 필드: title, date, source (또는 source_platform). tags는 필수에 가까움.


N7. v0.7.0 Phase 2 Rework 이슈 상세

GitHub 레포: Choi-Hyeonwoo/hermes. 실측 기준.

#47 cli.py argparse 재배선 + subcommand 모듈화 / Phase 2 of #10

  • Depends on: #10 (Phase 1 barrel split) 머지 후
  • 범위: HermesCLI 클래스의 슬래시 커맨드 디스패처를 argparse 기반 subcommand 모듈 (hermes_cli/commands/*.py)로 재배선. baseline help parity 테스트 포함. deprecation warning 경로(기존 호출자 호환) 추가.
  • 배경: #10 원본이 barrel split + argparse 재배선 + subcommand 분리까지 포함했으나, PR #40(run_agent.py) 패턴과 일관성을 위해 Phase 1은 barrel split만으로 좁히고 이 이슈가 Phase 2 담당.
  • 핵심 파일: hermes-agent/cli.py (6700+ LOC), hermes-agent/hermes_cli/commands/
  • 테스트: 기존 help 출력 캡처 → 재배선 후 동일성 확인 (help parity 스냅샷)

#48 gateway/run.py 추상화 심화 / Phase 2 of #11

  • Depends on: #11 (Phase 1 barrel split) 머지 후
  • 범위: 라우터/미들웨어/bootstrap 경계 재정의. gateway/platforms/ PlatformAdapter와 일관된 디스패치 경로 통합.
  • 배경: #11 원본 범위 중 순수 barrel split을 벗어나는 라우팅/미들웨어/플랫폼 디스패치 재설계를 Phase 2로 분리. PR #40 패턴 일관성 유지.
  • 핵심 파일: gateway/run.py, gateway/platforms/

#49 workspace/scripts/server.py 추상화 심화 / Phase 2 of #12

  • Depends on: #12 (Phase 1 barrel split) 머지 후
  • 범위: HTTP 핸들러 구조 재정리. 상태 저장소/startup-shutdown 경로 재설계.
  • 배경: #12 원본 범위 중 핸들러 재구성/상태 저장소 리팩터를 Phase 2로 분리. 순수 이동만 먼저 반영.
  • 핵심 파일: workspace/scripts/server.py

#55 state/ 패키지 SSOT 이관 / Phase 2 of #17

  • Depends on: #17 Phase 1 머지 후
  • 범위: Phase 1은 hermes_agent.state 패키지 facade만 추가. Phase 2에서 실제 SSOT 이관 수행.
  • SQLite 스키마 버전 관리 (alembic/yoyo/수동)
  • scripts/migrate_state_to_db.py 마이그레이션 스크립트
  • workspace/memory/, workspace/mission-control/ 직접 읽는 모든 *.pyhermes_agent.state 경유로 교체
  • 세션/메모리 round-trip 테스트 (tests/state/test_roundtrip.py)
  • 핵심 파일: hermes-agent/hermes_agent/state/, workspace/memory/, workspace/mission-control/

#58 errors/telemetry 전면 migration / Phase 2 of #15

  • Depends on: #15 Phase 1 머지 후
  • 범위: 기존 logging.getLogger(...), print('[ERROR]...'), ad-hoc sys.stderr.write() 전부를 새 errors.py + telemetry.py 경유로 교체.
  • get_logger() 교체 (grep 기반 전수 수정)
  • HermesError raise로 교체
  • 최상위 except 핸들러 (gateway, cli, scripts) → HermesError 분기 추가
  • docs/ERROR_CODES.md 신설 (최소 20개 코드 문서화)
  • 핵심 파일: hermes-agent/ 전체 *.py, docs/ERROR_CODES.md

#60 mypy strict 전면 확장 / Phase 2 of #14

  • Depends on: #14 Phase 1 머지 후
  • 범위: strict override를 아래 순서로 순차 확대. 각 모듈별 타입 힌트 보완 PR 분리.
  • hermes_agent/agentic.py
  • hermes_agent/tools/manager.py
  • hermes_agent/session.py
  • hermes_cli/**/*.py
  • gateway/server.py, gateway/router.py
  • hermes_agent/config/*
  • 전략: [tool.mypy.overrides]의 strict 블록에 순차 추가. CI에서 mypy --strict 통과 확인. 한 PR당 1~2 모듈 원칙. 기존 타입 힌트는 변경 없이 추가만.
  • 핵심 파일: pyproject.toml (mypy 설정), 각 모듈 *.py