# ๐Ÿ” Review Report โ€” Job cc059645 (`fix/issue-12-8-7` 2ํšŒ์ฐจ @ `ea911d7`) - **Reviewer**: `reviewer-grok-01` (role: reviewer) ยท 2026-09-13 - **๋ฒ”์œ„**: `git log`/`git diff` **`8a09e02...HEAD`** (๋ฃจํ”„ ์ˆ˜์ง‘ diff ๋Š” ๋น„์–ด ์žˆ์Œ) - **HEAD**: `ea911d7` `fix(issue-8,7): harden install_state merge and pin sibling-workspace edge cases` - **1ํšŒ์ฐจ HEAD**: `4176d75` (grok PASS). ์ด๋ฒˆ ์ดˆ์ : `0fedae2` (claude N1) + `ea911d7` (๋น„์ฐจ๋‹จ ๊ถŒ๊ณ ) - **์•ˆ์ „**: ์‹ค์ œ `.mam/jobs` ์— `scrub-secrets` ๋ฏธ์‹คํ–‰. ์‹ค์ œ ํ™ˆ purge ์—†์Œ. ์†Œ์Šค ๋ฌด๋ณ€๊ฒฝ. codex ์„ธ์…˜ ๋ฏธ์ ‘์ด‰. ์ปค๋ฐ‹: `e629cc1` โ†’ `4176d75` โ†’ **`0fedae2`** โ†’ **`ea911d7`**. `git diff --check 8a09e02...HEAD` ํด๋ฆฐ. ## (1) `0fedae2` N1 โ€” scrub-secrets ๊ฐ’ ๊ธฐ์ค€ ์„ ํƒ `_cmd_scrub_secrets` (`registry.py:360`): `"password" in broker` โ†’ `broker.get("password")`. JSON `null`ยท๋นˆ ๋ฌธ์ž์—ดยทํ‚ค ์—†์Œ์€ ๋ชจ๋‘ falsy ๋ผ ๋ชฉ๋ก์—๋„ ์žฌ๊ธฐ๋ก์—๋„ ์•ˆ ๋„ฃ์Œ. ๊ฐ’์ด ์žˆ๋Š” ๋ฌธ์ž์—ด๋งŒ pop ํ›„ `_atomic_write_record`. lock ๋ฒ”์œ„๋Š” ๊ทธ๋Œ€๋กœ ์ „์ฒด ์ˆœํšŒ์ง€๋งŒ **์“ฐ๊ธฐ๋Š” ๋น„๋ฐ€์ด ์žˆ๋Š” ๋ ˆ์ฝ”๋“œ๋งŒ**. `test_scrub_secrets_cli_migrates_a_registry`: dirty(`"leaked-earlier"`) 1๊ฑด๋งŒ dry-run/์‹ค์ œ ๋Œ€์ƒ. `password: null` ๋ ˆ์ฝ”๋“œ๋Š” stdout ์— id ๊ฐ€ ์—†๊ณ  ํŒŒ์ผ ๋ฐ”์ดํŠธ ๋ถˆ๋ณ€. ํ‚ค ์—†๋Š” clean ๋ ˆ์ฝ”๋“œ๋„ ๋ถˆ๋ณ€. `--dry-run` ์€ dirty ํŒŒ์ผ์˜ ์œ ์ถœ ๋ฌธ์ž์—ด์„ ๊ทธ๋Œ€๋กœ ๋‘ . 4176d75 ์—์„œ๋Š” null ํ‚ค๊นŒ์ง€ ์„ธ์–ด `would scrub 2` ๊ฐ€ ๋‚ฌ์„ ํ…Œ์ŠคํŠธ. `_atomic_write_record` ์˜ `_scrub_record_secrets` ๋Š” ์—ฌ์ „ํžˆ ํ‚ค๋งŒ ๋ณด๋ฉด pop โ€” null ํ‚ค๋Š” **๋‹ค์Œ ์ผ๋ฐ˜ ์“ฐ๊ธฐ** ๋•Œ ์ •๋ฆฌ. scrub ๊ฐ€ 901๊ฑด์„ ์žฌ๊ธฐ๋กํ•˜์ง€ ์•Š๋Š” ๋ถ„์—…๊ณผ ๋งž์Œ. ๋ฌธ์„œ: `VERSIONS.md` v4.4.4 ํ•ญ๋ชฉ 2, `registry.md:60-62` ๊ฐ€ โ€œ์ €์žฅ๋œ ๊ฐ’๋งŒ / null ์€ ๋‹ค์Œ ์“ฐ๊ธฐโ€๋กœ ์ •ํ•ฉ. ## (2) `ea911d7` #8 โ€” install_state ๋ณ‘ํ•ฉ ๋ณด๊ฐ• `deploy/update.sh:243-256`: - ๋น„์–ด ์žˆ์ง€ ์•Š๊ณ  ๋งˆ์ง€๋ง‰ ๋ฐ”์ดํŠธ๊ฐ€ ๊ฐœํ–‰์ด ์•„๋‹ˆ๋ฉด (`tail -c1` + `$(โ€ฆ)` ๊ฐ€ trailing newline ์„ ์ง€์šฐ๋Š” ๊ด€์šฉ) `printf '\n'` โ€” ์ฒซ ๋ณ‘ํ•ฉ ํ‚ค๊ฐ€ ๋งˆ์ง€๋ง‰ ์ค„์— ๋ถ™์ง€ ์•Š์Œ. - `case *=*` ๋กœ `=` ์—†๋Š” ์ค„ ๋ฌด์‹œ. - `awk -F= -v k="$key" '$1 == k'` ์ •ํ™• ๋ฌธ์ž์—ด ๋น„๊ต. `grep -q "^${key}="` ์˜ ์ •๊ทœ์‹ ํ•ด์„ ์—†์Œ. - ์‹คํŒจ `restore_on_failure` (`:168-171`) ๋Š” ์„ธ ํŒŒ์ผ `cp -f` ๊ทธ๋Œ€๋กœ. ์„ฑ๊ณต ๊ฒฝ๋กœ๋งŒ ๋ณ€๊ฒฝ. `test_issue8_update_state.py` ์‹ค์ œ installโ†’stale stampsโ†’`update.sh --force` ํ†ต๊ณผ(์•„๋ž˜ ์Šค์œ„ํŠธ). ## (3) `ea911d7` #7 ํ…Œ์ŠคํŠธ 2๊ฑด โ€” ์‹ค์ œ ๊ฒฝ๋กœ `test_idle_pane_in_a_later_workspace_is_reused`: w1=4(overflow) + w2=1 + `state["panes"]` ์— agent ์—†๋Š” `w2:p_idle`. mock `pane list` ๋Š” ์—์ด์ „ํŠธ pane ์— `agent` ๋ฅผ ๋„ฃ๊ณ  extra pane ์€ ์•ˆ ๋„ฃ์œผ๋ฏ€๋กœ, `lib.sh:771` `not p.get('agent')` ๊ฐ€ w2 ์—์„œ idle ์„ ๊ณ ๋ฆ„. split/create ์—†์Œ, `agent start โ€ฆ --pane w2:p_idle`. idle ์šฐ์„ ์ด ๊นจ์ง€๋ฉด w2 split ์œผ๋กœ ์‹คํŒจ. `test_ws_label_rename_targets_only_the_chosen_workspace`: ๊ฐ™์€ 4+1 ์—์„œ `MAM_WS_LABEL=team-b`. `lib.sh:854-856` ์€ ์„ ํƒ๋œ `existing_ws` ์—๋งŒ `workspace rename`. ํ˜ธ์ถœ ๋กœ๊ทธ๊ฐ€ ์ •ํ™•ํžˆ `["workspace", "rename", "w2", "team-b"]` โ€” w1 ์ด๋‚˜ ์ƒ์„ฑ ๊ฒฝ๋กœ `--label` ์ด ์•„๋‹˜. ## (4) 1ํšŒ์ฐจ PASS ํšŒ๊ท€ + ๋ฝ์Šคํ… #12 `to_registry_block` password ์ œ์™ธ, env ๋ณต์›, G6 `_cmd_scrub_secrets` ์˜ˆ์™ธ, `auth_token` ์œ ์ง€. #7 ํ›„๋ณด ์ˆœํšŒยทoverflow `continue`ยท๋‹จ์ผ ws ๋™์น˜. #8 ์„ฑ๊ณต ๊ฒฝ๋กœ version/hashes ๋น„๋ณต์›. ํšŒ๊ท€ ์—†์Œ. `lib.sh`/`eager.py`/8 SKILL.md/VERSIONS.md ๊ฐœ์š”ยท๋งคํŠธ๋ฆญ์Šค / READMEยทBOOTSTRAPยทMESSAGING = **4.4.4**. ๋ฆด๋ฆฌ์Šค ์ปค๋ฐ‹ `4176d75` ์ œ๋ชฉ ์œ ์ง€. `env -u MAM_VERSION` ์•„๋ž˜ `verify_framework_version` ํ†ต๊ณผ. ํ˜„์žฌ ๋ฒ„์ „ ์•ˆ๋‚ด ๋ฌธ์„œ์— ์ž”์—ฌ `4.4.3` ์—†์Œ. Non-blocking (1ํšŒ์ฐจ์™€ ๋™์ผ): ๋ฝ์Šคํ…์ด v4.4.3 ํ’ˆ์งˆ ๋ฌธ์žฅ์„ 24/17 โ†’ 26/19 ๋กœ ๊ณ ์นœ ๊ฒƒ์€ `fae70c1` ์ž‘์—…์ด์ง€ ์ด ๋ฒ ์ด์Šค๊ฐ€ ์•„๋‹˜. v4.4.4 ํ’ˆ์งˆ ๋ถˆ๋ฆฟ์€ ์•„์ง โ€œํ…Œ์ŠคํŠธ 8๊ฐœ/issue7 3๊ฐœโ€ โ€” ์ดํ›„ ํ…Œ์ŠคํŠธ 2๊ฑดยทN1 ๋ณด๊ฐ•์€ changelog ํ•ญ๋ชฉ 2ยท์ฝ”๋“œ์—๋งŒ ๋ฐ˜์˜. ๊ธฐ๋Šฅ ๊ฒฐํ•จ ์•„๋‹˜. ## (5) ํ…Œ์ŠคํŠธ ``` env -u MAM_VERSION .venv/bin/python -m pytest -q \ tests/test_issue7_workspace_packing.py tests/test_issue8_update_state.py \ tests/test_issue12_registry_secrets.py tests/test_issue5_phase1_delegation.py \ tests/test_issue5_phase2a_loop.py tests/test_herdr_shim_contract.py \ tests/test_layout.py tests/test_deploy_layout.py tests/test_loop_cli.py \ tests/test_issue5_phase4_runtime.py tests/test_version_consistency.py ``` **244 passed in 134.54s** (1ํšŒ์ฐจ 242 + #7 ํ…Œ์ŠคํŠธ 2). `bash -n` lib.sh/`update.sh` ํด๋ฆฐ. ์ „์ฒด ์Šค์œ„ํŠธ ๋ฏธ์‹คํ–‰. ## ์ข…ํ•ฉ N1(null password 901๊ฑด ์žฌ๊ธฐ๋ก)์€ ๊ฐ’ ๊ธฐ์ค€์œผ๋กœ ๋‹ซํ˜”๊ณ , install_state ๋ณ‘ํ•ฉ๊ณผ #7 idle/rename ๊ฒฝ๋กœ๊ฐ€ ํ…Œ์ŠคํŠธ๋กœ ๊ณ ์ •๋๋‹ค. 1ํšŒ์ฐจ PASS ํ•ญ๋ชฉ ํšŒ๊ท€ ์—†์Œ. ์„ค๊ณ„ ์žฌ์ž‘์—… ๋ถˆํ•„์š”. [VERDICT: PASS]