[Bug] 루프가 creator 의 하위 위임 잡을 기다리지 않고 리뷰로 넘어가 미완성 결과물이 PASS 됨 #34

Closed
opened 2026-09-22 06:59:31 +00:00 by Godopu · 0 comments
Owner

증상

run_loop.sh 로 돌린 작업에서 creator 가 작업의 일부를 다른 에이전트에게 delegate-job 으로 위임한 경우, 그 하위 잡이 아직 running 인데도 루프가 Phase 3(리뷰)로 넘어가 PASS 로 종료됩니다. 결과적으로 작업의 절반만 끝난 산출물이 승인됩니다.

재현

교재 저장소에서 아래 형태로 실행:

  • task: 문서 교정 + 챕터별 그림 삽입, 단 그림 제작은 creator-agy-image 에게 위임하도록 브리프에 명시
  • --plan --planner <p> --reviewer <p> --creator creator-claude-01 --max-loop 3

실제 진행:

시각 사건
Phase 2 creator 가 delegate-job 으로 이미지 잡 8c2ac62b 생성 (creator-agy-image)
Phase 2 종료 creator 자신의 잡 8e0fb22a 만 completed → 루프가 즉시 다음 단계로
Phase 3 리뷰어가 그림 없는 문서를 보고 [VERDICT: PASS]
루프 종료 이미지 잡 8c2ac62b 은 여전히 running

문서에는 이미지 참조가 0건인 채로 루프가 100% PASS 로 끝났습니다.

원인

  • lib_py/loop/runner.py:467 wait_for_job(job_id) 는 self.created_jobs(= 루프가 직접 만든 잡)만 감시합니다.
  • 잡 레코드에 부모-자식 관계가 없습니다. lib_py/ 와 multi-agent-mux-*/scripts/ 전체에 parent_job / child_job / children 이 존재하지 않습니다.
  • 따라서 creator 가 만든 하위 잡은 루프에게 보이지 않습니다.

수정 방향

1. 잡 트리 대기 (본 이슈의 주된 수정 방향)

레지스트리에 부모 잡 ID 를 기록하고(delegate-job 호출 시 환경/컨텍스트에서 상속), wait_for_job 이 자식 잡까지 함께 기다리도록 합니다.

검토 사항:

  • 부모 ID 상속 경로 — 에이전트가 delegate-job 을 호출할 때 자신이 수행 중인 잡 ID 를 어떻게 전달받을지 (환경변수 주입 등)
  • 대기 종료 조건 — 자식 잡이 계속 손자 잡을 만드는 경우의 깊이·타임아웃 처리
  • 자식 잡 실패 시 부모 잡의 판정 (실패 전파 여부)

참고로 lib_py/worktree.py:107 의 open_jobs(rows, dirs, exclude_ids) 가 "세션들의 열린 잡" 을 조회하며, multi-agent-mux-stop/scripts/worktree_remove.sh:75 에서 이미 같은 목적("열린 잡이 있으면 거부")으로 쓰이고 있습니다. 부모-자식 관계가 도입되기 전의 임시 방어선으로, 또는 잡 트리 대기의 보조 검사로 활용할 수 있습니다.

2. 리뷰어가 하위 잡 상태를 검토 근거에 포함

리뷰어 쪽에도 같은 맹점이 있습니다. DoD 에 "그림 5장 삽입"이 명시되어 있었는데도 PASS 가 나왔습니다. 리뷰 잡 프롬프트에 해당 작업에 딸린 하위 잡의 목록과 상태를 근거로 함께 전달하여, 열린 하위 잡이 있으면 리뷰어가 그것을 판정에 반영(미완료로 간주)하도록 합니다.

비고

  • 두 수정은 같은 근본 원인(하위 잡이 루프·리뷰어 모두에게 보이지 않음)을 공유하므로 한 이슈로 묶었습니다.
  • 위 재현 사례에서 하위 잡 8c2ac62b 은 권한 확인 창에서 멈춰 heartbeat 가 끊겼고 deadline_timeout 으로 닫힌 뒤에도 에이전트가 작업을 계속해 나중에 completed 를 발행했습니다. 멈춘 에이전트 감지는 #30 에서 다루고 있습니다.
