24 KiB
구현 계획서 Rev.2 — Job 7e5d9f2d
- Job ID: 7e5d9f2d (원 계획서:
f3b10c00) - Role: Planner (claude)
- 입력: Worker Challenge
48a9416f(agy,[VERDICT: PASS WITH CHALLENGE]) - Output:
.mam/jobs/7e5d9f2d/claude-reports/report-final.md - 첨부:
proposed/probe_new_session.sh— new-session 호출 패턴 하네스 (Rev.1 에서 이월)proposed/probe_layout_policy.sh— 신규. 이의제기의 전제 5가지를 격리 herdr 세션에서 실측하는 하네스
0. 이의제기 판정 요약
이의제기를 주장별로 분리해서 각각 실측했다. 라이브 herdr 세션은 건드리지 않고 격리 세션(mam-probe-*)을 띄워
측정 후 session stop + session delete 로 정리했다(라이브 워크스페이스 3페인 불변 확인).
| 이의제기 항목 | 판정 | 근거 |
|---|---|---|
[맹점 1-a] --split right 반복으로 인한 패널 폭 고갈 |
✅ 채택 (수치 정정 후) | 실측으로 재현. 4페인 시 폭 14/14/13/27 col 까지 붕괴 |
| [맹점 1-b] 종료된 유휴 패널 재활용 불가 → 고아 패널 증식 | ❌ 반박 | herdr 이 프로세스 종료 시 페인을 자동 삭제함(실측). kill-session 도 이미 pane close 수행. 그리고 agent start 에는 --pane 이 없어 재할당 자체가 불가능 |
[제약 1] mock_herdr 의 save_state() flock 필요 |
⚠️ 이미 구현됨 — 단, 이의제기가 놓친 다른 결함을 발견 | conftest.py:90-91 이 이미 fcntl.flock(LOCK_EX) 취득. 실제 위험은 agents 딕셔너리 통째 덮어쓰기(l.121) |
이의제기의 핵심 지적(1-a)은 옳고, 원 계획서의 실질적 결함이었다. 다만 근거 수치와 제안 해법은 둘 다 정정이 필요하다. 그리고 이의제기가 놓친 더 중요한 메커니즘을 하나 찾았다 — §2.2 의 "앵커가 전진하지 않는다".
1. 이의제기에 대한 실측 (신규 측정분)
재현 명령 (자체 정리 포함, 라이브 세션 무영향):
bash .mam/jobs/7e5d9f2d/claude-reports/proposed/probe_layout_policy.sh
1.1 프로덕션 현 상태 — 이의제기가 옳다
$ herdr pane layout # 라이브 workspace wM
area {height: 78, width: 184}
wM:p4 62 x 78 (agy)
wM:p3 61 x 78 (cline)
wM:p2 61 x 78 (claude)
splits: right(0.668) → right(0.5) ← 수평 분할 체인
이미 수평 분할 체인 구조이며, 에이전트당 61 col 이다. 이의제기가 지적한 구조가 실재한다.
단, 이의제기의 산술은 정정한다:
| 이의제기 | 실측 |
|---|---|
"터미널 폭 140col" |
184 col. create_session.sh 의 -x 140 -y 40 은 shim 이 -x|-y) shift 2 로 버린다(lib.sh:238). herdr 이 실제 터미널 크기를 쓴다 |
| "최소 렌더링 필요 폭 40~80 col" | 미검증 값. 반면 61 col 에서 3개 에이전트가 현재 정상 동작 중이라는 것은 검증된 사실이다 |
따라서 임계점은 이의제기가 시사한 N=3 이 아니라 N=4 (46 col) ~ N=5 (37 col) 구간이다. 계획서는 이 임계값을 하드코딩하지 않고 환경변수로 노출하며, 기본값은 "현재 동작이 확인된 값"에서 취한다.
1.2 4페인 붕괴 직접 재현
격리 세션(area 54×23, 헤드리스 기본 크기)에서 agent start 3회:
area {height: 23, width: 54}
w1:p1 14 x 12 ← 3번 연속 분할당한 페인
w1:p4 14 x 11
w1:p3 13 x 23
w1:p2 27 x 23
splits: right(0.5) → right(0.5) → down(0.5)
폭 13~14 col. 이의제기의 우려는 추측이 아니라 재현 가능한 현상이다.
1.3 [이의제기가 놓친 부분] 분할 앵커가 전진하지 않는다
위 레이아웃을 보면 w1:p1 이 세 번 모두 분할 대상이 되었다(54→27→14 폭, 그 뒤 23→12 행).
w1:p2(27 col)는 한 번도 분할되지 않았다. 원인:
agent start --split <dir>의 분할 앵커는focused_pane_id다 (실측: 포커스가w1:p1에 고정된 채 모든 분할이 p1 에 누적).- MAM 은
--no-focus를 쓰므로 포커스가 새 페인으로 이동하지 않는다 → 앵커가 영원히 제자리.
즉 실제 열화는 이의제기가 말한 "균등한 N분할(184/N)"보다 더 나쁜 기하급수 분할(184/2^N) 이다.
그리고 이 사실은 해법에도 영향을 준다: agent start 로는 앵커를 고를 수 없고 방향만 고를 수 있다.
(agent start 에 --pane 없음 — Rev.1 §2.1 실측. pane focus 는 방향 기반뿐, 임의 pane_id 지정 불가.)
1.4 [맹점 1-b 반박 근거] 종료된 페인은 herdr 이 자동으로 닫는다
임시 페인 생성: w1:p5
pane run w1:p5 "exit" → 3초 후 pane list: ['w1:p1','w1:p4','w1:p3','w1:p2','w2:p1']
→ w1:p5 없음 (herdr 이 자동 정리함)
추가로 MAM 자체 경로에서도 누적되지 않는다:
lib.sh:390-404kill-session은agent get으로pane_id를 얻어pane close를 이미 수행한다.- 라이브 워크스페이스는 여러 차례 stop/start 를 거쳤음에도(LOG.md 세션 상태표) 에이전트 3개에 페인 정확히 3개다. 잔여 페인 0.
즉 "고아/유휴 페인 증식"의 발생 경로가 존재하지 않는다.
1.5 [맹점 1-b 반박 근거] 유휴 페인 재할당은 has-session 을 깨뜨린다
이의제기의 권고("유휴 패널의 pane_id 를 대상으로 에이전트를 재할당")를 실행할 수 있는 유일한 경로는
pane split + pane run 이다(agent start 에 --pane 이 없으므로). 그 결과를 측정했다:
pane run w1:p6 "sleep 300"
$ herdr agent get w1:p6
{"error":{"code":"agent_not_found","message":"agent target w1:p6 not found"}}
$ herdr agent list → 등록된 agent: ['probeC','probeB','probeA'] # p6 없음
pane run 으로 띄운 프로세스는 agent 로 등록되지 않는다.
shim 의 has-session 은 _real_herdr agent get "$sess"(lib.sh:215)이고, kill-session 도 agent get 으로 pane_id 를 찾는다.
따라서 이 권고를 채택하면 세션 생존 확인과 세션 종료가 동시에 깨진다.
[REBUT: canary-projects-multi-agent-mux-creator-agy]— 맹점 1-b (유휴 패널 재활용) 항목에 한해 반박한다. 근거: (i) herdr 이 종료 페인을 자동 삭제하므로 증식 전제가 성립하지 않음(§1.4), (ii)kill-session이 이미pane close수행(§1.4), (iii)agent start에--pane이 없어 권고 자체가 표현 불가이며, 우회로인pane run은 agent 미등록으로has-session/kill-session을 파괴함(§1.5). 이는 본 계획서 전체가 제거하려는 결함(존재하지 않는 CLI 능력을 전제한 설계)과 동일한 유형이다. 맹점 1-a 는 반박하지 않고 전면 채택한다.
1.6 [제약 1 검증] mock 의 flock 은 이미 있다 — 진짜 결함은 다른 곳
# tests/conftest.py:90-91 (프로세스 시작 시점, 상태 읽기 전)
lock_f = open(state_file + ".lock", "a")
fcntl.flock(lock_f, fcntl.LOCK_EX) # ← 이미 존재. lock_f 는 close 되지 않음
lock_f 를 닫지 않으므로 락이 mock 프로세스 수명 전체를 덮는다. 읽기(l.93-104)도 락 안에서 일어나고,
save_state()(l.109-135)는 디스크를 재조회한 뒤 calls 를 병합하고 os.replace 로 원자 치환한다.
이의제기가 요구한 "flock 하 재조회 후 병합"은 이미 구현되어 있다.
다만 이의제기가 지목하지 않은 실제 결함이 같은 함수에 있다:
disk_state["agents"] = state.get("agents", {}) # l.121 — 키별 병합이 아니라 통째 덮어쓰기
if "workspaces" in state:
disk_state["workspaces"] = state["workspaces"] # l.122-123 — 동일
calls 만 병합되고 agents/workspaces 는 이 프로세스가 시작 시점에 읽은 스냅샷으로 통째 교체된다.
현재 안전한 이유는 오직 락이 프로세스 수명 전체를 덮어 mock 호출이 완전 직렬화되기 때문이다.
즉 이 락은 성능 최적화가 아니라 정합성의 유일한 근거(load-bearing) 다. 이 사실이 코드 어디에도 적혀 있지 않다.
부작용도 있다: 모든 mock herdr 호출이 전역 직렬화되므로 병렬 pytest 의 이득이 사라진다
(Rev.1 §7.3 에서 보고한 test_tier3_integration.py 10분 초과의 후보 원인 중 하나이나, 분리 측정하지 않았다).
2. Rev.1 → Rev.2 변경 요약
| 구분 | 내용 |
|---|---|
| 신규 | W2a 분할 방향 정책 (pane layout 기반), W2b 오버플로 시 신규 워크스페이스, W17 mock 락 불변식 명문화 + 테스트 |
| 신규 | 테스트 H-11 ~ H-14 (분할 정책 / 오버플로 / 앵커 / mock 락 불변식) |
| 수정 | W2 재사용 분기에서 --split right 무조건 부착 → 정책 기반 선택으로 변경 |
| 수정 | §7 리스크 2번(--workspace 권위 여부 미측정) → 실측 완료, 리스크 해소 |
| 유지 | W1, W3~W16 및 Phase 2/3/4 전부 Rev.1 그대로 (이의제기가 다루지 않았고, 새 측정으로도 흔들리지 않음) |
| 불채택 | 유휴 페인 재할당 분기 (§1.5) |
Rev.1 의 핵심 결론(§0: --kind/--pane 부재, WorkspaceInfo.cwd 부재, mock 계약 불일치)은 전부 그대로 유효하며
이의제기 역시 이 부분은 "매우 정확하고 타당"하다고 인정했다. 아래에는 변경/추가된 부분만 상세히 적고,
변경 없는 항목은 표로만 재수록한다. 원문 전체는 .mam/jobs/f3b10c00/claude-reports/report-final.md 를 병행 참조할 것.
3. 리팩토링 작업 계획 (Rev.2)
역할 경계: 본 계획서는 Planner 산출물이며 코드 수정은 Creator(agy)가 수행한다 (
.agents/MULTI_AGENT_RULES.md§1).
Phase 1 — herdr 실계약 기준 new-session 재작성 (P0)
대상: .agents/skills/lib.sh new-session case (현행 246-374).
| ID | 작업 | 수용 기준 | 변경 |
|---|---|---|---|
| W1 | 워크스페이스 해석을 workspace list(cwd 없음) → pane list 기반 cwd 매칭으로 교체. realpath(pane.cwd) == realpath(target) 인 페인의 workspace_id 채택 |
probe reuse 모드에서 existing_ws 결정, cwd 불일치 시 빈 값 |
유지 |
| W2 | --kind/--pane 분기 전량 삭제. agent start 단일 문법:재사용: agent start "$name" --workspace "$ws_id" --cwd "$ws" $split_arg $env_flags -- $final_cmd신규: workspace create --cwd "$ws" --no-focus → result.workspace.workspace_id → 동일 형태($split_arg 없음)$split_arg 는 W2a 정책이 결정 |
--kind/--pane 0회. 신규 경로에서 --workspace 필수 포함 |
수정 |
| W2a | [신규] 분할 방향 정책. 재사용 분기에서만 동작: 1. pane layout --pane <타깃 ws 의 페인 하나> 로 area / panes[].rect / focused_pane_id 취득2. 앵커 = focused_pane_id 의 rect (실측 §1.3)3. anchor.width / 2 >= MAM_MIN_PANE_COLS → --split right4. elif anchor.height / 2 >= MAM_MIN_PANE_ROWS → --split down5. else → W2b 로 위임 기본값 MAM_MIN_PANE_COLS=60, MAM_MIN_PANE_ROWS=20 |
H-11. 184×78 앵커 → right; 61×78 앵커 → down; 61×39 앵커 → W2b |
신규 |
| W2b | [신규] 오버플로 정책. W2a 5번에 도달하면 기존 워크스페이스를 분할하지 않고 신규 워크스페이스 생성 경로로 전환한다(= workspace create → --workspace <new>, --split 없음) |
H-12. 포화 상태에서 --split 미부착 + 신규 workspace create 발생 |
신규 |
| W3 | pane_id 탐지 기구(315-358) 및 pane split 선행 호출 전량 삭제. w1:p1 하드코딩 폴백 삭제. root_pane or workspace_id 타입 혼동 폴백 삭제 |
probe reuse 에서 pane split 0회, 고아 자원 0 |
유지 |
| W4 | kind 캐스케이드(267-280) + strip 블록(282-294) + ${final_cmd:-} 삭제. final_cmd 절대경로 보존 |
-- 뒤 첫 토큰 = 입력 절대경로 |
유지 |
| W5 | 재시도 최대 3회, 0.5→1→2 백오프. 출력이 usage: / unknown flag 계열이면 즉시 중단 |
probe create/fail 에서 agent start 1회, <1s |
유지 |
| W6 | 실패 시 echo "$res" >&2 후 exit 1 |
probe create/fail rc=1 + stderr |
유지 |
| W7 | 가드 없는 명령치환에 || echo "" 부착 (shim 은 set -euo pipefail) |
herdr 부재 시 W6 형태로 명시적 종료 | 유지 |
W2a 설계 근거 및 한계 (반드시 구현자에게 전달)
- 방향만 고를 수 있고 앵커는 고를 수 없다.
agent start에--pane이 없고,pane focus는 방향 기반이라 임의 pane_id 를 포커스할 수 없다. 따라서 정책은 "앵커(=현재 포커스 페인)의 rect 를 반으로 나눴을 때 살아남는 축"을 고르는 것이다. --split을 생략해도 새 페인은 생긴다(실측 §1.2 P3:--split없이도w1:p3신규 생성). 즉--split은 재사용 스위치가 아니라 방향 지정자다.- 기본값 근거:
MAM_MIN_PANE_COLS=60은 "61 col 에서 3개 에이전트가 현재 정상 동작"이라는 검증된 사실에서 취한 값이다. 이의제기의 40~80 은 근거가 제시되지 않았으므로 채택하지 않는다. 값이 틀렸다고 판단되면 환경변수로 조정 가능하게 만든 것이 이 항목의 요점이다. pane layout은--workspace필터가 없다. 타깃 워크스페이스의 페인 하나를pane list에서 골라--pane <id>로 조회한다.agent start응답의result.agent.{workspace_id,pane_id}로 배치 결과를 사후 검증할 수 있다(실측 확인). W6 의 성공 판정에 활용할 것.
Phase 2 — mock 계약 정합화 (P0, Phase 1 과 동시)
대상: tests/conftest.py
| ID | 작업 | 수용 기준 | 변경 |
|---|---|---|---|
| W8 | agent start 가 미지 플래그 거부(화이트리스트 --cwd --workspace --tab --split --env --focus --no-focus). 위반 시 usage 배너 출력 + 에이전트 미생성 |
--kind/--pane 전달 테스트가 실패함을 선확인 |
유지 |
| W9 | 성공 시 {"result":{"type":"agent_started","agent":{...,"pane_id","workspace_id"},"argv":[...]}} 출력 |
shim 의 grep -q agent_started 성립 |
유지 |
| W10 | workspace list 에서 cwd 제거. workspace create 는 workspace_created 전체 응답 출력 |
§3.1 죽은 코드가 mock 에서도 죽음 | 유지 |
| W11 | pane list(+--workspace 필터), pane split, pane layout 핸들러 추가. pane layout 은 area/panes[].rect/focused_pane_id 반환. 분할 시 앵커를 focused_pane_id 로 두고 rect 를 실제로 반분하여 W2a 를 검증 가능하게 할 것 |
W2a 정책이 mock 에서 검증 가능 | 수정 |
| W17 | [신규] save_state() 의 락 불변식 명문화: (a) "lock_f 는 의도적으로 close 하지 않으며, 이 전역 직렬화가 agents/workspaces 통째 덮어쓰기의 유일한 정합성 근거"라는 주석 추가, (b) 락을 세분화하려면 반드시 키별 병합으로 먼저 전환해야 한다는 경고, (c) H-14 테스트 추가 |
H-14 PASS | 신규 |
W17 은 이의제기 [제약 1]에 대한 응답이다. 요구된 flock 자체는 이미 있으므로 추가 구현이 아니라 불변식 문서화 + 회귀 테스트로 대응한다. 코드를 바꾸지 않는 이유는 §1.6 참조.
Phase 3 — 계약 회귀 테스트 (P1)
신규 파일: tests/test_herdr_shim_contract.py
| ID | 케이스 | 목적 | 변경 |
|---|---|---|---|
| H-1 | agent start 에 화이트리스트 외 플래그를 절대 넘기지 않는다 |
§3.2 재발 방지 | 유지 |
| H-2 | 신규 경로에서 workspace create id 가 --workspace 로 전달된다 |
고아 워크스페이스 방지 | 유지 |
| H-3 | 재사용 경로에서 pane split 을 선행 호출하지 않는다 |
고아 페인 방지 | 유지 |
| H-4 | -- 뒤 첫 토큰 = 입력 절대경로 |
§3.5 재발 방지 | 유지 |
| H-5 | usage 배너 → 재시도 없이 rc=1 + stderr | §3.4 재발 방지 | 유지 |
| H-6 | 일시 실패에만 최대 3회 재시도, 총 <3s | §3.4 재발 방지 | 유지 |
| H-7 | env FOO=bar → --env FOO=bar 정확히 1회 |
b0c2c08 회귀 방지 |
유지 |
| H-8 | herdr 부재 시 무성 종료하지 않는다 | W7 | 유지 |
| H-9 | mock 응답이 tests/fixtures/herdr_contract.json 을 만족 |
mock 표류 감지 | 유지 |
| H-10 | (herdr 미설치 시 skip) herdr api schema 실측 = 고정 픽스처 |
바이너리 업그레이드 감지 | 유지 |
| H-11 | 앵커 rect 가 넓으면 --split right, 좁고 높으면 --split down |
W2a | 신규 |
| H-12 | 양축 모두 임계 미만이면 --split 미부착 + 신규 workspace create |
W2b | 신규 |
| H-13 | MAM_MIN_PANE_COLS / MAM_MIN_PANE_ROWS 환경변수가 실제로 정책을 바꾼다 |
임계값 하드코딩 방지 | 신규 |
| H-14 | mock 을 동시 다중 프로세스로 호출해도 agents 유실 0 (락 불변식) |
W17 | 신규 |
proposed/probe_new_session.sh 를 H-1H-8/H-11H-13 의 구동 기반으로 재사용한다.
proposed/probe_layout_policy.sh 는 실 바이너리 계약이 바뀌지 않았음을 확인하는 수동 점검용이다(CI 비포함 — herdr 서버가 필요).
Phase 4 — 미리뷰 항목 정리 (P1) — Rev.1 그대로
| ID | 작업 |
|---|---|
| W12 | resolve_herdr_session 의 val != 'default' 스킵 동작 확정 + 테스트 2건 |
| W13 | ws 와 HERDR_SESSION_NAME 동시 지정 시 슬러그 우선 고정 (cline 83181aad 지적) |
| W14 | .mam/shim/ 잔여 임시파일 정리 (_init_herdr_isolation 에 선행 rm -f) |
Phase 5 — 선택 (P2)
- W15:
loop_lock.shsteal 락 순서 교정/제거 (별도 잡 권장) - W16:
agent start --no-focus부착 검토. 주의: §1.3 에 따라--no-focus는 분할 앵커를 고정시켜 열화를 가속한다. W2a 와 상호작용하므로 W16 은 W2a 확정 이후에 재검토할 것. (Rev.1 대비 성격 변경)
4. 리뷰 라운드 운영 계획
4.1 cline 리뷰 브리프 필수 요구사항
- 실 바이너리 대조 필수:
herdr agent --help,herdr api schema --json을 인용하고 전달 플래그를 1:1 대조. "코드가 논리적으로 맞다"를 PASS 근거로 삼지 말 것. - probe 하네스 실행 필수:
probe_new_session.sh를create/fail,create/ok,reuse/ok3모드로 실행하고 herdr 호출 내역 전량 첨부. - 누수 점검 필수: 생성/재사용 경로 각각에서 미소비 workspace/pane 이 0 임을 호출 내역으로 입증.
- 실패 경로 점검 필수: 전량 실패 시 rc≠0 + stderr 확인.
- mock 정합성 점검: Rev.1 §2.1 계약표와 항목별 대조.
- [신규] 레이아웃 정책 점검:
probe_layout_policy.sh실행 후 (a) 분할 앵커가focused_pane_id라는 전제가 유지되는지, (b) W2a 가 앵커의 실제 rect 를 읽는지(워크스페이스 평균이나pane_count가 아니라), (c) 포화 시 W2b 로 빠지는지 확인. - [신규] 회귀 앵커 확인:
agent start에--pane을 넘기는 코드가 한 줄도 없는지 grep 으로 확인.
4.2 라운드 구성
| 라운드 | 담당 | 입력 | 산출 |
|---|---|---|---|
| R0 (완료) | claude | 전 작업분 + herdr 실계약 | 계획서 Rev.1 (f3b10c00) |
| R0.5 (완료) | agy | Rev.1 | 이의제기 48a9416f |
| R0.6 (본 문서) | claude | 이의제기 + 신규 실측 | 계획서 Rev.2 |
| R1 | agy | Phase 1 + Phase 2 | 구현 + probe 2종 결과 |
| R2 | cline | R1 결과물 | §4.1 7개 항목 대조 리포트 |
| R3 | agy | Phase 3 + Phase 4 | test_herdr_shim_contract.py (H-1 |
| R4 | cline + claude | 전체 | 최종 판정 |
R2 에서 NOT PASS 시 R1 로 복귀. Phase 3 는 Phase 1/2 PASS 이후 착수(계약 확정 전 테스트를 먼저 쓰면 잘못된 계약을 고정하게 된다).
5. 검증 계획
| 단계 | 명령 | 통과 기준 |
|---|---|---|
| 문법 | bash -n .agents/skills/lib.sh, bash -n .mam/shim/herdr |
PASS |
| 정적 | CI shellcheck (deploy/gitea-ci.yml:31) — 로컬 미설치 |
신규 경고 0 |
| 계약 | probe_new_session.sh × 3모드 |
Phase 1 수용 기준 충족 |
| 레이아웃 | probe_layout_policy.sh (격리 세션, 자체 정리) |
P0~P5 전제가 §1 실측과 일치 |
| 단위 | pytest tests/test_herdr_shim_contract.py |
H-1~H-14 전부 PASS |
| 회귀 | pytest tests/test_orc_onboard.py tests/test_workspace_scope.py tests/test_tier1_unit.py tests/test_deploy_layout.py tests/test_deploy_freshness.py |
기존 통과 수 유지 |
| 통합 | pytest tests/test_tier3_integration.py tests/test_tier4_e2e.py |
HEAD 기준으로도 10분 초과(실측). 별도 시간 예산 필요 |
| 실환경 | 실 herdr 세션에서 create_session.sh 1회 → herdr pane layout |
고아 자원 0, 신규 페인 폭 ≥ MAM_MIN_PANE_COLS |
6. 리스크 및 범위 밖 항목 (Rev.2 갱신)
- herdr 버전 종속성: 모든 계약은 herdr 0.7.4 (protocol 16) 실측. H-10 이 업그레이드 시점을 잡아준다.
→ 해소.agent start --workspace의 배치 권위 미측정agent start --workspace w1이 포커스가 다른 상태에서도 w1 에 배치함을 실측(§1.2 P1).- 에이전트 TUI 최소 렌더링 폭은 여전히 미측정이다.
MAM_MIN_PANE_COLS=60은 "61 col 3에이전트 정상 동작"이라는 관측 사실에서 취한 값이지, claude/agy TUI 의 실제 하한을 측정한 값이 아니다. 하한을 정확히 알려면 폭을 줄여가며 렌더 깨짐을 관찰해야 하는데, 이는 라이브 에이전트 세션을 손상시키므로 수행하지 않았다. 환경변수로 노출한 이유가 이것이다. - 분할 앵커 =
focused_pane_id는 격리 세션 4회 관측에 기반한다. herdr 이 포커스 외 다른 규칙(예: 최근 생성 페인)을 쓰는 경계 조건은 확인하지 않았다. W2a 는 앵커를 가정하지 않고pane layout에서 읽으므로, 이 전제가 틀려도 정책이 잘못된 페인을 기준 삼을 뿐 크래시하지는 않는다. - mock 직렬화가 tier3 런타임에 미치는 영향은 분리 측정하지 못했다(§1.6). tier3 는 HEAD 기준으로도 10분을 초과하는 선재 문제다.
loop_lock.sh는 정적 분석 기반 리뷰이며 실제 경합을 재현하지 않았다.- 범위 밖: orc-onboard 스킬(리뷰 완료),
agent_identities최상위 키 미검증(5650172e§7.1 이월), W15/W16. - 측정 부작용 없음 확인: 격리 세션
mam-probe-f3b/mam-verify-7e5는session stop+session delete로 제거했고, 라이브 워크스페이스wM은 측정 전후 동일하게 3페인(agy/cline/claude)을 유지했다.git status는 측정 전과 동일하다.
7. 결론
이의제기의 핵심(맹점 1-a)은 옳고, 원 계획서의 실질적 결함이었다. 재사용 분기에서 --split right 를 무조건 부착하면
패널 폭이 고갈된다 — 격리 세션에서 13~14 col 까지 붕괴하는 것을 직접 재현했다. W2a/W2b 로 전면 채택한다.
동시에 두 가지를 정정한다. 첫째, 실제 열화는 이의제기가 상정한 184/N 균등 분할이 아니라 --no-focus 때문에 앵커가 고정되어 발생하는 184/2^N 분할이며,
agent start 로는 방향만 고를 수 있고 앵커는 고를 수 없다. 둘째, 유휴 페인 재활용은 필요하지도, 가능하지도 않다 —
herdr 이 종료 페인을 자동 삭제하고(실측), kill-session 은 이미 pane close 를 수행하며, pane run 우회로는 agent 미등록으로 has-session 을 파괴한다.
이 권고를 그대로 채택했다면 존재하지 않는 CLI 능력을 전제한 설계라는, 본 계획서가 제거하려는 바로 그 결함을 다시 도입했을 것이다.
mock_herdr 의 flock 요구는 이미 충족되어 있었다. 대신 같은 함수에서 agents 통째 덮어쓰기가 전역 락에 의존하고 있다는 미문서화 불변식을 발견해
W17/H-14 로 고정한다.
아래 토큰은 본 계획서 산출물의 완료 표시다. 검토 대상 코드에 대한 판정은 Rev.1 §3 그대로 — 미커밋 working tree = NOT PASS,
20e2e9b/b0c2c08= 판정 정정 필요.
[REBUT: canary-projects-multi-agent-mux-creator-agy] [AGREEMENT: REACHED]