Files
multi-agent-mux/implementation_plan.md
T

12 KiB

🚀 MAM 메시징 백플레인 전환 실행 로드맵 (implementation_plan.md)

  • 문서 버전: v1.0.0 (8c651798 / 28bb7340)
  • 작성/관리 주체: Multi-Agent Orchestration Team (claude, agy, cline)
  • 기준 커밋: a9934ad (276/276 baseline tests passing)
  • 문서 목적: MAM의 메시징 인프라를 공개 HiveMQ 브로커에서 nats-server 전용 사설 브로커로 무중단 전환하기 위한 4개 트랙(Track 03)과 5단계 마일스톤(M0M4)의 구체적 실행 지침 및 진행 상황 추적.
  • 연계 문서: NATS_REPORT.md, PRIVATE_SERVER.md, IMPROVEMENTS.md

1. 개요 및 4개 트랙 구조

[M0: 문서 정합성] ──> [M1: 내결함성 확보] ──> [M2: 브로커 실증] ──> [M3: 보안 종결] ──> [M4: 동기화 완료]
 (E-1~E-4 교정,       (Track 0: B-14,B-15,     (Track 1: O-5      (Track 2: A-2,      (Track 3: 문서,
  G-D1~G-D4 가드)      G-1~G-10 가드)           S-1~S-9 스파이크)  지문 토픽, G-11)    배포 스크립트)
