Files
multi-agent-mux/IMPROVEMENTS.md
T
Godopu ac82f9b993 fix(mqtt): resolve B-9 by implementing lazy get_logs_dir() evaluation
- Replace import-time LOGS_DIR cwd binding with dynamic get_logs_dir() function
- Implement PEP 562 __getattr__ and __dir__ for transparent LOGS_DIR backward compatibility
- Update audit-log callers in mqtt_common.py and registry.py to use dynamic resolution
- Add 5 regression guards in tests/test_tier1_unit.py (276/276 PASS)
- Update IMPROVEMENTS.md, VERSIONS.md, registry.md, and include plan and peer review reports
2026-08-17 13:37:51 +09:00

331 lines
43 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 🛠️ Multi-Agent Mux 종합 개선 및 미해결 과제 백로그 (`IMPROVEMENTS.md`)
- **최종 갱신일**: 2026-08-17 (B-9 감사 로그 루트 지연 평가 완료, B-13/Stage 2 완료, B-10 완료, B-5 종결, C-6 완료, 전체 276/276 회귀 통과 반영)
- **통합 관리 대상**: 기존 `CODEBASE_REVIEW_REPORT.md` + `OPTIMIZATION.md`
- **총 추적 미해결 과제**: **1건** (아키텍처 1건, 엣지케이스 0건, 오케스트레이션 0건, 레거시 잔재 0건)
- **완료된 과제**: **24건** (A-1, A-3, A-4, A-5, B-1, B-3, B-4, B-5, B-7, B-8, B-9, B-10, B-13, C-1, C-2, C-3b, C-6, O-1, O-2, O-3, O-4-OrcOnboard, Herdr-0.8.0-Compat-SanitizeHash, P2-1-DelegateJobSafe-TrapFix, P2-2-C3a-C4-LegacyCleanup)
---
## 📌 개요
본 문서는 Multi-Agent Mux (MAM) 프레임워크의 **코드베이스 아키텍처 결함, 런타임 엣지케이스, 레거시 잔재****`/multi-agent-mux-loop` 오케스트레이션 최적화 과제**를 단일 백로그로 통합 추적하기 위한 종합 관리 문서입니다.
---
## 1. 🔴 아키텍처 결함 (Architecture Flaws — 1건)
### **A-2: 공개 브로커 + HMAC 인증 Off + 와일드카드 전파**
- **현상**: `mqtt_common.py`의 기본 브로커가 공개 서버(`broker.hivemq.com`)이고, 잡 생성 시 `auth_token`**한 번도 발급되지 않아**(실측 26/26 잡이 `auth_token=None`) `verify_hmac``if not auth_token: return True` 경로가 항상 타집니다. 발행자는 워크스페이스 지문 토픽을 채택하지 않고 전역 `python/mqtt/jobs/<job_id>/events` 로 발행하며, `reconcile.sh:237` 이 같은 전역 토픽을 구독합니다. (HMAC 구현 자체는 정상입니다 — 토큰이 없어 검증이 공허해지는 것이 원인입니다.)
- **파급 효과**: 외부에서 유입되는 malicious `error` 이벤트 수신 시 `reconcile.sh`가 라이브 에이전트 pane을 `kill-session`으로 강제 파괴하는 치명적 보안/안정성 위험이 존재합니다.
### **A-4 (✅ 완료 — P3-1): 에이전트 지식 산재 — `BaseAgentAdapter` 어댑터 계층 도입 (Rev.2)**
> 결함 조치가 아니라 **구조 개선 제안**입니다. 상세 설계·실측 근거는 `.mam/jobs/44062a63/claude-reports/report-final.md` 및 `744ac67a` 를 참조하십시오.
- **현상**: "claude 의 transcript 는 어디 있나", "cline 재개 argv 는 무엇인가" 같은 **에이전트에 대한 사실**이 스크립트 8개 · **34개 팬아웃 지점**에 흩어져 있습니다. (8줄 윈도 안에 4개 에이전트 중 3개 이상이 등장하는 지점 기준: `create_session.sh` 8, `reconcile.sh` 7, `stop_session.sh` 6, `lib.sh` 4, `resolve_session_id.sh` 3, `resume_session.sh`/`update_yaml_resumed.sh`/`run_loop.sh` 각 2)
- **사본 현황**: `agent → *_id_own` 키 맵 **4벌**, `~/.claude/projects` 17참조, `antigravity-cli/conversations` 11참조, `.hermes/state.db` 6참조, `.cline/data/sessions` 5참조.
- **파급 효과**: 같은 질문에 **서로 다른 답**이 공존합니다. 세션명→에이전트 추론이 `reconcile.sh::row_agent`(pane.cmd → cmd_full → 이름 접미사)와 `run_loop.sh:236-243`(세그먼트 매칭 + 실패 시 `claude` 기본값) 두 벌로 존재하며 후자는 오판 가능합니다. b4a1d094 에서 드러난 "격리 분기 inert" 결함도 아티팩트 경로 규칙이 두 벌이었던 데서 비롯됐습니다.
#### 설계 요지 (Rev.2 갱신)
- **`.agents/skills/mam_agents/`** 패키지(약 484줄): `base.py`(ABC + `SpawnSpec` + `DiscoveryContext`), `registry.py`(정적 레지스트리), `__main__.py`(셸 브리지), `adapters/{claude,agy,hermes,cline}.py`.
- **인터페이스**: `own_key` / `supports_assigned_id` / `ready_tokens` 속성 + `auth_ok(run)` · `spawn_spec()` · `resume_spec(binary, uuid, materialized)` · `artifact_path(uuid, ctx)` · `verify_artifact(uuid, ctx)` · `discover(ctx)`.
- **`DiscoveryContext` & `discover()` 템플릿 메서드**: `cwd`(물리 절대경로), `ws_key`, `home`, `claude_dir`, `iso_root`, `epoch`, `claimed` 필드를 객체 하나로 캡슐화. `_raw_candidates(ctx)` 추상 메서드로 어댑터별 물리 탐색만 서술하고 `claimed`/`epoch` 필터는 기반 클래스 템플릿이 100% 보장.
- `auth_ok` 는 서브프로세스 실행자를 **주입**받아 CLI 미설치 환경에서도 단위 테스트가 가능합니다(hermes 는 현재 미설치).
- `resume_spec``materialized` 파라미터가 b4a1d094 규칙(`claude -r <미실현 uuid>` 실패 → `--session-id`)을 흡수합니다.
- `ready_tokens` 속성을 어댑터로 내보내 `wait_for_tui_ready` 의 25줄 inline shell `case` 블록을 단 1줄의 `grep -E -q "$MAM_READY_TOKENS"` 로 축소.
- **레지스트리 패턴**: **정적 dict 채택.** `entry_points` 는 MAM 이 `pip install` 되지 않고 `rsync`/`cp` 로 배포되므로 부적합, 디렉터리 스캔은 "0개 발견"과 "에이전트 미설치"가 구분되지 않아 부적합.
- **bash↔python 브리지**: `python -m mam_agents facts <agent>``shlex.quote``KEY=value` 를 출력. **스크립트당 1회 `eval`** 이 계약입니다(실측 22.8 ms/호출 vs bash `case` 2.3 ms — 분기마다 호출하면 안 됨).
#### 실현 가능성 및 부트스트랩 (Rev.2 실측)
- 파이썬 진입점 **3종 전부**에서 import 확인: `env_python`, `atomic_dump_yaml`(flock 쓰기 경로), venv 없는 **맨 `/usr/bin/python3`**.
- **`lib.sh` source 시점 1회 `export PYTHONPATH`**: `lib.sh` 로드 시 `_mam_export_pythonpath``mam_skills_dir``PYTHONPATH` 에 자동 얹어 `run_loop.sh` 등 셸 상의 모든 `python3 -c` 호출이 한 번에 호환됨.
- herdr shim 내부 `python3 -c` **9곳 전부 에이전트 지식 0** → shim 경계가 이미 올바른 위치에 있습니다.
- **제약(규칙화 필요)**: 어댑터는 **표준 라이브러리만** 사용해야 합니다. 서드파티 의존성이 들어오면 venv 없는 경로가 깨집니다.
#### 선행 필수 체크리스트 (누락 시 조용히 업그레이드가 막힘)
1. **`deploy/remove.sh:83-91` `fallback_assets``".agents/skills/mam_agents"` 등록.**
미등록 시 `tests/test_deploy_freshness.py::test_d2` 가 실패하며(프로토타입에서 실제 발생), 언인스톨 후 잔존 자산이 워크스페이스를 **영구히 구버전에 고정**시킵니다(`install.sh` 는 비-스킬 자산을 "없을 때만" 복사).
2. `deploy/install.sh` 무결성 자산 목록 등록.
3. `deploy/gitea-ci.yml:69-77``flake8` / `py_compile` 경로 추가 — 현재 CI 파이썬 잡은 `multi-agent-mux-delegate-job/scripts/` 만 검사하므로 신규 패키지는 린트 사각지대입니다.
#### 단계적 이행 (각 단계는 셸 사본 제거를 같은 커밋에 포함)
| 단계 | 내용 |
|---|---|
| M0 | 패키지 골격 + `lib.sh` source 시점 `PYTHONPATH` export + 배포/CI 등록 |
| M1 | `own_key` / `agent_of_row` 이관 — **프로토타입 검증 완료: 팬아웃 34 → 29** |
| M2 | `artifact_path` + `verify_artifact` (`verify_session_uuid` 4분기, `DiscoveryContext` 적용, 격리 경로 일원화) |
| M3 | `spawn_spec` / `resume_spec` / `auth_ok` (create·resume argv 및 프리플라이트) |
| M4 | `discover()` (raw candidates + base class template filter) — hermes DB 스키마 실측 선행 |
| M5 | `stop_session.sh` purge 경로 및 exit key |
| M6 | `ready_tokens` 어댑터 이관 (`wait_for_tui_ready` 25줄 case 제거) |
| M7 | claude ready tokens 에서 `projects` 제거 및 자체 검증 분리 커밋 |
- **정직한 상한**: 34 → **약 10**. 남는 약 10곳은 셸 상주 TUI·프로세스 제어(`send_keys_safe` 의 agy/claude/cline 분기, `handle_startup_dialogs`, spawn 래퍼 분기, `pgrep -P` 자식 pid 게이트)로 이 추상화의 대상이 아닙니다.
- **중단 기준**: M2 이후에도 팬아웃이 29 → 20 이하로 떨어지지 않으면 중단하고 잔여 단계를 재검토합니다.
- **검증 상태**: Rev.2 프로토타입 기준 전체 회귀 **162 passed (회귀 0)**, 변이 6/6 검출, 배포 스위트 25/25, `py_compile` 통과.
---
## 2. 🟠 엣지 케이스 및 런타임 버그 (Edge-case Bugs — 0건 — 전원 완료)
---
## 3. 🟡 오케스트레이션 최적화 과제 (Orchestration Optimizations — 0건 — 전원 완료)
---
## 4. ⚪ 레거시 잔재 및 죽은 코드 (Legacy Remnants — 0건 — 전원 완료)
---
## 5. 🎉 완료된 과제 (Completed Tasks — 24건)
### **B-9 (P4-1): `LOGS_DIR` import 시점 cwd 고정 해소** — ✅ 완료
- `mqtt_common.LOGS_DIR` 이 모듈 import 시점의 `os.getcwd()` 로 절대화되어, 이후 프로세스가 `chdir` 하면 감사 로그가 옛 경로에 계속 쌓이던 문제를 해소했습니다(실측 재현). 경로 해석을 호출 시점으로 미루는 `get_logs_dir()` 를 도입하고 모듈 전역 대입을 제거했습니다.
- **하위 호환**: PEP 562 모듈 `__getattr__``mqtt_common.LOGS_DIR` 속성 접근을 그대로 유지하되 동적으로 평가합니다. 저장소 내 `from mqtt_common import LOGS_DIR` 사용은 0건임을 전수 확인했으므로 호환 표면이 100% 덮입니다.
- **가시성 & 탐색성**: PEP 562 `__dir__` 을 함께 정의해 `dir(mqtt_common)` 및 탭 완성에서 `LOGS_DIR` 이 계속 보이도록 했습니다(`hasattr``__getattr__` 만으로도 동작하므로 별개입니다).
- **부수 개선**: `DELEGATE_JOB_LOGS_DIR` 환경변수가 이제 실행 중 변경까지 반영됩니다(종전에는 import 이후 변경이 무시되었습니다).
- 같은 파일의 `DEFAULT_REGISTRY_DIR` 은 상대 문자열로 남아 있어 애초에 이 결함이 없었습니다 — B-9 의 본질은 "함수가 아니라 **절대화 시점**"이었습니다.
- 회귀 가드 5종을 신설했습니다. 감사 로그 계층은 best-effort `except Exception` 으로 예외를 삼키므로, 잘못된 수정은 **무음 로그 소실 + 전 테스트 통과**로 나타납니다(실측). 이에 가드 하나는 문자열이 아니라 **실제 파일 생성**을 단언하도록 설계했습니다.
### **B-13 (Stage 2): 셀프 호스팅 루프 런타임 프리즈 스냅샷** — ✅ 완료
- 루프 기동 시 `.agents/skills/``$TMPDIR` 의 임시 디렉터리에 1회 동결하고 그 스냅샷에서 재실행(`exec`)하도록 하여, 턴 도중 Worker 가 프레임워크 스킬을 편집해도 진행 중인 루프가 영향을 받지 않게 했습니다. 상태·저장소 경로는 `MAM_REAL_ROOT`/`WORKSPACE_ROOT` 로 실제 루트를 계속 가리키므로 레지스트리·락·diff 수집 동작은 종전과 동일합니다.
- **계층 B 신규 대응**: bash 가 실행 중인 스크립트를 바이트 오프셋 기준으로 계속 읽는다는 사실을 실측 확인하여(정상 교체본에도 `unexpected EOF` 발생), 래퍼뿐 아니라 `run_loop.sh` 본체까지 동결 대상에 포함했습니다.
- **B-6 과의 구분**: B-6 이 제거한 것은 *위임 매 호출마다 스킬 트리 내부에* 만들던 `.tmp` 사본이고, 본 조치는 *기동 시 1회 트리 외부에* 만드는 스냅샷입니다. 스킬 트리에는 아무것도 쓰지 않으며 기존 가드 `test_z9_no_tmp_copy_left_in_skill_tree` 가 그대로 통과합니다.
- **결함 교정 (P1/C1/C2)**: 인자 파서의 `$@` 소진에 대비해 최상단에서 `MAM_LOOP_ARGV` 배열 포획, `export MAM_LOOP_FREEZE_OWNED="1"` 로 정리 게이트 누수 차단, `log_*` 정의 전 구간 `echo` 직접 사용으로 폴백 시의 구문 오류 크래시를 원천 방지했습니다.
- 정리 로직은 새 트랩을 추가하지 않고 기존 `_mam_release_guard` 를 확장했습니다 — `trap … EXIT` 중복 설치는 기존 핸들러를 조용히 대체하며(실측), 이는 B-12 와 동일한 계열의 사고입니다.
- 회귀 가드 5종(`test_b13_reexec_preserves_original_argv`, `test_b13_freeze_survives_broken_wrapper`, `test_b13_freeze_dir_is_outside_the_skill_tree`, `test_b13_release_guard_cleans_up_and_releases_lock`, `test_b13_no_freeze_switch_disables_reexec`)을 신설하고 뮤테이션 M0~M6 으로 방어력을 검증했습니다.
### **B-10 (P3-2): `agent_identities` tier-3 신원 캐시 완전 제거 (Option A)** — ✅ 완료
- 저장소 전체에 `agent_identities` 쓰기 코드가 0건임을 재확인하고(라이브 `.db` 최상위 키에도 부재), 구조적으로 히트 불가였던 읽기 경로 3곳을 제거했습니다 — `workspace_uuid.py` tier-3 폴백(28줄), `reconcile.sh` drift D 진단(35줄), `stop_session.sh` purge 시 캐시 소거(6줄), 관련 주석 3곳. UUID 해결은 tier-1(per-row own id) → tier-2(어댑터 `discover()`) 2단계로 단순화되었습니다.
- **PyYAML 의존 — 실행 경로 기준으로 해소**: `verify_session.py::mam_orchestrator_uuids``yaml` 을 함수 진입 즉시 import 하고 있어(`:10`), tier-3 을 지워도 UUID 해결 경로는 PyYAML 을 요구했습니다. `state.py` 의 기존 선례대로 YAML 폴백 분기 안으로 이동시켜 교정했습니다.
- **정정**: 원 항목이 서술했던 "`lib.sh` 의 PyYAML 하드 의존" 은 `load_state_json``state.py` 로 이관되며 **이미 해소된 상태**였습니다. 한편 `atomic_yaml.py` 는 모듈 존재 이유상 앞으로도 최상단에서 import 하므로 **저장소 차원의 PyYAML 요구와 설치 게이트는 유지**됩니다.
- 회귀 가드 3종(`test_b10_no_agent_identities_reader_in_production`, `test_b10_workspace_uuid_has_no_yaml_import`, `test_b10_find_workspace_uuid_runs_without_pyyaml`)을 신설하고 뮤테이션 5종(M1·M2·M3a·M3b·M4)으로 방어력을 검증했습니다.
### **B-5: macOS NFS 감지 `df -P` 폴백 검증 및 종결** — ✅ 완료 (종결)
- `_check_is_nfs`(`lib.sh:1181-1192`)에서 macOS/BSD 환경 시 GNU 전용 `df --output=target` 실패(`rc=64`)에 대비한 `df -P "$f" | tail -1 | awk '{print $6}'` POSIX 폴백이 정상 동작함을 실측 및 단위 테스트(`test_stop_check_is_nfs_local`)로 검증 완료하여 종결 처리했습니다.
### **C-6 (P2-3): `stop_session.sh` 레거시 주석 및 구버전 사용법 정리** — ✅ 완료
- 헤더 주석이 광고하던 `--mode soft|hard` / `--capture-id` / `--graceful` 3종은 파서가 `exit 2` 로 거부하는 폐지 플래그였습니다. 헤더 29줄을 현재 CLI 에 맞게 교체하고, `usage()` 에 누락돼 있던 옵션 설명과 `--agent` 접미사 추론 동작을 보강했으며, Option B 이후 무의미해진 "워크스페이스에 격리된" 표현과 내부 주석 3곳의 플래그 표기를 정리했습니다.
- `MESSAGING.md` 상태 표가 제거된 플래그로 `stopped`/`terminated` 를 정의하던 것을 교정하고, 생산자가 사라진 `archived` 를 레거시 값으로 명기했습니다.
- 도움말과 파서의 일치를 강제하는 회귀 가드 `test_comp_stop_usage_matches_parser` 를 신설하고 뮤테이션 3종(M1~M3)으로 방어력을 검증했습니다 — C-6 은 문서 과제라 기존 테스트가 전혀 잡지 못하던 영역입니다.
### **P3-1 (A-4 Phase 2 / Option B / C-3b / M2~M7): 에이전트 지식 계층 어댑터 일원화 및 isolation.root 완전 폐기** — ✅ 완료
- 에이전트별 아티팩트 경로, 검증 로직, 재개/시작 스펙, 토큰, 종료 키, 인증(`auth_ok`), 자동 발견(`discover`)을 `BaseAgentAdapter` 및 4개 구체 어댑터(`claude`, `agy`, `hermes`, `cline`)로 이관하고, CLI facts bridge(`shlex.quote`) 및 서브커맨드(`spawn-spec`, `resume-spec`, `exit-key`)를 구축했습니다.
- Universal Global Config 전환 후에도 남아있던 `isolation.root` 4개 소비자(`lib.sh`, `verify_session.py`, `workspace_uuid.py`, `stop_session.sh`, `atomic_yaml.py`)를 완전 폐기(Option B)했습니다.
- 전용 계약 테스트 스위트 `tests/test_a4_adapter_contract.py` (9/9 PASS) 및 전체 회귀 테스트 **259/259 PASS (100%)** 를 달성했습니다.
### **P2-2 (C-3a / C-4): 격리 빈 스텁 4종·공허한 테스트 4건·미사용 심볼 3종 제거** — ✅ 완료
- `.agents/skills/lib.sh` 의 백워드 호환 빈 스텁 `provision_isolation` / `isolation_lever` / `isolation_env_prefix` / `isolation_cmd_args` 4종(프로덕션 호출자 0건)을 제거하고, 주석 블록에 C-3b(`isolation.root` 행 필드) 경계를 명시해 후속 정리 시 오삭제를 차단했습니다.
- 위 스텁의 빈 출력만 재확인하던 공허한 테스트 4건(`tests/test_tier1_unit.py` 3, `tests/test_tier2_component.py` 1)을 제거하고, 그 자리에 `--isolate`/`--no-isolate` 레거시 no-op 플래그의 인자 파서 계약을 고정하는 `test_create_session_legacy_isolate_flags_noop` 1건을 신설했습니다. 신규 테스트는 분기 삭제·한쪽만 삭제·조용한 no-op 화·usage 문서 줄 삭제 4종 변이를 모두 검출함을 변이 검사로 입증했습니다. `test_tier1_unit.py:31` 섹션 헤더도 `(5 Test Cases)` 로 동기화했습니다.
- 참조 0회 미사용 심볼 3종을 제거했습니다: `_REAL_HERDR_PATH`(`lib.sh:126-127`, 대입+export만 — `_resolve_real_herdr_path` 의 stdout/rc 반환 채널은 불변임을 실측 확인), `TERMINAL_STATUSES`(`registry.py:38`, `__all__` 미포함으로 임포트 계약 불변), `ISOLATE`(`create_session.sh:57`, `set -u` 하 숨은 확장 불가능).
- `_HERDR_SHIM_DIR_PATTERN` / `_HERDR_SKILLS_BIN_PATTERN`(`lib.sh:83-84``:105` 사용 중), `VALID_STATUSES`(`registry.py:150-151` 사용 중), `--isolate`/`--no-isolate` 레거시 호환 분기, C-3b 소비자 4곳은 계획대로 미접촉입니다.
- 전체 회귀 **256/256 PASS (100%)** 로 입증했습니다 (259 → 256, 순감 3 = 제거 4 신설 1).
### **P2-1 (B-6 / B-12): `delegate_job_safe` 임시 사본 제거 및 서브셸 루프 락 조기 해제 차단 조치** — ✅ 완료
- `.agents/skills/multi-agent-mux-loop/scripts/run_loop.sh``delegate_job_safe``.agents/skills/...` 경로 내에 `.tmp` 사본을 생성하던 방식을 제거하고 원본 래퍼 스크립트를 인플레이스로 직접 실행(`bash "$orig_script" "$@"`)하도록 개선하여 버전 관리 트리 오염 및 rsync 배포 유출(B-6)을 완전히 해소했습니다.
- 명령 치환(`$(delegate_job_safe ...)`) 서브셸 내에 설치되던 `trap _mam_release_guard EXIT` 로 인해 첫 번째 위임 잡 종료 시점에 `.mam/loop-guard-active` 마커가 삭제되어 O-3 Scoped Guard 및 O-2 락이 무력화되던 인접 P0 결함(**B-12 / D1**)을 로컬 트랩 제거를 통해 근본 해결했습니다.
- 래퍼 스크립트 실행 실패 시 도달 불가능하던 에러 진단을 `delegate_job_safe` 내부에서 직접 표준오류로 출력(`log_error "delegate_job_safe failed (exit $rc)..."`)하도록 진단 로깅을 보강했습니다.
- `tests/test_o3_scoped_guard.py` 내 Z-9 테스트를 4개 세부 행위 기반 테스트(`test_z9_loop_lock_survives_delegation`, `test_z9_probe_detects_the_defect`, `test_z9_no_tmp_copy_left_in_skill_tree`, `test_z9_exit_code_and_diagnostics_propagation`)로 교체 검증했습니다.
### **multi-agent-mux-orc-onboard: 오케스트레이터 온보딩 스킬 및 `orchestrator_uuids` 배제 게이트 조치** — ✅ 완료
- `.agents/skills/multi-agent-mux-orc-onboard/` 스킬 및 `.agents/skills/multi-agent-mux-orc-onboard/scripts/orc_onboard.sh` 헬퍼 모듈을 생성하여, 메인 오케스트레이터가 프로젝트 맥락 파악 시 자신의 대화 UUID를 포착해 `.mam/agent-sessions.yaml` 및 SQLite DB 내 `orchestrator_uuids` 리스트로 원자적 기록하는 구조를 구축했습니다.
- `.agents/skills/lib.sh``find_workspace_uuid``verify_session_uuid` 함수를 갱신하여 `orchestrator_uuids` 리스트에 포함된 오케스트레이터 대화 ID를 서브 에이전트(`canary-projects-multi-agent-mux-creator-agy`)의 `find_workspace_uuid``capture_conversation_id` 탐색 대상에서 100% 스킵(Skip)하는 배제 게이트를 수립하여 오케스트레이터 대화 DB 오염 및 SQLite DB 락 결함을 원천 해결했습니다.
- 전용 회귀 테스트 스위트 `tests/test_orc_onboard.py` (40/40 PASS)를 작성하여 입증했습니다.
### **P0-2 (O-2): 동일 워크스페이스 내 중복 루프 기동 방지 원자적 락 및 마커 소유권 대조 삭제 조치** — ✅ 완료
- [`.agents/skills/multi-agent-mux-loop/scripts/loop_lock.sh`](file:///Users/godopu16/PuKi/laa/canary_projects/multi-agent-mux/.agents/skills/multi-agent-mux-loop/scripts/loop_lock.sh) 헬퍼 모듈을 작성하여, `set -C` (noclobber) 기반 원자적 락 생성 및 마커 임시 쓰기+Atomic Rename 구조를 구축했습니다.
- 마커 상의 `pid` + `lstart`(프로세스 시작시각) 신원 대조 검증을 수행하여, 동일 워크스페이스 내 중복 루프 기동 시 이를 감지하고 안전하게 기동을 차단합니다.
- 종료 트랩(`_mam_release_guard`) 시 마커 파일 상의 `pid``lstart` 가 자기 자신과 100% 일치할 때만 마커를 삭제하도록 소유권 대조 삭제를 수립하여, 타 루프 인스턴스의 마커를 실수로 제거하여 O-3 가드레일을 무력화시키는 결함을 원천 차단했습니다.
- 전용 회귀 테스트 스위트 `tests/test_o2_race_free_lock.py` (22/22 PASS) 및 전체 회귀 테스트 스위트 (46/46 PASS)를 작성하여 입증했습니다.
### **P0-1 (B-7): `run_loop.sh` 루프 기동 외곽 diff 누락 및 신규 미추적 파일 캡처 결함 조치** — ✅ 완료
- `.agents/skills/multi-agent-mux-loop/scripts/diff_collect.sh` 헬퍼 모듈을 작성하여, `run_loop.sh` 가 어느 CWD 에서 기동되더라도 항상 `$REPO_ROOT` 기반으로 안전하게 이동하여 `git diff` 를 수행하도록 CWD 독립성을 확립했습니다.
- Git 인덱스를 오염시키는 `git add -N` 대신, `git ls-files -o --exclude-standard -z``git diff --no-index --binary /dev/null "$f"` 구문을 조합하여 에이전트가 **새로 생성한 신규 미추적 파일(Untracked Files)까지 100% diff에 안전하게 병합**시키는 기법을 구현했습니다.
- diff 가 500줄 또는 30KB 를 초과할 경우 `--stat` 요약으로 전환하되, **리뷰어 프롬프트에 `[WARNING: Truncated]` 경고 태그를 명시적으로 노출**하여 감춰진 PASS 판정을 원천 차단했습니다.
- 멀티에이전트 자율 오케스트레이션 루프(`run_loop.sh --plan --all-reviewer`)를 통해 Planner(`claude`), Creator(`agy`), Reviewer(`cline`) 3자에 의해 구현 및 교차 검증 후 **`[VERDICT: PASS]` (만장일치 통과)** 되었습니다.
- 전용 회귀 테스트 스위트 `tests/test_b7_diff_untracked.py` (20/20 PASS)를 작성하여 입증했습니다.
### **Rev.2 (b4a1d094): 생성 시 세션 ID 자동 할당 및 Reconciler 고정/경로 정규화 프로토콜** — ✅ 완료
- 신규 `claude` 세션 생성 시 `mam_gen_uuid`로 UUID를 즉시 생성하여 `--session-id <uuid>`로 전달하고, `session_id_source: assigned`, `session_id_verified: false`로 등록하는 원자적 고정 구조를 구축했습니다.
- 첫 사용자 메시지 전달 시 디스크 트랜스크립트 `.jsonl` 생성을 모니터 루프(`reconcile.sh` drift C0)가 감지하고 `session_id_verified: true`, `last_visible_status: pinned`로 고정시킵니다.
- 미할당 다수 후보 발견 시 무작위 고정을 금지하고 `C-ambiguous` 상태를 명확히 보고하도록 강화했습니다.
- 심볼릭 링크/트레일링 슬래시/상대경로 계산 시 `mam_abs_workspace``mam_workspace_key` (`cd -P && pwd -P` / `os.path.realpath`) 경로 정규화를 전수 적용하여 100% 키 일치성을 확립했습니다.
- 전용 단위/통합 테스트 스위트 `tests/test_uuid_target.py` (13/13 PASS) 및 전체 회귀 테스트 스위트를 검증 완료했습니다.
### **B-4: 시프트 `ls`의 `created` 동적 POSIX 타임스탬프 복원 및 재개 가드 정상화** — ✅ 완료
- `.agents/skills/lib.sh` 554번 라인의 `999999` 하드코딩 출력을 제거하고, real herdr 또는 `.mam/agent-sessions.yaml` 에 기록된 세션 생성 시각(`created`/`created_at`/`created_epoch`) 및 동적 POSIX 타임스탬프(`int(time.time())`)를 리턴하도록 정제했습니다.
- `reconcile.sh` drift-B 감지 시 epoch 0 및 `1970-01-01` 오기록 결함을 차단하여 `find_workspace_uuid` 재개 가드가 정상 작동하도록 해결했습니다.
- 멀티에이전트 자율 오케스트레이션 루프(`run_loop.sh --plan --all-reviewer`)를 통해 Planner(`claude`), Creator(`agy`), Reviewer(`cline`) 3자에 의해 구현 및 교차 검증 후 **`[VERDICT: PASS]` (만장일치 통과)** 되었습니다.
- 전용 회귀 테스트 스위트 `tests/test_b4_session_created.py` (21/21 PASS)를 작성하여 입증했습니다.
### **O-2: 동일 워크스페이스 내 중복 루프 기동 방지 락 (Race-Free Mutex & Ownership)** — ✅ 완료
- `loop_lock.sh` 독립 락 모듈(`mam_acquire_loop_lock` / `mam_release_loop_lock`)을 생성하고 하드링크(`ln`) 기반 원자적 패키징 쓰기를 구현하여 빈/파티셜 마커 노출 및 Livelock 을 원천 차단했습니다.
- `pid` + `lstart`(프로세스 시작 시각) 기반 신원 검증 로직을 적용하여 PID Rollover 오판을 차단하고, stale 락 회수 시 마커 규약과 동일한 `steal_lock` (`$marker.steal`) 신원 인수 디스패처를 구축하여 고아 디렉터리로 인한 영구 워크스페이스 데드락 결함을 근본 해결했습니다.
- 이전 Rev.1 레거시 `.steal` 디렉터리 자동 정리 업그레이드 경로 및 소유권 검증 기반 원자적 해제(`mam_release_loop_lock`)를 통합하여 이차 루프 종료 시 소유권 없는 마커 파기를 차단하고 O-3 위임 가드를 완벽 보호했습니다.
- 전용 테스트 스위트 `tests/test_o2_race_free_lock.py` (22/22 PASS) 및 전체 회귀 테스트 스위트 (204/204 PASS)를 작성하여 입증했습니다.
### **O-3: 조건부 오케스트레이션 위임 가드 (Invocation-Aware Scoped Guard)** — ✅ 완료
- Normal Mode(직접 소스 수정)와 Loop Active Mode(`/multi-agent-mux-loop` 인보크 시 `run_loop.sh` 자율 위임)의 역할 경계를 명확히 구분하는 스킬 인터셉터 가드레일(`.agents/hooks.json` & `.agents/hooks/loop_delegation_guard.sh`)을 구축했습니다.
- step-type 파생명 매처(`file_change|edit_notebook|write_blob`)를 적용하여 가드 무발화 결함을 방지했습니다.
- `pid` + `lstart`(프로세스 시작시각) 신원 대조 검증을 통해 PID Rollover 및 `PermissionError` 시 발생할 수 있는 Livelock 영구 차단 오판을 완벽히 해결했습니다.
- `run_loop.sh` 마커 기록 및 `delegate_job_safe` 트랩 복원(`_mam_release_guard`)을 완료했습니다.
- `AGENTS.md`, `MULTI_AGENT_RULES.md` (.ko.md), `SKILL.md` 문서를 전수 대칭 갱신했습니다.
- 전용 단위/회귀 테스트 스위트 `tests/test_o3_scoped_guard.py` (22/22 PASS)를 수립하여 입증했습니다.
### **A-1: 워크스페이스 세션 격리 & drift-B 오등록 방지** — ✅ 완료
- `derive_workspace_slug` 헬퍼 함수를 추가하여 워크스페이스 경로 기반 단일 소켓 슬러그(`mam-<parent>-<work>`) 도출 체계를 구축했습니다.
- `reconcile.sh` drift-B 자동 등록 시 foreign cwd 차단 게이트를 구축하여 세션 오등록을 방지했습니다.
### **A-3: 시프트 버퍼 동시 주입 오염 & 자동 GC 체계 구축** — ✅ 완료
- `lib.sh``send_keys_safe` 시프트 버퍼 명령의 임시 파일명을 `sks_${sess}_${job_id}_$$_${RANDOM}_$(date +%s%N)` 식 호출 단위 독립 토큰으로 변환하여 다중 에이전트 동시 주입 시 대화 교차 오염 및 무음 유실(T5)을 원천 차단했습니다.
- `set-buffer` 시 원자적 임시 쓰기(`.$buf.$$.tmp`) 및 rename(`mv -f`) 구조를 구현하여 파티셜 레코드 관측을 방지했습니다.
- 인터럽트/예외 종료 시 남는 stale 버퍼 파일을 자동으로 정리하는 60분 내장 GC(`find -mmin +60 -delete`)를 내장했습니다.
- 전용 회귀 테스트 스위트 `tests/test_a3_buffer_isolation.py` (12/12 PASS)를 작성하여 입증했습니다.
### **C-2: 미사용 `.cache/` 상태 디렉터리 생성 및 데드 코드 정돈** — ✅ 완료
- `reconcile.sh`에서 아무 데이터도 저장하지 않던 미사용 `.cache/multi-agent-mux-monitor` 디렉터리 생성(`mkdir -p`) 구문 및 `STATE_DIR` 환경변수를 제거했습니다.
- 레거시 환경변수 `AGENT_SESSIONS_STATE_DIR` 설정 시 무음 생성을 방지하고 stderr에 가이드 경고만 안내하도록 정돈했습니다.
- `deploy/remove.sh` 언인스톨러에서 미사용 `.cache/` 디렉터리가 비어있는 경우 안전하게 제거(`rmdir .cache`)하도록 개선했습니다.
- 전용 단위/회귀 테스트 스위트 `tests/test_c2_no_stale_cache_dir.py` (5/5 PASS)를 작성하여 입증했습니다.
### **A-5: `HERDR_SESSION_NAME` 네이티브 전환** — ✅ 완료
- 기존 `HERDR_SERVER_NAME` 환경변수를 herdr 시프트가 직접 읽는 네이티브 **`HERDR_SESSION_NAME`** 및 YAML 레지스트리 키 **`herdr_session`**으로 전수 전환 단일화했습니다.
### **B-1: `find_workspace_uuid` tier-3 신원 캐시 해석 오류 해결** — ✅ 완료
- `lib.sh` tier-3 신원 캐시 조회 시 미정의 변수(`db_path`, `yaml_path`) 및 `yaml` import 누락으로 무조건 `NameError` 예외가 발생하던 결함을 해결했습니다.
- DB를 1차 권위 경로로, `$YAML_PATH`를 폴백으로 정제하고 전용 회귀 테스트 `tests/test_b1_tier3_identity.py` (8/8 PASS)를 작성하여 입증했습니다.
### **B-3: `command -v herdr` 프리플라이트 무력화** — ✅ 완료
- `lib.sh``_canonical_file()`, `_is_shim_path()`, `_resolve_real_herdr_path()`, `has_real_herdr()` 헬퍼를 작성하여 `herdr()` bash 함수 오판과 `.mam/shim/herdr` 래퍼 매칭(파일 수준 심링크 포함)을 완전 차단했습니다.
- `create_session.sh`, `multi-agent-mux-delegate-job`, `create/SKILL.md`, `status/SKILL.md` 프리플라이트를 `has_real_herdr`로 전수 교체했습니다.
- 회귀 테스트 `tests/test_b3_herdr_preflight.py` (11/11 PASS)를 작성하여 입증했습니다.
### **C-1: Kanban 문서 29회 언급 vs 실제 구현 0건** — ✅ 완료
- SKILL.md 3종(monitor 22 / status 5 / create 2)과 README 2종의 Kanban 서술을 전면 제거했습니다.
- `multi-agent-mux-monitor` 의 실행 메커니즘 서술을 실제 구현인 `reconcile.sh --subscribe` (MQTT push + 브로커 다운 시 폴링 폴백) 기준으로 재작성했습니다.
- 존재하지 않는 스킬 참조 2건(`kanban-worker`, `kanban-orchestrator`)을 실존 스킬로 교체했습니다.
- `hermes kanban create` CLI 플래그 잔재 10종(`--goal-max-turns`, `--assignee`, `--comment-card` 등)을 파생형 검증 게이트(G-C)로 차단했습니다.
- 제품 표면(`.agents/skills/`, `README*.md`) Kanban 참조 **0건** 확인.
### **O-1: 타당하지 않은 리뷰 피드백 거부/반론 프로토콜 미지원 (Rebuttal Protocol)** — ✅ 완료
- `run_loop.sh``--max-rebut N` (기본값 1) 옵션 및 Rebuttal/Re-adjudication/Arbitration 3단계 프로토콜을 구현했습니다.
- Creator가 지적 항목 거부 시 `[REBUT: <reviewer>]` 태그를 남겨 해당 리뷰어 대상 재심(`[ADJUDICATION: SUSTAINED/OVERRULED]`)을 가동하며, 교착 시 Planner 재정(`[ARBITRATION: CREATOR/REVIEWER]`) 또는 Fail-Closed 결정을 수행합니다.
- bash 3.2 macOS 규격 빈 배열 확장 안전성(`${ARR[@]+"${ARR[@]}"}`) 및 per-iteration budget reset / total budget cap 결함을 완벽히 보완하고 회귀 테스트 `tests/test_o1_rebuttal.py` (10/10 PASS)로 입증했습니다.
- `MULTI_AGENT_RULES.md`, `.ko.md`, `multi-agent-mux-loop/SKILL.md` 문서 연동을 완료했습니다.
### **Herdr-0.8.0-Compat-SanitizeHash: 세션명 32자 SHA-1 해시 접미사 절단 기반 유일성 보장 및 Mock Herdr 0.8.0 에러 정렬 (Commit `14b9de1`)** — ✅ 완료
- `.agents/skills/lib_py/agents/sanitize.py``.agents/skills/lib.sh``_sanitize_herdr_agent_name()`의 기존 단순 절단 방식(`s[:16]-s[-15:]`)으로 인해 동일 부모 경로 하위의 형제 워크스페이스들이 동일한 세션명으로 축약되던 결함을 **8자리 SHA-1 해시 접미사(`s[:23]-sha1[:8]`)** 결합 방식으로 100% 해소했습니다.
- 빈 문자열(`"agent"`), 숫자/특수문자 시작(`"x-"` 접두사), 32자 경계 및 33자 이상 절단 등 11개 엣지 케이스에서 **Bash 심 ↔ Python 모듈 간 100% 바이트 단위 동등성(Parity)**을 확립했습니다.
- `tests/conftest.py` Mock Herdr 에러 출력을 실제 Herdr 0.8.0 바이너리 출력 규격(`unknown option:`, `missing required`, `invalid_agent_name`)과 완전 일치하도록 정렬하고, `lib.sh` Early Abort 가드 정규식(`missing required`, `invalid_agent_name`, `^error:`)을 보강하여 불필요한 3회 재시도 루프 지연을 원천 차단했습니다.
- `lib.sh``has-session` 분기 내 잔존하던 구형 휴리스틱을 제거하고, `tests/conftest.py` 내의 7곳 구형 절단 사본을 `_match_agent` 헬퍼 함수로 일원화했습니다.
- 전용 단위 테스트 `tests/test_sanitize_and_mock_errors.py` (3/3 PASS) 및 전체 회귀 테스트 스위트 (**256/256 PASS, 0 Failures / 0 Errors**)를 검증 완료했습니다.
- 멀티에이전트 자율 오케스트레이션 루프(`run_loop.sh --all-reviewer`)를 통해 Creator(`agy`, Job: `94bceedd`) 및 Reviewer(`cline`, Job: `14187d43`) 교차 검증 만장일치 **`[VERDICT: PASS]`** 를 달성했습니다.
---
## 6. 🧭 우선순위 실행 로드맵 (Prioritized Execution Roadmap)
> 평가 근거·항목별 실측 결과는 `.mam/jobs/ecef05a3/claude-reports/report-final.md` 참조.
> **순위를 매기기 전에 12건을 전부 현재 코드에 대조했으며, 그중 4건(A-2·B-5·C-3·C-4)의 기존 서술이 현재 코드와 달라 본문을 정정했습니다.**
### 6.1 정렬 원칙
① 외부에서 트리거 가능한 위험 → ② 검증 신호를 **거짓으로** 만드는 결함 → ③ 다른 항목을 싸게 만드는 구조 작업 → ④ 국소 결함 → ⑤ 정리.
**조용한 실패에 가중치를 둡니다.** 시끄러운 실패는 사람이 보지만, 조용한 실패는 "통과"로 기록되고 그 위에 다음 작업이 쌓입니다.
### 6.2 실행 순서
> **사용자 지침 반영**: **A-2 (공개 브로커 & HMAC)** 과제는 차후 자체 전용 MQTT 브로커 서버를 구축할 예정이므로 사용자 지침에 따라 **우선순위를 최하위(P5)로 조정**하였습니다.
| 순위 | 항목 | 근거 | 비용 | 선행 |
|---|---|---|---|---|
| **P0-1** | **B-7** | 저장소 밖 기동 시 리뷰어가 문자열 `"No git diff available"``[VERDICT: PASS]` 를 냄. 신규(미추적) 파일은 리뷰 대상 밖. **(✅ 완료 — tests/test_b7_diff_untracked.py 20/20 PASS)** | 소 (1파일) | — |
| **P0-2** | **O-2** | 마커를 조건 없이 덮어쓰고 종료 트랩이 **타 인스턴스의 마커까지 삭제** → 완료 처리된 **O-3 가드가 조용히 무력화**됨 **(✅ 완료 — tests/test_o2_race_free_lock.py 22/22 PASS)** | 소~중 (1파일) | — |
| **P1-1** | **A-4 M0~M1** | `PYTHONPATH` 부트스트랩·배포/CI 등록·`own_key` 이관. B-8/B-10/C-3b 로직을 싸게 만듦 **(✅ 완료 — tests/test_a4_adapter_contract.py 3/3 PASS)** | 중 | B-7 |
| **P1-2** | **B-8** | agy 주입 시 `return 0` 우회 제거 및 제출 검증 루프 이관 **(✅ 완료 — tests/test_b8_send_keys_verification.py 1/1 PASS)** | 소 | A-4 M0 |
| **P2-1** | **B-6 / B-12** | 스킬 트리 내 임시 사본 및 서브셸 EXIT 트랩으로 인한 루프 락 조기 해제 차단 **(✅ 완료 — tests/test_o3_scoped_guard.py 27/27 PASS, commit b490713)** | 소 | — |
| **P2-2** | **C-3a + C-4** | 빈 스텁 4종 + 공허한 테스트 4건 + 죽은 심볼 3종 제거 및 `--isolate` no-op 회귀 가드 신설 **(✅ 완료 — tests/test_tier1_unit.py + test_tier2_component.py 256/256 PASS)** | 소 | — |
| **P2-3** | **C-6** | `stop_session.sh` 헤더/도움말/주석/MESSAGING.md 정리 및 회귀 가드 신설 **(✅ 완료 — tests/test_tier2_component.py 가드 신설, 전체 263/263 PASS)** | 극소 | — |
| **P3-1** | **A-4 M2~M7** | 어댑터 본이관 및 CLI facts 브리지/서브커맨드 구축 **(✅ 완료 — tests/test_a4_adapter_contract.py 9/9 PASS, 전체 259/259 PASS)** | 대 | P1-1 |
| **P3-2** | **B-10** | tier-3 신원 캐시 완전 제거 및 UUID 경로 PyYAML 탈의존 (Option A) **(✅ 완료 — tests/test_tier1_unit.py 가드 3건 신설, 전체 266/266 PASS)** | 중 | A-4 M2 |
| **P3-3** | **C-3b** | `isolation.root` 4개 소비자 완전 폐기 (Option B 채택) **(✅ 완료 — 전체 259/259 PASS)** | 소 | A-4 M2 |
| **B-13** | **Stage 2** | 셀프 호스팅 루프 런타임 프리즈 스냅샷 및 이중 루트 격리 **(✅ 완료 — tests/test_o3_scoped_guard.py 5건 가드 신설, 전체 271/271 PASS)** | 중 | — |
| **P4-1** | **B-9** | 감사 로그 루트 지연 평가 및 `__getattr__`/`__dir__` 동적 별칭 **(✅ 완료 — tests/test_tier1_unit.py 5건 가드 신설, 전체 276/276 PASS)** | 극소 | — |
| **P5-1** | **A-2** | 공개 브로커 및 HMAC 검증 보완 (📌 *사용자 지침: 차후 전용 MQTT 브로커 서빙 환경 구축 시점에 진행*) | 중 (3파일) | 전용 브로커 |
| **종결** | **B-5** | `df -P` 폴백 정상 동작 실측 및 단위 테스트 검증 완료 **(✅ 완료/종결 — tests/test_tier1_unit.py test_stop_check_is_nfs_local)** | — | — |
**A-2 과제의 후순위 배치 사유**: 사용자 지침에 따라 차후 자체 전용 MQTT 브로커 서빙 환경 구축 시점에 맞춰 진행하기 위해 **최하위(P5-1)**로 배치하였습니다.
**정리(C 계열)를 P2 에 두는 이유**: (a) C-3a 는 죽은 코드를 고정하던 테스트를 함께 제거해 C-3a 를 실행 가능하게 만들고, (b) C-4 는 **잘못 실행하면 버그를 만듭니다**. 방치할수록 누군가 "쉬운 정리"로 집어 들 확률이 올라갑니다.
### 6.3 병렬 실행 — 파일 소유권 슬롯 (Rev.2 교체)
> Rev.1 은 "주제별 트랙"으로 병렬화를 서술했고 **그 분해는 4곳에서 틀렸습니다**(챌린지 `7d604ee7` 계기로 파일 단위 재대조). 병렬 단위는 **주제가 아니라 파일**입니다.
**항목별 처방이 건드리는 파일**
| 파일 | 건드리는 항목 |
|---|---|
| `run_loop.sh` | **B-6, B-7, O-2** |
| `lib.sh` | **A-4, B-8, B-10, C-3a, C-4** |
| `reconcile.sh` | **A-2, A-4, B-10** |
| `mqtt_common.py` | **A-2, B-9** |
| `stop_session.sh` | **B-10, C-6** |
| `registry.py` | **A-2, C-4** |
| `create_session.sh` | **A-4, C-4** |
**슬롯 배치 — 슬롯 안은 직렬, 슬롯 간은 병렬**
| 슬롯 | 순서 |
|---|---|
| **`run_loop.sh`** | `B-7``O-2``B-6` |
| **`lib.sh`** | `C-3a`+`C-4``B-8` |
| **MQTT 계열** (`mqtt_common.py`·`registry.py`·`publish_event.py`·`job_subscriber.py`·`reconcile.sh`) | `A-2``B-9` |
| **`stop_session.sh`** | `C-6` |
| **단독 실행** (슬롯 경계를 넘음) | `A-4`, `B-10` |
- `A-4`(`lib.sh`+`reconcile.sh`+`create_session.sh`+`resume_session.sh`)와 `B-10`(`lib.sh`+`reconcile.sh`+`stop_session.sh`)은 **어떤 슬롯 조합과도 겹치므로 단독 실행**합니다.
- `A-4` 는 신규 파일을 대량 추가하므로 **B-7 이 먼저 닫혀 있어야 리뷰가 성립**합니다.
- **Rev.1 오류 정정 4건**: `B-6`(트랙 C→`run_loop.sh` 슬롯), `C-3a`·`C-4`(트랙 C→`lib.sh` 슬롯), `B-9`(독립→MQTT 슬롯), `C-6`(독립→`stop_session.sh` 슬롯).
- 참고: `reconcile.sh``MAM_LOOP_MARKER`·`send_keys_safe` 를 **참조 0건**이므로 `O-2`·`B-8` 과는 경합하지 않습니다(자체 `.mam/monitor.lock` 보유).
### 6.4 B-7 처방 (Rev.2 신설 — 진단만 있고 처방이 없었음)
`cd "$REPO_ROOT"` 만으로는 **미추적 신규 파일이 여전히 100% 누락**됩니다. `git diff` 는 정의상 추적 파일만 봅니다.
```bash
CHANGES_DIFF=$(
cd "$REPO_ROOT" || exit 1
git diff "$BASE_COMMIT"
# 미추적 신규 파일을 인덱스 변경 없이 덧붙인다.
# --exclude-standard 가 .gitignore / .git/info/exclude 를 그대로 존중한다.
git ls-files -o --exclude-standard -z | while IFS= read -r -d '' f; do
git diff --no-index --binary /dev/null "$f" 2>/dev/null || true
done
)
```
**`git add -N .` 은 채택하지 않습니다.** 미추적 파일을 diff 에 넣는 목적은 달성하지만(실측 확인) **인덱스에 `A` 항목을 남기며**, 그 상태에서 Creator 가 `git commit -am` 을 실행하면 **추가한 적 없는 파일이 내용째 커밋됩니다**(실측 확인). `run_loop.sh` 는 Creator 가 같은 저장소에서 작업하는 동안 반복 실행되므로 실제 위험입니다. 위 대안은 동일 결과를 내면서 인덱스를 건드리지 않습니다.
**크기 상한도 함께 필요합니다.** 현재 `CHANGES_DIFF`(537·539행)는 **아무 제한 없이** 547행 리뷰 프롬프트에 보간되고 `send_keys_safe` paste-buffer 로 주입됩니다. 미추적 파일을 포함시키면 커지기만 하므로 상한을 두고, 초과 시 `--stat` 요약으로 대체하되 **잘렸다는 사실을 리뷰어에게 반드시 노출**해야 합니다(조용히 자르면 "빈 diff PASS" 가 "부분 diff PASS" 로 바뀔 뿐입니다). 구체적 임계값은 구현자가 샌드박스 세션에서 paste-buffer 실패 지점을 측정해 확정할 것.
### 6.5 ⚠️ 실행 전 반드시 확인할 정정 사항
1. **C-3 (✅ 완료)**:
- **C-3a (✅ 완료)**: `provision_isolation` / `isolation_lever` / `isolation_env_prefix` / `isolation_cmd_args` 4종 빈 스텁 및 이를 고정하던 공허한 테스트 4건을 제거하고 `--isolate`/`--no-isolate` no-op 회귀 가드로 대체했습니다.
- **C-3b (✅ 완료 — P3-1 / Option B)**: `isolation.root` 4개 소비자(`lib.sh` `verify_session_uuid``iso_root` 분기, `mam_session_iso_root`, `find_workspace_uuid` 격리 분기, `stop_session.sh:277` purge 가드 및 `atomic_yaml.py:30-33` 유효성 검사)를 완전히 폐기하고 Universal Global Config 및 어댑터 기반 단일 경로로 이관했습니다.
2. **C-4 (✅ 완료)**:
- `_HERDR_SHIM_DIR_PATTERN`**사용 중입니다** (`lib.sh:83` 정의, `lib.sh:105` 사용). 목록대로 지우면 shim 경로 판정이 깨집니다.
- `local_herdr` — 참조 0건, **이미 제거됨**.
- 실제 대상 `_REAL_HERDR_PATH`, `TERMINAL_STATUSES`, `ISOLATE` 3종이 안전하게 제거되었습니다(`provision_isolation` 은 C-3a 에서 처리).
3. **A-2 의 원인 표현 정정**`verify_hmac` 구현 자체는 정상입니다(토큰이 있으면 `hmac.compare_digest` 로 검증). 원인은 **토큰이 아무 데서도 발급되지 않아 검증이 공허해지는 것** + 발행자가 워크스페이스 지문 토픽을 채택하지 않은 것입니다. 수정은 ① 발행자 토픽 교체 ② `reconcile.sh:237` 레거시 전역 구독 제거 ③ `verify_hmac` fail-closed + 토큰 발급 순입니다.
4. **B-5 잔여분** — 폴백으로 감지는 정상화됐으나 `mount | grep -E "$mountpoint.*(nfs|...)"` 가 마운트포인트를 **이스케이프 없이 ERE 에 보간**합니다(경로의 `.` 이 임의 문자로 해석). 이것만 신규 항목(B-11)으로 분리 권고.
### 6.6 결론
`IMPROVEMENTS.md` 는 남은 백로그 항목(아키텍처 2건, 엣지케이스 6건, 오케스트레이션 1건, 레거시 잔재 3건 — 총 12건)을 위 우선순위에 따라 일원화된 보완 로드맵으로 관리합니다.