Files
multi-agent-mux/.agents/reports/reviewer-agy-01/report-cae1ea73.md
T

7.8 KiB

PR #69 (Issue #63) Round 3 Code Review Report — agy (reviewer-agy-01)

  • Job ID: cae1ea73
  • Branch / Range: fix/issue-63 (dc886ecd6b38c01032a55a2d1c230c73362ae630..1614af5b673d7519d3a38f63e3636055592b4f14, 13 commits)
  • Tree: f1af6fdd548ee5d6f6b81e2202833edfaca98188
  • Verification Worktree: /var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261023T035928Z-2ccc02/1
  • Environment: macOS (Darwin arm64), /bin/bash 3.2.57(1)-release, /usr/bin/python3 3.9.6, .venv/bin/python 3.9.6
  • Summary: PASS (P0: 0, P1: 0, P2: 0)

1. 2·3차 리뷰 후속 커밋 (ede9c62, 8f64174, 7cac6f6, 1614af5) 집중 검증 결과

1.1 권위 있는 "세션 없음" 응답에서만 고아 마커 삭제 (8f64174, id_order.py:58-90,225-227)

  • herdr_session_state(server, session, timeout) (id_order.py:58-90)는 MAM_NO_AUTOSTART="1" 및 HERDR_SESSION_NAME=server or "default" 환경에서 source "$1" && _herdr agent list를 실행합니다.
  • res.returncode == 0이고 json.loads(res.stdout)["result"]["agents"]가 리스트이며, 그 안에 session 및 sanitize_herdr_agent_name(session)이 모두 없을 때에만 False를 반환합니다 (id_order.py:74-83).
  • _read_and_prune_markers (id_order.py:225-227)는 drop = live is False로 판정하여, 조회 실패·타임아웃·파싱 실패(live is None) 시에는 마커를 삭제하지 않고 _orphan = "unknown"으로 유지합니다.

1.2 server_not_running 불확실 처리 및 MAM_ID_ORDER_WAIT_S=0 무프로브 보장 (7cac6f6, id_order.py:58-90,280-291,330-346)

  • server_not_running을 포함한 모든 비정상 종료(res.returncode != 0)에서 herdr_session_state가 None을 반환하므로 서버 다운 상태에서도 고아 마커가 삭제되지 않고 fail-closed로 차단됩니다.
  • bounded_probe (id_order.py:285-290)가 deadline - time.monotonic()을 timeout으로 전달하고, herdr_session_state 첫 줄(if timeout <= 0: return None, id_order.py:64-65)에서 즉시 반환하므로:
    • 다수의 죽은 마커가 있더라도 전체 프로브 시간이 MAM_ID_ORDER_WAIT_S 상한 안에 엄격히 묶입니다 (test_id_order_herdr_probes_stay_within_the_wait_cap).
    • MAM_ID_ORDER_WAIT_S=0(cap == 0)일 때는 herdr 서브프로세스를 전혀 호출하지 않고 즉시 거부하며 (MAM_ID_ORDER_WAIT_S=0 leaves no time to ask herdr) 안내를 출력합니다 (id_order.py:336-338).
  • answers: Dict[str, bool] (id_order.py:283,287-289,333)가 이전 폴링에서 확인된 확정 응답을 보존하여 마지막 폴링 시점에 예산이 소진되더라도 "its herdr session is alive" 메시지를 정확히 유지합니다.

1.3 동일 세션 이름(sess == me)의 죽은 owner 마커에 동일한 고아 규칙 적용 (1614af5, id_order.py:180-235,305)

  • _read_and_prune_markers에서 sess == me일 때 무조건 삭제하던 분기를 제거하여(id_order.py:217-227), 이전 create/resume이 pane을 띄운 직후 죽어 고아 세션을 남긴 상태에서 같은 세션 이름으로 재시도하더라도:
    • 고아 herdr 세션이 살아 있거나 확인 불가(True/None)이면 마커를 유지하고 차단합니다 (blockers()는 m_sess == me를 건너뛰지 않음, id_order.py:130-145).
    • herdr가 해당 세션이 사라졌음을 확인(False)하면 죽은 마커를 삭제하고 새 시도의 마커로 교체(owner_pid == my_pid)하여 정상 진입합니다 (test_id_order_dead_owner_marker_blocks_while_its_unregistered_herdr_session_is_alive, test_id_order_real_probe_against_mock_herdr_fails_closed).