트랙 대상 과제 핵심 목표 코드 변경 지점
Track 0 B-14, B-15 (P1) 브로커 다운 시 65분 정지(Hang) 및 오판정 방지 (로컬 디스크 내결함성) publish_event.py, job_subscriber.py, multi-agent-mux-delegate-job
Track 1 O-5 (P2) nats-server MQTT 3.1.1 어댑터 호환성 및 Retained 메시지 실측 검증 격리 클론 ($SCRATCH/nats-spike)
Track 2 A-2, B-16 (P2) 워크스페이스 지문 토픽 격리 및 auth_token 무조건 발급 강제 mqtt_common.py, registry.py, reconcile.sh
Track 3 문서/설정 동기화 공식 가이드, 배포 스크립트, 환경변수 템플릿 일원화 MESSAGING.md, IMPROVEMENTS.md, VERSIONS.md, deploy/*

2. 단계별 마일스톤 (Milestones M0 ~ M4)

각 마일스톤은 완료 정의(DoD)와 엄격한 게이트(Gate)를 가지며, 게이트 조건을 충족하지 못하면 다음 마일스톤으로 진입할 수 없습니다.

M0 (문서 정합성) ──> M1 (Track 0 내결함성) ──> M2 (Track 1 실증) ──> M3 (Track 2 보안) ──> M4 (Track 3 완결)
마일스톤 이름 완료 정의 (Definition of Done) 통과 게이트 (Gate Condition)
M0 문서 정합성 확보 PRIVATE_SERVER.md E-1~E-4 교정, 다능성 절 추가, 본 로드맵 작성 G-D1 ~ G-D4 가드 테스트 통과 (276 -> 280)
M1 내결함성 확보 (Track 0) B-14, B-15 코드 패치 완료 G-1 ~ G-10 가드 통과 + mutation 전건 FAIL 확인 (280 -> 290)
M2 브로커 실증 (Track 1) 격리 클론에서 S-1 ~ S-9 스파이크 완수 S-3(Retained Terminal Event) 통과 (실패 시 mosquitto로 분기)
M3 보안 종결 (Track 2) A-2 지문 토픽 전환, G-11 무조건 토큰 발급 지문 토픽 동작 확인 legacy 구독 제거 (290 -> 291)
M4 동기화 완료 (Track 3) MESSAGING.md, IMPROVEMENTS.md, VERSIONS.md, deploy/* 정합 전체 테스트 스위트 100% Green

3. Track 0: 가용성 및 로컬 내결함성 교정 (B-14, B-15)

핵심 원칙: 브로커 선택과 완전히 독립적인 선행 과제이며, Step 1 -> Step 2 -> Step 3의 엄격한 순서 의존성을 갖습니다. Step 2를 먼저 구현하면 디스크에 터미널 상태가 기록되지 않아 폴백 효과가 0이 됩니다.

[Step 1: publish_event.py] ──> [Step 2: job_subscriber.py] ──> [Step 3: delegate-job rc 매핑]
  디스크 상태 동기화 선행         로컬 디스크 폴백 감지           인프라 에러(rc=3) 분리

3.1 Step 1 — publish_event.py 실패 처리 순서 재구성 (B-14 / F-1)

  1. publish(...) 함수를 try-except로 감싸되, 네트워크 실패 시 즉시 return 2 하지 않고 publish_ok = False로 표시합니다.
  2. mqtt_common.append_event 감사 로그 작성 및 mqtt_common.update_job_status(status=new_status) 레지스트리 상태 동기화를 발행 성공 여부와 무관하게 항상 수행합니다.
  3. 감사 로그 레코드에 "published": publish_ok"publish_error": str(exc) 필드를 기록합니다.
  4. 모든 로컬 디스크 동기화가 완료된 후, 네트워크 발행이 실패했다면 기존 호출부 계약 유지를 위해 return 2를 반환합니다.

3.2 Step 2 — job_subscriber.py 로컬 디스크 폴백 도입 (B-15 / C1)

  1. 대기 루프의 queue.Empty 분기(job_subscriber.py:233)에서, 3초 간격 스로틀로 감시 중인 잡의 디스크 터미널 상태를 확인합니다 (registry.load_job -> mqtt_common.read_logged_status).
  2. 디스크에서 터미널 상태(completed 또는 error)가 감지되면, source: disk-fallback 합성 이벤트를 표준 출력에 기록하고 즉시 정상 종료합니다.
  3. 종료 코드 매핑: 디스크 상태가 completed이면 return 0, error이면 return 1을 반환합니다.

3.3 Step 3 — multi-agent-mux-delegate-job 인프라 예외 분리 (B-15 / F-4)

  1. job_subscriber.py의 미포착 브로커 접속 예외에 전용 종료 코드 rc=3을 부여합니다.
  2. multi-agent-mux-delegate-job:331-341sub_rc 매핑에 rc=3 분기를 추가하여 job_status="broker_unavailable"로 분류하고, wait_for_job과 동일하게 디스크 상태를 재확인합니다.

3.4 Track 0 회귀 가드 매트릭스 (10종 신설 — G-1 ~ G-10)

ID 가드 내용 변이 검출 기준 (Mutation)
G-1 브로커 도달 불가 시 publish_event.pyrc=2이면서 레지스트리 status=completed 기록 return 2를 상태 동기화 앞으로 이동 시 FAIL
G-2 동일 상황 감사 로그에 published: falsepublish_error 레코드 존재 append_event를 성공 경로로만 한정 시 FAIL
G-3 브로커 정상 시 rc=0 + status=completed + published: true 무회귀 검증
G-4 발행 실패 후 last_seq가 1 증가하고 후속 발행이 더 큰 seq 사용 seq 롤백 도입 시 FAIL
G-5 디스크 status=completed 선작성 시 브로커 다운 상태에서도 job_subscriber.py가 3초 내 rc=0 종료 디스크 폴백 제거 시 FAIL
G-6 동일 조건에서 stdout 합성 라인에 disk-fallback 표기 확인 표기 누락 시 FAIL
G-7 디스크 status=error 시 폴백 rc=1 반환 확인 매핑 반전 시 FAIL
G-8 다중 잡 감시 시 전체 완료 전까지 조기 종료 방지 부분 종료 도입 시 FAIL
G-9 디스크 터미널 부재 + 브로커 실패 시 rc=3 반환 확인 rc=1로 되돌릴 시 FAIL
G-10 loop 위임 경로에서 rc=3 수신 시 job_status"error"로 오판되지 않음 확인 3분기 매핑 복원 시 FAIL

4. Track 1: nats-server 스파이크 검증 (O-5)

실행 원칙: 메인 저장소 작업 트리를 오염시키지 않기 위해 격리 클론(git clone --local --no-hardlinks . "$SCRATCH/nats-spike")에서 수행하고 종료 후 삭제합니다.

ID 검증 항목 검증 방법 통과 기준
S-1 nats-server MQTT 리스너 기본 수용 nats-server -c nats.conf 기동 후 started/progress/completed 3연속 발행 rc=0, 레지스트리 status=completed
S-2 paho 2.x CallbackAPIVersion.VERSION2 호환 on_connect CONNACK reason code 수신 확인 reason_code == 0
S-3 Retained Terminal Event 전달 (핵심 관문) --event completed 발행 후 신규 job_subscriber.py 기동 즉시 최종 이벤트 수신 (실패 시 mosquitto로 회귀)
S-4 QoS 1 발행 ACK info.wait_for_publish() 대기 is_published() == True
S-5 와일드카드 토픽 라우팅 mam/<fp>/jobs/+/events 구독 후 이벤트 수신 SUBSCRIBED 출력 및 페이로드 수신
S-6 인증 및 TLS 암호화 user/pass 및 TLS 구성 후 접속 테스트 자격증명 누락 시 거부, 유효 시 성공
S-7 Subject 단위 권한 격리 Publisher write-only / Subscriber read-only 설정 비인가 작업 시 연결 거부
S-8 전체 회귀 테스트 pytest tests/ -q 전건 PASS (0 failed)
S-9 Track 0 내결함성 통합 검증 nats-server 강제 종료 상태에서 위임 잡 완주 테스트 wait_for_job 3초 내 반환

5. Track 2: A-2 보안 결함 및 워크스페이스 격리 해소 (A-2, B-16)

  1. auth_token 무조건 발급 (F-3 / G-11): registry.register_job()에서 브로커 설정과 무관하게 항상 secrets.token_urlsafe(32) 기반 토큰을 발급하여 공개 브로커 환경에서도 HMAC 검증이 무력화되지 않도록 강제합니다.
  2. 워크스페이스 지문 토픽 3단계 전환 (F-2):
    • Step 1: 발행자 기본 토픽을 mam/<sha256[:12]>/jobs/<id>/events로 전환합니다.
    • Step 2: 실환경 및 통합 테스트에서 이벤트 수신을 확인합니다.
    • Step 3: reconcile.sh:237의 레거시 전역 토픽(python/mqtt/jobs/...) 구독을 제거합니다.

6. Track 3: 문서 및 배포 설정 동기화

대상 파일 갱신 내용
MESSAGING.md 브로커 표준을 nats-server로 갱신, F-1/C1 해소 기록, F-5 영속 세션 서술 정정
IMPROVEMENTS.md A-2 완료 전환, B-14/B-15/B-16/O-5 해결 상태 갱신
VERSIONS.md v2.0.0 릴리스 노트에 메시징 백플레인 고도화 및 내결함성 패치 기록
PRIVATE_SERVER.md 스파이크 결과 반영 및 최종 가이드 확정
deploy/install.sh requirements.txt 확인 (paho 유지) 및 개인 브로커 안내 추가
.mam.env MQTT_BROKER, MQTT_PORT, MQTT_TLS 기본 템플릿 확정

7. 의존성 그래프 및 롤백 전략

[M0: 문서/가드] ────────────┐
  │                         │ (M0 A-1 환경변수 정렬 선행)
  ▼                         ▼
[M1: Track 0 내결함성] ──> [M2: Track 1 스파이크] ──> [M3: Track 2 보안] ──> [M4: 동기화]
  • 롤백 전략:
    • nats-server 스파이크(S-3) 실패 시: 클라이언트 코드 변경 없이 .mam.env의 브로커 주소만 eclipse-mosquitto로 전환합니다 (가역성 100%).
    • Track 0 내결함성 패치는 브로커 제품과 무관하게 순수 이득이므로 롤백하지 않고 영구 유지합니다.

8. 진행 추적 체크리스트

M0: 문서 정합성 확보

  • PRIVATE_SERVER.md E-1~E-4 교정 및 다능성 절(§5) 추가
  • implementation_plan.md 4개 트랙 및 마일스톤 수립
  • tests/test_deploy_freshness.py 내 G-D1 ~ G-D4 문서 드리프트 가드 구현

M1: Track 0 내결함성 확보 (B-14, B-15)

  • Step 1: publish_event.py 상태 동기화 선행 처리 (B-14 / G-1~G-4)
  • Step 2: job_subscriber.py 로컬 디스크 폴백 도입 (B-15 / G-5~G-8)
  • Step 3: multi-agent-mux-delegate-job 인프라 rc=3 에러 분리 (F-4 / G-9~G-10)
  • M1 통합 검증 (브로커 다운 상태 위임 3초 완주)

M2: Track 1 nats-server 실증 (O-5)

  • 격리 클론 생성 ($SCRATCH/nats-spike)
  • S-1 ~ S-9 스파이크 매트릭스 검증 수행
  • S-3 Retained 메시지 게이트 통과 확인

M3: Track 2 보안 및 토픽 격리 (A-2, B-16)

  • G-11 무조건 auth_token 발급 적용
  • 워크스페이스 지문 토픽 발행 전환 및 레거시 구독 제거

M4: Track 3 문서 및 배포 동기화

  • MESSAGING.md, IMPROVEMENTS.md, VERSIONS.md, deploy/* 최종 갱신