← 리포트 목록
guardian 완료보고 반려(needs_evidence/failed) 미비 라벨 방지안
2026-10-14
claude
[guardian, completion-evidence, needs_evidence, proposal]
guardian 완료보고 반려 미비 라벨 방지안 (제안서, 코드 수정 없음)
[권고]
1순위: guardian 프롬프트(scripts/agent_registry.py:311~337)의 "검증:" 줄 양식에 exit code 리터럴 규칙을 SQL 집계·파일 작성형 작업까지 확장한다. - 이유: 차단 사유 필드에 라벨이 남은 건 중 exit code 계열(missing 12 + invalid 5)이 가장 많다. - 기대효과: 반려 20건 중 17건(85%)이 같은 원인이라 이 줄 하나로 대부분 막힌다. 2순위: guardian에게 오는 "반려 집계/분류" 메타 태스크(32건 중 29건, 91%)의 완료 보고를 짧은 4블록 고정 템플릿으로 쓰게 하고 길이를 제한한다. - 이유: 이 건들은 본문이 길어 result_note 앞 382자에서 잘리고 대체 문구("결과 확인 보류")로 바뀐다. - 기대효과: "결과 확인 보류" 템플릿 13건 + "검증 근거 없음" 8건이 해소된다. 3순위: 근거파일은 항상 절대경로로 쓰게 한다. 상대경로 jobs.json이 workspace/jobs.json으로 풀려 반려된 사례(#41323)가 있다.
[현황] (조회 2026-10-14 KST, sqlite3 -readonly ops_multiagent.db)
- 쿼리 1: claimed_by='guardian' AND status IN ('needs_evidence','failed') GROUP BY status → needs_evidence 30, failed 2, 합계 32행.
- 기간: updated_at 2026-09-28 ~ 2026-10-14 05:08.
- 지시문의 "미비 라벨 19건"은 직전 집계(CMD#41648) 값이다. 이번 재집계는 "차단 사유" 필드에 missing_/invalid_/path_not_found 라벨이 있는 건이 20건이다. 조회 시점 차이로 보이며, 정확한 원인은 미확인이다.
- 제목 유형: 반려 집계·분류 메타 태스크 29건, 실제 점검 태스크 3건(#40276 워커 패치 반영, #40346 mcp_health 중복 기동, #41323 크론 사전 점검).
- 즉 guardian의 반려 대부분은 "반려 사유를 분석하는 일"이 다시 반려되는 순환이다.
- result_note 길이: 확인한 대표 건(#41498, #41640) 모두 382자였다. 게이트가 "원본 요약:" 뒤를 잘라 대체 템플릿으로 바꾼 흔적이다.
라벨별 분류와 대표 사례 id (차단 사유 필드 기준, 한 건이 여러 라벨을 가질 수 있음)
| 라벨 | 건수 | 대표 id 2건 | 원인 |
|---|---|---|---|
| 결과 확인 보류(대체 템플릿) | 13 | 41628, 41627 | 원문 4블록이 잘려 대체 문구로 치환됨 |
| missing_verification_exit_code | 12 | 41640, 41498 | "검증:" 줄에 exit code 0 리터럴 없음 |
| 검증 근거 없음 / 검증 근거가 없음 | 10 | 41623, 41504 | 검증 명령+결과가 한 줄에 없음 |
| 결과물과 검증 근거가 없음 | 6 | 41623, 41316 | 산출물 경로(실존 파일)가 본문에서 잘림 |
| invalid_verification_exit_code | 5 | 41420, 41385 | exit code가 0이 아니거나 형식 오류 |
| missing_verification_command | 3 | 41431, 41323 | 실행 명령 1줄이 "검증:" 안에 없음 |
| missing_execution_artifact | 2 | 41431, 40842 | 근거파일 줄 없음 |
| execution_artifact_path_not_found | 2 | 41645, 41323 | 존재하지 않는 경로 인용 (#41323은 jobs.json 상대경로) |
| source_log_path_not_found / verification_command_unverifiable | 1 / 1 | 41646 | "bus_commands 테이블" 같은 서술을 경로 자리에 씀 |
| missing_result_or_verification / completion_result_note_forces_rework | 1 / 1 | 41623 | 위 항목의 복합 |
원인 비교: guardian 프롬프트 vs 제출 표준
- 4블록 양식은 있다. agent_registry.py:329~336에 결론/근거/검증/근거파일이 들어 있다.
- 따라서 "4블록이 없어서"는 원인이 아니다.
- 미실행 명령 안내도 아니다.
- 안내된 3개 도구는 모두 실존한다: scripts/health_check.py, scripts/ontology_core.py, ~/.hermes/.bus-token.
- ron/cowork에서 있었던 존재하지 않는 스크립트 참조 문제와 다르다.
- 실제 원인은 세 가지다.
- (a) 프롬프트의 "출력 형식"(agent_registry.py:321~325: [점검]/[수치]/[판단]/[다음행동])이 4블록과 따로 놀고, 4블록은 "끝에 추가"라고만 되어 있다. 긴 도메인 본문이 앞에 오면 잘린다.
- (b) 검증 예시가 health_check.py 하나뿐이다(333행). SQL 집계·파일 작성형 작업에서 exit code를 어떻게 적는지 안내가 없다. 같은 표준 문서 §3 부정형 명령 예시(config/agent_completion_submission_standard.md:183~195)도 guardian 프롬프트에는 없다.
- (c) 게이트가 둘로 나뉘어 있다.
- 작업자 쪽(agent_queue_worker.py:7441 부근)은 codex 외 에이전트에 exit code 숫자를 요구하지 않는다.
- 서버 저장 게이트(server.py:762
_completion_storage_required_result_gaps, 839행)는 "검증 결과"류 줄 근처에 통과 문구가 없으면 exit code 숫자를 요구한다. - 따라서 "검증: <명령> → 5행 반환"처럼 쓰면 작업자는 통과, 서버는
missing_verification_exit_code로 반려한다. 게이트 정합은 별도 codex 과제다.
- 프롬프트는 본문 라벨명 인접 숫자 금지 규칙(334행)을 이미 갖고 있다. 반려 문구 분석 보고에서
missing_verification_exit_code를 쓰는 메타 태스크 29건이 이 규칙과 자주 부딪힌다.
guardian 프롬프트에 추가할 4블록 문구 초안 (codex 후속 태스크가 agent_registry.py:329~336 부근에 반영)
## 완료 보고 4블록 (result_note 맨 앞에 쓰고, 전체 900자 이내로 쓴다)
결론: <실행/확인한 것> 완료형 한 줄. 예) needs_evidence 30건을 sqlite3로 조회해 라벨별로 분류했다.
근거: <절대경로 소스> + 조회 YYYY-MM-DD HH:MM KST + 반환 행 수. "bus_commands 테이블" 같은 서술만 쓰지 말고 DB 파일 절대경로를 쓴다.
검증: <실행한 명령 1줄> → <결과 수치>, exit code 0 (한 줄 안에 명령·수치·exit code를 모두 쓴다)
근거파일: <절대경로>:<줄번호> "<원문 1줄>" (산출물 파일 또는 읽은 파일. 상대경로·{ 로 시작하는 줄 금지)
규칙:
- 4블록을 [점검]/[수치] 본문보다 먼저 쓴다. 본문은 그 뒤에 짧게 붙인다.
- 반려 집계·분류 작업은 결과표를 파일로 저장하고 근거파일에 그 파일을 인용한다. 표 전체를 result_note에 붙이지 않는다.
- 부재 확인은 `! grep -rlq '<패턴>' <경로>; echo "exit code $?"` → 일치 0개, exit code 0 형식을 쓴다.
- 검증을 못 했으면 done이 아니라 blocked로 제출하고 실제 오류 메시지를 근거에 쓴다.
점검 명령별 근거파일 인용 예시 (형식 예시이며 줄번호는 작성 시점에 read_file로 확인한 값만 쓴다)
- python3 scripts/health_check.py
- 검증: python3 /Users/ron/.hermes/workspace/scripts/health_check.py → 전체 통과, exit code 0
- 근거파일: /Users/ron/.hermes/workspace/scripts/health_check.py:<연 줄> "<해당 점검 함수 정의 1줄>"
- python3 scripts/ontology_core.py --action check_integrity
- 검증: python3 /Users/ron/.hermes/workspace/scripts/ontology_core.py --action check_integrity → 무결성 이상 0건, exit code 0
- 근거파일: /Users/ron/.hermes/workspace/scripts/ontology_core.py:<줄> "check_integrity 관련 1줄"
- curl .../api/bus/command-queue?limit=20
- 검증: curl -s -o /tmp/q.json -w '%{http_code}' -H "X-Ops-Token: $(cat ~/.hermes/.bus-token)" http://127.0.0.1:3344/api/bus/command-queue?limit=20 → 200, 20건 수신, exit code 0
- 근거파일: /tmp/q.json:1 같은 임시파일은 인용하지 말고 /Users/ron/.hermes/workspace/memory/ 아래 저장본을 인용한다.
- sqlite3 -readonly 집계 (guardian 반려의 다수)
- 검증: sqlite3 -readonly /Users/ron/.hermes/data/ops_multiagent.db "SELECT status,COUNT(*) FROM bus_commands WHERE claimed_by='guardian' AND status IN ('needs_evidence','failed') GROUP BY status" → needs_evidence 30, failed 2, 합계 32행, exit code 0
- 근거파일: 결과표 저장 파일 절대경로:<줄> "<표 헤더 1줄>"
- 크론 점검 (#41323형)
- 근거파일은 /Users/ron/.hermes/cron/jobs.json:<줄> "id": "5c45c26045be" 처럼 절대경로로 쓴다.
jobs.json만 쓰면 /Users/ron/.hermes/workspace/jobs.json으로 해석돼 execution_artifact_path_not_found가 된다.
[리스크]
- 단일 원인이 아니다: 작업자·서버 두 게이트의 exit code 요구 차이와 result_note 382자 절단이 겹친다. 프롬프트만 고치면 일부는 남는다.
- 순환 위험: guardian이 반려 분석 태스크를 받고 다시 반려되는 구조(29/32건)를 오케스트레이터가 계속 발행하면 건수가 줄지 않는다. 오케스트레이터 측 발행 억제가 병행돼야 한다.
- 프롬프트 길이가 늘면 다른 규칙이 밀릴 수 있다. 추가분은 10줄 이내로 제한한다.
- 미확인: 382자 절단이 발생하는 정확한 코드 지점은 이번에 열어보지 않았다. 대표 2건의 길이만 실측했다.
[검증방법]
- KPI: 방지안 반영 후 7일간 claimed_by='guardian' 신규 needs_evidence 건수. 기준선은 현재 30건이며 목표는 주당 3건 이하다.
- 라벨별 확인: 같은 쿼리로 missing_verification_exit_code가 신규 0건인지 본다.
- 명령: sqlite3 -readonly /Users/ron/.hermes/data/ops_multiagent.db "SELECT COUNT(*) FROM bus_commands WHERE claimed_by='guardian' AND status='needs_evidence' AND updated_at>'<반영시각>'" → 기대 3 이하.
- 롤백 조건: 반영 후 guardian의 done 완료율이 하락하거나 프롬프트 변경으로 헬스체크 태스크가 늘어나 실패하면 agent_registry.py 변경 전 상태로 되돌린다.
codex 후속 태스크 (코드 수정은 여기서만)
- agent_registry.py guardian 항목(311~337)에 위 4블록 문구 반영. 검증은 py_compile과 해당 항목 grep -n으로 한다.
- server.py:839와 agent_queue_worker.py:7441의 exit code 요구 정합 여부 검토. 변경 전 해리 승인이 필요하다.
- 오케스트레이터가 반려 집계 메타 태스크를 연속 발행하지 않도록 상한 검토.