# PR #75 후속 리뷰 — job 028e98cb ## 판정과 검증 대상 이번 범위의 차단 사항을 발견하지 않았다. R2의 PGID 분리와 테스트 teardown 수정이 요구 사항을 충족한다. - base: 1d63e882bc1c46e9af8484647d5091b296d8fa3f - head: ec7f5c4e57286fb3c4238b8220f39094f4640391 - tree: fbadb24de60ccdae684b23e2e0a41cdf23ab81eb - 검증 경로: /var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261027T201245Z-63c71b/1 - HEAD/tree 일치, clean status, `git diff --check 1d63e88..HEAD` 통과. 실제 diff는 lib.sh와 test_issue72_update.py 두 파일이다. - 새 브리프의 좁혀진 범위인 1d63e88..HEAD를 검토했다. 이전 비차단 권고에 해당하는 파일/기능을 추가 변경하지 않았음을 확인했다. - `tea issues 72 --comments`, `tea pulls 75`를 다시 읽었다. 기준 이슈 내용은 앞선 검토와 같고, 이번 수정은 결정 2 및 기존 중복 방지/opt-out/PID/로그 계약과 정합적이다. ## 확인한 것 | 항목 | 파일:줄 근거 | 확인 결과 | |---|---|---| | R2: 호출자 PGID에서 분리 | `.agents/skills/lib.sh:2303–2309` | 기존 monitor 옵션을 기록하고 spawn 때만 `set -m` 사용. 비동기 monitor가 별도 PGID에서 뜨며, 기존 옵션은 복원된다. macOS에 없는 setsid(1) 없이 동작. | | 기존 기동 계약 | `lib.sh:2289–2315` | 정확한 PID 검색과 중복 방지, opt-out 분기는 유지. cwd를 작업 공간으로 두고 원래 cwd로 복원, stdin /dev/null, 로그 append, --idle-timeout 0, nohup의 SIGHUP 처리와 PID stdout 계약 유지. | | 0/1 × 세 복원 경로 회귀 | `tests/test_issue72_update.py:699–725`, 특히 `:724` | 정상 설치·정지 timeout·rollback의 두 모드 모두 실제 새 monitor와 PGID 분리를 검증한다. decoy 미신호 및 기동 횟수 검증도 유지. 여섯 조합 모두 통과. | | pkill 제거·소유 프로세스 정리 | `test_issue72_update.py:184–193,220–240` | 기록된 helper 그룹을 정리하고 wait한다. monitor는 이 테스트의 정확한 절대 스크립트 명령행으로 고른 뒤, 미리 수집한 자손 PID와 함께 정리한다. 전역 패턴 kill은 없다. | | 잔여 프로세스 검출 유지 | `test_issue72_update.py:237–240` | ws를 명령행에 남긴 프로세스가 있으면 최대 10초 기다린 뒤 실패한다. 이 문자열 검색은 보고/검증용이며 kill 대상으로 사용되지 않는다. 원본 테스트를 외부 정리 플러그인 없이 실행해 통과. | ## R2의 전후 재현 결과 base 1d63e88의 부정 대조는 직전 d14ae099 리뷰에서 실제로 실행한 동일 외부 탐침 로그를 사용했다. 당시 mode=0의 정상·timeout·rollback 세 경우는 PGID가 호출자와 같아 실패했고, mode=1의 세 대조군은 통과했다. 이번에도 같은 탐침 코드를 변경 없이 지정된 새 snapshot에서 실행했다. | 경로 | mode=0의 새 monitor PGID / caller PGID | mode=1의 새 monitor PGID / caller PGID | |---|---|---| | 정상 설치 | 93359 / 88049 — 분리 | 96481 / 88049 — 분리 | | 정지 timeout 복원 | 91992 / 88631 — 분리 | 94916 / 88631 — 분리 | | rollback 복원 | 93376 / 88631 — 분리 | 96166 / 88631 — 분리 | - 기존 `probe_monitor_group.py`: **2 passed / 11.95s** (base에서는 1 failed, 1 passed). - 기존 `probe_monitor_restore_group.py`: **4 passed / 10.40s** (base에서는 2 failed, 2 passed). - 별도 직접 호출 탐침으로 monitor 옵션 초기 off→off 및 on→on, cwd 복원을 확인: **2 passed / 3.24s**. 새 monitor의 PGID 분리도 확인했다. - PGID 검증은 조회로 했으며 호출자의 프로세스 그룹에 신호를 보내지 않았다. base 로그와 동일 탐침 코드, 이번 새 결과를 evidence/에 보존했다. base를 이번 허용 경로 밖에서 다시 실행한 것은 아니다. ## Mac에서 실행한 테스트 /bin/bash 3.2.57, Python 3.9.6에서 실행했다. 스냅샷에 .venv가 없어 브리프 앞부분에 명시된 제어 루트 .venv/bin/python을 사용했다. 작업 디렉터리는 위 snapshot이며, 주요 실행 명령은 다음과 같다. ```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=/var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review-028e98cb-pytest -ra \ tests/test_issue72_update.py \ tests/test_issue5_phase1_delegation.py::test_c07_watchdog_spawns_daemon_with_workdir_and_log \ tests/test_issue5_phase1_delegation.py::test_c08_watchdog_second_call_reuses_running_daemon \ tests/test_issue5_phase1_delegation.py::test_c09_start_watchdog_and_ensure_subscriber_daemon_agree \ tests/test_issue5_phase1_delegation.py::test_daemon_missing_monitor_raises_with_the_legacy_path \ tests/test_issue5_phase1_delegation.py::test_daemon_spawn_dedup_and_survives_parent_exit \ tests/test_issue19_subscriber_daemon_lifecycle.py::test_opt_out_still_reports_a_daemon_that_already_runs ``` **59 passed / 133.12s / exit 0**. update 파일 50건, phase1 watchdog 8건, 기존 daemon의 opt-out 보고 1건이다. 같은 환경 제거·Python·no-cache 설정으로 실행한 추가 검증: | 선택 | 결과 | |---|---| | `test_issue19_subscriber_daemon_lifecycle.py::test_sandbox_default_never_spawns_a_daemon` (0/1) | 2 passed / 0.53s | | `-p probe_monitor_group ... tests/test_issue72_update.py` | 2 passed / 11.95s | | `-p probe_monitor_restore_group ... tests/test_issue72_update.py` | 4 passed / 10.40s | | `-p probe_monitor_options ... tests/test_issue72_update.py` | 2 passed / 3.24s | 외부 탐침은 기존 Module의 Box fixture를 사용하고 항목만 외부 plugin으로 선택했다. source는 변경하지 않았다. 각 basetemp는 TMPDIR 아래 서로 다른 mam-review-028e98cb-{pytest,group,restore-group,options,optout}이었다. 이번에는 safe_cleanup 등의 외부 teardown 대체 없이 수정된 원본 cleanup을 실행했다. - `/bin/bash -n .agents/skills/lib.sh`: 통과. - `ast.parse(test_issue72_update.py, feature_version=(3,9))`: 통과. - diff --check: 통과. - ShellCheck는 PATH에 없어 실행하지 못했다. bash -n을 ShellCheck 통과로 표기하지 않는다. - 이번 새 브리프가 정한 수정 파일·watchdog 범위로 실행했고 전체 스위트는 실행하지 않았다. ## 발견 사항 및 사용자 확인 차단/비차단 신규 지적 없음. R2와 pkill 제거 요구 모두 해결됐다. 새 정책 결정이나 재계획이 필요하지 않다. ## 자원 안전 - 검증은 지정된 snapshot에서만 했고 creator 작업 트리에서 실행·수정하지 않았다. installer/update는 TMPDIR 가짜 설치 및 로컬 source/file:// installer만 사용했다. - 실제 herdr 서버·설정·에이전트 홈 DB를 조작하지 않았고, 실제 .mam.env 값을 테스트에 출력하거나 export하지 않았다. 이슈/PR 댓글·상태 변경, push/merge 없음. - 다섯 basetemp의 종료 후 프로세스 점검 결과 `remaining_test_processes=[]`. - 원래 제어 루트 monitor PID 3714는 실행 전후 같은 명령으로 살아 있었으며 신호를 보내지 않았다. - 종료 시 HEAD/tree와 clean status가 그대로이며 diff --check도 다시 통과했다. - 승인된 잡 이벤트·리포트 외에 실제 control-plane 상태를 수정하지 않았다. 원본 로그와 외부 탐침 코드는 이 리포트 옆 evidence/에 보존했다. [VERDICT: PASS]