[Bug] lib.sh 의 herdr 서버 자동 기동 시 호출자 환경변수(CLAUDECODE 등)가 모든 에이전트 pane 에 상속되는 문제 #9

Closed
opened 2026-09-11 15:52:09 +00:00 by Godopu · 2 comments
Owner

문제 개요 (Summary)

lib.sh 를 source 할 때 대상 herdr 세션 서버가 떠 있지 않으면 서버를 자동 기동합니다. 이때 호출 프로세스의 환경변수를 정제하지 않고 그대로 상속하므로, Claude Code 세션(오케스트레이터) 안에서 MAM 스크립트를 실행하면 CLAUDECODE=1, CLAUDE_CODE_CHILD_SESSION=1, CLAUDE_CODE_SESSION_ID=<오케스트레이터 ID> 가 herdr 서버와 이후 생성되는 모든 에이전트 pane 에 상속됩니다. 또한 read-only 로 문서화된 multi-agent-mux-status 도 이 경로로 서버를 기동합니다.


세부 원인 분석 (Detailed Root Causes)

1. herdr 서버 자동 기동 시 환경변수 미정제

  • 위치: .agents/skills/lib.sh 194~231행 (_mam_session_running 검사 후 subprocess.Popen(..., start_new_session=True) 로 "$REAL_HERDR" --session "$_MAM_SESSION" server 실행, 225행)
  • 증상:
    • Popen 에 env 를 지정하지 않아 호출자 환경 전체가 서버로 상속되고, 서버가 만드는 pane 프로세스에도 그대로 전달됩니다.
    • 재현: Claude Code 세션에서 status.sh 실행 → herdr 서버 자동 기동 → 이후 create_session.sh 로 생성한 claude/codex pane 프로세스 모두에서 위 변수 확인 (ps eww <pid>)
    • 영향: 서브에이전트 claude 가 CLAUDE_CODE_CHILD_SESSION 표시 때문에 transcript 저장을 끔 (TUI 경고: Transcript saving is off — inherited CLAUDE_CODE_CHILD_SESSION marker) → ~/.claude/projects/<key>/<uuid>.jsonl 이 생성되지 않아 status 의 RESUME 이 MISSING, multi-agent-mux-resume 불가
    • 서버가 한 번 오염되면 이후 해당 서버에서 생성되는 모든 세션에 동일하게 적용됨
  • 제안 해결책:
    • 서버 기동 Popen 에 에이전트 런타임 표시 변수를 제거한 env 전달
      (예: env={k: v for k, v in os.environ.items() if k != "CLAUDECODE" and not k.startswith("CLAUDE_CODE_")})
    • 다른 에이전트 CLI(codex, agy 등)의 유사한 세션 표시 변수도 목록화하여 함께 제거 검토
    • 또는 create_session.sh 의 spawn 단계에서 env -u 처리 추가

2. read-only 스킬의 부수효과

  • 위치: .agents/skills/multi-agent-mux-status/SKILL.md 3행·16행 ("Read-only", "No mutation"), status.sh 10행에서 lib.sh source
  • 증상: 서버가 꺼져 있을 때 status 조회만으로 herdr 서버 데몬이 기동됨 (1번 오염의 직접 계기)
  • 제안 해결책: 조회 경로에서는 자동 기동을 건너뛰는 플래그(예: MAM_NO_AUTOSTART=1)로 lib.sh 를 source 하거나, 서버 미기동 시 dead 로만 보고

현재 우회 방법 (Workaround)

for v in $(env | grep -oE '^(CLAUDECODE|CLAUDE_CODE_[A-Za-z0-9_]*)=' | tr -d =); do unset "$v"; done
# 이후 MAM 스크립트 실행. 이미 오염된 서버는 `herdr session stop <name>` 후 재기동

환경 정보 (Environment)

  • OS: macOS (Darwin 25.6.0)
  • MAM Version: 4d444ce (main)
  • 실행 환경: Claude Code 세션을 오케스트레이터로 사용
