# Code Review: MAM 세션 생성 · UUID 추출 · 4단계 무결성 검증 아키텍처 (v4 계획 반영 구현)

## Scope
이 diff는 이전 라운드(`03ae0809`가 리뷰한 구현)에서 발견된 치명적 결함(resume dry-run과 reconcile.sh 자신의 트랜잭션 간 SQLite 락 경합)과 그에 대한 Planner v4 계획(`95be74e1`)을 반영한 재구현이다. 6개 파일 변경:
- `.agents/skills/lib.sh` (`ea863c0..f8193e7`): 이전 라운드와 동일(`mode` 파라미터, `verify_tui_viewport` 등 — 변경 없음, blob 동일)
- `.agents/skills/multi-agent-mux-create/scripts/create_session.sh`: 이전 라운드와 동일
- `.agents/skills/multi-agent-mux-monitor/SKILL.md`: 이전 라운드와 동일
- `.agents/skills/multi-agent-mux-monitor/scripts/reconcile.sh` (`76be78c..3fa1325`, **신규 blob**): `_pin_and_verify_resume()` 공통 헬퍼로 `rc==0`/`rc==2` 중복 제거, `--dry-run`이 "어떤 분기로도 쓰기 없음을 보장"한다는 문서 주석/도움말 추가
- `.agents/skills/multi-agent-mux-resume/scripts/resume_session.sh` (`76716ab..e8ce867`, **신규 blob**): 2단계("herdr 이미 생존") 분기에 `DRY_RUN` 게이트 추가, `--help` 텍스트 갱신
- `.agents/skills/multi-agent-mux-resume/scripts/update_yaml_resumed.sh`: 이전 라운드와 동일

모든 파일의 워킹 트리 blob 해시가 diff 헤더와 정확히 일치함을 확인. 6개 파일 전부 `bash -n` 통과. `git status --short` — 추적 파일 변경은 이 6개뿐, `stop_session.sh`는 계획대로(다음 라운드 항목) 손대지 않음.

## 핵심 검증: 데드락 결함이 실제로 해소되었는가

이전 라운드(`03ae0809`)에서 지적한 문제는: `resume_session.sh`의 "herdr 이미 생존" 분기가 `--dry-run`으로 게이트되지 않아 `update_yaml_resumed.sh`를 통해 실제 쓰기를 수행했고, 이 서브프로세스가 `reconcile.sh` 자신이 이미 배타 락을 쥔 `atomic_dump_yaml` 트랜잭션 내부에서 호출되어 자기 자신과 락 경합을 일으켰다는 것이었다.

이번 diff에서 해당 분기를 직접 읽고 확인했다:
```bash
if herdr has-session -t "$SESSION_NAME" 2>/dev/null; then
  if [ "${DRY_RUN:-0}" = "1" ]; then
    echo "[dry-run] herdr '$SESSION_NAME' already running — nothing to validate"
    exit 0
  fi
  echo "herdr '$SESSION_NAME' already running."
  bash ".../update_yaml_resumed.sh" --session "$SESSION_NAME" --uuid "$UUID" --agent "$AGENT"
  exit 0
fi
```
`DRY_RUN=1`일 때 `update_yaml_resumed.sh` 호출에 도달하지 않고 즉시 `exit 0`함을 확인했다.

**추가로, dry-run 게이트 이전에 실행되는 모든 코드 경로가 실제로 쓰기가 없는지 직접 추적 검증했다** (이전 라운드에서 지적되지 않았던 부분까지 포함):
- 1단계 `resolve_session_id.sh` → `find_workspace_uuid()` — `env_python` 기반 순수 읽기, 락 없음. 확인.
- `resolve_herdr_workspace()` — `load_state_json()`(읽기 전용) + 순수 `python3 -c` 조회, 쓰기 없음. 확인.

즉 `resume_session.sh --dry-run`이 게이트 지점 이전까지 포함해 **어떤 코드 경로로도 실제 쓰기를 수행하지 않음**을 확인했다 — 데드락의 근본 원인이 완전히 제거되었다.

## 이전 라운드 발견 사항 반영 여부 확인

| 발견 | 상태 |
|---|---|
| 1 (치명적). resume dry-run 락 경합/데드락 | ✅ **완전히 해소 확인** — 위 상세 검증 참조 |
| 2 (경미). `rc==0`/`rc==2` 코드 중복 | ✅ **해소 확인** — `_pin_and_verify_resume(s, agent, cwd, uuid, degraded)` 공통 헬퍼로 추출, 4개 에이전트 × 2개 분기(8곳)의 중복 코드가 제거되고 `degraded` 플래그 하나로 `'C'`/`'C-degraded'` 드리프트 클래스만 분기됨. `id_name`(session vs conversation 어휘) 매핑도 원본 각 에이전트별 문구를 정확히 보존(`claude`/`cline` → "session id", `agy`/`hermes` → "conversation id") |

## 부가 확인: 문서/일관성
- `reconcile.sh` 상단 주석과 `--help` 출력에 `--dry-run`이 "어떤 분기로도 디스크/DB 쓰기가 발생하지 않음을 보장"한다는 문구가 추가됨 — v4 계획의 "dry-run류 플래그의 쓰기 없음 보장 계약을 문서화" 항목과 일치.
- `resume_session.sh`의 `--help`에도 "Safe to execute inside active write transactions."라는 문구가 추가되어, 이번에 고친 정확한 시나리오(트랜잭션 내부에서 안전하게 호출 가능)를 명시적으로 문서화함 — 계획에서 요구한 수준을 상회하는 좋은 보강.
- `_pin_and_verify_resume`는 여전히 `resume_session.sh --dry-run`을 `reconcile.sh`의 `atomic_dump_yaml` 트랜잭션 내부에서 서브프로세스로 호출하는 구조를 유지한다(2-패스 재설계는 채택되지 않음, v4 계획의 결정과 일치) — 이제 그 호출이 안전함을 위에서 확인했으므로 이 구조 유지는 타당하다.

## 검증 통과 항목 (정상)
- 6개 파일 모두 문법 통과, blob 해시 diff와 정확히 일치.
- `stop_session.sh`는 계획대로 이번 라운드 범위 밖으로 유지(새 문제 아님).
- 다른 무관한 파일 변경 없음(`git status --short` 확인, 미추적 `.tmp`/`.DS_Store`는 job-runner/OS 산출물).
- 이전 라운드까지 누적된 모든 발견 사항(하드코딩 nvm 경로, TUI 뷰포트 3분기, agy mode 구분, SKILL.md 문서 불일치, dead code, 데드락, 코드 중복)이 이번 라운드까지 전부 해소됨을 확인.

## 결론
이전 라운드에서 지적된 치명적 데드락 결함이 정확히 계획대로, 그리고 계획이 요구한 범위보다 더 철저하게(게이트 이전 경로까지 직접 추적 검증) 해소되었다. 경미했던 코드 중복 지적도 깔끔한 헬퍼 추출로 해결되었다. 이번 diff에는 새로운 결함을 발견하지 못했다. `stop_session.sh` 리팩터링만 계획대로 다음 라운드 과제로 남아있다.

[VERDICT: PASS]
