미국 IG 올인 금리 분해 태스크 3연속 반려 원인과 애널리스트 보고서형 태스크 발행 양식 방지안
미국 IG 올인 금리 분해 태스크 3연속 반려 원인과 방지안
결론(원인 판정)
세 번의 반려는 분석 결과물이 없어서 생긴 것이 아니다. 결과물 260927_hermes_us-ig-all-in-yield-decomp.md는 첫 반려 건(#40172) 실행 중인 12:19:59에 이미 생성됐다(파일 생성시각 stat 실측). 원인은 세 가지가 겹친 것이다.
1. 계획문 제출(#40172, #40175): 완료 보고가 실행 결과가 아니라 [액션]으로 시작하는 "앞으로 돌릴 명령" 목록이었고, 그 명령마저 market_indicator_tracker.py에 존재하지 않는 옵션(--target, --mode, --compare, --files, --dates)을 지어냈다. 이 스크립트의 실제 옵션은 --notify, --dry-run 둘뿐이다(2160~2161행). #40175는 날짜도 2024-09-16/23으로 연도를 틀렸다.
2. 오케스트레이터 재발행 본문의 파일명 오기(#40173): 1차 본문(#40172)은 all-in으로 지시했는데, 재발행 본문(#40173) 16행은 하이픈이 빠진 allin으로 다시 타이핑했다. analyst-macro는 지시대로 allin 경로를 인용했고, 그 파일은 한 번도 존재한 적 없다(ls | grep -c allin → 0). 즉 에이전트 실수가 아니라 발행 본문 오타가 1차 원인이다.
3. 다시 돌릴 수 있는 검증 명령을 본문이 미리 주지 않음(#40172, #40175): 본문이 "파싱 명령과 결과값을 적으라"고만 하고 실행 가능한 명령 1줄을 확정해 주지 않아, 에이전트가 가짜 옵션 명령을 만들어 냈다. 4번째 발행 #40177은 실존 검증 스크립트와 명령을 본문에 고정해 주자 1회에 마감됐다(REPORT_EXISTS=True MATCH=22/22, exit 0 — 13:4x 재실행으로 재확인).
파일명 접두어 hermes와 analyst-macro 혼동은 없었다 — 4건 모두 260927_hermes_...를 썼고, 차이는 오직 all-in / allin 하이픈 한 글자다.
[현황] 4건 대조표
조회: sqlite3 -readonly /Users/ron/.hermes/data/ops_multiagent.db "SELECT id,claimed_by,status,title,result_note FROM bus_commands WHERE id IN (40172,40173,40175,40177)" → 4행(출력 12줄), 2026-09-27 13:37 KST. 반려 당시 원문 제출물은 logs/completion_evidence_blocked.jsonl 18570~18572행의 note_preview로 대조.
| CMD | 담당 | 실행 구간(KST) | 반려 사유 | 본문 지시 경로 | 제출물에서 틀린 필드 | 검증 명령 재실행 가능 여부 |
|---|---|---|---|---|---|---|
| #40172 | analyst-macro | 12:17:06~12:20:10 | missing_verification_result | ...us-ig-all-in-... (정확) |
제출물이 [액션] python3 scripts/pipeline/market_indicator_tracker.py --target "BAMLC0A0CM.json,..." --mode "latest_observations" ... 계획문. 실행 결과·exit code 없음 |
불가 — --target/--mode 옵션 미존재. 단, 결과물은 이 구간 12:19:59에 실제 생성됨 |
| #40173 | analyst-macro | 12:32:38~12:34:12 | execution_artifact_path_not_found: .../260927_hermes_us-ig-allin-yield-decomp.md |
...us-ig-allin-... (본문 오타) |
근거파일 경로가 본문 오타를 그대로 따라 allin |
부분 가능 — 본문이 준 python3 -c "import json;..." 1줄은 실존 JSON을 읽으므로 재실행 가능. 막힌 것은 경로 실존 게이트 |
| #40175 | ron | 12:48:57~12:51:37 | verification_command_unverifiable | ...us-ig-all-in-... (정확) |
제출물이 [액션] → python3 scripts/pipeline/market_indicator_tracker.py --compare --files ... --dates "2024-09-16,2024-09-23" --target-file ... 계획문. 연도 오기(2024) |
불가 — --compare/--files/--dates/--target-file 옵션 미존재. 같은 구간 12:50:05에 검증 스크립트가 만들어졌지만 인용하지 않음. 보고서 mtime도 12:50:44로 갱신(링크 추가로 추정, 미확인) |
| #40177 | ron | 13:20:44~13:21:38 | 없음(done) | ...us-ig-all-in-... + "allin 인용 금지" 명시 |
해당 없음 | 가능 — 본문이 python3 scripts/verify_ig_allin_decomp_260927.py를 고정 제공 |
참고: 이 주제 첫 발행 #40170(11:31)은 모델 응답 시간초과(인프라)로 이번 표의 범위 밖이다. 총 5회 발행, 마감까지 약 1시간 50분(11:31→13:21).
[현황] 기존 정책과의 대조
config/agent_completion_submission_standard.md539행:넣는다. "검증했다"는 서술만으로는 verification_command_unverifiable로— #40175가 정확히 이 조항에 걸렸다.- 같은 문서 747행:
1. 명령을 실제로 실행한다 — "실행할 명령"이 아니라 "실행해서 받은— #40172/#40175의[액션]계획문 제출이 09-12 #38594(LQD)와 같은 유형의 재발이다. 규칙은 이미 있지만 태스크 본문 단계에서 재실행 가능한 명령을 주지 않으면 에이전트가 명령을 지어내는 문제는 막지 못했다. - 같은 문서 534~536행: 근거 경로는 제출 직전
search_files/find로 실존 재확인 — #40173에서 에이전트가 이를 지켰다면allin부재를 알아챘을 것이다. 그러나 발행 본문이 틀린 경로를 준 상태에서 에이전트 쪽 재확인에만 의존하는 것은 구조적으로 약하다. config/completion_evidence_policy.md933~945행: "검증:" 값 안에 워크스페이스 경로 토큰이 없으면 무조건verification_command_unverifiable— 본문이 경로 토큰이 들어 있는 명령 1줄을 미리 주면 이 사유는 원천 차단된다.
[권고]
- 1순위: 애널리스트 보고서형 태스크 본문에 아래 고정 문구 블록을 오케스트레이터가 그대로 삽입(codex에
orchestrator.py태스크 본문 생성부 반영 위임). 근거: 3건 반려 중 3건 모두가 이 블록의 한 항목으로 막힌다(파일명 고정→#40173, 재실행 명령 고정→#40172/#40175). 기대효과: 같은 유형(보고서형) 반려 재발 0건, 주제당 발행 횟수 평균 4~5회→1~2회. - 2순위: 재발행 전 "이미 결과물이 있는가" 선검사 규칙. 재발행 본문을 쓰기 전에
test -f <지시했던 경로>와ls <폴더> | grep <topic 일부>를 먼저 돌려, 있으면 "재분석"이 아니라 "기존 결과물 완료 등록"(#40177 방식)으로 발행한다. 경로는 ls 출력에서 복사하고 손으로 다시 타이핑하지 않는다. 근거: #40173·#40175 두 번의 헛발행이 결과물 존재 확인 없이 나갔다. 기대효과: 불필요 재발행 2건/주제 절감. - 3순위(관찰 과제): 완료 제출물이
[액션]으로 시작하는 경우(#40172·#40175 모두 해당)는 실행 루프의 중간 산출물이 완료 보고로 넘어간 것으로 보인다(미확인). guardian에 최근 7일completion_evidence_blocked.jsonl중 note_preview가[액션]으로 시작하는 건수 집계를 요청해 규모부터 확인한다.
오케스트레이터 고정 문구 초안(보고서형 태스크 본문 끝에 그대로 붙임)
[산출물 규칙 — 고정]
산출물 경로: /Users/ron/knowledge-agent/400-reports/{YYMMDD}_{source}_{topic}.md
- YYMMDD = 발행일 6자리, source = hermes|claude|pipeline|cowork 중 하나(애널리스트 에이전트 산출물은 hermes), topic = 영소문자·숫자·하이픈만(공백·언더스코어 금지).
- 이번 태스크의 확정 경로(이 문자열을 복사해 쓰고 다시 타이핑하지 않는다): {확정경로}
- frontmatter 필수: title, date, source, tags.
- 재발행 태스크라면: 위 경로가 이미 있으면(test -f) 분석을 다시 하지 말고 기존 파일을 검증만 해 완료 보고한다.
[검증 규칙 — 고정]
- 검증 명령(워크스페이스 루트 /Users/ron/.hermes/workspace 에서 이 한 줄을 그대로 실행):
test -f {확정경로} && python3 -c "import json,sys;[print(s,json.load(open('memory/macro-timeseries/'+s+'.json'))['data'][-1]) for s in {시리즈목록}]"; echo "exit code $?"
- 존재하지 않는 스크립트 옵션을 만들어 쓰지 않는다(예: market_indicator_tracker.py 의 옵션은 --notify, --dry-run 뿐).
- "[액션]"으로 시작하는 계획문을 완료 보고로 제출하지 않는다. 명령을 실제로 실행하고 받은 출력을 인용한다.
[완료 보고 — 고정]
결론: {판단 한 줄, 완료형, 숫자 포함}
근거: {확정경로}, {원천 파일 경로}, 조회 YYYY-MM-DD HH:MM KST
검증: 위 검증 명령 한 줄 그대로 → stdout 요약 → exit code 0
근거파일: {확정경로}:{줄번호} "{그 줄 원문 일부}"
exit code가 0이 아니면 done 대신 failed로 실제 오류를 적는다.
[리스크]
- 단일 장애점 = 발행 본문의 수작업 경로 타이핑: 오케스트레이터 LLM이 재발행 때마다 경로를 새로 생성하므로 하이픈·언더스코어·대소문자 편차가 생긴다. 게이트는 문자열 정확 일치로 실존을 보므로 한 글자만 달라도 반려된다.
- 의존관계: 고정 문구의 검증 명령 예시는
memory/macro-timeseries/*.json의data키 구조에 의존한다. 수집기 저장 형식이 바뀌면 예시 명령이 깨진다 — 시리즈형이 아닌 보고서는test -f+head -5형태로 대체해야 한다. - 가짜 옵션 생성 위험: 본문에 명령을 고정하지 않으면 에이전트가 "그럴듯한 CLI 옵션"을 지어낸다(이번 2건). 고정 문구가 반영되기 전까지 같은 유형 재발 가능.
- 본 문서 작성 과정에서 코드는 수정하지 않았다.
[검증방법]
- KPI 1: 반영 후 7일간 제목에 "보고서/분해/주간" 등 보고서형 키워드가 있는 analyst-*·ron 태스크의 반려 중
execution_artifact_path_not_found·verification_command_unverifiable·missing_verification_result합계. 기대값 0~1건(이번 주제 1건에서 3건 발생 대비). - KPI 2: 동일 주제 재발행 횟수. 기대값 ≤2회.
- 측정 명령:
grep -c '"reasons": \["execution_artifact_path_not_found' /Users/ron/.hermes/workspace/logs/completion_evidence_blocked.jsonl반영 전후 증가분 비교,sqlite3 -readonly /Users/ron/.hermes/data/ops_multiagent.db "SELECT title,count(*) FROM bus_commands WHERE created_at>=date('now','-7 day') GROUP BY title HAVING count(*)>=3". - 롤백 조건: 고정 문구 삽입 후 보고서형 태스크의
failed비율이 반영 전 7일 대비 증가하면 문구 삽입을 되돌리고 원인 재조사.
재현 근거
- 결과물 생성시각:
stat -f '%SB' .../260927_hermes_us-ig-all-in-yield-decomp.md→ birth 09-27 12:19:59, mtime 12:50:44, 4529바이트. - 검증 스크립트:
scripts/verify_ig_allin_decomp_260927.pybirth 12:50:05.python3 scripts/verify_ig_allin_decomp_260927.py→REPORT_EXISTS=True MATCH=22/22, exit 0. ls /Users/ron/knowledge-agent/400-reports/ | grep -c allin→ 0.grep -n add_argument scripts/pipeline/market_indicator_tracker.py→ 2160행--notify, 2161행--dry-run2건뿐.
관련: [[260927_hermes_us-ig-all-in-yield-decomp]] [[260907_hermes_analyst-macro-ig-credit-task-instruction-fix]]