Files
GodopuandClaude Fable 5.1 dcf2fab06e docs(design): archive the four design reviews of the worktree operating model
claude, agy, grok: PASS with amendments; codex: NOT PASS (recipe overstates
current env-override support; review identity and lifecycle ownership
underspecified). Direction (creator per worktree, shared reviewer pool)
agreed by all four.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
2026-09-14 11:14:07 +09:00

70 lines
6.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 🔍 Design Review — Job 2174eaaf (`worktree-creator-model.md` @ `fe96db1`)
- **Reviewer**: `reviewer-grok-01` · 2026-09-14
- **문서**: `multi-agent-mux-wt/design-worktree-model/docs/design/worktree-creator-model.md` (`git log -1` = `fe96db1`). 본 체크아웃은 `main`.
- **성격**: 설계 리뷰. 코드·문서 미수정, 체크아웃 미전환.
제안 C(creator=워크트리, 리뷰어 풀=본 체크아웃, `.mam` 공유)는 두 문제(병렬 구현, 공유 체크아웃 `checkout` 사고)를 **채택 가능한 수준으로** 풀며, §5 에 빠진 실패 경로를 보완하면 구현에 들어갈 수 있다.
## §6 질문
### 1. 역할 분리가 두 문제를 푸는가? — **동의 + 보완**
- **병렬성**: creator 가 이슈별 cwd/브랜치를 가지면 구현은 동시에 진행된다. 리뷰어 풀은 잡 단위 직렬(`session_busy` rc 5 → `MAM_SESSION_BUSY_RETRY_S` 1회, `runner.py:313-314`). 문서 §4 서술과 맞다.
- **checkout 사고**: 본 체크아웃을 `main` 에 고정하고 오케스트레이터·creator 커밋을 워크트리에서만 하면, 공유 `checkout` 한 방으로 전원이 움직이는 경로는 사라진다.
- **놓친 경로 (문서를 고칠 곳: §4 한계 / §5 추가)**:
- 리뷰어가 `$WT` 에서 pytest 를 돌리면 `.pytest_cache`/`__pycache__`/실패 산출물이 워크트리에 남아 creator 가 dirty 로 본다. PYTHONDONTWRITEBYTECODE, `--basetemp` 를 WT 밖, 리뷰 후 `git status` 제약을 §5 에 적을 것.
- 워크트리 삭제 전 `stop` 없이 `worktree remove` 하면 yaml 행·herdr pane 이 남는다. 레시피에 stop → worktree remove 순서.
- 모니터 **자동등록** (`reconcile.sh:651-654`) 은 `pane.cwd` 가 `WORKSPACE_ROOT` 또는 그 하위일 때만 탄다. WT 가 `.../multi-agent-mux-wt/issue-20` 이면 MAIN 의 prefix 가 아니므로 **미등록 herdr 세션은 자동등록되지 않는다**. yaml 에 이미 있는 행은 이 필터를 타지 않는다. “create 레시피로만 등록”을 §3 에 명시할 것. yaml 행을 drift 로 지우지는 않음(이름 매칭).
### 2. 제어 평면 env override 가 안전한가? — **동의 + 보완 (필수)**
| 변수 | 근거 | C 안에서 |
|---|---|---|
| `WORKSPACE_ROOT` | `lib.sh:26-27` 이미 override | MAIN 으로 두면 yaml/jobs 기본이 MAIN |
| `AGENT_SESSIONS_YAML` | `lib.sh:34` | 명시하면 안전. 미설정 시 `WORKSPACE_ROOT/.mam/...` |
| `MAM_JOBS_DIR` / `DELEGATE_JOB_LOGS_DIR` | `mqtt_common.py:150-163`, `186-187` — `MAM_JOBS_DIR` 우선, 아니면 `WORKSPACE_ROOT/.mam` | `WORKSPACE_ROOT=MAIN` 만으로도 jobs 는 MAIN. 문서의 네 변수는 과잉이 아니라 방어. |
- **status**: `status.sh:59-76` 이 **행의 `pane.cwd`** 로 claude 프로젝트 키를 만든다. WT cwd 행을 MAIN `WORKSPACE_ROOT` 와 혼동하지 않음. **동의.**
- **resume/stop**: `resume_session.sh:42,165` 은 `--workspace` 가 pane 생성 cwd. `verify_session_uuid` (`verify_session.py:90-93`) 는 `workspace_key(pane.cwd) != workspace_key(ws)` 이면 **즉시 False**. `find_workspace_uuid` (`workspace_uuid.py:57-59`) 도 pane.cwd 와 `--workspace` 일치만 본다. 따라서 resume/stop 의 `--workspace` 는 **MAIN 이 아니라 WT(pane.cwd)** 여야 한다. `WORKSPACE_ROOT`/yaml 은 MAIN. **§3 레시피에 이 이원성을 쓰지 않으면 resume 이 깨진다.** 고칠 곳: §3 코드블록 다음 문단.
- **claude 저장 키**: `claude.py:117-118` `workspace_key(ctx.workspace)` → `~/.claude/projects/<cwd 키>`. create `--workspace WT` 이면 키가 WT. resume 도 WT 를 넘겨야 한다. 문서 표(§1)와 맞음.
- **토픽 지문**: `reconcile.sh:288-290` `sha256(abspath(WORKSPACE_ROOT))[:12]`. 모니터·creator 가 같은 `WORKSPACE_ROOT=MAIN` 이면 지문이 하나. HMAC/`auth_token` 은 job 레코드 단위라 공유 레지스트리와 맞음. 워크트리에서 override 없이 reconcile 을 돌리면 지문이 갈라진다 → 모니터는 항상 MAIN 에서.
### 3. A/B 대비 C 비용·이득 — **동의**. 더 싼 1단계가 있다.
- A: 이슈당 에이전트 5개·문맥 리셋·`.mam` 분산. 비쌈. 동의.
- B: 병렬 없음 + creator 가 본 체크아웃을 옮김. #18 유형 잔존. 동의.
- C: 구현 병렬 + 리뷰 문맥 유지 + 제어 평면 하나. 맞다.
- **대안 D (비차단)**: 리뷰어에게도 **같은 브랜치의 읽기 전용 워크트리**를 주면 MAIN 테스트 오염을 줄인다. 비용↑. 1단계 C 로 시작하고 D 는 선택.
- **대안 E** (훅으로 main checkout 금지): 병렬을 안 줌. C 를 대체하지 못함.
### 4. §5 누락·과잉 / 다중 루프를 먼저? — **보완**
| §5 | 판정 |
|---|---|
| 1 브리프 절대경로 | **필수, 범위 부족.** `multi-agent-mux-delegate-job:199` 주입이 `.mam/jobs/<id>/brief.md` 상대경로. creator cwd=WT 에는 없음. 같은 파일 `:178` **Output Report Path** 도 상대경로. 루프 `find_report` (`runner.py:389-394`) 는 `self.mam_dir/jobs/<id>` = MAIN. creator 가 WT 에 리포트를 쓰면 루프가 못 찾는다. **brief 와 report-final.md 모두 `$REGISTRY_DIR` 절대경로.** |
| 2 `--worktree` | **필수.** `collect_changes_diff` `runner.py:399-408` 과 `base_commit` `runner.py:564-565` 가 `cwd=self.workspace_root`(MAIN HEAD). 워크트리 브랜치 diff 가 아님. 인용 정확. |
| 3 create 레시피 | **필수.** resume `--workspace $WT` 이원성 추가. |
| 4 `.mam` 경합 | **두 `run_loop.sh` 전에 필수, 1단계에는 과잉 가능.** `loop-checkpoint.json` (`runner.py:60`)·`loop-guard-active` (`:427`) 는 파일 하나. 두 루프는 체크포인트를 덮어쓴다. **시작은 “루프는 하나, creator 잡은 delegate-job 으로만 병렬”.** 이슈당 루프를 동시에 돌리려면 §5-4 가 선행. §4 문장에 이 단계를 밝힐 것. |
| 5 브리프 필드 | 필수. |
### 5. #17 항목 4 와의 순서 — **동의**
운영 모델(C)을 문서·레시피로 고정한 뒤, 항목 4(셸 계층 축소)에서 `--worktree`·절대 브리프/리포트 경로를 코드로 흡수하는 순서가 맞다. 항목 4 를 먼저 하면 워크트리 cwd 가 다시 깨진다.
## 브리프 (1)–(7) 요약
| # | 판정 |
|---|---|
| (1) env 일관성 | 동의. resume/stop `--workspace`=pane.cwd(WT). status 는 pane.cwd 사용. |
| (2) 상대 brief | 동의, 깨짐. 리포트 경로도 깨짐. |
| (3) diff/base | 동의, `runner.py:399-408`·`564-565`. |
| (4) 다중 루프 | 실위험. 1단계는 루프 하나. |
| (5) 실패 경로 | pytest 오염, yaml 잔행, 모니터 자동등록 prefix, 잘못된 WORKSPACE 로 resume. 토픽/HMAC 은 공유 `.mam` 이면 안전. |
| (6) A/B/C | 타당. D 는 후속. |
| (7) #17-4 | 문서 먼저. |
채택 가능. 근본 결함 없음. 구현 전 §3·§5-1·§5-4 문구를 고치면 된다.
[VERDICT: PASS]