원천 데이터 0건 태스크의 완료 판정 정책안 (지식사랑방 인사이트 반복 실패 방지)
원천 데이터 0건 태스크의 완료 판정 정책안
정책 한 줄: "원천 0건"은 실패가 아니라 하나의 정상 결과 유형(ZERO_SOURCE)으로 인정한다. 단 조회 명령·0 실측값·대상 경로·최근 원문 날짜 4필드를 갖춘 경우에만 done을 허용하고, 같은 계열이 원천 공백으로 2회 연속 끝나면 오케스트레이터는 같은 제목 재발행을 멈추고 guardian 수집경로 진단 태스크 1건으로 전환한다.
[권고]
- 1순위: ZERO_SOURCE 완료 경로 신설 + ron 인사이트 핸들러의 검증 명령 필드 누락 수정 (codex 위임).
근거: #39860은 ron이 LLM 없이 도는 결정적 핸들러(
scripts/agent_queue_worker.py::_handle_ron, 5405행is_insight분기)가 rc=0×3으로 끝났는데도 반환문(5468~5473행)에verification_command:리터럴이 없어missing_verification_command단독으로 반려됐다. 2026-09-06에 run-cycle/헬스체크 핸들러에서 고친 것과 똑같은 구조 결함이 인사이트 분기에만 남아 있다. 기대효과: 이 계열 반려 3건/일(09-24 실측) → 0건. 재발행 연쇄(원 1건 → 재생성 2건) 제거로 하루 최소 2건의 불필요 태스크 감소. - 2순위: 원천 공백 확인 시 동일 제목 재발행 중단 → guardian 진단 태스크 1건으로 전환 (codex 위임).
근거: 지식사랑방 원문은 2026-08-19(
260819_시장브리핑.md) 이후 36일간 0건이다. 이 상태에서 인사이트 태스크를 재발행해도 결과는 항상 "0건"이며, 09-23·09-24 이틀 연속 빈 보고서가 생성됐다. 실패 원인은 에이전트가 아니라 수집 경로다. 기대효과: 원천 공백 기간 중 인사이트 계열 태스크 생성 0건(현재 360분 주기 → 하루 최대 4건 + 재생성분), guardian 진단 1건으로 원인 추적이 시작됨. - 3순위: 정직한 "미확인" 표기를 hard block에서 제외.
근거: #39864(cowork)는 4블록·실존 경로·검증 명령을 모두 갖췄는데 [리스크] 절의 "수집이 멈춘 원인은 확인하지 못했습니다(미확인)" 한 문장이
_completion_block_reasons()의 "확인 못함" 패턴(3420행)에 걸려 반려됐다. 본 작업 범위 밖 항목을 미확인이라고 밝히는 것은 SOUL 원칙("확인 못 한 것은 미확인이라고 말한다")이 요구하는 행동이다. 기대효과: 정상 보고의 오탐 반려 1건/일(09-24 실측) → 0건.
[현황] (조회 2026-09-24 02:24~02:27 KST)
| CMD | 담당 | 상태 | 실제 반려 사유 (로그 원문) | 진짜 원인 |
|---|---|---|---|---|
| #39860 | ron | failed | reasons=missing_verification_command (agent-queue-ron.log 136491행) |
결정적 핸들러 반환문에 verification_command: 없음. 파이프라인 자체는 rc=0, discovery_filter Candidates: 3777, New: 0, Passed(≥6): 0 |
| #39863 | ron | failed | missing_* 7종 (result_note) | ron이 작업하지 않고 cowork로 위임만 함([위임] 코워크 작업 큐에 등록됨, 136575행). 위임 메모엔 증거가 없으니 게이트가 7종 전부 누락으로 판정 |
| #39864 | cowork | failed | reasons=확인 못함 (agent-queue-cowork.log 171997행) |
4블록 완비·0건 실측 포함. [리스크] 절 "확인하지 못했습니다(미확인)" 문장 오탐 |
- 지식사랑방 인사이트 계열 09-24 생성 3건 중 done 0건(0%), failed 3건(100%). 08-20 이후 이 계열 done 0건.
- 산출물은 실존한다:
260924_hermes_지식사랑방-인사이트.md(1,992바이트, 02:08),260923_hermes_지식사랑방-인사이트.md(1,531바이트, 09-23 13:15). 즉 "결과물은 있는데 완료 경로가 없는" 상태. - 원천 폴더 실측:
100 수신함/120 지식사랑방+200 정리/210 지식사랑방, 2026-09-20 이후 수정 파일 0건. 최근 원문260819_시장브리핑.md(수정일 2026-08-19). - 재발행 제목이 "오늘의 지식사랑방 인사이트 생성" → "지식사랑방 오늘자 인사이트 재생성(검증 명령 누락으로 반려됨)"으로 바뀌어
_normalize_retry_title_for_grouping()(orchestrator.py 3257행)이 같은 계열로 묶지 못한다. 그래서 evidence-gate 서킷브레이커(3969행, 임계 3회/30분)도 걸리지 않았다. - 부수 결함: #39863/#39864 body 앞에
[EVENT:hormuz_blockade]마커가 붙어 있다. 호르무즈는 해리가 현재 제외한 주제이고 이 태스크와 무관하다 — 이벤트 마커 상속 오류로 보이며 원인은 미확인.
정책 본문
(1) ZERO_SOURCE 완료 보고 필수 필드
원천 데이터가 0건이라 본래 산출물(인사이트, 가설 등)을 만들 수 없는 경우, 아래 조건을 모두 갖추면 status=done으로 인정한다. 결론은 "0건을 확인했다"는 완료형이어야 한다.
result_note 필수 요소 (4블록 라벨은 기존 표준 그대로 유지하고, 추가로 zero_source: 블록을 둔다):
결론: <대상> 원천 0건을 실측 확인했고 0건 보고서를 <경로>에 저장했다.
근거: zero_source_scope: <조회한 대상 폴더/테이블 절대경로, 1개 이상>
zero_source_query: <실제 실행한 조회 명령 1줄> → 0
zero_source_window: <조회 기간, 예: 2026-09-17~2026-09-24>
zero_source_latest: <대상 범위에서 가장 최근 원문 경로> (<날짜 YYYY-MM-DD>)
조회 YYYY-MM-DD HH:MM KST
검증: verification_command: <0건 재현 명령 또는 보고서 실존 확인 명령> → <결과값>, exit 0
근거파일: source_log_path: <0건 보고서 실경로>:<줄> "<원문 인용>"
필드별 판정 기준:
zero_source_scope— 경로가 실제로 존재해야 한다(Path.exists()). 없는 폴더를 조회해서 0이 나온 것은 0건이 아니라 경로 오류다 →zero_source_scope_not_found로 반려.zero_source_query— 명령 1줄과 결과값0(또는0건)이 같은 줄에 있어야 한다. "없었다" 같은 서술만은 불인정 →missing_zero_source_query.zero_source_window— 조회 기간 명시. 태스크가 "오늘자"를 요구해도 최소 최근 7일은 같이 보았다는 기록이 있어야 공백의 규모를 판단할 수 있다.zero_source_latest— 대상 범위의 최근 원문 1건 경로와 날짜. 이 파일은 실존해야 한다. 원문이 한 건도 없으면없음(폴더 전체 0건)으로 쓰되zero_source_scope폴더의 파일 수를 함께 적는다. 이 날짜가 "공백 일수" 계산의 기준이 된다(예: 2026-08-19 → 36일).- 0건 보고서 파일 —
source_log_path가 가리키는 파일이 실존하고, 본문에zero_source_query와 같은 명령이 들어 있어야 한다(보고서와 result_note가 서로 다른 말을 하지 않게).
금지:
- 원문이 없는데 인사이트·가설을 지어내는 것(기존 정책 그대로).
- zero_source_query의 결과가 0이 아닌데 ZERO_SOURCE로 제출하는 것 → zero_source_value_mismatch.
- 파이프라인이 rc≠0으로 실패했는데 0건으로 포장하는 것. 실행 실패는 원천 공백이 아니다(Passed: 0과 rc=1은 구분).
범위 밖 항목의 "미확인" 표기 허용:
- [리스크]/후속 조치 절에서 "원인 미확인", "확인하지 못했다(미확인)"처럼 태스크 범위 밖 항목을 밝히는 문장은 ZERO_SOURCE 필수 필드 4개가 모두 통과한 경우에 한해 hard block 사유에서 뺀다. 결론·근거·검증 블록 안의 "확인 못함"은 여전히 반려한다.
(2) 원천 공백 시 재발행 중단 → guardian 진단 전환 규칙
- 판정 신호: bus_commands 완료 result_note에
zero_source_query: ... → 0이 있으면(ZERO_SOURCE done), 또는 결정적 핸들러 출력이New: 0·Passed(≥6): 0이면 해당 루틴 계열을 "원천 공백 1회"로 센다. - 계열 키: 재발행 제목이 바뀌어도 한 계열로 묶이도록, 루틴 원 제목(RON_ROUTINES의
title) 또는state_key(last_insight_gen)를 기준으로 센다. "재생성", "(… 반려됨)" 같은 꼬리는 정규화에서 떼어낸다. - 2회 연속 원천 공백(서로 다른 날짜 또는 360분 주기 2회)이면:
- 같은 루틴의 신규 발행과 실패 재발행(
_retry_failed_commands)을 멈춘다. - guardian에 진단 태스크 1건만 발행한다: 제목
[수집공백] 지식사랑방 원천 <N>일째 0건 — 수집경로 점검, 본문에 scope 경로·최근 원문 날짜·공백 일수·마지막 0건 CMD id를 넣는다. 같은 계열 진단 태스크가 열려 있으면(queued/claimed) 추가 발행하지 않는다. - ops_todos에 1건 등록(중복 방지 키: 계열 키 + "zero_source").
- 해제 조건: scope 폴더에 최근 1일 내 수정 원문이 1건 이상 생기거나, guardian 진단이 done으로 끝나 "수집 복구"를 보고하면 루틴을 재개한다. 자동 해제 전에는 최대 7일 보류 후 1회 재시도.
- 원천 공백 중 발행된 태스크가 반려돼도 "근거미비" 재발행(기존 표준 §10-2)을 적용하지 않는다. 지시문을 고쳐도 원천이 없으면 결과가 같기 때문이다.
- 위임(핸드오프)만 하고 끝난 태스크(#39863처럼 "[위임] … 큐에 등록됨")는 failed로 세지 않고 delegated로 분류한다(기존 §8 원칙 재확인). 위임 대상이 반려되면 계열당 1회만 센다.
(3) codex 위임 코드 수정 지점 (파일·함수 수준, 코드는 작성하지 않음)
| 우선 | 파일 | 함수/위치 | 수정 내용 |
|---|---|---|---|
| 1 | scripts/agent_queue_worker.py |
_handle_ron() 내 is_insight 분기 (5405~5474행) |
반환 note에 결론/근거/검증/근거파일 4블록과 verification_command: 리터럴 추가(09-06 run-cycle 패치와 같은 방식). discovery_filter 출력이 Passed(≥6): 0이면 "정상 완료" 대신 ZERO_SOURCE 형식(scope=지식사랑방 두 폴더, latest=최근 원문)으로 반환 |
| 1 | scripts/agent_queue_worker.py |
_completion_required_evidence_gaps() (1404행) / _completion_block_reasons() (3397행) |
zero_source_* 4필드 파서 추가. 4필드 통과 시 산출물 부재 계열 gap을 면제하고, [리스크]/후속 조치 절의 "확인 못함"(3420행 패턴)을 제외 |
| 1 | scripts/shared/public_result_formatter.py |
completion_required_evidence_gaps() (2629행), completion_block_reason_labels() (3279행) |
위와 같은 규칙을 공용 판정 쪽에도 이중 반영(두 파일이 따로 판정하므로 한쪽만 고치면 다시 어긋남) |
| 2 | scripts/orchestrator.py |
_normalize_retry_title_for_grouping() (3257행) |
"재생성", "(…반려됨)", "오늘자/오늘의" 변형을 원 제목으로 정규화하거나 state_key 기준 그룹핑 추가 |
| 2 | scripts/orchestrator.py |
RON_ROUTINES 디스패치 경로(789행 정의, 2797행 사용) |
발행 전 "원천 공백 2회 연속" 여부 확인 → 해당 루틴 보류 + guardian 진단 태스크 발행 |
| 2 | scripts/orchestrator.py |
_retry_failed_commands() (3315행) |
원천 공백 계열은 재발행 대상에서 제외 |
| 2 | scripts/orchestrator.py |
create_task() (2203행) |
원천 공백 진단 태스크 중복 방지(열린 진단 태스크 있으면 생성 안 함). 재생성 태스크에 상위 이벤트 마커([EVENT:hormuz_blockade])가 잘못 상속되는 경로 조사 |
| 3 | config/agent_completion_submission_standard.md |
신규 §11 | 이 문서 (1)의 필드 표를 표준 본문으로 승격 |
| 3 | config/completion_evidence_policy.md |
신규 v34절 | 배경(#39860/#39863/#39864)과 (2) 규칙 기록 |
[리스크]
- 면제 남용: ZERO_SOURCE가 "일하기 싫을 때 0건이라고 쓰는" 우회로가 될 수 있다. 막는 장치는 (a) scope 경로 실존 검사, (b) 조회 명령 재실행 가능성(경로가 실존해야 함), (c) 보고서 본문과 result_note의 명령 일치 검사다. 그래도 조회 조건 자체를 좁게 잡는 남용(예: 파일명만 보고 본문은 안 봄)은 기계적으로 못 막는다 — window 7일 필수로 완화.
- 판정 이중화: 같은 규칙이
agent_queue_worker.py와public_result_formatter.py에 따로 있어 한쪽만 고치면 다시 어긋난다(기존 정책 문서에 동일 사례 다수). 반드시 두 곳 동시 반영 + 같은 fixture로 검증. - 단일 장애점: 지식사랑방 원천은 텔레그램 → 수신함 한 경로뿐이다. 이 정책은 반려 반복을 멈추게 할 뿐, 수집 복구는 guardian 진단 결과에 달려 있다. 수집 중단 원인은 현재 미확인.
- 보류 장기화: 자동 보류 후 해제가 안 되면 수집이 복구돼도 인사이트가 안 나온다. 7일 상한 재시도로 완화.
- 이 문서는 초안이다. config 두 문서 본문은 아직 고치지 않았다(표의 3순위 항목).
[검증방법]
- KPI 1: codex 반영 후 7일간 지식사랑방 인사이트 계열
failed건수 0.sqlite3 -readonly /Users/ron/.hermes/data/ops_multiagent.db "SELECT status,count(*) FROM bus_commands WHERE title LIKE '%지식사랑방%인사이트%' AND created_at>=date('now','-7 days') GROUP BY status"→ failed 0. - KPI 2: 원천 공백 중 같은 계열 신규 태스크 ≤ 2건 + guardian 진단 1건.
... WHERE target_agent='guardian' AND title LIKE '[수집공백]%'→ 1건. - KPI 3: #39864 result_note 원문을 fixture로 넣었을 때
_completion_block_reasons()결과[], 같은 문서에서zero_source_query줄을 지우면missing_zero_source_query반환. - KPI 4: #39860 핸들러 재실행 시 반환 note에
verification_command:포함, 게이트 통과. - 롤백 조건: 반영 후 7일간 ZERO_SOURCE done 중 수작업 표본 5건 이상에서 실제 원문이 있었던 것(거짓 0건)이 1건이라도 나오면 면제 규칙을 끄고 재설계.
근거 원문 위치
- bus_commands #39860/#39863/#39864:
/Users/ron/.hermes/data/ops_multiagent.db(조회 2026-09-24 02:24 KST) - ron 반려 로그:
/Users/ron/.hermes/logs/agent-queue-ron.log136491행[completion-evidence-block] id=39860 agent=ron reasons=missing_verification_command routed_status=failed - cowork 반려 로그:
/Users/ron/.hermes/logs/agent-queue-cowork.log171997행[completion-evidence-block] id=39864 agent=cowork reasons=확인 못함 routed_status=failed - 파이프라인 로그:
/Users/ron/.hermes/workspace/logs/insight-pipeline-result-20260924T004350.log - 0건 보고서:
/Users/ron/knowledge-agent/400-reports/260924_hermes_지식사랑방-인사이트.md - 기존 재발행 규칙:
config/agent_completion_submission_standard.md§10 (953행~)