## 증상 `run_loop.sh` 로 돌린 작업에서 creator 가 작업의 일부를 다른 에이전트에게 `delegate-job` 으로 위임한 경우, 그 하위 잡이 아직 running 인데도 루프가 Phase 3(리뷰)로 넘어가 PASS 로 종료됩니다. 결과적으로 **작업의 절반만 끝난 산출물이 승인**됩니다. ## 재현 교재 저장소에서 아래 형태로 실행: - task: 문서 교정 + 챕터별 그림 삽입, 단 **그림 제작은 `creator-agy-image` 에게 위임**하도록 브리프에 명시 - `--plan --planner <p> --reviewer <p> --creator creator-claude-01 --max-loop 3` 실제 진행: | 시각 | 사건 | | :--- | :--- | | Phase 2 | creator 가 `delegate-job` 으로 이미지 잡 `8c2ac62b` 생성 (`creator-agy-image`) | | Phase 2 종료 | creator 자신의 잡 `8e0fb22a` 만 completed → 루프가 즉시 다음 단계로 | | Phase 3 | 리뷰어가 그림 없는 문서를 보고 `[VERDICT: PASS]` | | 루프 종료 | 이미지 잡 `8c2ac62b` 은 여전히 running | 문서에는 이미지 참조가 0건인 채로 루프가 100% PASS 로 끝났습니다. ## 원인 - `lib_py/loop/runner.py:467` `wait_for_job(job_id)` 는 `self.created_jobs`(= 루프가 직접 만든 잡)만 감시합니다. - 잡 레코드에 부모-자식 관계가 없습니다. `lib_py/` 와 `multi-agent-mux-*/scripts/` 전체에 `parent_job` / `child_job` / `children` 이 존재하지 않습니다. - 따라서 creator 가 만든 하위 잡은 루프에게 보이지 않습니다. ## 수정 방향 ### 1. 잡 트리 대기 (본 이슈의 주된 수정 방향) 레지스트리에 부모 잡 ID 를 기록하고(`delegate-job` 호출 시 환경/컨텍스트에서 상속), `wait_for_job` 이 자식 잡까지 함께 기다리도록 합니다. 검토 사항: - 부모 ID 상속 경로 — 에이전트가 `delegate-job` 을 호출할 때 자신이 수행 중인 잡 ID 를 어떻게 전달받을지 (환경변수 주입 등) - 대기 종료 조건 — 자식 잡이 계속 손자 잡을 만드는 경우의 깊이·타임아웃 처리 - 자식 잡 실패 시 부모 잡의 판정 (실패 전파 여부) 참고로 `lib_py/worktree.py:107` 의 `open_jobs(rows, dirs, exclude_ids)` 가 "세션들의 열린 잡" 을 조회하며, `multi-agent-mux-stop/scripts/worktree_remove.sh:75` 에서 이미 같은 목적("열린 잡이 있으면 거부")으로 쓰이고 있습니다. 부모-자식 관계가 도입되기 전의 임시 방어선으로, 또는 잡 트리 대기의 보조 검사로 활용할 수 있습니다. ### 2. 리뷰어가 하위 잡 상태를 검토 근거에 포함 리뷰어 쪽에도 같은 맹점이 있습니다. DoD 에 "그림 5장 삽입"이 명시되어 있었는데도 PASS 가 나왔습니다. 리뷰 잡 프롬프트에 **해당 작업에 딸린 하위 잡의 목록과 상태**를 근거로 함께 전달하여, 열린 하위 잡이 있으면 리뷰어가 그것을 판정에 반영(미완료로 간주)하도록 합니다. ## 비고 - 두 수정은 같은 근본 원인(하위 잡이 루프·리뷰어 모두에게 보이지 않음)을 공유하므로 한 이슈로 묶었습니다. - 위 재현 사례에서 하위 잡 `8c2ac62b` 은 권한 확인 창에서 멈춰 heartbeat 가 끊겼고 `deadline_timeout` 으로 닫힌 뒤에도 에이전트가 작업을 계속해 나중에 `completed` 를 발행했습니다. 멈춘 에이전트 감지는 #30 에서 다루고 있습니다.
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: tmpl/multi-agent-mux#34