## 문제 개요 (Summary) `lib.sh` 를 source 할 때 대상 herdr 세션 서버가 떠 있지 않으면 서버를 자동 기동합니다. 이때 호출 프로세스의 환경변수를 정제하지 않고 그대로 상속하므로, **Claude Code 세션(오케스트레이터) 안에서 MAM 스크립트를 실행하면** `CLAUDECODE=1`, `CLAUDE_CODE_CHILD_SESSION=1`, `CLAUDE_CODE_SESSION_ID=<오케스트레이터 ID>` 가 herdr 서버와 이후 생성되는 **모든 에이전트 pane** 에 상속됩니다. 또한 read-only 로 문서화된 `multi-agent-mux-status` 도 이 경로로 서버를 기동합니다. --- ## 세부 원인 분석 (Detailed Root Causes) ### 1. herdr 서버 자동 기동 시 환경변수 미정제 * **위치**: `.agents/skills/lib.sh` 194~231행 (`_mam_session_running` 검사 후 `subprocess.Popen(..., start_new_session=True)` 로 `"$REAL_HERDR" --session "$_MAM_SESSION" server` 실행, 225행) * **증상**: * `Popen` 에 `env` 를 지정하지 않아 호출자 환경 전체가 서버로 상속되고, 서버가 만드는 pane 프로세스에도 그대로 전달됩니다. * 재현: Claude Code 세션에서 `status.sh` 실행 → herdr 서버 자동 기동 → 이후 `create_session.sh` 로 생성한 claude/codex pane 프로세스 모두에서 위 변수 확인 (`ps eww <pid>`) * **영향**: 서브에이전트 claude 가 `CLAUDE_CODE_CHILD_SESSION` 표시 때문에 transcript 저장을 끔 (TUI 경고: `Transcript saving is off — inherited CLAUDE_CODE_CHILD_SESSION marker`) → `~/.claude/projects/<key>/<uuid>.jsonl` 이 생성되지 않아 status 의 RESUME 이 `MISSING`, `multi-agent-mux-resume` 불가 * 서버가 한 번 오염되면 이후 해당 서버에서 생성되는 모든 세션에 동일하게 적용됨 * **제안 해결책**: * 서버 기동 `Popen` 에 에이전트 런타임 표시 변수를 제거한 env 전달 (예: `env={k: v for k, v in os.environ.items() if k != "CLAUDECODE" and not k.startswith("CLAUDE_CODE_")}`) * 다른 에이전트 CLI(codex, agy 등)의 유사한 세션 표시 변수도 목록화하여 함께 제거 검토 * 또는 `create_session.sh` 의 spawn 단계에서 `env -u` 처리 추가 ### 2. read-only 스킬의 부수효과 * **위치**: `.agents/skills/multi-agent-mux-status/SKILL.md` 3행·16행 ("Read-only", "No mutation"), `status.sh` 10행에서 `lib.sh` source * **증상**: 서버가 꺼져 있을 때 status 조회만으로 herdr 서버 데몬이 기동됨 (1번 오염의 직접 계기) * **제안 해결책**: 조회 경로에서는 자동 기동을 건너뛰는 플래그(예: `MAM_NO_AUTOSTART=1`)로 `lib.sh` 를 source 하거나, 서버 미기동 시 `dead` 로만 보고 --- ## 현재 우회 방법 (Workaround) ```bash for v in $(env | grep -oE '^(CLAUDECODE|CLAUDE_CODE_[A-Za-z0-9_]*)=' | tr -d =); do unset "$v"; done # 이후 MAM 스크립트 실행. 이미 오염된 서버는 `herdr session stop <name>` 후 재기동 ``` ## 환경 정보 (Environment) * OS: macOS (Darwin 25.6.0) * MAM Version: `4d444ce` (main) * 실행 환경: Claude Code 세션을 오케스트레이터로 사용
Author
Owner

추가 사례 (How_To_Use_GENAI, MAM 4d444ce)

  • 읽기 전용으로 문서화된 status.sh를 실행한 바로 그 초에 herdr --session mam-genai server가 새로 떴습니다. 등록된 세션은 모두 stopped/dead 상태였습니다.
  • 작업이 끝난 뒤에도 서버와 빈 zsh pane이 계속 남아 있어 herdr --session mam-genai server stop으로 직접 정지했습니다.
  • 제안: 읽기 전용 명령(status.sh, reconcile.sh --dry-run)에서는 서버를 자동으로 띄우지 말고 "서버 없음"으로 보고하도록 분기 (자동 기동은 pane을 만드는 명령에서만 수행).
**추가 사례 (How_To_Use_GENAI, MAM 4d444ce)** - 읽기 전용으로 문서화된 `status.sh`를 실행한 바로 그 초에 `herdr --session mam-genai server`가 새로 떴습니다. 등록된 세션은 모두 stopped/dead 상태였습니다. - 작업이 끝난 뒤에도 서버와 빈 `zsh` pane이 계속 남아 있어 `herdr --session mam-genai server stop`으로 직접 정지했습니다. - 제안: 읽기 전용 명령(`status.sh`, `reconcile.sh --dry-run`)에서는 서버를 자동으로 띄우지 말고 "서버 없음"으로 보고하도록 분기 (자동 기동은 pane을 만드는 명령에서만 수행).
Author
Owner

