Files
multi-agent-mux/.agents/reports/planner-reviewer-claude-01/report-2ab23f4e.md
T

11 KiB
Raw Blame History

PR #79 (Issue #68) 리뷰 — head 3b81f99

리뷰어: planner-reviewer-claude-01 (claude) · job 2ab23f4e

0. 리뷰 경로 확인

  • 검증 경로: /var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261029T045625Z-74296d/1
    • HEAD 는 3b81f9973223d2a910369711c08adc772003639d, tree 는 ff705b61bf25fe40d0ff054c372a399eacc79730 로 [리뷰 identity] 와 같다. 리뷰 전과 후 두 번 확인했다.
    • git status --porcelain --ignored 결과는 비어 있고, .mam 도 없다.
  • 리뷰 범위: base b9c828f 와 HEAD 사이의 커밋 5개, 9개 파일, +277/−22 줄.
  • 기준 문서(읽기만 했다): tea issues 68 --comments 의 결정 1–4 와 완료 조건, tea pulls 79 설명, INSTRUCTION.md.

1. 결정·완료 조건 대조표

조건 구현(파일:줄) 테스트 판정
결정 1: create 의 --no-onboard 유지, 기본은 온보딩 create_session.sh:67 ONBOARD=1, :87-88 그대로 기존 테스트 전체가 그대로 통과 ✅
결정 2: worktree_prepare 기본을 온보딩으로 worktree_prepare.sh:30 ONBOARD=1 test_prepare_onboards_by_default_end_to_end(온보딩 잡 completed, "onboarding completed" 출력) ✅
결정 2: --no-onboard 는 건너뛰고 create 에 그대로 넘김 :43, :232 args+=(--no-onboard) test_prepare_no_onboard_sends_none, test_prepare_forwards_onboarding_choice[opts2] ✅
결정 2: 기존 --onboard 도 같은 동작 :42 forwards[opts1], [opts3](둘 다 주면 마지막 것이 이김) ✅
결정 3: agy·codex·hermes·opencode 에만 경고, claude·grok 에는 없음 create_session.sh:208-211, facts lib_py/agents/__main__.py:75 test_facts_expose_post_discovered[6], test_no_onboard_warning_dry_run[6], ..._keeps_exit_and_row[6] ✅
결정 3: 경고 내용 "첫 대화 전까지 ID 미기록, 같은 폴더 같은 종류는 기다림(#63)" :210 의 문구가 이 두 가지와 MAM_ID_ORDER_WAIT_S 를 말한다 경고에 Issue #63 과 에이전트 이름이 들어 있는지 확인 ✅
결정 3: 종료 코드·행이 바뀌지 않음 경고 출력만 하고 분기는 없다 keeps_exit_and_row: rc 0, 행 필드(이름, status, role, server, workspace, cmd, cmd_full, cwd, id source·verified, 상태, control_plane)를 기대값과 비교 ✅
결정 3: 뒤에서 거부돼도 경고가 먼저 보임 spawn·#63 검사(:287 부근)보다 앞에서 출력 test_no_onboard_warning_precedes_a_later_refusal ✅
결정 4: 문서는 create SKILL.md 옵션 표와 worktree 절만 고침 SKILL.md:173, :205, :210, :213 네 줄 test_issue42_skill_blocks(블록 sha 와 근거 핀) ✅
완료: "기본은 온보딩 안 함" 을 전제로 한 worktree 테스트를 고침 test_issue21_acceptance.py:47, :207, test_issue21_phase2_loop_a.py:422 모두 통과 ✅
완료: macOS(bash 3.2, Python 3.9)에서 통과 — §3 ✅

빠진 조건은 없다.

2. 꼼꼼히 본 것

2.1 경고 판정과 facts

  • 이 Mac 에서 lib_py.agents facts <agent> 를 직접 실행했다.
    • agy, codex, hermes, opencode 는 MAM_ID_POST_DISCOVERED=1 이다.
    • claude, grok 은 0 이다.
    • 값은 어댑터의 id_lifecycle(base.py:174-175 의 PRE_ASSIGNED/POST_DISCOVERED)에서 나온다. 셸 쪽에는 에이전트 목록을 두지 않았다.
  • facts 를 쓰는 다른 곳에는 영향이 없다.
    • lib.sh:2596(eval 뒤 필요한 키만 읽음), :2957(eval), :3156(sed -n 's/^KEY=//p' 로 키별 추출)은 모두 키 단위로 읽는다. 그래서 줄이 하나 늘어도 문제가 없다.
    • facts 출력을 다루는 테스트(test_a4_adapter_contract.py, test_issue23_24_startup_path.py)도 이 Mac 에서 103 passed 였다.
  • facts 를 얻지 못하는 경우(파이썬 실패 등) eval "$(… || true)" 는 아무 값도 정하지 않는다. 그러면 ${MAM_ID_POST_DISCOVERED:-0} 가 0 이 되어 경고 없이 지나간다. 동작이 바뀌지 않는 쪽으로 실패하므로 안전하다.
  • MAM_DELEGATION_PY=0 는 위임(delegation) 경로에만 쓰이는 스위치다. lib_py.agents facts 와는 관계가 없어 경고 판정에 영향이 없다.
  • test_issue26_ints.py:111 은 이 값을 "문자열 비교" 로 분류해 정수 기본값 검사 대상에서 뺐다. 코드도 실제로 문자열로 비교하므로(= 1) 맞는 분류다.

