docs: clean up root markdown files and synchronize with v4.4.0 standards

- Relocate legacy implementation_plan.md to docs/contracts/nats-backplane/implementation_plan.md
- Synchronize root documentation (README, README.ko, BOOTSTRAP, BOOTSTRAP.ko, AGENTS, MESSAGING, IMPROVEMENTS) to latest v4.4.0 standards
- Consolidate IMPROVEMENTS.md to single source of truth (5 open / 31 completed tasks 1:1 matching section headers)
- Archive unanimous PASS review reports from Claude, Grok, Codex, and OpenCode along with Plan Rev.2
This commit is contained in:
Godopu committed 2026-09-08 08:02:37 +09:00
1 parent 07cae71667
commit f98b9582c7
13 files changed
+450 -112

No files matched your search

@@ -0,0 +1,138 @@
# 📑 Implementation Plan Rev.2 — Workspace Root Markdown 정리 및 최신화 (Job baea3f7e, 원본 45bd8635)
- **역할**: Planner (`planner-reviewer-claude-01`)
- **기준 커밋**: `07cae71` (`main`, v4.4.0, 전체 스위트 750 passed / 문서 바인딩 4모듈 49 passed)
- **개정 사유**: Creator(`creator-agy-01`, Job `87aa5b5a`) 이의제기 3건. **3건 모두 실측으로 사실 확인되어 전부 수용**하고, 검증 과정에서 Planner 자신의 Rev.1 오류 1건(D-1/Phase B-1 "잔재에 고유 내용 없음")을 추가로 발견하여 함께 정정한다.
- **Rev.1 대비 변경 범위**: §1 D-1, Phase A-2, Phase B 전면, Phase D-1, 게이트 4. 나머지 Phase C/E/F/G와 게이트 1·2·3·5·6은 Rev.1 그대로 유효(본문 하단에 원문 유지).
---
## 0. 이의제기 판정 (Adjudication of Challenge)
| # | Creator 주장 | Planner 실측 | 판정 |
|---|---|---|---|
| C-1 | 완료 과제는 §5 단일 섹션이 아니라 §2(5건)·§3(2건)·§5(24블록)에 분산되어 있고, 헤더 "30건"은 전역 합계이며 Rev.1 Phase B-2 지시("§5의 `###` 수로 재계산해 헤더와 일치")는 실행 불가 | `awk`로 전 `###` 블록을 섹션별로 열거: §2 완료 5(B-21,B-20,B-19,B-14,B-15), §3 완료 2(O-6,A-4), §5 24블록(O-2 중복 2회), 헤더 ID 정확히 30개. **주장 사실.** 단 Creator의 산식 "5+2+23=30"은 우연한 일치다. ID↔블록이 1:1이 아니기 때문이다(아래 §1-A) | **수용** — 방안 A 채택, 단 계수 규칙을 블록 기준으로 명문화 |
| C-2 | 이관되는 `implementation_plan.md` §7 표의 `[.mam.env](.mam.env)` 링크는 gitignored 파일(`test_d29`가 추적 금지)이라 클린 체크아웃에서 게이트 4 `test -e`가 실패 | `.gitignore:24` `.mam.env`, `git ls-files`에 `.mam.env.example`만 추적, `tests/test_deploy_freshness.py:687 test_d29_env_secrets_never_tracked` 존재, 원문 151행 링크 확인. **주장 사실.** | **수용** — 링크 대상을 `.mam.env.example`로, 게이트 4에 ignore 예외 규칙 추가 |
| C-3 | Phase D-1 트리 추가 목록에 `IMPROVEMENTS.md` 누락, 영문 README 트리에 `README.ko.md`/`BOOTSTRAP.ko.md` 부재, 한국어 README에는 `BOOTSTRAP.ko.md`만 존재 → "줄수 일치" 게이트 기준 불명확 | `README.md:188-190` 3개 루트 md, `README.ko.md:170-173` 4개 루트 md. **주장 사실.** | **수용** — 루트 md 8개 전부를 양 README 트리에 동일 순서로 명시 |
부수 정정: Creator 보고서의 "450줄"은 `wc -l` 기준 449줄(마지막 줄 개행 있음)이나 판단에 영향 없음.
---
## 1. 정정된 결함 진단
### 1-A. `IMPROVEMENTS.md` 완료 과제 원장 (Planner 실측, 정본)
헤더 ID 30개와 완료 `###` 블록 31개(잔재 제외)의 대응은 다음과 같다. 이 표가 Phase B의 유일한 기준이다.
| 헤더 ID | 현재 블록 위치 | 비고 |
|---|---|---|
| B-21, B-20, B-19, B-14, B-15 | §2 (30/44/54/64/68행) | 미해결 섹션에 완료 항목 혼재 |
| O-6, A-4 | §3 (99/106행) | A-4 블록은 Rev.2 어댑터 계층 45행 분량 |
| B-9, B-13, B-10, B-5, C-6, P2-2, P2-1, B-4, O-3, A-1, A-3, C-2, A-5, B-1, B-3, C-1, O-1, Herdr-0.8.0-Compat-SanitizeHash | §5 | 1:1 대응 |
| B-7 | §5 `P0-1 (B-7)` (253행) | 키 표기 상이 |
| O-4-OrcOnboard | §5 `multi-agent-mux-orc-onboard` (242행) | 키 표기 상이 |
| **O-2** | §5 **2블록**: `P0-2 (O-2)` 247행(Rev.1: pid+lstart 마커, 46/46) + `O-2` 273행(Rev.2: 하드링크 원자 쓰기, steal_lock, 204/204) | **동일 과제의 연속 개정** → 병합 대상 |
| **C-3b** | 독립 블록 없음. §5 `P3-1 (A-4 Phase 2 / Option B / C-3b / M2~M7)` 224행 제목에 포함 | P3-1 블록이 A-4(2차)와 C-3b를 동시에 담음 |
| **B-8** | **독립 블록 없음.** §6.2 표 367행 `P1-2(과거) B-8 … (✅ 완료 — tests/test_b8_send_keys_verification.py 1/1 PASS)`에만 존재 | `tests/test_b8_send_keys_verification.py` 실재 확인 |
| (헤더에 없음) | §5 `Rev.2 (b4a1d094)` 260행 세션 ID 자동 할당 | 헤더 ID 목록에서 누락된 블록 |
결론: "헤더 30 = §2 5 + §3 2 + §5 23"은 (O-2 중복 −1, C-3b 블록 없음 −1, B-8 블록 없음 −1, Rev.2 블록 ID 없음 +1, P3-1 별도 블록 +1)이 상쇄된 우연이다. Rev.2는 **"§5의 `###` 블록 1개 = 헤더 ID 1개"**를 강제하여 이 우연을 제거한다.
### 1-B. Rev.1 오류 정정 — 154~186행 잔재는 단순 삭제 불가
Rev.1 Phase B-1은 "앞쪽 사본이 최신 서술을 모두 포함(확인됨)"이라 했으나 **틀렸다**. 잔재 전용 토큰 20종을 실측했다: B-14 원 진단(`publish_event.py:195-199`, `wait_for_job()`, `max_wait=3900s`, `status=running`), B-15 원 진단(`job_subscriber.py:172-251`, `queue.Empty`, `idle_timeout`, `multi-agent-mux-delegate-job:331-341`, `wait "$sub_pid"`, `sub_rc`, `job_status="error"`, `job_status="broker_unavailable"`, `load_job`/`read_logged_status`, `source: disk-fallback`), O-5 배경(`nats-py` Option B 기각 사유). 앞쪽 B-14/B-15 블록(64~70행)은 각 2줄 요약뿐이다. B-16 블록은 양쪽 동일(잔재 고유 내용 없음). 따라서 잔재는 **병합 후 삭제**한다(Phase B-1).
---
## 2. 개정된 작업 계획 (변경된 Phase만 기술; 미기재 Phase는 Rev.1 원문 적용)
### Phase A-2 (개정) — 이관 파일 링크 규칙
- `git mv implementation_plan.md docs/contracts/nats-backplane/implementation_plan.md` 후 상대 링크를 `../../../` 접두로 승격하되, **§7 표의 `[.mam.env](.mam.env)`는 `[.mam.env (템플릿: .mam.env.example)](../../../.mam.env.example)`로 변경**한다. 이유: `.mam.env`는 gitignored(`.gitignore:24`)이며 `test_d29`가 추적을 금지하므로 클린 체크아웃에 존재하지 않는다.
- 같은 이유로 문서 내 `.mam.env`를 **파일 링크 없이 코드 스팬으로만** 언급하는 것은 허용한다(23행·122행은 링크가 아니므로 변경 불필요).
### Phase B (전면 개정) — `IMPROVEMENTS.md` 단일 원장화 (방안 A 채택)
작업 순서를 엄수한다. 행 번호는 착수 시점 기준이며 이후 단계는 **헤더 문자열로 앵커링**한다.
1. **잔재 병합 후 삭제** (1-B 반영)
- 잔재 `### **B-14 (F-1 / P1)…`(156행)의 `현상`·`파급 효과` 불릿을 앞쪽 `### **B-14 (✅ 완료 — F-1 / P1)…` 블록의 `현상` 불릿 **아래에 "원 진단" 불릿으로 추가**(내용 원문 유지, 시제만 과거형 허용).
- 잔재 B-15(161행)의 `현상` 1·2항과 `파급 효과`를 앞쪽 B-15 블록에 동일 방식으로 추가.
- 잔재 O-5(179행)의 `현상` 문장 중 "`nats-py` 클라이언트 재작성(Option B)을 배제하고" 구절을 앞쪽 O-5 `현상`에 삽입.
- 잔재 B-16(170행)은 앞쪽과 동일하므로 추가 없음.
- 그 다음 두 번째 `## 2. 🟠 …(Edge-case Bugs — 3건)`부터 두 번째 `## 3.` 블록 끝(`## 4. ⚪ 레거시 잔재` 직전 구분선)까지 삭제.
- **검증**: 위 20종 토큰 전부가 삭제 후 파일에 여전히 존재(`grep -cF`로 각 1 이상), `grep -c '^## 2\.'`=1, `grep -c '^## 3\.'`=1.
2. **완료 블록 §5 이관** (방안 A)
- §2의 B-21, B-20, B-19, B-14, B-15 블록과 §3의 O-6, A-4 블록을 **현재 등장 순서 그대로** `## 5. 🎉 완료된 과제` 제목 바로 아래(기존 B-9 앞)에 삽입. 블록 본문은 한 글자도 바꾸지 않는다(제목의 `(✅ 완료 — …)` 표기 포함).
- 이관 후 §2에는 B-16, B-17, B-18만, §3에는 O-5만 남는다.
3. **O-2 중복 병합**
- `### **O-2: 동일 워크스페이스 … (Race-Free Mutex & Ownership)**`(Rev.2, 최종본)을 유지하고, `### **P0-2 (O-2): …**` 블록은 제목을 제거한 뒤 그 불릿 4개를 O-2 블록 **끝에 `- **Rev.1 (P0-2) 선행 조치**:` 하위 불릿으로** 편입한다. 제목은 `### **O-2 (P0-2): …**`로 갱신하여 키 대응을 유지.
4. **B-8 블록 신설** (원장 완결성)
- `## 5` 말미(Herdr-0.8.0 블록 뒤)에 `### **B-8 (P1-2): agy 주입 시 \`return 0\` 우회 제거 및 제출 검증 루프 이관** — ✅ 완료` 블록을 추가하고, 불릿 1개만 둔다: §6.2 표 367행의 서술을 그대로 옮기고 근거로 `tests/test_b8_send_keys_verification.py` (1/1 PASS)를 명기한다. **새 사실을 지어내지 않는다** — 표 367행 밖의 내용은 쓰지 않는다.
5. **섹션 헤더 카운트 확정** (계수 규칙: 해당 섹션 하위 `###` 블록 수)
- `## 1. 🔴 아키텍처 결함 (Architecture Flaws — 1건)` (A-2)
- `## 2. 🟠 엣지 케이스 및 런타임 버그 (Edge-case Bugs — 3건)` (B-16, B-17, B-18)
- `## 3. 🟡 오케스트레이션 최적화 과제 (Orchestration Optimizations — 1건)` (O-5)
- `## 4. ⚪ 레거시 잔재 및 죽은 코드 (Legacy Remnants — 0건 — 전원 완료)` (변경 없음)
- `## 5. 🎉 완료된 과제 (Completed Tasks — 31건)` = 기존 24 − 1(O-2 병합) + 7(이관) + 1(B-8) = **31**
6. **헤더 요약(3~6행) 동기화**
- `최종 갱신일`: `2026-09-07 (IMPROVEMENTS.md 단일 원장화: §2/§3 완료 항목 §5 이관, 머지 잔재 병합 제거, v4.1.x~v4.4.0 완료 사항 반영)`.
- `총 추적 미해결 과제`: **5건** 문구 유지(A-2 / B-16, B-17, B-18 / O-5).
- `완료된 과제`: **31건**으로 갱신하고 괄호 목록을 **§5 블록 키를 등장 순서대로 나열한 31개**로 교체: `B-21, B-20, B-19, B-14, B-15, O-6, A-4, B-9, B-13, B-10, B-5, C-6, P3-1-A4Phase2-C3b, P2-2-C3a-C4-LegacyCleanup, P2-1-DelegateJobSafe-TrapFix, O-4-OrcOnboard, O-2-P0-2, P0-1-B-7, Rev.2-b4a1d094-SessionIdPinning, B-4, O-3, A-1, A-3, C-2, A-5, B-1, B-3, C-1, O-1, Herdr-0.8.0-Compat-SanitizeHash, B-8`. (기존 `B-7`, `C-3b`, `O-2`, `A-4`는 위 키 안에 포함되어 유실되지 않는다.)
7. **v4.1.x~v4.4.0 반영** (Rev.1 B-3 유지, 위치만 명확화)
- 기존 `### **B-13 (Stage 2)…` 블록 끝에 1불릿: "v4.4.0(Issue #5 Phase 4)에서 freeze 스냅샷을 기본 경로에서 철거, `MAM_LOOP_FREEZE=1` 롤백 스위치만 잔존 (`docs/contracts/issue-5/phase4-freeze-removal.md`)".
- 신규 블록은 추가하지 않는다(codex/grok/opencode 통합, Python 코어 마이그레이션은 `VERSIONS.md`가 정본이며, 백로그 ID가 부여된 과제가 아니므로 §5에 등재하지 않는다). 대신 `📌 개요` 절 끝에 1문장: "v4.1.0 이후 릴리스 단위 변경 이력은 `VERSIONS.md`를 정본으로 하며 본 백로그는 ID가 부여된 과제만 추적한다."
8. **보존 필수 문자열**: `### **O-1: 타당하지 않은 리뷰 피드백 거부/반론 프로토콜 미지원 (Rebuttal Protocol)**` 제목과 본문은 변경 금지 (`test_o1_rebuttal.py::test_v10`).
- **Phase B 검증 스크립트 (Creator 실행 필수)**:
```bash
f=IMPROVEMENTS.md
test "$(grep -c '^## 2\.' $f)" = 1 && test "$(grep -c '^## 3\.' $f)" = 1
# §5 블록 수 = 31, 헤더 괄호 ID 수 = 31
awk '/^## 5\./{s=1;next} /^## 6\./{s=0} s&&/^### /{n++} END{print n}' $f # → 31
sed -n '6p' $f | grep -o -E '\(B-21.*\)' | tr ',' '\n' | grep -c . # → 31
# 각 완료 ID의 ### 제목이 정확히 1회
for id in B-21 B-20 B-19 B-14 B-15 O-6 O-2 B-8 A-4; do test "$(grep -c "^### \*\*$id[ :(]" $f)" = 1 || echo "DUP/MISSING $id"; done
# §2·§3에 ✅ 완료 블록 잔존 금지
awk '/^## 2\./{s=1} /^## 4\./{s=0} s&&/^### .*✅/{print "LEAK: "$0}' $f
.venv/bin/python -m pytest -q tests/test_o1_rebuttal.py
```
### Phase D-1 (개정) — README 트리의 루트 마크다운 표기 기준
- 양 README의 `text` 트리 **루트 레벨 마크다운 항목은 다음 8개를 알파벳 순으로 전부** 기재한다(언어별 미러 포함, 기존 3~4개 → 8개): `AGENTS.md`, `BOOTSTRAP.ko.md`, `BOOTSTRAP.md`, `IMPROVEMENTS.md`, `MESSAGING.md`, `README.ko.md`, `README.md`, `VERSIONS.md`. 설명 문구만 언어별로 다르다.
- 디렉터리 항목 추가 목록은 Rev.1 D-1 그대로(`lib_py/` 3패키지, `scripts/` shim 재표기, `docs/` 4항목, `nats-docker/`, `tests/`).
- **검증**: 두 파일의 트리 블록에서 `├──|└──`로 시작하는 줄 수가 동일하고, 루트 md 8개 문자열이 양쪽에 각 1회 존재.
### 게이트 4 (개정) — 깨진 상대 링크 0건
- 검사 대상: 루트 8개 + 이관 문서. 링크 경로 추출 후 `test -e`; **단 `git check-ignore -q <path>`가 참인 경로는 검사에서 제외**하지 않고 **오류로 처리**한다(추적되지 않는 파일로의 링크는 문서 결함이므로 Phase A-2 규칙에 따라 링크 자체를 제거/대체해야 한다). 즉 게이트 4 = "모든 링크 대상이 존재하고 git 추적 대상이다".
```bash
for f in README.md README.ko.md BOOTSTRAP.md BOOTSTRAP.ko.md MESSAGING.md IMPROVEMENTS.md AGENTS.md VERSIONS.md docs/contracts/nats-backplane/implementation_plan.md; do
d=$(dirname "$f")
grep -o -E '\]\(([^)#]+)(#[^)]*)?\)' "$f" | sed -E 's/^\]\(//; s/#.*//; s/\)$//' | grep -v -E '^(https?:|mailto:|file:)' | while read -r p; do
t="$d/$p"; { test -e "$t" && git ls-files --error-unmatch "$t" >/dev/null 2>&1; } || echo "BROKEN/UNTRACKED: $f -> $p"
done
done
```
- 주의: `IMPROVEMENTS.md` 248행 등에 `file:///Users/...` 절대 링크가 존재한다. 본 게이트에서는 제외(`file:` 필터)하되, Phase B-3 O-2 병합 시 해당 불릿의 `file://` 링크는 상대 경로 `.agents/skills/multi-agent-mux-loop/scripts/loop_lock.sh`로 교체한다(같은 불릿을 만지는 김에 최소 수정).
---
## 3. 최종 검증 게이트 (Rev.2 확정본)
1. 루트 마크다운 8개, `implementation_plan.md`는 `docs/contracts/nats-backplane/`.
2. `pytest -q tests/test_deploy_layout.py tests/test_o1_rebuttal.py tests/test_deploy_freshness.py tests/test_version_consistency.py` → 49 passed.
3. `pytest -q tests/` → 750 passed.
4. 위 개정 게이트 4 스크립트 출력 0줄.
5. `git diff --stat`에 `.agents/skills/**`, `tests/**`, `deploy/**` 변경 없음.
6. `MAM_INSTALL_DOCS=minimal|full` 설치 시 루트 문서 1개/4개.
7. **(신설)** Phase B 검증 스크립트 전 항목 통과: §5 블록 31 = 헤더 ID 31, §2/§3 완료 블록 누출 0, 잔재 토큰 20종 보존.
## 4. 범위 외 (Rev.1 §4 유지) + 추가
- `nats-docker/PRIVATE_SERVER.md:5` 깨진 링크 — 서브모듈 별도 커밋.
- 미해결 5건(A-2, B-16, B-17, B-18, O-5)의 코드 대조 재판정 — 별도 리뷰 잡. 특히 B-17은 `MESSAGING.md:310`이 "구현됨"으로 서술하고 있어 상태 불일치 의심이 있으나 **본 작업에서는 손대지 않는다**(코드 확인 없이 완료로 옮기면 원장 오염).
- README 배지 5번째 lockstep 레그 — 별도 잡.
## 5. 리스크
- Phase B는 이동·병합이 많아 유실 위험이 가장 크다. 반드시 **B-1 → B-2 → B-3 → B-4 순서**로 각 단계 후 검증 스크립트를 실행하고, 최종적으로 `git diff --stat IMPROVEMENTS.md`의 삭제 줄 수가 (잔재 33줄 + P0-2 제목 1줄 + 이관에 따른 이동분) 범위 안인지 확인한다. 이관은 `git diff`에서 삭제+추가로 보이므로 `git diff --color-moved=plain`으로 이동임을 확인한다.
---
## 부록. Rev.1 원문 중 유효 유지 항목 (변경 없음)
- §0 실측 인벤토리 표 및 KEEP/이관 판정 9건.
- §1 D-2(MESSAGING lib_py 미반영), D-3(README 트리), D-4(BOOTSTRAP §1), D-5(implementation_plan 이관), D-6(AGENTS §5).
- Phase A-1/A-3/A-4, Phase C 전체, Phase D-2~D-4, Phase E, Phase F, Phase G.
@@ -0,0 +1,52 @@
# 🔍 Cross-Review Report (재검토) — Workspace Root Markdown 정리 및 최신화 (Job f28629a3)
- **리뷰어**: `planner-reviewer-claude-01` (Reviewer)
- **기준**: `main` `07cae71` 워킹트리(미커밋). 직전 리뷰 `50886e6f`([VERDICT: NOT PASS], 차단 결함 D-1/D-2)에 대한 재검토.
- **범위 고정**: 브리프 내장 diff = `git diff HEAD -- . ':(exclude).agents/reports'`(55,043 B) + 아카이브된 Rev.2 계획 사본(`.agents/reports/planner-reviewer-claude-01/plan-baea3f7e.md`). 두 diff의 차이는 계획 사본 블록(145줄)뿐. 변경 파일 8 + 이관 1, 코드·테스트·인스톨러 변경 0건.
---
## 1. 직전 리뷰 대비 델타 (실측: `diff head_5088.diff head_f286.diff`)
정확히 3곳만 달라졌다. 그 외 diff 본문은 바이트 동일.
| # | 위치 | 변경 | 직전 지적 대응 |
|---|---|---|---|
| Δ1 | `MESSAGING.md:350` §5.1 CAS 문단 | "monotonic `dispatch_token`" → "opaque per-attempt `dispatch_token` (fresh `uuid4` hex issued whenever an attempt starts via `claim`/`redispatch`) … compared inside the registry lock as an `expected_dispatch_token` precondition; ordering … tracked separately by the monotonic `transition_seq` counter" | **D-1 해소** |
| Δ2 | `MESSAGING.md:353` §5.1 항목 1 | 로그 경로 `<job_id>.<phase>.subscriber.out` → `<job_id>.subscriber.out (loop iterations use <job_id>.iter_<n>_<role>.subscriber.out)` | **D-2 해소** |
| Δ3 | `IMPROVEMENTS.md:307-311` B-8 블록 | 앞 공백 2줄→1줄, 뒤 `---` 앞 공백 1줄 추가 | 비차단 O-2 해소 |
## 2. 델타의 코드 대조
| 문장 요소 | 코드 근거 | 판정 |
|---|---|---|
| `dispatch_token` = 시도 시작 시 `uuid4` hex 재발급 | `engine.py:300` `record[DISPATCH_TOKEN_FIELD] = uuid.uuid4().hex`, 발급 조건 `request in ATTEMPT_STARTING_REQUESTS` (`engine.py:87` = `("claim", "redispatch")`) | ✅ |
| 락 안에서 `expected_dispatch_token` 전제조건 대조 | `engine.py:181-183`; 계약 `docs/contracts/issue-5/state-transitions.md:57` | ✅ |
| 순서는 `transition_seq` 단조 카운터 | `engine.py:296` `+ 1` 증가, 주석 "A monotonic counter" | ✅ |
| `MAM_ENGINE_CAS=1` 기본 | `engine.py:109` | ✅ (변경 없음) |
| direct 경로 `<job_id>.subscriber.out` | `multi-agent-mux-delegate-job:165` | ✅ |
| 루프 경로 `<job_id>.iter_<n>_<role>.subscriber.out` | `:286` `${JOB_ID}.iter_${iteration}_${display_role}.subscriber.out` | ✅ |
| `grep -n monotonic MESSAGING.md` | 3건: 227행(`last_seq`, HEAD 기존), 294행(monotonic time, HEAD 기존), 350행(`transition_seq`, 신규·정확). HEAD 기준 2건 → 3건 | ✅ 직전 리뷰 재검증 조건 충족 |
## 3. Rev.2 게이트 전건 재실행
| 게이트 | 결과 |
|---|---|
| G1 루트 md 8개, 이관 파일 존재 | ✅ 8 |
| G2 문서 바인딩 4모듈 | ✅ **49 passed** (57.96s) |
| G3 전체 스위트 | §5 |
| G4 상대 링크 (서브모듈 인식 보강판: `nats-docker/*`는 `git -C nats-docker ls-files`로 추적 확인) | ✅ BROKEN/UNTRACKED 0건 (직전 오탐 6건 해소) |
| G5 `.agents/skills`, `tests`, `deploy` 무변경 | ✅ stat 0줄 |
| G6 인스톨러 | ✅ minimal rc=0 `AGENTS.md`; full rc=0 `AGENTS.md BOOTSTRAP.ko.md BOOTSTRAP.md MESSAGING.md` |
| G7 원장 | ✅ `## 2.`/`## 3.` 1/1, §5 블록 31 = 헤더 ID 31, 10개 핵심 ID 제목 각 1회, §2~§3 `✅` 누출 0, 잔재 토큰 **20/20** 보존 |
| README 트리 | ✅ 40/40줄, 루트 md 8/8 |
## 4. 잔여 관측 (비차단, 조치 불요)
- O-1(직전) B-14 "원 진단" 불릿과 `현상` 불릿 부분 중복 — 유지됨. 토큰 보존 목적이므로 허용.
- README `tests/ (32 modules)` — `test_*.py` 31 + `conftest.py` 1. 계수 기준 미명시이므로 허용.
- 게이트 4 스크립트의 서브모듈 오탐은 Planner(본인) 측 스크립트 결함이었으며 본 리뷰에서 보강판으로 대체. 향후 계획서 게이트에 반영 필요(Planner 후속).
## 5. 전체 회귀 스위트 (G3)
- `.venv/bin/python -m pytest -q tests/` (워킹트리, 본 변경 적용): **750 passed in 930.36s (0:15:30)**, FAILED/ERROR 0건. 기준선 `07cae71`(750)과 동일.
## 6. 결론
직전 차단 결함 D-1(`dispatch_token` 단조성 오기)·D-2(submit 로그 경로 오기)는 제시한 검증 문장으로 정확히 교체되었고, 코드(`engine.py:87/296/300`, `multi-agent-mux-delegate-job:165/286`)와 일치한다. 그 외 diff는 직전 리뷰 시점과 바이트 동일하며 모든 게이트(문서 테스트 49, 전체 750, 링크 0건 깨짐, 인스톨러 두 모드, 원장 31=31, 잔재 토큰 20/20, README 트리 40/40)를 통과한다. 린트·동작성·유실 관점 모두 결함 없음.
[VERDICT: PASS]
@@ -0,0 +1,28 @@
# Cross-review — root Markdown cleanup, follow-up
Job: `fd874949`
Reviewer: `planner-reviewer-codex-01` (`planner,reviewer`)
Baseline: `07cae71`, current working tree including the staged roadmap move.
No blocking findings remain. Both findings from review `2601270d` are resolved by documentation changes that match the implementation.
## Previous findings verified as resolved
1. **Optional dispatch-token comparison — resolved (`MESSAGING.md:350`).** The paragraph now distinguishes the token stored for an attempt from the optional `expected_dispatch_token` supplied by callers. It explicitly states that ordinary publisher status updates do not supply the precondition. This matches `lib_py/delegation/engine.py:181` and `:270`, the publisher update path in `lib_py/delegation/mqtt_common.py:435`, and inferred completion in `lib_py/loop/autocomplete.py:224`. Token generation and transition ordering also match `engine.py:296-300`.
2. **Subscriber readiness fallback — resolved (`MESSAGING.md:354`).** The handshake bullet now describes a bounded readiness attempt, warning and continuation after the polling budget expires, and continuation on early exit status 0 or 3. These statements match `multi-agent-mux-delegate-job/multi-agent-mux-delegate-job:172-194`; the previous unconditional readiness guarantee has been removed.
## Verification and review scope
- Compared the complete embedded diff payloads of jobs `2601270d` and `fd874949`: only the two passages above and the corresponding `MESSAGING.md` blob hash changed. The previously reviewed roadmap move, backlog consolidation, bilingual trees, bootstrap updates, and archived reports are unchanged.
- Verified every file included in the new brief against its recorded new Git blob hash; all match the current files.
- `git diff HEAD --check`: clean.
- No changes under `.agents/skills/`, `tests/`, or `deploy/`.
- Root Markdown inventory remains the required eight files. Backlog section counts remain **1 / 3 / 1 / 0 / 31**, with no completed blocks in sections 2 or 3.
- Rechecked **34 local link targets**, including six references tracked inside the `nats-docker` submodule: all exist and are tracked. The plan's parent-repository-only tracking check produces submodule false positives; validating those targets within their owning repository resolves them.
- Prior independent preservation checks remain applicable because the relevant files are byte-identical to the preceding review: O-1 content, moved completed blocks, legacy diagnosis details, README tree parity, and roadmap links showed no content-loss defect.
- Prior independent focused regression result from job `2601270d`: **49 passed in 54.88s**, using `tests/test_deploy_layout.py`, `tests/test_o1_rebuttal.py`, `tests/test_deploy_freshness.py`, and `tests/test_version_consistency.py`. This run was not repeated for the two prose corrections. The attached peer report's full-suite result of 750 passing tests and minimal/full installation checks remain attributed peer evidence, not an independent rerun in this job.
The two requested wording corrections close the review. No runtime changes or planner escalation are needed.
[VERDICT: PASS]
@@ -0,0 +1,35 @@
# Root markdown cleanup review (uncommitted tree on `07cae71`)
- **Reviewer**: `reviewer-creator-grok-01`
- **Job**: `30122522`
- **HEAD**: `07cae71` (working tree)
- **Diff**: `AGENTS.md`, `BOOTSTRAP.md` / `.ko.md`, `IMPROVEMENTS.md`, `MESSAGING.md`, `README.md` / `.ko.md`, `implementation_plan.md` → `docs/contracts/nats-backplane/implementation_plan.md`
- **Checks**: `git diff --check` clean. Root `*.md`: `AGENTS.md`, `BOOTSTRAP.md`, `BOOTSTRAP.ko.md`, `IMPROVEMENTS.md`, `MESSAGING.md`, `README.md`, `README.ko.md`, `VERSIONS.md`.
Documentation only. No production tests required. Tree re-read independently (same diff as job `01859590`; residuals below still present).
---
## What holds
The NATS backplane plan is off the workspace root and lives next to Issue #5 contracts. The new file records the move date and uses working relative links to `nats-docker/NATS_REPORT.md` and `PRIVATE_SERVER.md`.
`BOOTSTRAP.md` / `.ko.md` list `lib_py/{agents,delegation,loop}` and call `scripts/*.py` shims. `README.md` / `.ko.md` do the same in the skills list and directory tree. `MESSAGING.md` stamps v4.4.0, names `lib_py.delegation` as the body, notes CAS/`dispatch_token`, and marks HMAC as implemented. `AGENTS.md` O-3 still delegates via `run_loop.sh` and names the Python loop runtime.
`IMPROVEMENTS.md` is one ledger: **5 open** (A-2, B-16, B-17, B-18, O-5) and **31 completed**. Header IDs match completed `###` headings. Merge-duplicate B-14/B-15/B-16 blocks are gone. O-2 (P0-2) is still in §5. B-13 notes freeze removal in v4.4.0.
---
## Residuals (non-blocking)
1. **README architecture narrative was not updated.** Skills list and tree mention `lib_py.loop`; Layer A is still “lib.sh + status/resume/stop/create” and Layer B does not mention the CAS engine (`README.md:62-63`, same in `README.ko.md:44-45`).
2. **Inbound link not updated with the move.** `nats-docker/PRIVATE_SERVER.md:5` still points `implementation_plan.md` at `lac/curriculum/How_To_Use_GENAI/implementation_plan.md`. After this relocate it should be `../docs/contracts/nats-backplane/implementation_plan.md`. `IMPROVEMENTS.md` still names `NATS_REPORT.md` without a path; the file is `nats-docker/NATS_REPORT.md`.
3. **Stale line number.** B-16 still says `mqtt_common.py:258`; `client_id` is built at `lib_py/delegation/mqtt_common.py:276`.
4. **BOOTSTRAP parent line** still calls `skills/` “a collection of shell scripts” while listing `lib_py/` under it.
5. **`AGENTS.md` / `README.md` have no trailing newline.** Pre-existing. `git diff --check` is clean.
No `[ESCALATE: PLANNER]`.
---
[VERDICT: PASS]
@@ -0,0 +1,50 @@
# 🔍 Cross-Review: Workspace Root Markdown Cleanup & Modernization (Job b049e495)
- **Reviewer**: `reviewer-opencode-01` (role: reviewer)
- **Target**: Uncommitted working tree on `main` @ `07cae71` (v4.4.0): 7 modified root docs + 1 rename (`implementation_plan.md` → `docs/contracts/nats-backplane/implementation_plan.md`) — the Rev.2 plan (`plan-baea3f7e.md`) executed, refined through multiple review rounds (Claude `50886e6f` NOT PASS → `f28629a3` PASS re-review; Grok `30122522` PASS; codex `2601270d` findings remediated by `09f2c915`).
- **Method**: All plan gates re-run by me against the live tree — ledger algebra, link integrity (submodule-aware), tree parity, installer modes, doc-binding tests, the full regression suite, and every new MESSAGING.md technical claim traced to code.
---
## 0. My Verification Runs
| Check | Result |
|---|---|
| Full suite `pytest tests/ -q` (my own run, started in the interrupted `ee242671` round; tree unchanged since — only MESSAGING.md §350/§354 prose refined, no code/tests touched) | **750 passed / 0 failed** (983s) — identical to the `07cae71` baseline |
| Doc-binding 4-module suite (G2) | **49 passed** |
| Installer both modes (G6) | minimal rc=0, full rc=0 |
| Code/test/deploy drift | **0 files** — pure documentation change |
## 1. All Rev.2 gates re-verified by me
- **G1**: Root markdowns exactly 8 (AGENTS, BOOTSTRAP, BOOTSTRAP.ko, IMPROVEMENTS, MESSAGING, README, README.ko, VERSIONS); NATS plan relocated to `docs/contracts/nats-backplane/` via proper git rename, with move-date annotation and `../../../`-prefixed links; the §7 `.mam.env` link correctly retargeted to the tracked `.mam.env.example` (challenge C-2's gitignored-file trap avoided).
- **G4 (links)**: All relative links resolve and are git-tracked — 0 broken. (My first run flagged 6 `nats-docker/*` paths; I traced this to my own script lacking submodule handling — the files exist and are tracked in the submodule's repo, exactly the false-positive Claude's `f28629a3` documented and fixed. Submodule-aware re-run: clean.)
- **G7 (IMPROVEMENTS.md single ledger)**: single `## 2.`/`## 3.` headers; §5 = **31 blocks** = header **31 IDs**; per-ID `###` uniqueness holds for all spot-checked IDs; zero ✅ leakage into §2/§3; all 20 remnant-only tokens (B-14/B-15 original diagnoses, O-5 nats-py rationale, etc.) preserved ≥1 occurrence each — merged-then-deleted as the plan required, not silently dropped.
- **README trees**: 45/45 line parity, all 8 root mds in both trees' tree blocks (each exactly once within the block; the extra `BOOTSTRAP.md`/`VERSIONS.md` occurrences are the prose link and version badge — outside the tree block, expected).
- **O-1 preserved string**: covered by the passing `test_o1_rebuttal.py` in the 49.
## 2. The codex-review remediations (`2601270d` → `09f2c915`) — independently verified against code
This diff's MESSAGING.md §5.1 evolved after my interrupted prior round; the two changes are the codex reviewer's precision findings, and I verified both remediations against live source myself:
1. **`dispatch_token` precondition correctly scoped as optional** (MESSAGING.md:350) — verified: `engine.py:181` compares only `if expected_dispatch_token is not None` (default `None` at :147/:270); `mqtt_common.py:435` (ordinary publisher updates) calls `engine.transition` without the precondition; `lib_py/loop/autocomplete.py:224` (inferred completion) explicitly supplies `expected_dispatch_token=token`; token issuance gated on `ATTEMPT_STARTING_REQUESTS = ("claim", "redispatch")` (`engine.py:87`, `uuid4().hex` at :300); ordering by monotonic `transition_seq` (+1 at :296); `MAM_ENGINE_CAS` default-on (:109). Every sentence in the paragraph matches code.
2. **Subscriber handshake described as bounded wait with fallback** (MESSAGING.md:354) — verified: `multi-agent-mux-delegate-job:172-195` polls `^SUBSCRIBED ` every 0.2s for 25 iterations; on budget expiry it warns ("falling back to proceed") and proceeds; early subscriber exits 0 or 3 permit continuation. The old "ensure the subscriber is connected" overstated the guarantee — now accurate.
3. The D-1/D-2 fixes from the earlier Claude NOT PASS round (monotonic-token mischaracterization; `<job_id>.<phase>.subscriber.out` path error) remain correctly in place — the direct path `<job_id>.subscriber.out` (:165) and loop path `iter_<n>_<role>.subscriber.out` (:286) both match the doc, and `monotonic` appears exactly 3 times, all now accurate.
## 3. Peer-review trail (all registry-verified)
The chain is honest and complete: plan Rev.1 (`45bd8635`) → challenge (`87aa5b5a`, 3 findings all accepted) → plan Rev.2 (`baea3f7e`) → execution → Grok PASS (`30122522`, residuals non-blocking) → Claude NOT PASS (`50886e6f`, D-1/D-2 factual errors) → remediation → Claude PASS re-review (`f28629a3`, all gates green + 750 suite) → codex review (`2601270d`, 2 precision findings) → remediation (`09f2c915`, verified) → this review. Grok's residuals (README architecture narrative, `PRIVATE_SERVER.md` inbound link, B-16 stale line number, BOOTSTRAP "shell scripts" parent line, trailing newlines) remain — all non-blocking, all explicitly out-of-scope per the plan (§4).
## 4. Residual observations (non-blocking)
- Grok's five residuals stand as documented — each is a candidate for a follow-up docs pass, none affects correctness.
- `README tests/ (32 modules)` counts `test_*.py` + `conftest.py`; counting basis unstated but tolerable.
- The prior interrupted round's own report artifact (`ee242671`) was never published — this report supersedes it; the job registry shows only its `started` event, consistent with an interrupted run.
---
## 5. Verdict
Every Rev.2 acceptance gate passes under my own re-execution (root 8 + relocation, 49 doc-binding tests, 750 full-suite green, 0 broken links submodule-aware, installer both modes, ledger 31=31 with zero ✅ leakage and all remnant tokens preserved, README trees in parity, zero code/test/deploy drift). The two most recent precision findings (codex) are correctly remediated with every technical claim independently traced to code by me, and the multi-round review chain — including a genuine NOT PASS → fix → re-verify cycle — is recorded honestly. Documentation-only change with no functional risk.
[VERDICT: PASS]
+1 -1
View File
@@ -73,4 +73,4 @@ Read [MULTI_AGENT_RULES.md](.agents/MULTI_AGENT_RULES.md) (or [Korean version](.
**Normal vs. Orchestration Modes**
- **Normal Mode**: The orchestrator acts as Main Creator and may edit files directly.
- **Loop Active Mode (`/multi-agent-mux-loop`)**: Direct file mutation is intercepted by `.agents/hooks.json`. Do not seek workarounds when a tool call is denied — delegate the task immediately via `run_loop.sh`.
- **Loop Active Mode (`/multi-agent-mux-loop`)**: Direct file mutation is intercepted by `.agents/hooks.json`. The loop runtime is powered by the Python core (`lib_py.loop`, eager-import immutable runtime), and the delegation principle to `run_loop.sh` upon hook denial remains identical. Do not seek workarounds when a tool call is denied — delegate the task immediately via `run_loop.sh`.
+11 -5
View File
@@ -17,6 +17,10 @@
* `MULTI_AGENT_RULES.ko.md`: 에이전트 간의 역할 분담(PM, Worker, Reviewer) 및 이벤트 발행 규약 정의 (한국어)
* `skills/`: 멀티 에이전트 구동 및 비동기 잡 처리를 수행하는 셸 스크립트 모음
* `lib.sh`: 오케스트레이션의 핵심 셸 함수 및 가상환경(venv) 자동 연동 라이브러리
* `lib_py/`: 파이썬 코어 오케스트레이션 패키지
* `agents/`: 멀티 에이전트 CLI 수명 주기 어댑터
* `delegation/`: 코어 비동기 위임 엔진 및 CAS 상태 머신
* `loop/`: 자율 계획-실행-교차검증 루프 런타임
* `multi-agent-mux-create/`: 격리된 herdr 에이전트 세션을 시작하는 스크립트
* `multi-agent-mux-stop/`: 세션을 정상적으로 중지하고 상태를 업데이트하는 스크립트
* `multi-agent-mux-resume/`: 중지된 에이전트 세션을 이전 대화 상태 그대로 복원하는 스크립트
@@ -24,14 +28,16 @@
* `multi-agent-mux-monitor/`: herdr 상태와 레지스트리 상태를 동기화하는 모니터 스크립트
* `multi-agent-mux-delegate-job/`: 비동기 잡 분할 실행 모듈
* `requirements.txt`: Python 의존성 목록 (paho-mqtt, pyyaml)
* `scripts/`: 핵심 비즈니스 로직을 구동하는 Python 스크립트 디렉터리
* `registry.py`: 잡의 등록, 클레임 및 원자적 파일 락 제어 (CLI 지원)
* `job_subscriber.py`: 백그라운드 이벤트 구독기 및 오디팅 로그 생성기
* `publish_event.py`: 실행 상태 및 에러 트랩 시 이벤트 퍼블리셔
* `mqtt_common.py`: 공통 MQTT 브로커 연결 유틸리티
* `scripts/`: 레거시 호출 호환성을 위한 하위 호환 shim 스크립트 디렉터리
* `registry.py`: 잡의 등록, 클레임 및 원자적 파일 락 제어 shim
* `job_subscriber.py`: 백그라운드 이벤트 구독기 및 오디팅 로그 생성기 shim
* `publish_event.py`: 실행 상태 및 에러 트랩 시 이벤트 퍼블리셔 shim
* `mqtt_common.py`: 공통 MQTT 브로커 연결 유틸리티 shim
* `multi-agent-mux-loop/`: 자율적인 계획-실행-교차검증 반복 순환 루프 오케스트레이터
* `multi-agent-mux-orc-onboard/`: 오케스트레이터 세션 UUID 온보딩 및 서브에이전트 격리 헬퍼
* `AGENTS.md`: 에이전트 행동 지침 및 오케스트레이터 스코프 가드
* `MESSAGING.md`: 에이전트 간 주고받는 MQTT 메시지 와이어 스킴 가이드라인
* `VERSIONS.md`: 릴리스 노트 및 4-way 락스텝 버전 원장
---
+11 -5
View File
@@ -17,6 +17,10 @@ Before cloning this project into a new environment, you must first understand th
* `MULTI_AGENT_RULES.ko.md`: Definition of agent roles (PM, Worker, Reviewer) and event publication rules (Korean).
* `skills/`: A collection of shell scripts that execute multi-agent coordination and asynchronous job processing.
* `lib.sh`: The core orchestration shell functions and virtual environment (venv) auto-loading library.
* `lib_py/`: Python core orchestration package.
* `agents/`: Multi-agent CLI lifecycle adapters.
* `delegation/`: Core asynchronous delegation engine and CAS state machine.
* `loop/`: Autonomous planning-execution-review loop runtime.
* `multi-agent-mux-create/`: Script to launch isolated herdr agent sessions.
* `multi-agent-mux-stop/`: Script to gracefully stop agent sessions and update states.
* `multi-agent-mux-resume/`: Script to restore stopped agent sessions back to their previous conversation state.
@@ -24,14 +28,16 @@ Before cloning this project into a new environment, you must first understand th
* `multi-agent-mux-monitor/`: Monitor script to sync herdr states with the registry.
* `multi-agent-mux-delegate-job/`: Asynchronous job splitting and delegation module.
* `requirements.txt`: Python dependency list (`paho-mqtt`, `pyyaml`).
* `scripts/`: Python scripts running the core business logic.
* `registry.py`: Job registration, claiming, and atomic file lock control (CLI supported).
* `job_subscriber.py`: Background event subscriber and audit log generator.
* `publish_event.py`: Event publisher for runtime states and error traps.
* `mqtt_common.py`: Common utility for connecting to the MQTT broker.
* `scripts/`: Wire-compatibility shims for legacy callers.
* `registry.py`: Job registration, claiming, and atomic file lock control shim.
* `job_subscriber.py`: Background event subscriber and audit log generator shim.
* `publish_event.py`: Event publisher for runtime states and error traps shim.
* `mqtt_common.py`: Common utility for connecting to the MQTT broker shim.
* `multi-agent-mux-loop/`: Autonomous planning-execution-review loop orchestrator.
* `multi-agent-mux-orc-onboard/`: Orchestrator session UUID onboarding and sub-agent isolation helper.
* `AGENTS.md`: Behavioral guidelines and orchestrator scope guards.
* `MESSAGING.md`: Messaging scheme and wire protocol guidelines for MQTT communication between agents.
* `VERSIONS.md`: Release notes and 4-way lockstep version ledger.
---
+56 -81
View File
@@ -1,15 +1,15 @@
# 🛠️ Multi-Agent Mux 종합 개선 및 미해결 과제 백로그 (`IMPROVEMENTS.md`)
- **최종 갱신일**: 2026-08-24 (`nats-docker` 서브모듈 분리, B-20 2×K 그리드 TUI 레이아웃 엔진, J-1/J-2 레이아웃 환경변수/임계값 보강, B-21 `--agent` 표준화 및 레지스트리 agent_of_row 폴백 통합 완료)
- **최종 갱신일**: 2026-09-07 (IMPROVEMENTS.md 단일 원장화: §2/§3 완료 항목 §5 이관, 머지 잔재 병합 제거, v4.1.x~v4.4.0 완료 사항 반영)
- **통합 관리 대상**: 기존 `CODEBASE_REVIEW_REPORT.md` + `OPTIMIZATION.md` + `NATS_REPORT.md`
- **총 추적 미해결 과제**: **5건** (아키텍처 1건: `A-2`, 엣지케이스 및 가용성 3건: `B-16`, `B-17`, `B-18`, 오케스트레이션 1건: `O-5`)
- **완료된 과제**: **30건** (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, B-20, B-21, 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)
- **완료된 과제**: **31건** (B-21, B-20, B-19, B-14, B-15, O-6, A-4, B-9, B-13, B-10, B-5, C-6, P3-1-A4Phase2-C3b, P2-2-C3a-C4-LegacyCleanup, P2-1-DelegateJobSafe-TrapFix, O-4-OrcOnboard, O-2-P0-2, P0-1-B-7, Rev.2-b4a1d094-SessionIdPinning, B-4, O-3, A-1, A-3, C-2, A-5, B-1, B-3, C-1, O-1, Herdr-0.8.0-Compat-SanitizeHash, B-8)
---
## 📌 개요
본 문서는 Multi-Agent Mux (MAM) 프레임워크의 **코드베이스 아키텍처 결함, 런타임 엣지케이스, 레거시 잔재** 및 **`/multi-agent-mux-loop` 오케스트레이션 최적화 과제**를 단일 백로그로 통합 추적하기 위한 종합 관리 문서입니다.
본 문서는 Multi-Agent Mux (MAM) 프레임워크의 **코드베이스 아키텍처 결함, 런타임 엣지케이스, 레거시 잔재** 및 **`/multi-agent-mux-loop` 오케스트레이션 최적화 과제**를 단일 백로그로 통합 추적하기 위한 종합 관리 문서입니다. v4.1.0 이후 릴리스 단위 변경 이력은 `VERSIONS.md`를 정본으로 하며 본 백로그는 ID가 부여된 과제만 추적한다.
---
@@ -25,7 +25,43 @@
---
## 2. 🟠 엣지 케이스 및 런타임 버그 (Edge-case Bugs — 6건 / 완료 5건)
## 2. 🟠 엣지 케이스 및 런타임 버그 (Edge-case Bugs — 3건)
### **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단 구조)**:
1. import 시점: 명시적 `MAM_ENV_FILE` 경로 부재 시 `logger.error` 기록 및 `_env_file_missing = True` 플래그 설정 (상위 임의 탐색 금지, import 예외 방지).
2. 접속 시점: `make_client()` 시 `_env_file_missing`이면 `RuntimeError`로 fail-closed 거부. 최종 호스트가 `broker.hivemq.com`인 경우 눈에 띄는 보안 경고 출력.
### **B-18 (P2): `.mam.env`와 `.env` 공존 및 다중 워크스페이스 경계 탐색 정합성**
- **현상**: `.mam.env`와 `.env`의 우선순위 및 워크스페이스 경계(`.agents`, `.git`) 탐색 과정에서 다중 워크스페이스 환경에서의 일관성 유지.
- **조치 방향**: `MAM_REAL_ROOT` -> `WORKSPACE_ROOT` -> 상위 경계 디렉터리 -> `cwd` 순서의 first-hit-wins 탐색 규칙 적용.
---
## 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)이 확정되었습니다.
- **조치 방향**:
1. **Track 1 (스파이크 검증)**: 격리 환경에서 `nats-server -js`의 MQTT 3.1.1 호환성 실측 검증.
2. **Track 2 (보안/격리)**: 워크스페이스 지문 기반 토픽(`mam/<sha256[:12]>/jobs/...`) 및 무조건 `auth_token` 발급(G-11)을 적용하여 A-2 보안 결함 완전 종결.
3. **Track 3 (문서/설정)**: `MESSAGING.md`, `VERSIONS.md`, `.mam.env`에 `nats-server` 서빙 가이드 및 설정 동기화.
---
## 4. ⚪ 레거시 잔재 및 죽은 코드 (Legacy Remnants — 0건 — 전원 완료)
---
## 5. 🎉 완료된 과제 (Completed Tasks — 31건)
### **B-21 (✅ 완료 — `--agent` 플래그 표준화 및 `stop_session.sh`/`update_yaml_resumed.sh` 레지스트리 `agent_of_row` 폴백 통합)**
- **현상**:
@@ -63,38 +99,16 @@
### **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`) 갱신이 누락되던 결함.
- **원 진단 (`publish_event.py:195-199`)**: `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)**했습니다.
- **조치 결과 (완료 — 커밋 `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단 구조)**:
1. import 시점: 명시적 `MAM_ENV_FILE` 경로 부재 시 `logger.error` 기록 및 `_env_file_missing = True` 플래그 설정 (상위 임의 탐색 금지, import 예외 방지).
2. 접속 시점: `make_client()` 시 `_env_file_missing`이면 `RuntimeError`로 fail-closed 거부. 최종 호스트가 `broker.hivemq.com`인 경우 눈에 띄는 보안 경고 출력.
### **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)이 확정되었습니다.
- **조치 방향**:
1. **Track 1 (스파이크 검증)**: 격리 환경에서 `nats-server -js`의 MQTT 3.1.1 호환성 실측 검증.
2. **Track 2 (보안/격리)**: 워크스페이스 지문 기반 토픽(`mam/<sha256[:12]>/jobs/...`) 및 무조건 `auth_token` 발급(G-11)을 적용하여 A-2 보안 결함 완전 종결.
3. **Track 3 (문서/설정)**: `MESSAGING.md`, `VERSIONS.md`, `.mam.env`에 `nats-server` 서빙 가이드 및 설정 동기화.
- **원 진단 1 (`job_subscriber.py:172-251`)**: `job_subscriber.py:172-251`가 `queue.Empty` 시 네트워크 큐만 대기하며 로컬 디스크 상태를 확인하지 않아, 브로커 다운 시 120초 `idle_timeout` 동안 불필요하게 블로킹되었습니다 (`NATS_REPORT.md` §4.1 C1 챌린지 검증).
- **원 진단 2 (`multi-agent-mux-delegate-job:331-341`)**: `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)가 발생했습니다.
- **조치 결과 (완료 — 커밋 `c6b6c77`)**: `_check_disk_fallback()`을 도입하여 로컬 디스크(`load_job`/`read_logged_status`) 상의 터미널 상태를 감지하면 `source: disk-fallback` 합성 이벤트를 출력하고 3초 내 즉시 `rc=0`으로 정상 종료하도록 개선. 브로커 인프라 접속 실패는 전용 `rc=3` (`job_status="broker_unavailable"`)으로 분리 (G-5 ~ G-10 회귀 가드로 봉인 완료).
### **O-6 (✅ 완료 — P1): 원격 프로덕션 브로커 자산 정본화 및 `nats-docker` 서브모듈 분리**
- **내용**:
@@ -149,48 +163,6 @@
- **중단 기준**: 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` 디스크 폴백 부재 및 위임 경로 인프라 에러 오판정**
- **현상**:
1. `job_subscriber.py:172-251`가 `queue.Empty` 시 네트워크 큐만 대기하며 로컬 디스크 상태를 확인하지 않아, 브로커 다운 시 120초 `idle_timeout` 동안 불필요하게 블로킹됩니다 (`NATS_REPORT.md` §4.1 C1 챌린지 검증).
2. `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)**:
1. `job_subscriber.py` 대기 루프에 로컬 디스크(`load_job`/`read_logged_status`) 상태 폴백을 도입하여 디스크 완료 감지 시 `source: disk-fallback` 합성 이벤트를 출력하고 3초 내 `rc=0`으로 조기 정상 종료합니다.
2. 브로커 인프라 연결 실패에 전용 `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)이 확정되었습니다.
- **조치 방향**:
1. **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) 실측 검증.
2. **Track 2 (보안/격리)**: 워크스페이스 지문 기반 토픽(`mam/<sha256[:12]>/jobs/...`) 및 무조건 `auth_token` 발급(G-11)을 적용하여 A-2 보안 결함 완전 종결.
3. **Track 3 (문서/설정)**: `MESSAGING.md`, `VERSIONS.md`, `.mam.env`에 `nats-server` 서빙 가이드 및 설정 동기화.
---
## 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% 덮입니다.
@@ -206,6 +178,7 @@
- **결함 교정 (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 으로 방어력을 검증했습니다.
- v4.4.0(Issue #5 Phase 4)에서 freeze 스냅샷을 기본 경로에서 철거, `MAM_LOOP_FREEZE=1` 롤백 스위치만 잔존 (`docs/contracts/issue-5/phase4-freeze-removal.md`).
### **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단계로 단순화되었습니다.
@@ -244,12 +217,6 @@
- `.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에 안전하게 병합**시키는 기법을 구현했습니다.
@@ -270,11 +237,16 @@
- 멀티에이전트 자율 오케스트레이션 루프(`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)** — ✅ 완료
### **O-2 (P0-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)를 작성하여 입증했습니다.
- **Rev.1 (P0-2) 선행 조치**:
- [`.agents/skills/multi-agent-mux-loop/scripts/loop_lock.sh`](.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)를 작성하여 입증했습니다.
### **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`)을 구축했습니다.
@@ -333,6 +305,9 @@
- 전용 단위 테스트 `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]`** 를 달성했습니다.
### **B-8 (P1-2): agy 주입 시 `return 0` 우회 제거 및 제출 검증 루프 이관** — ✅ 완료
- agy 주입 시 `return 0` 우회 제거 및 제출 검증 루프 이관 (`tests/test_b8_send_keys_verification.py` 1/1 PASS).
---
## 6. 🧭 우선순위 실행 로드맵 (Prioritized Execution Roadmap)
+19 -3
View File
@@ -1,5 +1,7 @@
# Messaging System Technical Analysis & Architecture Report
Applies to: MAM v4.4.0
This report provides a comprehensive, deep-dive analysis of the messaging system implemented in the `multi-agent-mux-delegate-job` skill. It covers the MQTT broker architecture, event protocols, job lifecycles, codebase internals, cross-system integration, and a list of known limitations along with production recommendations.
---
@@ -235,7 +237,11 @@ stateDiagram-v2
## 4. Code Internals Analysis
The core implementation logic of the delegation system resides within the Python package `.agents/skills/lib_py/delegation/` (`mqtt_common.py`, `job_subscriber.py`, `engine.py`, `cli.py`, `registry.py`, `publish_event.py`, etc.). The entry scripts located in `.agents/skills/multi-agent-mux-delegate-job/scripts/*.py` (`registry.py`, `publish_event.py`, `job_subscriber.py`, `mqtt_common.py`) serve as wire-compatible shims that delegate directly into `lib_py/delegation/`.
### 4.1 `registry.py` & `lib.sh` (Locking & Atomicity)
* **Underlying Module**: `.agents/skills/lib_py/delegation/registry.py` (shim: `.agents/skills/multi-agent-mux-delegate-job/scripts/registry.py`) and `.agents/skills/lib.sh`.
Two concurrency control schemes co-exist in this workspace to coordinate state modification:
1. **`lib.sh::atomic_dump_yaml()`**: Used for workspace-wide herdr session inventory (`agent-sessions.yaml`).
@@ -249,6 +255,8 @@ Two concurrency control schemes co-exist in this workspace to coordinate state m
---
### 4.2 `publish_event.py` (Retries and Handshakes)
* **Underlying Module**: `.agents/skills/lib_py/delegation/publish_event.py` (shim: `.agents/skills/multi-agent-mux-delegate-job/scripts/publish_event.py`).
The publisher script enforces robust error handling and fail-safe local persistence:
* **Fresh Connection Pattern**: Instead of maintaining a persistent socket connection (which is susceptible to socket timeouts or channel leaks), `publish_event.py` opens a fresh socket, completes the authentication/TLS handshake, publishes a single QoS 1 event, waits for `PUBACK`, and closes the connection.
* **Guaranteed Disk Synchronization (B-14)**: Before attempting any network transmission over MQTT, `publish_event.py` records the event into the local registry (`append_event` and `update_job_status`). If the broker is unreachable or network publish fails, local audit logs and state machine files remain 100% accurate. The script returns exit code `2` at the very end to signal a transport failure without corrupting local state.
@@ -262,6 +270,8 @@ The publisher script enforces robust error handling and fail-safe local persiste
---
### 4.3 `job_subscriber.py` (Timers and Queue Semantics)
* **Underlying Module**: `.agents/skills/lib_py/delegation/job_subscriber.py` (shim: `.agents/skills/multi-agent-mux-delegate-job/scripts/job_subscriber.py`).
The subscriber acts as the central execution watchdog:
* **Queue Serialization**: Uses a thread-safe `queue.Queue` internally. The Paho MQTT callback thread adds messages to the queue, and the main thread processes them sequentially. This separates network I/O from state machine validation.
* **Local Disk Fallback Verification (B-15)**: On initial startup and upon any broker connection failure, `_check_disk_fallback()` immediately queries local job records (`.mam/jobs/<job_id>.json`) and audit logs (`status.json`). If the target job has already reached a terminal state locally, the subscriber completes immediately without waiting on a dead broker.
@@ -286,6 +296,8 @@ The subscriber acts as the central execution watchdog:
---
### 4.4 `mqtt_common.py` (Logging, Env Vars & Config Resolution)
* **Underlying Module**: `.agents/skills/lib_py/delegation/mqtt_common.py` (shim: `.agents/skills/multi-agent-mux-delegate-job/scripts/mqtt_common.py`).
* **Log Routing Isolation**: Configured via `setup_logging()`. The root logger is bound to `sys.stderr`. This preserves the standard output stream (`stdout`) exclusively for clean JSON-lines payloads, enabling downstream bash tools to pipeline event feeds cleanly (e.g., `job_subscriber.py ... | jq`).
* **Environment Variable Dictionary**:
The system parses and supports the following 10 configuration variables:
@@ -334,8 +346,12 @@ graph LR
```
### 5.1 Orchestration Wrappers (`multi-agent-mux-*`)
The system integrates a Compare-And-Swap (CAS) state transition engine implemented in `.agents/skills/lib_py/delegation/engine.py` (`MAM_ENGINE_CAS=1` by default). The engine stores a fresh opaque `dispatch_token` (`uuid4().hex`) when an attempt starts through `claim` or `redispatch`. Callers such as inferred completion supply `expected_dispatch_token`, which the engine compares under the registry lock before committing. This precondition is optional; ordinary publisher status updates do not supply it. Committed transitions are ordered separately by the monotonic `transition_seq` counter. The Python core implementation is guarded by the `MAM_DELEGATION_PY=1` feature flag (enabled by default), which provides a transparent fallback rollback switch to legacy shell/shim execution paths if set to `0`.
1. **`multi-agent-mux-delegate-job (submit)`**:
* Registers a job, spawns `job_subscriber.py` to capture standard output streams to `.mam/jobs/<job_id>.subscriber.out`, and sleeps for `1` second.
* Registers a job, spawns `job_subscriber.py` to capture standard output streams to `.mam/jobs/<job_id>.subscriber.out` (loop iterations use `.mam/jobs/<job_id>.iter_<n>_<role>.subscriber.out`).
* Attempts a subscriber readiness handshake by polling for `SUBSCRIBED ` every 0.2 seconds for up to 25 iterations. If readiness is not observed before the polling budget expires, it warns and proceeds with agent launch. Early subscriber exits with status 0 or 3 also permit continuation.
* Boots the agent pane in herdr:
```bash
herdr new-session -d -s "$sess" -c "$WORKDIR" \
@@ -371,8 +387,8 @@ graph LR
1. **[Implemented] Migrate to SQLite WAL Backend**:
The `agent-sessions.yaml` locking mechanism in `lib.sh` has been upgraded to use a SQLite database (`agent-sessions.db`) configured with Write-Ahead Logging (`PRAGMA journal_mode=WAL`). The YAML file is now only updated as a finalized archive when a session reaches a terminal state (`stopped`, `terminated`, `archived`), eliminating `flock` contention during active session updates.
**Architecture Decision Note**: This means `agent-sessions.yaml` is **no longer a real-time view** of currently `running` sessions. We have explicitly accepted the trade-off of giving up real-time text readability of running sessions in favor of robust concurrency and solving NFS flock limits. Tooling and status checks must now query the SQLite DB to observe live `running` states.
2. **Implement Signature-Based Payload Verification**:
Rather than sending a plaintext token, utilize HMAC signatures. The delegator and worker share a secret key; the worker publishes a signature of the payload (e.g. `HMAC-SHA256(secret_key, payload_bytes)`). The subscriber validates the signature, preventing token interception.
2. **[Implemented] Implement Signature-Based Payload Verification**:
HMAC payload verification has been implemented using SHA-256 signatures (`auth_token` generation and verification). The delegator and worker share a secret key; the publisher generates an HMAC-SHA256 signature over the payload bytes and timestamp, which is attached as `data.hmac_sig` on the wire and verified by the subscriber (see [§2.4 Integrity and Authentication Verification (HMAC-SHA256 Signatures)](#24-integrity-and-authentication-verification-hmac-sha256-signatures)).
3. **Enforce Mandatory NATS Broker-Side Authentication, JetStream and ACLs**:
Standardize on private `nats-server` with JetStream and account-level ACL isolation (`nats-docker/docker/nats.conf`). For public WAN exposures, terminate TLS v1.3 (`MQTT_TLS=true`) over port `8883`.
4. **Build Auto-Reconnecting Subscriber Loops**:
+19 -4
View File
@@ -27,12 +27,12 @@ Herdr와 MQTT 브로커를 기반으로 구축된 고신뢰성 **다중 에이
* **`multi-agent-mux-resume`**: 디스크 또는 캐시에서 특정 워크스페이스의 세션 UUID를 조회하여 기존 대화 상태(`claude -r <uuid>`, `agy --conversation <uuid>`, `hermes --resume <uuid>`, `grok --resume <uuid>`, `opencode --session <uuid>`, `codex resume <uuid>`) 그대로 세션을 복구하고 재개합니다.
* **`multi-agent-mux-status`**: 활성화된 모든 세션의 실시간 작동 상태를 쿼리하여 PID 정합성, 실행 명령 포맷, herdr 실제 상태와 데이터베이스 간의 동기화 드리프트를 감지합니다.
* **`multi-agent-mux-monitor`**: 백그라운드 Reconcile 프로세스로 실행되어, 실시간 herdr 세션 변화를 모니터링하고 `.mam/agent-sessions.yaml` 메타데이터 파일에 상태를 동기화합니다.
* **`multi-agent-mux-delegate-job`**: 태스크를 비동기식 독립 잡으로 위임 및 관리하는 핵심 모듈입니다:
* **`multi-agent-mux-delegate-job`**: 태스크를 비동기식 독립 잡으로 위임 및 관리하는 핵심 모듈입니다 (본체 구현은 `.agents/skills/lib_py/delegation/`에 위치하며, `scripts/*.py`는 하위 호환 shim):
* `registry.py`: 파일 락(`fcntl`)을 활용해 경쟁 조건 없이 잡을 원자적으로 등록 및 점유(claim)합니다.
* `job_subscriber.py`: MQTT 백플레인 채널을 구독하여 실시간 상태 이벤트를 수집하고 이를 감사 로그(audit trail)에 기록합니다.
* `publish_event.py`: 실행 상태 전환 및 세부 에러 내용을 워크스페이스 스크립트에서 백플레인으로 발행합니다.
* `mqtt_common.py`: 브로커 접속 규칙, 크레덴셜 인증 및 HMAC 서명 기능을 공통 관리합니다.
* **`multi-agent-mux-loop`**: Planner, Creator, Reviewer 3자 간의 자율적인 계획-실행-교차검증 반복 순환 루프를 구동합니다.
* **`multi-agent-mux-loop`**: Planner, Creator, Reviewer 3자 간의 자율적인 계획-실행-교차검증 반복 순환 루프를 구동합니다 (Python 루프 런타임 `lib_py.loop`, eager-import 불변 런타임, strict verdict parser 기반).
* **`multi-agent-mux-orc-onboard`**: 오케스트레이터 UUID를 레지스트리에 격리 등록하여 서브 에이전트 자동 탐색 오염을 방지합니다.
---
@@ -146,6 +146,10 @@ sequenceDiagram
│ ├── MULTI_AGENT_RULES.ko.md # 에이전트 역할 행동 강령 (한국어 백업)
│ └── skills/ # 코어 오케스트레이션 셸 스크립트 및 라이브러리
│ ├── lib.sh # 공통 오케스트레이션 셸 함수 라이브러리
│ ├── lib_py/ # 파이썬 코어 오케스트레이션 엔진
│ │ ├── agents/ # 멀티 에이전트 CLI 수명 주기 어댑터
│ │ ├── delegation/ # 비동기 잡 위임 및 CAS 상태 전이 엔진
│ │ └── loop/ # 자율 계획-실행-교차검증 루프 런타임
│ ├── multi-agent-mux-create/
│ ├── multi-agent-mux-stop/
│ ├── multi-agent-mux-resume/
@@ -153,7 +157,7 @@ sequenceDiagram
│ ├── multi-agent-mux-monitor/
│ ├── multi-agent-mux-delegate-job/
│ │ ├── requirements.txt # 파이썬 의존성 패키지 선언
│ │ └── scripts/ # 파이썬 기반 백플레인 구현체
│ │ └── scripts/ # 하위 호환 shim 스크립트 (Python)
│ ├── multi-agent-mux-loop/
│ └── multi-agent-mux-orc-onboard/
├── .mam/ # Multi-Agent Mux 메타데이터 (git-ignored)
@@ -167,10 +171,21 @@ sequenceDiagram
│ ├── install.sh # 원격/네트워크 인스톨러 스크립트
│ ├── update.sh # 업데이트 헬퍼 스크립트
│ └── remove.sh # 삭제/언인스톨 헬퍼 스크립트
├── docs/ # 기술 규격서, 가이드 및 아키텍처 계약 문서
│ ├── contracts/ # 이슈/백플레인 계약 및 마이그레이션 로드맵
│ ├── MAM_WEB_PTY_BRIDGE_PLAN.md # Web PTY 터미널 브리지 설계 계획서
│ ├── NEW_AGENT_INTEGRATION_GUIDE.md # 신규 AI 코딩 에이전트 연동 가이드
│ └── OPENCODE_OLLAMA_GUIDE.md # OpenCode 인터프리터 + Ollama 연동 가이드
├── nats-docker/ # 사설 NATS 브로커 배포 서브모듈
├── tests/ # 종합 회귀 테스트 스위트 (32개 모듈)
├── AGENTS.md # 에이전트 행동 지침 및 오케스트레이터 스코프 가드
├── BOOTSTRAP.ko.md # 프로젝트 초기 설치 가이드 (한국어 백업)
├── BOOTSTRAP.md # 프로젝트 초기 설치 및 검증 상세 가이드
├── IMPROVEMENTS.md # 이슈 백로그 및 완료된 아키텍처 과제 추적 원장
├── MESSAGING.md # MQTT 메시징 프로토콜 와이어 규격서
└── README.md # 프로젝트 대표 소개 파일
├── README.ko.md # 프로젝트 대표 소개 파일 (한국어)
├── README.md # 프로젝트 대표 소개 파일 (영문 원본)
└── VERSIONS.md # 릴리스 노트 및 4-way 락스텝 버전 원장
```
---
+21 -5
View File
@@ -45,12 +45,12 @@ All orchestration functionalities are structured under the `.agents/skills/` dir
* **`multi-agent-mux-resume`**: Restores stopped sessions by resolving workspace UUIDs from disk or cache, and invokes the underlying agent using session-resume parameters (e.g., `claude -r <uuid>`, `agy --conversation <uuid>`, `hermes --resume <uuid>`, `grok --resume <uuid>`, `opencode --session <uuid>`, or `codex resume <uuid>`).
* **`multi-agent-mux-status`**: Queries the running states of all active sessions, detecting PID mismatches, command signatures, and drifts between actual herdr instances and the registry database.
* **`multi-agent-mux-monitor`**: A long-running reconcile worker that dynamically monitors herdr sessions and synchronizes states to `.mam/agent-sessions.yaml`.
* **`multi-agent-mux-delegate-job`**: The core asynchronous task distribution module containing:
* **`multi-agent-mux-delegate-job`**: The core asynchronous task distribution module (core implementation in `.agents/skills/lib_py/delegation/`; `scripts/*.py` serves as compatibility shims):
* `registry.py`: Atomically registers and claims jobs using file advisory locks (`fcntl`).
* `job_subscriber.py`: Connects to the MQTT backplane, captures live events, and appends them to audit trails.
* `publish_event.py`: Emits execution status transitions and error details from workspace scripts.
* `mqtt_common.py`: Manages connection policies, authentication, and HMAC signing.
* **`multi-agent-mux-loop`**: Autonomous planning-execution-review orchestration loop across Planner, Creator, and Reviewers until unanimous consensus.
* **`multi-agent-mux-loop`**: Autonomous planning-execution-review orchestration loop across Planner, Creator, and Reviewers until unanimous consensus (driven by Python loop runtime in `lib_py.loop`, eager-import immutable runtime, strict verdict parser).
* **`multi-agent-mux-orc-onboard`**: Helper to register and isolate orchestrator session UUIDs to prevent sub-agent discovery capture.
---
@@ -164,6 +164,10 @@ To ensure communication integrity across public MQTT brokers, the backplane inte
│ ├── MULTI_AGENT_RULES.ko.md # Agent roles, snapshottings, and execution charter (Korean)
│ └── skills/ # Core orchestration shell wrappers & libraries
│ ├── lib.sh # Shared orchestration library
│ ├── lib_py/ # Python core orchestration engine
│ │ ├── agents/ # Multi-agent CLI lifecycle adapters
│ │ ├── delegation/ # Asynchronous delegation & CAS state engine
│ │ └── loop/ # Autonomous planning-execution-review loop runtime
│ ├── multi-agent-mux-create/
│ ├── multi-agent-mux-stop/
│ ├── multi-agent-mux-resume/
@@ -171,7 +175,7 @@ To ensure communication integrity across public MQTT brokers, the backplane inte
│ ├── multi-agent-mux-monitor/
│ ├── multi-agent-mux-delegate-job/
│ │ ├── requirements.txt # Python dependency declaration
│ │ └── scripts/ # Core backplane implementation (Python)
│ │ └── scripts/ # Wire-compatibility shims (Python)
│ ├── multi-agent-mux-loop/
│ └── multi-agent-mux-orc-onboard/
├── .mam/ # Multi-Agent Mux metadata (git-ignored)
@@ -185,9 +189,21 @@ To ensure communication integrity across public MQTT brokers, the backplane inte
│ ├── install.sh # Remote/Network installer script
│ ├── update.sh # Updater script
│ └── remove.sh # Uninstaller script
├── docs/ # Specifications, guides, and architectural contracts
│ ├── contracts/ # Issue/backplane contracts and migration roadmaps
│ ├── MAM_WEB_PTY_BRIDGE_PLAN.md # Web PTY terminal bridge design plan
│ ├── NEW_AGENT_INTEGRATION_GUIDE.md # Guide for integrating new AI coding agents
│ └── OPENCODE_OLLAMA_GUIDE.md # OpenCode interpreter + Ollama integration guide
├── nats-docker/ # Private NATS broker deployment submodule
├── tests/ # Comprehensive test suite (32 modules)
├── AGENTS.md # Behavioral guidelines and orchestrator scope guards
├── BOOTSTRAP.ko.md # Installation and verification guide (Korean)
├── BOOTSTRAP.md # Detailed installation and verification guide
├── MESSAGING.md # MQTT wire protocol specification
└── README.md # Project introduction and overview (this file)
├── IMPROVEMENTS.md # Backlog tracking issues and completed architectural tasks
├── MESSAGING.md # MQTT wire protocol specification and internals
├── README.ko.md # Project introduction and overview (Korean)
├── README.md # Project introduction and overview (this file)
└── VERSIONS.md # Release notes and 4-way lockstep version ledger
```
---
@@ -1,10 +1,11 @@
# 🚀 MAM 메시징 백플레인 전환 실행 로드맵 (`implementation_plan.md`)
- **문서 버전**: v1.2.0
- **문서 버전**: v1.3.0
- **작성/관리 주체**: Multi-Agent Orchestration Team (`claude`, `agy`, `hermes`, `grok`)
- **이관 사유/일자**: 2026-09-07 (루트 마크다운 정리 작업으로 docs/contracts/nats-backplane/ 이관)
- **기준 커밋**: `916185c` (306/306 baseline tests passing)
- **문서 목적**: MAM의 메시징 인프라를 공개 HiveMQ 브로커에서 `nats-server` 전용 사설 브로커로 무중단 전환하기 위한 5개 트랙(Track 0~3, Track 1R)과 6단계 마일스톤(M0~M4, M2b)의 구체적 실행 지침 및 진행 상황 추적.
- **연계 문서**: [`NATS_REPORT.md`](nats-docker/NATS_REPORT.md), [`PRIVATE_SERVER.md`](nats-docker/PRIVATE_SERVER.md), [`IMPROVEMENTS.md`](IMPROVEMENTS.md)
- **연계 문서**: [`NATS_REPORT.md`](../../../nats-docker/NATS_REPORT.md), [`PRIVATE_SERVER.md`](../../../nats-docker/PRIVATE_SERVER.md), [`IMPROVEMENTS.md`](../../../IMPROVEMENTS.md)
---
@@ -143,12 +144,12 @@ M0 (문서 정합성) ──> M1 (Track 0 내결함성) ──> M2a (로컬 스
| 대상 파일 | 갱신 내용 |
|---|---|
| [`MESSAGING.md`](MESSAGING.md) | 브로커 표준을 `nats-server`로 갱신, F-1/C1 해소 기록, F-5 영속 세션 서술 정정, 10개 환경변수 및 해석 계층 문서화 |
| [`IMPROVEMENTS.md`](IMPROVEMENTS.md) | B-14/B-15 완료 상태 반영, O-6 신설, B-17/B-18 신설 등록 |
| [`VERSIONS.md`](VERSIONS.md) | `v2.0.0` 릴리스 노트에 메시징 백플레인 고도화 및 내결함성 패치 기록 |
| [`PRIVATE_SERVER.md`](nats-docker/PRIVATE_SERVER.md) | 스파이크 결과 반영 및 최종 가이드 확정 |
| [`deploy/install.sh`](deploy/install.sh) | `requirements.txt` 확인 (paho 유지) 및 개인 브로커 안내 추가 |
| [`.mam.env`](.mam.env) | `MQTT_BROKER`, `MQTT_PORT`, `MQTT_TLS` 기본 템플릿 확정 |
| [`MESSAGING.md`](../../../MESSAGING.md) | 브로커 표준을 `nats-server`로 갱신, F-1/C1 해소 기록, F-5 영속 세션 서술 정정, 10개 환경변수 및 해석 계층 문서화 |
| [`IMPROVEMENTS.md`](../../../IMPROVEMENTS.md) | B-14/B-15 완료 상태 반영, O-6 신설, B-17/B-18 신설 등록 |
| [`VERSIONS.md`](../../../VERSIONS.md) | `v2.0.0` 릴리스 노트에 메시징 백플레인 고도화 및 내결함성 패치 기록 |
| [`PRIVATE_SERVER.md`](../../../nats-docker/PRIVATE_SERVER.md) | 스파이크 결과 반영 및 최종 가이드 확정 |
| [`deploy/install.sh`](../../../deploy/install.sh) | `requirements.txt` 확인 (paho 유지) 및 개인 브로커 안내 추가 |
| [`.mam.env (템플릿: .mam.env.example)`](../../../.mam.env.example) | `MQTT_BROKER`, `MQTT_PORT`, `MQTT_TLS` 기본 템플릿 확정 |
---