# Hermes 구조·코드·운영·완성도 감사

- 기준 시각: 2026-08-03 09:35 KST 전후
- 범위: `~/.hermes/`의 사용자 작성 코드, Hermes Agent 런타임, cron, 상태 원장, 최근 회귀·운영 산출물
- 기준 문서: `PROJECT_CANON_20260728.md` → `GOALS.md` 최신 블록 → 설계 문서 순
- 제외: 비밀 디렉터리·환경변수·인증값·개인 포트폴리오 수치. 외부 전송 없음.
- 방법: 파일/LOC 인벤토리, 활성 cron 124개 전수 집계, 최근 상태·실행 원장 확인, 최근 회귀 결과 확인, 핵심 경로 정적 코드 리뷰. 16만 줄 전체의 의미론적 라인 리뷰가 아니라 구조·런타임 증거 중심 감사다.

## 0. 결론

Hermes는 “프로토타입” 단계를 넘었다. 수집, 분석, 기억, 채점, 운영 감시를 망라하는 큰 시스템이고 사용자 작성 프로덕션 코드만 약 16.2만 LOC, 테스트 약 14.0만 LOC다. 다만 북극성인 “판단을 기록·채점해 엣지를 축적”하는 제품으로 보면 완성도는 코드량보다 훨씬 낮다.

현재 병목은 기능을 더 만드는 일이 아니다.

1. 수집·생성기는 많고 실제로 돈다.
2. 생성 결과를 정식 소비자가 읽고, 승인하고, 결과를 채점하는 연결이 약하다.
3. 실행 성공과 산출물 품질 성공을 같은 것으로 취급하는 구간이 남아 있다.
4. 사용자에게 전달된 결과가 실제로 읽히고 유용했는지는 거의 측정하지 못한다.

완성도를 단일 숫자로 표현하면 오해가 커서 층별로 본다.

| 층 | 현재 추정 | 판정 |
|---|---:|---|
| 수집·코드 구현 | 65~75% | 넓고 상당수가 실제 작동 |
| end-to-end 배선·운영 | 45~55% | 핵심 루프 일부만 연결 |
| 정확도·성과 증거 | 15~25% | unscorable·HOLD가 큼 |
| 사용자 가치 검증 | 5~15% | 읽음·유용성 측정 부재 |
| 북극성 전체 | 약 30~40% | “많이 만들었지만 아직 학습 시스템으로 닫히지 않음” |

## 1. 실제 물리 구조

```text
~/.hermes/
├── PROJECT_CANON_20260728.md   # 프로그램 헌법·18축
├── GOALS.md                    # 현재 실행 큐(최상단 최신 블록이 유효)
├── SYSTEM_MAP.md               # 런타임 지도이나 6/25 스냅샷으로 오래됨
├── config.yaml                 # Hermes Agent 기본 모델·런타임 설정
├── cron/
│   ├── jobs.json               # 124개 작업 SSOT
│   └── output/                 # 실행 산출물
├── scripts/                    # 수집기·브리지·크론 진입점·운영 도구
├── market_lens/                # 분석 본체·도시에·렌즈·백테스트·관찰·검증
├── harness/                    # Oracle·사실 동기화·정확도 하네스
├── hermes-agent/               # 스케줄러·에이전트·게이트웨이 런타임
├── rag/                        # 검색/임베딩 지식 저장소
├── wiki_mirror/                # 지민 위키 미러
├── x_distill/                  # X 계정 증류
├── world_designers/            # 세계 설계자 후보/수집
├── pine/                       # Pine/차트 관련 자산
├── skills/                     # 런타임 스킬
└── state/                      # 모든 상태·원장·감사·측정 결과
```

### 1.1 크기와 코드량

| 영역 | 프로덕션 Python | 프로덕션 LOC | 테스트 Python | 테스트 LOC |
|---|---:|---:|---:|---:|
| `scripts/` | 284 | 100,204 | 158 | 68,025 |
| `market_lens/` | 193 | 57,427 | 169 | 51,221 |
| `harness/` | 23 | 4,755 | 47 | 12,063 |
| 루트 테스트 | - | - | 15 | 8,509 |
| 합계 | 500 | 약 162,386 | 389 | 약 139,818 |

