Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
5.8 KiB
5.8 KiB
PR #62 리뷰 2회차 — Issue #60 Linux 확인 후속 (job 1fb2cefa)
- 리뷰어: planner-reviewer-claude-01
- 검증 경로:
/var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261019T015801Z-05463c/1 - identity: HEAD
6a37c0019baa31ee28b32a086e57b4c8239413c4, tree87013e7ef7f5239f1bf6ea38a2cbda214257be3c가 일치한다. 작업 트리는 clean 이고.mam은 없다. - 범위: base
1d7b7da..head 9커밋. 판정은 base..head 전체에 대한 것이다. 1회차 이후 바뀐 것은6a37c00하나이고,opencode.py·status.sh·reconcile.sh·test_issue60_linux_fixes.py4개 파일만 바뀌었다. - 1회차(@6a4e385)의 확인은
6a37c00이 건드리지 않은 코드라 그대로 유효하다. 1회차에 확인한 것: 임시 DB 에서_ro_connect세 갈래,_DB_PATHS키,auth-okCLI, stop 문구. - 환경: macOS, Python 3.9.6, sqlite 3.51.0. 실제 opencode 데이터는
ls·grep -c·ps·lsof로만 봤다.
결론
1회차의 공통 차단(B1)과 codex·agy 지적이 모두 해결됐고, 새 회귀는 찾지 못했다. base..head 전체를 병합 가능으로 판단한다.
1회차 지적별 확인
B1 (clean 상태 5개가 macOS 에서 실패) — 해결.
make("clean")이 close 뒤 남은-wal·-shm을 지운다(tests/test_issue60_linux_fixes.py:158-162). 1회차 사본에서 내가 검증한 수정과 같다.- 검증 경로에서 이 모듈이 모두 통과한다(아래 실행 결과).
- 뮤테이션 i1(immutable 분기를
mode=ro로)이 이제 이 Mac 에서 5 failed 로 잡힌다. 1회차에는 fixture 가 먼저 실패해서 이 뮤테이션이 가려졌었다.
안내 문구 패턴이 사용자가 친 Ask anything… 를 지움(codex) — 해결.
- 패턴이
Ask anything(?:…|\.\.\.) "[^"]*"?가 되어 따옴표 예시가 필수다(opencode.py:80). - 두 fixture 에 넣어 직접 확인한 결과:
Ask anything…,Ask anything...는 친 그대로 읽힌다.- 홈 화면 원본, 잘린 예시,
Ask anything… "는 빈 입력으로 읽힌다.
- 회귀 테스트 2개가 추가됐다(
:84-85). 뮤테이션 p1(예시를 다시 선택 사항으로)은 4 failed 로 잡힌다.
auth_ok 가 실행 불가한 ~/.opencode/bin/opencode 도 인정(codex) — 해결.
- 이제
isfile and access(X_OK)로 본다(opencode.py:322-323). - 권한 644 파일과 디렉터리는 모두 False 로 고정됐다(
test_a_home_install_that_cannot_run_is_not_enough). 뮤테이션 a1(exists로 되돌림)은 1 failed 로 잡힌다. shutil.which가 이미 실행 가능 여부를 보므로 PATH 쪽은 그대로다.
status.sh·reconcile.sh 의 sqlite3.connect(odb)(agy) — 해결.
- status 의 opencode 두 블록(
status.sh:115-117,:316-318)과 reconcile drift C(reconcile.sh:953-955)가_ro_connect를 쓴다. - 두 스크립트는 lib_py 를 이미 import 하는 경로에서 돌기 때문에 import 가 된다(status 는
env_python/PYTHONPATH, reconcile 은env_python). - status 블록에서
import sqlite3를 지웠지만 영향이 없다. 같은 함수의 다른 블록(hermes:90, codex:132)은 각자import sqlite3를 한다. - 행동 확인: git archive 사본에 임시 e2e 를 넣었다. 순서는 이렇다.
- mam_sandbox+mock 에서 create → 자식 세션 추가 →
journal_mode=wal→ 사이드카 삭제(Linux 의 닫힌 상태) reconcile.sh --once --emit-diff→status.sh --json과 plain status
- mam_sandbox+mock 에서 create → 자식 세션 추가 →
- 결과(head): rc 는 모두 0. 부모 id 로 고정됐고
resume_state == "yes"이다. DB 디렉터리는 실행 전후 모두['opencode.db']였다. - 대조(두 스크립트를
sqlite3.connect(odb)로 되돌린 사본): reconcile 뒤opencode.db-shm·opencode.db-wal이 생겨 같은 테스트가 실패했다. - 참고: mock opencode 가 만드는 DB 는 WAL 모드가 아니다. 그래서 WAL 로 바꾸지 않으면 이 차이가 드러나지 않는다.
테스트 실행 (검증 경로)
- 조건:
env -i, 임시 HOME,XDG_DATA_HOME=<scratchpad>, basetemp 는 scratchpad,-p no:cacheprovider,PYTHONDONTWRITEBYTECODE=1. - 대상 12개 모듈: issue60_linux_fixes, issue60_opencode_v2, a4, tier1, tier2, issue31, issue55, issue57, issue21_worktree_prereqs, issue50_dispatch, issue30_stall_watch, c1_tui_readiness.
- 결과: 463 passed, 2 skipped, 실패 0, 16분.
- skip 1:
/proc전용 테스트. - skip 2: PATH 에 opencode 가 없어 건너뛴 실바이너리 계약 테스트(1회차·이전 이슈에서 따로 확인함).
- skip 1:
- 부작용 확인:
- scratchpad XDG 디렉터리는 실행 뒤에도 비어 있었다.
- 실제
~/.local/share/opencode의 목록은 전후가 같았다. - 실제 log 의
debug줄 수는 2 → 2 였다. - 남은 opencode 프로세스는 사용자 서비스 하나뿐이다(pid 23630, 시작 08:13, 이 잡 이전).
- #55 가드 오탐은 없었다.
- 린트:
git diff --check 1d7b7da..HEAD는 깨끗하다.- 바뀐 Python 은 3.9 로 파싱된다.
status.sh·reconcile.sh는/bin/bash -n(3.2)을 통과한다.
비차단
- N1. 새
test_status_and_reconcile_open_the_database_read_only는 소스 문자열만 센다.sqlite3.connect(odb, timeout=…)같은 변형은 지나간다. 위의 임시 e2e(WAL DB, 사이드카 없음 → reconcile·status → 목록 불변)를 tier2 opencode e2e 에 붙이면 행동으로 고정할 수 있다. - N2. 1회차 비차단은 의도된 완화로 그대로 남아 있다(브리프에도 기록됨):
- immutable 경쟁 창(ms 수준)
_DB_PATHS의 프로세스 수명 캐시- create 사전 검사의 완화
- N3. 아주 좁은 화면에서 예시의 여는 따옴표까지 잘리면
Ask anything…만 남는다. 이때는 친 초안으로 읽힌다(안전한 쪽). 실제 캡처로는 확인하지 않았다.
[VERDICT: PASS]