virtual-insanity
← 리포트 목록

analyst-macro IG 크레딧 스프레드 태스크 반복 실패 — 지시문 개선안

2026-09-07 hermes [cowork, analyst-macro, completion-evidence-policy, ig-credit-spread, orchestrator]

analyst-macro IG 크레딧 스프레드 태스크 지시문 개선안

1. 사건 개요 (실측)

  • CMD#38417 → #38418("IG 크레딧 스프레드 근거 재제출") → #38421("미국 IG 회사채 크레딧 스프레드 재점검") 3연속 status=failed.
  • 조회(2026-09-07): sqlite3 /Users/ron/.hermes/data/ops_multiagent.db "SELECT id,claimed_by,status,title FROM bus_commands WHERE id IN (38418,38421)" → 둘 다 claimed_by=analyst-macro, status=failed.
  • 38418 result_note: `execution_artifact_path_not_found:

    /Users/ron/.hermes/workspace/scripts/pipeline/market_indicator.py, missing_verification_command`
  • 38421 result_note: `execution_artifact_path_not_found:

    /Users/ron/.hermes/workspace/scripts/pipeline/market_indicator.py, /Users/ron/.hermes/workspace/scripts/scripts/pipeline/vault_macro_bridge.py, missing_verification_command, missing_v....`

2. 근본원인 — "에이전트가 못 채워서"가 아니라 "지시문 자체가 존재하지 않는 경로를 가리킴"

두 실패 모두 4블록 미준수가 아니라 지시문에 박힌 파일 경로가 애초에 실존하지 않는다. 실측:

ls /Users/ron/.hermes/workspace/scripts/pipeline/market_indicator.py
→ No such file or directory
ls /Users/ron/.hermes/workspace/scripts/scripts/pipeline/vault_macro_bridge.py
→ No such file or directory (경로에 scripts/가 중복됨 — 오타)

실제 존재하는 파일명:

find scripts/pipeline -iname "*market_indicator*"
→ scripts/pipeline/market_indicator_tracker.py (실존)
find scripts/pipeline -iname "*vault_macro*"
→ scripts/pipeline/vault_macro_bridge.py (실존, scripts/ 중복 없이 1회)

즉 orchestrator가 태스크를 생성할 때 두 스크립트명을 줄임말(market_ indicator.py)과 경로 중복 오타(scripts/scripts/pipeline/...)로 잘못 박아 넣었고, analyst-macro가 그대로 인용하니 게이트의 execution_artifact_path_not_found 체크가 걸린 것이다. 에이전트가 근거를 안 쓴 게 아니라 지시받은 근거 경로 자체가 오염되어 있었다.

또한 두 태스크의 완료 기준 문구를 비교하면:

  • 38418 body: "4블록(결론/근거/검증/근거파일) 형식을 그대로 채운다"는

    라벨은 명시했으나, 실제로 인용해야 할 소스가 어느 파일인지는 틀린 경로로 지정했다.
  • 38421 body: "실측 스프레드 수치 + 변화폭 + 실패 재현 여부를 담은

    결과를 큐에 제출"만 있고 4블록 라벨(source_log_path:/ verification_command: 리터럴 요구) 언급이 아예 없다 — #38418 반려 직후 후속 태스크인데도 지시 강도가 오히려 후퇴함.

정리하면 이 태스크 계열의 실패 원인은 두 갈래다: 1. 경로 오염: 지시문이 존재하지 않는/오타난 파일 경로를 "근거파일"로 지정 → 게이트가 파일 존재 여부를 실제로 검사하므로 100% 반려. 2. 라벨 요구 후퇴: 재시도 지시문이 이전 실패의 4블록 요구사항을 유지하지 않고 자연어 완료기준으로 되돌아감 → 에이전트가 게이트가 요구하는 리터럴 필드명(source_log_path:, verification_command:)을 안 쓸 가능성이 커짐.

3. 실제 존재하는 1차/대체 데이터 소스 (검증됨)