디스크는 `~/.hermes` 약 26GB, 별도 백업 약 8.3GB다. 이 중 RAG 약 7.6GB, 현재 Hermes Agent 약 2.9GB이며, 깨진 Hermes Agent 스냅샷 세 개가 약 9.2GB를 차지한다. 용량은 당장 위험하지 않지만 런타임·상태·백업이 한 트리 주변에 얽혀 있다.

### 1.2 코드 구조의 성격

- 분석 흐름은 대체로 `run → orchestrator → analyze → lens → verify → source → DB/state`다.
- cron 진입점은 `scripts/`에 집중되고, 실제 도메인 구현은 `market_lens/`와 `harness/`로 분산된다.
- 사용자 작성 코드 전체를 묶는 루트 `pyproject.toml`/lockfile이 없다. 대부분 `hermes-agent/venv`를 사실상의 공용 런타임으로 사용한다.
- 프로덕션 파일 334개가 `sys.path`를 직접 변경한다. 패키지 경계보다 경로 주입으로 결합한 구조다.
- 40개 파일이 홈 디렉터리 또는 `~/.hermes`를 직접 가정한다.
- `except Exception` 약 1,430건, 그중 조용히 `pass`하는 형태 약 120건이 있다. 모두 결함은 아니지만 관측성 누락 위험이 크다.
- 큰 단일 파일이 남아 있다: `market_lens/analyze/dossier.py` 4,442줄, `scripts/breaking-news-monitor.py` 3,874줄, `market_lens/run.py` 2,493줄 등.
- 루트 Git 아래에 빈/미초기화 `scripts/.git`, `scripts/data_sources/.git`이 있어 도구가 저장소 경계를 오판할 수 있다. 실제 루트는 `~/.hermes/.git`이다.

## 2. 기능 구조: 무엇이 무엇을 먹고 사는가

```text
[외부 소스]
  SaveTicker / 증권사 / 공공기관 / Fed / X / 가격 / 이벤트 / 위키
      │
      ▼
[수집·계약]
  scripts/*collect* · source_contract_probe · archive
      │
      ├──────────────► [RAG·기억] rag / wiki_mirror / Kapasi replay
      │
      ▼
[정규화 상태]
  world_state · portfolio_state · event_ledger · market_state_packet
      │
      ▼
[분석]
  market_lens · dossier · committee/clones · riskwarden · backtest
      │
      ▼
[판단 원장]
  claims · clone_scores · DR scores · shadow intents · receipts
      │
      ▼
[채점·학습]
  forward test · scorecard · memory attribution · Goal B
      │
      ▼
[전달·사용]
  Telegram / wiki / report
```

강한 구간은 외부 소스→수집과 정규화 상태의 일부다. 약한 구간은 판단 원장→채점·학습, 그리고 전달→사용자 가치 환류다.

## 3. 하위 프로젝트별 구조와 완성도

척도는 0=아이디어, 1=설계, 2=코드, 3=배선/실행, 4=운영 안정, 5=효과 검증 완료다.

