virtual-insanity
← 리포트 목록

guardian 완료보고 4블록 미준수 반려 방지안 (정책 제안서)

2026-10-13 claude [ops, completion-evidence, needs_evidence, guardian, 4block, policy]

guardian 완료보고 4블록 미준수 반려 방지안 (조회 2026-10-13 11:57~12:01 KST)

코드는 수정하지 않았다. 이 문서는 문서 수준 방지안과 코드 수정 지점 후보만 적는다.

[권고]

1순위 — config/agent_completion_submission_standard.md에 guardian 조회·집계형 전용 고정 문구 절(§9-3-3)을 신설하고, 같은 파일 578~579행의 잘못된 예시를 고친다. - 이유: guardian 반려 26건은 4블록 라벨 누락이 아니라 "검증:" 값에서 게이트가 읽는 exit code <숫자> 리터럴이 빠져서 막힌 건이다(아래 [현황] 표). 그런데 현재 guardian용 템플릿(578행)은 "<exit code/결과 수치>"로 둘 중 하나만 써도 되는 것처럼 적혀 있고, 579행 예시는 → exit 1,이라 게이트 정규식(exit code만 인식)에 걸리지 않는 형식을 가르친다. 문서가 오히려 실패 형식을 가르치고 있다. - 고정 문구(한 줄): 검증: <명령> → <결과 수치>, exit code 0 — 명령·결과·exit code를 "검증:" 같은 줄 안에 모두 넣는다. 금지 형식 5종은 [현황] 표의 원인 코드와 1:1로 표로 붙인다. - 기대효과: [현황] D표의 "검증 줄 비움" 6건, "조사 끼움" 4건, "exit code 전무" 6건(일부 겹침)이 제출 단계에서 줄어든다. 목표는 guardian 최근 10건 제출 중 done 7건 이상(현재 2026-10-06 이후 20건 중 done 1건=5%).

2순위 — config/completion_evidence_policy.md에 "반려 분류 작업 재발행 루프 차단" 절을 신설한다. - 이유: 반려 26건 중 21건(80.8%)이 제목에 needs_evidence·반려가 들어간 "반려 분류 작업"이다. 이 작업의 보고가 다시 반려되고, 반려되면 같은 분류 작업이 또 발행된다. 2026-10-06 이후 guardian은 20건 중 18건이 needs_evidence라 큐를 이 루프가 채우고 있다. - 조치(문서): 같은 제목군은 직전 건이 done이 되기 전에는 재발행하지 않는다는 규칙, 그리고 분류 결과는 파일로 남기고 보고는 4줄로 끝낸다는 규칙을 명문화한다. - 기대효과: 큐 안 guardian needs_evidence 26건 중 신규 유입이 일 4~5건(2026-10-11 5건, 10-12 4건)에서 1건 이하로 준다.

3순위 — 자동 보강 문구 복사 금지 조항을 같은 절에 추가한다. 26건 중 6건(40276, 40842, 40902, 41274, 41316, 41494)이 보고 안에 "수행한 일과 현재 상태를 완료형 한 문장으로 적는다."를 그대로 넣었고, 40276은 이 문장을 "결론:" 값으로 제출했다. 작업 지시문 본문에는 26건 중 25건에 이 보강 블록이 붙어 있다.

[현황]

범위: sqlite3 -readonly /Users/ron/.hermes/data/ops_multiagent.db의 bus_commands, status='needs_evidence' AND claimed_by='guardian' = 26행(전체 needs_evidence 37행의 70.3%). 생성일 2026-09-28~2026-10-12. 에이전트별 전체: guardian 26, analyst-pm 4, cowork 4, analyst-macro 2, ron 1 = 37.

A. 게이트가 result_note에 기록한 "차단 사유" (건당 대표 조합, 합계 26) | 차단 사유 조합 | 건수 | |---|---:| | missing_verification_exit_code 단독 | 8 | | invalid_verification_exit_code 단독 | 5 | | "결과 확인 보류"만 있고 구체 코드 없음 | 5 | | 검증 근거 없음 + 결과물과 검증 근거가 없음 + 결과 확인 보류 | 5 | | missing_execution_artifact + missing_verification_command + missing_verification_exit_code | 2 | | execution_artifact_path_not_found(jobs.json) + missing_verification_command + missing_verification_exit_code | 1 |