이 태스크가 인용해야 했던 정확한 근거는 다음과 같다:

  • 1차 수집 스크립트: scripts/pipeline/macro_series_collector.py (39~40행에 BAMLH0A0HYM2="ICE BofA US HY OAS", BAMLC0A0CM="ICE BofA US IG OAS" 시리즈 정의 확인, 33행 INBOX_MACRO_DIR = ~/knowledge-agent/ 100-inbox/117 macro-series). 크론 등록 확인: grep -n macro_series_collector /Users/ron/.hermes/cron/jobs.json → 178행 /usr/bin/python3 .../macro_series_collector.py.
  • 실제 산출물(존재 확인):
  • /Users/ron/knowledge-agent/100-inbox/117 macro-series/BAMLC0A0CM_latest.json — last_updated: 2026-09-04, 최근값 2026-09-02=0.81(%) (2026-08-26=0.80 → 2026-09-02=0.81, 1주 변화 +1bp).
  • /Users/ron/knowledge-agent/100-inbox/117 macro-series/BAMLH0A0HYM2_latest.json — last_updated: 2026-09-06, 최근값 2026-09-03=2.65(%) (2026-08-27=2.63 → 2026-09-03=2.65, 1주 변화 +2bp).
  • /Users/ron/knowledge-agent/100-inbox/117 macro-series/_summary.md — generated_at: 2026-09-06T10:46:47+09:00, HY OAS 2026-09-03=2.65.
  • 대체 소스: scripts/shared/fred_client.py (FredClient.get_series("BAMLC0A0CM") / .get_latest_value(...), 단 SERIES 딕셔너리에 BAMLC0A0CM/BAMLH0A0HYM2가 사전 등록돼 있지 않으므로 series_id 문자열을 직접 인자로 넘겨야 함 — 140행 get_series(self, series_id: str, ...) 시그니처 확인). FRED API 키는 ~/.hermes/fred_api_key에 존재(확인: ls -la → 33바이트 파일 존재, 2026-03-11 생성).

4. 개선 전 지시문 (원문, #38421 body 그대로)

대상: ICE BofA US Corporate Index OAS(FRED 시리즈 BAMLC0A0CM), LQD ETF
가격/거래량, CDX IG 지수. #38418 'IG 크레딧 스프레드 근거' 태스크가
실패 처리된 채로 종결되었고 이 주제는 해리 최우선 관심사(미국 IG
회사채)다. 실행: 위 데이터소스로 현재 스프레드 수준과 최근 1주/1개월
변화(bp 단위)를 실제 수치로 확인하고, #38418이 실패한 원인(데이터소스
접근 문제였는지, 분석 로직 문제였는지)을 함께 짚는다. 완료 기준: 실측
스프레드 수치 + 변화폭 + 실패 재현 여부를 담은 결과를 큐에 제출.

문제점: (a) 근거파일 경로를 아예 지정 안 함 → analyst-macro가 임의로 잘못된 경로를 인용하게 방치, (b) 4블록 라벨 요구 없음, (c) LQD/CDX IG는 FRED 시리즈가 아니라 별도 벤더 데이터라 실제 접근 가능한 소스인지 사전 확인이 안 됨(이 초안에서는 검증 못함 — 아래 개선안에서 1차 소스만 남기고 별도 확인 필요 항목으로 명시).

5. 개선 후 지시문 (초안)

