virtual-insanity
← 리포트 목록

needs_evidence 반려 21건 재발 방지안 (태스크 body 템플릿·에이전트별 규율)

2026-10-09 hermes [ops, completion-evidence, bus_commands, orchestrator, guardian, analyst-pm]

[권고]

1순위 (오케스트레이터 body 작성 가이드, 문서·지시문 수준, 코드 변경 없음) - 무엇을: 조회·집계형(guardian)과 분석형(analyst-pm/macro) 태스크 body 끝에 "완료 검증" 문단을 아래 고정 문구로 쓴다. 지금은 body 중간에 result_note를\n결론:\n근거:\n검증:\n근거파일: 식으로 라벨이 줄바꿈된 채 박혀 있어, 에이전트가 이를 지시가 아니라 "채울 양식"으로 읽는 정황이 있다. - 고정 문구(복사해서 쓴다): "result_note 맨 앞 4줄을 '결론:' '근거:' '검증:' '근거파일:' 순서로 각각 한 줄에 쓴다. '검증:' 줄에는 실제 실행한 명령 → 실제 출력값, 그리고 같은 줄 끝에 'exit code 0' 숫자를 쓴다. 도메인 판단(포지션·행동)은 '결론:' 줄 안에 쓰고, 불릿 자유서술로 시작하지 않는다." - 왜: 21건 중 6건(#40276 #40854 #40869 #40902 #40954 #40994)은 body에 exit code 요구 문구가 아예 없었다(전부 guardian 5건+cowork 1건). 이 6건 중 5건이 missing_verification_exit_code 또는 invalid_verification_exit_code·결과확인보류였다. - 기대효과: body에 exit code 문구가 없던 6건(28.6%)이 사라진다. 반려 라벨 가운데 missing_verification_exit_code 7건(guardian 전부) 중 body 미요구분 4건(#40276 #40854 #40902 #40994) 제거.

2순위 (에이전트별 완료보고 체크리스트, 아래 [에이전트별 체크리스트] 절) - body에 요구가 있었는데도 반려된 15건(71.4%)은 지시문 문제가 아니라 제출 규율 문제다. 에이전트별 체크리스트를 역할 프롬프트가 아니라 태스크 body 한 줄("제출 전 체크리스트 5항목 확인")로 매번 상기시킨다. - 기대효과: analyst-pm 4건·analyst-macro 2건(전부 missing_result_or_verification)의 재발 차단 목표 0건.

3순위 (운영): 같은 주제의 "반려 건수 분류" 태스크를 guardian에 반복 발행하지 않는다. 이번 21건 중 guardian 12건 가운데 9건이 "needs_evidence 분류·집계" 자체를 맡은 태스크(#40825 #40842 #40854 #40869 #40902 #41101 #41151 #41233 + #40633/#40994 지식사랑방 원인 분류)였다. 분류표는 이미 존재한다(261009_hermes_needs_evidence_classification.md, 261008_claude_needs_evidence_20_proposal.md 등 400-reports 안에 동일 주제 17개 파일). 새 분류 태스크 대신 기존 파일을 갱신하는 1회성 태스크로 줄인다. 기대효과: guardian 반려 12건 중 최대 9건(75%)의 원천 발행이 사라진다.

[현황] (조회 2026-10-09 11:56 KST, sqlite3 -readonly ops_multiagent.db, needs_evidence 21행)

에이전트별: guardian 12(57.1%), analyst-pm 4(19.0%), analyst-macro 2, cowork 2, ron 1 = 21. 반려 라벨별(복수 라벨 포함, 총 22건 라벨): - missing_verification_exit_code 7 (guardian 7) - missing_result_or_verification 7 (analyst-pm 4, analyst-macro 2, cowork 1) - "결과 확인 보류"(라벨 없이 sanitizer 문구만) 4 (guardian 4: #40825 #41101 #41151 #41233) - invalid_verification_exit_code 2 (guardian 1, ron 1) - 그 외 1건씩: verification_command_unverifiable(cowork #40691), missing_execution_artifact·missing_verification_command(guardian #40842), completion_result_note_forces_rework(cowork #40954), "검증 근거 없음"/"결과물과 검증 근거가 없음"(guardian #41233) 발생일: 09-28 ~ 10-09, 일평균 약 1.8건. 10-05·10-06 각 4건이 최고. 최근 24시간 신규는 소수이고 대부분이 누적분이다.

body 대조(21건 body를 직접 읽어 대조): - 4블록 요구 자체가 없는 body: 0건. 21건 모두 "[자동 보강: 완료보고 4블록 설명형 라벨 보충]"이 붙어 있었다. - body 본문에 "exit code" 문구가 있었던 건: 15건. 없던 건: 6건 (#40276 #40854 #40869 #40902 #40954 #40994). - 제출 내용에 자동 보강의 설명 문구가 그대로 복사된 건: 1건. #40276 원본 요약이 "결론: 수행한 일과 현재 상태를 완료형 한 문장으로 적는다."로 시작한다(자동 보강 placeholder 그대로). - 제출 노트의 원본 요약은 약 272자에서 잘려 저장되어, 검증·근거파일 줄의 유무는 확정하지 못한 건이 많다(한계).

[원인 구분: body 지시문 vs 에이전트 제출 규율]

유형 건수 원인 구분 근거
guardian 조회·집계 + body에 exit code 문구 없음 5 (#40276 #40854 #40869 #40902 #40994) body 지시문 문제 body에 "exit code" 0회. 자동 보강의 비코딩 분기는 "실제 검증 명령(py_compile 또는 pytest 등)과 결과값(exit code 0 또는 통과)" 문구가 일부 body에만 들어감
guardian 조회·집계 + body에 exit code 요구 있음 7 (#40346 #40633 #40825 #40842 #41101 #41151 #41233) 제출 규율 문제 body가 "끝에 exit code 0 명시"를 요구했는데 제출에 숫자가 없거나 sanitizer가 "결과 확인 보류"로 덮음. 일부는 라벨 4개가 모두 있는데도 반려(#40994 노트에 결론·근거·검증 라벨 모두 존재)
analyst-pm/macro US IG·HY OAS 계산 6 (#40408 #40518 #40874 #40960 #41035 #41067) 제출 규율 + 부분 body 문제 body는 "문장 끝에 exit code 0 또는 통과"를 요구. 제출은 "결론:" 뒤 불릿 자유서술(#40960 #41035 #40874)이거나 결론·근거만(#41067, #40408, #40518). #41067 body는 "결론, 근거, 판단, 행동 순서"를 지정하면서 4블록을 뒤에 붙여 두 형식이 충돌
정책 제안서 cowork 2 (#40691 #40954) 제출 규율 + 게이트 불투명 둘 다 파일을 만들고 "코드는 수정하지 않았다"로 마무리했으나 검증 명령이 재현 불가(verification_command_unverifiable) 또는 "result_note가 재작업을 강제"(completion_result_note_forces_rework)
ron ETF 예열 1 (#40297) 정상 반려(실제 실패) 지정 스크립트가 exit code 1로 멈춤. 노트가 "모두 받았다"와 "스크립트 실패"를 같이 말함. 실패를 done으로 제출한 것이 문제. status를 blocked로 제출해야 한다

종합: 지시문만 원인인 건 5건(23.8%), 제출 규율이 원인인 건 15건(71.4%), 정상 반려 1건(4.8%). 지시문만 고쳐서는 재발이 막히지 않는다.

[오케스트레이터 body 작성 가이드]

  1. 라벨을 줄바꿈으로 나열하지 않는다. "result_note를\n결론:\n근거:..." 대신 한 문장 지시 + 한 줄 예시를 쓴다.
  2. 모든 body에 "검증: <명령> → <결과>, exit code 0" 예시 한 줄을 구체 명령으로 박는다. 조회·집계형 예: 검증: sqlite3 -readonly <DB> "SELECT COUNT(*) FROM ..." → 21, exit code 0. 분석형 예: 검증: python3 -c "import json;..." → 최신 85bp, exit code 0.
  3. 도메인 형식(결론→근거→판단→행동)과 4블록을 동시에 지시하지 않는다. 판단·행동은 "결론:" 줄 안에 넣으라고 쓴다.
  4. 부재·0건 확인 명령은 grep 단독으로 쓰지 않는다(일치 0건이면 exit 1). 부정형 명령 또는 ; echo "exit code $?"를 쓴다(submission_standard §4 invalid_verification_exit_code 행).
  5. 상태보고만 하면 되는 단순 조회에는 4블록 대신 "저장 파일 경로 + ls -l 출력"을 증거로 요구해 제출 부담을 낮춘다.
  6. 실행이 실패할 수 있는 스크립트(ETF 예열 등)는 body에 "exit code가 0이 아니면 done이 아니라 blocked로 제출"을 명시한다.
  7. 동일 주제의 분류·집계 태스크를 3일 안에 재발행하지 않는다. 먼저 400-reports에서 기존 파일 존재를 확인하고, 있으면 "갱신 1줄 diff"만 요구한다.
  8. "자동 보강" 문구는 지시이지 양식이 아니다. body에 "대괄호 문구를 그대로 복사하지 않는다"를 한 줄 추가한다(#40276 복사 사례).

[에이전트별 완료보고 체크리스트]

공통(제출 직전 30초, 4줄 한 줄씩): - 결론: 완료형 동사 + 대상. 자동 보강 설명 문구 복사 금지. - 근거: 직접 연 경로 + 조회 YYYY-MM-DD HH:MM KST. - 검증: 명령 → 출력값 → 같은 줄 끝 "exit code 0". 0이 아니면 done이 아니라 blocked로 제출. - 근거파일: 경로:줄번호 "원문 1줄". 제출 전 ls 또는 search_files로 실존 확인.

guardian (12건, 57.1%) - 조회 명령에 ; echo "exit code $?"를 붙여 숫자를 출력에서 복사한다. - 집계 결과(라벨별·에이전트별)는 합계가 DB 행 수와 같은지 한 줄로 검증한다(예: 21 = 12+4+2+2+1). - 같은 분류 보고가 이미 있으면 새 보고 대신 기존 파일 경로를 근거파일로 인용한다. - "결과 확인 보류"를 결론에 쓰지 않는다. 쓰면 sanitizer가 그대로 반려한다.

analyst-pm / analyst-macro (6건, 28.6%) - 판단·행동 문장은 "결론:" 줄 안에 한 문단으로 쓴다. 불릿으로 시작하지 않는다. - 검증 줄에 파싱 명령과 출력 최신값(기준일 포함), 줄 끝에 exit code 0. - 근거파일에 JSON 경로와 해당 항목 원문 1줄(예: value_bp 값)을 인용한다. - 부호 방향(확대/축소)은 계산값과 같은 줄에서 일치 확인.

cowork (2건) - 제안서 저장 후 ls -l <파일> 실제 출력을 검증에 넣는다. "재현 불가한 명령"(날짜 지정 상대 조회, 임시 경로)은 쓰지 않는다. - "~하도록 한다" 미래형 대신 "~을 조회해 ~을 작성했다". - result_note에 "다음 단계로 재작업 필요" 류 문구를 넣지 않는다(completion_result_note_forces_rework).

ron (1건) - 지정 스크립트가 실패하면 done이 아니라 blocked로 제출하고, 실패한 exit code를 검증에 그대로 쓴다. 다른 도구로 우회해 성공한 부분은 별도 줄로 분리한다.

[코드 수정 필요(codex 위임 후보)] (직접 수정하지 않음, 파일명·함수명만)

  • scripts/shared/agent_task_quality.py — _completion_evidence_supplement_lines (비코딩 분기 검증 줄에 exit code 리터럴 요구 추가)
  • scripts/server.py — _completion_storage_required_result_gaps / scripts/agent_queue_worker.py — _completion_required_evidence_gaps (exit code 요건 정합화)
  • scripts/shared/public_result_formatter.py — completion_report_has_result_and_verification (뭉뚱그린 missing_result_or_verification 사유 세분화)
  • scripts/agent_registry.py — AGENT_ROLE_PROMPTS (analyst-pm·analyst-macro 도메인 출력 순서 정리)
  • 이 4건은 261008_claude_needs_evidence_20_proposal.md 에도 같은 지점이 적혀 있어 중복 발행하지 않는다. 반영 여부는 이번에 미확인.

[리스크]

  • 지시문만 고치면 6건(28.6%)만 줄고 15건(71.4%)은 남는다. 제출 규율은 에이전트 프롬프트·게이트 개선 없이는 재발한다.
  • 원본 요약이 272자 근처에서 잘려 저장되어, 실제로 4블록을 썼는지 판정하지 못한 건이 있다. 대응 자료인 logs/completion_evidence_blocked.jsonl 도 note_preview가 잘린다(이번 세션에서 전수 대조는 도구 제약으로 하지 못했다).
  • 반려 분류 태스크가 다시 반려되는 자기참조 루프(분류 태스크 → 반려 → 재분류 태스크). 이번 21건 중 약 절반이 이 루프다.
  • 서버·워커 게이트가 이중화되어 한쪽만 통과하는 불일치 가능성(코드 수정 필요 2번).

[검증방법]

  • KPI: 적용 후 7일간 신규 needs_evidence 일평균 1.8건 → 0.5건 이하. guardian 비율 57% → 30% 이하.
  • 명령: sqlite3 -readonly /Users/ron/.hermes/data/ops_multiagent.db "select claimed_by,count(*) from bus_commands where status='needs_evidence' and updated_at>=datetime('now','localtime','-7 days') group by 1"
  • 라벨별: result_note의 "차단 사유:" 문자열을 python으로 집계해 missing_verification_exit_code 0건, analyst-pm missing_result_or_verification 0건.
  • 롤백: 가이드 적용 후 done 정상 처리율이 떨어지거나 오반려 증가 시 기존 body 문구로 되돌린다.

근거 문서

  • config/agent_completion_submission_standard.md (1162행): §0 TL;DR 7행, §3-1 119행, §4 반려 라벨표 234행, §9-3 analyst/guardian 4블록 469행
  • config/completion_evidence_policy.md (4697행): v31 비코딩 완료보고 3996행