라벨 기준 누적(한 건에 여러 개): exit code 계열 합 16건(missing 11, invalid 5), 일반 문구 10건, missing_verification_command 3건, missing_execution_artifact 2건, 경로 미실존 1건(#41323).

B. llm_infra_failure 계열 분리 집계 - 차단 사유 앞부분에 인프라 라벨이 붙은 건: 0건. - 저장된 result_note 어디에든 "llm_infra" 문자열이 있는 건: 12건. 모두 보고 본문이 "인프라 실패는 0건"이라고 적은 문장이거나 분석 대상 목록에서 인용한 것이다. 반려 사유가 아니다. - 결론: 인프라 지연 반려 0건. 26건 전부 제출 형식 문제다. guardian의 10:2x 집계 보고(#41504)의 주장과 일치한다.

C. 4블록 라벨별 누락 (원본 보고 26건을 /Users/ron/.hermes/logs/agent-queue-guardian.log에서 복원해 대조) | 항목 | 누락 건수 | 비고 | |---|---:|---| | "결론:" 라벨 | 0 | 단 40276은 보강 문구 복사본이 값 | | "근거:" 라벨 | 1 | #41323은 "근거 (조회 …)" 형태로 라벨 뒤에 괄호를 붙임 | | "검증:" 라벨 | 0 | | | "근거파일:" 라벨 | 0 | |

라벨은 거의 안 빠진다. 빠지는 것은 라벨 안의 값이다.

D. 값 수준 누락 (원본 26건을 정규식으로 재분류, 겹침 있음) | 값 누락 유형 | 건수 | 대표 CMD | |---|---:|---| | "검증:" 줄이 비어 있고 아래 불릿에 내용을 나눠 씀 | 6 | 40902, 40994, 41323, 41385, 41435, 41498 | | 검증 블록에 exit code <숫자>가 전혀 없음 | 6 | 40276("검증: pytest"만), 40854, 40994, 41274, 41295, 41498 | | 그중 "exit code는 0입니다"처럼 조사가 끼어 숫자와 떨어짐 | 4 | 40854, 41274, 41295, 41498 | | exit code는 있으나 "검증:" 줄 밖 불릿에 있음 | 4 | 40902, 41323, 41385, 41435 | | "검증:"에 실행 명령이 없고 합계 대조 서술뿐 | 6 | 41101, 41387, 41420, 41485, 41494, 41504 | | "근거파일:"에 줄 번호가 없음 | 11 | 40825, 40842, 41101, 41151, 41233 외 | | "근거파일:"에 인용 문구가 없음 | 1 | 40276 | | 근거파일 경로가 실존하지 않음 | 1 | 41323(/Users/ron/.hermes/workspace/jobs.json, 실제는 /Users/ron/.hermes/cron/jobs.json) | | 보강 문구를 보고에 그대로 복사 | 6 | 40276 외(40276은 "결론:" 값) |

E. 현재 코드로 재생(replay)한 결과 - 복원한 원본 26건을 현재 scripts/agent_queue_worker.py::_codex_has_verification_result_field에 넣으면 17건 통과, 9건 missing_verification_result로 실패한다. 실패 9건은 40276, 40854, 40994, 41274, 41295, 41323, 41385, 41435, 41498이다. 대부분 D표의 "줄 비움"·"조사 끼움"·"exit code 전무"와 겹친다. - 단 이 재생은 현재 디스크 파일 기준이다. 실행 중인 guardian 워커(PID 3974)는 2026-09-29 02:16 기동이고, scripts/agent_queue_worker.py와 scripts/agent_registry.py의 수정시각은 2026-10-13 09:35다. 파일 내 reload 계열(execv, importlib.reload) 검색은 0건이라 워커가 최신 패치를 읽었다고 확인되지 않는다. 그래서 "17건은 지금 통과한다"는 현재 파일 기준 주장이고, 실행 중 워커가 같은 판정을 내린다는 확인은 못 했다. - "결과 확인 보류"만 찍힌 일반 문구 반려 10건 중 9건이 재생에서는 통과한다. 이 10건이 어느 게이트(워커 선검사인지 서버 쪽 scripts/shared/public_result_formatter.py인지)에서 막혔는지는 확인하지 못했다.

F. 반복 구조 - 제목에 needs_evidence 또는 반려가 들어간 분류 작업 21건(80.8%), 그 외 5건(40276, 40346, 40633, 40994, 41323). - 생성일 분포: 2026-10-09 3건, 10-10 3건, 10-11 5건, 10-12 4건. 최근 4일에 15건(57.7%)이 몰려 있다. - 2026-10-06 이후 guardian 전체 20건: needs_evidence 18, done 1, failed 1.

[리스크]

  1. 문서가 실패 형식을 가르친다: config/agent_completion_submission_standard.md 578행 <exit code/결과 수치>, 579행 → exit 1,. 에이전트는 이 예시를 그대로 따른다. 같은 파일 187행이 이미 "exit=0 표기는 못 잡아 반려된다"고 적었지만 §9-3-1에는 반영되지 않았다.
  2. 정규식과 문서의 어긋남: _CODEX_VERIFICATION_EXIT_CODE_RE(agent_queue_worker.py 7042행)는 exit code 바로 뒤 숫자만 읽는다. "exit code는 0", "exit=0", "exit 1"은 읽지 못한다. 서술형 한국어 보고는 조사를 끼우기 쉽다(4건).
  3. 자기참조 루프: 분류 작업의 보고가 반려 → 분류 작업 재발행 → 큐 적체. 이 루프가 계속되면 guardian 본연의 점검 작업이 밀린다.
  4. 단일 장애점: 워커가 기동 후 코드를 다시 읽지 않는 것으로 보인다(reload 검색 0건). 문서·프롬프트·게이트를 고쳐도 재시작 전에는 같은 반려가 이어질 수 있다. 재시작은 진행 중 태스크가 있을 수 있어 해리 승인 후 한다.
  5. 보강 문구 복사: 오케스트레이터가 지시문에 붙이는 4줄 보강이 에이전트에게는 템플릿처럼 보인다. 보고에 그대로 들어가면 자기지시적 placeholder로 반려된다.
  6. 이 분석의 한계: D표는 정규식 분류라 일부 경계 사례(예: "검증:" 줄이 비었지만 불릿에 명령이 있는 경우)는 보수적으로 해석했다. 건별 원문은 /Users/ron/.hermes/logs/agent-queue-guardian.log에서 command_id로 확인할 수 있다.

[방지안 본문 — 문서 수정 초안]

1) standard 문서 §9-3-1 수정 (578~579행)

  • 578행 → <exit code/결과 수치>를 → <결과 수치>, exit code <숫자>로 바꾼다.
  • 579행 예시 → exit 1,을 → cron_ok=True, worker_ok=False (2/4 무응답), exit code 1처럼 "exit code 숫자"가 들어가는 형식으로 바꾼다. 단, exit code가 0이 아니면 invalid_verification_exit_code로 반려되므로, 점검에서 이상을 발견한 보고의 "검증:"은 "점검 명령 자체"의 exit code 0을 쓰고 이상 수치는 결론·수치에 쓴다고 명시한다.

2) standard 문서 §9-3-3 신설 — guardian 조회·집계형 고정 문구

