격리 herdr 서버(multi-agent-mux)가 에이전트를 정지하지 않은 채 꺼진 뒤(재부팅 등) 다시 뜨면, herdr 가 저장해 둔 레이아웃을 복원하면서 에이전트를 herdr 자신의 재개 명령으로 다시 실행한다. MAM 의 등록부와 무관하게 일어나며, 결과가 두 가지다.
권한 플래그 없이 에이전트가 뜬다. herdr 의 재개 명령은 claude --resume <id>, grok --resume <id>, agy --conversation <id> 처럼 MAM 이 붙이는 --dangerously-skip-permissions / --permission-mode bypassPermissions 가 없다. 이대로 잡을 받으면 권한 확인 창에 멈춘다(#30 의 blocked).
MAM 이 지운 에이전트가 되살아난다. 서버가 꺼진 상태에서 지운 에이전트의 pane 은 저장 레이아웃에 남아 있어, 서버가 뜰 때 이미 지운 대화 ID 로 다시 실행된다.
여기에 MAM 쪽 동작이 겹쳐 상황이 가려진다.
resume_session.sh 는 복원된 에이전트를 보고 "already running" 으로 처리해, 실제 프로세스와 다른 자기 cmd_full 로 행을 running 으로 갱신하고 실행을 건너뛴다. 행과 실제 프로세스가 어긋난다.
복원되지 않은 에이전트(관측상 codex)는 재개가 다른 에이전트가 차지한 pane 을 쓰려다 실패하기도 한다(agent_pane_busy … is not an available shell).
복원된 에이전트가 herdr 이름 없이 뜨면 stop_session.sh 가 그 프로세스를 찾지 못한 채 행만 갱신하고 대화 파일을 지운다(프로세스는 계속 실행).
관측
2026-09-23 (herdr 업그레이드 뒤 서버 재시작): 재개를 시작하자 claude 두 개, grok, agy 가 플래그 없이 복원됐고 codex 는 복원되지 않아 재개가 agent_pane_busy 로 실패했다. 네 개를 정지하고 다시 재개해 바로잡았다.
2026-10-03 (재부팅, 에이전트 정지 없이): 서버가 꺼진 상태에서 오케스트레이터가 creator-claude-issue26 을 --purge-conversation 으로 지웠다. stop_session.sh 는 herdr already dead, just updating YAML 로 행과 대화 파일만 지웠다. 이어 재개가 서버를 띄우자:
13:05:09 WARN herdr::persist::restore: saved pane cwd does not exist, falling back to HOME cwd=…/multi-agent-mux-wt/issue-26
13:05:09 INFO session restore evaluated event="persist.restore" outcome="ok" workspaces=3
팀 리더 셋(claude 플래너, agy, grok)이 플래그 없이 복원됐다.
지운 creator 가 홈 디렉터리에서 삭제된 대화 ID 로claude --resume edda5fdc… 를 실행하고 "이 폴더를 신뢰하는가" 창에서 blocked 로 멈췄다. 워크트리는 이미 지워져 있었다.
재개는 셋에 대해 "already running" 을 냈고, codex 는 첫 재개가 실패했다.
원인
herdr 는 named session 의 레이아웃을 ~/.config/herdr/sessions/<name>/session.json 에 저장한다. pane 마다 cwd 와 agent_session(에이전트 종류, 대화 ID)이 들어 있고, 서버 기동 시 persist::restore 가 이를 되살린다.
MAM 이 서버가 떠 있을 때 정지하면 pane 이 닫혀 저장 레이아웃에서도 빠진다. 그래서 정상 정지 뒤에는 문제가 없다.
서버가 꺼진 상태에서는 MAM 이 저장 레이아웃을 건드릴 수 없다. 정지·삭제는 등록부와 대화 파일만 바꾸고, 다음 서버 기동 때 herdr 가 옛 pane 을 그대로 되살린다.
herdr 0.9.1 의 CLI 도움말과 설정에서 복원을 끄는 옵션은 찾지 못했다(확인 필요).
제안 — 코드로 강제
사람이 "재부팅 전에 정지하라"는 절차를 지키는 데 기대지 않는다. 재부팅은 예고 없이 일어난다.
서버 기동 직후 복원 결과를 등록부와 대조한다. MAM 이 격리 서버를 띄우는 모든 경로(lib.sh 의 headless bootstrap)에서, 기동 직후 herdr agent list·pane process-info 로 복원된 pane 을 읽어 등록부와 맞춘다.
등록부에 없거나 terminated·stopped 인 에이전트의 pane 은 닫는다(지운 에이전트가 되살아나지 않게).
등록부에 running 인데 실제 명령줄이 MAM 의 cmd_full(권한 플래그 포함)과 다르면, 그 pane 을 닫고 MAM 의 재개 경로로 다시 띄운다.
resume_session.sh 의 "already running" 판단에 명령줄 검증을 넣는다. 이름만 보고 실행 중이라 판단하지 말고, 실제 프로세스의 명령줄이 행의 cmd_full 과 같은지 확인한다. 다르면 위 1 과 같이 처리한다.
서버가 꺼진 상태의 정지·삭제가 저장 레이아웃을 남기지 않게 한다. 방법은 계획에서 정한다: herdr 가 복원을 끄는 수단을 제공하면 MAM 의 격리 서버에서 끈다 / 정지·삭제 시 서버를 복원 없이 잠깐 띄워 pane 을 닫는다 / 다음 기동 때 1 의 대조가 처리하게 둔다 등. session.json 을 직접 고치는 방식은 herdr 내부 형식에 기대므로 피한다.
이름 없이 뜬 에이전트도 정지 대상에 잡히게 한다. 등록부의 대화 ID 와 프로세스 명령줄로 찾는다.
테스트는 실제 herdr 0.9.1 서버로, 저장 레이아웃이 남은 상태에서 서버를 띄워 복원이 일어나는 경로를 그대로 재현해야 한다. 가짜 herdr 로 대체하면 이 문제를 잡지 못한다.
#21 워크트리 운영 모델 (지운 워크트리 경로의 pane 이 홈 디렉터리로 복원된 경우)
## 증상
격리 herdr 서버(`multi-agent-mux`)가 에이전트를 정지하지 않은 채 꺼진 뒤(재부팅 등) 다시 뜨면, herdr 가 저장해 둔 레이아웃을 복원하면서 에이전트를 **herdr 자신의 재개 명령으로** 다시 실행한다. MAM 의 등록부와 무관하게 일어나며, 결과가 두 가지다.
1. **권한 플래그 없이 에이전트가 뜬다.** herdr 의 재개 명령은 `claude --resume <id>`, `grok --resume <id>`, `agy --conversation <id>` 처럼 MAM 이 붙이는 `--dangerously-skip-permissions` / `--permission-mode bypassPermissions` 가 없다. 이대로 잡을 받으면 권한 확인 창에 멈춘다(#30 의 `blocked`).
2. **MAM 이 지운 에이전트가 되살아난다.** 서버가 꺼진 상태에서 지운 에이전트의 pane 은 저장 레이아웃에 남아 있어, 서버가 뜰 때 이미 지운 대화 ID 로 다시 실행된다.
여기에 MAM 쪽 동작이 겹쳐 상황이 가려진다.
- `resume_session.sh` 는 복원된 에이전트를 보고 "already running" 으로 처리해, 실제 프로세스와 다른 자기 `cmd_full` 로 행을 `running` 으로 갱신하고 실행을 건너뛴다. 행과 실제 프로세스가 어긋난다.
- 복원되지 않은 에이전트(관측상 codex)는 재개가 다른 에이전트가 차지한 pane 을 쓰려다 실패하기도 한다(`agent_pane_busy … is not an available shell`).
- 복원된 에이전트가 herdr 이름 없이 뜨면 `stop_session.sh` 가 그 프로세스를 찾지 못한 채 행만 갱신하고 대화 파일을 지운다(프로세스는 계속 실행).
## 관측
**2026-09-23** (herdr 업그레이드 뒤 서버 재시작): 재개를 시작하자 claude 두 개, grok, agy 가 플래그 없이 복원됐고 codex 는 복원되지 않아 재개가 `agent_pane_busy` 로 실패했다. 네 개를 정지하고 다시 재개해 바로잡았다.
**2026-10-03** (재부팅, 에이전트 정지 없이): 서버가 꺼진 상태에서 오케스트레이터가 `creator-claude-issue26` 을 `--purge-conversation` 으로 지웠다. `stop_session.sh` 는 `herdr already dead, just updating YAML` 로 행과 대화 파일만 지웠다. 이어 재개가 서버를 띄우자:
```
13:05:09 WARN herdr::persist::restore: saved pane cwd does not exist, falling back to HOME cwd=…/multi-agent-mux-wt/issue-26
13:05:09 INFO session restore evaluated event="persist.restore" outcome="ok" workspaces=3
```
- 팀 리더 셋(claude 플래너, agy, grok)이 플래그 없이 복원됐다.
- 지운 creator 가 홈 디렉터리에서 **삭제된 대화 ID 로** `claude --resume edda5fdc…` 를 실행하고 "이 폴더를 신뢰하는가" 창에서 `blocked` 로 멈췄다. 워크트리는 이미 지워져 있었다.
- 재개는 셋에 대해 "already running" 을 냈고, codex 는 첫 재개가 실패했다.
## 원인
- herdr 는 named session 의 레이아웃을 `~/.config/herdr/sessions/<name>/session.json` 에 저장한다. pane 마다 `cwd` 와 `agent_session`(에이전트 종류, 대화 ID)이 들어 있고, 서버 기동 시 `persist::restore` 가 이를 되살린다.
- MAM 이 서버가 떠 있을 때 정지하면 pane 이 닫혀 저장 레이아웃에서도 빠진다. 그래서 정상 정지 뒤에는 문제가 없다.
- 서버가 꺼진 상태에서는 MAM 이 저장 레이아웃을 건드릴 수 없다. 정지·삭제는 등록부와 대화 파일만 바꾸고, 다음 서버 기동 때 herdr 가 옛 pane 을 그대로 되살린다.
- herdr 0.9.1 의 CLI 도움말과 설정에서 복원을 끄는 옵션은 찾지 못했다(확인 필요).
## 제안 — 코드로 강제
사람이 "재부팅 전에 정지하라"는 절차를 지키는 데 기대지 않는다. 재부팅은 예고 없이 일어난다.
1. **서버 기동 직후 복원 결과를 등록부와 대조한다.** MAM 이 격리 서버를 띄우는 모든 경로(lib.sh 의 headless bootstrap)에서, 기동 직후 `herdr agent list`·`pane process-info` 로 복원된 pane 을 읽어 등록부와 맞춘다.
- 등록부에 없거나 `terminated`·`stopped` 인 에이전트의 pane 은 닫는다(지운 에이전트가 되살아나지 않게).
- 등록부에 `running` 인데 실제 명령줄이 MAM 의 `cmd_full`(권한 플래그 포함)과 다르면, 그 pane 을 닫고 MAM 의 재개 경로로 다시 띄운다.
2. **`resume_session.sh` 의 "already running" 판단에 명령줄 검증을 넣는다.** 이름만 보고 실행 중이라 판단하지 말고, 실제 프로세스의 명령줄이 행의 `cmd_full` 과 같은지 확인한다. 다르면 위 1 과 같이 처리한다.
3. **서버가 꺼진 상태의 정지·삭제가 저장 레이아웃을 남기지 않게 한다.** 방법은 계획에서 정한다: herdr 가 복원을 끄는 수단을 제공하면 MAM 의 격리 서버에서 끈다 / 정지·삭제 시 서버를 복원 없이 잠깐 띄워 pane 을 닫는다 / 다음 기동 때 1 의 대조가 처리하게 둔다 등. `session.json` 을 직접 고치는 방식은 herdr 내부 형식에 기대므로 피한다.
4. **이름 없이 뜬 에이전트도 정지 대상에 잡히게 한다.** 등록부의 대화 ID 와 프로세스 명령줄로 찾는다.
테스트는 실제 herdr 0.9.1 서버로, 저장 레이아웃이 남은 상태에서 서버를 띄워 복원이 일어나는 경로를 그대로 재현해야 한다. 가짜 herdr 로 대체하면 이 문제를 잡지 못한다.
## 관련
- #30 멈춘 에이전트 알림 (플래그 없이 복원된 에이전트가 권한 창에 멈추는 경우)
- #24 시작 다이얼로그 처리 (되살아난 에이전트가 신뢰 창에 멈춘 경우)
- #21 워크트리 운영 모델 (지운 워크트리 경로의 pane 이 홈 디렉터리로 복원된 경우)
A: MAM 이 격리 herdr 서버를 띄울 때 사용자 herdr 설정에 [session] resume_agents_on_restore = false 만 더한 설정을 HERDR_CONFIG_PATH 로 넘긴다. 서버가 재기동돼도 저장된 에이전트를 권한 플래그 없이 다시 띄우지 않는다.
B: 복원된 pane 은 빈 셸로 돌아오는데, resume 이 기동 직전에 자기 세션의 그 빈 셸만 닫는다.
주의: 설정 병합에는 PATH 의 python3 에 tomllib(3.11+)이 필요하다. macOS 기본 3.9 에서는 복원은 꺼지지만 MAM 서버가 사용자의 다른 herdr 설정 없이 뜬다(경고 표시). 사용자가 직접 attach 해 띄운 서버는 복원이 켜진 채 남으므로, 재부팅 뒤에는 attach 전에 /multi-agent-mux-resume 을 먼저 실행한다.
범위 밖으로 남은 제안: 2(resume 의 "already running" 판단에 명령줄 검증), 4(이름 없이 뜬 에이전트 정지). 필요하면 새 이슈로 다룬다. 리뷰 경과는 PR #48 코멘트에 있습니다.
PR #48(v4.8.5, 7209750)로 닫힙니다. 합의한 범위 A+B:
- **A**: MAM 이 격리 herdr 서버를 띄울 때 사용자 herdr 설정에 `[session] resume_agents_on_restore = false` 만 더한 설정을 `HERDR_CONFIG_PATH` 로 넘긴다. 서버가 재기동돼도 저장된 에이전트를 권한 플래그 없이 다시 띄우지 않는다.
- **B**: 복원된 pane 은 빈 셸로 돌아오는데, resume 이 기동 직전에 자기 세션의 그 빈 셸만 닫는다.
주의: 설정 병합에는 PATH 의 `python3` 에 `tomllib`(3.11+)이 필요하다. macOS 기본 3.9 에서는 복원은 꺼지지만 MAM 서버가 사용자의 다른 herdr 설정 없이 뜬다(경고 표시). 사용자가 직접 attach 해 띄운 서버는 복원이 켜진 채 남으므로, 재부팅 뒤에는 attach 전에 `/multi-agent-mux-resume` 을 먼저 실행한다.
범위 밖으로 남은 제안: 2(resume 의 "already running" 판단에 명령줄 검증), 4(이름 없이 뜬 에이전트 정지). 필요하면 새 이슈로 다룬다. 리뷰 경과는 PR #48 코멘트에 있습니다.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
증상
격리 herdr 서버(
multi-agent-mux)가 에이전트를 정지하지 않은 채 꺼진 뒤(재부팅 등) 다시 뜨면, herdr 가 저장해 둔 레이아웃을 복원하면서 에이전트를 herdr 자신의 재개 명령으로 다시 실행한다. MAM 의 등록부와 무관하게 일어나며, 결과가 두 가지다.claude --resume <id>,grok --resume <id>,agy --conversation <id>처럼 MAM 이 붙이는--dangerously-skip-permissions/--permission-mode bypassPermissions가 없다. 이대로 잡을 받으면 권한 확인 창에 멈춘다(#30 의blocked).여기에 MAM 쪽 동작이 겹쳐 상황이 가려진다.
resume_session.sh는 복원된 에이전트를 보고 "already running" 으로 처리해, 실제 프로세스와 다른 자기cmd_full로 행을running으로 갱신하고 실행을 건너뛴다. 행과 실제 프로세스가 어긋난다.agent_pane_busy … is not an available shell).stop_session.sh가 그 프로세스를 찾지 못한 채 행만 갱신하고 대화 파일을 지운다(프로세스는 계속 실행).관측
2026-09-23 (herdr 업그레이드 뒤 서버 재시작): 재개를 시작하자 claude 두 개, grok, agy 가 플래그 없이 복원됐고 codex 는 복원되지 않아 재개가
agent_pane_busy로 실패했다. 네 개를 정지하고 다시 재개해 바로잡았다.2026-10-03 (재부팅, 에이전트 정지 없이): 서버가 꺼진 상태에서 오케스트레이터가
creator-claude-issue26을--purge-conversation으로 지웠다.stop_session.sh는herdr already dead, just updating YAML로 행과 대화 파일만 지웠다. 이어 재개가 서버를 띄우자:claude --resume edda5fdc…를 실행하고 "이 폴더를 신뢰하는가" 창에서blocked로 멈췄다. 워크트리는 이미 지워져 있었다.원인
~/.config/herdr/sessions/<name>/session.json에 저장한다. pane 마다cwd와agent_session(에이전트 종류, 대화 ID)이 들어 있고, 서버 기동 시persist::restore가 이를 되살린다.제안 — 코드로 강제
사람이 "재부팅 전에 정지하라"는 절차를 지키는 데 기대지 않는다. 재부팅은 예고 없이 일어난다.
herdr agent list·pane process-info로 복원된 pane 을 읽어 등록부와 맞춘다.terminated·stopped인 에이전트의 pane 은 닫는다(지운 에이전트가 되살아나지 않게).running인데 실제 명령줄이 MAM 의cmd_full(권한 플래그 포함)과 다르면, 그 pane 을 닫고 MAM 의 재개 경로로 다시 띄운다.resume_session.sh의 "already running" 판단에 명령줄 검증을 넣는다. 이름만 보고 실행 중이라 판단하지 말고, 실제 프로세스의 명령줄이 행의cmd_full과 같은지 확인한다. 다르면 위 1 과 같이 처리한다.session.json을 직접 고치는 방식은 herdr 내부 형식에 기대므로 피한다.테스트는 실제 herdr 0.9.1 서버로, 저장 레이아웃이 남은 상태에서 서버를 띄워 복원이 일어나는 경로를 그대로 재현해야 한다. 가짜 herdr 로 대체하면 이 문제를 잡지 못한다.
관련
PR #48(v4.8.5,
7209750)로 닫힙니다. 합의한 범위 A+B:[session] resume_agents_on_restore = false만 더한 설정을HERDR_CONFIG_PATH로 넘긴다. 서버가 재기동돼도 저장된 에이전트를 권한 플래그 없이 다시 띄우지 않는다.주의: 설정 병합에는 PATH 의
python3에tomllib(3.11+)이 필요하다. macOS 기본 3.9 에서는 복원은 꺼지지만 MAM 서버가 사용자의 다른 herdr 설정 없이 뜬다(경고 표시). 사용자가 직접 attach 해 띄운 서버는 복원이 켜진 채 남으므로, 재부팅 뒤에는 attach 전에/multi-agent-mux-resume을 먼저 실행한다.범위 밖으로 남은 제안: 2(resume 의 "already running" 판단에 명령줄 검증), 4(이름 없이 뜬 에이전트 정지). 필요하면 새 이슈로 다룬다. 리뷰 경과는 PR #48 코멘트에 있습니다.
#45 의 범위 밖 제안 2·4 는 #49 로 옮겼습니다(서비스 차원의 훅이 생길 때까지 보류, herdr 이벤트 확인을 첫 단계로).