[Bug] 테스트가 에이전트 pane 의 CLAUDE_PROJECT_DIR 를 따라 실제 ~/.claude/projects 에 가짜 대화 폴더를 남긴다 #55

Closed
opened 2026-10-10 13:41:37 +00:00 by Godopu · 1 comment
Owner

증상

전체 테스트를 돌릴 때마다 사용자의 실제 ~/.claude/projects/ 에 가짜 claude 대화 폴더가 하나씩 생긴다.

  • 2026-10-10 에 -tmp-…-test-adapter-discover0-ws 형태의 폴더가 40 개 쌓여 있었다.
  • 각 폴더에는 u-c1.jsonl({"sessionId": "u-c1"}) 한 줄만 들어 있었다. 사용자 확인 뒤 지웠다.
  • 폴더 이름에 남은 basetemp 로 보면, 그동안 리뷰어·creator·오케스트레이터가 여러 루프에서 돌린 전체 스위트가 남긴 것이다.
    • pytest-of-godopu16-pytest-N
    • codex-…-related
    • opencode-basetemp-…
    • i25-bt
    • 오케스트레이터 scratchpad 등

claude 의 대화 탐색(어댑터 discover(), resume 의 디스크 스캔)은 이 디렉터리를 읽는다. 그래서 가짜 기록이 실제 동작에 섞일 수 있다. "테스트는 실제 홈·실제 제어 평면을 건드리지 않는다"는 원칙(#20 의 control-plane 가드와 같은 취지)에도 어긋난다.

원인

  • tests/test_a4_adapter_contract.py::test_adapter_discover 는 격리 픽스처(mam_sandbox)를 쓰지 않는다. 임시 home_dir 만 DiscoveryContext 에 넘긴다.
  • 그런데 DiscoveryContext.claude_dir 는 CLAUDE_PROJECT_DIR 환경변수가 있으면 넘겨받은 home_dir 보다 그 값을 먼저 쓴다(lib_py/agents/base.py:101).
  • lib.sh:77 이 CLAUDE_PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$HOME/.claude/projects}" 를 정한다. herdr 서버가 이를 물려받아 모든 에이전트 pane 에 CLAUDE_PROJECT_DIR=/home/<user>/.claude/projects 가 들어 있다(claude·agy·grok·codex 프로세스 환경에서 확인).
  • 그래서 에이전트가 스위트를 돌리면 이 테스트가 실제 ~/.claude/projects 에 쓴다. 오케스트레이터 셸에는 이 변수가 없어 지금까지 드러나지 않았다.

재현(실제 홈 대신 임시 디렉터리):

CLAUDE_PROJECT_DIR=<임시 dir> pytest tests/test_a4_adapter_contract.py -k adapter_discover
# -> <임시 dir>/-…-test-adapter-discover0-ws/u-c1.jsonl 생성
# CLAUDE_PROJECT_DIR 없이 돌리면 생기지 않음

#53(v4.8.8)은 lib.sh 를 source 하는 테스트의 WORKSPACE_ROOT 만 막았다. 에이전트 홈 경로 변수는 그대로다.

제안 — 코드로 강제

  1. 모든 테스트에 적용되는 autouse 픽스처(tests/conftest.py)를 둔다. 에이전트 홈·대화 경로 변수를 테스트별 임시 디렉터리로 바꾸거나 지운다.
    • 대상 예: CLAUDE_PROJECT_DIR, HOME_DIR, CODEX_HOME, 그 밖에 어댑터가 읽는 경로 변수. 어댑터 코드에서 찾아 빠짐없이 넣는다.
    • 개별 테스트를 고치는 것이 아니라 같은 실수가 다시 생길 수 없게 막는다.
    • mam_sandbox 를 쓰는 테스트의 동작은 그대로여야 한다.
  2. 실제 홈 가드를 둔다. 스위트 시작 시점과 끝 시점에 사용자 실제 에이전트 디렉터리(~/.claude/projects 등)의 항목을 비교한다. 테스트 중에 새로 생긴 항목이 있으면 실패시키고 경로를 출력한다. #20 의 control-plane 가드와 같은 방식이다. 이 테스트는 원래 실제 홈을 읽어야 하므로, 읽기만 하고 쓰지 않는다.
  3. 위 재현을 회귀 테스트로 고정한다. CLAUDE_PROJECT_DIR 가 실제 경로처럼 설정된 환경에서도 test_adapter_discover 가 그 경로에 쓰지 않아야 한다.

비범위

  • lib.sh 가 CLAUDE_PROJECT_DIR 를 기본값으로 export 하는 운영 동작은 바꾸지 않는다. 에이전트가 실제로 쓰는 경로다.
  • 이미 생긴 폴더는 2026-10-10 에 수동으로 지웠다.
