Files
multi-agent-mux/.agents/reports/planner-reviewer-claude-01/report-834fa032.md
T
GodopuandClaude Opus 5.5 50c8da8269 release(v4.9.1): tests no longer reach a real herdr server - archive the review reports and bump the lockstep version
Review loop (--review-only, --all-reviewer): round 1 (@325b056) 4/4 PASS,
round 2 (@db7f4ca, HERDR_SESSION) 4/4 PASS. Full suite at 325b056 on
macOS / Python 3.9 / bash 3.2 / herdr 0.9.3 from an agent pane:
1845 passed / 0 failed / 56 skipped (18 test_deploy_freshness skips: no
nats-docker submodule in the fresh worktree); the panes of the real
servers (default, multi-agent-mux) and ~/.claude/projects were unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
2026-10-13 10:33:04 +09:00

4.6 KiB

테스트 실제 herdr 서버 누수 수정 2차 리뷰 — 커밋 db7f4ca (job 834fa032)

  • 리뷰어: planner-reviewer-claude-01 (Reviewer)
  • 리뷰 identity: loop-20261013T010208Z-f90dd4 / base 325b0560 .. head db7f4cab (커밋 1개, 2 파일) / tree f32cabd3
  • 검증 경로: /var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261013T010208Z-f90dd4/1 — HEAD·tree 일치, git status --porcelain 0 줄(시작·종료), .mam 생성 없음. 본 체크아웃 HEAD 8b0b4a0(main) 변동 없음.
  • 실행 안전: 1차와 같이 모든 테스트·탐침은 env -i(PATH/HOME/LANG/TMPDIR 만, 필요한 변수는 명시 추가)로 돌려 브리프의 -u 목록 전부가 비워진다. basetemp 는 scratchpad 아래(이름에 "shim" 없음). 실제 바이너리는 일회용 HOME 에서 status server 읽기만(서버 미기동). Python 은 본 체크아웃 .venv(3.9.6). 전체 스위트는 돌리지 않았다. 범위는 이 커밋만.

1. 변경

  • tests/conftest.py:299: mam_sandbox 가 HERDR_SESSION 도 지운다(주석 :296-297). 현재 제거 목록: HERDR_CONFIG_PATH, HERDR_PANE_ID, HERDR_SERVER_NAME, HERDR_SESSION_NAME, HERDR_SESSION, HERDR_SOCKET_PATH, HERDR_TAB_ID, HERDR_WORKSPACE_ID, XDG_CONFIG_HOME.
  • tests/test_herdr_real_server_leak.py:76: L2 의 PANE_VARS 에 HERDR_SESSION 추가. 수정 전 conftest(325b056)에 새 테스트를 얹은 scratch 복사본에서 L2 는 AssertionError: ['HERDR_SESSION'] 로 실패 → 테스트가 이 변경을 정확히 겨눈다.
  • Python 3.9 컴파일 통과. 제품 코드 변경 없음.

2. HERDR_SESSION 을 지워서 깨지는 테스트가 있는가 (검토 관점 1)

  • 소비자: lib.sh:1425 _herdr_caller_server, lib_py/pane_lock.py:49 caller_server, lib_py/loop/watcher.py:64 — 셋 다 "있으면 호출자 서버, 없으면 HERDR_SOCKET_PATH 모양" 이고 HERDR_SOCKET_PATH 는 이미 지워지므로 샌드박스에서는 일관되게 "pane 밖" 으로 판정된다.
  • 테스트 쪽 bare HERDR_SESSION 참조는 전부 테스트가 스스로 넣는 값이다(픽스처 뒤라 영향 없음): test_issue23_24_startup_path.py:264,369,395(S1g·watcher 케이스는 env={...} 로 명시), test_issue34_job_tree.py:580, test_issue30_stall_watch.py:486, test_issue45_restore.py:42(SCOPE_ENV 로 이미 HERDR_SESSION·HERDR_ENV 까지 자체 제거). 반대로 "HERDR_SESSION 이 없어야" 하는 테스트(test_s2b…:188, S2 계열 "pane 밖 호출자") 는 이제 pane 안에서 돌려도 전제가 보장된다 — 이것이 이 변경의 목적이다.
  • 실측: 같은 6 파일(test_herdr_real_server_leak, test_issue50_pane_lock, test_issue23_24_startup_path, test_herdr_shim_contract, test_issue45_herdr_config, test_issue9_server_env)을 (a) 깨끗한 환경, (b) 바깥 환경에 HERDR_SESSION=pane-real-srv 를 넣은 환경에서 각각 돌렸다: 둘 다 139 passed, 34 skipped (skip 은 모두 Python 3.9 의 tomllib skip). pane 안/밖 결과가 같다.

3. 다른 라우팅 변수가 남았는가 (검토 관점 2)

  • 내 pane 이 내보내는 HERDR_* 는 HERDR_BIN_PATH, HERDR_CONFIG_PATH, HERDR_ENV, HERDR_PANE_ID, HERDR_SESSION, HERDR_SESSION_NAME, HERDR_SOCKET_PATH, HERDR_TAB_ID, HERDR_WORKSPACE_ID 아홉 개. 샌드박스가 지우지 않는 것은 HERDR_BIN_PATH·HERDR_ENV 둘뿐이다.
  • 실제 바이너리(0.9.3) 에 각각을 단독으로 주고 status server 를 읽었다: HERDR_ENV, HERDR_BIN_PATH, HERDR_CONFIG_PATH, HERDR_WORKSPACE_ID, HERDR_PANE_ID 모두 소켓은 $HOME/.config/herdr/herdr.sock(가짜 HOME) — 서버 선택에 영향 없음. 1차에서 확인한 대로 소켓을 바꾸는 것은 HERDR_SOCKET_PATH(최우선)와 HERDR_SESSION(HOME 상대) 둘뿐이며 이제 둘 다 제거된다.
  • .agents·tests 에서 HERDR_BIN_PATH·HERDR_ENV 를 읽는 코드는 없다(test_issue45_restore.py:42 가 자체 정리 목록에 넣어 둔 것뿐). 남은 라우팅 변수 없음.

4. 잔류물

  • scratch 복사본·basetemp·로그는 scratchpad 아래. 일회용 HOME /tmp/j834-h 제거(서버 미기동). 실제 .mam·.mam.env·모니터·실제 서버·~/.config/herdr·에이전트 홈은 건드리지 않았다.

결론

HERDR_SESSION 제거는 호출자 서버 판정을 pane 안/밖에서 동일하게 만들고, 그 값을 쓰는 테스트는 모두 자체 설정이라 깨지지 않는다(두 환경에서 동일하게 139 passed). 실제 바이너리의 서버 선택에 관여하는 변수는 이제 모두 샌드박스에서 제거된다.

[VERDICT: PASS]