virtual-insanity
← 리포트 목록

guardian needs_evidence 반려 반복 원인 분석과 4블록 완료보고 개선안

2026-10-12 claude [guardian, needs_evidence, completion-evidence, 4블록, 제안서, hermes-ops]

guardian needs_evidence 반려 반복 원인 분석과 4블록 완료보고 개선안

조회: 2026-10-12 KST, sqlite3 -readonly /Users/ron/.hermes/data/ops_multiagent.db, status='needs_evidence' 32행. 코드·설정·DB는 수정하지 않았다.

[권고]

1순위 (코드, codex 후속): scripts/agent_queue_worker.py의 _completion_block_reasons(3995행)에서 "확인 보류"(4005행)·"검증 근거가 없음"·"근거 없음" 같은 문구 검사가 보고서 본문에 인용된 라벨 이름까지 잡는다. 인용부호·백틱·괄호 안, 그리고 "라벨 N건" 형태의 집계 문장은 검사 대상에서 빼야 한다. - 이유: guardian 보고가 "반려 라벨 이름"을 설명하는 순간 게이트가 그 보고를 반려한다. 직접 재현했다(아래 [현황] 3). - 기대효과: guardian 22건 중 메타 집계 태스크 17건(77.3%)의 자기 반려 고리가 끊긴다.

2순위 (코드, codex 후속): _codex_has_verification_result_field(7127행)와 _CODEX_VERIFICATION_EXIT_CODE_RE(7030행)는 missing_verification_exit_code 9건의 "exit_code 9"를 실제 종료코드 9로 읽는다. 라벨 이름 토큰을 먼저 지우고 exit code 0 리터럴만 읽게 고친다. 또 "검증:" 줄바꿈 뒤 불릿 형식(검증:\n- ... exit code 0, 통과)도 인식해야 한다(현재 missing_verification_result). - 기대효과: invalid_verification_exit_code 7건(21.9%)과 missing_verification_exit_code 일부(10건 중 라벨 오독 사례)가 줄어든다. 이 비율은 상한 추정이며 건별 원인 확정은 아니다.

3순위 (프롬프트·문서, codex 후속): scripts/agent_registry.py의 guardian 프롬프트(311행~)에 "집계·분류형 태스크 전용 4블록 틀" 한 블록을 넣는다. 현재 guardian 프롬프트는 일반 4줄 형식만 안내하고, cowork 프롬프트에는 있는 "비코딩 완료 보고 추가 규칙" 절이 없다. - 기대효과: 라벨 단독 서술·이전 보고 인용 습관을 줄인다.

4순위 (운영, ron/orchestrator): "needs_evidence N건 집계·분류" 메타 태스크의 자동 재발행을 멈추고 1건으로 합친다. guardian 22건 중 17건(77.3%)이 제목에 반려·needs_evidence 집계가 든 같은 유형이다. 이 유형은 10월 4일~11일에 반복 발행됐고 전부 반려됐다.

[현황]

  1. 집계 (필수 검증: 합계 32)
에이전트 건수 비율
guardian 22 68.8%
analyst-pm 4 12.5%
cowork 3 9.4%
analyst-macro 2 6.3%
ron 1 3.1%
합계 32 100%
  1. 건별 대표 사유 (한 건당 1개, 배타 분류)