| # | 프로젝트 축 | 주요 위치 | 현재 상태 | 핵심 미완성 | 단계 |
|---:|---|---|---|---|---:|
| 1 | SaveTicker·소스 계약 | `scripts/saveticker_*`, `source_contract_probe.py`, RAG | 전량 아카이브와 프로브가 활성. raw 28개 확인 | Source Contract v2가 NOW. 인증 세션과 정식 소비자 계약 미완 | 3/5 |
| 2 | Kapasi·RAG·기억 | `rag/`, `memory_*`, `market_lens/kapasi_*` | RAG 약 353,415건, 건강검사·replay·연상 기억 활성 | 기억이 실제 판단을 개선했다는 생산 증거는 HOLD. 소비자 브리지 미완 | 3/5 |
| 3 | 기술 리포트·강의 | `tech_report_weekly.py`, case generators | 생성 코드와 주간 cron 존재 | 최신 기술 리포트는 추출 후 JSON 파싱 실패. 안정된 배포 루프 아님 | 2/5 |
| 4 | 가독성·설명력 | digest/brief 렌더러, lint | 포맷·린트·초보용 문구 규칙이 존재 | 사용자가 읽고 이해했는지 계측 없음 | 3/5 |
| 5 | X 증류·증거 | `x_collect_cron.py`, `x_distill/`, breaking monitor | X feed 3,000행, 최신 수집 정상. 기본 live 후보는 격리 | 정식 source contract와 장기 채점 소비자 미완 | 3/5 |
| 6 | 클론·위원회 | clone/committee/scorer 계열 | 7,187건 점수 원장과 실행 루프 존재 | 6,939건(96.55%)이 unscorable. “돌아감”이 “검증됨”으로 이어지지 않음 | 2.5/5 |
| 7 | 섹터·공급망 | sector series, dossier supply lens | 도시에 안 일부 렌즈와 학습 생성기 존재 | 전용 6섹터 루프 일부 중단, 요청된 일일 전달 루프 미완 | 2/5 |
| 8 | 세계·크로스에셋 | `world_pulse.py`, world state, `world_designers/` | 세계/거시 상태가 당일 갱신됨. 설계자 후보 124개 | 후보 124개가 모두 candidate이며 정식 소비 흔적 없음 | 3/5 |
| 9 | 이벤트·실적 | event calendar/ledger, risk card | 캘린더·원장·보유교차 카드가 활성 | 잔여 출처 fence와 사후 채점 연결 필요 | 3.5/5 |
| 10 | 입법·정책 | policy/crypto watcher, source monitors | 일부 공식출처 watcher 활성 | 법안 생애주기·Congress 인증·포트폴리오 영향 연결 미완 | 2/5 |
| 11 | 크립토 | `crypto_policy_watch.py` 등 | 정책 공식출처 주간 체크 활성 | 시장·정책·클론·성과를 잇는 독립 분석 체계는 부분적 | 2.5/5 |
| 12 | 포트폴리오·리스크 | portfolio state, dossier, risk card, riskwarden | 상태·도시에·리스크 카드가 실제 운용 | 권한 필요한 자본구조 입력과 fallback 문제, riskwarden 회귀 다수 | 3/5 |
| 13 | DR·판단 채점 | DR/stance/clone score, Goal B | 코드·스키마·일부 채점 존재 | DR 최신 점수가 7/22에서 멈춤. Goal B는 `MEASUREMENT_HOLD` | 1.5/5 |
| 14 | 백테스트·검증 | `market_lens/backtest`, rolling/drift/forward jobs | 코드가 크고 여러 Layer cron 활성 | 데이터·가정 유효성, 회귀 타임아웃, 생산 측정과의 경계가 불안정 | 2.5/5 |
| 15 | Shadow paper | `shadow_cycle_daily.py`, shadow ledger | 2,944건 intent, 1,357 settled | 2,875건(97.66%)이 `riskwarden_not_wired`로 차단. 성능 관측 표본 아님 | 2/5 |
| 16 | 운영·견고성 | cron, execution ledger, health audit, fleet watch | 124개 cron과 원장·감사 체계 존재 | 활성 110개 중 11개 오류. 성공 판정 false-green과 4상태 미완 | 2.5/5 |
| 17 | 모델·토큰·비용 | `llm_provider.py`, usage DB, budget tools | 다중 모델과 토큰 추정 원장 활성 | USD 비용 없음, `run_kind` 오염, reset-aware 라우팅 부재 | 2/5 |
| 18 | 사용자 가치 | Telegram/wiki/report, scorecards | 다수 산출물 전달 경로 존재 | 읽음·행동·유용성·오탐 비용을 측정하지 않음 | 1/5 |

자동매매는 “미완성 기능”으로 채점하지 않는다. 프로젝트 헌법상 현재는 동결된 미래 정책이다.

## 4. 현재 운영 스냅샷

### 4.1 Cron

