# ๐Ÿ” Review Report โ€” Job addfcf70 (PR #38 @ `ed293dc`) - **Reviewer**: `reviewer-grok-01` ยท 2026-09-25 - **๊ฒ€์ฆ ๊ฒฝ๋กœ**: `/var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20260925T055502Z-a37cf1/1` - **identity**: base `7a4a0c2` head `ed293dc` tree `671b0e5` (์ผ์น˜) - **๋ณธ ์ฒดํฌ์•„์›ƒ**: `main` `7a4a0c2` ์œ ์ง€ `git diff --check 7a4a0c2...HEAD` ํด๋ฆฐ. 6์ปค๋ฐ‹. ## NOT PASS ### N1. `cancelled` ์‚ฌ์œ ๋Š” `get_feedback` ์ด ์ฝ์ง€ ์•Š์•„ `NOT-DISPATCHED` ๊ฐ€ ๋˜์ง€ ์•Š๋Š”๋‹ค `registry.py:316-349` `get_feedback` ์€ ๋งˆ์ง€๋ง‰ `completed`/`error` ์˜ detail ๋งŒ ๋Œ๋ ค์ค€๋‹ค. `cancelled` ๋Š” ๋ณด์ง€ ์•Š๋Š”๋‹ค. ๋ž˜ํผ๋Š” ๋ฏธํˆฌ์ž… ์ข…๋ฃŒ๋ฅผ `publish_event --event cancelled --detail target_not_found|session_busy` ๋กœ๋งŒ ๋‚จ๊ธด๋‹ค (`multi-agent-mux-delegate-job` finalize). `runner.py:687-694` `_subjob_state` ๋Š” ๊ทธ reason ์ด `session_busy` / `target_not_found` / `rolled backโ€ฆ` ์ผ ๋•Œ๋งŒ `NOT-DISPATCHED` ๋‹ค. reason ์ด ํ•ญ์ƒ `""` ์ด๋ฏ€๋กœ ํ‘œ๋Š” `cancelled` / `-` ๊ฐ€ ๋œ๋‹ค. `deadline_timeout`ยท`agent_blocked` ๋Š” `error` ์ด๋ฒคํŠธ detail ์ด๋ผ `CLOSED-UNCONFIRMED` ๋Š” ๋งž๋‹ค. ์‚ฌ์œ  ์—†๋Š” `error` ๋„ ๋งž๋‹ค. ๋น ์ง€๋Š” ๊ฒƒ์€ ์ทจ์†Œ ์ชฝ๋ฟ์ด๋‹ค. `test_issue34_job_tree.py` ๋Š” `NOT-DISPATCHED` ๋ฅผ ๋‹จ์–ธํ•˜์ง€ ์•Š๋Š”๋‹ค. **๋Œ€์•ˆ**: `get_feedback` ์ด ๋งˆ์ง€๋ง‰ `cancelled` detail ๋„ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ํ•˜๊ฑฐ๋‚˜, `_subjob_state` ๊ฐ€ `events.log` ์˜ ๋งˆ์ง€๋ง‰ `cancelled` detail ์„ ์ง์ ‘ ์ฝ๊ฒŒ ํ•˜๋ผ. ๊ทธ ๋’ค์— `target_not_found` ์žก์ด ํ‘œ์—์„œ `NOT-DISPATCHED | target_not_found` ์ธ ํ…Œ์ŠคํŠธ๋ฅผ ๋‘˜ ๊ฒƒ. ๋ฆฌ๋ทฐ์–ด ๊ทœ์น™์ด `cancelled` ์ž์ฒด๋„ ์‹คํŒจ๋กœ ๋ณด๊ฒŒ ํ•˜๋ฏ€๋กœ ํŒ์ •์ด ๋’ค์ง‘ํžˆ์ง€๋Š” ์•Š๋Š”๋‹ค. ์‚ฌ์œ (ํˆฌ์ž… ์ „ ์ทจ์†Œ vs ์—์ด์ „ํŠธ ์‹คํŒจ)๋Š” ์‚ฌ๋ผ์ง„๋‹ค. ## ๊ทธ ์™ธ (N1 ๋งŒ ๋ง‰์Œ) **(1)** ์—†๋Š” `--parent-job` ์€ ๋ž˜ํผ์™€ `registry.py register` ๋‘˜ ๋‹ค exit 1. `MAM_JOB_ID` ๊ฐ€ ์ด ๋“ฑ๋ก๋ถ€์— ์—†์œผ๋ฉด ๊ฒฝ๊ณ  ํ›„ ๋ถ€๋ชจ ์—†์Œ. `descendants_of` ๋Š” ํ•œ ๋ฒˆ ์Šค์บ”, `seen` ์œผ๋กœ ์ˆœํ™˜ ์ค‘๋‹จ, `depth` ๋Š” ์กฐํšŒ ๋•Œ 1๋ถ€ํ„ฐ. ํด๋ง๋งˆ๋‹ค ์ „์ฒด ์Šค์บ”์€ ์ˆ˜๋ฐฑ ๊ฑด์—์„œ ๋ถ€๋‹ด์ด ์ž‘๋‹ค. `MAM_JOB_TREE_MAX` ์ดˆ๊ณผยท`MAM_CHILD_WAIT_S` ๋งŒ๋ฃŒ๋Š” ๋Œ€๊ธฐ๋ฅผ ๋ฉˆ์ถ”๊ณ  ๋ฃจํ”„๋Š” ๋ฆฌ๋ทฐ๋กœ ๊ฐ„๋‹ค. ํ‘œ๋Š” ์ƒํ•œ ์—†์ด ์ž์†์„ ๊ทธ๋ฆฌ๋ฏ€๋กœ `OPEN` ์ด ๋‚จ์•„ NOT PASS ๊ทœ์น™์ด ์ ์šฉ๋œ๋‹ค. ๊ธฐ๋‹ค๋ฆฌ๋Š” ์ชฝ์ด ๋” ์œ„ํ—˜ํ•˜๋‹ค. **(2)** ์ฃผ์ž…๋ฌธยทbriefยทcreate `--submit-job` ์ด `--parent-job` ์„ ์ ๋Š”๋‹ค. ์—์ด์ „ํŠธ๊ฐ€ ๋น ๋œจ๋ฆฌ๋ฉด `--wait-open-jobs`(๊ธฐ๋ณธ off)์™€ `[๊ท€์†๋˜์ง€ ์•Š์€ ์—ด๋ฆฐ ์žก]` ์ด ์•ˆ์ „๋ง์ด๋‹ค. ์›๊ฒฉ์€ `MAM_JOB_ID` ๊ฐ€ ์ด ๋“ฑ๋ก๋ถ€์— ์žˆ์„ ๋•Œ๋งŒ ๊ธฐ๋ณธ ๋ถ€๋ชจ. **(3)** `wait_for_job_tree` ๋Š” ์‹คํ–‰(`round_roots = [exec_jid]`), ์ˆ˜์ •ยท์ˆœ์‘(`append` ํ›„)์— ๊ฑธ๋ฆฐ๋‹ค. `MAM_CHILD_WAIT_S` ๊ธฐ๋ณธ 3900 ์€ ๊ทธ ํ˜ธ์ถœ ์‹œ๊ฐ๋ถ€ํ„ฐ. SIGINT/SIGTERM ํ•ธ๋“ค๋Ÿฌ๋Š” `sys.exit` ์ด๋ผ `interrupted` ํด๋ง์€ ๋ณด์กฐ๋‹ค. `wait_for_descendants` ๊ฐ€ False ์—ฌ๋„ `wait_for_job_tree` ๋Š” True ๋ฅผ ๋Œ๋ ค ๋ฆฌ๋ทฐ๋กœ ๋„˜๊ธด๋‹ค(OPEN ์€ ํ‘œ์— ๋‚จ์Œ). **(4)** ์ž์†๋„ stray ๋„ ์—†์œผ๋ฉด `_subjobs_block` ์€ `""`. stray ๋Š” `created_jobs` ๋ฅผ ๋นผ๋ฏ€๋กœ ์ด ๋ฃจํ”„์˜ ๋ฆฌ๋ทฐ์–ด ์žก์€ ์ œ์™ธ๋œ๋‹ค. ๋‹ค๋ฅธ ๋ฃจํ”„์˜ ๋ถ€๋ชจ ์—†๋Š” ์—ด๋ฆฐ ์žก์€ ํ‘œ์‹œ๋œ๋‹ค(๊ธฐ๋ณธ ๋Œ€๊ธฐ๋Š” ์•ˆ ํ•จ). `SUBJOB_RULE` ์€ OPENยทCLOSED-UNCONFIRMEDยท์‹คํŒจ ์‹œ NOT PASS, ๋Œ€์ฒด ์™„๋ฃŒ๋Š” ์˜ˆ์™ธ๋ผ๊ณ  ์ ๋Š”๋‹ค. **(5)** `_fingerprint` ๋Š” `.mam`ยทjobsยท๊ฐ์‚ฌ ๋กœ๊ทธ๊ฐ€ ์†Œ์Šค ์•ˆ์ผ ๋•Œ๋งŒ exclude. ์ ˆ๋Œ€ `DELEGATE_JOB_LOGS_DIR` ์€ ์†Œ์Šค ๋ฐ–์ด๋ผ ๋น„๊ต์— ์•ˆ ๋“ค์–ด๊ฐ„๋‹ค. ๊ฐ€๋“œ๋Š” `subjobs` ๊ฐ€ ๋น„์ง€ ์•Š์„ ๋•Œ๋งŒ(1d4f338). identity ๋ชจ๋“œ(`--worktree`/`--base`)๋Š” `light` ๋ฅผ ์•ˆ ์ผ ๋‹ค. ์Šน๊ฒฉ ์ง์ „ `light` ์žฌํ™•์ธ์ด ์žˆ๋‹ค. `test_e2e_scenario5_multi_agent_review_loop` ํ†ต๊ณผ. **(6)** ๊ฐ™์€ ์„œ๋ฒ„์—์„œ `agent|has-session|kill-session` ์ด๊ณ  `HERDR_PANE_ID` ์˜ ์›Œํฌ์ŠคํŽ˜์ด์Šค๊ฐ€ `HERDR_WORKSPACE_ID` ์™€ ๊ฐ™์„ ๋•Œ๋งŒ ๊ทธ ID ๋ฅผ ๋บ€๋‹ค. ๊ต์ฐจ ์„œ๋ฒ„๋Š” ๊ธฐ์กด์ฒ˜๋Ÿผ ์„ธ ID ๋ฅผ ์ „๋ถ€ ๋บ€๋‹ค. pane ๋ฐ–ยท๋ถˆ์ผ์น˜ IDยท`new-session`/pane ํ˜ธ์ถœ์€ ์œ ์ง€(#7 ํŒจํ‚น). `target_not_found` ๋Š” preflight detailยทcancelled ์ด๋ฒคํŠธ์— ๋“ค์–ด๊ฐ„๋‹ค(ํ‘œ ๋ผ๋ฒจ์€ N1). **(7)** `test_issue34_job_tree.py` ๋Š” ์‹ค์ œ ๋ž˜ํผ `--dry-run`ยทregistryยทpublish. tmp ๋งŒ ์”€. **(8)โ€“(9)** SKILLยทMULTI_AGENT_RULES(ko) ๊ฐ€ `--parent-job`, `MAM_CHILD_WAIT_S`, `--wait-open-jobs`, ํŒ์ • ๊ทœ์น™, stale ๊ฐ€๋“œ๋ฅผ ์ ๋Š”๋‹ค. 4.7.4 bump ๋Š” ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ดํ„ฐ ์˜ˆ์ •. ## ํ…Œ์ŠคํŠธ ๊ฒ€์ฆ ๊ฒฝ๋กœ, `AGENT_PYTHON_BIN` = ์ปจํŠธ๋กค `.venv`, basetemp `/tmp`: `test_issue34_job_tree.py` + `test_issue23_24_startup_path.py` + `test_tier4_e2e.py` + `test_issue5_phase1_delegation.py` + `test_issue21_worktree_prereqs.py` **193 passed in 1429.09s.** N1 ์€ ์ด ์Šค์œ„ํŠธ์— ๋‹จ์–ธ์ด ์—†๋‹ค. [VERDICT: NOT PASS]