Files
multi-agent-mux/.agents/reports/planner-reviewer-codex-01/report-ee26d64c.md
T

94 lines
12 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.
# PR #79 / Issue #68 리뷰 — PASS
- Job: ee26d64c / Reviewer: planner-reviewer-codex-01
- 기준: `tea issues 68 --comments`의 “구현 전에 정한 것”(결정 1–4), `tea pulls 79`, `INSTRUCTION.md:5`.
- Loop: `loop-20261029T045625Z-74296d`
- Base: `b9c828f09214b4bed6651a223cbb941e7b432647`
- Head: `3b81f9973223d2a910369711c08adc772003639d`
- Tree: `ff705b61bf25fe40d0ff054c372a399eacc79730`
- 검증 루트: `/var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261029T045625Z-74296d/1`
- 아래 파일:줄은 이 검증 루트 기준이다. 시작·종료 HEAD/tree 일치, `git status --short` 빈 출력, `git diff --check b9c828f..HEAD` 통과. creator 작업 트리에서 실행하거나 수정하지 않았다.
## 결정·완료 조건 대조
| 요구사항 | 코드·문서 근거 | 검증 | 빠진 조건 |
|---|---|---|---|
| 결정 1: create의 기본 온보딩 및 --no-onboard 유지 | `create_session.sh:67`, `:87`, `:88`, `:440` | 새 파일의 기본 dry-run 대조군·6종 실제 skip 행 검증, 기존 Issue #50 완료/44/45 테스트 | 없음 |
| 결정 2: worktree creator 기본 온보딩, skip 전달, 기존 --onboard 수용 | `worktree_prepare.sh:30`, `:42`, `:43`, `:230`, `:232` | 새 테스트 `:195`, `:215`, `:233`: 옵션 전달 4조합 및 실제 mock 온보딩 완료/잡 미생성; 외부 탐침에서 반대 순서 옵션도 확인 | 없음 |
| 결정 3: agy/codex/hermes/opencode에만 경고 1줄 | `lib_py/agents/__main__.py:75`, `create_session.sh:207`–`:211` | 새 테스트 `:50`, `:67`, `:95`: 6종 facts, dry-run/실제 create 및 기본 옵션 대조군 | 없음 |
| 경고가 종료 코드·행을 바꾸지 않음 | 변경은 facts 출력과 stderr 조건문뿐; 행 기록 분기는 그대로 | 새 테스트 `:95`에서 rc=0, 이름·역할·status·cmd·cwd·ID 출처·검증 상태·control_plane·delegate_job_id 검증. base 대조에서도 이 검증 후 경고 단언에서만 실패 | 없음 |
| 경고 이후의 거부도 기존 동작 유지 | `create_session.sh:209` 및 기존 #63 순서 게이트 | 새 테스트 `:157`: 미발견 agy 선행 세션, wait=0, rc=1 및 경고가 거부 설명보다 먼저 출력 | 없음 |
| 결정 4: 문서 변경 최소화 | create `SKILL.md:173`, `:205`, `:210`, `:213` | 옵션 표 1줄·worktree 절 3줄만 변경. 각 설명을 위 코드와 대조 | 없음 |
| 기존 implicit skip 호출 수정 및 Mac 통과 | `test_issue21_acceptance.py:47`, `:207`; `test_issue21_phase2_loop_a.py:422` | 변경 파일 5개와 관련 파일 3개 직접 실행. 아래 경로 이름 충돌 1건은 경로 보정 재실행으로 해소 | 없음 |
`create_session.sh`와 `worktree_prepare.sh`의 경로는 `.agents/skills/multi-agent-mux-create/scripts/` 아래다. 새 테스트 줄은 `tests/test_issue68_onboard_default.py` 기준이다.
## 추가 코드·호출부 확인
- 어댑터: `lib_py/agents/base.py:379`–`:382`의 기본값은 POST_DISCOVERED. claude의 `adapters/claude.py:188`–`:190`, grok의 `adapters/grok.py:18`–`:20`만 PRE_ASSIGNED로 재정의한다. 나머지 4종은 기본값을 사용한다. facts는 이 값을 0/1로 출력하므로 셸에 별도 에이전트 목록을 복제하지 않는다.
- facts 소비자는 `lib.sh:2596`(readiness eval), `:2957`(send_keys_safe eval), `:3156`(dialog facts의 이름별 sed 선택), `create_session.sh:207`이다. 새 항목은 숫자 할당문이므로 기존 eval 계약을 유지하고, 이름별 파싱에도 섞이지 않는다. 기존 facts 계약·CLI 인용 테스트 통과.
- `MAM_DELEGATION_PY=0`도 agents facts 호출을 건너뛰지 않는다. 외부 탐침에서 6종 경고 판정 및 worktree 기본 온보딩을 확인했다. facts 출력이 비거나 조회가 실패하면, 값이 미설정인 경우 `${MAM_ID_POST_DISCOVERED:-0}`에 의해 경고만 생략된다. rc=0/1의 빈 facts 탐침 모두 dry-run rc=0, nounset 오류 없음. Python 조회 불가 상황에 새 hard failure를 추가하지 않는 기존 best-effort 동작이다.
- `git grep -n worktree_prepare.sh` 및 `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` | 이미 --onboard이며 실제 mock 완료를 검증 |
| `test_issue21_phase2_loop_a.py:355` | submodule 초기화 거부가 creator 단계보다 앞서 발생; 온보딩 대기 없음 |
| `test_issue50_onboard.py:192` | 기존 --onboard + stub의 44/45 전달 검증 유지 |
| `test_issue50_dispatch_herdr.py:868` | 이미 --onboard를 명시한 실제 herdr 통합 테스트. 이번 제약에 따라 실행하지 않음 |
| `test_issue57_logs_follow_registry.py:276` | 기존 --onboard 및 mock 완료. 이번 Mac 실행 통과 |
| 새 테스트 `:202,219,237` | 전달·기본 온보딩·skip를 의도적으로 각각 검증 |
| create `SKILL.md:205`, `docs/design/worktree-creator-model.md:48`–`:52` | 사용자 실행 예시는 이제 기본 온보딩을 수행. SKILL의 `:213`이 44/45 및 세션·worktree 보존을 명시 |
| README/README.ko의 `:51`, VERSIONS의 역사 기록, `lib_py/worktree.py:3` | 설명/주석이며 추가 실행 호출 없음 |
- `tests/data/skill_code_blocks.json`: 변경된 evidence/passthrough 9곳을 base와 HEAD의 실제 줄 내용으로 비교해 모두 동일함을 확인했다. 변경된 비핀 필드는 worktree 사용 예시의 sha 1개(`38836d31bf38 → 8bfabafb0328`)뿐이며 --onboard → --no-onboard에 해당한다. inventory 테스트 통과.
- 새 테스트는 단순 문자열 존재 검사에 그치지 않고 옵션 전달, 실제 mock 잡의 completed 상태, skip 시 잡 미생성, 행의 안정 필드, 후속 거부를 확인한다. 아래 base 대조 결과도 예상과 일치했다.
## Mac 실행 및 결과
환경: Darwin arm64, `bash`는 `/bin/bash` 3.2.57, `/usr/bin/python3` 및 사용한 제어 루트 venv Python은 3.9.6. 검증 트리에는 venv가 없어 브리프 상단에 지정된 제어 루트 인터프리터를 사용했다. 모든 pytest 실행 cwd는 검증 루트이며 공통 접두부는 다음과 같다.
```bash
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 -u AGENT_SESSIONS_YAML \
PYTHONDONTWRITEBYTECODE=1 \
/Users/godopu16/PuKi/laa/canary_projects/multi-agent-mux/.venv/bin/python \
-m pytest -p no:cacheprovider --basetemp=<아래의 TMPDIR 경로> -q <선택 항목>
```
TMPDIR 접두부는 `/var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/`이다.
| 실행 | 선택 항목·추가 옵션 | 결과·증거 |
|---|---|---|
| 주 실행, basetemp `mam-review-ee26d64c-main` | `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_uuid_target.py tests/test_issue21_worktree_prereqs.py` | 265 passed, 1 failed, 1 skipped / 819.55s. [main.log](evidence/main.log) |
| 위 실패 사례 재실행, basetemp `mam-eval-ee26d64c-a4` | `tests/test_issue21_acceptance.py::test_a4_main_checkout_is_unchanged_by_the_whole_cycle` | 1 passed / 2.04s. [a4.log](evidence/a4.log) |
| 계약/create 회귀, basetemp `mam-review-ee26d64c-contract` | `tests/test_a4_adapter_contract.py::test_agent_adapter_registry ::test_facts_bridge_eval_contract ::test_cli_bridge_subcommands_and_quote_safety`(각각 전체 node 경로 사용), `tests/test_tier2_component.py`, `tests/test_issue57_logs_follow_registry.py::test_worktree_prepare_keeps_the_logs_next_to_the_control_root_registry`; `-k 'create or facts_bridge or agent_adapter_registry or cli_bridge'` | 16 passed, 30 deselected / 184.63s. 마지막 logs 노드는 이 필터에서 제외되어 아래 별도 실행. [contract.log](evidence/contract.log) |
| logs 별도 실행, basetemp `mam-eval-ee26d64c-logs` | `tests/test_issue57_logs_follow_registry.py::test_worktree_prepare_keeps_the_logs_next_to_the_control_root_registry` | 1 passed / 18.13s. [logs.log](evidence/logs.log) |
| 외부 탐침, basetemp `mam-review-ee26d64c-probes` | `tests/test_issue68_onboard_default.py -s -p probe_issue68`; 추가 env `PYTHONPATH=/tmp/mam-review-ee26d64c-harness` | 12 passed / 41.84s. legacy 6종 경고+기본 온보딩 1건, 빈 facts 2건, 마지막 skip 옵션 1건, 기본 44/45 전달 2건. [probes.log](evidence/probes.log), [probe_issue68.py](evidence/probe_issue68.py) |
| base 대조, basetemp `mam-eval-ee26d64c-base` | 같은 새 테스트 파일에 `-p base_issue68`; 같은 추가 PYTHONPATH | 의도한 20 failed, 5 passed / 77.25s. [base.log](evidence/base.log), [base_issue68.py](evidence/base_issue68.py) |
주 실행 실패는 `tests/test_issue21_acceptance.py:142`의 “worktree list 어디에도 mam-review 문자열이 없어야 한다”는 기존 단언 때문이다. 이 검토의 basetemp 이름 자체에 그 문자열이 들어갔다. 바로 앞의 HEAD·branch·status·branch tip·worktree list 원상복구 단언은 통과했다. 소스나 단언을 바꾸지 않고 basetemp 이름만 `mam-eval-ee26d64c-a4`로 바꾼 재실행이 통과했으므로 제품 회귀로 판정하지 않는다. 새 테스트 25건은 주 실행에서 모두 통과했다.
skip 1건은 `test_issue42_skill_blocks.py:266`: 검증 worktree에 추적되지 않는 `.claude/skills` 링크가 없는 경우다. 해당 링크의 합성 layout 테스트들은 실행됐다. 주 실행의 경로 보정까지 반영하면 제품 검증은 266건 통과·1건 skip이며, 추가 회귀/탐침 29건도 통과했다. 중복 확인한 A3 단독 실행은 별도 총계에 넣지 않았다.
base 대조는 다른 checkout에서 실행한 것이 아니다. HEAD의 새 테스트와 fixtures를 그대로 두고, `git show b9c828f:<path>`로 얻은 제품 파일 3개(create, worktree_prepare, agents CLI)만 임시 샌드박스에 넣었다. 직접 facts를 조회하는 6건은 base CLI를 임시 스크립트로 실행했고, 어댑터는 변경 없는 검증 트리 것을 사용했다. 실패 구성은 facts 6 + dry-run 경고 4 + 실제 행 검증 후 경고 4 + 후속 거부 경고 1 + 전달 3 + 기본 완료 1 + skip 1이다. 통과 5건은 claude/grok 경고 없음 각 2건과 기존 --onboard 전달 1건이다.
추가 정적 검사: 변경 셸 2개 `/bin/bash -n` 통과, 변경 Python 5개 `ast.parse(..., feature_version=(3,9))` 통과, diff 공백 검사 통과. ShellCheck는 설치되어 있지 않아 실행하지 않았다. 전체 스위트는 실행하지 않았다.
## 발견 사항
- **차단: 없음.**
- **비차단(P3):** `tests/test_issue68_onboard_default.py:17`의 `import yaml`은 사용되지 않는다. 해당 1줄을 제거하면 된다. 동작성·데이터 유실 문제는 아니며 판정을 막지 않는다.
- 위 A4 경로 문자열 단언의 민감성은 이번 diff에 도입되지 않았다. 이 리뷰에서는 경로 보정으로 검증을 완료했으며 PR 범위 확대를 요구하지 않는다.
## 격리·잔존 확인 및 사용자 확인 필요
모든 create/worktree 동작은 테스트의 mock herdr와 임시 작업 공간에서만 실행했다. 실제 에이전트 홈 DB를 열거나 실제 opencode 서비스·herdr 서버를 사용하지 않았다. 실제 .mam.env를 읽어 출력하거나 export하지 않았다. 테스트 종료 후 이번 실행의 임시 경로를 가진 프로세스는 0개이고, 실제 제어 루트 모니터는 시작·종료 모두 PID 3714다([process-audit.json](evidence/process-audit.json)). 패턴 kill, pkill, killall 및 실제 모니터에 대한 신호는 사용하지 않았다. 제품 소스·브랜치·이슈/PR 상태를 수정하거나 push/merge하지 않았다. 제어 평면 쓰기는 승인된 잡 이벤트와 이 리포트·증거뿐이다.
사용자 확인 필요: 없음. 결정 변경이나 재설계가 필요하지 않다.
[VERDICT: PASS]