사유 guardian pm macro cowork ron 합
missing_verification_exit_code 단독 7 0 0 0 0 7
invalid_verification_exit_code 5 0 0 1 1 7
missing_result_or_verification 0 4 2 0 0 6
라벨 없는 일반 "결과 확인 보류" (검증 근거 없음 3건 포함) 7 0 0 0 0 7
missing_execution_artifact + missing_verification_command + exit_code 2 0 0 0 0 2
execution_artifact_path_not_found (#41323, 존재하지 않는 workspace/jobs.json 인용) 1 0 0 0 0 1
verification_command_unverifiable 0 0 0 1 0 1
completion_result_note_forces_rework 0 0 0 1 0 1
합계 22 4 2 3 1 32

인프라 지연(llm_infra_failure 계열)이 차단 사유 라벨인 건은 32건 중 0건이다. 전부 증거 게이트 반려다.

  1. 구조적 원인 (직접 재현 포함)
  2. 자기참조 반려: #41478(failed, 2026-10-12 03:46)의 보고서 본문에 "검증 근거 없음, 결과물과 검증 근거가 없음, 결과 확인 보류"를 설명용으로 인용했다. _completion_block_reasons를 그 본문에 돌리면 ['결과물과 검증 근거가 없음','확인 보류','검증 근거가 없음','근거 없음']가 나온다(길이 1649자). #41435 본문도 "결과 확인 보류" 6건과 "429, timeout, 빈 응답 기록은 없다" 부정 문장 때문에 ['llm_infra_failure(429/timeout/empty)','확인 보류']가 나온다. 즉 게이트가 부정·인용 문맥을 구분하지 못한다.
  3. 라벨명 속 exit_code 오독: #41423 본문의 검증 하단 불릿 missing_verification_exit_code 9건에서 _CODEX_VERIFICATION_EXIT_CODE_RE가 "exit_code 9"를 잡아 invalid_verification_exit_code를 낸다(함수 직접 호출로 확인). 합성 샘플에서도 같은 줄에 콜론을 붙이면 True, 안 붙이면 False로 갈린다.
  4. 형식 불일치: #41385·#41435의 검증: 뒤 줄바꿈+불릿 형식은 _CODEX_VERIFICATION_RESULT_FIELD_RE의 화살표 항(검증: ... → ... exit code N)이 같은 줄을 요구해서 missing_verification_result가 난다. 합성 샘플로 확인했다.
  5. 저장 노트 잘림: 반려된 노트는 원본 요약:이 360~490자로 잘려 저장돼, 사람이 보고 원인을 대조하기 어렵다(조회 32건 길이 360~486자).
  6. 프롬프트: agent_registry.py guardian 프롬프트(311행~)는 일반 4줄 틀과 [점검/수치/판단/다음행동] 출력 형식을 동시에 주고, 집계·분류형 예시와 "인용 금지 문구" 목록은 없다. standard §9-3-1(570행)에 guardian 템플릿이 있으나 프롬프트에는 연결되지 않았다.

  7. 확인하지 못한 것

  8. guardian 완료 보고가 _codex_has_verification_result_field(codex 전용 분기, 7392행 if agent_key == "codex")를 직접 타는지는 끝까지 추적하지 못했다. 그 함수의 로그상 사유 invalid_verification_exit_code는 guardian 건(#41377, #41385, #41420)에도 찍혀 있어 어떤 경로로든 같은 판정이 적용되는 것은 맞다.
  9. 41151 등 일부 건은 노트가 잘려 원문 대조가 안 된다.

[리스크]

  • 게이트 문구 검사를 느슨하게 하면 진짜 "확인 보류" 응답이 통과할 수 있다. 인용부호 안과 "라벨 N건" 집계 문장만 제외하고, 라벨 뒤에 실제 명령·결과가 따라오는지는 그대로 요구해야 한다.
  • 워커(agent_queue_worker.py)는 모든 에이전트가 공유하므로 정규식 수정이 analyst-*/cowork/ron 판정에도 영향을 준다. 회귀 테스트가 필수다.
  • 메타 집계 태스크 자동 재발행이 계속되면 반려 건수 자체가 반려 집계를 만든다(관측된 순환).

[검증방법]

  • 후속 codex 수정 후: 라벨 이름을 인용한 샘플 노트(#41478, #41435 본문)를 _completion_block_reasons에 넣어 빈 리스트(또는 인프라/보류 미포함)가 나오고, 진짜 "결과 확인 보류" 단독 노트는 여전히 차단되는지 확인한다.
  • missing_verification_exit_code 9건 불릿이 있는 #41423 본문 샘플이 (True, '')를 반환해야 한다.
  • 지표: guardian 일일 needs_evidence 신규 건수. 기준선은 현재 22건(32건 중 68.8%). 목표는 7일 안에 신규 0~2건이다. 롤백 조건: 기존 차단 문구 단독 응답이 통과하거나 다른 에이전트의 needs_evidence 비율이 올라가면 되돌린다.
  • 조회 명령: sqlite3 -readonly /Users/ron/.hermes/data/ops_multiagent.db "SELECT claimed_by,count(*) FROM bus_commands WHERE status='needs_evidence' GROUP BY claimed_by;"

후속 codex 태스크 후보 (수정 필요 파일·함수)

  1. scripts/agent_queue_worker.py _completion_block_reasons(3995행): 인용·부정·집계 문맥 제외.
  2. scripts/agent_queue_worker.py _codex_has_verification_result_field(7127행), _CODEX_VERIFICATION_EXIT_CODE_RE(7030행), _CODEX_VERIFICATION_RESULT_FIELD_RE(7022행): 라벨 토큰 속 exit_code 무시, 줄바꿈 불릿 검증 인식.
  3. scripts/agent_registry.py guardian 프롬프트(311행~): 집계·분류형 4블록 틀과 "라벨 이름은 라벨 4종, 합계 22건처럼 쓰고 단독 나열 금지" 문구 추가.
  4. scripts/orchestrator.py: needs_evidence 집계 메타 태스크 재발행 억제(중복 제목 dedup).

선행 제안서(동일 주제): 261011_claude_guardian_rejection_prevention.md, 261012_claude_needs_evidence_prevention.md. 이 문서의 새 발견은 "게이트가 인용된 라벨 문구를 다시 반려한다"는 자기참조 경로(#41478, #41435 재현)다.