2.2 --creator-agent 를 부르는 모든 곳 (git grep -n creator-agent)

  • 테스트
    • test_issue21_acceptance.py:47, :207 와 test_issue21_phase2_loop_a.py:422 에는 이제 --no-onboard 가 붙어 있다.
    • test_issue21_phase2_loop_a.py:339, test_issue50_onboard.py:192, test_issue57_logs_follow_registry.py:276, test_issue50_dispatch_herdr.py:868 는 원래 --onboard 를 명시하므로 동작이 같다.
    • test_issue21_phase2_loop_a.py:355(w6c)는 옵션이 없다. 하지만 서브모듈 초기화가 실패해 create 이전에 exit 1 로 끝나고, 행이 없음을 확인하는 테스트다. 그래서 온보딩까지 가지 않는다. 뒤에 다시 부르는 _prepare(main, wt) 에는 --creator-agent 가 없다.
    • 새 테스트 파일의 세 호출은 의도한 대로다.
  • 문서와 기록
    • docs/design/worktree-creator-model.md:48-51 의 예시에는 옵션이 없다. 그래서 이제 온보딩하는데, 예시가 보여 주려는 creator 흐름에도 그게 맞다. 이 문서에는 "기본은 온보딩 안 함" 이라는 문장이 없어 고칠 내용도 없다. 결정 4 의 "최소 변경" 과도 맞는다.
    • VERSIONS.md:632 는 과거 기록이고, README*.md:51 은 create 에 대한 설명이라 맞다.
    • 그 밖의 스크립트에서는 worktree_prepare.sh 를 부르는 곳이 없다.
  • 결론적으로 온보딩 대기(최대 MAM_ONBOARD_WAIT_S) 때문에 의도치 않게 느려지거나 44/45 로 끝날 호출은 남아 있지 않다.

2.3 SKILL.md 와 코드의 줄 단위 대조 (INSTRUCTION.md)

  • SKILL.md:173 은 "--no-onboard 로 만든, ID 가 첫 턴 뒤에 생기는 에이전트(id_lifecycle)는 그때까지 ID 를 기록하지 않고, 같은 폴더의 같은 종류 create 를 막는다(#63). create 가 경고한다" 고 설명한다.
    • 코드(create_session.sh:209-210)의 조건과 문구가 이와 같다.
    • #63 쪽은 정확히는 "막는다" 가 아니라 "기다린 뒤 거부" 다. 하지만 표 한 줄 요약으로는 맞다.
  • SKILL.md:205 의 시놉시스 [--no-onboard] 는 worktree_prepare.sh:9, :43 과 같다.
  • SKILL.md:210 의 "onboards it … --no-onboard skips it, --onboard is the default and still accepted" 는 :30, :42-43, :232 와 같다.
  • SKILL.md:213 의 종료 코드 "44/45 are create's (…onboarding is the default…)" 는 스크립트 머리말 :17-19 와 같고, create 의 44/45 정의(create_session.sh:22-23)와도 같다.
  • 판단이 필요한 내용만 문서에 있고, 판정은 코드(adapter facts)에 있다. INSTRUCTION.md 를 따른 것이다.

2.4 tests/data/skill_code_blocks.json

  • 근거 핀의 줄 번호 이동은 실제로 늘어난 줄 수와 맞는다.
    • create_session.sh 는 경고 4줄을 :208 에 넣었으므로 그 뒤 근거가 모두 +4 줄 밀렸다(360→364, 518-545→522-549 등).
    • worktree_prepare.sh 는 --no-onboard case 한 줄 때문에 +1 줄 밀렸다(250→251).
  • 내용이 바뀐 블록은 하나다. SKILL.md:202-206 의 worktree 시놉시스가 [--onboard] 에서 [--no-onboard] 로 바뀌었고, 그 블록의 sha 만 38836d31bf38 에서 8bfabafb0328 로 바뀌었다.
  • test_issue42_skill_blocks.py 가 sha 와 근거를 다시 계산해 통과했다(§3).

