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

6.1 KiB

Issue #60 리뷰 3차 — opencode 2.x 전용 지원 (job f1132474)

  • 리뷰어: planner-reviewer-claude-01
  • 검증 경로: /var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261018T073639Z-b5cb7f/1
  • identity: HEAD 0e05b1b6777ceb837066454ac688e04a0f5d14a0, tree c5cb1b16af283b3fdb447bafb865ba1abbfbb5a8 — 일치, 작업 트리 clean, .mam 없음. base..head 5커밋(a311c23, f0d1c00, 6b4b96f, cb5f439, 0e05b1b). 판정은 base..head 전체에 대해 내린다.
  • 1차(6b4b96f)·2차(cb5f439)에서 실바이너리로 확인한 사항은 0e05b1b 가 건드리지 않은 제품 코드라 그대로 유효하다. 0e05b1b 는 status.sh, tests/_agent_home_guard.py, tests/test_issue60_opencode_v2.py 만 바꿨다. 확인한 사항:
    • 측정 사실과 구현의 일치
    • session delete 의 자식 삭제, cwd 무관, 공유 행 보존
    • 3단 자손 정리
    • 서비스 보유자 제외
    • --standalone 수명
    • resident children
  • 실제 opencode 데이터는 읽기(grep -c, stat)로만 봤다.

결론

2차 차단 지적(B1)과 비차단 N1·N2 가 모두 해결됐고 새 회귀는 찾지 못했다. base..head 전체를 병합 가능으로 판단한다. 남은 것은 테스트 보강 권고뿐이다.

2차 지적별 확인

B1 (XDG_DATA_HOME 테스트 격리) — 해결.

  • _agent_home_guard.DROPPED_VARS 에 XDG_DATA_HOME 이 추가됐다(tests/_agent_home_guard.py:21). 그래서 conftest._isolate_agent_homes(conftest.py:210)가 테스트마다 이를 지운다. mam_sandbox·issue31 home 처럼 HOME 만 바꾸는 fixture 도 이제 <HOME>/.local/share 를 본다.
  • 2차에서 실패한 두 테스트(tier2 opencode e2e, test_opencode_purge_leaves_no_rows)가 XDG_DATA_HOME=<scratchpad> 에서 통과한다(아래 실행 결과).
  • 뮤테이션: DROPPED_VARS 에서 다시 빼면 그 두 테스트와 test_issue55::test_l1_every_path_variable_the_code_reads_is_accounted_for 가 실패한다(3 failed). L1 은 환경과 무관하게 실패하므로, 이후 누가 지워도 잡힌다.
  • 세션 가드는 XDG_DATA_HOME 이 설정돼 있으면 <XDG_DATA_HOME>/opencode 를 감시한다(:48-49). ambient 는 conftest 가 drop 전에 기록한 pane 값(_AGENT_HOME_VARS = ("HOME",) + DROPPED_VARS)이라 올바른 위치다.

N1 (status.sh 고정 경로) — 해결.

  • 두 Python 블록(status.sh:105-113, :305-313) 모두 get_adapter('opencode')._resolve_db(DiscoveryContext(workspace=cwd, agent_name='opencode', home_dir=home)) 를 쓴다.
  • cwd(:59/:259)와 home(HOME_DIR, :41/:241)은 각 블록에 정의돼 있다. env_python 이 PYTHONPATH=$SKILL_DIR 를 넣고 환경을 상속하므로(lib.sh:1852-1871) lib_py import 와 PATH·XDG 가 그대로 전달된다. 같은 파일이 이미 lib_py.delegation.logroot 등을 import 한다.
  • 행동 확인: git archive 사본에 임시 테스트를 넣고 실행했다(mam_sandbox+mock_herdr+mock_agents → create → reconcile 로 id 고정 → status). 1 passed.
    • --json 의 resume_state == "yes" 와 plain 출력 행의 yes, 둘 다 rc 0.
    • PATH 에서 opencode 를 빼도 폴백 경로로 yes.
    • DB 를 XDG_DATA_HOME 쪽으로 옮기면, XDG 없이 MISSING, XDG 를 주면 yes.
    • 행을 지우면 MISSING. 모두 rc 0.
  • status 는 이제 opencode 행마다 opencode debug paths 를 실행한다. 이 명령은 opencode 자신의 log 디렉터리에 기록한다. 하지만 status 가 이미 돌리는 reconcile.sh --dry-run 의 drift C 도 같은 _resolve_db 를 부르므로 새로운 종류의 부작용은 아니다.

N2 (--version 탐침이 실제 로그에 기록) — 해결.

  • _real_opencode()(test_issue60_opencode_v2.py:290-303)가 TemporaryDirectory 를 HOME·TMPDIR 로 하고 PATH 만 넘긴다. XDG_* 는 넘기지 않는다.
  • 실제 ~/.local/share/opencode/log/opencode.log 의 args="[\"--version\"]" 줄 수를 읽기로 세었다. 아래 두 스위트 실행 전 50, 후 50(증가 없음) 이다.

테스트 실행 (검증 경로, env -i, basetemp 는 scratchpad)

관련 10개 모듈: a4, issue31, issue10_13, issue60, tier2, issue55, issue57(status), issue21_worktree_prereqs(status), issue30_stall_watch, tier1.

  • XDG_DATA_HOME=<scratchpad>/jf1/xdg, PATH 에 opencode 없음: 363 passed, 1 skipped, rc 0. 실행 뒤 그 XDG 디렉터리는 비어 있었다(아무 파일·디렉터리도 생기지 않음).
  • XDG_DATA_HOME 미설정, PATH 에 ~/.opencode/bin 포함(실바이너리 계약 테스트 실행): 363 passed, 1 skipped, rc 0.
  • skip 은 두 번 모두 /proc 전용 테스트(macOS)다. #55 가드 오탐은 없었고, 실행 뒤 남은 opencode 프로세스도 없었다.

비차단 (테스트 보강 권고)

  • T1. 이번에 바뀐 두 동작은 회귀 테스트가 없다. 뮤테이션(XDG_DATA_HOME 설정 상태, issue55·issue60·issue31·tier2):

    • 가드의 XDG 감시를 원래대로 되돌림 → 28 passed, 실패 0
    • status.sh 를 고정 경로로 되돌림 → 28 passed, 실패 0

    test_issue55::test_g1 에 watch_dirs({"HOME": h, "XDG_DATA_HOME": x})["opencode"] == x/opencode 한 줄을 넣고, 위 임시 테스트와 같은 status 행동 테스트(XDG 쪽 DB → yes)를 넣기를 권한다.

  • T2 (기존 설계). 가드는 opencode 데이터 디렉터리의 항목 이름을 비교한다. XDG_DATA_HOME 이 설정된 Linux 러너에서 사용자 opencode(서비스 포함)가 그 디렉터리에 새 항목을 만들면 #55 와 같은 종류의 오탐이 날 수 있다. 판정 근거로 쓰지 말고 보고만 할 종류다.

  • 1·2차 비차단 N3(다른 MAM opencode 세션이 떠 있으면 무관한 purge 도 exit 4, lsof 없는 Linux 에서는 DB 보유자 검사 생략)는 의도된 동작으로 보고 그대로 둔다.

병합 가능성

  • base..head 전체에서 git diff --check 는 깨끗하다.
  • 변경 Python 파일은 Python 3.9(/usr/bin/python3 3.9.6)로 컴파일된다. 셸 스크립트는 /bin/bash -n(3.2)을 통과한다.
  • 1·2차의 실바이너리 검증과 뮤테이션 결과에 이번 검증이 더해져, 차단 사항이 없다.

[VERDICT: PASS]