virtual-insanity
← 리포트 목록

needs_evidence 68건 해소 방안 제안서 (guardian #42357 분류 재집계 기반)

2026-10-22 claude [needs_evidence, 완료보고, 증거게이트, 재집계, KPI, 아카이브, 제안서, cowork]

needs_evidence 68건 해소 방안 제안서

작성: Cowork(다듬) / CMD#42362 / 조회 2026-10-22 14:44~14:52 KST / 코드·DB·크론·재큐잉 변경 없음(제안서만)

이미 있는 내용은 다시 쓰지 않는다. 겹침 확인 대상: AGENTS.md "대행 태스크 완료보고 검증 근거 정책", config/agent_completion_submission_standard.md, config/needs_evidence_recurrence_policy_proposal_20261022.md, 400-reports/261021_hermes_needs_evidence_prevention.md, 261022_claude_needs_evidence_개선안.md, 261020_claude_needs_evidence_triage.md. 이 문서는 위 문서들에 없는 것만 담았다.

[권고]

→ 1순위 (운영 규칙 + 해리 승인 대기 코드 후보): 성과 지표를 "라이브 needs_evidence 건수"에서 "반려 유입량(라이브+아카이브 합산)"으로 바꾼다. 이유: 기존 제안서 6개의 KPI는 전부 status='needs_evidence' 라이브 건수만 센다. 그런데 2026-10-16 이후 반려 문구가 저장된 310건 중 needs_evidence로 남은 것은 26건(8.4%)뿐이고 284건(91.6%)은 failed로 저장돼 2시간 뒤 아카이브로 빠진다. 지금 KPI로는 반려가 하루 40~60건 계속 나도 "신규 ≤3건/주" 목표가 달성된 것으로 읽힌다. 기대효과: 오판 없는 합격선(아래 [검증방법] 쿼리 한 개).

→ 2순위 (codex 후보, 해리 승인 후): needs_evidence 상태에는 나가는 길이 없다. orchestrator.py::_cleanup_old_commands는 done/cancelled/failed만 아카이브하고 needs_evidence는 대상에서 빠져 있다. 그래서 68건 중 42건(61.8%)이 7일 넘게, 20건(29.4%)이 14일 넘게(최고령 9월 28일, 24일) 쌓여 있다. 오래된 반려 건에 일정 기간 뒤 아카이브로 옮기는 경로를 만든다(초안은 아래 T1). 기대효과: 라이브 68건 → 14일 기준 적용 시 48건, 7일 기준이면 26건. 단 이는 정리일 뿐 재발 방지가 아니므로 1순위와 묶어서만 의미가 있다.

→ 3순위 (기준선 정정, 코드 없음): 261022_claude_needs_evidence_개선안.md의 C1 기대효과 기준선 "집계 태스크 일 4.7건"은 라이브 테이블만 센 값이다. 실측 기준선은 하루 28~36건이다. C1 반영 후 KPI는 이 기준선으로 비교해야 한다. 기대효과: C1 효과를 7배 낮게 평가해 중단하는 판단 오류를 막는다.

[현황]

1. 직접 재집계 (sqlite3 -readonly, 조회 14:44~14:50)

  • 상태 전체: claimed 1, done 6, failed 1, needs_evidence 68. needs_evidence 68건의 claimed_by는 guardian 50, cowork 8, analyst-macro 5, analyst-pm 4, ron 1 (합 68). 요청자는 68건 전부 orchestrator다.
  • 분류 방법: result_note의 차단 사유: ~ 보완 필요 구간만 파싱했다. 같은 단어가 "원본 요약" 안에 서술로 쓰인 경우를 세지 않기 위해서다.
순위 반려 라벨(차단 사유 구간) 건수 비율 에이전트
1 missing_verification_exit_code 20 29.4% guardian 19, cowork 1
2 missing_result_or_verification 13 19.1% analyst-macro 5, analyst-pm 4, guardian 3, cowork 1
3 invalid_verification_exit_code 8 11.8% guardian 5, cowork 2, ron 1
4 missing_verification_command 6 8.8% guardian 5, cowork 1
5 completion_result_note_forces_rework 4 5.9% guardian 3, cowork 1
6 verification_command_unverifiable 3 4.4% guardian 2, cowork 1
6 missing_execution_artifact 3 4.4% guardian 2, cowork 1
6 execution_artifact_path_not_found 3 4.4% guardian 3
- 구체 라벨 없음(껍데기 문구만) 24 35.3% guardian 21, cowork 3
  • 한 건에 라벨이 둘 이상인 경우가 10건이라 라벨 합계는 68을 넘는다.
  • 상위 2개 라벨: missing_verification_exit_code(20건), missing_result_or_verification(13건). 라벨이 있는 44건 중 검증 줄 계열(exit code 누락·오류, 검증 명령 누락·재현 불가)은 31건(45.6%)이다.
  • 편중된 에이전트: guardian 50/68 = 73.5%. 제목에 needs_evidence가 들어간 집계·분류 태스크가 49건(guardian 43, cowork 6, 72.1%)이다. 상위 1위 라벨은 guardian이 19/20, 상위 2위 라벨은 analyst 9건(전부 미국 IG/HY OAS 파일 판독)이 중심이다.
  • 요청서가 예시로 든 라벨: missing_source 0건, missing_execution_value 0건, missing_verification_value 0건(차단 사유 구간 기준). 본문 서술에 한 번씩 쓰인 것만 있다(missing_source 1, missing_execution_value 1). execution_artifact_path_not_found는 3건이다.

2. guardian #42357 분류표와의 대조

  • 42357(guardian, 13:42:35 생성, 13:44:05 done)의 result_note는 DB에 476자만 저장돼 있다. 결론 줄이 "…#42127..."에서, 근거 줄이 "ORD..."에서, 근거파일 줄이 근거파일: :2 "라벨별 합계: verification=25, unlabeled(코드 없음…)=24, result_or_verification(execution+verificati…에서 잘려 있다. 분류표 본문과 파일 경로는 DB에서 복원되지 않는다. 13:30~13:50에 새로 생긴 파일도 workspace/memory와 knowledge-agent에서 찾지 못했다(find -newermt, 0건). 즉 분류표 전체는 미확인이다.

  • 보이는 범위에서의 대조:
  • "llm_infra_failure와 missing_source 계열은 실제 반려 사유로는 0건": 일치(차단 사유 구간 0건/0건).
  • "unlabeled=24": 일치(24건).
  • "verification=25": 불일치. 내 재집계는 exit code 계열만 28건(missing 20 + invalid 8), 명령 누락·재현 불가까지 넣으면 31건이다. guardian의 25가 어떤 정의인지 잘려서 알 수 없다. 이 숫자는 인용하지 않는다.
  • 문자열 검색으로 세면 llm_infra_failure가 17건으로 나온다(전부 guardian). 차단 사유 구간에는 0건이고, "인프라 때문이 아니다"라고 쓴 문장 때문이다(기존 개선안 문서가 이미 지적한 오분류와 같은 현상이 재현됐다).

3. 새로 확인한 사실 A — 라이브 건수는 유입량의 일부일 뿐이다

  • 조회: bus_commands + bus_commands_archive를 합쳐 result_note가 결론: 결과 확인 보류나 결론: needs_evidence:로 시작하는 건(created_at 기준).
날짜 failed needs_evidence 합
10-16 49 3 52
10-17 57 5 62
10-18 43 2 45
10-19 38 3 41
10-20 40 4 44
10-21 39 5 44
10-22(부분) 18 4 22
합계 284 26 310
  • logs/agent-queue-guardian.log에서 "worker_status": "needs_evidence"인 줄 621개가 전부 "routed_status": "failed"이고, 그중 620줄에 block_reasons: non_ron_harry_direct가 있다(누적 로그, 기간 미한정). 즉 워커는 needs_evidence로 판정했지만 저장 단계에서 failed로 기록되는 경로가 대다수다. 어떤 조건에서 나머지 소수만 needs_evidence로 남는지는 미확인이다(server.py 964행, 3124행, 5711행에 needs_evidence 저장 분기가 있다는 것까지만 확인).
  • 이 중 failed 건은 _cleanup_old_commands가 2시간 뒤 아카이브로 옮기고, 아카이브는 30일 지나면 삭제한다(orchestrator.py 2790~2810행). 아카이브에는 model_used·workflow_id·notify_flag·parent_cmd_id 열이 없다.

4. 새로 확인한 사실 B — 집계 태스크 실제 발행량

  • guardian 대상, 제목에 needs_evidence 포함, 라이브+아카이브 합산:
날짜 합산 발행 이 중 done 라이브 테이블만 본 값
10-17 18 2 3
10-18 22 2 2
10-19 28 3 2
10-20 34 3 4
10-21 36 3 5
10-22(부분) 19 4 5
  • 10-19~10-21 3일 합계 98건(일 약 33건), done은 9건(9.2%). 261022_claude_needs_evidence_개선안.md [현황]의 "일 평균 약 4.7건"은 라이브만 센 값이라 약 7배 낮다.
  • 10-19~10-22 합산 101건의 제목은 숫자를 지워도 86개 서로 다른 문구다(가장 흔한 문구 5건). 재발행 루프 게이트의 계열 키로는 묶이지 않는다는 기존 지적과 같은 방향의 수치다.
  • orchestrator.py 911행은 지금도 "counts": counts로 큐 상태를 Ron LLM에 그대로 넘긴다. 파일 수정 시각은 10-19 21:01이고 C1 반영 흔적은 없다. NEEDS_EVIDENCE_REISSUE_LOOP_BLOCKED는 logs/ron_orchestrator.log·ron_orchestrator_error.log·orchestrator_rescue.log에 0건이다.

5. 기존 문서와 겹침 확인 (넣지 않은 것)

  • 106개 문서(config/.md, 400-reports/needs_evidence*, memory 관련)에서 _cleanup_old_commands, TTL, 아카이브 제외, 일 유입 합산 같은 표현은 0건이다(grep -l). 그래서 위 1~3순위만 새로 제안한다.
  • 이미 있는 내용이라 다시 쓰지 않는다: exit code 리터럴 규칙(standard §9-4 조항 1), 4블록 템플릿(§3, §9-3), 재발행 루프 게이트 설계(261019 reissue_loop_policy)와 계열 키 확장안(261021 후보 1, 261022 C4), 큐 건수 입력 차단(C1), 제출 전 라벨 사전검사(261021 후보 3), 종결 51건 안(261020 triage, 해리 승인 대기).

T1. codex용 태스크 초안 (코드 수정 필요, 직접 수정하지 않음, 해리 승인 후 발행)

  • 제목: orchestrator _cleanup_old_commands에 오래된 needs_evidence 반려 건 아카이브 경로 추가
  • 수정 대상: scripts/orchestrator.py _cleanup_old_commands (2790~2803행의 INSERT/DELETE 두 구문 부근)
  • 내용: status='needs_evidence'이고 created_at이 기준일(환경변수, 기본 14일)보다 오래됐고 result_note가 결론: 결과 확인 보류나 결론: needs_evidence:로 시작하는 건만 아카이브로 복사한 뒤 라이브에서 제거한다. 환경변수 0이면 비활성(롤백). 복사 전 건수를 로그로 남긴다. 아카이브에 없는 열(model_used 등) 손실은 로그에 한 줄로 알린다. 삭제가 아니라 이동이므로 30일 아카이브 보존 정책 안에서만 복원 가능함을 로그에 적는다.
  • 검증 명령: python3 -m py_compile scripts/orchestrator.py → exit 0. 신규 pytest(임시 DB에 14일 초과 needs_evidence 2건, 14일 이내 1건, done 1건을 넣고 실행) → 2건만 이동. 실제 DB 시험 전 읽기 전용 예상치 sqlite3 -readonly …ops_multiagent.db "SELECT count(*) FROM bus_commands WHERE status='needs_evidence' AND created_at<datetime('now','localtime','-14 days')" → 2026-10-22 14:50 기준 20.
  • 기대값: 반영 후 첫 정리 주기에 라이브 needs_evidence 68 → 약 48.
  • 롤백 조건: 기준일 설정을 0으로 되돌리고, 이동된 건은 아카이브에서 id 기준으로 되돌린다(열 손실 허용 범위 해리 확인).
  • 선행 조건: 해리 승인. 261020_claude_needs_evidence_triage.md의 종결 51건 안과 같은 건들을 건드리므로 둘 중 하나만 실행한다.

T2. codex용 조사 초안 (읽기 전용, 코드 수정 아님)

  • 제목: 워커 needs_evidence 판정이 저장 시 failed로 기록되는 조건 확인
  • 대상: scripts/server.py 1089행(non_ron_harry_direct 부착), 964행, 3124행, 5711행의 needs_evidence 저장 분기
  • 질문: 621줄 중 620줄에 붙은 non_ron_harry_direct가 최종 bus_commands.status를 failed로 만드는지, 그렇다면 의도된 동작인지. 확인 못 했으므로 현재는 가설이다.
  • 검증: 재현 1건을 임시 DB로 돌려 최종 status가 failed인지 needs_evidence인지 로그와 함께 보고. 코드 변경이 필요하면 별도 태스크로 분리한다.

[리스크]

  • 합산 KPI도 result_note 접두 문구에 의존한다. 게이트 문구가 바뀌면 건수가 누락된다. 대비책: 쿼리의 두 접두어를 문서에 고정하고 분기마다 샘플 5건으로 확인한다.
  • T1은 라이브 건수만 줄인다. 1순위 기준선이 없으면 "68 → 48 감소"를 개선으로 오해할 수 있다. 성과 판정은 반드시 합산 유입량으로 한다.
  • 아카이브는 30일 뒤 삭제된다. 오래된 반려 사유 증거가 장기 보존되지 않는다. 필요한 분류 결과는 400-reports 파일로 남겨야 한다(기존 261021 공백 C와 같은 방향).
  • 단일 장애점: orchestrator 프로세스 PID 46446(9월 27일 07:55 기동)이 10-19 이후 수정본을 로드했는지는 이번에도 확인하지 못했다. ps로 기동 시각은 확인했으나 코드 재로드 여부는 미확인. 재시작은 해리 승인 사항이다.
  • 미확인: guardian #42357 분류표 본문, 반려가 failed로 기록되는 정확한 조건(T2), verification=25 정의.

[검증방법]

  • KPI 1 (유입량, 이 문서의 합격선): sqlite3 -readonly /Users/ron/.hermes/data/ops_multiagent.db "SELECT substr(created_at,1,10), count(*) FROM (SELECT created_at, result_note FROM bus_commands UNION ALL SELECT created_at, result_note FROM bus_commands_archive) WHERE created_at>='2026-10-23' AND (result_note LIKE '결론: 결과 확인 보류%' OR result_note LIKE '결론: needs_evidence:%') GROUP BY 1" 기대값: 현재 일 41~62건에서 하루 20건 이하로 감소(첫 합격선), 롤백 판단은 7일 평균이 감소하지 않을 때.
  • KPI 2 (집계 태스크 발행량): SELECT substr(created_at,1,10), count(*) FROM (SELECT created_at,target_agent,title FROM bus_commands UNION ALL SELECT created_at,target_agent,title FROM bus_commands_archive) WHERE target_agent='guardian' AND title LIKE '%needs_evidence%' AND created_at>='2026-10-23' GROUP BY 1 → C1 반영 뒤 하루 3건 이하(현재 28~36건).
  • KPI 3 (잔량): SELECT count(*) FROM bus_commands WHERE status='needs_evidence' → T1 반영 후 48 안팎, 이후 증가폭 0.
  • 이 문서 자체: 위 쿼리 결과가 14:50 기준값(310건, 98건)과 어긋나면 재집계한다.
  • 롤백 조건: T1 반영 후 24시간 안에 아카이브 이동 건이 기준 밖 상태이거나 정상 점검 태스크가 사라지면 기준일을 0으로 되돌린다.