Files
multi-agent-mux/.agents/reports/planner-reviewer-claude-01/report-f0f131cd.md
T
GodopuandClaude Opus 5.5 cd82ab6e72 release(v4.8.7): Issue #17 follow-ups - archive the review reports and bump the lockstep version
Merge-workspace review loop (--all-reviewer): round 1 (@8241bd5) claude
grok PASS, agy NOT PASS (two static wrapper-literal tests did not follow
_decided/_exit_for), codex NOT PASS (R1: a yes/no decision that could not
run read as "no"); fixed in 541c3fe and 65b78b6. Round 2 (@65b78b6) 4/4
PASS. Full suite at 65b78b6 on macOS / Python 3.9 / herdr 0.9.3: 1730
passed / 0 failed / 56 skipped; 18 of the skips were the uninitialized
nats-docker submodule in the fresh worktree, and with it
tests/test_deploy_freshness.py is 31 passed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
2026-10-08 11:32:39 +09:00

4.9 KiB
Raw Blame History

리뷰 리포트 — Job f0f131cd (Issue #17 후속 2회차 델타, 8241bd5..65b78b6)

  • 리뷰어: planner-reviewer-claude-01 (claude)
  • 리뷰 identity: loop-20261007T224638Z-cf1efb / base 56d0bfd / head 65b78b6 / tree b805d9f — 검증 경로(…/2)에서 git rev-parse HEAD 'HEAD^{tree}' 일치, 미커밋 변경 없음
  • 범위: 커밋 2개 — 541c3fe(agy 지적: 동결 리터럴을 _decided/_exit_for 로), 65b78b6(codex R1: 실패한 yes/no 판정은 "no" 가 아니다). wrapper.py +24/−4, 래퍼 +18/−4, 테스트 3개. 버전·VERSIONS·문서 변경 없음(브리프대로).

결론 요약

codex R1 이 닫혔고, 그 수정이 1회차에 내가 남긴 N1(stall-watch 판정 실패 시 조용히 감시 생략)도 함께 닫는다. 정상 경로(yes/no 두 분기 모두)의 동작은 불변. 새 테스트 15건이 1회차 head 코드에서 실제로 실패하며, 8건은 codex 가 지적한 바로 그 증상(rc 0)으로 실패한다. 차단 결함 없음.

1. 지적 종결

지적 수정 확인
codex R1: _decide subscriber-up/stall-watch 를 rc 로 읽어, 판정 실패(rc 1·127, 빈 답)가 "no" 와 구분되지 않음. subscriber-up 에서는 rc 0 으로 끝난 구독자가 "not up" → "died early" 경로 → sub-status 0 = completed → submit 이 0 으로 종료 wrapper.py:8-17, :335-340, :344-353 — 두 yes/no 서브커맨드에 --print(yes/no 출력 + rc 0). 래퍼 :121-131 _decided_yes 가 _decided 로 답을 받아 yes/no 외에는 _decision_failed → exit 1. 호출 3곳(:396, :568, :730) 교체 1회차 head(8241bd5) 래퍼+wrapper.py 를 넣은 사본에서 test_f_a_failed_yes_no_decision_ends_the_submit_with_1 9건 모두 실패 — subscriber-up 6건은 assert 0 == 1(codex 의 증상 그대로), stall-watch 3건은 오류 문구 없이 정상 종료. 현재 코드에서는 9건 모두 rc 1 + "could not decide"
claude N1(1회차): stall-watch 판정 실패가 || return 0 으로 조용히 감시만 끔 위와 같음 — "no" 는 여전히 return 0(감시 안 함), 실패는 exit 1 stall-watch-direct-{error,gone,empty} 통과
agy: test_issue5_phase1_delegation·test_tier1_unit 의 동결 리터럴이 옛 _decide sub-status/exit "$(_decide exit-code 문자열을 가리킴 _decided job_status sub-status "$sub_rc", _exit_for "$job_status" 로 갱신 두 파일 통과(아래)

2. 정상 경로 불변

  • rc 형식은 그대로 남아 있다(--print 없이 subscriber-up 1 → rc 1 확인; test_u_yes_no_print 가 두 형식을 함께 고정).
  • test_f_yes_and_no_keep_their_branches(direct·loop × up/not-up): "yes" 는 진행, "no" 는 "subscriber died early" 경로로 가고 direct 의 종료 코드는 0/1 — 옛 코드에서도 통과(4 passed)하고 새 코드에서도 통과한다 = 분기 결과 불변. 옛·새 비교 테스트(test_c_*) 전부 통과.
  • _decided_yes 는 if …; then(:396, :568)과 … || return 0(:730) 안에서 직접 호출되며 서브셸이 아니므로 exit 1 이 래퍼를 끝낸다. --print 를 위치 인자 뒤에 붙여도 argparse 가 받는다(3.9 에서 직접 확인: stall-watch remote:r claude --print → stderr 진단 + stdout no, rc 0).
  • stall_watch 의 진단 메시지는 전과 같이 stderr 로만 나가 stdout 의 한 줄 답을 더럽히지 않는다.

3. 정적 가드

test_s_no_printed_decision_is_read_raw 가 _decide (subscriber-up|stall-watch) 의 rc 읽기 재유입을 막고 _decided_yes 호출 수(2+1)를 고정한다. 옛 코드에서 실패, 새 코드에서 통과.

4. 이식성

/bin/bash -n(3.2.57) 통과. 추가된 bash 는 case·local·함수 호출뿐. wrapper.py 변경은 argparse store_true 와 print.

5. 테스트 실행 (검증 경로 …/2, 워크트리 .venv Python 3.9.6, env -i 로 HERDR_·MAM_·MQTT_*·WORKSPACE_ROOT 제거)

실행 결과
test_issue45_restore, test_issue45_restore_unit, test_issue17_item4_decisions, test_issue33_budget, test_issue5_phase1_delegation, test_tier1_unit 461 passed / 0 failed / 0 skipped (537 s; 실서버 restore 5건 포함, herdr 0.9.3)
새 테스트 19건, 1회차 head 코드 사본 15 failed / 4 passed (실패 = yes/no 실패 9 + --print 단위 5 + 정적 가드; 통과 4 = 분기 불변 테스트, 의도대로)
격리: 실행 전후 herdr 프로세스 차이는 오케스트레이터의 agent wait pid 교체뿐, /private/tmp/m45* 없음, ~/.config/herdr sessions·config.toml 불변, 실제 .mam/jobs 항목 수 불변.

6. 비차단

  • 1회차 N2(_env 가 상속 WORKSPACE_ROOT 를 비우지 않아 _run_both 4곳이 에이전트 pane 의 워크스페이스로 lib.sh 를 초기화할 수 있음)와 N3(herdr_restore.py docstring 줄바꿈)는 이 델타에서 다루지 않았다. 둘 다 이 PR 이 만든 문제가 아니며 그대로 비차단.
  • 새 관찰 없음.

[VERDICT: PASS]