Files
multi-agent-mux/CLAUDE_WORK_LOGS.md

103 lines
11 KiB
Markdown

# CLAUDE_WORK_LOGS.md
작업 일자: 2026-07-19
작업자: Claude (herdr 세션 `default:w3:p1`, `claude`)
## 개요
`.agents/skills/` 아래 multi-agent-mux 스킬 세트가 tmux 시절 문법(`capture-pane`, `list-panes`, `kill-session`, `send-keys`, `session attach` 등)을 실제 herdr CLI 문법인 것처럼 잘못 사용하고 있던 문제를 발견하고 전수 조사·수정했다. 추가로 `HERDR_SERVER_NAME` 격리 기능이 진짜 herdr 서버 격리가 아니라 workspace label 흉내에 불과했던 것을 실제 `herdr --session <name>` 격리로 재설계했고, 프롬프트 주입 검증 로직(`send_keys_safe`)의 멀티바이트/줄바꿈 버그도 잡았다. 모든 수정은 herdr 실제 바이너리(v0.7.4) 대조 + 디스포저블 herdr 세션 실구동 테스트로 검증했으며, 일부는 실제 cline reviewer 에이전트(`canary-projects-multi-agent-mux-reviewer-cline`)에게 `multi-agent-mux-delegate-job`으로 위임하여 독립 교차검증(`[VERDICT: PASS]`)까지 받았다.
커밋은 아직 하지 않았다 (전부 워킹 트리 변경 상태).
---
## 1. 수정한 내용
### 1.1 `.agents/skills/lib.sh` (공유 라이브러리)
- **`mam_herdr` shim의 `kill-session` 케이스**: `herdr session stop/delete "$sess"` (herdr의 `session`은 서버 전체 단위 개념이라 개별 에이전트 이름으로는 절대 못 찾음, 항상 조용히 실패) → `agent get`으로 `pane_id`를 먼저 해석한 뒤 `pane close <pane_id>`로 교체.
- **`send-keys` 케이스**: 동일하게 `pane send-keys "$sess" ...`(pane_id가 아니라 이름을 넘겨서 항상 실패)를 `agent get`으로 `pane_id` 선해석 후 `pane send-keys <pane_id> ...`로 교체.
- **`list-panes` 케이스**: JSON 경로가 `d.get('pane', d)`로 완전히 틀려있었음 (실제 응답은 `result.agent.{cwd, pane_id, agent}`) → cwd/cmd는 `agent get`에서, pid는 별도로 `pane process-info --pane <pane_id>`에서 조회하도록 재작성. 이 버그로 인해 `create_session.sh`/`update_yaml_resumed.sh``PANE_PID`/`PANE_CWD`/`PANE_CMD` 캡처가 전부 항상 빈 값이었음.
- **`HERDR_SERVER_NAME` 격리를 진짜 herdr session 격리로 통일**:
- `_init_herdr_isolation`에 세션 부트스트랩 로직 추가 — `HERDR_SERVER_NAME != default`일 때 `herdr session list`로 확인 후 없으면 `herdr --session <name> server`를 헤드리스로 백그라운드 기동 (인터랙티브 launch가 걸리는 "nested herdr is disabled" 제한을 회피).
- `_real_herdr()` 헬퍼 도입 — 모든 실제 herdr 호출에 `--session "$HERDR_SERVER_NAME"`를 자동 스코핑.
- `new-session` 케이스에서 기존의 "workspace label 매칭으로 격리 흉내"(진짜 격리가 전혀 아니었음, `agent list`가 서버 전역이라 아무 효과 없었음) 로직을 통째로 제거하고, 활성 세션 안에 fresh workspace를 만들도록 단순화.
- `resolve_herdr_workspace()` 단순화 — workspace_id를 찾던 로직 제거, YAML에 저장된 세션 라벨을 그대로 반환 (호출자 3곳 — resume/stop/update_yaml_resumed — 호환 유지를 위해 함수명은 유지).
- **`send_keys_safe()` paste 검증 로직 버그 2건 수정**:
1. 마커를 `tail -c 24`(바이트 기준)로 잘라서 한글 등 멀티바이트 UTF-8 문자를 중간에서 자를 위험 → `python3` 문자 기준 슬라이싱(`[-24:]`)으로 교체.
2. 렌더링된 pane은 터미널 폭에 맞춰 자동 줄바꿈하는데(cline은 이어지는 줄에 공백 들여쓰기까지 추가) 마커가 그 지점에 걸리면 `grep -F`(줄 단위)가 못 찾음 → 매칭 직전에 `tr -d '[:space:]'`로 공백/개행을 전부 제거하고 매칭 (paste 확인 지점 + Enter 제출 확인 지점 둘 다 적용).
### 1.2 `.agents/skills/multi-agent-mux-create/`
- `SKILL.md`: 문서 예시 명령 정정(`herdr attach``agent attach` 등), 존재하지 않는 `list-sessions` 제거, 격리 섹션에 실제 메커니즘(헤드리스 세션 부트스트랩) 설명 추가.
- `scripts/create_session.sh`: YAML에 저장하는 `attach_command`/`kill_command`/`start_command` 템플릿이 `herdr session attach/stop/delete`(서버 전체 단위 명령을 개별 에이전트 이름으로 잘못 호출)로 깨져 있던 것을 `HERDR_SERVER_NAME=<server> herdr ...` 형태로 수정.
### 1.3 `.agents/skills/multi-agent-mux-resume/`
- `SKILL.md`: Verification 블록의 pseudo-명령 정정, `herdr attach -t`(존재하지 않는 문법) → `herdr agent attach`.
- (스크립트 자체는 버그 없었음 — herdr 관련 이슈 전수조사 완료.)
### 1.4 `.agents/skills/multi-agent-mux-monitor/`
- `SKILL.md`: `herdr ls`/`list-panes` 문서 예시 정정.
- `scripts/reconcile.sh`: `attach_command` 템플릿의 존재하지 않는 `attach -t``agent attach` 수정. (이 파일은 원래 다른 목적 — purging 세션 자동등록 스킵 — 으로 이미 일부 수정되어 있었음.)
### 1.5 `.agents/skills/multi-agent-mux-status/`
- `SKILL.md`: `herdr has-session`/`list-panes` 설명 정정, 드리프트 안내 메시지의 `herdr kill-session` 제안을 스킬 경유 안내로 변경.
### 1.6 `.agents/skills/multi-agent-mux-stop/`
- `SKILL.md`: Verification 블록 정정.
- `scripts/stop_session.sh`: (원래 다른 목적으로 이미 수정 중이던) purge 락 파일(`purging-<session>`) 추가, `--agent` 값 검증 추가.
### 1.7 `.agents/skills/multi-agent-mux-delegate-job/`
- `multi-agent-mux-delegate-job` (메인 스크립트) `run_agent()` 함수의 herdr 버그 3건:
1. `lib.sh``has-session` 체크보다 늦게 source하고 있어서 체크 시점엔 아직 shim이 아니라 진짜 바이너리 → 존재하지 않는 `has-session` 서브커맨드 호출 → 항상 실패. `source lib.sh`를 파일 최상단으로 이동.
2. `HERDR_SERVER_NAME`을 레지스트리에서 자동 해석 안 하고 호출자가 export해뒀길 기대함 → 격리 세션에 위임 시 실패 가능 → `resolve_herdr_workspace "$sess"` 자동 호출 추가.
3. 안내 메시지의 `herdr session attach`(서버 전체 단위) → `herdr agent attach`로 수정.
- `SKILL.md`: "프롬프트는 영어/ASCII/짧게, 한국어 상세 내용은 마크다운 브리핑 파일로" 운영 규칙 추가 (send_keys_safe 버그의 실질적 완화책이자, `submit`의 기본 instructions 템플릿이 이미 따르고 있던 패턴을 명문화).
### 1.8 기타
- 루트 `.gitignore`에 Flutter/Dart 빌드 산출물, IDE 파일 패턴 추가 (`multi-agent-mux-ui`), 커밋 완료(`cccc30a`).
- `.mam/agent-sessions.yaml`의 stale 3개 세션(herdr 죽었는데 YAML엔 running으로 남아있던 것) `reconcile.sh`로 정리 → `terminated` 처리.
---
## 2. 검증된 스킬
### 2.1 cline reviewer 독립 교차검증 완료 (`[VERDICT: PASS]`)
**1차 — job `14943484`** (`.mam/jobs/14943484/cline-reports/herdr-cli-fix-review.md`)
- 대상: `lib.sh`(kill-session/send-keys/list-panes 수정 + session 격리 통일), `multi-agent-mux-create/scripts/create_session.sh`, `multi-agent-mux-monitor/scripts/reconcile.sh`, `multi-agent-mux-stop/scripts/stop_session.sh`, 5개 SKILL.md (create/resume/monitor/status/stop)
- 방법: 실제 herdr v0.7.4 바이너리로 10개 명령 문법 + 6개 JSON 스키마 직접 대조, 실구동 테스트, default 경로 회귀 테스트, pipefail 런타임 테스트, 정적분석.
- 잔여 LOW 2건 + INFO 1건 (전부 non-blocking, 비회귀).
**2차 — job `80040741`** (`.mam/jobs/80040741/cline-agent-reports/report-final.md`, 정식 delegate-job 프로토콜로 완주)
- 대상: `lib.sh``send_keys_safe()` 공백 정규화 수정, `multi-agent-mux-delegate-job/SKILL.md`의 새 규칙.
- 방법: python3 슬라이싱 시뮬레이션(엣지 케이스 15개) + 실제 bash 파이프라인 재현 + 실제 delegate-job 기본 템플릿으로 회귀 테스트.
- 잔여 INFO 1건(빈 marker_norm 위양성 가능성 — 실사용 경로에서 도달 불가로 확인, non-blocking).
### 2.2 실제 프로덕션 사용으로 검증 (정식 리뷰 없음)
- **`multi-agent-mux-delegate-job` 메인 스크립트의 `run_agent()` 수정 3건**: 정식 리뷰(job `e84698d7`)가 세션 hang으로 유실됐지만, 그 이후 실제로 여러 차례 `submit`을 성공 실행하면서(격리 세션 안의 살아있는 에이전트를 정확히 찾아내는 것 포함) 실사용 검증됨.
- **`multi-agent-mux-stop/scripts/stop_session.sh`**: 실제로 hung된 `canary-projects-multi-agent-mux-reviewer-cline` 세션을 대상으로 진짜 stop을 실행 — graceful exit-keys → kill-session(수정된 pane close 경로) → conversation id 캡처까지 전 과정 실전 확인.
- **`multi-agent-mux-resume/scripts/resume_session.sh`**: 같은 세션을 동일 conversation id로 실제 resume하여 대화 이력이 정확히 복원되는 것 확인 (2회 반복).
---
## 3. 추후 검증할 스킬
| 스킬 | 상태 |
|---|---|
| **`multi-agent-mux-delegate-job` 메인 스크립트** | 정식 cline 리뷰(job `e84698d7`)가 세션 hang으로 미완료. 재위임하면 공식 PASS 서명을 받을 수 있음. |
| **`multi-agent-mux-status/scripts/status.sh`** | `SKILL.md` 문구만 검토됨. 스크립트 자체는 이번 작업에서 한 번도 직접 실행 안 함 (내부적으로 쓰는 `reconcile.sh`는 검증됨). |
| **`multi-agent-mux-loop`** | 완전히 손대지 않음. `run_loop.sh`가 herdr를 직접 다루지 않고 `delegate-job`을 통해서만 위임하는 구조라 영향권 밖일 가능성 높지만 미확인. |
| **`multi-agent-mux-ui`** (Flutter/Dart) | `.gitignore` 정리만 진행. `mam_core``status.sh`를 래핑하는 로직 자체는 이번 herdr 문법 수정과 별개로 전혀 검토 안 함. |
---
## 4. 추후 작업
1. **커밋**: 지금까지의 모든 수정(11개 파일, lib.sh + 6개 스킬)이 워킹 트리에 uncommitted 상태. 커밋 여부/단위 결정 필요.
2. **`multi-agent-mux-delegate-job` 메인 스크립트 정식 리뷰 재위임** — job `e84698d7` 재시도 (섹션 3 참조).
3. **`send_keys_safe`의 INFO급 잔여 이슈** — 빈 `marker_norm`일 때 `grep -Fq ''`가 항상 매칭되는 위양성 가능성. 실사용 경로에서 도달 불가로 확인됐지만, 원하면 방어적으로 빈 텍스트 가드를 추가할 수 있음.
4. **`multi-agent-mux-status/scripts/status.sh` 실제 실행 검증** — 아직 한 번도 직접 실행 안 됨.
5. **`multi-agent-mux-loop`/`multi-agent-mux-ui` 전수 조사** — 이번 herdr 문법 감사 범위 밖.
6. **`.mam/agent-sessions.yaml``herdr_workspace`/`herdr_server` 필드명 정리** — 현재 `resolve_herdr_workspace()`가 반환하는 값의 실제 의미(workspace_id가 아니라 session 라벨)와 함수명이 불일치하는 상태(호출자 호환을 위해 이름은 유지함). 장기적으로는 필드명/함수명을 실제 의미(session)에 맞게 리네이밍하는 리팩터링을 고려할 수 있음.