feat(issue-21): 워크트리 운영 모델 2단계 — 워크트리 헬퍼, 리뷰 identity, 수용 사례, #20 테스트 격리, #27 #29

Manually merged
Godopu merged 0 commits from feat/issue-21-items-4-5-7 into main 2026-09-21 14:54:27 +00:00
Owner

개요

Refs #21 — 워크트리 운영 모델 2단계(작업 항목 4·5·7). 항목 8(다중 루프)은 보류로 남아 이슈는 열어 둔다.
Closes #20. Closes #27.

main(1134d74) 위 20커밋: #21 2단계 15커밋 + #20(단계 C, 항목 7 시험 운영) 5커밋.

변경 사항

범위 커밋 내용
#27 fadd38c deploy 관리 블록이 .venv 를 파일·디렉터리·링크 모두로 무시
항목 4 + 권고 ①② 2679ddf resume 은 원래 cwd 에서만, 이미 실행 중 경로에서도 제어 평면 바인딩 영속화, 워크트리 바인딩 계산 실패는 exit 2
항목 4 657b4b7 7988db9 worktree_prepare.sh / worktree_remove.sh(서브모듈 opt-in, 변경 전 판정, 서브모듈 워크트리는 검증된 단일 --force), 문서·호환성 표
항목 4 리뷰 bbbbb95 c7c559b 25f4be3 제거 헬퍼의 데이터 유실 사례 R1–R6(종료 중 쓰기, 서브모듈 stash, 부분 init 롤백, 기존 파일, deinit 저장소, tag 로만 보존한 커밋)
권고 ③ 4ad622e T2-6 의 env 변경을 monkeypatch 로 격리
항목 5 e57663a c01a119 a21986e 리뷰 identity: 라운드별 snapshot·diff, --review-isolation(detached 리뷰 워크트리), stale 라운드 재리뷰, 증거가 붙은 identity 기록, 승격 직전 재확인, 원격 리뷰어 거부/diff-only(--remote-review), dirty 서브모듈 거부
권고 ⑤ 7bc3e1a 371099a e6d2168 acceptance5 가 공용 브로커 지연에 흔들리지 않게
항목 7 b1e313b 수용 사례 A1–A8 테스트 (tests/test_issue21_acceptance.py)
#20 + 권고 ④ 3433ffd 7bd695c c5844a8 a2be70d 46ea4cc 수집 전에 ambient 제어 평면 바인딩을 기록·제거하고 테스트마다 레지스트리·감사 로그 기본 루트를 tmp 로, 기록된 제어 평면의 .mam/jobs·.mam/delegate_job_logs 세션 가드, issue15 누수 검사는 자기 잡 id 만 판정, issue14 헬퍼 감사 로그를 tmp_path 로, 회귀 테스트