- 전체 124개, 활성 110개, 비활성 14개
- 활성 작업 중 최근 상태: 정상 99개, 오류 11개
- 활성 작업 형태: 에이전트 프롬프트 작업 36개, 스크립트 전용 74개
- 110개 모두 작업별 provider/model을 명시하지 않고 전역 설정을 상속한다.

현재 오류 11개:

1. 속보 모니터: LLM 시간초과. 다만 `skipped/llm_error/delivery_not_attempted`로 fail-closed 처리되어 오발송은 막음.
2. 토큰·계층 self-audit: 컨텍스트 파일 길이 규칙 위반.
3. Fact Library 동기화: 스크립트 경로 불일치.
4. Hermes Agent update: 업데이트 후 회귀 12/46 실패, 자동 롤백 성공.
5. 결과물 검증: 예전 디렉터리/산출물 기대와 현재 구조 불일치.
6. market_lens 자료 수집: 외부 5,400초 timeout.
7. market_lens 거시 다관점: 내부 3,600초 timeout.
8. Claude keepalive: 현재 사용 한도/인증 경로 오류.
9. 일일 회귀: 4,004개 중 3,924 통과·80 실패, 그중 신규 코드 회귀 의심 31건. scripts suite 자체도 timeout.
10. standing goals: `claude-auth-alive` 위반.
11. 기술 리포트: 추출 응답 JSON 파싱 실패.

### 4.2 상태 신선도

- portfolio/world/event/market packet, LLM usage, X feed는 8/3 당일 갱신.
- DR score는 7/22 이후 정지.
- 자본구조 상태는 7/11 이후 오래되었고 필수 사용자 권한 입력이 완결되지 않음.
- RAG·위키·기억 관련 cron은 대체로 정상.

### 4.3 회귀 수준

최신 일일 회귀는 4,004개 중 80개 실패다. 단순 실패율은 약 2%지만, 중요한 것은 실패 위치다.

- Kapasi prereg digest/불변성 테스트가 넓게 깨짐.
- riskwarden 핵심 상태 전이·fallback 테스트가 여러 개 깨짐.
- holdings 계약 테스트가 실제 상태와 불일치.
- scripts suite 전체가 600초를 넘겨 결과가 불완전.

따라서 “98% 통과”만으로 운영 안전을 판정하면 안 된다. 실패가 북극성 루프와 리스크 경계에 몰려 있다.

감사 중 관련 단위 테스트를 별도로 재실행한 결과 `test_daily_regression.py`와 `test_system_health_audit.py`는 **122개 모두 통과(0.15초)**했다. 즉 H-02의 end-to-end exit/rebaseline 안전성과 M-02의 혼합 range-list cron 표현은 현재 테스트가 다루지 않는 사각지대다.

## 5. 코드·구조상 발견사항

### H-01 · HIGH — 모델 한도 메시지가 cron 성공으로 기록되는 false-green

- 실패 시나리오: 에이전트가 실제 감사 결과 대신 “주간 한도 도달” 한 줄을 반환한다. 반환값이 비어 있지 않으므로 cron은 성공·발송으로 기록한다. 운영자는 health audit가 정상 수행된 것으로 오인한다.
- 실제 증거: 8/3 09:00 health audit의 agent 응답은 한도 메시지였지만 작업은 `last_status=ok`, 원장도 `execution_status=ok`, 알림도 sent다.
- 원인: `hermes-agent/cron/scheduler.py:2119-2137`은 `failed/completed` 플래그와 빈 응답만 검사한다. quota/auth 문구의 의미를 검사하지 않는다. `scheduler.py:2295-2305`도 비어 있지 않은 응답은 성공으로 둔다.
- 영향: 현재 활성 오류 수보다 더 위험한 “거짓 정상”이 존재한다.
- 권고: scheduler 공통 결과 분류기에 quota/auth/model-unavailable 마커를 넣고, `generation_status=error`로 승격한다. 해당 케이스 회귀 테스트를 추가한다.

### H-02 · HIGH — 일일 회귀의 suite timeout이 exit code와 rebaseline에서 fail-open