## 증상 전체 테스트를 돌릴 때마다 사용자의 **실제** `~/.claude/projects/` 에 가짜 claude 대화 폴더가 하나씩 생긴다. - 2026-10-10 에 `-tmp-…-test-adapter-discover0-ws` 형태의 폴더가 40 개 쌓여 있었다. - 각 폴더에는 `u-c1.jsonl`(`{"sessionId": "u-c1"}`) 한 줄만 들어 있었다. 사용자 확인 뒤 지웠다. - 폴더 이름에 남은 basetemp 로 보면, 그동안 리뷰어·creator·오케스트레이터가 여러 루프에서 돌린 전체 스위트가 남긴 것이다. - `pytest-of-godopu16-pytest-N` - `codex-…-related` - `opencode-basetemp-…` - `i25-bt` - 오케스트레이터 scratchpad 등 claude 의 대화 탐색(어댑터 `discover()`, resume 의 디스크 스캔)은 이 디렉터리를 읽는다. 그래서 가짜 기록이 실제 동작에 섞일 수 있다. "테스트는 실제 홈·실제 제어 평면을 건드리지 않는다"는 원칙(#20 의 control-plane 가드와 같은 취지)에도 어긋난다. ## 원인 - `tests/test_a4_adapter_contract.py::test_adapter_discover` 는 격리 픽스처(`mam_sandbox`)를 쓰지 않는다. 임시 `home_dir` 만 `DiscoveryContext` 에 넘긴다. - 그런데 `DiscoveryContext.claude_dir` 는 `CLAUDE_PROJECT_DIR` 환경변수가 있으면 넘겨받은 `home_dir` 보다 그 값을 먼저 쓴다(`lib_py/agents/base.py:101`). - `lib.sh:77` 이 `CLAUDE_PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$HOME/.claude/projects}"` 를 정한다. herdr 서버가 이를 물려받아 모든 에이전트 pane 에 `CLAUDE_PROJECT_DIR=/home/<user>/.claude/projects` 가 들어 있다(claude·agy·grok·codex 프로세스 환경에서 확인). - 그래서 에이전트가 스위트를 돌리면 이 테스트가 실제 `~/.claude/projects` 에 쓴다. 오케스트레이터 셸에는 이 변수가 없어 지금까지 드러나지 않았다. 재현(실제 홈 대신 임시 디렉터리): ``` CLAUDE_PROJECT_DIR=<임시 dir> pytest tests/test_a4_adapter_contract.py -k adapter_discover # -> <임시 dir>/-…-test-adapter-discover0-ws/u-c1.jsonl 생성 # CLAUDE_PROJECT_DIR 없이 돌리면 생기지 않음 ``` #53(v4.8.8)은 lib.sh 를 source 하는 테스트의 `WORKSPACE_ROOT` 만 막았다. 에이전트 홈 경로 변수는 그대로다. ## 제안 — 코드로 강제 1. **모든 테스트에 적용되는 autouse 픽스처**(`tests/conftest.py`)를 둔다. 에이전트 홈·대화 경로 변수를 테스트별 임시 디렉터리로 바꾸거나 지운다. - 대상 예: `CLAUDE_PROJECT_DIR`, `HOME_DIR`, `CODEX_HOME`, 그 밖에 어댑터가 읽는 경로 변수. 어댑터 코드에서 찾아 빠짐없이 넣는다. - 개별 테스트를 고치는 것이 아니라 같은 실수가 다시 생길 수 없게 막는다. - `mam_sandbox` 를 쓰는 테스트의 동작은 그대로여야 한다. 2. **실제 홈 가드**를 둔다. 스위트 시작 시점과 끝 시점에 사용자 실제 에이전트 디렉터리(`~/.claude/projects` 등)의 항목을 비교한다. 테스트 중에 새로 생긴 항목이 있으면 실패시키고 경로를 출력한다. #20 의 control-plane 가드와 같은 방식이다. 이 테스트는 원래 실제 홈을 읽어야 하므로, 읽기만 하고 쓰지 않는다. 3. 위 재현을 회귀 테스트로 고정한다. `CLAUDE_PROJECT_DIR` 가 실제 경로처럼 설정된 환경에서도 `test_adapter_discover` 가 그 경로에 쓰지 않아야 한다. ## 비범위 - `lib.sh` 가 `CLAUDE_PROJECT_DIR` 를 기본값으로 export 하는 운영 동작은 바꾸지 않는다. 에이전트가 실제로 쓰는 경로다. - 이미 생긴 폴더는 2026-10-10 에 수동으로 지웠다.
Author
Owner

Fixed by PR #56, merged as 8b0b4a0 (v4.9.0). Verified on macOS / Python 3.9: full suite at 21f0c12 passed (1860 passed / 0 failed / 38 skipped) after a unanimous review.

Fixed by PR #56, merged as 8b0b4a0 (v4.9.0). Verified on macOS / Python 3.9: full suite at 21f0c12 passed (1860 passed / 0 failed / 38 skipped) after a unanimous review.
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: tmpl/multi-agent-mux#55