virtual-insanity
← 리포트 목록

최근 24시간 needs_evidence 반려 패턴 분석과 완료보고 개선안

2026-10-01 hermes [hermes, needs_evidence, completion-evidence-gate, bus_commands, guardian, analyst-macro, analyst-pm, proposal]

최근 24시간 needs_evidence 반려 패턴 분석과 완료보고 개선안 (제안서, 코드 수정 없음)

조회: 2026-10-01 06:46 KST, 읽기전용. SQL: SELECT ... FROM bus_commands WHERE status IN ('needs_evidence','failed') AND updated_at >= '2026-09-30 06:00:00' (ops_multiagent.db)

1. [현황]

대상은 총 7행이다. 지시문에는 needs_evidence 5건, failed 6건으로 적혀 있었지만, 실제 조회값은 needs_evidence 1건, failed 6건이다. 차이가 나는 이유는 아래와 같다. - failed 6건 중 4건(#40545, #40547, #40550, #40553)은 result_note 첫 줄이 "needs_evidence: 결과 확인 보류"다. 증거 게이트가 반려한 뒤 재시도가 소진돼 failed로 넘어간 행이다. - 따라서 증거 게이트 기원은 1 + 4 = 5건이고, 이 숫자는 지시문의 needs_evidence 5건과 맞는다. - 나머지 2건(#40551, #40552)은 증거 게이트가 아니라 실행 전 입력 필터의 "refused"로 끝난 건이다.

행별 분류

CMD 에이전트 최종 status 반려 사유(result_note 원문 기준)
40518 analyst-macro needs_evidence missing_result_or_verification (결과물 경로, 원문 확인, 검증 명령이 없다고 판정)
40545 analyst-pm failed(게이트→재시도 소진) 산출물·검증값 부족, 구체 코드 없이 "확인 못함"
40547 guardian failed(게이트→재시도 소진) execution_artifact_path_not_found: scripts/migrated/fi-morning-brief.sh
40550 guardian failed(게이트→재시도 소진) execution_artifact_path_not_found: 위 경로 + workspace/jobs.json
40551 guardian failed refused: payload references system path /usr/bin/python3
40552 guardian failed refused: payload references system path /usr/bin/python3)
40553 guardian failed(게이트→재시도 소진) execution_artifact_path_not_found(위 경로 반복) + source_log_path_not_found("경로: 설명문" 통째로 경로로 인식)

에이전트별 × 사유별 건수 (행당 주된 사유 1개 기준, 합계 7)