[작업] 미국 IG 회사채 크레딧 스프레드 재점검 (#38418/#38421 반복실패 재작성)

대상 시리즈(1차, 존재 확인됨):
- BAMLC0A0CM (ICE BofA US IG OAS) — 캐시:
  /Users/ron/knowledge-agent/100-inbox/117 macro-series/BAMLC0A0CM_latest.json
- BAMLH0A0HYM2 (ICE BofA US HY OAS, 병기용) — 캐시:
  /Users/ron/knowledge-agent/100-inbox/117 macro-series/BAMLH0A0HYM2_latest.json

실행 순서:
1. 위 두 JSON 파일을 read_file로 직접 읽어 최신값과 last_updated를
   확인한다. last_updated가 오늘 기준 3영업일 이상 지났으면
   `python3 scripts/pipeline/macro_series_collector.py --series
   BAMLC0A0CM` (및 BAMLH0A0HYM2)를 재실행해 갱신한다 — 이 재실행 명령
   자체가 "검증:" 블록의 verification_command가 된다.
2. 최신치와 1주 전(영업일 기준 -5)/1개월 전(-21) 값을 JSON의 `data`
   배열에서 직접 비교해 bp 변화를 계산한다. (IG는 %, 1%=100bp 단위로
   환산 — 예: 0.80% → 0.81%는 +1bp)
3. LQD 가격/거래량, CDX IG는 이 워크스페이스에 확인된 수집 파이프라인이
   없다 — 시도할 경우 whitelist 밖 도구(curl 등 외부 API) 호출 결과를
   검증 근거로 쓰지 않는다(정책 §5, `agent_completion_submission_standard.md`).
   접근 불가면 "검증:" 블록에 "LQD/CDX IG: 워크스페이스 내 수집 파이프라인
   부재, 확인 불가"로 명시하고 이 부분만 스코프에서 제외한다 — 억지로
   채우려다 whitelist 차단 응답을 근거로 쓰면 자동 반려 대상이다.
4. #38417/#38418 실패 원인을 재현 확인한다:
   `grep -n "market_indicator_tracker\|vault_macro_bridge" 원래 body`
   대신, 이번엔 존재하는 스크립트 `macro_series_collector.py`만
   실행값으로 인용한다 — 잘못된 파일명을 반복 인용하지 않는다.

완료 기준 (result_note에 아래 4블록을 이 라벨 그대로, 순서대로 채울 것
— 이 형식이 없으면 게이트가 자동 반려한다):

결론: <IG OAS 방향+수치, HY 병기 한 줄>
근거: source_log_path: /Users/ron/knowledge-agent/100-inbox/117 macro-series/BAMLC0A0CM_latest.json (및 BAMLH0A0HYM2_latest.json), 조회 <YYYY-MM-DD HH:MM KST>
검증: verification_command: <read_file 실행 또는 macro_series_collector.py 재실행 명령> → <실제 last_updated/최신값/1주 변화 bp>
근거파일: /Users/ron/knowledge-agent/100-inbox/117 macro-series/BAMLC0A0CM_latest.json:<data 배열 내 최신 2개 항목 줄> "<원문 인용>"
다음 행동: <후속 조치 또는 "추가 조치 없음">

금지: (1) scripts/pipeline/market_indicator.py, scripts/scripts/pipeline/
vault_macro_bridge.py 등 실존하지 않는 경로 인용 금지 — 인용 전
`search_files`/`ls`로 실존을 먼저 확인한다. (2) "정상 확인함"/"확인함"
단독 서술 금지. (3) whitelist 차단 응답(blocked: not in whitelist)을
검증 근거로 인용 금지.

6. 어떤 실패 원인을 어떻게 막는가

실패 원인(실측) 개선 조치 기대 효과
존재하지 않는 market_indicator.py 경로를 근거파일로 지정 → execution_artifact_path_not_found 지시문에 사전 검증된 실존 경로(BAMLC0A0CM_latest.json 등)를 직접 박아넣고, "인용 전 search_files로 실존 확인" 규칙 명시 경로 오염발 반려(#38418/#38421 공통 사유) 원천 차단
scripts/scripts/pipeline/... 중복 오타 경로 정확한 단일 경로(scripts/pipeline/vault_macro_bridge.py)를 언급하지 않고 애초에 이번 태스크 스코프에서 제외(불필요한 참조 제거) 오타로 인한 반려 재발 방지
#38421이 4블록 라벨(source_log_path:/verification_command:)을 요구하지 않아 자연어 서술로 되돌아감 → missing_verification_command 개선 지시문에 리터럴 라벨 템플릿을 그대로 박아넣어 자가점검 없이 복붙 가능하게 함 라벨 누락형 반려(missing_verification_command, missing_verification_value) 감소
LQD/CDX IG처럼 수집 파이프라인이 없는 소스를 억지로 확인하려다 whitelist 차단 응답을 근거로 쓸 위험 (정책 §5 기존 결함 패턴) 접근 불가 시 명시적으로 스코프 제외하고 "확인 불가"로 쓰라고 사전 지시 truncated_unverifiable_evidence/whitelist 차단 오용형 반려 예방

7. 검증방법 (본 개선안 성공/실패 판정)

  • KPI: 이 개선 지시문으로 재발행한 CMD가 status=done으로 1회 재시도 내 통과하는지.
  • 측정 명령: sqlite3 /Users/ron/.hermes/data/ops_multiagent.db \ "SELECT id,status,result_note FROM bus_commands \ WHERE title LIKE '%IG 회사채 크레딧 스프레드%' \ AND datetime(created_at) >= datetime('now') \ ORDER BY id DESC LIMIT 3;"
  • 기대값: 신규 CMD의 result_note에 execution_artifact_path_not_found 라벨이 재발하지 않고(경로를 사전 검증했으므로), source_log_path:/ verification_command: 리터럴이 포함된 상태로 status=done 저장.
  • 롤백 조건: 개선 지시문 적용 후에도 동일하게 execution_artifact_path_not_found가 재발하면, 이는 지시문 문제가 아니라 게이트의 파일존재검사 로직 자체(scripts/agent_queue_worker.py 또는 public_result_formatter.py)가 상대경로/절대경로 불일치 등으로 오탐하는 별개 결함 가능성 — claude-code-queue-evidence-gate 스킬 절차로 codex에 코드 재검토를 위임한다.

8. 저장 파일 경로

/Users/ron/knowledge-agent/400-reports/260907_hermes_analyst-macro-ig-credit-task-instruction-fix.md (본 파일)