2.5 새 테스트가 결함을 잡는지

  • base 대조 실행: git archive HEAD 를 TMPDIR 에 풀고, 코드 3개 파일(__main__.py, create_session.sh, worktree_prepare.sh)만 b9c828f 판으로 바꾼 뒤 tests/test_issue68_onboard_default.py 를 돌렸다.
    • 결과는 20 failed, 5 passed 로, 작성자의 주장과 같다.
    • 통과한 5건은 base 에서도 맞아야 하는 경우다. claude·grok 의 dry-run 과 행 시험 4건, 그리고 --onboard 전달 1건이다.
    • 사본은 확인한 뒤 지웠다.
  • Python 3.9 호환성: str.removeprefix 는 3.9 부터 있다. list[str] 주석은 from __future__ import annotations 덕분에 3.9 에서도 문제가 없다.

3. 실행한 테스트 (이 Mac: macOS, /bin/bash 3.2, /usr/bin/python3 3.9.6)

cd <검증 경로>
env -u HERDR_SOCKET_PATH -u HERDR_PANE_ID -u HERDR_TAB_ID -u HERDR_WORKSPACE_ID -u HERDR_SESSION_NAME \
    -u HERDR_SESSION -u WORKSPACE_ROOT -u MAM_ENV_FILE -u MAM_JOBS_DIR -u DELEGATE_JOB_LOGS_DIR \
    PYTHONDONTWRITEBYTECODE=1 /Users/godopu16/PuKi/laa/canary_projects/multi-agent-mux/.venv/bin/python \
    -m pytest -p no:cacheprovider --basetemp="$TMPDIR/claude-j2ab-bt" -q -rfs \
    tests/test_issue68_onboard_default.py tests/test_issue21_acceptance.py tests/test_issue21_phase2_loop_a.py \
    tests/test_issue26_ints.py tests/test_issue42_skill_blocks.py tests/test_issue50_onboard.py \
    tests/test_issue57_logs_follow_registry.py tests/test_issue63_same_cwd_ids.py
  • 결과: 265 passed, 1 skipped, 0 failed (724 s).
    • skip 1건은 test_issue42_skill_blocks.py:266 이다. untracked .claude/skills 가 worktree 에 없어서 생기는 환경 문제다.
  • facts 를 쓰는 다른 테스트 tests/test_a4_adapter_contract.py, tests/test_issue23_24_startup_path.py 는 103 passed (152 s).
  • base 대조 실행(§2.5)은 test_issue68_onboard_default.py 기준 20 failed, 5 passed.
  • test_issue50_dispatch_herdr.py 는 실제 herdr 서버를 띄우므로 브리프 제약에 따라 실행하지 않았다. 이 파일이 worktree_prepare 를 부르는 곳(:868)은 --onboard 를 명시하므로 이번 변경으로 동작이 바뀌지 않는다.
  • 테스트가 끝난 뒤 남은 프로세스: 테스트가 띄운 reconcile.sh, mock herdr, 구독자는 없다. 남아 있는 것은 원래 있던 셋뿐이다.
    • 본 체크아웃 모니터 3714
    • 이번 루프 88445
    • 이번 잡의 job_subscriber 88788 (13:56:28 시작)

4. 발견 사항

차단

  • 없음.

비차단

  • N1. tests/test_issue68_onboard_default.py:17 의 import yaml 은 쓰이지 않는다. PR 설명에서도 남긴 것으로 밝혔다.
  • N2. --no-onboard --submit-job "<프롬프트>" 를 함께 주면, 제출한 잡이 첫 턴이 되는데도 경고가 나온다.
    • 이 조합에서는 원래 온보딩 프롬프트를 만들지 않는다(create_session.sh:440). 그래서 --no-onboard 가 사실상 아무 일도 하지 않는다.
    • 결정 3 의 조건("--no-onboard 를 주고 ID 후발견 에이전트이면")을 그대로 구현한 결과다. 그래서 결함은 아니고, 문구가 조금 지나치게 경고할 뿐이다.
  • N3. facts 를 얻지 못했는데 호출자 환경에 MAM_ID_POST_DISCOVERED=1 이 export 돼 있으면, claude 에도 경고가 나올 수 있다. 현실적인 경로가 없어 참고로만 적는다.

5. 사용자 확인 필요

  • N2: --submit-job 과 함께 준 --no-onboard 에도 경고를 낼지. 지금은 결정 3 의 문언대로 경고를 낸다.

6. 결론

  • 결정 1–4 와 완료 조건이 모두 구현됐고 테스트로 덮였다.
  • 새 테스트는 base 에서 20건이 실패하므로 결함을 실제로 잡는다.
  • 바뀐 테스트 파일과 create/worktree 관련 테스트가 이 Mac 에서 모두 통과한다.
  • SKILL.md 의 설명은 코드와 줄 단위로 맞는다.

[VERDICT: PASS]