chore(docs): clean up temporary FIX.md and bug_report.md

This commit is contained in:
2026-08-27 21:43:26 +09:00
parent c3631e2aa1
commit 4a5a093986
2 changed files with 0 additions and 237 deletions
-22
View File
@@ -1,22 +0,0 @@
### 수정 내역 (lib.sh)
1. 에이전트 시작 판별 조건 완화 (new-session / `agent start`)
- 치명적 CLI 오류(`^usage:` / `^error:` 등)를 **성공 분류보다 먼저** 판별한다.
- `agent_started`뿐 아니라 herdr 문서의 `agent_not_ready`(프로세스는 살아 있고 다이얼로그에 막힘)도
롤백하지 않고 `wait_for_tui_ready`로 넘긴다.
- `timed out waiting for agent startup`**성공으로 승격하지 않는다.** herdr는 `/bin/false`처럼
이미 죽은 프로세스에도 같은 메시지를 반환하므로, 이 토큰은 실패와 지연을 구분하지 못한다.
2. Claude 풀스크린 렌더러 업셀 모달
- 차단형 모달 고유 시그니처는 `Yes, try it`이다. `_MAM_DIALOG_TOKENS`
`handle_startup_dialogs`는 이 문자열만 쓴다.
- 거절은 **Escape**다. Enter는 기본 선택지 `Yes, try it`을 수락하고 세션을 permission flag 없이
재시작한다.
- idle 팁 `Try the new fullscreen renderer — … · /tui fullscreen`은 입력을 막지 않으므로
다이얼로그로 취급하지 않는다. 광의 토큰 `fullscreen renderer|Try the new fullscreen`
팁과 모달을 동시에 매칭해 `wait_for_tui_ready`를 데드락 시킨다.
3. 검증: `tests/test_b19_headless_reconcile_fixes.py`에서 `_pane_capture`를 stub 한 행위 테스트
(모달 vs 팁).
-215
View File
@@ -1,215 +0,0 @@
# 🐛 버그 리포트: Herdr 패인 라우팅 및 지침 주입 안전성 분석 리포트
- **문서 버전**: v1.0
- **작성일자**: 2026-08-27
- **대상 모듈**: `.agents/skills/lib.sh` (Multi-Agent Mux 코어 라이브러리)
- **검토 참여 리뷰어**: `planner-reviewer-claude-01` (Claude), `reviewer-creator-grok-01` (Grok), `reviewer-cline-01` (Cline)
---
## 1. 개요 및 배경
Multi-Agent Mux(MAM) 오케스트레이션 루프(`run_loop.sh`) 구동 중, `herdr agent`로 자동 등록되지 않고 `herdr pane` 라벨(`label: creator-agy-01`, `label: reviewer-cline-01`) 형태로 동작하는 에이전트 세션에 대해 **프롬프트 주입(`inject_instructions` / `send_keys_safe`)이 도달하지 못하고 세션이 무한 대기/타임아웃되는 현상**이 발생했습니다.
이에 대한 임시 라우팅 패치 후 3개 독립 리뷰어 세션(`claude`, `grok`, `cline`)을 통해 교차 피어 리뷰를 수행한 결과, 추가적인 핵심 맹점(P0~P2)이 발굴되었습니다. 본 문서는 타 프로젝트 및 업스트림(`multi-agent-mux`) 반영을 위해 분석된 문제점과 권고 수정안을 상세히 정리합니다.
---
## 2. 핵심 결함 상세 분석 (Findings)
### [ISSUE-1] P0: `paste-buffer`의 불필요한 `Enter` 전송으로 인한 이중 제출 (Double Submit)
- **위치**: `.agents/skills/lib.sh` `paste-buffer` (~880줄) 및 `send_keys_safe` (~1890줄)
- **현상**:
`paste-buffer` 구현부에서 `_real_herdr pane send-text` 호출 직후 `_real_herdr pane send-keys "$pane_id" Enter`를 실행하도록 작성됨.
그러나 상위 `send_keys_safe` 함수는 자체적으로 텍스트 주입 확인 후 `_sks_herdr send-keys -t "$sess" C-m`을 1~3회 재시도하며 제출하는 **2단계(Paste $\rightarrow$ Submit) 프로토콜**을 가짐.
- **문제점**:
1. `paste-buffer`가 텍스트를 넣으면서 이미 1차 엔터를 쳐버림.
2. `send_keys_safe`의 후속 `C-m` 루프가 빈 프롬프트(Empty Enter)를 전송하거나, CLI에 떠 있는 대화창/옵션을 의도치 않게 자동 수락하는 사이드 이펙트 유발.
- **해결 방안**:
`paste-buffer`는 순수하게 텍스트를 입력 버퍼에 배치하는 작업만 수행해야 하며, 엔터 제출(`Enter`/`C-m`)은 `send_keys_safe` 단독으로 제어해야 함.
---
### [ISSUE-2] P0: `agent in tn` 부분 매칭으로 인한 오라우팅 (Cross-Pane Mis-Routing)
- **위치**: `.agents/skills/lib.sh` `capture-pane`, `send-keys`, `paste-buffer` 내부 파이썬 스크랩 코드
- **현상**:
```python
if p.get("label") == tn or (p.get("agent") and p.get("agent") in tn):
print(p.get("pane_id", ""))
sys.exit(0)
```
- **문제점**:
동일한 CLI를 사용하는 다중 에이전트(예: `planner-reviewer-claude-01`과 `creator-claude-02`, 또는 `reviewer-creator-grok-01`과 `worker-grok-02`)가 동일 서버에 공존할 때, `p.get("agent") == "grok"`이 `tn == "reviewer-creator-grok-01"`의 부분 문자열(`"grok" in tn`)로 참(True)이 되어, 목록에서 먼저 발견된 다른 에이전트의 패인으로 키와 텍스트가 잘못 전송됨.
- **해결 방안**:
부분 매칭을 전면 제거하고, `p.get("label") == tn` (라벨 완전 일치) $\rightarrow$ `p.get("agent") == tn or p.get("name") == tn` (이름 완전 일치) 순서로 엄격한 일치만 허용.
---
### [ISSUE-3] P1: `pane list` 조회 시 워크스페이스 미격리로 인한 패인 충돌 (Cross-Workspace Collision)
- **위치**: `has-session`, `kill-session`, `capture-pane`, `send-keys`, `paste-buffer`
- **현상**:
`herdr pane list`의 결과는 서버 전체 전역(Server-Global) 목록임.
- **문제점**:
`MULTI_AGENT_RULES.md`의 표준 명명 규칙에 따라 여러 프로젝트가 `creator-agy-01`, `reviewer-cline-01` 등 동일한 기본 라벨을 사용할 경우, 다른 워크스페이스의 패인을 조회하여 텍스트를 탈취하거나 명령을 잘못 주입할 위험이 있음.
- **해결 방안**:
현재 세션의 `workspace_id`(예: `resolve_herdr_workspace` 또는 `p.get("workspace_id") == target_ws`)를 조건에 포함하여 동일 워크스페이스 내의 패인만 식별하도록 스코프 제한.
---
### [ISSUE-4] P2: `agent start` 성공 판정 정규식의 타임아웃 오인
- **위치**: `.agents/skills/lib.sh` `new-session` (~560줄)
- **현상**:
```bash
if echo "$res" | grep -qE "agent_started|agent_not_ready|timed out waiting for agent startup"; then
success=1
```
- **문제점**:
`timed out waiting for agent startup` 및 `agent_not_ready`는 실제로는 기동 실패 또는 지연 상태임에도 `success=1`로 처리되어 즉시 재시도 루프를 빠져나감. 이로 인해 TUI가 아직 뜨지 않은 빈 셸 상태에서 프롬프트 주입이 시도되어 실패를 초래함.
- **해결 방안**:
성공 판정은 `agent_started` (및 이미 실행 중인 확인 응답)만 인정하고, `agent_not_ready`/타임아웃 시에는 백오프 재시도를 수행하도록 엄격화.
---
### [ISSUE-5] P2: 중복된 파이썬 원라이너 파서 및 데드 파이프라인
- **위치**: 5개 이상의 명령 분기(`has-session`, `kill-session`, `capture-pane`, `send-keys`, `paste-buffer`)
- **현상**:
각 분기마다 독립적으로 파이썬 스크립트가 복사-붙여넣기되어 구현이 제각각으로 분기(Drift)되었고, `python3 -c "... except: pass"`가 항상 exit code 0을 반환하여 bash의 `||` 체인이 2차 폴백으로 넘어가지 않는 데드 코드가 존재함.
- **해결 방안**:
단일 공용 헬퍼 함수(`_resolve_herdr_pane_id`)를 선언하여 모든 분기가 일관된 단일 로직을 호출하도록 리팩터링.
---
## 3. 권고 아키텍처 및 개선 코드 (Recommended Implementation)
### 3.1 단일 공용 헬퍼 함수 선언 (`_resolve_herdr_pane_id`)
```bash
# _resolve_herdr_pane_id <session_name> [workspace_id]
# Resolves the concrete pane_id ("wN:pN") for a given session name or label.
# Strict resolution order:
# 1. herdr agent get <sanitized_name>
# 2. herdr agent get <raw_name>
# 3. herdr pane list (scoped by workspace_id, exact match on label, then exact match on agent/name)
_resolve_herdr_pane_id() {
local target="$1"
local target_ws="${2:-${HERDR_WORKSPACE_ID:-}}"
local sat
sat=$(_sanitize_herdr_agent_name "$target")
# 1 & 2. Try native agent get
local pid=""
pid=$(_real_herdr agent get "$sat" 2>/dev/null | python3 -c "
import sys, json
try:
d = json.load(sys.stdin)
print(d.get('result', {}).get('agent', {}).get('pane_id') or '')
except Exception:
pass
" 2>/dev/null || echo "")
if [ -z "$pid" ]; then
pid=$(_real_herdr agent get "$target" 2>/dev/null | python3 -c "
import sys, json
try:
d = json.load(sys.stdin)
print(d.get('result', {}).get('agent', {}).get('pane_id') or '')
except Exception:
pass
" 2>/dev/null || echo "")
fi
# 3. Fallback to pane list with exact matching and optional workspace scoping
if [ -z "$pid" ]; then
pid=$(_real_herdr pane list 2>/dev/null | TARGET_NAME="$target" TARGET_WS="$target_ws" python3 -c "
import sys, json, os, re
tn = os.environ.get('TARGET_NAME', '')
tws = os.environ.get('TARGET_WS', '')
try:
data = json.load(sys.stdin)
panes = data.get('result', {}).get('panes', [])
# Filter by workspace if provided
if tws:
panes = [p for p in panes if p.get('workspace_id') == tws]
# Priority 1: Exact label match
for p in panes:
if p.get('label') == tn:
pid = p.get('pane_id', '')
if pid:
print(pid)
sys.exit(0)
# Priority 2: Exact agent name match (NO substring matching)
for p in panes:
if p.get('agent') == tn or p.get('name') == tn:
pid = p.get('pane_id', '')
if pid:
print(pid)
sys.exit(0)
except Exception:
pass
sys.exit(1)
" 2>/dev/null || echo "")
fi
# Validate pane_id format (e.g. w1:p2)
if [[ "$pid" =~ ^w[0-9]+:p[0-9]+$ ]]; then
echo "$pid"
return 0
fi
return 1
}
```
### 3.2 분기별 Shim 간소화 및 정합성 보장
```bash
# capture-pane
capture-pane)
sess=""
# ... parse -t ...
pane_id=$(_resolve_herdr_pane_id "$sess")
if [ -n "$pane_id" ]; then
_real_herdr pane read "$pane_id" --source visible --lines 100 2>/dev/null || true
else
_real_herdr agent read "$sess" --source visible --lines 100 2>/dev/null || true
fi
;;
# send-keys
send-keys)
sess="" key=""
# ... parse -t and key ...
[ "$key" = "C-m" ] && key="Enter"
pane_id=$(_resolve_herdr_pane_id "$sess")
if [ -n "$pane_id" ]; then
_real_herdr pane send-keys "$pane_id" "$key" >/dev/null 2>&1 || true
else
_real_herdr pane send-keys "$sess" "$key" >/dev/null 2>&1 || true
fi
;;
# paste-buffer (NO Enter, insert-only)
paste-buffer)
# ... parse -b and -t ...
pane_id=$(_resolve_herdr_pane_id "$sess")
if [ -f "$buffer_dir/$buf" ]; then
if [ -n "$pane_id" ]; then
# Insert text only. Enter submission is strictly delegated to send_keys_safe.
_real_herdr pane send-text "$pane_id" "$(cat "$buffer_dir/$buf")" >/dev/null 2>&1 || true
else
_real_herdr agent send "$sess" "$(cat "$buffer_dir/$buf")" >/dev/null 2>&1 || true
fi
fi
;;
```
---
## 4. 결론 및 향후 조치
- 본 버그 리포트에 명시된 5대 핵심 결함(P0: 이중 제출, P0: substring 오라우팅, P1: 워크스페이스 미격리, P2: 타임아웃 성공 오인, P2: 중복 파서)은 독립적인 3인 리뷰어의 정밀 교차 검증을 통해 그 위험성과 재현 경로가 명백히 입증되었습니다.
- 본 리포트의 내용을 기반으로 `multi-agent-mux` 업스트림 저장소 및 라이브러리 유지보수 프로젝트에서 `lib.sh` 리팩터링 패치를 공식 배포할 것을 강력히 권고합니다.