- 실패 시나리오 A: suite 하나가 timeout되면 `ok=False`지만 실패 목록은 빈 dict다. 새 코드 회귀가 없으면 프로세스가 0으로 끝날 수 있다.
- 실패 시나리오 B: `--rebaseline` 실행 시 suite가 timeout된 불완전 결과를 정상 기준선으로 저장하고 0으로 종료할 수 있다.
- 원인: `scripts/daily_regression.py:185-189`는 timeout을 실패 ID 없이 반환한다. `:245-252`는 problems에만 담고, `:631-640`은 problems를 막지 않은 채 baseline을 저장한다. 최종 반환 `:671`도 `result["problems"]`를 반영하지 않는다.
- 재현 방향: synthetic runner가 한 suite에서 `subprocess.TimeoutExpired`를 내게 한 뒤 `main()`의 exit와 `--rebaseline` 파일 변경 여부를 검증한다.
- 권고: `problems`가 하나라도 있으면 일반 실행 exit 1, rebaseline은 저장 전 중단. end-to-end 테스트를 추가한다.

### H-03 · HIGH — 실행/생성/검증/전달 4상태 중 실행 상태만 공통화

- 실패 시나리오: 스크립트 exit 0 또는 에이전트 비어 있지 않은 응답만으로 정상 처리되지만, JSON 계약이나 품질 검증은 실패하고도 공통 원장에 드러나지 않는다.
- 원인: `hermes-agent/cron/scheduler.py:2317-2328`의 공통 원장은 `execution_status`, `llm_called`, `notify_status`만 기록한다. 목표로 둔 `generation/quality/delivery` 상태가 표준 필드가 아니다.
- 대조 증거: 속보 모니터의 전용 terminal receipt는 4상태를 구분해 올바르게 fail-closed한다. 이 계약을 공통 원장으로 일반화하지 못했다.
- 권고: `execution_status`, `generation_status`, `quality_status`, `delivery_status`를 모든 job에 강제하고 기존 필드는 호환 alias로 둔다.

### H-04 · HIGH — 측정 백플레인이 아직 북극성 루프를 닫지 못함

- 실패 시나리오: 클론/판단은 대량 생성되지만 채점 불가가 누적되어 어떤 판단 방식이 엣지를 갖는지 알 수 없다.
- 증거: clone score 7,187건 중 6,939건(96.55%) unscorable. DR는 7/22 이후 정지. Goal B 생산 상태는 `MEASUREMENT_HOLD`다.
- 권고: 새 분석 축 추가를 중지하고 claim→outcome canonical mapping, producer golden, 외부 감사 조건을 먼저 닫는다. HOLD를 우회해 성과 숫자를 발표하면 안 된다.

### H-05 · HIGH — Shadow paper의 대부분이 RiskWarden 미배선으로 차단

- 실패 시나리오: shadow 원장이 커져 실험이 진행되는 것처럼 보이지만 대부분 사전 게이트에서 같은 이유로 거절되어 전략 성능 관측 표본이 아니다.
- 증거: 2,944 intent 중 2,875건(97.66%)이 `riskwarden_not_wired`.
- 권고: 권한 필요한 자본구조 입력과 RiskWarden 계약을 해결하기 전까지 shadow 건수를 진척 KPI로 쓰지 않는다.

### H-06 · HIGH — 장시간 핵심 파이프라인이 중첩 timeout

- 실패 시나리오: 자료 수집은 5,400초, quant multi는 내부 3,600초 후 죽는다. 스케줄이 겹쳐 다음 작업의 CPU·메모리·모델 한도를 잠식할 수 있다.
- 파일: `scripts/market_lens_quant_multi.py:27-29`의 단일 `subprocess.run(... timeout=3600)`; 외부 scheduler timeout 5,400초.
- 권고: 단계별 checkpoint·부분 재개·세부 timeout을 도입하고, 수집과 LLM 분석의 동시성 예산을 분리한다.

### H-07 · HIGH — 개인정보 백스톱이 “외부 금지”가 아니라 “비-Anthropic 외부만 금지”