결론: <조회한 대상>을 <몇 건> 집계해 <무엇을 확인했다> (완료형)
근거: sqlite3 -readonly <DB 경로> "<쿼리 요약>" → <N>행, 조회 YYYY-MM-DD HH:MM KST
검증: <재실행 명령 한 줄> → <합계 일치 수치>, exit code 0 통과
근거파일: <실존 경로>:<줄번호> "<원문 인용 1줄>"

금지 형식 표(원인 코드와 연결): | 쓰지 말 것 | 이유 | 대신 | |---|---|---| | 검증: 한 줄 비우고 아래 불릿으로 나눠 쓰기(6건) | 같은 줄에 명령·결과가 없음 | 한 줄에 명령 → 결과, exit code 0 | | exit code는 0입니다(4건) | 조사가 끼어 숫자를 못 읽음 | exit code 0 또는 exit code: 0 | | exit=0, exit 0 | 정규식이 인식 안 함 | exit code 0 | | 검증: pytest만(1건) | 명령·결과 없음 | 실제 명령과 N passed, exit code 0 | | 합계 대조 서술만 쓰고 명령 없음(6건) | 실행 명령이 없음 | 합계를 만든 명령을 같은 줄에 | | 근거파일에 경로만(11건) | 줄 번호 없음 | 경로:줄번호 "인용" | | [자동 보강 …] 아래 문장 복사(6건) | 자기지시적 placeholder | 실제 내용을 직접 씀 |

