Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
72 lines
5.8 KiB
Markdown
72 lines
5.8 KiB
Markdown
# 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`, tree `87013e7ef7f5239f1bf6ea38a2cbda214257be3c` 가 일치한다. 작업 트리는 clean 이고 `.mam` 은 없다.
|
|
- 범위: base `1d7b7da`..head 9커밋. 판정은 base..head 전체에 대한 것이다. 1회차 이후 바뀐 것은 6a37c00 하나이고, `opencode.py`·`status.sh`·`reconcile.sh`·`test_issue60_linux_fixes.py` 4개 파일만 바뀌었다.
|
|
- 1회차(@6a4e385)의 확인은 6a37c00 이 건드리지 않은 코드라 그대로 유효하다. 1회차에 확인한 것: 임시 DB 에서 `_ro_connect` 세 갈래, `_DB_PATHS` 키, `auth-ok` CLI, 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 를 넣었다. 순서는 이렇다.
|
|
1. mam_sandbox+mock 에서 create → 자식 세션 추가 → `journal_mode=wal` → 사이드카 삭제(Linux 의 닫힌 상태)
|
|
2. `reconcile.sh --once --emit-diff` → `status.sh --json` 과 plain status
|
|
- 결과(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회차·이전 이슈에서 따로 확인함).
|
|
- 부작용 확인:
|
|
- 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]
|