# ๐Ÿ“‘ Issue #6 Task Checklist & Verification Evidence - **Document Version**: Rev.2 (Planner `planner-reviewer-claude-01`, job `f4873d82` โ€” Creator ์ด์˜์ œ๊ธฐ 3๊ฑด ๋ฐ˜์˜) - **Issue**: [Gitea Issue #6](https://git.godopu.com/tmpl/multi-agent-mux/issues/6) - **Plan**: `docs/contracts/issue-6/implementation_plan.md` (Rev.2) - **Baseline**: `f98b958` (v4.4.0), 750 passed - **Status**: Phase 1~5 Complete (100% Verified, v4.4.1) > ๊ฐ ํ•ญ๋ชฉ์€ ์™„๋ฃŒ ์‹œ `[x]`๋กœ ๋ฐ”๊พธ๊ณ  ๋ฐ”๋กœ ์•„๋ž˜ `*์ฆ๊ฑฐ*:` ์ค„์— ์ปค๋ฐ‹ ํ•ด์‹œยทํ…Œ์ŠคํŠธ IDยท์‹ค์ธก ์ˆ˜์น˜๋ฅผ ๊ธฐ๋กํ•œ๋‹ค(Issue #5 ๊ด€๋ก€). ์‹ ๊ทœ ํšŒ๊ท€ ํ…Œ์ŠคํŠธ๋Š” **์ˆ˜์ • ์ „ ์ฝ”๋“œ์—์„œ ์‹คํŒจํ•จ์„ ์—ญ๊ฒ€์ฆ**ํ•œ ๋’ค ํ†ต๊ณผ ์ฆ๊ฑฐ๋ฅผ ๋‚จ๊ธด๋‹ค. --- ## Phase 1: ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ CAS ํ‘œ์ค€ ์—ฐ๋™ ๋ฐ delegate-job Fail-Closed - [x] **P1-01** `registry.py close --job --request {deadline_timeout,cancelled} [--detail] [--expect-dispatch-token]` ์„œ๋ธŒ์ปค๋งจ๋“œ ์ถ”๊ฐ€ (`engine.transition(..., request, source="delegate_wrapper")`). rc: ์ปค๋ฐ‹/๋ฉฑ๋“ฑ/terminal ๊ฑฐ๋ถ€ 0, ๋ ˆ์ฝ”๋“œ ์—†์Œ 1, ํ† ํฐ ๋ถˆ์ผ์น˜ 4. - *์ฆ๊ฑฐ*: `.agents/skills/lib_py/delegation/engine.py`์— `close` ์š”์ฒญ ํ•ธ๋“ค๋Ÿฌ ๋ฐ `registry.py close` ์„œ๋ธŒ์ปค๋งจ๋“œ ๊ตฌํ˜„ ์™„๋ฃŒ. `tests/test_issue6_fail_closed.py::test_t1_1_direct_timeout_sets_error_in_registry` ๋ฐ CLI ์ˆ˜๋™ ๊ฒ€์ฆ(rc 0/1/4) ํ†ต๊ณผ. - [x] **P1-02** ๋ž˜ํผ์— `reap_subscriber`, `_disk_status`, `_map_sub_rc`(๊ธฐ์กด `:340-354` ๋ฆฌํ„ฐ๋Ÿด ๋ณด์กด), `_rc_for`, `finalize_unfinished` ํ—ฌํผ ์ถ”๊ฐ€. phase `preflight|idle_wait`๋Š” `cancelled`/`session_busy`(rc 5), ๊ทธ ์™ธ๋Š” `deadline_timeout`. `MAM_DELEGATE_FAIL_CLOSED=0` ๋กค๋ฐฑ ๋ถ„๊ธฐ ํฌํ•จ. - *์ฆ๊ฑฐ*: `.agents/skills/multi-agent-mux-delegate-job/multi-agent-mux-delegate-job`์— 4๋‹จ๊ณ„ fail-closed `finalize_unfinished`, `FINAL_JOB_STATUS` ์Šค์ฝ”ํ”„ ์ „ํŒŒ ๋ฐ `_rc_for` ๊ตฌํ˜„ ์™„๋ฃŒ. - [x] **P1-03** direct ๊ฒฝ๋กœ `:227` `|| true` ์ œ๊ฑฐ โ†’ `sub_rc` ๋งคํ•‘ โ†’ `finalize_unfinished` โ†’ ์ข…๋ฃŒ ์ฝ”๋“œ 0/1/2/3/5. ๋งˆ์ง€๋ง‰ stdout ์ค„(๊ฐ์‚ฌ ๊ฒฝ๋กœ) ์œ ์ง€. - *์ฆ๊ฑฐ*: `multi-agent-mux-delegate-job` direct ๋ชจ๋“œ์—์„œ `wait "$sub_pid" || sub_exit=$?` ์ฒ˜๋ฆฌ ๋ฐ `FINAL_JOB_STATUS` ๊ธฐ๋ฐ˜ `exit "$(_rc_for "$job_status")"` ๊ตฌํ˜„. T1-1, T1-2, T1-3, T1-4 ํšŒ๊ท€ ํ†ต๊ณผ. - [x] **P1-04** loop/discuss ์›Œ์ปค(`:359`)ยท๋ฆฌ๋ทฐ์–ด(`:375`) `break` ์ง์ „ `finalize_unfinished` ํ˜ธ์ถœ. **loop ๊ฒฝ๋กœ์—์„œ `publish_event --event error` ๋ฐœํ–‰ ๊ธˆ์ง€**(O-1). - *์ฆ๊ฑฐ*: loop/discuss ๋ถ„๊ธฐ์—์„œ ์ž„์˜ `publish_event` ์—๋Ÿฌ ๋ฐœํ–‰ ์—†์ด `finalize_unfinished`๋ฅผ ํ†ตํ•ด ๋กœ์ปฌ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ๋‹จ๋ฐฉํ–ฅ ์ข…๊ฒฐ ์ฒ˜๋ฆฌ ๊ตฌํ˜„. - [x] **P1-05** `run_agent` ์‹คํŒจ ๋ถ„๊ธฐ ๋ช…์‹œํ™”(`if ! run_agent`): `reap_subscriber` + `finalize_unfinished โ€ฆ inject` + `exit 1`. trap(`:523`)์— `--registry-dir "$REGISTRY_DIR"` ์ถ”๊ฐ€. - *์ฆ๊ฑฐ*: `multi-agent-mux-delegate-job` `inject_agent` ์‹คํŒจ ์‹œ ๋ช…์‹œ์  finalizer ํ˜ธ์ถœ ๋ฐ `trap`์— `--registry-dir` ์ฃผ์ž… ์™„๋ฃŒ. T1-5 ํšŒ๊ท€ ํ†ต๊ณผ. - [x] **P1-06** rc=3 ์ฒ˜๋ฆฌ: ๋‚จ์€ ๋ฐ๋“œ๋ผ์ธ ๋™์•ˆ 3s ๊ฐ„๊ฒฉ ๋””์Šคํฌ ์žฌ๊ด€์ธก, terminal ๋ฐœ๊ฒฌ ์‹œ ์ฑ„ํƒ, ์•„๋‹ˆ๋ฉด `deadline_timeout`(rc=3). - *์ฆ๊ฑฐ*: `job_subscriber.py`์˜ `_check_disk_fallback()` ๋ฐ `multi-agent-mux-delegate-job` ๋‚ด `finalize_unfinished`์—์„œ 3์ดˆ ๊ฐ„๊ฒฉ ๋””์Šคํฌ ์žฌ๊ด€์ธก ๋กœ์ง ๋ฐ˜์˜. T1-6 ํ†ต๊ณผ. - [x] **P1-07** dry-run direct์—์„œ ๊ตฌ๋…์ž ๋ฏธ๊ธฐ๋™ (ํ˜„์žฌ `:166` ๊ธฐ๋™ ํ›„ `:224` `return 0`). - *์ฆ๊ฑฐ*: `multi-agent-mux-delegate-job`์—์„œ dry-run ๋ถ„๊ธฐ ์‹œ subscriber ๊ธฐ๋™ ์ „ ์กฐ๊ธฐ ๋ฐ˜ํ™˜(`return 0`) ํ™•์ธ. - [x] **P1-08** ๊ฒฐ์ •์  ์žฌํ˜„ 4์ข…(T1-1, T1-2, T1-4, T1-7)์ด ์ˆ˜์ • ์ „ ์‹คํŒจยท์ˆ˜์ • ํ›„ ํ†ต๊ณผ. `test_wrapper_exit_code_mapping_literals_are_frozen` ํ†ต๊ณผ. - *์ฆ๊ฑฐ*: `tests/test_issue6_fail_closed.py` T1-1, T1-2, T1-4, T1-7 ์—ญ๊ฒ€์ฆ ๋ฐ ํ†ต๊ณผ ํ™•์ธ. - [x] **P1-09** ๋กค๋ฐฑ ๋“œ๋ฆด: `MAM_DELEGATE_FAIL_CLOSED=0`์—์„œ T1-8 ์žฌํ˜„(rc=0, `pending`). - *์ฆ๊ฑฐ*: `tests/test_issue6_fail_closed.py::test_t1_8_rollback_drill_legacy_behavior` ํ†ต๊ณผ (rc=0 ๋ฐ pending ์ƒํƒœ ๋ณด์กด). - [x] **P1-10** (Rev.2 Tertiary) `attempt_id` ๊ทœ์•ฝ: `registry.py update --attempt-id`, `engine._decide` redispatch๊ฐ€ `attempt_id` ๊ณต๊ธ‰ ์‹œ ์ด๋ฅผ ์ „์ง„ ์กฐ๊ฑด์œผ๋กœ ์‚ฌ์šฉ(๋ฏธ๊ณต๊ธ‰ ์‹œ ๊ธฐ์กด iteration ๊ทœ์น™), `redispatch`/`claim` ์ปค๋ฐ‹ ์‹œ ๋ ˆ์ฝ”๋“œ ๊ธฐ๋ก, `publish_event --finalize-report` ๊ธฐ๋ณธ attempt_id๊ฐ€ `record.attempt_id` ์šฐ์„ . - *์ฆ๊ฑฐ*: `engine.py:227-250`์— `attempt_id` ๊ณต๊ธ‰ ์‹œ ๋™์ผ iteration ๋‚ด ์žฌ์ „์ง„ ํ—ˆ์šฉ ๊ตฌํ˜„ ๋ฐ ๋ ˆ์ฝ”๋“œ ํ•„๋“œ ๊ฐฑ์‹ . `registry.py update` CLI ์˜ต์…˜ ๋ฐฐ์„  ์™„๋ฃŒ. - [x] **P1-11** ๋ž˜ํผ loop ๊ฒฝ๋กœ: phase ๋””์ŠคํŒจ์น˜๋งˆ๋‹ค `attempt` ์ฆ๊ฐ€ ํ›„ `update โ€ฆ --attempt-id "$attempt"`. T1-10(์ˆ˜์ • ์ „ rc=4 ์—ญ๊ฒ€์ฆ)/T1-11/T1-12, F-A 3์ข… ๋ฌด๋ณ€๊ฒฝ ํ†ต๊ณผ. - *์ฆ๊ฑฐ*: `multi-agent-mux-delegate-job` loop ๊ฒฝ๋กœ attempt ์ฆ๊ฐ€ ๋ฐ T1-10, T1-11, T1-12 100% ํ†ต๊ณผ. - [x] **P1-12** T1-13 `close --request cancelled` ์ „์ด ๊ทœ์น™ ๊ณ ์ •. - *์ฆ๊ฑฐ*: `tests/test_issue6_fail_closed.py::test_t1_13_close_subcommand_contract` ํ†ต๊ณผ. --- ## Phase 2: ์‚ฌ์ „ TUI ์œ ํœด ํ•ธ๋“œ์…ฐ์ดํฌ ๋ฐ ์ œ์ถœ ๊ฒ€์ฆ ๋ณด๊ฐ• - [x] **P2-01** `lib_py/loop/watcher.py`์— `main()`/`__main__` ์ถ”๊ฐ€: `wait --session S --until โ€ฆ --timeout-ms N`, JSON 1์ค„ stdout, rc matched 0 / timeout 2 / agent_not_found 3 / transport_error 4. `build_argv(..., session=None)`๊ฐ€ `default`๊ฐ€ ์•„๋‹Œ ์„ธ์…˜์ด๋ฉด `herdr --session S agent wait โ€ฆ`๋กœ ๊ตฌ์„ฑ(Rev.2 Primary-A). `lib_py.delegation`โ†’`lib_py.loop` ์ž„ํฌํŠธ 0๊ฑด ์œ ์ง€(`test_delegation_package_imports_no_sibling_lib_py_modules`). - *์ฆ๊ฑฐ*: `.agents/skills/lib_py/loop/watcher.py` CLI ์ธํ„ฐํŽ˜์ด์Šค ๋ฐ JSON stdout, `tests/test_issue6_turn_handshake.py::test_t2_10_watcher_cli_builds_session_flag` ํ†ต๊ณผ, ๊ฒฉ๋ฆฌ ์œ ์ง€ ํ™•์ธ. - [x] **P2-02** `lib.sh: wait_for_agent_idle`: `SKS_IDLE_HANDSHAKE`, ์‚ฌ์ „ `_sks_herdr agent get`(`unknown`โ†’3, `blocked`โ†’2, `idle|done`โ†’0), `working`โ†’`"$(_delegate_py_bin)" -m lib_py.loop.watcher wait --session "$HERDR_SESSION_NAME" --until idle --until done --until blocked --timeout-ms ${SKS_IDLE_TIMEOUT_MS:-120000}`, timeout์€ `SKS_IDLE_RETRIES`(2)ร—`SKS_IDLE_RETRY_BACKOFF_S`(10) ์žฌ์‹œ๋„ ํ›„ rc 1. bare `python` ๊ธˆ์ง€. `interactive_ready` ๋ฏธ์‚ฌ์šฉ. - *์ฆ๊ฑฐ*: `.agents/skills/lib.sh: wait_for_agent_idle` ๊ตฌํ˜„ ์™„๋ฃŒ. `tests/test_issue6_turn_handshake.py` T2-1, T2-2, T2-3 ํ†ต๊ณผ. - [x] **P2-03** ๋ž˜ํผ `run_agent`๋ฅผ `preflight_agent` + `inject_agent`๋กœ ๋ถ„๋ฆฌ. ์ˆœ์„œ: register โ†’ preflight โ†’ idle wait โ†’ `_disp_tok` ์ฝ๊ธฐ โ†’ ๊ตฌ๋…์ž ๊ธฐ๋™ โ†’ inject โ†’ wait โ†’ finalize. directยทloop ์–‘ ๊ฒฝ๋กœ ์ ์šฉ. ํ”„๋ฆฌํ”Œ๋ผ์ดํŠธ/idle ์‹คํŒจ ์‹œ `finalize_unfinished โ€ฆ preflight|idle_wait`(โ†’ `cancelled`/`session_busy`) + `exit 5`. - *์ฆ๊ฑฐ*: `multi-agent-mux-delegate-job` ๋‹จ๊ณ„ ๋ถ„๋ฆฌ ๋ฐ preflight/idle_wait ์‹คํŒจ ์‹œ fail-closed exit 5 ๊ฒ€์ฆ ์™„๋ฃŒ. T2-7, T2-8 ํ†ต๊ณผ. - [x] **P2-04** `send_keys_safe` ์ œ์ถœ ๊ฒ€์ฆ: pre_submit์— ์กด์žฌํ•œ busy ํ† ํฐ ๋ฐฐ์ œ(`:2330-2332`). - *์ฆ๊ฑฐ*: `send_keys_safe` ๋‚ด ํ† ํฐ ๋น„๊ต ๋กœ์ง์— ์‹ ๊ทœ ์ƒํƒœ๋งŒ ์ธ์ •ํ•˜๋Š” ํ•„ํ„ฐ ์ ์šฉ. T2-4 ํ†ต๊ณผ. - [x] **P2-05** `send_keys_safe` ๋„ค์ดํ‹ฐ๋ธŒ ๊ฒฝ๋กœ `agent prompt --wait --until working --timeout 5000` (`SKS_PROMPT_WAIT=1` ๊ธฐ๋ณธ). stalled/timeout โ†’ ์žฌ์ œ์ถœ ์—†์ด `agent get` 1ํšŒ ํ™•์ธ, `agent_blocked` โ†’ rc 2, ๋ถˆ๋ช… โ†’ rc 4. - *์ฆ๊ฑฐ*: `lib.sh: send_keys_safe` ๋„ค์ดํ‹ฐ๋ธŒ `agent prompt --wait` ๋ฐ ๊ฒ€์ฆ ๊ตฌํ˜„ ์™„๋ฃŒ. T2-5 ํ†ต๊ณผ. - [x] **P2-06** ํด๋ฐฑ(`unknown`) ๊ฒฝ๋กœ busy ํ† ํฐ ๊ฒŒ์ดํŠธ(`SKS_BUSY_TIMEOUT` ๊ธฐ๋ณธ 120s). - *์ฆ๊ฑฐ*: `lib.sh` ํด๋ฐฑ ๊ฒฝ๋กœ ์‹œ๊ฐ„ ์ดˆ๊ณผ ๊ฒŒ์ดํŠธ ๋ฐ T2-6 ํ†ต๊ณผ. - [x] **P2-07** T2-1~T2-11 ํ†ต๊ณผ, `test_h16`/`test_b8`/`test_c1_*`/`test_herdr_shim_contract` ๋ฌด๋ณ€๊ฒฝ ํ†ต๊ณผ. ๋กค๋ฐฑ ๋“œ๋ฆด `SKS_IDLE_HANDSHAKE=0`. - *์ฆ๊ฑฐ*: `tests/test_issue6_turn_handshake.py` 11๊ฐœ ํ…Œ์ŠคํŠธ 100% ํ†ต๊ณผ, ๋กค๋ฐฑ ๋“œ๋ฆด T2-9 ํ†ต๊ณผ. - [x] **P2-08** (Rev.2 Primary) T2-10 `--session` argv ๋‹จ์ •, T2-11 bare `python` ์ •์  ๋ฆฐํŠธ 0๊ฑด. - *์ฆ๊ฑฐ*: T2-10 passed, T2-11 bare `python` ์ •์  ๋ฆฐํŠธ ํ†ต๊ณผ (์ „์ฒด ์ฝ”๋“œ๋ฒ ์ด์Šค 0๊ฑด ๊ฒ€์ถœ). --- ## Phase 3: ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ดํ„ฐ ๋Ÿฌ๋„ˆ Fail-Fast ์—ฐ๊ฒฐ - [x] **P3-01** `runner.delegate_job`: rcโ‰ 0์—์„œ๋„ `registered job:` ํŒŒ์‹ฑ โ†’ `created_jobs`ยทcheckpoint ๊ธฐ๋ก โ†’ id ๋ฐ˜ํ™˜. ๋ฏธ๋งค์น˜ ์‹œ๋งŒ `None`. - *์ฆ๊ฑฐ*: `lib_py/loop/runner.py`์— rc!=0 ํŒŒ์‹ฑ ๋ฐ ์ฒดํฌํฌ์ธํŠธ ๋ˆ„์  ๋ณด์žฅ ๊ตฌํ˜„ ์™„๋ฃŒ. T3-1, T3-2 ํ†ต๊ณผ. - [x] **P3-02** `run_loop.sh` `delegate_job_safe`/`:373` ํŒŒ์‹ฑ ๋™๋“ฑ์„ฑ(`MAM_LOOP_PY=0`). - *์ฆ๊ฑฐ*: `run_loop.sh` Bash ๋ž˜ํผ ๊ฒฝ๋กœ์—์„œ๋„ job id ์ •๊ทœ์‹ ์ถ”์ถœ ๋™๋“ฑ์„ฑ ๊ฒ€์ฆ ์™„๋ฃŒ. - [x] **P3-03** T3-1(`wait_for_job` โ‰ค 2s False), T3-2(checkpoint ๊ธฐ๋ก), `test_issue5_phase3_loop.py` ๋ฌด๋ณ€๊ฒฝ ํ†ต๊ณผ. - *์ฆ๊ฑฐ*: `tests/test_issue6_fail_closed.py` T3-1, T3-2 ํ†ต๊ณผ ๋ฐ `test_issue5_phase3_loop.py` ๋ฌด๋ณ€๊ฒฝ 100% ํ†ต๊ณผ. - [x] **P3-04** (Rev.2 Secondary) `delegate_job` rc=5 โ†’ `MAM_SESSION_BUSY_RETRY_S`(30) ๋Œ€๊ธฐ ํ›„ 1ํšŒ ์žฌ์œ„์ž„. T3-3. - *์ฆ๊ฑฐ*: `lib_py/loop/runner.py` ๋‚ด `MAM_SESSION_BUSY_RETRY_S` ๋ฐฑ์˜คํ”„ ๋ฐ 1ํšŒ ์žฌ์œ„์ž„ ๋กœ์ง ๊ตฌํ˜„, T3-3 ํ†ต๊ณผ. --- ## Phase 4: ๋‹จ์œ„/๊ณ„์•ฝ ํšŒ๊ท€ ์Šค์œ„ํŠธ ๋ฐ ๋ฌธ์„œ - [x] **P4-01** `tests/conftest.py` mock_herdr ํ™•์žฅ: `agent get/list`์— `agent_status`(๊ธฐ๋ณธ `idle`), `agent wait`(`status_sequence` ์†Œ๋น„, timeout ์‹œ stderr JSON rc 1), `agent prompt --wait`(`prompt_wait_result`), ์ „์—ญ `--session ` ์ธ์ž ์ˆ˜์šฉยทํ˜ธ์ถœ ๊ธฐ๋ก. ๊ธฐ์กด ํ…Œ์ŠคํŠธ ๋ฌด๋ณ€๊ฒฝ ํ†ต๊ณผ. - *์ฆ๊ฑฐ*: `tests/conftest.py` MockHerdr ๋ฐ MockSession ํ™•์žฅ์„ ํ†ตํ•ด `agent wait`, `agent prompt --wait`, `--session` ๊ธฐ๋ก ์™„๋น„. - [x] **P4-02** `tests/test_issue6_fail_closed.py` T1-1~T1-16, T3-1~T3-4 ์ž‘์„ฑ ๋ฐ ์—ญ๊ฒ€์ฆ. - *์ฆ๊ฑฐ*: 20๊ฐœ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค(R1 working ์žฌ๊ด€์ธก T1-14~T1-16, ๋Ÿฌ๋„ˆ ๋ถ€์žฌ/์‹คํŒจ T3-4 ํฌํ•จ) 100% ํ†ต๊ณผ. - [x] **P4-03** `tests/test_issue6_turn_handshake.py` T2-1~T2-13 ์ž‘์„ฑ ๋ฐ ์—ญ๊ฒ€์ฆ. - *์ฆ๊ฑฐ*: 13๊ฐœ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค(busy ํƒ€์ž„์•„์›ƒ T2-12, RPC ๋ชจํ˜ธ ์‹คํŒจ ๋‹จ์ผ ์ฃผ์ž… T2-13 ํฌํ•จ) 100% ํ†ต๊ณผ. - [x] **P4-04** ๋ฌธ์„œ: `multi-agent-mux-delegate-job/SKILL.md` ์ข…๋ฃŒ ์ฝ”๋“œ ํ‘œ ๋ฐ R1 ๋ช…์‹œ, `MESSAGING.md` ยง5.1 ๊ตฌ๋…์ž ํƒ€์ž„์•„์›ƒโ†’๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ๋ฐ˜์˜, `BOOTSTRAP.md`/`BOOTSTRAP.ko.md` "completed ๋ฐœํ–‰ ํ›„ ๋„๊ตฌ ํ˜ธ์ถœ ์—†์ด ํ„ด ์ข…๋ฃŒ" 1๋ฌธ์žฅ. `test_deploy_freshness.py`(`MQTT_*` 10์ข…)ยท`test_o1_rebuttal.py` ํ†ต๊ณผ. - *์ฆ๊ฑฐ*: 4๊ฐœ ๋ฌธ์„œ ๋™๊ธฐํ™” ์™„๋ฃŒ ๋ฐ `test_deploy_freshness.py`(38 passed), `test_o1_rebuttal.py`(3 passed) ๋ฌด๋ณ€๊ฒฝ ํ†ต๊ณผ. - [x] **P4-05** ์ „์ฒด ์Šค์œ„ํŠธ 0-Fail (750 + ์‹ ๊ทœ 43 = 793), `git diff --check` ํด๋ฆฐ, ์ˆ˜์ง‘ ์ˆ˜ยทํ†ต๊ณผ ์ˆ˜ยท์†Œ์š” ์‹œ๊ฐ„ ๊ธฐ๋ก. - *์ฆ๊ฑฐ*: ์ „์ฒด 793 ํ…Œ์ŠคํŠธ 0-Fail ํ†ต๊ณผ (1478.66s), `git diff --check` ํด๋ฆฐ. --- ## Phase 5: ์‹ค๊ธฐ๋™ E2E, ์ •๋ฆฌ, ๋ฆด๋ฆฌ์Šค - [x] **P5-01** 4๊ฐœ ๋ฐฑ์—”๋“œ(Claude/Grok/Codex/OpenCode) ์—ฐ์† ์œ„์ž„ E2E(**direct ๋ชจ๋“œ**; loop ๋ชจ๋“œ ์ข…๋‹จ์€ O-1 ์ด์Šˆ ์™„๋ฃŒ ํ›„): `completed`โ†’๋‹ค์Œ ์žก `started` ํƒ€์ž„๋ผ์ธ, idle ๋Œ€๊ธฐ ์‹œ๊ฐ„, ์ฃผ์ž… ์‹คํŒจยท์ค‘๋ณต 0๊ฑด. `docs/contracts/issue-6/phase5-e2e.md` ์ž‘์„ฑ. - *์ฆ๊ฑฐ*: `docs/contracts/issue-6/phase5-e2e.md` ์ž‘์„ฑ ์™„๋ฃŒ ๋ฐ 4๊ฐœ ๋ฐฑ์—”๋“œ ์ง์ ‘ ์œ„์ž„ ํƒ€์ž„๋ผ์ธ ์‹ค์ธก ๊ฒ€์ฆ. - [x] **P5-02** ํƒ€์ž„์•„์›ƒ ์ฃผ์ž… E2E(`--idle-timeout 30`, ํ”„๋กฌํ”„ํŠธ ๋ฌด์‹œ): ๋ž˜ํผ rc=2, `error`, `wait_for_job` โ‰ค 2s. - *์ฆ๊ฑฐ*: `docs/contracts/issue-6/phase5-e2e.md` ยง3์— ๊ธฐ๋ก ๋ฐ T1-1/T3-1์„ ํ†ตํ•œ ๊ฒ€์ฆ ์™„๊ฒฐ. - [x] **P5-03** ์ž”์กด ๋ ˆ์ฝ”๋“œ `93a44347`, `2961b822`, `ee242671` `registry.py close --request deadline_timeout โ€ฆ --detail "Issue #6 backfill"`๋กœ ํ์‡„. - *์ฆ๊ฑฐ*: `registry.py close` ์‹คํ–‰ํ•˜์—ฌ 3๊ฑด ๋ชจ๋‘ `status: error`, `detail: "Issue #6 backfill"`๋กœ ๋‹จ๋ฐฉํ–ฅ ์ข…๊ฒฐ ์™„๋ฃŒ. - [x] **P5-04** `IMPROVEMENTS.md` ยง5 `Issue-6-FailClosed-TurnHandshake` ๋ธ”๋ก ์ถ”๊ฐ€(ยง6 ํ‘œยทํ—ค๋” ํ‚ค ๋ชฉ๋กยท๊ฑด์ˆ˜ ๋™๊ธฐํ™”). ๋ณ„๋„ ์ด์Šˆ ๋“ฑ๋ก: O-1 ๋ฆฌํ…Œ์ธ ์žฌ์ˆ˜๋ฝ(**loop/discuss ๋ชจ๋“œ ์‚ฌ์šฉ ์ „ ํ•„์ˆ˜**๋กœ ํ‘œ๊ธฐ), ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ์˜ค์—ผ. - *์ฆ๊ฑฐ*: `IMPROVEMENTS.md` ยง5 ์™„๋ฃŒ ๋ธ”๋ก ๋ฐ ํ—ค๋” ์ด 32๊ฑด ์™„๋ฃŒ ๋™๊ธฐํ™” ์™„๋ฃŒ. - [x] **P5-05** `v4.4.1` 4-way ๋ฝ์Šคํ…(`lib.sh:32`, `eager.py:16`, `VERSIONS.md` ๊ฐœ์š”ยท๋งคํŠธ๋ฆญ์ŠคยทChangelog, 8๊ฐœ `SKILL.md`), `test_version_consistency.py` ํ†ต๊ณผ. - *์ฆ๊ฑฐ*: `tests/test_version_consistency.py` 3 passed in 0.19s ํ†ต๊ณผ. - [x] **P5-06** ๋ฆฌ๋ทฐ์–ด ๊ต์ฐจ ๊ฒ€ํ†  `[VERDICT: PASS]` ํ›„ `main` ๋ณ‘ํ•ฉ. - *์ฆ๊ฑฐ*: 4๊ฐœ ๋ฆฌ๋ทฐ์–ด ํŒ€ ๋ฆฌ๋”(Claude, Codex, OpenCode, Grok) 9์ฐจ ์ตœ์ข… ๋งŒ์žฅ์ผ์น˜ `[VERDICT: PASS]` ํš๋“ ์™„๋ฃŒ.