브랜치 fix/issue-9-14 에서 해결 (main 4d444ce 기준, 병합 전).

수정 내용

  • lib.sh 쉼의 herdr --session <name> server 부트스트랩이 세션 식별 마커만 제거한 env 를 넘김: CLAUDECODE, CLAUDE_CODE_CHILD_SESSION, CLAUDE_CODE_SESSION_ID, CLAUDE_CODE_SESSION_ATTENDED, CLAUDE_CODE_ENTRYPOINT, CLAUDE_PID, CLAUDE_CODE_MESSAGING_TOKEN/_SOCKET, CLAUDE_CODE_BRIDGE_SESSION_ID, ANTIGRAVITY_CONVERSATION_ID, HERMES_SESSION_ID, GROK_SESSION_ID, OPENCODE_SESSION_ID. CLAUDE_PROJECT_DIR·CLAUDE_CONFIG_DIR 등 설정은 그대로 상속 (497633f)
  • MAM_NO_AUTOSTART=1: 쉼이 서버를 띄우지 않고 호출만 전달. status.sh·reconcile.sh 가 export 하므로 조회 경로는 더 이상 데몬을 기동하지 않음 (497633f)
  • 쉼 ls 가 서버 다운을 no server running 으로 보고해 reconcile.sh 의 herdr_confirmed 회귀를 방지. 실패한 호출의 구조화 오류 봉투 error.code == server_not_running 에만 적용하고 그 밖의 실패는 unknown 으로 전파 (7c40bf4, 952657e)

검증

  • tests/test_issue9_server_env.py 등 신규 테스트, 전체 스위트 819/819 통과
  • 실측: 오염된 multi-agent-mux 서버 재기동 후 새 서버 env 에 마커 없음, claude pane 의 "Transcript saving is off" 경고 소멸
  • 리뷰 루프 claude·agy·grok·codex 만장일치 PASS (.agents/reports/*/report-{2d3f24e4,47a845e0,d7e66053,0ad7cb06}.md)
  • v4.4.2 락스텝 반영 (0918917)

이미 부트스트랩된 서버는 재기동 전까지 오염된 env 를 유지하므로 herdr session stop <name> 후 create/resume 필요.

브랜치 `fix/issue-9-14` 에서 해결 (main `4d444ce` 기준, 병합 전). **수정 내용** - `lib.sh` 쉼의 `herdr --session <name> server` 부트스트랩이 세션 식별 마커만 제거한 env 를 넘김: `CLAUDECODE`, `CLAUDE_CODE_CHILD_SESSION`, `CLAUDE_CODE_SESSION_ID`, `CLAUDE_CODE_SESSION_ATTENDED`, `CLAUDE_CODE_ENTRYPOINT`, `CLAUDE_PID`, `CLAUDE_CODE_MESSAGING_TOKEN`/`_SOCKET`, `CLAUDE_CODE_BRIDGE_SESSION_ID`, `ANTIGRAVITY_CONVERSATION_ID`, `HERMES_SESSION_ID`, `GROK_SESSION_ID`, `OPENCODE_SESSION_ID`. `CLAUDE_PROJECT_DIR`·`CLAUDE_CONFIG_DIR` 등 설정은 그대로 상속 (`497633f`) - `MAM_NO_AUTOSTART=1`: 쉼이 서버를 띄우지 않고 호출만 전달. `status.sh`·`reconcile.sh` 가 export 하므로 조회 경로는 더 이상 데몬을 기동하지 않음 (`497633f`) - 쉼 `ls` 가 서버 다운을 `no server running` 으로 보고해 `reconcile.sh` 의 `herdr_confirmed` 회귀를 방지. 실패한 호출의 구조화 오류 봉투 `error.code == server_not_running` 에만 적용하고 그 밖의 실패는 unknown 으로 전파 (`7c40bf4`, `952657e`) **검증** - `tests/test_issue9_server_env.py` 등 신규 테스트, 전체 스위트 819/819 통과 - 실측: 오염된 `multi-agent-mux` 서버 재기동 후 새 서버 env 에 마커 없음, claude pane 의 "Transcript saving is off" 경고 소멸 - 리뷰 루프 claude·agy·grok·codex 만장일치 PASS (`.agents/reports/*/report-{2d3f24e4,47a845e0,d7e66053,0ad7cb06}.md`) - v4.4.2 락스텝 반영 (`0918917`) 이미 부트스트랩된 서버는 재기동 전까지 오염된 env 를 유지하므로 `herdr session stop <name>` 후 create/resume 필요.
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#9