3) 제출 직전 체크 3줄 (guardian 전용, 작업 지시문 머리말에도 붙이기)

  1. "검증:" 같은 줄에 exit code 0 글자가 있고 그 사이에 조사(는·은·가)가 없는가?
  2. "근거파일:"의 경로를 방금 ls로 열어 봤고 경로:줄번호 "인용" 형태인가?
  3. "[자동 보강 …]" 아래 문장을 한 글자도 복사하지 않았는가?

4) completion_evidence_policy 신규 절 — 분류 작업 재발행 루프 차단

  • 제목군 "needs_evidence N건 … 분류/집계"는 직전 건이 done이 되기 전 재발행 금지.
  • 분류 결과는 memory/ 또는 400-reports/의 파일로 남기고 보고는 4줄로 끝낸다.
  • 분류 작업 자체의 보고도 위 §9-3-3 형식을 따른다.

5) 운영 체크리스트 한 줄 추가

게이트·프롬프트 패치 후에는 ps -axo pid,lstart,command | grep 'agent_queue_worker.py --agent guardian'의 기동시각과 해당 파일 수정시각(stat -f '%Sm' <파일>)을 비교하고, 기동시각이 더 이르면 재시작 전까지 "패치 반영됨"이라고 보고하지 않는다.

[코드 수정 지점 후보] (수정하지 않음, codex 위임용)

  • scripts/agent_registry.py 311~337행 guardian 프롬프트: 334행 경고를 "exit code 바로 뒤 숫자, 같은 줄 필수, 조사 금지"로 확장. 라벨 설명에 §9-3-3 고정 문구 4줄을 넣는 것도 후보.
  • scripts/shared/agent_task_quality.py 1016행(결론: 보강 문구)과 _supplement_bare_completion_evidence_description(1039행): 문구를 "[예시]"가 아닌 지시형으로 바꾸거나, 에이전트가 복사했을 때 탐지하는 게이트 추가.
  • scripts/orchestrator.py 1129행, 1517행: 같은 보강 문구 생성 지점. 재발행 루프 방지 판단은 태스크 생성 함수의 제목군 중복 검사(함수명 미확인, 확인 필요).
  • scripts/agent_queue_worker.py 7042행 _CODEX_VERIFICATION_EXIT_CODE_RE: exit code는 0을 읽을지(조사 허용) 여부는 정책 결정 사항. 허용하면 4건 구제, 허용하지 않으면 문서로 막는다. 문서 우선을 권고한다.
  • scripts/agent_queue_worker.py 워커 기동 후 코드 미재적재: 주기적 mtime 비교 경고 후보. 현재는 PID 3974 재시작 필요 여부를 해리가 판단.

[검증방법]

지표(KPI): - guardian 최근 10건 제출 중 done ≥ 7건(현재 2026-10-06 이후 20건 중 1건, 5%). - guardian needs_evidence 신규 유입: 일 4~5건 → 일 1건 이하(문서 반영 후 3일). - D표 "검증 줄 비움"·"조사 끼움" 유형 신규 발생 0건.

검증 명령(조회만): - sqlite3 -readonly /Users/ron/.hermes/data/ops_multiagent.db "select status,count(*) from bus_commands where claimed_by='guardian' and created_at>='<문서 반영 시각>' group by status" → done 비율 확인. - sqlite3 -readonly /Users/ron/.hermes/data/ops_multiagent.db "select count(*) from bus_commands where status='needs_evidence' and claimed_by='guardian'" → 기준 26에서 감소 확인. - grep -n '9-3-3' /Users/ron/.hermes/workspace/config/agent_completion_submission_standard.md → 신설 절 존재(1건 이상).

롤백 조건: 문서 반영 후 guardian 연속 5건에서 missing_verification_exit_code 또는 invalid_verification_exit_code가 3건 이상 다시 나오면, 문서 문구가 아니라 워커 미재시작(기동시각 < 파일 수정시각)부터 의심하고 해리에게 재시작 승인을 요청한다. 그래도 개선이 없으면 _CODEX_VERIFICATION_EXIT_CODE_RE 조사 허용을 codex에 위임한다.

부록: 확인 못 한 것

  • 일반 문구("결과 확인 보류"만) 반려 10건 중 재생에서 통과한 9건이 정확히 어느 게이트에서 막혔는지.
  • 현재 실행 중 guardian 워커가 10-13 패치 코드를 읽고 있는지(기동시각 기준으로는 읽지 않았을 가능성이 높으나 프로세스 내부 확인은 안 함).
  • orchestrator의 분류 작업 재발행 판단 함수명.