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

71 lines
7.7 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.
# Review Report — Job d05e8e15 (v4.4.0 릴리스 락스텝 갱신)
- Reviewer: planner-reviewer-claude-01
- 리뷰 범위: `b347efd..HEAD` (단일 커밋 `3874797` "release(v4.4.0)"), 21 파일 +160/−40
- 범위 고정: 브리프 내장 diff(39,725 B) vs `git diff b347efd..HEAD -- . ':(exclude).agents/reports'`(39,724 B) — 말미 개행 1바이트 외 **바이트 동일**. `.agents/reports` 하위 변경 없음.
- 검증 환경: Python 3.9.6, `.venv`, 실제 리뷰어 셸의 ambient `MAM_VERSION=4.3.0` (이 커밋이 고친 격리 결함의 실전 재현 조건)
- 참고: 현재 체크아웃 브랜치는 `release/v4.4.0`이며 `main`은 아직 `b347efd`(릴리스 커밋 미포함). VERSIONS.md "기준 브랜치: main"은 병합 후 상태를 선기술한 것으로, 병합 시점에 사실이 된다.
## 1. SemVer 판정(MINOR `v4.4.0`) 근거 재검증
작업자의 "규모는 크지만 깨는 것이 없다" 주장을 항목별로 실 트리에서 재확인했다.
| 주장 | 검증 방법 | 결과 |
| :--- | :--- | :--- |
| Issue #5 전 구간 삭제·rename 0건 | `git diff --name-status fc0bd96..HEAD \| grep -v '^[AM]'` | 0건 ✅ |
| `SCHEMA_VERSION = 1` 불변 | `mqtt_common.py:135` | ✅ |
| `scripts/*.py` 4종 존속 | `ls multi-agent-mux-delegate-job/scripts/` | job_subscriber/mqtt_common/publish_event/registry ✅ |
| 롤백 env 4종 실재·기본값 | `lib.sh:1972,1989,2000` (`MAM_DELEGATION_PY:-1`), `engine.py:109` (`MAM_ENGINE_CAS` 기본 "1"), `run_loop.sh:122` (`MAM_LOOP_PY:-1`, `MAM_LOOP_FREEZE:-0`) | ✅ |
| 자동 완료 기본 비활성 | `loop/autocomplete.py:29,53` — `os.environ.get("MAM_AUTO_COMPLETE","0") == "1"` | ✅ |
| 레거시 셸 루프 968줄 존치 | `wc -l run_loop.sh` = 968 (Phase 3 직전 936, Phase 4 직전 960) — VERSIONS.md의 "936줄 이식" / "968줄 존치" 두 숫자 모두 정확 | ✅ |
| `run_loop.sh:17` source, `lib.sh:32-33` 무조건 재export | 행 번호 실측 일치. `MAM_VERSION=4.3.0 bash -c 'source lib.sh; echo $MAM_VERSION'` → `4.4.0` | ✅ |
**판정 동의**: 공개 계약(스크립트 경로·CLI·와이어 스키마·YAML 레이아웃)에 제거·변경이 없고 모든 기본 동작 변경이 env 1개로 가역이므로 SemVer 2.0.0 §8의 MAJOR 요건을 충족하지 않는다. 유일한 신규 fail-closed 거부(`MAM_VERSION` 게이트)는 프로덕션 경로에서 `lib.sh`가 값을 무조건 덮어쓰므로 정상 배포된 트리에서는 발동할 수 없고, 혼재 트리에서만 발동한다. 이는 릴리스 노트 "부분 배포 금지"로 명시되어 있다. **v4.4.0 MINOR가 옳다.**
## 2. 락스텝 갱신 검증
- `lib.sh` MAM_VERSION, `eager.py` FRAMEWORK_VERSION, VERSIONS.md 현재 버전 + 매트릭스 8행, 8개 `SKILL.md` frontmatter 모두 `4.4.0` (grep 실측).
- README/BOOTSTRAP 4종 배지: **v4.1.3 / v4.2.0 → v4.4.0**. `b347efd` 시점 README 배지는 `v4.2.0`인데 `lib.sh`는 `4.3.0`이었다. 즉 배지는 두 릴리스 동안 유실 상태였고, 이번 작업이 이를 함께 회수했다(유실 관점에서 긍정). 다만 배지는 락스텝 테스트 미커버(→ O-1).
- 트리 내 잔존 `4.3.0` 문자열은 VERSIONS.md 이력, `delegate-job` README/job-protocol/registry/SKILL.md의 "구현 위치 각주 (v4.3.0)" 등 **역사적 서술**뿐이며 현재 버전 표기로 남은 것은 없다.
## 3. 테스트 변경 검증 (재현)
### 3-1. 락스텝 4번째 다리(`eager.py`) 커버리지 — 주장 사실
- `b347efd` 트리에서 `eager.py`만 4.4.0으로 올린 뒤 구 `test_version_consistency.py` 실행 → **2 passed (미검출)**.
- HEAD 트리에서 `eager.py`만 4.5.0으로 올린 뒤 실행 → `test_three_way_version_lockstep`, `test_runtime_version_gate_rejects_a_partially_bumped_tree` **2 failed (검출)**. 커밋 메시지의 "gap" 주장과 수정 효과 모두 확인.
- `_get_eager_py_framework_version`은 정적 regex 파싱(`^FRAMEWORK_VERSION\s*=\s*"(\d+\.\d+\.\d+)"`, MULTILINE)으로 `eager.py:16` 형식과 정확히 일치. 새 게이트 테스트는 `importlib.util.spec_from_file_location`으로 `sys.path` 오염 없이 로드하고 `os.environ`을 try/finally로 복원한다. `os`/`re`는 파일 상단에 이미 import되어 있다.
### 3-2. 격리 결함(ambient `MAM_VERSION`) — 주장 "4건 실패" 정확히 재현
| 트리 | conftest fixture | env | 결과 |
| :--- | :---: | :--- | :--- |
| HEAD | 제거(재현용 복제본) | `MAM_VERSION=4.3.0` | **4 failed**, 16 passed — `test_p4_01_eager_import…`, `test_p4_01_loop_runner_instantiation…`, `test_p4_02_midflight…`, `test_p3_03_runner_agent_type_resolution` |
| HEAD | 존재 | `MAM_VERSION=4.3.0` (리뷰어 셸 실값) | 20 passed |
| HEAD | 존재 | `MAM_VERSION=9.9.9` | 20 passed |
| `b347efd` | 없음 | `MAM_VERSION=4.3.0` (자기 트리와 일치) | 19 passed — "우연히 같아 잠복" 주장 확인 |
| `b347efd` | 없음 | `MAM_VERSION=9.9.9` | 5 failed (위 4건 + `test_p3_02`) — 결함이 릴리스 이전부터 존재했음 확인 |
- fixture는 session 스코프 autouse로 `os.environ.pop`, 종료 시 복원. 게이트를 직접 검사하는 테스트(`test_p4_01` monkeypatch 9.9.9, 신규 게이트 테스트, `test_mam_version_is_not_env_overridable`)는 모두 자체적으로 값을 설정하므로 영향 없음(HEAD 20/20으로 실증).
- `test_issue5_phase4_runtime.py`는 하드코딩 리터럴 제거 후 `verify_framework_version(eager.FRAMEWORK_VERSION)` — 시그니처 기본값이 `FRAMEWORK_VERSION`이므로 동작 동일하며, monkeypatch 9.9.9 불일치 검사는 그대로 유지.
### 3-3. 린트
- `py_compile` 4파일 OK, `bash -n lib.sh` OK, 변경 추가행 중 100자 초과 없음, `git status` clean. (pyflakes/ruff는 venv 미설치 — 이전 라운드와 동일.)
## 4. 문서 검증
- VERSIONS.md 4.4.0 절: 인용 파일·행 번호(`mqtt_common.py:135`, `run_loop.sh:17`, `lib.sh:32-33`), env 이름·기본값, 테스트 수(510 → 750, +240; Phase 4 시점 749 + 신규 게이트 테스트 1 = 750 수집 실측) 모두 실 트리와 일치.
- `implementation_plan.md` Phase 0/3/4 상태 열, `phase4-freeze-removal.md` 부분 배포 금지 문구, `task.md` Rev.9 / P4-01 증거 갱신 — 내용 정확.
## 5. 결함
**차단 결함 없음.** 코드 변경은 상수 2개 + 테스트 3파일이며 세 가지 주장(락스텝 갭, 4건 격리 실패, fixture 효과)이 모두 실측 재현되었다.
### 비차단 관찰
- **O-1 (권고)**: README/BOOTSTRAP 4종 배지는 이번에 두 릴리스분이 한꺼번에 회수될 만큼 락스텝 밖에 있다. `test_three_way_version_lockstep`에 5번째 다리로 추가 권고. 검증한 프로토타입(15줄, `BADGE_DOCS` + `_get_badge_version` regex `badge/version-v(\d+\.\d+\.\d+)-`): HEAD에서 3 passed, `b347efd`에 역적용 시 `README.md badge (4.2.0) != lib.sh (4.3.0)`로 정확히 실패한다.
- **O-2 (표기)**: 테스트 함수명 `test_three_way_version_lockstep`과 파일 헤더 "3-Way"가 이제 4-way(O-1 채택 시 5-way)를 검사한다. 이름 변경은 선택 사항.
- **O-3 (환경)**: `test_p3_02_run_loop_wrapper_delegates_to_python_default`는 `.venv`가 없는 git worktree에서 `No module named 'paho'`로 실패한다(리뷰 중 관측, `.venv` 심링크로 해소). 본 커밋과 무관한 기존 테스트의 실행 환경 의존이며 메인 트리에서는 통과.
- **O-4 (브랜치)**: 릴리스 커밋은 `release/v4.4.0`에만 있고 `main`은 `b347efd`이다. VERSIONS.md의 "main 병합 완료"는 이 릴리스 브랜치 병합으로 완성된다.
- 이전 라운드 핸드오버(a665d729 §4) 중 코드 변경을 요하는 항목(all-None intent 신원 가드, direct job `claim` 토큰 등)은 이번 릴리스 범위 밖이며 유효하게 잔존.
## 6. 전체 스위트
- `env -u MAM_VERSION .venv/bin/python -m pytest tests -q`: __SUITE_RESULT__
[VERDICT: PASS]