55 KiB
🛠️ Multi-Agent Mux 종합 개선 및 미해결 과제 백로그 (IMPROVEMENTS.md)
- 최종 갱신일: 2026-08-23 (
nats-docker서브모듈 분리, B-19 헤드리스 레이아웃/리컨사일/Fast-path 게이팅 개선, 37/37 신규 가드 통과 유지) - 통합 관리 대상: 기존
CODEBASE_REVIEW_REPORT.md+OPTIMIZATION.md+NATS_REPORT.md - 총 추적 미해결 과제: 5건 (아키텍처 1건:
A-2, 엣지케이스 및 가용성 3건:B-16,B-17,B-18, 오케스트레이션 1건:O-5) - 완료된 과제: 28건 (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, B-14, B-15, B-19, C-1, C-2, C-3b, C-6, O-1, O-2, O-3, O-4-OrcOnboard, O-6, 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 (P5-1): 공개 브로커 + HMAC 인증 Off + 와일드카드 전파 (해결책: nats-server 전용 브로커 채택)
- 현상:
mqtt_common.py의 기본 브로커가 공개 서버(broker.hivemq.com)이고, 잡 생성 시auth_token이 발급되지 않는 조건 분기(평문/공개 브로커)로 인해verify_hmac의if not auth_token: return True경로가 타집니다. 발행자는 워크스페이스 지문 토픽을 채택하지 않고 전역python/mqtt/jobs/<job_id>/events로 발행하며,reconcile.sh:237이 같은 전역 토픽을 구독합니다. - 파급 효과: 외부에서 유입되는 malicious
error이벤트 수신 시reconcile.sh가 라이브 에이전트 pane을kill-session으로 강제 파괴하는 치명적 보안/안정성 위험이 존재합니다. - 최신 실측 및 해결 방침 (
NATS_REPORT.md확정):- 클라이언트 프로토콜(
paho-mqtt)을 비동기nats-py로 전면 재작성하는 방안(Option B)은 46개 테스트 파괴 및 단명 동기 CLI 마찰 위험으로 만장일치 기각되었습니다. - 대신 **
nats-server의 내장 MQTT 3.1.1 리스너를 전용 사설 브로커로 채택(Option C)**하여 클라이언트 코드 0줄 변경으로 NKey/JWT 계정·Subject별 ACL 격리 및 JetStream 영속성을 100% 확보하기로 확정했습니다. - 단, 브로커 제품과 무관하게 존재하는 **가용성 선행 결함(Track 0: B-14, B-15)**을 먼저 교정한 후 Track 1(스파이크) 및 Track 2(A-2 워크스페이스 지문 토픽 + 무조건 토큰 발급)를 순차 전개합니다.
- 클라이언트 프로토콜(
2. 🟠 엣지 케이스 및 런타임 버그 (Edge-case Bugs — 4건 / 완료 3건)
B-19 (✅ 완료 — 헤드리스 분할 레이아웃 0×0 예외 처리, reconcile SKILLS_DIR 누락 및 Fast-path 게이팅 보완)
- 현상:
lib.sh:449헤드리스 환경에서herdr pane layout이0×0을 반환할 때overflow로 오판정되어 새 워크스페이스(w1, w2, w3)가 계속 증식하던 결함.reconcile.sh:814, 816에서SKILLS_DIR을 전달하지 않아 Python 내에서 상대 경로 조립 실패(resume dry-run failed: No such file or directory)가 기록되던 결함.lib.sh:1667send_keys_safe에서herdr agent promptFast-path가 렌더러 안정화 및 다이얼로그 체크 이전에 실행되거나 실패 시 중복 입력이 발생할 수 있던 결함.
- 조치 결과 (완료):
lib.sh:w <= 0 or h <= 0인 헤드리스 상태일 때 기본'right'분할 적용.send_keys_safe의 Fast-path를 안정화/다이얼로그 확인 후로 배치하고 단일 성공 즉시return 0처리.reconcile.sh:env_python및atomic_dump_yaml실행 시SKILLS_DIR="$SKILLS_DIR"명시 주입 및 3중 fallback 경로 추가.- 회귀 가드:
tests/test_b19_headless_reconcile_fixes.py(4개 테스트 신규 작성 및 100% 통과).
B-14 (✅ 완료 — F-1 / P1): publish_event.py 브로커 장애 시 return 2 조기 탈출로 인한 65분 루프 정지
- 현상:
publish_event.py에서 브로커 네트워크 장애 발생 시return 2로 조기 종료되어, 뒤따르는 로컬 레지스트리 상태(update_job_status(status=completed)) 및 감사 로그(append_event,registry.append_event) 갱신이 누락되던 결함. - 조치 결과 (완료 — 커밋
c6b6c77): 네트워크 발행 실패 여부와 무관하게 로컬 레지스트리 및 감사 로그를 100% 먼저 동기화한 후published=False와 함께return 2를 반환하도록 실행 순서를 재배치 (G-1 ~ G-4 회귀 가드로 봉인 완료).
B-15 (✅ 완료 — C1 & F-4 / P1): job_subscriber.py 디스크 폴백 부재 및 위임 경로 인프라 에러 오판정
- 현상:
job_subscriber.py가 네트워크 큐만 대기하며 로컬 디스크 상태를 확인하지 않아 브로커 다운 시 블로킹되거나 인프라 에러가 작업error로 오판정되던 결함. - 조치 결과 (완료 — 커밋
c6b6c77):_check_disk_fallback()을 도입하여 로컬 디스크 상의 터미널 상태를 감지하면 합성 이벤트를 출력하고 즉시rc=0으로 정상 종료하도록 개선. 브로커 인프라 접속 실패는 전용rc=3으로 분리 (G-5 ~ G-10 회귀 가드로 봉인 완료).
B-16 (F-5 / P3): make_client() 매 실행 랜덤 client_id 발급으로 인한 영속 세션(Durable Session) 구성 불가
- 현상:
mqtt_common.py:258에서client_id를 매번uuid.uuid4().hex[:8]로 생성하여, 브로커가 클라이언트 재연결을 식별할 수 없습니다 (NATS_REPORT.md§3.5 F-5). - 파급 효과: 네트워크 재연결 시 미수신 이벤트 유실 가능성이 발생합니다.
- 조치 방향: B-15의 로컬 디스크 폴백을 표준 복원 경로로 확립하여 네트워크 세션 의존도를 제거하고, 필요 시 결정론적 식별자 규칙을 적용합니다.
B-17 (P1): _load_dotenv 오타/부재 경로 지정 시 Fail-Closed 및 공용 브로커 폴백 방지
- 현상:
MAM_ENV_FILE이 명시적으로 지정되었으나 해당 경로가 존재하지 않는 경우,_load_dotenv가 조용히 리턴하여broker.hivemq.com공개 브로커로 폴백되는 위험. - 파급 효과: 설정 오타 발생 시 잡 이벤트와 프롬프트가 공개 브로커로 전송될 수 있음.
- 조치 방향 (2단 구조):
- import 시점: 명시적
MAM_ENV_FILE경로 부재 시logger.error기록 및_env_file_missing = True플래그 설정 (상위 임의 탐색 금지, import 예외 방지). - 접속 시점:
make_client()시_env_file_missing이면RuntimeError로 fail-closed 거부. 최종 호스트가broker.hivemq.com인 경우 눈에 띄는 보안 경고 출력.
- import 시점: 명시적
B-18 (P2): .mam.env와 .env 공존 및 다중 워크스페이스 경계 탐색 정합성
- 현상:
.mam.env와.env의 우선순위 및 워크스페이스 경계(.agents,.git) 탐색 과정에서 다중 워크스페이스 환경에서의 일관성 유지. - 조치 방향:
MAM_REAL_ROOT->WORKSPACE_ROOT-> 상위 경계 디렉터리 ->cwd순서의 first-hit-wins 탐색 규칙 적용.
3. 🟡 오케스트레이션 최적화 과제 (Orchestration Optimizations — 추적 중 1건 / 완료 1건: O-5, O-6)
O-5 (P2): NATS/MQTT 메시징 백플레인 고도화 및 nats-server 스파이크 검증 (Track 1 ~ Track 2)
- 현상:
NATS_REPORT.md아키텍처 실측 분석에 따라nats-server내장 MQTT 3.1.1 어댑터를 사설 전용 브로커로 채택하는 전략(Option C)이 확정되었습니다. - 조치 방향:
- Track 1 (스파이크 검증): 격리 환경에서
nats-server -js의 MQTT 3.1.1 호환성 실측 검증. - Track 2 (보안/격리): 워크스페이스 지문 기반 토픽(
mam/<sha256[:12]>/jobs/...) 및 무조건auth_token발급(G-11)을 적용하여 A-2 보안 결함 완전 종결. - Track 3 (문서/설정):
MESSAGING.md,VERSIONS.md,.mam.env에nats-server서빙 가이드 및 설정 동기화.
- Track 1 (스파이크 검증): 격리 환경에서
O-6 (✅ 완료 — P1): 원격 프로덕션 브로커 자산 정본화 및 nats-docker 서브모듈 분리
- 내용:
- 원격 Docker NATS 배포 가이드 및 자산(
docker-compose.yaml,nats.conf,.env.example,README.md) 구현. nats-docker독립 Git 저장소 및 서브모듈(.gitmodules,nats-docker/) 분리 완료 (커밋629a67f,12ba30b,916185c).- 배포 신선도 및 보안 회귀 가드 D-22 ~ D-30 9종 구축 (297 -> 306 tests 100% PASS 달성).
- 테스트 프레임워크 내
_resolve_docker_dir()및_resolve_private_server_doc()동적 경로 해석기 도입.
- 원격 Docker NATS 배포 가이드 및 자산(
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.sh8,reconcile.sh7,stop_session.sh6,lib.sh4,resolve_session_id.sh3,resume_session.sh/update_yaml_resumed.sh/run_loop.sh각 2) - 사본 현황:
agent → *_id_own키 맵 4벌,~/.claude/projects17참조,antigravity-cli/conversations11참조,.hermes/state.db6참조,.cline/data/sessions5참조. - 파급 효과: 같은 질문에 서로 다른 답이 공존합니다. 세션명→에이전트 추론이
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 shellcase블록을 단 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 bashcase2.3 ms — 분기마다 호출하면 안 됨).
실현 가능성 및 부트스트랩 (Rev.2 실측)
- 파이썬 진입점 3종 전부에서 import 확인:
env_python,atomic_dump_yaml(flock 쓰기 경로), venv 없는 맨/usr/bin/python3. lib.shsource 시점 1회export PYTHONPATH:lib.sh로드 시_mam_export_pythonpath가mam_skills_dir을PYTHONPATH에 자동 얹어run_loop.sh등 셸 상의 모든python3 -c호출이 한 번에 호환됨.- herdr shim 내부
python3 -c9곳 전부 에이전트 지식 0 → shim 경계가 이미 올바른 위치에 있습니다. - 제약(규칙화 필요): 어댑터는 표준 라이브러리만 사용해야 합니다. 서드파티 의존성이 들어오면 venv 없는 경로가 깨집니다.
선행 필수 체크리스트 (누락 시 조용히 업그레이드가 막힘)
deploy/remove.sh:83-91fallback_assets에".agents/skills/mam_agents"등록. 미등록 시tests/test_deploy_freshness.py::test_d2가 실패하며(프로토타입에서 실제 발생), 언인스톨 후 잔존 자산이 워크스페이스를 영구히 구버전에 고정시킵니다(install.sh는 비-스킬 자산을 "없을 때만" 복사).deploy/install.sh무결성 자산 목록 등록.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 — 3건)
B-14 (F-1 / P1): publish_event.py 브로커 장애 시 return 2 조기 탈출로 인한 65분 루프 정지
- 현상:
publish_event.py:195-199에서 브로커 네트워크 장애 발생 시return 2로 조기 종료되어, 뒤따르는 로컬 레지스트리 상태(update_job_status(status=completed)) 및 감사 로그(append_event,registry.append_event) 갱신이 누락됩니다 (NATS_REPORT.md§3.1 실측 재현). - 파급 효과:
run_loop.sh의wait_for_job()은 로컬 디스크 파일의 상태가status=running으로 멈춰있어max_wait=3900s를 소진할 때까지 **65분간 루프가 완전 정지(Hang)**합니다. - 조치 방향 (Track 0 Step 1): 네트워크 발행 실패 시에도
append_event와update_job_status를 온전히 완수한 후published=False를 기록하고return 2를 반환하도록 실행 순서를 재배치합니다 (G-1 ~ G-4 회귀 가드 신설).
B-15 (C1 & F-4 / P1): job_subscriber.py 디스크 폴백 부재 및 위임 경로 인프라 에러 오판정
- 현상:
job_subscriber.py:172-251가queue.Empty시 네트워크 큐만 대기하며 로컬 디스크 상태를 확인하지 않아, 브로커 다운 시 120초idle_timeout동안 불필요하게 블로킹됩니다 (NATS_REPORT.md§4.1 C1 챌린지 검증).multi-agent-mux-delegate-job:331-341에서wait "$sub_pid"의sub_rc를 직접job_status로 매핑(rc=1->job_status="error")하여, 브로커 연결 실패로 인한 미포착 예외(rc=1) 발생 시 작업자의 정상 산출물이 존재하더라도 작업을 강제로"error"로 오판정합니다 (NATS_REPORT.md§3.4 F-4).
- 파급 효과: 브로커 장애 시 작업자가 작업을 정상 완수했음에도 루프가 2분 이상 지연되거나 거짓 실패(False Failure)가 발생합니다.
- 조치 방향 (Track 0 Step 2 & 3):
job_subscriber.py대기 루프에 로컬 디스크(load_job/read_logged_status) 상태 폴백을 도입하여 디스크 완료 감지 시source: disk-fallback합성 이벤트를 출력하고 3초 내rc=0으로 조기 정상 종료합니다.- 브로커 인프라 연결 실패에 전용
rc=3을 부여하고job_status="broker_unavailable"분기로 분리하여 작업 결과와 인프라 에러를 엄격히 격리합니다 (G-5 ~ G-10 회귀 가드 신설).
B-16 (F-5 / P3): make_client() 매 실행 랜덤 client_id 발급으로 인한 영속 세션(Durable Session) 구성 불가
- 현상:
mqtt_common.py:258에서client_id를 매번uuid.uuid4().hex[:8]로 생성하여, 브로커가 클라이언트 재연결을 식별할 수 없습니다 (NATS_REPORT.md§3.5 F-5). - 파급 효과: 네트워크 재연결 시 미수신 이벤트 유실 가능성이 발생합니다.
- 조치 방향: B-15의 로컬 디스크 폴백을 표준 복원 경로로 확립하여 네트워크 세션 의존도를 제거하고, 필요 시 결정론적 식별자 규칙을 적용합니다.
3. 🟡 오케스트레이션 최적화 과제 (Orchestration Optimizations — 1건)
O-5 (P2): NATS/MQTT 메시징 백플레인 고도화 및 nats-server 스파이크 검증 (Track 1 ~ Track 2)
- 현상:
NATS_REPORT.md아키텍처 실측 분석에 따라,nats-py클라이언트 재작성(Option B)을 배제하고nats-server내장 MQTT 3.1.1 어댑터를 사설 전용 브로커로 채택하는 전략(Option C)이 확정되었습니다. - 조치 방향:
- Track 1 (스파이크 검증): 격리 환경에서
nats-server -js의 MQTT 3.1.1 호환성(Retained 터미널 이벤트 전달 S-3, QoS 1 ACK S-4, Subject 라우팅 S-5 등 9종 매트릭스 S-1 ~ S-9) 실측 검증. - Track 2 (보안/격리): 워크스페이스 지문 기반 토픽(
mam/<sha256[:12]>/jobs/...) 및 무조건auth_token발급(G-11)을 적용하여 A-2 보안 결함 완전 종결. - Track 3 (문서/설정):
MESSAGING.md,VERSIONS.md,.mam.env에nats-server서빙 가이드 및 설정 동기화.
- Track 1 (스파이크 검증): 격리 환경에서
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.pytier-3 폴백(28줄),reconcile.shdrift D 진단(35줄),stop_session.shpurge 시 캐시 소거(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/--graceful3종은 파서가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.root4개 소비자(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_args4종(프로덕션 호출자 0건)을 제거하고, 주석 블록에 C-3b(isolation.root행 필드) 경계를 명시해 후속 정리 시 오삭제를 차단했습니다.- 위 스텁의 빈 출력만 재확인하던 공허한 테스트 4건(
tests/test_tier1_unit.py3,tests/test_tier2_component.py1)을 제거하고, 그 자리에--isolate/--no-isolate레거시 no-op 플래그의 인자 파서 계약을 고정하는test_create_session_legacy_isolate_flags_noop1건을 신설했습니다. 신규 테스트는 분기 삭제·한쪽만 삭제·조용한 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헬퍼 모듈을 작성하여,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.shdrift 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.sh554번 라인의999999하드코딩 출력을 제거하고, real herdr 또는.mam/agent-sessions.yaml에 기록된 세션 생성 시각(created/created_at/created_epoch) 및 동적 POSIX 타임스탬프(int(time.time()))를 리턴하도록 정제했습니다.reconcile.shdrift-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.shdrift-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.shtier-3 신원 캐시 조회 시 미정의 변수(db_path,yaml_path) 및yamlimport 누락으로 무조건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 createCLI 플래그 잔재 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.pyMock Herdr 에러 출력을 실제 Herdr 0.8.0 바이너리 출력 규격(unknown option:,missing required,invalid_agent_name)과 완전 일치하도록 정렬하고,lib.shEarly 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 실행 순서 (4-Track Priority Alignment)
우선순위 원칙 및 NATS 분석 합의 반영 (
NATS_REPORT.md):
- Track 0 (최우선 P1 — 가용성 및 내결함성 교정): 브로커 장애 시 65분 루프 정지(
B-14) 및 120초 지연/오판정(B-15)을 방지하는 로컬 디스크 내결함성 확보 (G-1 ~ G-10 회귀 가드 신설, 브로커 제품 무관 선행 필수).- Track 1 (차순위 P2 — 브로커 스파이크 검증): 격리 환경에서
nats-server -js의 MQTT 3.1.1 호환성(Retained 터미널 이벤트 S-3, QoS 1 ACK S-4 등 9종 매트릭스 S-1 ~ S-9) 실측 스파이크 검증 (O-5).- Track 2 (보안/격리 완결 P3): 워크스페이스 지문 기반 토픽(
mam/<sha256[:12]>/jobs/...) 및 무조건auth_token발급(G-11)으로A-2보안 결함 완전 종결 및B-16완결.- Track 3 (문서/설정 동기화 P4):
MESSAGING.md,VERSIONS.md,.mam.env템플릿 동기화.
| 순위 | 항목 | 근거 | 비용 | 선행 |
|---|---|---|---|---|
| P1-1 | B-14 (F-1) | 브로커 다운 시 publish_event.py 조기 탈출로 인한 65분 루프 정지(Hang) 원천 차단 (append_event/update_job_status 선행 보장, G-1 ~ G-4 회귀 가드) |
소 (1파일) | — |
| P1-2 | B-15 (C1/F-4) | 브로커 다운 시 job_subscriber.py 120초 지연 제거 및 정상 완료 작업의 job_status="error" 오판정 차단 (디스크 폴백 및 rc=3 분리, G-5 ~ G-10 회귀 가드) |
소~중 (2파일) | B-14 |
| P2-1 | O-5 (Track 1) | nats-server -js MQTT 3.1.1 호환성 스파이크(S-1 ~ S-9 매트릭스 실측, S-3 Retained 터미널 이벤트 관문) 및 환경변수 템플릿 연동 |
소 (격리 스파이크) | B-15 |
| P3-1 | A-2 (Track 2) | 워크스페이스 지문 토픽(mam/<fp>/jobs/...) 및 무조건 auth_token 발급(G-11)으로 A-2 보안 결함 완전 종결 |
중 (3파일) | O-5 (S-3 통과) |
| P3-2 | B-16 (F-5) | 매 실행 랜덤 client_id 발급으로 인한 영속 세션 불가 이슈를 B-15 디스크 폴백 표준화로 완결 |
극소 | B-15 |
| 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) |
극소 | — |
| 종결 | B-5 | df -P 폴백 정상 동작 실측 및 단위 테스트 검증 완료 (✅ 완료/종결 — tests/test_tier1_unit.py test_stop_check_is_nfs_local) |
— | — |
정리(C 계열)를 과거 P2 에 두었던 이유: (a) C-3a 는 죽은 코드를 고정하던 테스트를 함께 제거해 C-3a 를 실행 가능하게 만들고, (b) C-4 는 잘못 실행하면 버그를 만듭니다. 방치할수록 누군가 "쉬운 정리"로 집어 들 확률이 올라갑니다.
6.3 병렬 실행 — 파일 소유권 슬롯 (Rev.3 갱신)
병렬 단위는 주제가 아니라 파일입니다.
항목별 처방이 건드리는 파일
| 파일 | 건드리는 항목 |
|---|---|
publish_event.py |
B-14 |
job_subscriber.py |
B-15 |
multi-agent-mux-delegate-job |
B-15 |
mqtt_common.py |
A-2, B-9, B-16 |
registry.py |
A-2, B-14, C-4 |
reconcile.sh |
A-2, A-4, B-10 |
.mam.env / MESSAGING.md |
O-5, A-2 |
run_loop.sh |
B-6, B-7, O-2 |
lib.sh |
A-4, B-8, B-10, C-3a, C-4 |
stop_session.sh |
B-10, C-6 |
create_session.sh |
A-4, C-4 |
슬롯 배치 — 슬롯 안은 직렬, 슬롯 간은 병렬
| 슬롯 | 순서 |
|---|---|
Track 0 발행자/구독자 슬롯 (publish_event.py·job_subscriber.py·delegate-job) |
B-14 → B-15 |
Track 1 브로커 스파이크 슬롯 (격리 환경 $SCRATCH/nats-spike) |
O-5 (S-1 ~ S-9) |
Track 2 보안/레지스트리 슬롯 (mqtt_common.py·registry.py·reconcile.sh) |
A-2 → B-16 |
run_loop.sh 슬롯 |
B-7 → O-2 → B-6 (완료) |
lib.sh 슬롯 |
C-3a+C-4 → B-8 (완료) |
stop_session.sh 슬롯 |
C-6 (완료) |
| 단독 실행 (슬롯 경계를 넘음) | A-4, B-10 (완료) |
6.4 B-7 처방 (Rev.2 신설 — 진단만 있고 처방이 없었음)
cd "$REPO_ROOT" 만으로는 미추적 신규 파일이 여전히 100% 누락됩니다. git diff 는 정의상 추적 파일만 봅니다.
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 ⚠️ 실행 전 반드시 확인할 정정 사항
- C-3 (✅ 완료):
- C-3a (✅ 완료):
provision_isolation/isolation_lever/isolation_env_prefix/isolation_cmd_args4종 빈 스텁 및 이를 고정하던 공허한 테스트 4건을 제거하고--isolate/--no-isolateno-op 회귀 가드로 대체했습니다. - C-3b (✅ 완료 — P3-1 / Option B):
isolation.root4개 소비자(lib.shverify_session_uuid의iso_root분기,mam_session_iso_root,find_workspace_uuid격리 분기,stop_session.sh:277purge 가드 및atomic_yaml.py:30-33유효성 검사)를 완전히 폐기하고 Universal Global Config 및 어댑터 기반 단일 경로로 이관했습니다.
- C-3a (✅ 완료):
- C-4 (✅ 완료):
_HERDR_SHIM_DIR_PATTERN— 사용 중입니다 (lib.sh:83정의,lib.sh:105사용). 목록대로 지우면 shim 경로 판정이 깨집니다.local_herdr— 참조 0건, 이미 제거됨.- 실제 대상
_REAL_HERDR_PATH,TERMINAL_STATUSES,ISOLATE3종이 안전하게 제거되었습니다(provision_isolation은 C-3a 에서 처리).
- A-2 의 원인 표현 정정 —
verify_hmac구현 자체는 정상입니다(토큰이 있으면hmac.compare_digest로 검증). 원인은 토큰이 아무 데서도 발급되지 않아 검증이 공허해지는 것 + 발행자가 워크스페이스 지문 토픽을 채택하지 않은 것입니다. 수정은 ① 발행자 토픽 교체 ②reconcile.sh:237레거시 전역 구독 제거 ③verify_hmacfail-closed + 토큰 발급 순입니다. - B-5 잔여분 — 폴백으로 감지는 정상화됐으나
mount | grep -E "$mountpoint.*(nfs|...)"가 마운트포인트를 이스케이프 없이 ERE 에 보간합니다(경로의.이 임의 문자로 해석). 이것만 신규 항목(B-11)으로 분리 권고.
6.6 결론
IMPROVEMENTS.md 는 남은 백로그 항목(아키텍처 1건: A-2, 엣지케이스 및 가용성 3건: B-16·B-17·B-18, 오케스트레이션 1건: O-5 — 총 5건)을 위 우선순위(Track 0 → Track 1 → Track 2)에 따라 일원화된 보완 로드맵으로 관리합니다.