1.4 세 수정 간 정합성 및 일반 사용(정상 create/resume, 재시도) 600초 대기 미발생 검증

  • 정상 create 후 진행 중: 첫 세션이 YAML 행을 status: "running" 및 herdr_session_epoch > prev_epoch로 등록하면 _registered_for_attempt (id_order.py:174-177)가 True를 반환해 herdr 프로브 없이 마커가 즉시 삭제되고, 이후에는 YAML 행의 own_id 기록 여부에 따라 대기가 결정됩니다.
  • 정상 stop 후 후속 create/resume: 세션이 정상 중지되면 own_id가 기록되거나(pinned_for_attempt == True) stopped_at_epoch > max(m_at, prev_end_epoch)(ended_after_attempt == True)가 성립하므로 blockers() (id_order.py:150-163)가 이를 차단 목록에서 즉시 제외하여 600초 대기가 발생하지 않습니다.
  • create 실패·롤백(exit 42) 후 재시도: create_session.sh의 cleanup_herdr_on_error 트랩(create_session.sh:337-368)이 실행 중인 워크스페이스 herdr 서버에서 세션을 즉시 종료하므로, 재시도 시 첫 폴링의 _herdr agent list가 빈 에이전트 목록(False)을 반환해 죽은 마커를 즉시 정리하고 대기 없이 통과합니다.

2. 전체 체크리스트 (1~8) 점검 요약

# 점검 항목 결과 근거 파일 및 라인
1 완료 조건 1~8 및 테스트 커버리지 PASS session_ids.py:116-297, id_order.py:1-382, tests/test_issue63_same_cwd_ids.py (총 27개 테스트)
2 #40 autopin.capture 재사용 (판정 단일화) PASS session_ids.py:19,176,272 (from lib_py.agents.autopin import OWN_KEYS, capture, claimed_elsewhere), lib.sh 구 capture_conversation_id 제거
3 id_order.py 잠금·만료·비차단 조건·MAM_ID_ORDER_WAIT_S PASS fcntl.flock (id_order.py:293), wait_s (id_order.py:36-41), herdr_session_state (id_order.py:58-83), _read_and_prune_markers (id_order.py:180-235)
4 resume: --drop-stale-id, 사전 거부(exit 1), 이미 실행 중 분기, SKILL.md PASS resume_session.sh:132-170,243,270-276, update_yaml_resumed.sh:21,66-197, multi-agent-mux-resume/SKILL.md:59-83,165-171
5 stop: kill 전 ID 판정, 죽은 herdr 미기록+이유 기록, purge 재검증 PASS stop_session.sh:104-179,233-286,308-358, multi-agent-mux-stop/SKILL.md:38-55,98-115
6 삭제된 심볼 잔존 참조 없음 (capture_conversation_id, CAPTURE_ID) PASS git grep 결과 코드·문서·테스트 내 잔존 참조 0건
7 macOS 호환성 (/bin/bash 3.2.57, /usr/bin/python3 3.9.6) PASS 수정된 셸 6개 /bin/bash -n 통과, Python 3.9 AST 파싱 및 모듈 import(PY39_IMPORT_OK) 통과
8 test_issue34_job_tree.py::test_t5b_a_*[False] 관련성 여부 PASS 본 브랜치는 루프·잡 트리(lib_py/loop, delegate-job)를 전혀 수정하지 않으며, 해당 테스트는 본 변경과 무관함

3. 실행한 검증 명령 및 결과

  1. 정적 검사 (git diff --check, /bin/bash -n, /usr/bin/python3 3.9.6 import):
    • Exit 0 (PY39_IMPORT_OK).
  2. Issue #63 id_order 및 이식성 테스트 + 실제 herdr 호출 감시(Spy) 검증:
    • pytest tests/test_issue63_same_cwd_ids.py -k "test_id_order or test_c6_id_order_markers or test_portability" -v
    • 결과: 8 passed, SPY_LOG 비어 있음 (0 calls).
  3. Herdr 격리 및 Skill 블록 인벤토리 정합성 테스트:
    • pytest tests/test_herdr_real_server_leak.py tests/test_issue42_skill_blocks.py -v
    • 결과: 40 passed, 1 skipped in 1.52s.
  4. Negative Regression 검증:
    • Base(dc886ec): test_issue63_same_cwd_ids.py 12개 실패 확인.
    • ede9c62 대비: test_id_order_real_probe_against_mock_herdr_fails_closed가 protocol_mismatch에서 assert 0 == 1로 실패하고 HEAD에서 통과함을 확인.
    • 7cac6f6(HEAD~1) 대비: 1614af5의 동일 세션 이름 고아 마커 검증(assert wait_same() == 1)이 HEAD~1에서 assert 0 == 1로 실패하고 1614af5(HEAD)에서 통과함을 확인.

4. 발견 사항

  • 차단 결함(P0/P1) 및 비차단 결함(P2) 없음.

[VERDICT: PASS]