리뷰 (multi-agent-mux-loop)

  • 루프 A (claude·agy·codex, grok 은 한도 임박으로 정지): 3회차 claude·agy PASS, codex R6 NOT PASS → R6 후속 루프(codex 단독) PASS.
  • 루프 B: 1회차 codex 지적 B-R1–B-R4 → a21986e·b1e313b 로 반영. 2·3회차 claude·agy PASS. codex 는 사용 한도로 재리뷰 job 이 시작되지 못함(agent_blocked) → codex 가 남긴 재현 테스트 4건이 HEAD 에서 모두 통과함을 확인해 대체.
  • 단계 C (#20, 워크트리 모델 시험 운영): claude·agy·opencode(신규 리뷰어) 1회차 만장일치 PASS. 세 판정의 identity 기록이 모두 같은 loop_id, base b1e313b, head 46ea4cc 에 묶였다(항목 5 실동작).

항목 7 시험 운영 — 실제 herdr 확인

  • A1 기존 herdr 서버 위 형제 워크트리 + 워크트리 creator 생성(worktree_prepare.sh --creator-agent claude).
  • A2 creator pane 프로세스 env 에 바인딩 4개(WORKSPACE_ROOT, AGENT_SESSIONS_YAML, MAM_JOBS_DIR, DELEGATE_JOB_LOGS_DIR)가 본 체크아웃을 가리키도록 전달됨.
  • A6 다른 경로로 resume → exit 2(안내 메시지), 원래 워크트리 경로로 resume → 같은 대화(claude -r <id>)로 성공, 바인딩 재전파.
  • 시험 운영에서 드러난 상호작용: 워크트리 creator pane 은 제어 평면 변수를 명시적으로 받으므로, 그 pane 에서 돈 테스트는 본 체크아웃 .mam 에 쓸 수 있었다. #20 수정이 이 조건을 다룬다.
  • 정리: worktree_remove.sh --stop 이 모든 검사를 통과하고 plain 제거.

테스트

  • b1e313b 전체: 974 passed / 33 failed — base 1134d74 기준 실패 집합과 동일(신규 0).
  • 46ea4cc, creator pane 과 같은 조건(바인딩 4개가 본 체크아웃): 980 passed / 33 failed / 2 skipped, 실제 .mam/jobs·.mam/delegate_job_logs 새 항목 0(787 → 787).
    • 실패 구성 차이: test_send_keys_safe_is_confirmed_by_the_job_started_event 추가(HEAD·base 모두 간헐), test_t1_4_broker_unavailable_fail_closed 해소(실제 .mam.env 를 더 이상 읽지 않음, #28 일부).
  • 이 호스트의 기준 실패 33건은 #28.

알려진 사항 / 후속 후보

  • 버전 bump 미포함(병합 시 처리).
  • 생존 판정의 알려진 한계(#18 의 의도된 절충): heartbeat 타이머는 에이전트 프로세스에 묶여 있어 죽은 에이전트는 K×N 뒤 닫히지만, 살아 있지만 멈춘 에이전트(권한 확인 창 blocked, 종료 이벤트 없는 턴 종료)는 job 제한 시간으로만 감지된다. 단계 C 에서 creator 가 권한 확인 창에 멈춘 사례를 사용자가 먼저 발견했다(planner 의 idle 은 백그라운드 테스트 대기로 정상). 알림 수준 개선을 #30 으로 등록했다.
  • herdr 격리 세션 pane env 에 MAM_VERSION=4.5.0 이 남아 있다(서버 기동 시점 env). 경미.
  • 리뷰어 비차단 권고: A4 의 status 비교가 untracked .agents/·.mam/ 변화를 보지 못함, A4 가 info/exclude 추가를 선반영, remove 실패 시 prune 이 전역, 서브모듈 거부 시 중복 출력.
  • codex·grok 은 사용 한도로 정지(대화 보존, resume 가능). opencode 리뷰어를 새로 추가했다.

🤖 Generated with Claude Code

https://claude.ai/code/session_01PfoijjCS2U6TQPFuxAE5Pn

## 개요 Refs #21 — 워크트리 운영 모델 **2단계**(작업 항목 4·5·7). 항목 8(다중 루프)은 보류로 남아 이슈는 열어 둔다. Closes #20. Closes #27. `main`(`1134d74`) 위 20커밋: #21 2단계 15커밋 + #20(단계 C, 항목 7 시험 운영) 5커밋. ## 변경 사항 | 범위 | 커밋 | 내용 | |---|---|---| | #27 | `fadd38c` | deploy 관리 블록이 `.venv` 를 파일·디렉터리·링크 모두로 무시 | | 항목 4 + 권고 ①② | `2679ddf` | resume 은 원래 cwd 에서만, 이미 실행 중 경로에서도 제어 평면 바인딩 영속화, 워크트리 바인딩 계산 실패는 exit 2 | | 항목 4 | `657b4b7` `7988db9` | `worktree_prepare.sh` / `worktree_remove.sh`(서브모듈 opt-in, 변경 전 판정, 서브모듈 워크트리는 검증된 단일 `--force`), 문서·호환성 표 | | 항목 4 리뷰 | `bbbbb95` `c7c559b` `25f4be3` | 제거 헬퍼의 데이터 유실 사례 R1–R6(종료 중 쓰기, 서브모듈 stash, 부분 init 롤백, 기존 파일, deinit 저장소, tag 로만 보존한 커밋) | | 권고 ③ | `4ad622e` | T2-6 의 env 변경을 monkeypatch 로 격리 | | 항목 5 | `e57663a` `c01a119` `a21986e` | 리뷰 identity: 라운드별 snapshot·diff, `--review-isolation`(detached 리뷰 워크트리), stale 라운드 재리뷰, 증거가 붙은 identity 기록, 승격 직전 재확인, 원격 리뷰어 거부/diff-only(`--remote-review`), dirty 서브모듈 거부 | | 권고 ⑤ | `7bc3e1a` `371099a` `e6d2168` | acceptance5 가 공용 브로커 지연에 흔들리지 않게 | | 항목 7 | `b1e313b` | 수용 사례 A1–A8 테스트 (`tests/test_issue21_acceptance.py`) | | #20 + 권고 ④ | `3433ffd` `7bd695c` `c5844a8` `a2be70d` `46ea4cc` | 수집 전에 ambient 제어 평면 바인딩을 기록·제거하고 테스트마다 레지스트리·감사 로그 기본 루트를 tmp 로, 기록된 제어 평면의 `.mam/jobs`·`.mam/delegate_job_logs` 세션 가드, issue15 누수 검사는 자기 잡 id 만 판정, issue14 헬퍼 감사 로그를 tmp_path 로, 회귀 테스트 | ## 리뷰 (multi-agent-mux-loop) - **루프 A** (claude·agy·codex, grok 은 한도 임박으로 정지): 3회차 claude·agy PASS, codex R6 NOT PASS → R6 후속 루프(codex 단독) **PASS**. - **루프 B**: 1회차 codex 지적 B-R1–B-R4 → `a21986e`·`b1e313b` 로 반영. 2·3회차 claude·agy **PASS**. codex 는 사용 한도로 재리뷰 job 이 시작되지 못함(`agent_blocked`) → codex 가 남긴 재현 테스트 4건이 HEAD 에서 모두 통과함을 확인해 대체. - **단계 C** (#20, 워크트리 모델 시험 운영): claude·agy·opencode(신규 리뷰어) 1회차 **만장일치 PASS**. 세 판정의 identity 기록이 모두 같은 `loop_id`, base `b1e313b`, head `46ea4cc` 에 묶였다(항목 5 실동작). ## 항목 7 시험 운영 — 실제 herdr 확인 - **A1** 기존 herdr 서버 위 형제 워크트리 + 워크트리 creator 생성(`worktree_prepare.sh --creator-agent claude`). - **A2** creator pane 프로세스 env 에 바인딩 4개(`WORKSPACE_ROOT`, `AGENT_SESSIONS_YAML`, `MAM_JOBS_DIR`, `DELEGATE_JOB_LOGS_DIR`)가 본 체크아웃을 가리키도록 전달됨. - **A6** 다른 경로로 resume → exit 2(안내 메시지), 원래 워크트리 경로로 resume → 같은 대화(`claude -r <id>`)로 성공, 바인딩 재전파. - 시험 운영에서 드러난 상호작용: 워크트리 creator pane 은 제어 평면 변수를 **명시적으로** 받으므로, 그 pane 에서 돈 테스트는 본 체크아웃 `.mam` 에 쓸 수 있었다. #20 수정이 이 조건을 다룬다. - 정리: `worktree_remove.sh --stop` 이 모든 검사를 통과하고 plain 제거. ## 테스트 - `b1e313b` 전체: **974 passed / 33 failed** — base `1134d74` 기준 실패 집합과 동일(신규 0). - `46ea4cc`, creator pane 과 같은 조건(바인딩 4개가 본 체크아웃): **980 passed / 33 failed / 2 skipped**, 실제 `.mam/jobs`·`.mam/delegate_job_logs` **새 항목 0**(787 → 787). - 실패 구성 차이: `test_send_keys_safe_is_confirmed_by_the_job_started_event` 추가(HEAD·base 모두 간헐), `test_t1_4_broker_unavailable_fail_closed` 해소(실제 `.mam.env` 를 더 이상 읽지 않음, #28 일부). - 이 호스트의 기준 실패 33건은 #28. ## 알려진 사항 / 후속 후보 - 버전 bump 미포함(병합 시 처리). - 생존 판정의 알려진 한계(#18 의 의도된 절충): heartbeat 타이머는 에이전트 **프로세스**에 묶여 있어 죽은 에이전트는 K×N 뒤 닫히지만, 살아 있지만 멈춘 에이전트(권한 확인 창 `blocked`, 종료 이벤트 없는 턴 종료)는 job 제한 시간으로만 감지된다. 단계 C 에서 creator 가 권한 확인 창에 멈춘 사례를 사용자가 먼저 발견했다(planner 의 idle 은 백그라운드 테스트 대기로 정상). 알림 수준 개선을 #30 으로 등록했다. - herdr 격리 세션 pane env 에 `MAM_VERSION=4.5.0` 이 남아 있다(서버 기동 시점 env). 경미. - 리뷰어 비차단 권고: A4 의 status 비교가 untracked `.agents/`·`.mam/` 변화를 보지 못함, A4 가 `info/exclude` 추가를 선반영, remove 실패 시 prune 이 전역, 서브모듈 거부 시 중복 출력. - codex·grok 은 사용 한도로 정지(대화 보존, resume 가능). opencode 리뷰어를 새로 추가했다. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01PfoijjCS2U6TQPFuxAE5Pn
Author
Owner

병합 완료 — main 6fc9194 (v4.7.0, --no-ff)

리뷰 경과 (병합 워크스페이스, PR head 를 detached 워크트리에 받아 4인 독립 검토)

  • 1회차 @46ea4cc: claude·agy·grok PASS, codex NOT PASS — R1 status.showUntrackedFiles=no 로 숨긴 서브모듈 untracked 파일이 worktree_remove.sh 의 force 제거를 통과, R2 같은 결함으로 리뷰 스냅샷 가드가 미포착 내용을 승인, R3 worktree_prepare.sh 가 여전히 .venv 심링크.
  • 정정 08db1da: 세 검사(lib_py/worktree.py, worktree_remove.sh, runner._dirty_submodules)에 --untracked-files=all; prepare 는 제어 루트 인터프리터로 워크트리 자체 venv 생성(링크 거부). 각 회귀는 수정 없이는 실패함을 확인.
  • 델타 리뷰 @08db1da: claude·agy·grok PASS(비차단 D1–D3). codex 는 루프의 프롬프트 주입이 전달되지 않아(잡 14c7dc38) 직접 재위임 → @80a5614 PASS.
  • 후속 80a5614: pip 설치 실패 시 반쯤 만든 venv 제거(D1), 프롬프트의 미커밋 표시도 --untracked-files=all(D3), prepare 가 delegate-job 스킬의 requirements.txt(paho) 까지 설치.
  • 릴리스 cf5d114: 4.6.0 → 4.7.0 락스텝, 리포트 8건 .agents/reports/<session>/ 아카이브.

테스트: #28 의 33건은 삭제 없이 환경 의존성 제거로 처리(7a94ba2). 전체 스위트 @46ea4cc 1013 통과/1 skip/1 실패(벽시계 flake → 90a289d); @08db1da 자체 venv 없는 워크트리에서 1015 통과/4 실패 — 4건 모두 system python(paho 없음) 탓이며 워크트리 venv 에서 통과.

Closes #20, #27. #21 은 항목 8 로 열어 둠, #28 은 Linux 확인 요청 후 닫음.

## 병합 완료 — main `6fc9194` (v4.7.0, `--no-ff`) **리뷰 경과 (병합 워크스페이스, PR head 를 detached 워크트리에 받아 4인 독립 검토)** - 1회차 @46ea4cc: claude·agy·grok PASS, codex NOT PASS — R1 `status.showUntrackedFiles=no` 로 숨긴 서브모듈 untracked 파일이 `worktree_remove.sh` 의 force 제거를 통과, R2 같은 결함으로 리뷰 스냅샷 가드가 미포착 내용을 승인, R3 `worktree_prepare.sh` 가 여전히 `.venv` 심링크. - 정정 `08db1da`: 세 검사(`lib_py/worktree.py`, `worktree_remove.sh`, `runner._dirty_submodules`)에 `--untracked-files=all`; prepare 는 제어 루트 인터프리터로 워크트리 자체 venv 생성(링크 거부). 각 회귀는 수정 없이는 실패함을 확인. - 델타 리뷰 @08db1da: claude·agy·grok PASS(비차단 D1–D3). codex 는 루프의 프롬프트 주입이 전달되지 않아(잡 14c7dc38) 직접 재위임 → @80a5614 PASS. - 후속 `80a5614`: pip 설치 실패 시 반쯤 만든 venv 제거(D1), 프롬프트의 미커밋 표시도 `--untracked-files=all`(D3), prepare 가 delegate-job 스킬의 `requirements.txt`(paho) 까지 설치. - 릴리스 `cf5d114`: 4.6.0 → 4.7.0 락스텝, 리포트 8건 `.agents/reports/<session>/` 아카이브. **테스트**: #28 의 33건은 삭제 없이 환경 의존성 제거로 처리(`7a94ba2`). 전체 스위트 @46ea4cc 1013 통과/1 skip/1 실패(벽시계 flake → `90a289d`); @08db1da 자체 venv 없는 워크트리에서 1015 통과/4 실패 — 4건 모두 system python(paho 없음) 탓이며 워크트리 venv 에서 통과. Closes #20, #27. #21 은 항목 8 로 열어 둠, #28 은 Linux 확인 요청 후 닫음.
Godopu closed this pull request 2026-09-20 12:51:21 +00:00
Godopu deleted branch feat/issue-21-items-4-5-7 2026-09-20 12:51:21 +00:00
Godopu reopened this pull request 2026-09-20 12:51:47 +00:00
Godopu force-pushed feat/issue-21-items-4-5-7 from cf5d1142e9 to 80a5614f7c 2026-09-20 12:53:07 +00:00 Compare
Godopu closed this pull request 2026-09-20 15:05:43 +00:00
Godopu reopened this pull request 2026-09-21 02:09:44 +00:00
Godopu force-pushed feat/issue-21-items-4-5-7 from f7f85ff67f to cf5d1142e9 2026-09-21 02:19:35 +00:00 Compare
Godopu manually merged commit 6fc9194f89 into main 2026-09-21 14:54:27 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: tmpl/multi-agent-mux#29