Files
multi-agent-mux/implementation_plan.md
T

13 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 1R 원격 프로덕션 (P1) VPS/홈랩 nats-server Docker 상시 가동 및 MAM 원격 백플레인 전환 PRIVATE_SERVER.md §9, 서버측 docker-compose.yml/nats.conf, .mam.env
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 내결함성) ──> M2a (로컬 스파이크) ──> M2b (원격 배포) ──> 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)
M2a 로컬 스파이크 (Track 1) 격리 클론에서 S-1 ~ S-9 스파이크 완수 S-3(Retained Terminal Event) 통과 (실패 시 mosquitto로 분기)
M2b 원격 프로덕션 전환 (Track 1R) D-1~D-5 교정 + §9 원격 배포 + §9.5 전환 R-3(노출0) · R-5(retained) · R-6(신원) · R-9(계정격리) 동시 통과
M3 보안 종결 (Track 2) A-2 지문 토픽 전환, G-11 무조건 토큰 발급 지문 토픽 동작 확인 legacy 구독 제거
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 1R: 원격 프로덕션 전환 로드맵 (M2b 상세)

[P0 교정]      D-1~D-5 문서 교정 + §5.2 경계 명문화 + 신규 가드 7종
   ▼
[P1 서버 준비] VPS/홈랩 프로비저닝, Docker, Tailscale 가입
   ▼
[P2 배포]      nats.conf + compose 기동, healthcheck healthy 확인
   ▼
[P3 잠금]      바인드 주소 한정 + UFW + ss/nmap 로 노출 면적 0 단언 (R-3)
   ▼
[P4 전환]      드레인 → 잔여 스캔 → .mam.env 교체 (§9.5)
   ▼
[P5 검증]      R-1 ~ R-10. R-5(retained) / R-9(계정 경계) 를 최종 관문으로
   ▼
[P6 상시화]    로그 로테이션, JetStream 볼륨 백업, healthcheck 알림

6. 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/...) 구독을 제거합니다.

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

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

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초 완주)

M2a: Track 1 nats-server 로컬 실증 (O-5)

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

M2b: Track 1R 원격 프로덕션 전환

  • D-1 store_dir 절대경로 교정 + 비인용 heredoc (PRIVATE_SERVER.md:73, :146)
  • D-2 이미지 핀 nats:2.12-alpine + /healthz healthcheck
  • D-3 8222/8080 바인드 주소 한정
  • D-4 TLS 절의 IP 예시 제거 및 DNS/SAN 요건 명시
  • D-5 .mam.env.example 정합 (MQTT_KEEPALIVE 추가)
  • N-1 §5.2 에 retained=MQTT 전용 경계 명문화 + §9.1 mam_observer 추가
  • 신규 가드 G-D5 ~ G-D9, G-R1, G-R2 구현 및 검증 (290 -> 297)
  • 서버 배포 및 R-3 노출 면적 0 단언
  • §9.5 드레인·잔여 스캔 후 .mam.env 전환
  • R-1 ~ R-10 전건 통과 (R-5 / R-9 최종 관문)

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

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

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

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