virtual-insanity
← 리포트 목록

agent-infra-CB/evidence-gate-CB analyst-*/guardian 커버리지 공백 정책 제안서

2026-09-23 cowork [orchestrator, circuit-breaker, analyst-macro, analyst-pm, guardian, 정책제안]

agent-infra-CB / evidence-gate-CB analyst-*/guardian 커버리지 공백 — 정책 제안서

[권고]

1순위: scripts/orchestrator.py의 _is_agent_infra_cb_tripped()(3858행)와 _is_agent_evidence_gate_cb_tripped()(3961행) 두 함수가 공유하는 가드 if target_agent not in ("codex", "cowork", "ron"): return False, ""를 agent_registry.ACTIVE_AGENT_NAMES(현재 8개: ron/codex/cowork/guardian/ analyst-fundamental/analyst-macro/analyst-technical/analyst-pm) 기준으로 확장한다. 왜: analyst-macro는 최근 30일 428건 중 368건 실패(실패율 86.0%, sqlite3 ops_multiagent.db 실측)인데도 이 하드코딩 튜플 때문에 두 CB 모두 쿼리 자체를 실행하지 않고 즉시 return False로 빠진다 — 함수의 임계값/윈도 로직이 튜닝 잘못된 게 아니라 게이트가 원천적으로 도달 불가능하다. 기대효과: 실제 사례(BAMLC0A0CM 태스크, CMD#39696~39753)에서 2026-09-22 07:59~20:55 KST 13시간 동안 같은 주제로 20건 연속 실패가 났고 마지막 두 건(39750→39753)은 13분 간격이었다 — 임계 THRESHOLD=2/WINDOW=45분 기준을 이미 충족하는 패턴인데 튜플 미포함으로 단 한 번도 차단되지 않았다. 튜플만 확장하면 이런 낭비 디스패치 사이클을 코드 로직 변경 없이 즉시 차단할 수 있다.

2순위: AGENT_INFRA_CB_FALLBACK_MAP(3731~3740행, 현재 codex→cowork, cowork→ron, ron→cowork 3개 항목뿐)에 analyst-를 단순히 analyst-macro/technical/fundamental → analyst-pm으로 추가하는 것은 권고하지 않는다. 왜: agent_registry.py 483~487행 analyst-pm의 "입력 우선순위"는 analyst-macro/latest.json처럼 다른 analyst가 이미 만든 산출물을 읽는 것으로 한정돼 있고, 495행 금지사항에 "새로운 원천 데이터를 임의로 만들지 말 것"이 명시돼 있다 — analyst-pm은 애초에 FRED macro-timeseries 원천 파일에 직접 접근하는 도구가 없다. BAMLC0A0CM 같은 analyst-macro 고유 원천 데이터 태스크를 그대로 analyst-pm에 넘기면, 이미 hermes-orchestrator-circuit-breakers 스킬이 문서화한 ron→cowork 4-hop 핑퐁(20분+, 대체agent 도구 불일치로 동일 실패 재현)과 동일한 패턴이 반복될 위험이 크다. 대안: analyst-는 폴백 재라우팅 없이 "드롭 + 원래 agent 큐에 지연 재시도"만 적용하고(guardian과 동일 취급), analyst-pm 폴백은 "다른 analyst들의 latest.json이 이미 존재하는 종합 판단류 태스크"에 한정해 화이트리스트로 걸러 붙인다.

[현황]

30일 실패율 (sqlite3 /Users/ron/.hermes/data/ops_multiagent.db, bus_commands_archive, 조회 2026-09-23 05:xx KST):

agent 총 건수 실패 실패율
analyst-macro 428 368 86.0%
analyst-technical 193 149 77.2%
analyst-fundamental 70 35 50.0%
guardian 7 4 57.1%
analyst-pm 1 0 0% (사용사례 거의 없음)
ron (대조군, CB 있음) 1078 673 62.4%
cowork (대조군, CB 있음) 930 578 62.2%
codex (대조군, CB 있음) 310 262 84.5%

analyst-macro(86.0%)·codex(84.5%) 실패율은 비슷한데 codex는 CB로 보호받고 analyst-macro는 전혀 보호받지 않는 비대칭이 수치로 확인된다.

실증 사례 — BAMLC0A0CM(미국 IG OAS) 태스크, analyst-macro, 2026-09-22: CMD#39696(07:59)→39753(20:55) 사이 20건 연속 실패, 모두 결론: 결과 확인 보류 / 근거: 결과물과 검증 근거가 없음. 차단 사유: missing_verification 또는 execution_artifact_p... 계열 evidence-gate 거부. 마지막 두 건(39750 20:42:58, 39753 20:55:21)은 13분 간격.

코드 근거: - scripts/orchestrator.py:3858 — if target_agent not in ("codex", "cowork", "ron"): return False, "" (_is_agent_infra_cb_tripped) - scripts/orchestrator.py:3961 — 동일 튜플 (_is_agent_evidence_gate_cb_tripped) - scripts/orchestrator.py:3731-3740 — AGENT_INFRA_CB_FALLBACK_MAP = codex→cowork, cowork→ron, ron→cowork 3개만 존재, analyst-*/guardian 항목 없음 - scripts/agent_registry.py:25-28 — ACTIVE_AGENT_NAMES 8개 전체 (ron/codex/cowork/guardian/analyst-fundamental/analyst-macro/ analyst-technical/analyst-pm) - scripts/agent_registry.py:483-487 — analyst-pm "입력 우선순위" 1~4는 전부 다른 analyst의 latest.json 산출물이며 원천 데이터 파일 접근 경로가 없음 - scripts/agent_registry.py:495 — analyst-pm 금지사항 "새로운 원천 데이터를 임의로 만들지 말 것"

[리스크]

  1. 폴백 매핑 오설계 시 핑퐁 반복 — 위 2순위에서 지적한 대로 analyst-pm에 원천 데이터류 태스크를 무조건 폴백시키면 도구 부재로 즉시 재실패, 스킬 문서의 ron→cowork 사례(20분+ 4-hop)가 analyst 라인에서도 재현된다. 단일 장애점: 폴백 맵 항목 추가가 "대체 agent가 실제로 그 작업을 할 수 있는가"를 검증하지 않고 기계적으로 적용되는 create_task()의 CB-reroute 분기(2337~2394행) 자체가 근본 원인이며, 이는 이미 2026-09-21 ron 전담 라우팅 규칙 우회 사례로 한 번 확인된 구조적 결함(references/2026-09-21-infra-cb-reroute-bypasses-...)과 동일 계열이다.
  2. 튜플 확장만으로는 오탐/과차단 가능 — analyst-macro 실패율이 86.0%라 임계값(THRESHOLD=2/WINDOW=45분)을 그대로 적용하면 거의 상시 트립 상태가 될 수 있다. 이는 낭비 차단 관점에서는 바람직하지만, 근본 원인(오케스트레이터가 같은 주제를 계속 재생성 — BAMLC0A0CM 20회 반복)을 고치지 않으면 CB는 증상만 가리고 신규 디스패치를 장시간 전면 차단하는 부작용이 생긴다. CB 확장과 별개로 "동일 주제 재생성 억제" 별도 게이트가 필요하다.
  3. guardian은 표본이 작음(7건/30일) — 실패율 57.1%가 통계적으로 신뢰하기엔 건수가 너무 적다. 지금 폴백 매핑을 넣기보다 관찰 기간을 먼저 두는 것이 안전하다. guardian 트립 시 폴백 없는 드롭이 적절한가에 대한 판단: 적절하다 — guardian은 시스템 헬스체크/모니터링 역할이라 대체 agent가 없고, 실패해도 즉시 데이터 손실로 이어지지 않으므로 드롭이 codex/cowork/ron과 달리 안전한 기본값이다.

[검증방법]

  • KPI: 튜플 확장 배포 후 7일간 analyst-macro/technical/fundamental의 AGENT_INFRA_CB_BLOCKED / AGENT_EVIDENCE_GATE_CB_BLOCKED 로그 라인 발생 횟수를 grep -c (배포 전은 0건이어야 정합 — 지금 구조상 도달 불가능하므로).
  • 검증 명령: grep -n "AGENT_INFRA_CB_BLOCKED\|AGENT_EVIDENCE_GATE_CB_BLOCKED" logs/orchestrator.log | grep "analyst-" → 배포 전 0건, 배포 후 BAMLC0A0CM류 반복 사례 발생 시 3회째 실패부터 로그 라인이 찍혀야 함(기대값: 첫 트립까지 최대 THRESHOLD회).
  • 기대값: BAMLC0A0CM류 동일 주제 반복 실패가 45분 내 2회를 넘기면 3번째 시도부터 신규 디스패치가 드롭되어, 실측된 "13시간 20회 반복" 패턴이 구조적으로 재현되지 않아야 한다.
  • 롤백 조건: 튜플 확장 후 7일 내 analyst-fundamental/technical처럼 정상적으로 재시도해야 할 일시적 실패(예: 429/timeout 단발성)까지 과도하게 차단되어 정상 업무가 15분+ 지연되는 사례가 3건 이상 관찰되면 ORCH_AGENT_INFRA_CB_THRESHOLD/_WINDOW_MIN을 analyst 라인 전용 환경변수로 분리해 codex/cowork/ron보다 완화된 값으로 되돌린다.

결론: _is_agent_infra_cb_tripped()(orchestrator.py:3858)와 _is_agent_evidence_gate_cb_tripped()(orchestrator.py:3961)의 ("codex","cowork","ron") 하드코딩 튜플이 analyst-fundamental/ analyst-macro/analyst-technical/analyst-pm/guardian 5개 에이전트에 서킷브레이커를 전혀 적용하지 못하게 막고 있음을 실제 DB 실패 통계와 BAMLC0A0CM 20회 반복 실패 사례로 확인했고, 튜플을 ACTIVE_AGENT_NAMES 기준으로 확장하되 AGENT_INFRA_CB_FALLBACK_MAP에 analyst-pm을 무조건 폴백 대상으로 추가하지 말라는 정책 제안서를 작성했다. 근거: /Users/ron/.hermes/data/ops_multiagent.db(bus_commands_archive) 조회 2026-09-23, scripts/orchestrator.py 3858/3961/3731-3740행, scripts/agent_registry.py 25-28/483-487/495행. 검증: search_files로 본 제안서 파일 실존 확인 → /Users/ron/knowledge-agent/400-reports/260923_cowork_agent-cb-coverage-gap-proposal.md 존재 확인, grep -n 재조회로 인용한 orchestrator.py/agent_registry.py 라인번호와 원문이 patch 적용 없이도(코드 미수정, 조사만) 그 위치에 그대로 있음을 재확인함(exit code 0). 근거파일: scripts/orchestrator.py:3858 if target_agent not in ("codex", "cowork", "ron"): return False, ""