# ๐Ÿ“‘ Issue #5 Task Checklist & Verification Evidence - **Document Version**: Rev.7 (Phase 2a ์‹คํ–‰ ์™„๋ฃŒ โ€” P2A-01~P2A-04 ์ฆ๊ฑฐ ๊ธฐ๋ก) - **Issue**: [Gitea Issue #5](https://git.godopu.com/tmpl/multi-agent-mux/issues/5) - **Status**: Phase 0 Complete / **Phase 1 Complete (v4.3.0)** / **Phase 2a Complete (shadow-only)** / **Phase 2b Complete (default-off)** / Phase 3โ€“4 Staged --- ## Phase 0: ์‚ฌ์ „ ๊ณ„์•ฝ ๊ธฐ์ค€์„  ๋ฐ Fixture ์ˆ˜์ง‘ (์ด๋ฒˆ ์‹คํ–‰ ๋ฒ”์œ„) - [x] **P0-01** ๊ธฐ์ค€ commit, dirty diff, Herdr/Python ๋ฒ„์ „, pytest collection ์ˆ˜ ๊ธฐ๋ก. - *์ฆ๊ฑฐ*: Commit `47640e2`, Herdr `0.8.2`, Python `3.9.6`, Pytest `469 tests collected initially` โž” `510 tests collected with Phase 0 suite` (+41 contract & mutation tests). - [x] **P0-02** `docs/contracts/issue-5/baseline.md` ์ž‘์„ฑ: ๊ณต๊ฐœ CLI/default/invalid input/stdout-stderr/exit/interpreter/path/signal ๊ณ„์•ฝ๊ณผ ์†Œ์Šคยท๊ธฐ์กด ํ…Œ์ŠคํŠธ ๋งคํ•‘. - *์ฆ๊ฑฐ*: `docs/contracts/issue-5/baseline.md` ยง2 (`--all-reviewer` ์šฐ์„ ์ˆœ์œ„ ๋ฐ L192โ€“196 ์†Œ์Šค ๋งคํ•‘ ๋ฐ˜์˜). - [x] **P0-03** event schema/HMAC/seq/retain/audit/๋””์Šคํฌ fallback ๋ฐ publisher ์‹คํŒจ ํ›„ ๋กœ์ปฌ commit ๋™์ž‘ ๊ธฐ๋ก. - *์ฆ๊ฑฐ*: `docs/contracts/issue-5/baseline.md` ยง3 (๊ฐ์‚ฌ ๋กœ๊ทธ ๊ฒฝ๋กœ `.mam/delegate_job_logs//` ์ •ํ™•ํžˆ ๋ฐ˜์˜). - [x] **P0-04** event์™€ registry status ๋ถ„๋ฆฌ; permission clearanceยทcancelled subscriber ์ฐจ์ดยทpick_pending ๋“ฑ writer inventory/gap ๊ธฐ๋ก. - *์ฆ๊ฑฐ*: `docs/contracts/issue-5/baseline.md` ยง3, `job_subscriber.py:46, 80` vs `publish_event.py:49` ๊ฐ„๊ทน ๋ช…์‹œ. - [x] **P0-05** report strictness/promotion/cleanup ๋ฐ job/session/loop lock ํš๋“ยทํ•ด์ œ/ownership ๊ณ„์•ฝ ๊ธฐ๋ก. - *์ฆ๊ฑฐ*: `docs/contracts/issue-5/baseline.md` ยง4, ยง5. - [x] **P0-06** `docs/contracts/issue-5/state-transitions.md` ์ž‘์„ฑ: 4์ค‘ ๊ท€์†, dispatch anchor, target CAS ํ‘œ์™€ duplicate/conflict/deadline ์ •์ฑ…. - *์ฆ๊ฑฐ*: `docs/contracts/issue-5/state-transitions.md` ยง2, ยง3. - [x] **P0-07** writing/stable_candidate/finalized ๋ฐ manifest/hash/๋ถ€์ˆ˜ํšจ๊ณผ ํ™•์ • ๊ณ„์•ฝ ๊ธฐ๋ก; debounce๋งŒ์œผ๋กœ completed ๊ธˆ์ง€. - *์ฆ๊ฑฐ*: `docs/contracts/issue-5/state-transitions.md` ยง4. - [x] **P0-08** Herdr native wait version/help/spec ๋ฐ ๋‹จ์ผ ๊ฒฐ๊ณผ capture ์ˆ˜์ง‘. timeout/unknown target/transport failure์™€ unknown ์ƒํƒœ๋ฅผ ๋ถ„๋ฆฌํ•˜๊ณ  ์™ธ๋ถ€ collector์˜ before/after ์ฐธ์กฐ๋ฅผ ๊ฒ€์ฆ. - *์ฆ๊ฑฐ*: `tests/fixtures/issue_5/herdr/wait-contract.json`, `docs/contracts/issue-5/herdr-runtime.md` ยง1 (timeout stderr ์ฑ„๋„ ๋ฐ˜์˜). - [x] **P0-09** claude native ์ƒํƒœ/call-outcome ํ–‰๋ ฌยท์‹ค์ธก provenanceยท๋ฏธ๊ด€์ธก gap ๊ธฐ๋ก. - *์ฆ๊ฑฐ*: `tests/fixtures/issue_5/herdr/claude/idle.json`, `herdr/manifest.json`. - [x] **P0-10** agy native ์ƒํƒœ/call-outcome ํ–‰๋ ฌยท์‹ค์ธก provenanceยท๋ฏธ๊ด€์ธก gap ๊ธฐ๋ก. - *์ฆ๊ฑฐ*: `tests/fixtures/issue_5/herdr/agy/working.json`, `tests/fixtures/issue_5/herdr/agy/wait_timeout.json`, `herdr/manifest.json`. - [x] **P0-11** hermes native ์ƒํƒœ/call-outcome ํ–‰๋ ฌยท์‹ค์ธก provenanceยท๋ฏธ๊ด€์ธก gap ๊ธฐ๋ก. - *์ฆ๊ฑฐ*: `herdr/manifest.json` (๋ฏธ๊ฐ€๋™ ์„ธ์…˜ gap์œผ๋กœ ์ •์งํ•˜๊ฒŒ ๊ธฐ๋ก). - [x] **P0-12** grok native ์ƒํƒœ/call-outcome ํ–‰๋ ฌยท์‹ค์ธก provenanceยท๋ฏธ๊ด€์ธก gap ๊ธฐ๋ก. - *์ฆ๊ฑฐ*: `tests/fixtures/issue_5/herdr/grok/idle.json`, `herdr/manifest.json`. - [x] **P0-13** opencode native ์ƒํƒœ/call-outcome ํ–‰๋ ฌยท์‹ค์ธก provenanceยท๋ฏธ๊ด€์ธก gap ๊ธฐ๋ก. - *์ฆ๊ฑฐ*: `herdr/manifest.json` (๋ฏธ๊ฐ€๋™ ์„ธ์…˜ gap์œผ๋กœ ์ •์งํ•˜๊ฒŒ ๊ธฐ๋ก). - [x] **P0-14** codex native ์ƒํƒœ/call-outcome ํ–‰๋ ฌยท์‹ค์ธก provenanceยท๋ฏธ๊ด€์ธก gap ๊ธฐ๋ก. - *์ฆ๊ฑฐ*: `tests/fixtures/issue_5/herdr/codex/done.json`, `herdr/manifest.json`. - [x] **P0-15** `herdr/manifest.json`๊ณผ `watcher/manifest.json` ๋ถ„๋ฆฌ. native observed ์บก์ฒ˜๋งŒ ์ €์žฅ; watcher timeline source๋ณ„ observed/simulated, ์ „์ฒด mixed ์—ฌ๋ถ€, identity association๊ณผ redaction ๊ฒ€์ฆ. - *์ฆ๊ฑฐ*: `tests/fixtures/issue_5/herdr/manifest.json`, `tests/fixtures/issue_5/watcher/manifest.json`. - [x] **P0-16** ๋‘ ๊ณ„์ธต schema/reference/coverage ํ…Œ์ŠคํŠธ ์ถ”๊ฐ€: native payload์— job/attempt/report phase ์ฃผ์ž… ๊ฑฐ๋ถ€, ์˜ค๋ฅ˜์™€ ์ƒํƒœ ๋ถ„๋ฆฌ, simulated๋ฅผ observed๋กœ ํ‘œ๊ธฐ ๊ฑฐ๋ถ€. ์šด์˜ session ์“ฐ๊ธฐ ๊ธˆ์ง€. - *์ฆ๊ฑฐ*: `tests/test_issue5_phase0_contracts.py`. - *Rev.5 ๋ณด๊ฐ• (Codex [P1] ๋Œ€์‘)*: `source_kind` ๋ช…์‹œ์  ๋ถ„๊ธฐ(`SUPPORTED_SOURCE_KINDS`), ๊ด€์ธก ์ฆ๊ฑฐ ์Šคํ‚ค๋งˆ ๋ฏธ๊ตฌํ˜„ kind(event/filesystem/harness)์˜ `observed` ํ‘œ๊ธฐ fail-closed ๊ฑฐ๋ถ€, Herdr ํ•ญ๋ชฉ์˜ ํ•„์ˆ˜ ํ•„๋“œยท์ „ ํ•„๋“œ ๋Œ€์‘ยท์„ธ์…˜ UUID/pane/backend ์ •์ฒด์„ฑ ๋Œ€์‘, `capture_ref` ์ฆ๊ฑฐ ๋ฃจํŠธ ๊ฒฉ๋ฆฌ, 1์บก์ฒ˜=1๊ด€์ธก, ๋งค๋‹ˆํŽ˜์ŠคํŠธโ†”ํŒŒ์ผ ์ •ํ•ฉ์„ฑ ๊ฒ€์ฆ. ๊ณ„์•ฝ ๋ช…์„ธ๋Š” `herdr-runtime.md` ยง3-1. - [x] **P0-16a** watcher ๋ณตํ•ฉ ์‹œ๋‚˜๋ฆฌ์˜ค 7์ข… ์ž‘์„ฑ: initial idle, tool active, report pause, finalized candidate, blocked, disconnect, generation restart. source๋ณ„ ์ฆ๊ฑฐ/๊ฐ€์ƒ ์‹œ๊ณ„/expected policy๋ฅผ ๊ตฌ๋ถ„. - *์ฆ๊ฑฐ*: `tests/fixtures/issue_5/watcher/*.json` (7๊ฐœ ์‹œ๋‚˜๋ฆฌ์˜ค ์™„๋ฃŒ). - [x] **P0-16b** `herdr-runtime.md`์— native APIยท๋‹จ์ผ waitยท์™ธ๋ถ€ collectorยทfile/event/dispatch source ๊ฒฝ๊ณ„๋ฅผ ๋ช…์‹œ. - *์ฆ๊ฑฐ*: `docs/contracts/issue-5/herdr-runtime.md`. - [x] **P0-17** Phase 1โ€“4 `implementation_plan.md`/`task.md` ์ž‘์„ฑ, live-helper version/๊ณตํ†ต CAS/notification ๋ณต๊ตฌ ๊ฒฐ์ • ๊ธฐ๋ก. - *์ฆ๊ฑฐ*: `docs/contracts/issue-5/implementation_plan.md`, `docs/contracts/issue-5/task.md`. - [x] **P0-18** ๊ด€๋ จ CLI/lock/rebuttal/adapter ํ…Œ์ŠคํŠธ์™€ ์ „์ฒด suite ์‹คํ–‰; ์ˆ˜์ง‘ยท์‹คํ–‰ยทํ†ต๊ณผยท์‹คํŒจ ์ˆซ์ž ๋ถ„๋ฆฌ. - *์ฆ๊ฑฐ (Rev.3 ๋‹น์‹œ)*: ์ „์ฒด 484๊ฐœ ์ˆ˜์ง‘, ์„ ํ–‰ ์ „์ฒด ์‹คํ–‰ 481๊ฐœ ํ†ต๊ณผ(0 failed, 0 skipped, 786.18s), 15๊ฐœ ๊ณ„์•ฝ/๋ณ€์ด ํ…Œ์ŠคํŠธ ์ „์ฒด ํ†ต๊ณผ, ์ง‘์ค‘ ์ฝ”์–ด ํšŒ๊ท€ 155๊ฐœ ํ†ต๊ณผ(60.48s). - *์ฆ๊ฑฐ (Rev.5, job `fb7fadd4`)*: ์ „์ฒด suite ์‹คํ–‰ **499 passed, 0 failed, 0 skipped (848.90s)** โ€” ์ปค๋ฐ‹ `19d798b` ๊ธฐ์ค€์„ (๊ณ„์•ฝ ํ…Œ์ŠคํŠธ 30๊ฐœ ํฌํ•จ)์—์„œ ์‹คํ–‰. Rev.5 ๋ณด๊ฐ• ํ›„ ๊ณ„์•ฝ ํ…Œ์ŠคํŠธ ํŒŒ์ผ ๋‹จ๋… ์žฌ์‹คํ–‰ **41 passed** (`+11`), ์ˆ˜์ง‘ ์ด๊ณ„ **510** (`--collect-only`). Rev.5 ๋ณ€๊ฒฝ์€ `tests/test_issue5_phase0_contracts.py` ๋ฐ `docs/`์— ๊ตญํ•œ๋˜์–ด ๋‚˜๋จธ์ง€ 469๊ฐœ ํ…Œ์ŠคํŠธ์— ์˜ํ–ฅ ์—†์Œ. - [x] **P0-19** ๋ฌธ์„œ ๋งํฌ/JSON/git diff --check/production ์ฝ”๋“œ ๋ฌด๋ณ€๊ฒฝ ํ™•์ธ. - *์ฆ๊ฑฐ*: `git diff --check` ํด๋ฆฐ, ๊ณต๋ฐฑ ๋ฆฐํŠธ ์™„๋ฃŒ, ํ”„๋กœ๋•์…˜ `.sh`/`.py` ๋ฌด๋ณ€๊ฒฝ (์˜ค์ง `docs/`, `tests/` ๋ณ€๊ฒฝ). - [x] **P0-20** ๊ฒฐ๊ณผ ๋ณด๊ณ : Phase 0 ์‚ฐ์ถœ๋ฌผ ์™„๋ฃŒ ์—ฌ๋ถ€, backend๋ณ„ native live gapยทmixed/simulated scenario ํ˜„ํ™ฉ, ๋‚จ์€ gate๋ฅผ ๋ณ„๋„ ๋ช…์‹œํ•˜๊ณ  peer review ์š”์ฒญ. - *์ฆ๊ฑฐ*: `.mam/jobs/61f2fa87/agy-reports/report-final.md` (Rev.3 ์ตœ์ดˆ ๋ณด๊ณ ), `.mam/jobs/f29cb24e/claude-code-reports/report-final.md` (Codex [P1]ยทClaude [Finding 2] ์ •์ •, ์ปค๋ฐ‹ `19d798b`), `.mam/jobs/fb7fadd4/claude-reports/report-final.md` (Rev.5 ์ž์ฒด ์žฌ๋ฆฌ๋ทฐ ๋ฐ ๋ณด๊ฐ•). --- ## Phase 1: `lib_py/delegation/` ๊ตฌ์ถ• (์™„๋ฃŒ, v4.3.0) - [x] **P1-00** ์ด๋™ ์ „ ํŠน์„ฑํ™” ํ…Œ์ŠคํŠธ ์„ ํ–‰. ์œ„์ž„ ์…ธ ํ—ฌํผ 3์ข…์˜ ๊ธฐ์กด ์ง์ ‘ ์ปค๋ฒ„๋ฆฌ์ง€๋Š” 0๊ฑด์ด์—ˆ๋‹ค. - *์ฆ๊ฑฐ*: `tests/test_issue5_phase1_delegation.py` C-01~C-09 (`MAM_DELEGATION_PY` 0/1 ์–‘์ชฝ parametrize), CLI ๊ณ„์•ฝ ์Šค๋ƒ…์ƒท, ์ž๋™์™„๋ฃŒ 3ํ‘œ๋ฉด ๋ถˆ๋ณ€ ๊ฐ€๋“œ. ์ปค๋ฐ‹ `265a1f6`. - [x] **P1-01** delegation ์Šคํฌ๋ฆฝํŠธ 4์ข…์„ `lib_py/delegation/`์œผ๋กœ `git mv` ํ•˜๊ณ  `scripts/*.py`๋Š” ํŒจํ‚ค์ง€ ๋ฐ”์ธ๋”ฉ shim์œผ๋กœ ๋ณด์กด. ์ €์žฅ์†Œ ํ†ตํ•ฉ ์—†์Œ, non-fatal ๊ณ„์•ฝ ๋ณด์กด. - *์ฆ๊ฑฐ*: ์ปค๋ฐ‹ `fb3498e`. PV-1 ์ •์ฒด์„ฑ+์ถœ์ฒ˜, PV-4 10๊ฐœ ์‹œ๋‚˜๋ฆฌ์˜ค(A/A_pe/B/B2/C1/C1_pe/C2/C2_pe/D/E) + K1/K3/K6 ์„œ๋ธŒํ”„๋กœ์„ธ์Šค ๋งคํŠธ๋ฆญ์Šค, PV-5 shim ๋ฐ”์ดํŠธ ๋™์ผ์„ฑ, AST ๊ธฐ๋ฐ˜ ํ˜•์ œ ์ž„ํฌํŠธ ๊ธˆ์ง€ ๊ฒ€์‚ฌ, `--help` ์ด๋™ ์ „ ์บก์ฒ˜์™€ ๋ฌด์ฐจ์ด. - *์„ค๊ณ„ ๊ทผ๊ฑฐ*: `creator-claude-01`์˜ ์ด์˜์ œ๊ธฐ(job `c0b9c987`)๋กœ `sys.path.insert(0)` ๋ฐฉ์‹์ด pytest์—์„œ `lib_py.agents`๊นŒ์ง€ ์ƒŒ๋“œ๋ฐ•์Šค ์‚ฌ๋ณธ์œผ๋กœ ๊ฐ€๋กœ์ฑ„๋Š” ๊ฒƒ์ด ์‹ค์ฆ๋˜์–ด, ํŒจํ‚ค์ง€ ๋‹จ์œ„ bind-once๋กœ ํ™•์ •. - [x] **P1-02** `DelegationService`/`cli.py`/`daemon.py` ๊ตฌํ˜„ ๋ฐ `lib.sh` ํ—ฌํผ ๊ต์ฒด. daemon PIDยท์ค‘๋ณตยท์ˆ˜๋ช… ๊ณ„์•ฝ ์ผ์น˜. - *์ฆ๊ฑฐ*: ์ปค๋ฐ‹ `78cb9ec`. C-01~C-09๊ฐ€ ๋ ˆ๊ฑฐ์‹œยทํŒŒ์ด์ฌ ๋‘ ๋ณธ์ฒด์—์„œ ํ†ต๊ณผ, daemon ๋ถ€๋ชจ ์ข…๋ฃŒ ํ›„ ์ƒ์กด ๋ฐ `pgrep` ์ค‘๋ณต ๊ฒ€์ถœ, cli๊ฐ€ ๋ ˆ๊ฑฐ์‹œ ์‹คํŒจ ๋ฌธ๊ตฌ๋ฅผ ์ •ํ™•ํžˆ ์žฌํ˜„, ๋ฐœํ–‰ ์‹คํŒจ ์‹œ๋งจํ‹ฑ(status ๋™๊ธฐํ™”ยทseq ์†Œ๋น„ยท`published: false`)์ด shim ๊ฒฝ๋กœ์™€ cli ๊ฒฝ๋กœ์—์„œ ๋™์ผ. - [x] **P1-03** ์žฅ์ˆ˜ MQTT ์—ฐ๊ฒฐ ํ”„๋กœํ† ํƒ€์ž… ๋ฐ ๋ฒค์น˜๋งˆํฌ. HMAC/seq/retain/๋””์Šคํฌ ํด๋ฐฑ ํšŒ๊ท€ ์œ ์ง€, ์ž๋™์™„๋ฃŒ ๋น„ํ™œ์„ฑ ์œ ์ง€. - *์ฆ๊ฑฐ*: ์ปค๋ฐ‹ `a4b7b45` + ์ž์ฒด ๋ฆฌ๋ทฐ ์ˆ˜์ • `f5286a0`(job `5e3c7660`์—์„œ ๋ฐœ๊ฒฌํ•œ `PersistentPublisher` CONNACK ์ƒํƒœ ๊ณต์œ  ๊ฒฐํ•จ ์ˆ˜์ • ๋ฐ ํšŒ๊ท€ 3์ข… ์ถ”๊ฐ€). `publish_event.main`์„ `prepare_event`/`record_outcome`/`main`์œผ๋กœ ๋ถ„๋ฆฌ(๋™์ž‘ ๋ถˆ๋ณ€, G-1~G-4 ํ†ต๊ณผ). ๊ฐ€์งœ ์ „์†ก์—์„œ OneShot N connect vs Persistent 1 connect, ๋‘ ์ „์†ก์˜ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌยท๊ฐ์‚ฌ ๋ ˆ์ฝ”๋“œ ํ•„๋“œ ๋‹จ์œ„ ๋™์ผ, PUBACK ๋ฏธํ™•์ธ ์‹œ ์žฌ์‹œ๋„ ํ›„ `published=false`, ๋ธŒ๋กœ์ปค ์ƒ์ด ์‹œ ๊ฑฐ๋ถ€. ๋„คํŠธ์›Œํฌ ์ ‘์ด‰ 0. - [x] **P1-04** ๋ฒค์น˜๋งˆํฌ ์‹ค์ธก ๋ฐ ๋ฌธ์„œ ๋™๊ธฐํ™”, ๋กค๋ฐฑ ๋“œ๋ฆด. - *์ฆ๊ฑฐ*: `docs/contracts/issue-5/phase1-benchmark.md`. ๊ฐ€์งœ ์ „์†ก p50 54.813ms โ†’ 0.002ms(์—ฐ๊ฒฐ 50ํšŒ โ†’ 1ํšŒ), ์‹ค๋ธŒ๋กœ์ปค p50 1892.728ms โ†’ 275.992ms(์ •๋ณด์„ฑ). `MAM_DELEGATION_PY=0` ๋กค๋ฐฑ ๋“œ๋ฆด ๋ฐ K2(freeze ์‚ฌ๋ณธ + ๋ผ์ด๋ธŒ `PYTHONPATH`) ์‹ค์ฆ ์™„๋ฃŒ. --- ## Phase 2a: `lib_py/loop/` ์ฝ”์–ด & Shadow Watcher (์™„๋ฃŒ, shadow-only) - [x] **P2A-00** ์ด๋™ ์ „ writer ํŠน์„ฑํ™” ์„ ํ–‰ (X-01~X-04, `MAM_ENGINE_CAS` 0/1 parametrize). - *์ฆ๊ฑฐ*: ์ปค๋ฐ‹ `9389d7e`. X-02๊ฐ€ ๊ณ„ํš์„œ์˜ ์ดˆ๊ธฐ ๊ฐ€์ •์„ ์ •์ •ํ•œ๋‹ค โ€” `pick_pending`์€ ๋ฝ ์•ˆ์—์„œ `pending`์„ ํ•„ํ„ฐํ•˜๋ฏ€๋กœ **์ด๋ฏธ ์˜ฌ๋ฐ”๋ฅธ CAS**์ด๋ฉฐ, ๋ฌธ์ œ๋Š” ์ •ํ™•์„ฑ์ด ์•„๋‹ˆ๋ผ **์ค‘๋ณต**์ด๋‹ค. - [x] **P2A-01** ๋‹จ์ผ ์ „์ด ๊ฒฝ๊ณ„ ๊ตฌํ˜„ ๋ฐ writer 2์ข… ๋ผ์šฐํŒ…. - *์ฆ๊ฑฐ*: ์ปค๋ฐ‹ `2532e78`. `engine.transition`์ด ์œ ์ผํ•œ ์ƒํƒœ writer. `state-transitions.md` ยง3 ํ‘œ ์ „ ํ•ญ๋ชฉ(claim/๋น„terminal/explicit terminal/๋ฉฑ๋“ฑ ์žฌ์ˆ˜์‹ /์ƒ์ถฉ ๊ฑฐ๋ถ€+๊ฐ์‚ฌ/stale attempt/deadline) ํ…Œ์ŠคํŠธ. `MAM_ENGINE_CAS=0` ๋ ˆ๊ฑฐ์‹œ ๋ณธ์ฒด ๋ณด์กด. - *๊ณ„ํš ๋Œ€๋น„ ๊ตฌ์กฐ ์ •์ •*: ๊ณ„ํš์„œ๋Š” `engine.py`๋ฅผ `lib_py/loop/`์— ๋‘์—ˆ์œผ๋‚˜, ๊ทธ๋Ÿฌ๋ฉด `lib_py.delegation`์ด **ํ˜•์ œ ํŒจํ‚ค์ง€๋ฅผ ์ž„ํฌํŠธ**ํ•˜๊ฒŒ ๋˜์–ด freeze ํ•˜์—์„œ ํŠธ๋ฆฌ๊ฐ€ ์„ž์ธ๋‹ค(Phase 1์ด ๋ช…๋ฌธํ™”ํ•œ ๊ทœ์น™). Phase 1์˜ ๊ธฐ์กด ๊ฐ€๋“œ ํ…Œ์ŠคํŠธ๊ฐ€ ์ด๋ฅผ ์ฆ‰์‹œ ๊ฒ€์ถœํ–ˆ๊ณ , ์—”์ง„์„ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ writer๋“ค์ด ์žˆ๋Š” `lib_py/delegation/`์œผ๋กœ ์˜ฎ๊ฒผ๋‹ค. - *๋ฝ ๊ทœ์œจ*: ๋ฝ์€ ํŒ์ • + ๋ ˆ์ฝ”๋“œ 1ํšŒ ์“ฐ๊ธฐ๋งŒ ๋ฎ๊ณ , ๊ฐ์‚ฌ mirror๋Š” ํ์ž‰ ํ›„ ๋ฝ ํ•ด์ œ ๋’ค flushํ•œ๋‹ค. ์ˆœ์„œ๋Š” `transition_seq`๋กœ ๋ณต์›ํ•œ๋‹ค. ๋ฝ ๋ณด์œ  ์ค‘ `subprocess`/`socket`/`sleep` ํ˜ธ์ถœ 0๊ฑด์„ ํ…Œ์ŠคํŠธ๋กœ ๊ฐ์‹œํ•œ๋‹ค. - [x] **P2A-02** watcherยท๊ท€์†ยทdispatch ์ฆ๊ฑฐยท์žฌ์—ฐ๊ฒฐ ๋ฐฑ์˜คํ”„. - *์ฆ๊ฑฐ*: ์ปค๋ฐ‹ `b49af56`. `--timeout`์€ **๋ฐ€๋ฆฌ์ดˆ**(ํŒŒ๋ผ๋ฏธํ„ฐ๋ช… `timeout_ms`), `--until` ํ•ญ์ƒ ๋ช…์‹œ(์ƒ๋žต ์‹œ `working` ๋ˆ„๋ฝ), exit 1์€ **stderr**์—์„œ ํŒŒ์‹ฑ. ๋ฐฑ์˜คํ”„ 1โ†’2โ†’4โ†’8โ†’16s ์ƒํ•œ, ์‹คํŒจ ์‹œ ์บ์‹œ ์Šค๋ƒ…์ƒท ํ๊ธฐ. ๊ท€์† ์ฆ๊ฑฐ๋Š” **๋ ˆ์ง€์ŠคํŠธ๋ฆฌ๊ฐ€ ์•„๋‹Œ shadow ์ „์šฉ ์ €์žฅ์†Œ**(`.mam/shadow/`)์— ๋‘”๋‹ค โ€” ๋ ˆ์ฝ”๋“œ์— 3๊ฐœ ํ•„๋“œ๊ฐ€ ์ „๋ถ€ ์—†๊ณ  Phase 1์ด ์Šคํ‚ค๋งˆ๋ฅผ ๋™๊ฒฐํ–ˆ๊ธฐ ๋•Œ๋ฌธ. - [x] **P2A-03** shadow-only๊ฐ€ terminal์„ ์“ฐ์ง€ ์•Š์Œ์„ ๊ฒ€์ฆ. - *์ฆ๊ฑฐ*: ์ปค๋ฐ‹ `964abc6`. `ShadowRunner`๋Š” engine ์ฐธ์กฐ๋ฅผ **๊ฐ–์ง€ ์•Š๋Š”๋‹ค**(๊ตฌ์กฐ์  ์ฐจ๋‹จ, AST ๋‹จ์ •). ์ธก์ •: ์ „์ฒด ์‹œ๋‚˜๋ฆฌ์˜ค ์‹คํ–‰ ์ „ํ›„ **๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ๋””๋ ‰ํ„ฐ๋ฆฌ ์ „ ํŒŒ์ผ SHA-256 ๋™์ผ**. - [x] **P2A-05** ๊ต์ฐจ ๋ฆฌ๋ทฐ(`68abd0ff` Claude / `cae12436` Codex) ์ง€์  5๊ฑด ์ „๊ฑด ์ˆ˜์šฉยท์ˆ˜์ •. - *์ฆ๊ฑฐ*: ์ปค๋ฐ‹ `56d08ef`. F-A(๋ž˜ํผ loop/discuss ์ „์ด 2๊ฑด ๋ˆ„๋ฝ โ†’ ์šด์˜์ž ๊ถŒํ•œ ์š”์ฒญ `redispatch`/`finalize` ์‹ ์„ค + CLI ๊ฑฐ๋ถ€ ์‹œ non-zero), F-B(๊ฐ์‚ฌ mirror ์ˆœ์„œ ํšŒ๊ท€ โ†’ `transition_seq` ๋น„๊ต), R1(๊ด€์ธก ์‹๋ณ„์ž ๋ฏธ๋Œ€์กฐ โ†’ `collect_observed_identity` ์ „๋Ÿ‰ ๋Œ€์กฐ + ๋งค๋‹ˆํŽ˜์ŠคํŠธ attempt ๊ฒ€์ฆ), R2(`expected_attempt`๊ฐ€ ๋ ˆ์ฝ”๋“œ์— ์—†์œผ๋ฉด ๋ฌด์‹œ โ†’ fail-closed), R3(raw `status` ํ•„๋“œ ์šฐํšŒ โ†’ ์š”์ฒญ๋งŒ์ด status๋ฅผ ์„ค์ •). ์‹ ๊ทœ ํšŒ๊ท€ 11์ข… ์ „๋ถ€ ์ˆ˜์ • ์ „ ์ฝ”๋“œ์—์„œ ์‹คํŒจํ•จ์„ ์—ญ๊ฒ€์ฆ. - [x] **P2A-06** ๊ต์ฐจ ๋ฆฌ๋ทฐ Round 2(`cb792e91` Claude / `0026165b` Codex) ์ง€์  4๊ฑด ์ „๊ฑด ์ˆ˜์šฉยท์ˆ˜์ •. - *์ฆ๊ฑฐ*: ์ปค๋ฐ‹ `cb575fa`. F-C(๋ฉฑ๋“ฑ ACK๋ฅผ ๊ฑฐ๋ถ€๋กœ ๋ถ„๋ฅ˜ โ†’ ๋ž˜ํผ ์„ฑ๊ณต ๊ฒฝ๋กœ๊ฐ€ `set -e`๋กœ ์ค‘๋‹จ; ๋ฉฑ๋“ฑ์€ rc 0, ์ง„์งœ ๊ฑฐ๋ถ€๋งŒ rc 4), F-D(`VALID_STATUSES` ๊ฒ€์ฆ ์†Œ์‹ค โ†’ ๋‘ ๋ชจ๋“œ ๊ณตํ†ต rc 1ยท๋ ˆ์ฝ”๋“œ ๋ถˆ๋ณ€), R1(์ฆ๊ฑฐ ๋ถ€์žฌ ์‹œ์—๋„ ์Šน์ธ โ†’ 4์‹๋ณ„์ž์™€ ๋งค๋‹ˆํŽ˜์ŠคํŠธ attempt **ํ•„์ˆ˜**, ์‹๋ณ„์ž๋Š” ๋„ค์ดํ‹ฐ๋ธŒ payload๊ฐ€ ์•„๋‹Œ `collector_attribution` ๋ด‰ํˆฌ์—์„œ ์ˆ˜์ง‘), R4(๋น„์›์ž์  ๋น„๊ต-ํ›„-์“ฐ๊ธฐ โ†’ per-job ๊ฐ์‚ฌ ๋ฝ + ๊ณ ์œ  ์ž„์‹œ ํŒŒ์ผ). ์‹ ๊ทœ ํšŒ๊ท€ 8์ข… ์ „๋ถ€ ์ˆ˜์ • ์ „ ์ฝ”๋“œ์—์„œ ์‹คํŒจํ•จ์„ ์—ญ๊ฒ€์ฆ. - [x] **P2A-04** race/attempt ์žฌ์‚ฌ์šฉ/๋ถ€๋ถ„ report/๋„๊ตฌ ์‹คํ–‰/blocked/unknown/์žฌ์‹œ์ž‘ ์‹œ๋‚˜๋ฆฌ์˜ค. - *์ฆ๊ฑฐ*: ์‹ ๊ทœ 5์ข…(`race_double_dispatch`, `attempt_reuse`, `partial_report`, `unknown_status`, `restart_midflight`)์„ Phase 0 ์Šคํ‚ค๋งˆ๋กœ ์ž‘์„ฑํ•ด **Phase 0์˜ `validate_watcher_scenario`๋ฅผ ํ†ต๊ณผ**์‹œ์ผฐ๊ณ , ๊ธฐ์กด 7์ข…๊ณผ ํ•ฉ์ณ **12์ข… ์ „๋ถ€ `expected_policy.decision`๊ณผ ์ผ์น˜**ํ•จ์„ ๋‹จ์ •ํ•œ๋‹ค. --- ## Phase 2b: ์ด์ค‘ ๊ฐ์ง€ ์ž๋™์™„๋ฃŒ ํ™œ์„ฑํ™” (์™„๋ฃŒ, ๊ธฐ๋ณธ ๋น„ํ™œ์„ฑ) - [x] **P2B-00** ์ž๋™์™„๋ฃŒ ๋„์ž… ์ „ fail-closed ์„ ํ–‰ ์กฐ๊ฑด ํŠน์„ฑํ™” (X-01~X-05). - *์ฆ๊ฑฐ*: ์ปค๋ฐ‹ `9a827b3`. ๋งค๋‹ˆํŽ˜์ŠคํŠธ ์—†๋Š” job์ด ์ด๋ฏธ `hold`์ž„์„ ๊ณ ์ • โ€” ๋ฏธ์ง€์› ๊ฒฝ๋กœ ๋ณด์กด์ด ์ƒˆ ๋ถ„๊ธฐ ์—†์ด ์„ฑ๋ฆฝํ•˜๋Š” ๊ทผ๊ฑฐ. - [x] **P2B-01** ๋ฆฌํฌํŠธ ํ™•์ • ๊ณ„์•ฝ(๋งค๋‹ˆํŽ˜์ŠคํŠธยทSHA-256) ๋ฐ ๋ถ€์ˆ˜ํšจ๊ณผ ์ฆ๊ฑฐ ํ”„๋กœํ† ์ฝœ. - *์ฆ๊ฑฐ*: ์ปค๋ฐ‹ `3ea5757`. `lib_py/delegation/finalize.py` + `publish_event --finalize-report/--side-effect`. **์„ ์–ธ์€ ์—์ด์ „ํŠธ๊ฐ€, ํ•ด์‹œ ์žฌ๊ณ„์‚ฐ์€ ์ฝ๋Š” ์ชฝ์ด** โ€” ์›Œ์ฒ˜๊ฐ€ ๋งŒ๋“  ๋งค๋‹ˆํŽ˜์ŠคํŠธ๋Š” ์ž๊ธฐ ์ฆ๋ช…์ด๋ฏ€๋กœ ์ฑ„ํƒํ•˜์ง€ ์•Š์•˜๋‹ค. ๋ฆฌํฌํŠธ ์žฌ์ž‘์„ฑ ์‹œ ์ฆ‰์‹œ ๋ฌดํšจ, ์„ ์–ธํ•œ ๋ถ€์ˆ˜ํšจ๊ณผ๋Š” ์ „๋ถ€ ์ฆ๊ฑฐ ํ•„์š”. - [x] **P2B-02** terminal + pending notification, ์žฌ์ „์†กยท์žฌ์‹œ์ž‘ยท๋Šฆ์€ conflict. - *์ฆ๊ฑฐ*: ์ปค๋ฐ‹ `803ba43`. `pending_notification`์„ ์ƒํƒœ์™€ **๊ฐ™์€ ์›์ž์  ์“ฐ๊ธฐ**๋กœ ์ปค๋ฐ‹, ๋ฝ ๋ฐ– ๋ฐœํ–‰, `notification_settled`(์ƒํƒœ ๋ฌด๋ณ€๊ฒฝ bookkeeping ์š”์ฒญ โ€” terminal์—์„œ๋„ ํ—ˆ์šฉ)๋กœ ์ •๋ฆฌ, ๊ธฐ๋™ ์‹œ ์žฌ๋ฐœํ–‰. ๋ฐœํ–‰ ์‹คํŒจ ์‹œ intent ๋ณด์กด. - [x] **P2B-03** ๊ฒ€์ฆ๋œ backend/job ํ•œ์ • default-off ํ”Œ๋ž˜๊ทธ. - *์ฆ๊ฑฐ*: ์ปค๋ฐ‹ `803ba43`. 3์ค‘ ๊ฒŒ์ดํŠธ(์ „์—ญ OFF ๊ธฐ๋ณธ / ๊ด€์ธก ์ฆ๊ฑฐ ๊ธฐ๋ฐ˜ ํ—ˆ์šฉ๋ชฉ๋ก `claude,grok,codex` / ์žก๋ณ„ opt-in). ํ—ˆ์šฉ๋ชฉ๋ก์€ ์ขํžˆ๊ธฐ๋งŒ ๊ฐ€๋Šฅ. ์ž๋™์™„๋ฃŒ terminal์— `completed_by` ํ‘œ์‹. - [x] **P2B-05** ๊ต์ฐจ ๋ฆฌ๋ทฐ 3์ธ(`3fa76e08` Claude / `a0de0e5e` Grok / `e5f26823` Codex) ์ฐจ๋‹จ ์ง€์  7๊ฑด ์ „๊ฑด ์ˆ˜์šฉยท์ˆ˜์ •. - *์ฆ๊ฑฐ*: ์ปค๋ฐ‹ `cb7ed1a`. ํ•„์ˆ˜ ๋งค๋‹ˆํŽ˜์ŠคํŠธ ๊ฒ€์ฆ(`report_dir` ์ƒ๋žต = ๊ฑฐ๋ถ€), ์ฆ๊ฑฐ์˜ ๋Œ€์ƒ ์ผ์น˜(job/attempt/session/pane), Reviewer ํŒ์ • ํ† ํฐ ๊ฒŒ์ดํŠธ(Phase 0 ์•ˆ์ „ ๊ณ„์•ฝ), bookkeeping ํ•„๋“œ ์ œํ•œ, ์กฐ๊ฑด๋ถ€ settle + intent ์‹ ์› ์ „๋‹ฌ, ๋ถ€์ˆ˜ํšจ๊ณผ evidence ์Šคํ‚ค๋งˆ ๊ฒ€์ฆ, `MAM_ENGINE_CAS=0` ์ค€์ˆ˜, ๋ฐฑ์—”๋“œ ์ •ํ™• ์ผ์น˜, ์ ˆ๋Œ€ ๊ฒฝ๋กœ. ์‹ ๊ทœ ํšŒ๊ท€ 21์ข… ์ „๋ถ€ ์ˆ˜์ • ์ „ ์ฝ”๋“œ์—์„œ ์‹คํŒจํ•จ์„ ์—ญ๊ฒ€์ฆ. - *๋ฐฐ์„  ํ˜„ํ™ฉ*: `evaluate`/`recover`์˜ **ํ”„๋กœ๋•์…˜ ํ˜ธ์ถœ์ž๋Š” ์•„์ง ์—†๋‹ค**(Phase 3 ๋ฐฐ์„ ). ์šด์˜ ๋…ธํŠธ ยง2-1์— ์ •์ • ๊ธฐ๋ก. - [x] **P2B-06** ๊ต์ฐจ ๋ฆฌ๋ทฐ Round 2(`a45e5b7f` Codex) ์ง€์  2๊ฑด ์ˆ˜์šฉยท์ˆ˜์ •. - *์ฆ๊ฑฐ*: ์ปค๋ฐ‹ `01b465f`. R2(๊ท€์†์ด ์ปค๋ฐ‹๊ณผ ์›์ž์ ์ด์ง€ ์•Š์Œ โ†’ `dispatch_token`์„ ๋ ˆ์ฝ”๋“œ์— ๋„์ž…, `claim`/`redispatch`์—์„œ ๋ฐœ๊ธ‰, `expected_dispatch_token`์œผ๋กœ ๋ฝ ์•ˆ์—์„œ ๋Œ€์กฐ), R4(intent ์‹ ์›์„ ๋ฐœํ–‰๋งŒ ํ•˜๊ณ  ์†Œ๋น„์ž๊ฐ€ ๋ฌด์‹œ โ†’ `job_subscriber`๊ฐ€ ์•ˆ์ • ์‹ ์›์œผ๋กœ ์ค‘๋ณต ์ œ๊ฑฐ). ์‹ ๊ทœ ํšŒ๊ท€ 7์ข… ์ „๋ถ€ ์ˆ˜์ • ์ „ ์ฝ”๋“œ์—์„œ ์‹คํŒจํ•จ์„ ์—ญ๊ฒ€์ฆ. - *์ด์ „ ํŒ๋‹จ ์ •์ •*: "์‹œ๋„ ๋ณด์ฆ์ด ์ฆ๊ฑฐ ๊ณ„์ธต์— ์žˆ์œผ๋ฏ€๋กœ ๋ ˆ์ฝ”๋“œ ์Šคํ‚ค๋งˆ ๋ณ€๊ฒฝ ๋ถˆํ•„์š”"๋Š” **๋Œ€์กฐ**์—๋Š” ๋งž์ง€๋งŒ **์›์ž์„ฑ**์—๋Š” ํ‹€๋ ธ๋‹ค. ์ถ”๊ฐ€ ํ•„๋“œ์ด๋ฏ€๋กœ `SCHEMA_VERSION`์€ 1 ์œ ์ง€. - [x] **P2B-07** ๊ต์ฐจ ๋ฆฌ๋ทฐ Round 3(Codex) ์ง€์  1๊ฑด + ๊ทธ ๊ณผ์ •์—์„œ ๋“œ๋Ÿฌ๋‚œ ์ธ์ ‘ ๊ฒฐํ•จ 1๊ฑด ์ˆ˜์šฉยท์ˆ˜์ •. - *์ฆ๊ฑฐ*: `job_subscriber._Watcher.on_message`์˜ `seen_intents` ๊ธฐ๋ก์ด ๋‹จ์กฐ seq ๊ฐ€๋“œ๋ณด๋‹ค **์•ž์„œ** ์‹คํ–‰๋˜์–ด, ๋Šฆ๊ฒŒ ๋„์ฐฉํ•œ ๊ณผ๊ฑฐ ํŒจํ‚ท์ด ์ž๊ธฐ intent๋ฅผ "์ด๋ฏธ ์ฒ˜๋ฆฌํ•จ"์œผ๋กœ ํƒœ์šฐ๊ณ  **๋’ค๋”ฐ๋ฅด๋Š” ์ •๋‹นํ•œ ์žฌ์‹œ๋„๊ฐ€ ๋“œ๋กญ**๋๋‹ค(`last_seq=10`, seq=9 ๊ฑฐ๋ถ€ ํ›„ ๋™์ผ intent์˜ seq=11 โ†’ `qsize()==0`). ์‹ ์› **๋Œ€์กฐ**๋Š” seq ๊ฐ€๋“œ ์•ž์—, ์‹ ์› **๊ธฐ๋ก**์€ seq ๊ฐ€๋“œ ๋’ค์— ๋‘์–ด "๋ณธ ์  ์žˆ๋‹ค"๊ฐ€ "๋ฐ›์•„๋“ค์˜€๋‹ค"๋ฅผ ๋œปํ•˜๋„๋ก ๊ณ ์ณค๋‹ค. ํ•จ๊ป˜: ํ•ด์‹œ ๋ถˆ๊ฐ€๋Šฅยท๋น„๊ฐ์ฒด intent๊ฐ€ `TypeError`๋กœ ์ฝœ๋ฐฑ์„ ๋น ์ ธ๋‚˜๊ฐ€ **๊ทธ ๊ตฌ๋…์ž์˜ ๋ชจ๋“  job ์ˆ˜์‹ ์„ ๋Š์„ ์ˆ˜ ์žˆ๋˜** ๊ฒฝ๋กœ๋ฅผ ๋“œ๋กญ+๊ฒฝ๊ณ ๋กœ ๋‹ซ์•˜๋‹ค. ์‹ ๊ทœ ํšŒ๊ท€ 6์ข…(๊ทธ์ค‘ 3์ข…์€ ์ˆ˜์ • ์ „ ์ฝ”๋“œ์—์„œ ์‹คํŒจํ•จ์„ ์—ญ๊ฒ€์ฆ, 3์ข…์€ ๋ณด์กดยท์ปค๋ฒ„๋ฆฌ์ง€ ๊ฐ€๋“œ) + ๋ฐœํ–‰โ†’์†Œ๋น„ ์‹ค๊ฒฝ๋กœ ์ข…๋‹จ ํ…Œ์ŠคํŠธ. - [x] **P2B-04** ๋ถ€์ˆ˜ํšจ๊ณผ ์˜ˆ์™ธยท๋ฌดํŒ์ • fail-closedยท๊ฒฝ์Ÿ/์žฌ์‹œ์ž‘ ์‹œ๋‚˜๋ฆฌ์˜ค. - *์ฆ๊ฑฐ*: ์‹ ๊ทœ ์‹œ๋‚˜๋ฆฌ์˜ค 3์ข…(`side_effect_unproven`, `no_verdict_fail_closed`, `notification_crash_window`)์„ Phase 0 ์Šคํ‚ค๋งˆ๋กœ ์ถ”๊ฐ€, **์ด 15์ข… ์ „๋ถ€** `expected_policy.decision` ์ผ์น˜. - *๊ณ„ํš ๋Œ€๋น„ ์ดํƒˆ(์ดํ›„ ์ •์ •๋จ)*: ์ฒ˜์Œ์—๋Š” ๊ณ„ํš์„œ ยงD2์˜ `attempt_id` ๋ ˆ์ฝ”๋“œ ์Šน๊ฒฉ์ด ๋ถˆํ•„์š”ํ•˜๋‹ค๊ณ  ํŒ๋‹จํ–ˆ์œผ๋‚˜, **P2B-06์—์„œ ์ด ํŒ๋‹จ์˜ ์ ˆ๋ฐ˜์„ ์ฒ ํšŒํ–ˆ๋‹ค.** ์ฆ๊ฑฐ๋ฅผ dispatch์™€ *๋Œ€์กฐ*ํ•˜๋Š” ๋ฐ์—๋Š” ์ฆ๊ฑฐ ๊ณ„์ธต์œผ๋กœ ์ถฉ๋ถ„ํ•˜์ง€๋งŒ ์ปค๋ฐ‹๊ณผ์˜ *์›์ž์„ฑ*์—๋Š” ๋ถ€์กฑํ•˜๋‹ค. ์ตœ์ข…์ ์œผ๋กœ ์Šน๊ฒฉํ•œ ๊ฒƒ์€ `attempt_id`๊ฐ€ ์•„๋‹ˆ๋ผ **๋ถˆํˆฌ๋ช…ํ•œ `dispatch_token`**์ด๋‹ค(`iteration`์€ ๋ฃจํ”„ ํšŒ์ฐจ๋ผ๋Š” ๋‹ค๋ฅธ ๋œป์„ ์ด๋ฏธ ๊ฐ–๊ณ  ์žˆ๋‹ค). ๋ ˆ์ฝ”๋“œ ์Šคํ‚ค๋งˆ๋Š” ํ•„๋“œ ์ถ”๊ฐ€๋งŒ์ด๋ฉฐ `SCHEMA_VERSION`์€ 1 ์œ ์ง€. ์ƒ์„ธ๋Š” `phase2b-autocomplete.md` ยง9(๋ถ€๋ถ„ ์ฒ ํšŒ ํ‘œ์‹œ). --- ## Phase 3: `run_loop.sh` Thin Wrapper ์ „ํ™˜ ๋ฐ ์ „๋ฉด ํšŒ๊ท€ (ํ›„์†) - [ ] **P3-01** planner/reviewer/rebuttal/promotion ๋ฐ strict ํŒ์ •/์˜ˆ์‚ฐ/์ค‘์žฌ/ํ•ฉ์˜ ํ…Œ์ŠคํŠธ. - [ ] **P3-02** thin wrapper ์ธ์žยทinterpreterยทcwdยทsignalยทguardยทchild cleanup ํ˜ธํ™˜ ๊ฒ€์ฆ. - *์ธ๊ณ„ (๊ต์ฐจ ๋ฆฌ๋ทฐ `25609c81` O-4)*: freeze ์‚ฌ๋ณธ์˜ `lib.sh`์—์„œ `_delegate_py_bin`์€ `AGENT_PYTHON_BIN`/`VIRTUAL_ENV`๊ฐ€ ์—†์œผ๋ฉด **์ž๊ธฐ ์œ„์น˜์—์„œ ์ƒํ–ฅ ํƒ์ƒ‰**ํ•˜๋Š”๋ฐ, freeze ๋””๋ ‰ํ„ฐ๋ฆฌ ์•„๋ž˜์—๋Š” `.venv`๊ฐ€ ์—†์–ด paho๊ฐ€ ์—†๋Š” ์‹œ์Šคํ…œ `python3`๋กœ ๋–จ์–ด์ง„๋‹ค. Phase 1์—์„œ๋Š” freeze `lib.sh`์˜ ์œ„์ž„ ํ—ฌํผ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ํ”„๋กœ๋•์…˜ ๊ฒฝ๋กœ๊ฐ€ ์—†์–ด ๋ฌดํ•ดํ•˜๋‚˜, **Phase 3์—์„œ ๋ฃจํ”„ ํ”„๋กœ์„ธ์Šค๊ฐ€ freeze `lib.sh`์˜ ํ—ฌํผ๋ฅผ ์ง์ ‘ ํ˜ธ์ถœํ•˜๊ธฐ ์‹œ์ž‘ํ•˜๋ฉด** ์ธํ„ฐํ”„๋ฆฌํ„ฐ ํ•ด์„์„ `WORKSPACE_ROOT`(๋˜๋Š” `MAM_REAL_ROOT`) ๊ธฐ์ค€์œผ๋กœ ์•ต์ปค๋งํ•ด์•ผ ํ•œ๋‹ค. - [ ] **P3-03** ์ „์ฒด suite+์‹ ๊ทœ race/restart/lifecycle, writer ๋‹จ์ผ์„ฑ, rollback checkpoint ์ธ๊ณ„ ๊ฒ€์ฆ. --- ## Phase 4: ๋ถˆ๋ณ€ ๋Ÿฐํƒ€์ž„ ๊ฒ€์ฆ ๋ฐ Freeze ์ œ๊ฑฐ (ํ›„์†) - [ ] **P4-01** eager import+child/helper/template ์‹คํ–‰ ๋ฒ„์ „ ์ •์ฑ… ๊ตฌํ˜„/๊ฒ€์ฆ. - [ ] **P4-02** ์‹คํ–‰ ์ค‘ ์ฝ”๋“œ ๊ต์ฒด์™€ ๋Šฆ์€ ์žฌ์‹ฌ/์Šน๊ฒฉ/rollback ์ŠคํŠธ๋ ˆ์Šค ๊ฒ€์ฆ. - [ ] **P4-03** gate ํ†ต๊ณผ ํ›„์—๋งŒ Freeze ์ œ๊ฑฐ ๋ฐ ์šด์˜ ๋ฌธ์„œ ๊ฐฑ์‹ .