- 실패 시나리오: 개인 보유 구조가 Codex 경로에서는 차단되지만 Claude subprocess로는 전송될 수 있다. 공급자 교체 여부와 무관하게 “개인 수치를 외부 서비스에 보내지 않는다”는 현재 정책과 맞지 않는다.
- 원인: `scripts/llm_provider.py:55-61`은 `PortfolioDataBlocked`를 비-Anthropic 외부용으로 정의하고 Anthropic/로컬 강등을 허용한다. `:813-816`, `:831-833`도 차단 후 안전 단에 Claude subprocess와 Ollama를 함께 둔다.
- 현재 감사에서는 개인 수치를 읽거나 외부로 전송하지 않았으며, 실제 과거 전송 여부도 판정하지 않았다. 이 발견은 코드상 가능한 경로에 대한 것이다.
- 권고: 개인 데이터가 감지되면 공급자 종류와 무관하게 **로컬 모델 또는 비식별·집계 입력만** 허용한다. 테스트는 Claude/Codex/Grok/NVIDIA 모두 차단, Ollama만 허용하는 표로 고정한다.

### M-01 · MEDIUM — Fact Library 활성 job의 경로가 틀림

- 실패 시나리오: 매주 실행되지만 항상 `scripts/fact_sync.py`를 찾지 못해 실패한다.
- 증거: 구현은 `harness/fact_sync.py:1`, job은 `cron/jobs.json:1255-1263`에서 `fact_sync.py`로 지정. scheduler는 스크립트를 `~/.hermes/scripts` 아래로 제한해 해석한다(`hermes-agent/cron/scheduler.py:987-1039`).
- 권고: `scripts/fact_sync.py`의 얇은 wrapper를 두거나 안전한 허용 루트 계약을 확장한다.

### M-02 · MEDIUM — cron schedule parser가 혼합 범위 목록을 못 읽음

- 실패 시나리오: `17 0-9,12,15,18,21,23 * * *` 같은 식에서 `0-9`를 int로 바꾸다 실패하여 해당 job의 지연 감지가 빠진다.
- 파일: `scripts/system_health_audit.py:259-282`.
- 권고: hour field parser를 range/list/step 공통 파서로 바꾸고 이 표현의 테스트를 추가한다.

### M-03 · MEDIUM — 패키지 경계가 약하고 단일 파일이 비대함

- 실패 시나리오: 공용 venv·`sys.path` 주입·절대 경로가 결합되어 Hermes Agent 업데이트나 실행 cwd 변경이 다수 스크립트를 동시에 깨뜨린다.
- 증거: prod 334개 파일의 path mutation, 40개 하드코딩, 루트 의존성 lock 부재, 수천 줄 모놀리스.
- 권고: 즉시 전면 리팩터링하지 말고, 자주 실패하는 `breaking`, `dossier`, `market_lens/run`부터 패키지 경계와 typed receipt를 분리한다.

### M-04 · MEDIUM — 문서와 실제 런타임의 drift

- 실패 시나리오: 오래된 지도를 보고 작업 수와 우선순위를 잘못 판단한다.
- 증거: `SYSTEM_MAP.md`는 6/25 기준 cron 70개를 말하지만 실제는 124개. 루트 markdown 158개, 설계/계획/seed 계열만 77개다.
- 권고: `PROJECT_CANON`과 `GOALS` 최신 블록만 명령 SSOT로 유지하고, `SYSTEM_MAP`은 자동 생성 스냅샷으로 바꾼다. 역사 문서는 archive index로 격리한다.

### M-05 · MEDIUM — 저장소·백업·상태 경계가 혼재

- 실패 시나리오: 도구가 빈 nested `.git`을 별도 저장소로 오인하거나, 업데이트/백업이 3GB대 런타임 사본을 반복 생성한다.
- 증거: 루트와 current/broken Hermes Agent 외에 `scripts/.git`, `scripts/data_sources/.git`; 깨진 Agent 사본 3개 약 9.2GB.
- 권고: 삭제는 별도 승인 후 수행. 먼저 보존 manifest를 만들고, nested `.git`의 의도와 복구 필요성을 확인한다.

## 6. “자동화가 전부 Claude인가?”

아니다. 다만 Claude가 기본이자 주력이다.

### 스케줄러 층

