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

41 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 리뷰 리포트 — 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]