From b61c8b177a111f14e4da38d8283e4545c5db2dfc Mon Sep 17 00:00:00 2001 From: Godopu Date: Mon, 14 Sep 2026 03:34:48 +0000 Subject: [PATCH] docs(issue-21): correct the worktree design doc - partial support, phase-1 review-only flow, compatibility matrix Fixes the sentences the four design reviews flagged and records what phase 1 actually implements: status line, monitor-topic scope, option A's isolation and capacity wording, creator/reviewer ownership (tests write; promotion is the control root's), the control-plane binding persisted and forwarded, two loop recipes ((a) the loop implements, (b) the base recorded before an out-of-loop implementation, then --base --review-only; no base in --task), the loop lock as a refusal, "phase 1 = parallel implementation, one review loop", the eight Issue #21 items with their status, and a new section 7 with root definitions and a per-skill compatibility table. The review files are unchanged. The loop SKILL.md lock note names the lock branch instead of line numbers that moved. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_017R3Eg7MEpSWnm1oB9ZPP6G --- .agents/skills/multi-agent-mux-loop/SKILL.md | 2 +- docs/design/worktree-creator-model.md | 91 ++++++++++++++------ 2 files changed, 67 insertions(+), 26 deletions(-) diff --git a/.agents/skills/multi-agent-mux-loop/SKILL.md b/.agents/skills/multi-agent-mux-loop/SKILL.md index 3fd113e..66bae18 100644 --- a/.agents/skills/multi-agent-mux-loop/SKILL.md +++ b/.agents/skills/multi-agent-mux-loop/SKILL.md @@ -247,5 +247,5 @@ bash .agents/skills/multi-agent-mux-loop/scripts/run_loop.sh \ - **Incorrect Verdict format (앵커링 파서 하드닝)**: 리뷰 리포트 파일 내에서 `[VERDICT: PASS]` 또는 `[VERDICT: NOT PASS]` 토큰은 반드시 리포트의 **마지막에 단독 행**으로 기재되어야 합니다. 코드 인용이나 변경 diff 내에 등장하는 토큰은 매칭 대상에서 완전 배제됩니다. - **Fail-closed on missing verdict**: 최종 Verdict 토큰이 누락되거나 리포트 픽업에 실패하면, 파서는 **경고 후 통과시키는 것이 아니라** 안전을 위해 즉시 `NOT PASS`로 판정(fail-closed)하고 교정 사이클을 수행합니다. 리뷰어에게는 반드시 리포트 끝에 단독 행으로 토큰을 찍도록 지시해야 합니다. - **Session Availability**: `run_loop.sh` 기동 전에 참조되는 Planner, Target Agent, Reviewer 세션들이 모두 herdr 세션으로 기동되어 (`status.sh` 기준 `alive` 및 `running`) 있어야 합니다. -- **동시 루프 기동 금지 (NFS Lock Shadowing)**: 동일한 작업 트리 내에서 다수의 `run_loop.sh` 제어기를 동시에 기동하면 SQLite DB 갱신 경합 및 YAML 데이터 오염이 발생합니다. 하나의 루프가 끝날 때까지 다른 루프를 병렬로 기동하지 마십시오. (실제로는 loop lock 이 두 번째 루프를 exit 1 로 거부한다 — run_loop.sh:189-203) +- **동시 루프 기동 금지 (NFS Lock Shadowing)**: 동일한 작업 트리 내에서 다수의 `run_loop.sh` 제어기를 동시에 기동하면 SQLite DB 갱신 경합 및 YAML 데이터 오염이 발생합니다. 하나의 루프가 끝날 때까지 다른 루프를 병렬로 기동하지 마십시오. (실제로는 loop lock 이 두 번째 루프를 exit 1 로 거부한다 — run_loop.sh 의 `mam_acquire_loop_lock` 분기) - **원자적 아카이빙 (Promotion)**: 루프 성공 종료 시 최종 계획서와 검증 리포트들은 `.agents/reports//` 디렉토리로 원자적으로 덮어쓰기(`mv -f`)되어 보존됩니다. 해당 경로의 리포트들로 VCS 추적성을 확보해야 합니다. diff --git a/docs/design/worktree-creator-model.md b/docs/design/worktree-creator-model.md index aaf4749..ab123ff 100644 --- a/docs/design/worktree-creator-model.md +++ b/docs/design/worktree-creator-model.md @@ -1,6 +1,6 @@ # 워크트리 운영 모델 제안 — creator 만 워크트리, 리뷰어는 공유 (Design Proposal) -- 상태: 제안 (리뷰 요청) +- 상태: 리뷰 반영(4건, docs/design/reviews/) — 1단계 선행 작업 구현(Issue #21 항목 1·2·3·6) - 작성: 오케스트레이터 세션 `dbe6dd10-a210-4b46-b613-58a1860499b6`, 2026-09-14 - 배경 이슈: #17 항목 4(셸 계층 축소)·#18 사후 분석(체크아웃 전환 사고) @@ -13,7 +13,7 @@ MAM 은 **워크스페이스 = `.agents/skills` 가 들어 있는 체크아웃 | `WORKSPACE_ROOT` | `lib.sh:26` — `${WORKSPACE_ROOT:-$SKILL_DIR/../..}` | | `.mam/` (agent-sessions.yaml, jobs 레지스트리, 감사 로그, monitor.lock) | `$WORKSPACE_ROOT/.mam` (gitignore 대상) | | herdr 서버 이름 | `resolve_herdr_session` — 워크스페이스 경로 슬러그, `--herdr-session` 으로 override | -| 모니터 토픽 지문 | `reconcile.sh:288-290` — `sha256(abspath(workspace_root))[:12]` | +| 모니터 토픽 지문 | `reconcile.sh:288-290` — `sha256(abspath(workspace_root))[:12]`. 모니터 구독에만 쓰인다. 잡 토픽은 레코드의 topic_prefix `python/mqtt/jobs/`(mqtt_common.py:137, :351), HMAC 은 레코드의 auth_token 이다 | | claude 대화 저장 키 | `~/.claude/projects/` — resume 는 같은 디렉터리여야 함 | 그 결과 두 가지 문제가 있다. @@ -24,63 +24,104 @@ MAM 은 **워크스페이스 = `.agents/skills` 가 들어 있는 체크아웃 ## 2. 후보안 ### A. 모두 워크트리별 (오케스트레이터 + creator + 리뷰어) -- 장점: 완전 격리. 현재 코드가 그대로 동작한다(워크트리 = 새 워크스페이스). -- 단점: 이슈마다 에이전트 5개를 새로 띄운다 → 토큰·요청 한도가 이슈 수에 비례(codex 는 이번 세션에서 이미 한도 도달). 리뷰어 대화 문맥이 이슈마다 초기화된다. `.mam`·모니터·토픽 지문이 이슈마다 흩어져 관측이 분산된다. +- 장점: 런타임 분리가 가장 강하다(단 git 워크트리는 refs·객체 저장소를 공유하고, `.venv`·캐시·자격증명·브로커도 공유 자원이다). 워크트리 준비·수명 처리는 별도로 필요하다. +- 단점: 이슈마다 에이전트를 새로 띄운다. 용량 추정: 이슈당 5개 에이전트는 운영 정책이고, 토큰 사용은 살아 있는 세션 수가 아니라 실제 작업량에 비례한다. 리뷰어 대화 문맥이 이슈마다 초기화된다. `.mam`·모니터·토픽 지문이 이슈마다 흩어져 관측이 분산된다. ### B. 오케스트레이터 커밋만 워크트리, 에이전트는 본 체크아웃 - 장점: 오케스트레이터 커밋은 격리된다. - 단점: **병렬성이 없다.** 에이전트는 대화 하나짜리 프로세스라 잡을 하나씩만 처리하고, 두 루프가 같은 creator·리뷰어를 두고 `session_busy`(rc 5) 로 경합해 직렬화된다. creator 는 여전히 본 체크아웃에서 브랜치를 옮겨 커밋해야 하므로 #18 사고 유형이 그대로 남는다. 리뷰어가 검증하는 트리가 브랜치 트리가 아니다. ### C. (제안) creator 만 워크트리, 리뷰어 풀은 공유, 제어 평면은 하나 -- **creator = 워크트리 전용 인스턴스.** 편집·커밋하는 유일한 에이전트이므로 cwd 가 곧 이슈 브랜치여야 한다. 이슈마다 `creator--` 로 만들고 끝나면 정지(대화 보존, 필요 시 재개). -- **리뷰어 풀 = 본 체크아웃 공유.** 읽기 전용. 브리프가 워크트리 경로·base·head 를 명시하고 리뷰어는 그 경로에서 `git diff ...` 와 테스트를 실행한다. 리뷰가 병목이면 리뷰어 인스턴스를 추가한다. +- **creator = 워크트리 전용 인스턴스.** 제품 코드를 편집·커밋하는 유일한 에이전트이므로 cwd 가 곧 이슈 브랜치여야 한다. 오케스트레이터 커밋과 루프의 리포트 승격(`runner.py` 의 Promotion 블록 → 제어 루트 `.agents/reports/`)은 별도 소유다. 이슈마다 `creator--` 로 만들고 끝나면 정지(대화 보존, 필요 시 재개). 재개하려면 같은 워크트리 경로가 있어야 한다(대화 키가 cwd). +- **리뷰어 풀 = 본 체크아웃 공유.** 리뷰어는 소스를 편집하지 않는다. 그러나 테스트 실행은 쓰기를 동반하므로 '읽기 전용'이 아니다. 검증 격리(head SHA detached 워크트리 또는 격리 옵션)와 (loop_id, base, head) 판정 결속은 항목 5 에서 정한다. 1단계 브리프는 러너가 경로·base·head·커밋 수를 자동 삽입한다(`--worktree`/`--base`). 리뷰가 병목이면 리뷰어 인스턴스를 추가한다. - **오케스트레이터 커밋 = 워크트리.** 본 체크아웃은 리뷰어의 작업 공간이므로 오케스트레이터는 그곳에서 브랜치를 바꾸지 않는다. -- **제어 평면 = 본 체크아웃의 `.mam` 하나.** 워크트리에서 creator 를 만들 때 `WORKSPACE_ROOT`·`AGENT_SESSIONS_YAML`·`MAM_JOBS_DIR`·`DELEGATE_JOB_LOGS_DIR` 를 본 체크아웃으로 넘기면 같은 yaml 에 등록되고(행의 `pane.cwd` 는 워크트리), 잡 레지스트리·토픽 지문·모니터가 한 곳에 모인다. +- **제어 평면 = 본 체크아웃의 `.mam` 하나.** create/resume 이 바인딩(`WORKSPACE_ROOT`·`AGENT_SESSIONS_YAML`·`MAM_JOBS_DIR`·`DELEGATE_JOB_LOGS_DIR`)을 행(`control_plane`)에 영속하고, `--workspace` 기본값과 다르면 pane 에 명시 전파한다(항목 3). 호출자 env 만으로는 pane 상속이 보장되지 않는다(lib.sh:667-680 — new-session 은 선행 `K=V` 토큰만 `--env` 로 바꾼다). 행의 `pane.cwd` 는 워크트리다. -## 3. C 안의 동작 방식 (현재 코드 기준) +## 3. C 안의 동작 방식 (부분 지원 + 1단계 수정 반영) ```bash -MAIN=/path/to/multi-agent-mux # 본 체크아웃: 리뷰어 풀 + .mam -WT=/path/to/multi-agent-mux-wt/issue-20 # 이슈 워크트리 +MAIN=/path/to/multi-agent-mux # 본 체크아웃: 리뷰어 풀 + .mam (제어 루트) +WT=/path/to/multi-agent-mux-wt/issue-20 # 이슈 워크트리 (소스 루트) git -C "$MAIN" worktree add -b fix/issue-20 "$WT" main -ln -s "$MAIN/.venv" "$WT/.venv"; git -C "$WT" submodule update --init # 워크트리 준비(.venv, nats-docker) +ln -s "$MAIN/.venv" "$WT/.venv"; git -C "$WT" submodule update --init # 워크트리 준비(.venv, nats-docker) — 헬퍼는 항목 4 -# creator 를 워크트리 cwd 로, 그러나 본 체크아웃의 .mam 에 등록 +# creator 를 워크트리 cwd 로, 그러나 본 체크아웃의 .mam 에 등록. +# 바인딩은 행의 control_plane 에 남고, --workspace 기본값과 다르므로 pane 에 --env 로 전파된다. WORKSPACE_ROOT="$MAIN" AGENT_SESSIONS_YAML="$MAIN/.mam/agent-sessions.yaml" \ MAM_JOBS_DIR="$MAIN/.mam/jobs" DELEGATE_JOB_LOGS_DIR="$MAIN/.mam/delegate_job_logs" \ bash "$MAIN/.agents/skills/multi-agent-mux-create/scripts/create_session.sh" \ --workspace "$WT" --agent claude --role Creator --session creator-claude-issue20 \ --herdr-session multi-agent-mux --herdr-workspace mam-agent -# 루프는 본 체크아웃에서, creator 이름만 워크트리용으로 +# (a) 루프가 구현까지 한다: base 는 Phase 2 시작 시점의 워크트리 HEAD cd "$MAIN" && bash .agents/skills/multi-agent-mux-loop/scripts/run_loop.sh \ - --creator creator-claude-issue20 --all-reviewer \ - --task "[이슈 #20 @ $WT, branch fix/issue-20, base ] ... 리뷰어는 $WT 에서 git diff ...HEAD 와 pytest 를 실행하라 ..." + --worktree "$WT" --creator creator-claude-issue20 --all-reviewer --task "Issue #20 ..." + +# (b) 구현은 루프 밖(1단계 기본): base 를 구현 위임 **전에** 기록한다 +BASE=$(git -C "$WT" rev-parse HEAD) +bash "$MAIN/.agents/skills/multi-agent-mux-delegate-job/multi-agent-mux-delegate-job" submit --type direct \ + --agent claude --agent-session herdr:creator-claude-issue20 --workdir "$MAIN" --prompt "Issue #20 ..." +# ... creator 가 $WT 에서 구현·커밋 ... +cd "$MAIN" && bash .agents/skills/multi-agent-mux-loop/scripts/run_loop.sh \ + --worktree "$WT" --base "$BASE" --review-only --creator creator-claude-issue20 --all-reviewer --task "Issue #20 review" + +# 정지·재개: --workspace 는 원래 워크트리 경로. 재개는 행에 영속된 바인딩을 다시 전파한다 +bash "$MAIN/.agents/skills/multi-agent-mux-stop/scripts/stop_session.sh" --session creator-claude-issue20 +bash "$MAIN/.agents/skills/multi-agent-mux-resume/scripts/resume_session.sh" \ + --workspace "$WT" --agent claude --session creator-claude-issue20 ``` -- 브리프 규약: 첫 줄에 `워크트리 경로 / 브랜치 / base sha` 를 적고, 리뷰어에게 "그 경로에서 검증"을 명시한다. 잡 브리프 파일(`.mam/jobs//brief.md`)은 본 체크아웃에 있으므로 creator 는 `$MAIN/.mam/jobs//brief.md` 를 읽는다(주입 문구의 상대경로 `.mam/jobs/...` 는 creator cwd 기준으로는 존재하지 않는다 → **주입 문구를 절대경로로 바꾸는 작은 변경이 필요**). -- 루프 러너의 `base_commit`/diff 수집(`runner.py:399-401`)은 `workspace_root`(본 체크아웃) 기준이다. C 안에서는 워크트리 경로를 기준으로 diff 를 모아야 하므로 **`--worktree ` 옵션(또는 `MAM_LOOP_WORKTREE` env)이 필요**하다. +- `--task` 에 base 를 적지 말 것. 러너가 넣는 base 와 둘이 된다. 리뷰어가 받는 base 는 러너의 `[워크트리 컨텍스트]` 블록 하나뿐이어야 한다. +- 모니터(`reconcile.sh`)는 본 체크아웃에서만 띄운다. +- 브리프·발행 명령(`--registry-dir`, 감사 로그 루트 `DELEGATE_JOB_LOGS_DIR`)·Output Report Path 를 제어 평면 절대경로로 바꿨다(항목 1). creator 는 워크트리 cwd 에서 주입된 명령을 그대로 실행하면 된다. +- 루프 러너 `--worktree` 가 추가됐다: diff·base·head 만 소스 루트 기준이고, wrapper·레지스트리·체크포인트·승격은 제어 루트다. `--worktree`/`--base` 가 있으면 빈 변경분(또는 판정 불가)에 리뷰를 요청하지 않는다(fail-closed). `--base` 는 소스 HEAD 의 조상이어야 하고 env 폴백이 없다. - 오케스트레이터 커밋 규칙: 커밋 전 `git branch --show-current` 확인(메모리 규칙), 본 체크아웃에서는 `main` 유지. ## 4. 기대 효과와 한계 - 병렬화 이득은 **구현 단계**에서 크다: 워크트리마다 creator 가 동시에 작업하고, 전체 스위트도 워크트리마다 동시에 돈다. - **리뷰 단계는 풀 크기만큼만 병렬**이다. 이슈 3개를 동시에 돌려도 리뷰어 하나는 잡을 순서대로 처리한다(래퍼는 busy 세션에 rc 5 → 러너가 `MAM_SESSION_BUSY_RETRY_S` 뒤 1회 재시도 → 그래도 busy 면 실패). 다중 루프 동시 기동에는 **리뷰어 큐잉 또는 리뷰어 인스턴스 증설**이 전제다. -- 루프 SKILL.md 의 "동시 루프 기동 금지(NFS lock shadowing)" 는 **같은 `.mam` 을 쓰는 루프**에 대한 경고다. C 안은 `.mam` 을 공유하므로, 다중 루프 동시 기동 전에 이 제약(체크포인트 파일·SQLite 갱신 경합)을 해소해야 한다. -- 워크트리 준비 비용(.venv 링크, 서브모듈, `.mam.env` 복사)은 스크립트 한 줄로 흡수 가능하다. +- 같은 `.mam` 의 두 번째 루프는 경고가 아니라 **거부**다: loop lock 이 exit 1 로 막는다(`run_loop.sh` 의 `mam_acquire_loop_lock` 분기). 체크포인트·loop guard 도 파일 하나다(`runner.py` 의 `checkpoint_file`, `MAM_LOOP_MARKER`). YAML/SQLite 는 flock·`BEGIN IMMEDIATE` 로 트랜잭션 안전(atomic_yaml.py)하므로, 문제는 DB 손상이 아니라 **공유 논리 상태와 리뷰어 소유권**이다. +- **1단계 운영 형태 = 구현 병렬, 리뷰 루프 하나**: creator 구현은 루프 밖(delegate-job direct)에서 워크트리마다 병렬로 한다. 리뷰는 `run_loop.sh --worktree --base <구현 전 sha> --review-only` 로 한 번에 하나씩 한다. base 를 구현 위임 **전에** 기록하지 않으면 리뷰를 시작할 수 없다(가드가 빈 변경분을 거부한다). busy 처리는 큐가 아니다(1회 재시도). 다중 루프는 항목 8(리뷰어 스케줄러) 이후다. +- 준비 헬퍼는 항목 4 다. `.mam.env` 는 복사 대신 중앙 `MAM_ENV_FILE` 정책으로 하고, `.venv` 심링크는 gitignore 되지 않으므로 `.git/info/exclude` 로 처리한다. -## 5. 필요한 변경 (작업 항목) +## 5. 필요한 변경 (Issue #21 작업 항목) -1. 주입 문구·브리프의 잡 경로를 절대경로로(`$REGISTRY_DIR//brief.md`). -2. 루프 러너에 `--worktree ` (diff 수집·`base_commit`·리뷰 브리프의 경로 자동 삽입). -3. `create_session.sh` 문서에 "제어 평면 override" 레시피 추가(`WORKSPACE_ROOT`/`AGENT_SESSIONS_YAML`/`MAM_JOBS_DIR`/`DELEGATE_JOB_LOGS_DIR`), 워크트리 준비 헬퍼(`scripts/worktree_prepare.sh`). -4. 다중 루프 동시 기동 시 `.mam` 경합 해소(체크포인트 파일 이름에 루프 id 포함, 리뷰어 busy 시 대기 큐). -5. 리뷰어 브리프 템플릿에 워크트리 경로·base·head 필드 고정. +| # | 항목 | 상태 | +|---|---|---| +| 1 | 래퍼 주입 문구·시작 명령(`--registry-dir`, 감사 로그 루트)·Output Report Path 절대경로화, `MAM_JOBS_DIR` 존중 | 이 브랜치 | +| 2 | 루프 러너 `--worktree` / `--base` / `--review-only`, 빈 변경분 fail-closed 가드, 러너의 `MAM_JOBS_DIR` 존중 | 이 브랜치 | +| 3 | 제어 평면 바인딩 영속(`control_plane`)·명시 전파(create/resume), stop·status·reconcile 의 `MAM_JOBS_DIR`·행 바인딩 존중 | 이 브랜치 | +| 4 | 워크트리 준비·해체 헬퍼, resume 을 원래 cwd 로만 허용, create 의 reconcile/watchdog 기동 위치, `MAM_NO_SUBSCRIBER_DAEMON` 기본화, reconcile 의 루트 밖 cwd 재발견 거부(#17-4 셸 축소와 함께) | 대기 | +| 5 | 리뷰 identity: (loop_id, base_sha, head_sha) 판정 기록·무효화, 리뷰어 검증 격리(detached 워크트리) | 대기 | +| 6 | 이 설계 문서 정정 | 이 브랜치 | +| 7 | 수용 사례 고정(실제 herdr 의 pane env 전파 포함) | 대기 | +| 8 | 다중 루프 네임스페이스·리뷰어 스케줄러 | 보류 | ## 6. 리뷰어에게 묻는 것 +답변: docs/design/reviews/ 4건, 종합은 Issue #21. + 1. C 안의 역할 분리(쓰는 쪽만 격리, 읽는 쪽 공유)가 두 문제(병렬성, 체크아웃 전환 사고)를 실제로 해소하는가? 놓친 경로가 있는가(예: 리뷰어가 테스트 중 파일을 만드는 경우, 모니터 reconcile 이 워크트리 cwd 행을 어떻게 다루는지). 2. 제어 평면 공유(env override)가 현재 코드에서 안전한가? 특히 `pane.cwd` 가 워크트리인 행을 status/monitor/stop/resume 스킬이 올바르게 처리하는가. 3. A/B 안 대비 C 안의 비용·이득 평가에 동의하는가? 다른 대안이 있는가? 4. §5 작업 항목의 누락·과잉. 특히 다중 루프 동시 기동의 `.mam` 경합을 먼저 풀어야 하는지, 아니면 "루프는 하나씩, 구현만 병렬" 로 시작해도 되는지. 5. #17 항목 4(셸 계층 축소)와의 순서: 이 모델을 먼저 문서·레시피로 굳히고 항목 4 에서 코드로 흡수하는 순서가 맞는가. + +## 7. 루트 정의와 스킬별 호환성 + +- **제어 루트**: `.mam` 을 가진 본 체크아웃. 레지스트리·감사 로그·세션 yaml·체크포인트·loop guard·리포트 승격이 여기 있다. +- **소스 루트**: 이슈 워크트리. creator 의 cwd, 루프의 diff·base·head 대상. +- **런타임 코드 루트**: 실제로 실행되는 `.agents/skills` 사본. 루프는 제어 루트의 사본을 실행하며, 워크트리의 미검토 `diff_collect.sh` 를 실행하지 않는다. + +| 스킬 | 제어 평면 바인딩 | 워크트리 cwd 행 | 1단계 이후 남은 제한 (항목) | +|---|---|---|---| +| create | env 에서 결정 → 행 `control_plane` 에 항상 영속. `--workspace` 기본값과 다르면 pane 에 전파(새 pane 은 `--env`, 재사용 idle pane 은 `env K=V`). 전파가 필요한데 경로에 공백이 있으면 exit 2. `~/.local/bin` wrapper 경로는 기록만 하고 경고 | pane.cwd = `--workspace` | create 가 `$WORKSPACE` 사본으로 reconcile/watchdog 기동, `MAM_NO_SUBSCRIBER_DAEMON` 미기본 (4) | +| resume | 행 바인딩 우선(호출자 env 와 다르면 stderr 경고) 재전파. 바인딩 없는 기존 행은 호출자 바인딩으로 채움 | `--workspace` 는 원래 워크트리 경로여야 함 | 워크트리 삭제 시 재개 불가, 종료 헬퍼 (4) | +| stop | `MAM_JOBS_DIR` > 행의 `mam_jobs_dir` > `$WORKSPACE_ROOT/.mam/jobs` 순으로 잡 조회·발행 | 행 cwd 로 uuid 캡처·purge | 해체 순서 헬퍼 (4) | +| status | `MAM_JOBS_DIR`·행 `mam_jobs_dir`·감사 로그(`DELEGATE_JOB_LOGS_DIR`·행 `delegate_job_logs_dir`)·기존 후보 순 조회 | 행 cwd 로 대화 키 | — | +| monitor/reconcile | `MAM_JOBS_DIR` 우선(정적 가드로만 검증) | 기존 행은 행 cwd 로 검증 | 루트 밖 cwd 의 미등록 세션은 자동 등록 안 됨 → create 로만 등록 (4) | +| delegate-job | `--registry-dir` > `MAM_JOBS_DIR` > `.mam/jobs`(`--workdir` 기준), 모두 절대화. 발행 명령이 감사 로그 루트(`DELEGATE_JOB_LOGS_DIR`)를 고정 | 문구·명령·리포트 경로 절대 | 작은따옴표가 든 경로는 지원 범위 밖 | +| loop | `MAM_JOBS_DIR` 존중, 래퍼에 `--registry-dir` 명시. `--worktree` 로 소스 루트 분리 | diff·base·head 만 소스 루트. **구현이 루프 밖이면 `--base <구현 전 sha> --review-only` 필수**. `--worktree`/`--base` 가 있으면 빈 변경분 거부 | 루프 하나(8), 리뷰 identity·검증 격리(5), 레거시 셸 루프(`MAM_LOOP_PY=0`)는 새 옵션 거부 | + +실제 herdr 가 `pane split --env` / `workspace create --env` 로 pane 환경을 넘기는지는 1단계에서 mock 수준으로만 검증했다. 실제 전파는 항목 7 의 수용 사례로 고정한다.