- 활성 110개 중 36개는 Hermes Agent 프롬프트 작업이고, 74개는 script-only다.
- 110개 모두 job별 provider/model이 없어서 전역 설정을 상속한다.
- 전역 Hermes Agent 설정은 현재 `claude-opus-4-8`을 로컬 custom proxy로 보낸다: `config.yaml:1-6`.

### 스크립트 내부 LLM 층

- `scripts/llm_provider.py:981-986`의 기본 provider는 Claude CLI subprocess다.
- 생존 사다리를 켠 경로는 Claude → Codex → Ollama 순이다: `llm_provider.py:823-833`.
- Codex provider의 기본 모델은 이미 `gpt-5.6-sol`이다: `llm_provider.py:442-451`.
- breaking monitor, market_lens run, portfolio dossier 등 일부 핵심은 사다리를 사용한다. Oracle처럼 Claude를 명시 고정한 경로도 있다.

최근 7일 `run_kind=prod` usage 원장:

| 실제 provider | 호출 | 추정 토큰 | 비중 해석 |
|---|---:|---:|---|
| Claude subprocess | 739 | 3.499M | 호출 80.9%, 토큰 71.0% |
| GPT/Codex | 94 | 0.695M | 모두 `gpt-5.6-sol` |
| 로컬 Ollama | 80 | 0.736M | 외부 전송 없는 로컬 단 |
| 합계 | 913 | 4.930M | - |

따라서 정확한 표현은 “전부 Claude”가 아니라 “Hermes Agent 전역과 직접 호출 기본은 Claude이고, Sol과 Ollama가 폴백·교차검증·일부 생산 경로로 이미 들어와 있다”다.

## 7. GPT-5.6 Sol을 기본으로 바꾸는 판단

### 결론

기술적으로 가능하고, 지금처럼 Claude 주간 한도가 실제 운영 장애가 된 상황에서는 Sol 비중을 늘리는 것이 타당하다. 그러나 전역 문자열을 한 번에 바꾸는 방식은 권하지 않는다. 두 호출 층을 따로 바꿔야 하고, 개인정보 경계·비용·프롬프트/도구 호환을 먼저 검증해야 한다.

### 왜 전면 즉시 전환은 위험한가

1. `config.yaml`만 바꾸면 36개 agent job 중심으로 바뀌고, 직접 `llm_provider`를 호출하는 script-only 경로는 그대로다.
2. `HERMES_LLM_PROVIDER` 기본만 바꾸면 직접 LLM 스크립트는 바뀌지만 Hermes Agent의 36개 작업은 그대로다.
3. Claude 모델명을 호출자가 넘겨도 CodexProvider는 이를 Sol로 정규화한다. 모델명 단순 치환보다 provider 계약 검증이 중요하다.
4. 개인 보유 구조는 외부 OpenAI 경로에서 현재 `CodexProvider`가 fail-closed 검사한다. 그러나 Claude는 허용하므로 외부 전송 금지 정책을 완전히 지키지는 못한다. dossier/risk 계열은 provider 전환보다 local/redacted 경계를 먼저 고쳐야 한다.
5. 최근 usage 원장에 USD 비용 필드가 없고 `run_kind` 오염도 있어 전체 전환 비용을 신뢰성 있게 계산할 수 없다.
6. 현재 Hermes Agent update가 회귀로 롤백된 상태라, 구버전 런타임에서 provider 전환까지 동시에 하면 장애 원인 분리가 어려워진다.

### 권장 라우팅

| 작업 유형 | 1순위 | 2순위 | 이유 |
|---|---|---|---|
| 개인 포트폴리오 원문·자본구조 | 로컬 Ollama 또는 결정론 코드 | 비식별·집계 후 별도 승인 경로 | 모든 외부 공급자 전송 금지 |
| 고난도 공개정보 종합·반론·코드 리뷰 | GPT-5.6 Sol | Claude | Sol 강점 활용, Claude quota 단일점 제거 |
| 대량 분류·추출·정규화 | 로컬 Ollama 또는 저비용 모델 | Sol | 모든 단순 작업에 Sol은 과함 |
| Oracle/최종 품질 판정 | 생성 모델과 다른 계보 | 로컬/Claude/Sol 교차 | 같은 모델이 생성과 판정을 독점하지 않게 함 |
| 장애 시 생존 사다리 | Sol → Claude → Ollama 또는 작업별 반대 순서 | - | quota 도메인을 분산 |