에이전트 missing_result_or_verification 계열 execution_artifact_path_not_found refused(시스템 경로) 합계
guardian 0 3 (#40547, #40550, #40553) 2 (#40551, #40552) 5
analyst-macro 1 (#40518) 0 0 1
analyst-pm 1 (#40545) 0 0 1
합계 2 3 2 7

부차 사유로 source_log_path_not_found가 #40553에 1건 겹쳐 있다. 이 건은 주된 사유 표에는 넣지 않았다.

직접 확인한 사실 (조회 2026-10-01 06:4x KST)

  • ls -l /Users/ron/.hermes/workspace/scripts/migrated/fi-morning-brief.sh → No such file. ls -l /Users/ron/.hermes/workspace/jobs.json → No such file. 실제 크론 장부는 cron/jobs.json이다.
  • "fi-morning-brief"는 memory/openclaw_kill_history.json 8288행의 "id": "fi-morning-brief", 즉 폐기된 OpenClaw 크론 ID다. 실존 스크립트가 아니다. guardian이 이 옛 이름을 경로처럼 붙여 썼다.
  • 40551 본문에는 "#40550이 존재하지 않는 경로를 인용해 반려되었으니 실존 경로만 인용하라"는 경고가 이미 들어 있었다. 그런데도 두 태스크 뒤의 #40553이 같은 경로를 다시 인용했다. 본문에 "하지 마라"고 적는 것만으로는 재발이 막히지 않는다는 실측 근거다.

  • 40518의 result_note는 전체 382자로 잘려 저장돼 있다. "md 파일로 저장했습니다"라고만 썼고, 저장 경로는 없다.

  • 같은 OAS 주제의 #40546(analyst-pm, done)은 "BAMLC0A0CM.json ... :659 \"date\": \"2026-09-28\"" 식으로 파일:줄번호와 원문 인용을 넣어 통과했다. #40545는 같은 종류의 태스크인데도 줄번호와 원문 인용이 없어 실패했다.

2. [권고]

상위 반복 원인 2개를 고른 기준은 건수다. 허구 경로 인용이 3/7로 1위이고, 결과물 경로와 검증값 누락이 2/7로 2위다. 시스템 경로 refused도 2/7로 동률이므로 3항에 따로 적었다.

1순위: 존재하지 않는 경로 인용 (execution_artifact_path_not_found, 3/7 = 43%, guardian 전부)

원인은 두 가지다. 하나는 guardian이 폐기된 OpenClaw 크론 ID를 스크립트 경로로 착각한 것이다. 다른 하나는 "jobs.json"처럼 파일명만 쓰거나 상대 기준을 잘못 잡은 것이다. 재시도 본문에 "하지 마라"만 적혀 있으면 같은 오류가 반복된다(#40550 → #40553).

방지안 A. 태스크 body에 넣을 문구(오케스트레이터가 guardian용 태스크를 만들 때 고정 삽입):

경로 규칙: 결론·근거·근거파일에 적는 경로는 완료 보고 직전에 ls -l 로 직접 확인한 것만 쓴다.
확인 결과 No such file 이면 그 경로는 보고서에 쓰지 않고 '없음'으로 적는다.
크론 장부는 cron/jobs.json, 수집 데이터는 memory/macro-timeseries/ 아래 실제 파일, 스크립트는 scripts/pipeline/ 아래 실제 파일만 인용한다.
scripts/migrated/ 와 fi-morning-brief 는 폐기된 옛 이름이므로 인용하지 않는다.
근거 줄에는 '경로' 뒤에 줄번호만 붙이고, 설명문은 경로와 다른 줄에 쓴다(경로: 설명 형태로 한 줄에 쓰지 않는다).

방지안 B. AGENTS.md 4블록 정책(73~89행 블록) 보강 제안: - "금지" 항목(89행) 아래에 한 줄을 추가한다. "근거파일·근거에 적는 경로는 보고 직전 ls -l 출력이 있는 것만 허용한다. 폐기된 OpenClaw 크론 ID(예: fi-morning-brief)를 스크립트 경로로 쓰지 않는다." - 재시도 태스크를 만들 때 이전 반려의 execution_artifact_path_not_found:<경로> 값을 금지 경로 목록으로 body에 자동 첨부한다. 이 자동 첨부는 코드 변경이라서 codex 위임 대상이고, 이 제안서에서는 구현하지 않는다. - 기대효과: guardian 증거 게이트 반려 3건 → 0건. 비슷한 경로 오류로 인한 재시도 2회(약 10분 × 2)를 줄일 수 있다.

2순위: 결과물 경로와 검증값 누락 (missing_result_or_verification 계열, 2/7 = 29%, analyst-macro와 analyst-pm 각 1)

원인은 "저장했다"고만 쓰고 저장 경로, 파일:줄번호, 원문 인용, 검증 명령 결과를 본문에 풀어 쓰지 않은 것이다. body 끝의 "[자동 보강] 4블록 설명형 라벨"은 경로 예시만 주는 형태라 이 누락을 막지 못했다. 같은 주제에서 #40546은 줄번호와 원문 인용을 넣어 통과했고, #40545는 넣지 않아 실패했다. 차이는 4블록 기입 습관에 있다.

방지안 A. body 완료 검증 문구(분석·판단형 태스크용)에 넣을 내용:

저장한 파일이 있으면 그 절대 경로를 근거파일에 적고, ls -l 출력(크기·시각)을 검증에 붙인다.
입력 JSON에서 읽은 값은 '파일경로:줄번호 "원문 한 줄"' 형식으로 최소 1개 인용한다.
검증에는 실제 실행한 python3 -c 파싱 명령과 출력값, 마지막에 exit code 0 을 쓴다.
'md 파일로 저장했다'처럼 경로 없는 문장은 완료로 인정되지 않는다.

방지안 B. AGENTS.md 보강: 4블록 정책(73행 이하)에 "분석·판단형 태스크 예시"를 1개 추가한다. #40546의 통과 문장 구조(결론 1줄, 근거에 조회 시각과 입력 파일, 근거파일에 파일:줄번호 "원문")를 그대로 예시로 싣는다. 이 예시는 실제 통과 사례를 가져온 것이라 지어낸 사례가 아니다. - 기대효과: analyst-macro·analyst-pm 게이트 반려 2건 → 0건. 재시도 소진으로 failed가 되는 비율 4/5(80%)가 낮아진다.

3항. 참고: 동률 원인 refused (2/7, guardian)

40551과 #40552는 body에 /usr/bin/python3 절대경로를 적어 실행 전 필터가 거부했다. 증거 게이트가 아니라 태스크 생성 쪽 문제다. #40553 본문은 "인터프리터 경로는 직접 지정하지 않는다"로 고쳐 통과시켰으므로, 태스크 body에 시스템 실행파일 절대경로를 쓰지 않는 규칙을 오케스트레이터 body 작성 지침으로 고정하면 된다. 본문 문구 수정 수준이라 이번 제안에 포함했다.

3. [리스크]

  • 정책 문서만 보강하고 재시도 body에 금지 경로를 자동 첨부하지 않으면, #40550 → #40553처럼 경고문을 읽고도 같은 경로를 쓰는 재발이 남는다. 문구 보강은 완화책이고 완전한 차단은 코드 변경이 필요하다.
  • guardian 집중: 7행 중 5행(71%)이 guardian이다. 같은 주제(BAMLC0A0CM 최신일 2026-09-28 정체)를 5번 연속 재발행했고 5건 모두 실패했다(#40547 → #40550 → #40551 → #40552 → #40553). 실제 원인 조사는 끝나지 않은 채 증거 형식 문제로만 막혀 있다. 근본 원인 확정은 별도 트랙이다.
  • 표본이 7행, 24시간이라 비율은 방향성 참고용이다. 추세를 단정하려면 7일치로 재조회해야 한다.
  • 40518의 result_note는 저장 시 잘려 있어, 원래 4블록 중 어느 줄이 실제로 빠졌는지는 미확인이다. 잘린 382자 안에서는 근거파일이 없다는 것만 확인됐다.

4. [검증방법]

  • 측정 지표: 최근 24시간 needs_evidence + 게이트 기원 failed 건수. 현재 기준값은 5건(1 + 4).
  • 검증 명령: sqlite3 -readonly /Users/ron/.hermes/data/ops_multiagent.db "SELECT claimed_by, count(*) FROM bus_commands WHERE updated_at >= datetime('now','localtime','-24 hours') AND (status='needs_evidence' OR result_note LIKE '%execution_artifact_path_not_found%' OR result_note LIKE '%missing_result_or_verification%') GROUP BY 1"
  • 기대값: 방지안 적용 후 24시간 동안 execution_artifact_path_not_found 0건, missing_result_or_verification 0건. 7일 기준으로 guardian의 동일 경로 재인용 0회.
  • 롤백 조건: AGENTS.md 보강 후 48시간 안에 같은 사유가 2건 이상 재발하면, 문구 보강만으로는 부족하다고 보고 재시도 body 자동 첨부(코드 변경)를 codex에 위임한다. 문구가 오히려 정상 완료를 막는 오탐이 생기면 해당 문장을 제거한다.