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