### 안전한 전환 순서

1. **0단계 — 판정기부터 고친다.** quota/auth 문구 false-green과 회귀 timeout fail-open을 먼저 수정한다.
2. **1단계 — 공개정보 3개 작업 shadow A/B.** 동일 입력으로 Claude와 Sol을 같이 돌리되 실제 발송은 기존 경로만 한다. 사실 오류, JSON 통과, 인과 완결성, 지연, 토큰을 비교한다.
3. **2단계 — 비개인 핵심 작업 10~20% canary.** system audit, public research synthesis, code review 계열부터 Sol 우선으로 바꾼다.
4. **3단계 — reset-aware router.** Claude/Sol의 한도·인증 상태를 공통 circuit으로 기록하고 정상 공급자를 먼저 고른다.
5. **4단계 — 1주 증거 후 기본값 결정.** 성공률·품질·지연·비용 네 축이 기준을 통과할 때만 전역 기본을 바꾼다.

현재 상태에서 가장 합리적인 1차안은 **“Sol을 비개인 고난도 작업의 기본으로 승격하고, 전 시스템 단일 기본으로는 아직 두지 않는다”**다. 이미 Sol provider와 실제 호출 증거가 있으므로 새 어댑터 개발보다 라우팅·상태 계약·A/B 계측이 일의 중심이다.

## 8. 우선순위

### P0 — 거짓 정상 제거

1. scheduler quota/auth 결과 분류
2. daily regression timeout/rebaseline fail-closed
3. 4상태 receipt 공통 스키마

### P1 — 북극성 루프 닫기

1. Goal B HOLD 조건 해소: canonical mapping, producer golden, 외부 감사
2. clone unscorable 원인 상위 패턴 제거
3. RiskWarden 권한 입력·계약 확정 후 shadow 재개

### P2 — 운영 병목

1. market_lens collect/quant checkpoint와 timeout 분해
2. Fact sync 경로 수정
3. 기술 리포트 JSON 계약 강화
4. schedule range parser 확장

### P3 — 구조 정리

1. 자동 생성 SYSTEM_MAP
2. 패키지/의존성 경계
3. nested Git·깨진 Agent 사본 보존 정책
4. 사용자 읽음·유용성 최소 계측

## 9. 재현·확인 명령

비밀을 출력하지 않는 읽기 전용 확인 예시다.

```bash
jq '{total:(.jobs|length), enabled:([.jobs[]|select(.enabled)]|length)}' ~/.hermes/cron/jobs.json

jq -r '.jobs[] | select(.enabled and .last_status != "ok") | [.name,.last_status] | @tsv' \
  ~/.hermes/cron/jobs.json

sqlite3 -readonly ~/.hermes/state/llm_usage.db \
  "SELECT run_kind,provider,COUNT(*),SUM(token_estimate) FROM usage GROUP BY run_kind,provider;"

~/.hermes/hermes-agent/venv/bin/python -m pytest \
  ~/.hermes/scripts/test_daily_regression.py \
  ~/.hermes/scripts/test_system_health_audit.py -q -p no:cacheprovider
```

## 10. 최종 판정

Hermes의 가장 좋은 자산은 이미 충분한 수집기와 방대한 검증 코드, 그리고 실패를 숨기지 않으려는 운영 설계다. 가장 큰 부채는 “생성된 것이 실제로 소비·채점·학습되었는가”를 닫는 공통 계약이 약하다는 점이다.

다음 개발 사이클은 새 렌즈를 더 만드는 것보다 아래 한 문장에 집중하는 편이 낫다.

> 모든 중요한 자동화는 실행·생성·검증·전달을 따로 기록하고, 판단은 결과와 연결되어 채점되며, 사용자가 실제로 쓴 것만 가치로 센다.
