docs(reports): archive issue #5 consolidated cross-review report (Rev.2)

This commit is contained in:
Godopu committed 2026-09-06 13:27:40 +09:00
1 parent 47640e2fd7
commit fa59741a9b
1 file changed
+142
@@ -0,0 +1,142 @@
# 📊 Issue #5 기술 심층 검토 통합 보고서 (Rev. 2)
- **대상 이슈**: [Gitea Issue #5 — `[Refactor] lib.sh 작업 위임 로직 및 run_loop.sh 오케스트레이터의 Python 모듈화 (lib_py 승격)`](https://git.godopu.com/tmpl/multi-agent-mux/issues/5)
- **작성 주체**: Antigravity (총괄 오케스트레이터)
- **검토 참여자**: 3개 팀 리더 리뷰어 에이전트 전원 참여 (1차 검토 및 2차 교차 검토 완료)
- `planner-reviewer-claude-01`
- `reviewer-creator-grok-01`
- `planner-reviewer-codex-01`
- **검토 일시**: 2026-09-06 (Rev.1 발행 및 2차 정밀 교차 검증 반영)
- **기준 브랜치 / 커밋**: `refactor` (`47640e2`)
- **종합 합의 상태**: **파이썬 모듈화 방향성 만장일치 지지 (단, 자동완료 증거 계약·CAS 상태 전이·런타임 불변성의 필수 안전 조건 선결을 전제로 한 조건부 동의이며, 기계 판정용 최종 구현 PASS가 아님)**
---
## 1. 개요 및 합의 수준의 사실적 기술
본 보고서는 `lib.sh`의 작업 위임 로직 및 `run_loop.sh` 오케스트레이터 전체를 파이썬 패키지(`lib_py`)로 승격 및 모듈화하는 제안(Issue #5)에 대해, 세 팀 리더 리뷰어가 코드베이스 실측과 2차에 걸친 독립적 교차 분석을 통해 도출한 최종 정제 통합 보고서입니다.
세 리뷰어 모두 **파이썬 모듈화의 필요성과 아키텍처 방향성에 공통으로 찬성**합니다. 그러나 이 찬성은 "무조건적 구현 승인"이 아니며, 자동완료 오탐 방지, 다중 Writer 경합, 런타임 자기수정 크래시(B-13)의 단계적 해소 조건에 대해 엄격한 기술적 안전 계약이 수립되어야 함을 강력히 요구하고 있습니다.
### 📌 리뷰어별 평가 및 판정 토큰 현황 (사실 대조)
| 리뷰어 에이전트 | 세션명 | 1차 검토 Job | 2차 검토 Job | 공식 `[VERDICT: ...]` 토큰 | 종합 평가 성격 |
| :--- | :--- | :---: | :---: | :---: | :--- |
| **Claude** | `planner-reviewer-claude-01` | `1919bf5e` | `cdc926e3` | **미발행 (산문형 지지)** | 방향성 지지, Herdr 1급 API 실재 발견, 1,621줄 subprocess 테스트 재타겟팅 공수 경고 |
| **Grok** | `reviewer-creator-grok-01` | `9885ecd6` | `3e3b6d18` | **`[VERDICT: PASS]`** | 방향성 조건부 PASS, `interactive_ready` 배제 실측 증명, 15s 디바운스 및 6대 게이트 제시 |
| **Codex** | `planner-reviewer-codex-01` | `5da43b79` | `14f9eac4` | **미발행 (조건부 동의)** | 방향성 동의, 실행 귀속(Attribution)·리포트 확정 계약·단일 CAS 전이 필수 조건화 |
> 3명 중 1명(Grok)만 단독 행 `[VERDICT: PASS]` 토큰을 남겼으며, Claude와 Codex는 구체적 안전 조건을 요구하는 산문형 조건부 동의를 제출했습니다. 본 프로젝트의 엄밀한 fail-closed 계약에 따라 이를 "만장일치 최종 PASS"로 왜곡하지 않고 **"안전 계약 선결을 전제로 한 방향성 만장일치 합의"**로 명문화합니다.
---
## 2. 2차 교차 검증을 통해 복원된 핵심 안전 계약
세 리뷰어의 2차 정밀 피드백을 통해 1차 요약 과정에서 누락되거나 단순화되었던 핵심 엔지니어링 계약들이 복원되었습니다.
### 2-1. 실행 귀속(Execution Attribution) 보장 계약 (Codex 복원, 전원 지지)
- 단순히 터미널이 `idle`이라고 해서 완료로 판단해서는 안 됨 (세션 재사용 시 이전 작업의 잔여 유휴 상태 오인 위험).
- 자동완료 후보는 반드시 다음 **4중 식별자**가 일치해야 함:
`Job ID` + `Attempt ID` + `Agent/Session UUID` + `Pane/Process Generation`
- 디스패치 확인 시점 이후 해당 시도(Attempt)의 실제 실행 및 응답이 관측된 경우에만 완료 후보로 인정.
- 동일 에이전트 세션에는 동시에 단 하나의 Job만 배정.
### 2-2. 리포트 확정 계약의 단계적 진화 (Grok vs Codex 이견 정리)
- **1차/보조 필터 (Grok 제안)**: `report-final.md` mtime이 일정 디바운스 구간(기본 권장 ≥15초, monotonic clock 측정) 동안 불변일 것.
- **2차/강화 계약 (Codex 제안)**: 시간 경과(15s)만으로는 파일 쓰기 완료를 완벽히 증명할 수 없으므로, 임시 파일 작성 후 **원자적 이름 변경(Atomic Rename)** 및 `Attempt ID`와 `Report Hash`가 명시된 **완료 매니페스트(Finalization Manifest)** 생성을 최종 목표로 설정.
- **적용 규칙**: Phase 2a에서는 mtime 디바운스(15s)를 보조 필터로 검증하고, Phase 2b에서는 확정 계약 미지원 작업은 자동 완료 대신 "복구 후보/수동 확인"으로 남김.
### 2-3. 단일 상태 전이 주체(Engine)와 원자적 CAS (Compare-And-Swap)
- **책임의 엄격한 격리**:
- `watcher.py`: 오직 관측 증거(증거 튜플: Event, Herdr status, Report path/hash)만 수집하여 큐로 전달.
- `engine.py`: 락 하에서 상태 전이를 결정하는 **유일한 주체**.
- **원자적 상태 전이 불변식**:
- Agent의 `publish_event`와 Engine의 Watcher 감시 모두 **공통 전이 함수/서비스**를 사용.
- `expected attempt` 및 `비terminal(started/progress)` 상태임을 확인한 후 원자적으로 전이 (CAS).
- 명시적 `error` 또는 `cancelled` 상태를 자동 `completed`로 덮어쓰지 않음.
- 완료 확정 후 뒤늦게 도착한 `progress`나 `started` 이벤트로 상태를 역행시키지 않음.
- **잠금(Lock) 내 I/O 및 재진입 대기 위험 방지**:
- Registry Lock 유지 상태에서 자식 프로세스 호출(subprocess)이나 네트워크 I/O(MQTT)를 실행하지 않음.
- 짧은 트랜잭션으로 상태 확정 및 Pending Notification 기록 ➔ Lock 즉시 해제 ➔ 비동기 MQTT 발행 및 멱등 재시도 수행.
- `auth_token != null`인 경우 레지스트리의 토큰으로 HMAC 서명하여 정규 발행 (누락 시 silent drop 방지).
### 2-4. Herdr 네이티브 API의 정확한 호출 규격 및 예외 처리
- **옵션 명시 필수**:
- `herdr agent wait <target>`의 CLI 기본값은 `idle, done, or blocked`이며, `blocked`는 permission_required나 입력 대기 상태이므로 완료가 아님.
- 따라서 Watcher는 반드시 상태를 명시적으로 지정하여 호출해야 함:
`herdr agent wait <TARGET> --until idle --until done --timeout <MS>`
- **`interactive_ready`의 성격 규정**:
- 에이전트가 코딩 작업 중(`agent_status=working`)일 때도 `interactive_ready=true`임이 실측으로 증명됨.
- 따라서 `interactive_ready`는 완료 충분조건이 아니며, 오직 `agent_status in {"idle", "done"}`만 완료 후보로 인정.
- **소켓 단절 및 버전 드리프트 가드**:
- Herdr 소켓 단절 시 반환되는 `unknown`을 idle로 오인하지 않고, 재연결 백오프 및 스냅샷 재동기화를 수행.
- 의존하는 Herdr CLI/JSON 필드의 최소 호환 버전을 검증하고, 불일치 시 fail-closed(수동 확인)로 폴백.
### 2-5. 특수 작업에 대한 예외 및 Fail-Closed 원칙
- **외부 부수효과 작업 예외**:
- Gitea 댓글 등록, Git push, 배포 등 리포트 파일 생성 외에 외부 시스템에 부수효과를 일으키는 작업은 리포트 파일 존재만으로 자동완료 처리하지 않음 (외부 실행 완료 증거가 없을 경우 수동 확인 유지).
- **무판정 Reviewer 리포트 처리**:
- Reviewer 작업의 리포트 마지막 줄에 `[VERDICT: PASS]` 또는 `[VERDICT: NOT PASS]` 토큰이 누락된 경우, `completed` 승격 절대 금지.
- 작업 deadline 도달 시 명시적 `error` 발행 또는 반려 처리 (Fail-Closed 엄격 유지).
- Reviewer의 `completed`(리뷰 행위 완료)와 `PASS`(검증 통과)를 절대 혼동하지 않음.
---
## 3. 합의된 안전 상태 머신 아키텍처
```mermaid
flowchart TD
subgraph Watcher["이중 감시 체계 (Watcher - 관측 증거 수집 전용)"]
W1["채널 1: MQTT 이벤트 스트림 및 로컬 작업 레코드"]
W2["채널 2: herdr agent wait --until idle --until done"]
W3["파일 증거: 지정 경로 report-final.md mtime 디바운스 (≥15s)"]
end
subgraph Gate["안전 검증 게이트 (Fail-Closed AND Gate)"]
G1{"4중 귀속 일치?\n(Job ID + Attempt + UUID + Generation)"}
G2{"agent_status in (idle, done)?\n(interactive_ready 단독 불인정)"}
G3{"리포트 확정 완료?\n(디바운스 경과 및 매니페스트 확인)"}
G4{"Reviewer: 마지막 행 정식 판정 토큰 존재?"}
G5{"외부 부수효과 작업 여부 확인\n(부수효과 시 별도 증거 필요)"}
end
subgraph Engine["단일 상태 제어 엔진 (Engine - 배타적 전이)"]
E1["공통 상태 전이 트랜잭션 (CAS Lock)"]
E2["Terminal State Commit & Pending Notification 기록"]
E3["Lock 해제"]
E4["정규 publish_event 경로로 이벤트 발행 (HMAC 서명)"]
E5["다음 루프 단계 디스패치"]
end
W1 & W2 & W3 --> Gate
G1 & G2 & G3 & G4 & G5 -->|모두 충족 (AND)| Engine
Gate -->|하나라도 미충족| Wait["계속 대기 (Wait / Fail-Closed)"]
```
---
## 4. 4단계 마이그레이션 로드맵 (세부 기준 보완)
| 단계 | 작업 목표 | 상세 구현 내용 및 필수 완료 기준 (Gate) |
| :--- | :--- | :--- |
| **Phase 0** | **사전 계약 고정 및 Fixture 수집** | • CLI, 상태 이벤트, 리포트 형식, 락 계약 기준선 문서화<br>• Herdr 6개 어댑터별 런타임 상태 전이 fixture 수집<br>• 미합의 기술 항목(디바운스 vs 매니페스트)의 단계별 채택 기준 확정 |
| **Phase 1** | **`lib_py/delegation/` 구축** | • `lib.sh` L1833 위임 헬퍼를 파이썬 서비스 클래스로 추출<br>• `start_watchdog`은 실제 역할에 맞춰 `ensure_subscriber_daemon`으로 명명<br>• 인메모리 단일 MQTT 연결 재사용 프로토타입 (레이턴시는 벤치마크로 보고)<br>• 기존 CLI/non-fatal/HMAC/seq/디스크 폴백 회귀 100% 통과<br>• **자동완료 정책 변경 없음, 세션 DB와 Job 레지스트리 저장소 통합 시도 금지** |
| **Phase 2a** | **`lib_py/loop/` 코어 & Shadow Watcher** | • `engine.py` (단일 전이 주체), `watcher.py` (`herdr agent wait` 래핑) 구현<br>• 자동완료는 수행하지 않고 "Would-Complete" 로깅만 수행하는 Shadow 모드 가동<br>• 소켓 단절/재연결 백오프, 부분 리포트, 승인 대기, 도구 실행 시뮬레이션 검증 |
| **Phase 2b** | **이중 감지 자동완료 활성화 (Flag-Gated)** | • 4중 실행 귀속 + 리포트 확정 계약 + 단일 CAS 전이 게이트 검증<br>• 부수효과 작업 예외 규정 및 무판정 fail-closed 단위 테스트 완료<br>• 기본 off 플래그로 배포 후 검증 완료 시 기본값 활성화 |
| **Phase 3** | **`run_loop.sh` Thin Wrapper 전환 및 회귀** | • `run_loop.sh`를 인자 전달 래퍼(`exec python3 -m lib_py.loop "$@"`)로 전환<br>• `--creator` 필수, `--target-agent` 거부, bash 3.2, PYTHONPATH 계약 보존<br>• 5개 subprocess 전용 테스트(~1,621줄) 포함 **현행 전체 469개 테스트 0-Fail**<br>• **신·구 엔진의 동일 작업공간 동시 Writer 병행 금지** |
| **Phase 4** | **불변 런타임 검증 및 B-13 정리** | • 기동 시 전체 모듈 상주(Eager Import) 및 자식 인터프리터/템플릿 불변성 검증<br>• 작업 도중 스킬 파일 교체 및 늦은 경로(재심/승격/롤백) 스트레스 테스트 통과<br>• `/tmp/mam-loop-freeze.XXXXXX` 셸 임시 우회책 완전 제거 및 문서화 |
---
## 5. 명시적 비범위(Out of Scope) 및 호환성 계약
1. **저장소 통합 금지**: 본 리팩토링에서 TMUX 세션 관리용 SQLite/YAML 저장소와 비동기 작업 관리용 `.mam/jobs/` JSON 레지스트리를 하나로 통합하려 시도하지 않습니다 (목적과 수명이 다름).
2. **원샷 스킬의 Live Tree 사용 유지**: `multi-agent-mux-create`, `resume`, `stop` 등 단발성 셸 스크립트는 Freeze 복사본이 아닌 실제 작업 트리의 코드를 실행하도록 유지합니다.
3. **타임아웃의 3원 분리 보존**: (a) 전체 벽시계 타임아웃, (b) MQTT 가입자 idle-timeout, (c) TUI idle 자동완료를 독립적으로 유지하며, 자동완료가 기존 타임아웃 메커니즘을 덮어쓰지 않습니다.
---
## 6. 결론
2차 교차 검토를 통해 본 통합 보고서는 세 리뷰어의 실질적 발견과 기술적 차이를 충실히 수렴하여 완성도를 대폭 끌어올렸습니다.
모든 리뷰어가 지적한 대로 **Phase 0(사전 계약 및 어댑터 fixture 정리)** 을 즉시 수립한 후, **Phase 1(`lib_py/delegation/` 구축 및 안전한 서비스 추출)** 에 착수하는 것이 가장 안전하고 확실한 진행 경로입니다.