Final-round reports of the fix/issue-9-14 review loop: planner-reviewer-claude-01
(2d3f24e4), reviewer-agy-01 (47a845e0), reviewer-grok-01 (d7e66053) and
planner-reviewer-codex-01 (0ad7cb06), all [VERDICT: PASS] on ebe58f6.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
7.9 KiB
7.9 KiB
🔍 Review Report — Job 2d3f24e4 (branch fix/issue-9-14, HEAD ebe58f6)
- Reviewer:
planner-reviewer-claude-01(role: planner,reviewer) · 2026-09-13 - 대상:
git log 4d444ce..HEAD9커밋 —497633f,16376c5,4b31345,eaa49aa,0918917(release v4.4.2),7c40bf4,d5a191c,952657e,ebe58f6(이번 라운드 신규). 이전 라운드에서 본 커밋은 변경분만 재확인하고,ebe58f6는 전체를 검토했다. - 방법: 코드 정독,
events.log소비자 전수 확인, 선택 테스트(부하 없는 단독 실행) + publish 계약 스위트. 리뷰 중 45초 간격progressheartbeat 발행. 코드 수정 없음.
0. 직전 라운드(HEAD 952657e) 결과와 처리
| 리뷰어 | 판정 | 요지 |
|---|---|---|
planner-reviewer-claude-01(9323564c) |
PASS | 벽시계 경계 확인, t1_20 부하 민감성 권고 |
reviewer-agy-01(f191b557) |
PASS | — |
reviewer-grok-01(b0591d20) |
NOT PASS | publish_event.py 가 heartbeat 를 와이어 발행(브로커 ACK·재시도) 뒤에 events.log 에 기록 → R1 의 디스크 근거가 늦게 도착해 살아 있는 잡이 deadline_timeout 으로 닫힘. 실제 publish_event 경로 테스트가 2/2 실패 |
planner-reviewer-codex-01(e657c660) |
리뷰 없음 | 구독자가 120 s 동안 이벤트 0건(idle timeout … still pending) 후 deadline_timeout. codex 가 started 조차 발행하지 않았으므로 heartbeat 순서 문제와는 무관 |
creator 는 grok 지적을 반론 없이 수용해 ebe58f6 로 고쳤다. 952657e 에서 새 순서 테스트 2건과 grok 의 테스트가 실패함을 역검증했고, 수정 후 grok 의 테스트는 무변경으로 3/3 통과했다.
1. ebe58f6 검토 — ✅
1-1. 순서와 중복 방지
- CLI
publish_event.main:- token·attempt 검증 — 불일치는 rc 4 로 거부되며 기록되지 않는다(
publish_event.py:290-341) prepare_event(seq 소비)(:343-356)record_local_event(:360) →registry.append_event(:165-175)with_retry(_publish_once)(:364-376)record_outcome(..., local_event_recorded=True)(:385-388) — 감사 로그published항목과 상태 동기화만 발행 뒤에 수행하고,events.logappend 는 건너뛴다(:204-205)
- token·attempt 검증 — 불일치는 rc 4 로 거부되며 기록되지 않는다(
DelegationService.publish_event: 같은 순서다(service.py:82-100).- 다른 호출자:
record_outcome의 기본값은local_event_recorded=False라서 직접 호출하는 테스트(G-1/G-2/G-4)는 동작이 그대로다.prepare_event의 유일한 다른 호출자bench.py:149는 원래events.log를 쓰지 않았으므로 영향이 없다.
- 새 테스트가 "발행 시작 순간 이미 1줄", "재시도 2회에도 1줄 + 감사
published=False"를 단정한다.
1-2. events.log 소비자 영향
_recent_disk_heartbeat(래퍼): 의도한 수혜자다. 브로커 지연(실측 약 5 s/발행)과 무관하게 heartbeat 가 즉시 디스크에 보인다.registry.get_feedback폴백(registry.py:241-260): 감사 ndjson 에 terminal 이벤트가 없을 때만events.log에서 detail 을 읽는다. 호출 시점이 잡 종료 이후이고, 기록 내용은 이전과 같다(CAS 로 거부된 terminal 이벤트도 원래 기록되었다). 달라진 것은 시점뿐이다.- 그 밖의 소비자: 셸·파이썬 전수 grep 결과 없다. 상태의 권위는 계속 레지스트리 레코드(
_disk_status)다.
1-3. 의도된 의미 변화 (creator 문서화)
- 발행 도중 프로세스가 죽으면
events.log에는 줄이 남지만 감사published항목과 상태 동기화는 없다. - terminal 이벤트라면
events.log에completed가 있어도 레코드는 아직 비종료일 수 있다. R1 은 이를 liveness 근거로만 쓰고 결과는 레코드에서 읽으므로 잘못된 완료 판정으로 이어지지 않는다.
2. 검증 항목별 결과
| # | 항목 | 결과 |
|---|---|---|
| (1) | 서버 env denylist | ✅ 무변경(1회차 판단 유지, 호스트 마커 권고는 비차단) |
| (2) | MAM_NO_AUTOSTART · ls 번역 |
✅ 무변경(952657e 에서 확인한 구조화 판정·unknown 종료 유지) |
| (3) | send_keys_safe |
✅ 무변경 |
| (4) | _inject_acknowledged · _agent_still_working · _recent_disk_heartbeat · R1 창 |
✅ 벽시계 경계(952657e)는 그대로다. 이번 커밋으로 heartbeat 가 발행 전에 디스크에 기록되어 grok 이 재현한 미탐이 사라졌다(해당 테스트가 이번 실행에서 통과) |
| (5) | T1-7 트리거 | ✅ 무변경 |
| (6) | 버전 락스텝 · 릴리스 커밋 | ✅ lib.sh:32·eager.py:16 = 4.4.2. VERSIONS.md 항목 6 이 "와이어 발행 전 로컬 기록(CLI·service 두 경로)"으로 코드와 일치. "신규 테스트 21개" = test_issue9_server_env.py 9 + test_issue14_delivery_ack.py 12 함수(직접 셈) |
| (7) | 테스트 · 정적 검사 | ✅ 아래 |
- 선택 실행 11파일(부하 없이 단독): 163 passed in 431 s
- 대상:
test_issue9_server_env,test_issue14_delivery_ack,test_issue6_fail_closed,test_issue6_turn_handshake,test_a4_adapter_contract,test_loop_cli,test_issue5_phase4_runtime,test_version_consistency,test_herdr_shim_contract,test_b19_headless_reconcile_fixes,test_deploy_registry_merge - grok 의
test_wrapper_idle_timeout_grace_accepts_disk_heartbeat, 새 순서 테스트 2건, 직전 라운드에 부하 속에서 한 번 실패했던test_t1_20모두 통과
- 대상:
- publish 계약 스위트
tests/test_issue5_phase1_delegation.py(G-1/G-2/G-4, transport parity,record_outcome직접 호출): 66 passed(주 실행이 끝난 뒤 따로 실행) - 정적 검사:
py_compile(publish_event·service),bash -n(lib.sh·래퍼·status.sh·reconcile.sh),git diff --check 4d444ce...HEAD모두 클린. 작업 트리 깨끗, HEADebe58f6.
3. 비차단 권고
events.log의미 명시: 이제 이 파일은 "수락된 상태"가 아니라 "시도된 이벤트"의 기록이다(발행 전 기록, CAS 거부분 포함).MESSAGING.md나registry.append_eventdocstring 에 한 줄 적어 두면, 이후 이 파일을 상태 판단에 쓰는 코드가 생기는 것을 막을 수 있다.- t1_20 예산(직전 라운드 권고, 미반영): 이번 부하 없는 실행에서는 통과했지만
--timeout 12는 부하가 걸린 CI 에서 여전히 간헐 실패할 수 있다. 20–25 s 로 늘리기를 권한다. - loop 모드 마감 서술(직전 라운드 권고, 미반영):
START_TIME은cmd_submit에서 한 번만 정해진다(:166-167). 주석의 "this dispatch's deadline" 은 loop 모드에서 "이 래퍼 실행의 마감"이 정확하다. - 보류된 후속 항목 묶음(호스트 마커,
$WRAPPER경로, pane 변화 신호, ack dispatch 고정, heartbeat token 필터,_within_deadline의Terminated표시 잡음)은 변동이 없다. 하나의 후속 이슈로 모으기를 권한다.
4. GM 참고
- codex 는
952657e·ebe58f6를 리뷰하지 않았다. 마지막 codex 판정은d5a191c에 대한 NOT PASS(75c1d06c)였고, 그 두 지적은952657e에서 해소되었다(본 세션 확인).e657c660은 codex 가 이벤트를 하나도 발행하지 않은 채 닫혔다. 병합 전에 codex 세션 상태를 확인하고 재리뷰할지 결정할 것을 권한다.
5. 종합
ebe58f6는 grok 의 차단 지적(디스크 heartbeat 가 브로커 지연 뒤에 기록됨)을 정확한 위치에서 최소 변경으로 고쳤다. 검증 우선·seq·G-1/G-2/G-4 계약을 유지하고, 중복 기록이 없으며,events.log소비자에도 부작용이 없다.- 브랜치 전체가 브리프의 7개 검증 항목을 충족하고, 부하 없는 선택 실행 163건과 계약 스위트 66건이 모두 통과했다. 설계 재검토는 필요 없다.
[VERDICT: PASS]