From f98b9582c7090c061ecda46257a550235beba380 Mon Sep 17 00:00:00 2001 From: Godopu Date: Tue, 8 Sep 2026 08:02:37 +0900 Subject: [PATCH] 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 --- .../plan-baea3f7e.md | 138 ++++++++++++++++++ .../report-f28629a3.md | 52 +++++++ .../report-fd874949.md | 28 ++++ .../report-30122522.md | 35 +++++ .../reviewer-opencode-01/report-b049e495.md | 50 +++++++ AGENTS.md | 2 +- BOOTSTRAP.ko.md | 16 +- BOOTSTRAP.md | 16 +- IMPROVEMENTS.md | 137 +++++++---------- MESSAGING.md | 22 ++- README.ko.md | 23 ++- README.md | 26 +++- .../nats-backplane/implementation_plan.md | 17 ++- 13 files changed, 450 insertions(+), 112 deletions(-) create mode 100644 .agents/reports/planner-reviewer-claude-01/plan-baea3f7e.md create mode 100644 .agents/reports/planner-reviewer-claude-01/report-f28629a3.md create mode 100644 .agents/reports/planner-reviewer-codex-01/report-fd874949.md create mode 100644 .agents/reports/reviewer-creator-grok-01/report-30122522.md create mode 100644 .agents/reports/reviewer-opencode-01/report-b049e495.md rename implementation_plan.md => docs/contracts/nats-backplane/implementation_plan.md (91%) diff --git a/.agents/reports/planner-reviewer-claude-01/plan-baea3f7e.md b/.agents/reports/planner-reviewer-claude-01/plan-baea3f7e.md new file mode 100644 index 0000000..2147ef2 --- /dev/null +++ b/.agents/reports/planner-reviewer-claude-01/plan-baea3f7e.md @@ -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 `๊ฐ€ ์ฐธ์ธ ๊ฒฝ๋กœ๋Š” ๊ฒ€์‚ฌ์—์„œ ์ œ์™ธ**ํ•˜์ง€ ์•Š๊ณ  **์˜ค๋ฅ˜๋กœ ์ฒ˜๋ฆฌ**ํ•œ๋‹ค(์ถ”์ ๋˜์ง€ ์•Š๋Š” ํŒŒ์ผ๋กœ์˜ ๋งํฌ๋Š” ๋ฌธ์„œ ๊ฒฐํ•จ์ด๋ฏ€๋กœ 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. diff --git a/.agents/reports/planner-reviewer-claude-01/report-f28629a3.md b/.agents/reports/planner-reviewer-claude-01/report-f28629a3.md new file mode 100644 index 0000000..7f703c2 --- /dev/null +++ b/.agents/reports/planner-reviewer-claude-01/report-f28629a3.md @@ -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 | ๋กœ๊ทธ ๊ฒฝ๋กœ `..subscriber.out` โ†’ `.subscriber.out (loop iterations use .iter__.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 ๊ฒฝ๋กœ `.subscriber.out` | `multi-agent-mux-delegate-job:165` | โœ… | +| ๋ฃจํ”„ ๊ฒฝ๋กœ `.iter__.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] diff --git a/.agents/reports/planner-reviewer-codex-01/report-fd874949.md b/.agents/reports/planner-reviewer-codex-01/report-fd874949.md new file mode 100644 index 0000000..f63c4ed --- /dev/null +++ b/.agents/reports/planner-reviewer-codex-01/report-fd874949.md @@ -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] diff --git a/.agents/reports/reviewer-creator-grok-01/report-30122522.md b/.agents/reports/reviewer-creator-grok-01/report-30122522.md new file mode 100644 index 0000000..c676d10 --- /dev/null +++ b/.agents/reports/reviewer-creator-grok-01/report-30122522.md @@ -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] diff --git a/.agents/reports/reviewer-opencode-01/report-b049e495.md b/.agents/reports/reviewer-opencode-01/report-b049e495.md new file mode 100644 index 0000000..ce71bf5 --- /dev/null +++ b/.agents/reports/reviewer-opencode-01/report-b049e495.md @@ -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; `..subscriber.out` path error) remain correctly in place โ€” the direct path `.subscriber.out` (:165) and loop path `iter__.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] \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md index 2f7881f..f1a421d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -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`. \ No newline at end of file +- **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`. \ No newline at end of file diff --git a/BOOTSTRAP.ko.md b/BOOTSTRAP.ko.md index 7ee0193..0c26893 100644 --- a/BOOTSTRAP.ko.md +++ b/BOOTSTRAP.ko.md @@ -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 ๋ฝ์Šคํ… ๋ฒ„์ „ ์›์žฅ --- diff --git a/BOOTSTRAP.md b/BOOTSTRAP.md index c761c07..e905c82 100644 --- a/BOOTSTRAP.md +++ b/BOOTSTRAP.md @@ -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. --- diff --git a/IMPROVEMENTS.md b/IMPROVEMENTS.md index 629cb1a..f2b97bd 100644 --- a/IMPROVEMENTS.md +++ b/IMPROVEMENTS.md @@ -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//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//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//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) diff --git a/MESSAGING.md b/MESSAGING.md index 80ea109..0a13dca 100644 --- a/MESSAGING.md +++ b/MESSAGING.md @@ -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/.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/.subscriber.out`, and sleeps for `1` second. + * Registers a job, spawns `job_subscriber.py` to capture standard output streams to `.mam/jobs/.subscriber.out` (loop iterations use `.mam/jobs/.iter__.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**: diff --git a/README.ko.md b/README.ko.md index b165ae5..e670917 100644 --- a/README.ko.md +++ b/README.ko.md @@ -27,12 +27,12 @@ Herdr์™€ MQTT ๋ธŒ๋กœ์ปค๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ตฌ์ถ•๋œ ๊ณ ์‹ ๋ขฐ์„ฑ **๋‹ค์ค‘ ์—์ด * **`multi-agent-mux-resume`**: ๋””์Šคํฌ ๋˜๋Š” ์บ์‹œ์—์„œ ํŠน์ • ์›Œํฌ์ŠคํŽ˜์ด์Šค์˜ ์„ธ์…˜ UUID๋ฅผ ์กฐํšŒํ•˜์—ฌ ๊ธฐ์กด ๋Œ€ํ™” ์ƒํƒœ(`claude -r `, `agy --conversation `, `hermes --resume `, `grok --resume `, `opencode --session `, `codex resume `) ๊ทธ๋Œ€๋กœ ์„ธ์…˜์„ ๋ณต๊ตฌํ•˜๊ณ  ์žฌ๊ฐœํ•ฉ๋‹ˆ๋‹ค. * **`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 ๋ฝ์Šคํ… ๋ฒ„์ „ ์›์žฅ ``` --- diff --git a/README.md b/README.md index 6990853..6a03347 100644 --- a/README.md +++ b/README.md @@ -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 `, `agy --conversation `, `hermes --resume `, `grok --resume `, `opencode --session `, or `codex resume `). * **`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 ``` --- diff --git a/implementation_plan.md b/docs/contracts/nats-backplane/implementation_plan.md similarity index 91% rename from implementation_plan.md rename to docs/contracts/nats-backplane/implementation_plan.md index a7b5656..76e13de 100644 --- a/implementation_plan.md +++ b/docs/contracts/nats-backplane/implementation_plan.md @@ -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` ๊ธฐ๋ณธ ํ…œํ”Œ๋ฆฟ ํ™•์ • | ---