# ๐Ÿ” Cross Review โ€” Job 5e43d80f: Layout Engine 2ร—K ๊ตฌํ˜„ - **Reviewer**: `planner-reviewer-claude-01` - **๋Œ€์ƒ**: W1~W5 (`layout.py`, `lib.sh:435`, `.mam.env.example`, ํ…Œ์ŠคํŠธ 3ํŒŒ์ผ) - **๊ฒ€์ฆ**: BSP ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ ์‹คํ–‰ + ํ—ค๋“œ๋ฆฌ์Šค ๊ถค์  ์‹คํ–‰ + **pytest ์ „์ฒด 393๊ฑด ์‹คํ–‰** > **์ดํ•ด์ถฉ๋Œ ๊ณ ์ง€**: ๋ณธ ๊ตฌํ˜„์˜ ์‚ฌ์–‘(`layout_engine_improvement_plan.md` Rev.2)์€ ์ œ๊ฐ€ Planner ๋กœ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜๋Š” **ํƒ€์ธ์ด ์ž‘์„ฑํ•œ ์ฝ”๋“œ๊ฐ€ ๊ทธ ์‚ฌ์–‘์„ ์ถฉ์กฑํ•˜๋Š”๊ฐ€**์— ๋Œ€ํ•œ ๊ฒ€์ฆ์ด๋ฉฐ, ์‚ฌ์–‘ ์ž์ฒด์˜ ํƒ€๋‹น์„ฑ์— ๋Œ€ํ•œ ๋…๋ฆฝ ๊ฒ€์ฆ์ด ์•„๋‹™๋‹ˆ๋‹ค. ยง4 ์˜ F-1 ์€ ์‹ค์ œ๋กœ **์ œ ์‚ฌ์–‘์˜ ๊ฒฐํ•จ**์ด๋ฉฐ ๊ทธ๋ ‡๊ฒŒ ๋ช…์‹œํ•ฉ๋‹ˆ๋‹ค. --- ## 1. ํ•ต์‹ฌ ๋ชฉํ‘œ ๋‹ฌ์„ฑ โ€” ์‹ค์ธก ํ™•์ธ BSP ์„ธ๋ถ„ํ•  ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ๋กœ N=1โ†’5 ๊ถค์ ์„ ์‹คํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค. ``` N=1 [p1 277x78] N=2 split right on p1 (new_column_right) p1 138x78 / p2 139x78 widths=[138,139] heights=[78] balanced=True N=3 split down on p1 (fill_column) p1 138x39 / p3 138x39 / p2 139x78 (์ „์ด ์ƒํƒœ โ€” ์ •์ƒ) N=4 split down on p2 (fill_column) p1 138x39 / p3 138x39 / p2 139x39 / p4 139x39 widths=[138,139] heights=[39] balanced=True โ† ๐ŸŽฏ ๊นจ๋—ํ•œ 2ร—2 N=5 OVERFLOW (grid_capacity_reached) โ†’ ์ƒˆ ์›Œํฌ์ŠคํŽ˜์ด์Šค ``` **4 ์—์ด์ „ํŠธ 2ร—2 ๋ชฉํ‘œ ๋‹ฌ์„ฑ.** Rev.1 ์ด ์ง„๋‹จํ•œ R-1 ์™œ๊ณก(N=4 ์—์„œ widths `{138,139,277}`, heights `{19,20,39}`)์ด ์™„์ „ํžˆ ํ•ด์†Œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ### 1.1 GUI โ†” ํ—ค๋“œ๋ฆฌ์Šค ํŒจ๋ฆฌํ‹ฐ (C-1 ์ฒ˜๋ฐฉ ๊ฒ€์ฆ) ``` headless n=1: right target=p1 reason=new_column_right headless n=2: down target=p1 reason=fill_column headless n=3: down target=p2 reason=fill_column headless n=4: overflow target=p4 reason=grid_capacity_reached ``` GUI ์™€ **๋ฐฉํ–ฅยท์ˆœ์„œ๊ฐ€ ์™„์ „ํžˆ ์ผ์น˜**ํ•˜๋ฉฐ, ํƒ€๊นƒ๋„ `p1 โ†’ p2` ๋กœ **์—ด์„ ๋ฒˆ๊ฐˆ์•„** ๊ฐ‘๋‹ˆ๋‹ค(ยง4.2 `panes[n - max_columns]` ๋ช…์„ธ๋Œ€๋กœ). ํ™€์ง(`n % 2`) ๋กœ์ง์€ ์™„์ „ํžˆ ์ œ๊ฑฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. `creator-grok-01` ์ด ์ œ๊ธฐํ–ˆ๋˜ "n=3 ๊ฐˆ๋ผ์ง"์ด ์›์ฒœ ์ฐจ๋‹จ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. --- ## 2. W1~W5 ํ•ญ๋ชฉ๋ณ„ ๊ฒ€์ฆ | W | ํ•ญ๋ชฉ | ์ƒํƒœ | |---|---|---| | **W1** | ๋‹จ์ผ ๊ฒฐ์ •ํ‘œ ๊ณต์œ  | โœ… `_decide` / `_decide_headless` ๋ถ„๋ฆฌ, `compute_2xk_layout` ์€ ๊ด€์ธกโ†’์œ„์ž„ 2๋‹จ | | **W2** | N=1 โ†’ `right` | โœ… `_full_height_pane` ๊ฒฝ์œ  `new_column_right` | | **W3** | `_full_height_pane` | โœ… `len(col)!=1 โ†’ None`, `area_h<=0` ํด๋ฐฑ, `tol=2` | | **W4** | ์บก 3์ค‘ ๋ฐฐ์„  | โœ… **์ „๋ถ€** โ€” ์•„๋ž˜ ยง2.1 | | **W5** | ํ…Œ์ŠคํŠธ | โœ… ์‚ฌ์–‘์˜ 8๊ฐœ ํ…Œ์ŠคํŠธ ์ „๊ฑด ๊ตฌํ˜„ | ### 2.1 W4 โ€” Rev.2 ๊ฐ€ ์ง€์ ํ•œ ์ด์ค‘ ๋ˆ„๋ฝ์ด ๋ชจ๋‘ ํ•ด์†Œ๋จ ```python # layout.py:235-236 โ† _env_int ์— default ๋ถ€์—ฌ (์ด์ „์—” None ๋ฐ˜ํ™˜) --max-cols default=_env_int("MAM_MAX_COLS", "MAM_MAX_PANE_COLS", default=2) --max-rows default=_env_int("MAM_MAX_ROWS", "MAM_MAX_PANE_ROWS", default=2) ``` ```bash # lib.sh:435 โ† ์ด์ „์—” --max-cols ๋ฅผ ์•„์˜ˆ ๋„˜๊ธฐ์ง€ ์•Š์•˜์Œ --max-cols "${MAM_MAX_PANE_COLS:-2}" --max-rows "${MAM_MAX_PANE_ROWS:-2}" ``` ``` # .mam.env.example:147-153 โ† C-5 ๋ฌธ์„œ ์ž์ฒด ๋ถˆ์ผ์น˜("unset -> no cap" vs "=3")๋„ ์ •์ • #default: 2 / MAM_MAX_PANE_COLS=2 + MAM_MAX_PANE_ROWS=2 ์‹ ๊ทœ ๋ธ”๋ก ``` ์ถ”๊ฐ€๋กœ `compute_2xk_layout` ์ง„์ž…๋ถ€์— `max_columns is None โ†’ 2` ๋ฐฉ์–ด๊ฐ€ ๋“ค์–ด๊ฐ€ **๋„ค ๋ฒˆ์งธ ๊ฒฝ๋กœ**๊นŒ์ง€ ๋ง‰์•˜์Šต๋‹ˆ๋‹ค. ์‚ฌ์–‘๋ณด๋‹ค ๊ฒฌ๊ณ ํ•ฉ๋‹ˆ๋‹ค. `test_max_cols_default_reaches_cli_path` ์™€ `test_lib_sh_passes_max_cols_and_rows` ๊ฐ€ ์ด ๋ฐฐ์„ ์„ ๊ณ„์•ฝ์œผ๋กœ ๊ณ ์ •ํ•ฉ๋‹ˆ๋‹ค โ€” Rev.2 ๊ฐ€ "์ด๊ฒŒ ์—†์œผ๋ฉด ์ „์ฒด๊ฐ€ ํ”„๋กœ๋•์…˜์—์„œ ๋ฌดํšจ"๋ผ๊ณ  ๊ฒฝ๊ณ ํ•œ ์ง€์ ์ด๋ผ ํŠนํžˆ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ### 2.2 ๊ธฐ์กด ํ…Œ์ŠคํŠธ ๊ฐฑ์‹  ์ฒ˜๋ฆฌ | ํ…Œ์ŠคํŠธ | ์ฒ˜๋ฆฌ | |---|---| | `test_1_pane_split_down` โ†’ `test_1_pane_split_right` | โœ… ๊ฐœ๋ช… + ๊ณ„์•ฝ ๊ฐฑ์‹  | | `test_2_panes_to_3_panes_new_column_right` โ†’ `test_2_panes_fill_left_column_down` | โœ… | | `test_4_panes_to_5_panes_new_column` โ†’ `..._overflows_at_capacity` | โœ… | | `test_headless_max_columns_growth_guard` | โœ… ์˜› ํ™€์ง ๋‹จ์–ธ(`n=2โ†’right`, `headless_odd_down`) ์ „๋ฉด ์žฌ์ž‘์„ฑ | | `test_b19_headless_layout_does_not_overflow` | โœ… tall ์ผ€์ด์Šค ์žฌํ•ด์„ + **wide-tall ์ผ€์ด์Šค ์‹ ์„ค๋กœ ์ปค๋ฒ„๋ฆฌ์ง€ ๋ณด์กด** | `test_b19` ์ฒ˜๋ฆฌ๊ฐ€ ํŠนํžˆ ์ข‹์Šต๋‹ˆ๋‹ค โ€” ๋‹จ์–ธ๋งŒ ๋’ค์ง‘์ง€ ์•Š๊ณ  ๋น„์˜ค๋ฒ„ํ”Œ๋กœ ๊ฒฝ๋กœ๋ฅผ ๊ฒ€์ฆํ•˜๋Š” ์ƒˆ ํ”ฝ์Šค์ฒ˜๋ฅผ ์ถ”๊ฐ€ํ•ด ์ปค๋ฒ„๋ฆฌ์ง€๋ฅผ ์œ ์ง€ํ–ˆ์Šต๋‹ˆ๋‹ค. ### 2.3 ํ…Œ์ŠคํŠธ ์‹คํ–‰ ``` pytest tests/ -q โ†’ 393 passed in 511.60s ``` **์‹คํŒจ 0๊ฑด.** (์ง์ „ ๋ฆฌ๋ทฐ์—์„œ ๊ด€์ธก๋œ `test_d23` nats ํƒœ๊ทธ ๋ถˆ์ผ์น˜๋„ ํ•ด์†Œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.) --- ## 3. ๐ŸŸก F-2 โ€” `MAX_*=0` ์ด "๋ฌด์ œํ•œ"์ด ์•„๋‹ˆ๋ผ "์ „๋ฉด ์ฐจ๋‹จ"์ž…๋‹ˆ๋‹ค `_env_int` ๋Š” J-1 ๊ณ„์•ฝ์— ๋”ฐ๋ผ ๋ช…์‹œ์  `0` ์„ ๋ณด์กดํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ๊ฒฐ๊ณผ: | ์„ค์ • | ์‹ค์ธก ๊ฒฐ๊ณผ | |---|---| | `max_columns=0, max_rows=2` | `down / fill_column` | | `max_columns=2, max_rows=0` | `right` โ†’ ์ดํ›„ `overflow` | | `max_columns=0, max_rows=0` | **`overflow / grid_capacity_reached` (์ฆ‰์‹œ)** | | ํ—ค๋“œ๋ฆฌ์Šค, ๋‘˜ ์ค‘ ํ•˜๋‚˜๋ผ๋„ 0 | `n >= 0` ์ด ํ•ญ์ƒ ์ฐธ โ†’ **์˜๊ตฌ overflow** | ๋ฌธ์ œ๋Š” **๊ฐ™์€ ์„ค์ • ํŒŒ์ผ ์•ˆ์˜ ์˜๋ฏธ ์ถฉ๋Œ**์ž…๋‹ˆ๋‹ค: ``` # .mam.env.example # MAM_MIN_PANE_ROWS=0 โ† "Set to 0 to disable vertical row constraints" # MAM_MAX_PANE_ROWS=2 โ† 0 ์„ ๋„ฃ์œผ๋ฉด "์šฉ๋Ÿ‰ 0" = ๋ชจ๋“  ์„ธ์…˜์ด ์ƒˆ ์›Œํฌ์ŠคํŽ˜์ด์Šค ``` `MIN_*=0` ์ด "์ œ์•ฝ ํ•ด์ œ"๋ฅผ ๋œปํ•˜๋ฏ€๋กœ, ์šด์˜์ž๊ฐ€ `MAX_*=0` ์„ "์ƒํ•œ ์—†์Œ"์œผ๋กœ ์ฝ๋Š” ๊ฒƒ์€ ์ž์—ฐ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์‹ค์ œ๋กœ๋Š” **์—์ด์ „ํŠธ๋งˆ๋‹ค ์›Œํฌ์ŠคํŽ˜์ด์Šค๊ฐ€ ๋ฌดํ•œ ์ƒ์„ฑ**๋ฉ๋‹ˆ๋‹ค. **๊ฐœ์„  ๋ฐฉํ–ฅ**: ```python if max_columns is None or max_columns <= 0: max_columns = 2 # ๋˜๋Š” '๋ฌด์ œํ•œ' ์˜๋„๋ผ๋ฉด sys.maxsize if max_rows is None or max_rows <= 0: max_rows = 2 ``` `.mam.env.example` ์—๋„ `0 ์€ ํ—ˆ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค(์ตœ์†Ÿ๊ฐ’ 1)` ํ•œ ์ค„์„ ๋ง๋ถ™์ด์‹ญ์‹œ์˜ค. ๋น„์ฐจ๋‹จ์ด๋‚˜ ์˜ค์„ค์ • ์‹œ ํ”ผํ•ด๊ฐ€ ํฌ๊ณ  ๋˜๋Œ๋ฆฌ๊ธฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค(์ƒ์„ฑ๋œ ์›Œํฌ์ŠคํŽ˜์ด์Šค๊ฐ€ ๋‚จ์Œ). --- ## 4. ๐ŸŸ  F-1 โ€” ์„ธ๋กœ ์ „์šฉ ์ ์ธต ๋Šฅ๋ ฅ์ด ์‚ฌ๋ผ์กŒ์Šต๋‹ˆ๋‹ค (**์ œ ์‚ฌ์–‘์˜ ๊ฒฐํ•จ**) ### ํ˜„์ƒ (์‹ค์ธก) `min_cols=60` ์—์„œ ๋‹จ์ผ ํŽ˜์ธ ํญ๋ณ„ ๊ฒฐ์ •: | ํญ ร— ๋†’์ด | ๊ฒฐ๊ณผ | |---|---| | 80ร—60 | `overflow / column_width_overflow` | | 100ร—60 | `overflow` | | 119ร—60 | `overflow` | | 120ร—60 | `right` | **ํญ 120 ๋ฏธ๋งŒ์ด๋ฉด N=1 ์—์„œ ์ฆ‰์‹œ ์˜ค๋ฒ„ํ”Œ๋กœ**ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ 80ร—60 ์„ ์„ธ๋กœ๋กœ ์Œ“์œผ๋ฉด `80ร—30` ํŽ˜์ธ 2๊ฐœ๊ฐ€ ๋˜๊ณ , **๋‘ ํŽ˜์ธ ๋ชจ๋‘ ํญ 80 โ‰ฅ min_cols 60 ์„ ๋งŒ์กฑ**ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰ **์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ฐฐ์น˜๋ฅผ ๊ฑฐ๋ถ€ํ•˜๊ณ  ์ƒˆ ์›Œํฌ์ŠคํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.** ### ์›์ธ โ€” ํญ ๊ฒŒ์ดํŠธ๊ฐ€ ํด์Šค๋ฃจํ•˜์ง€ ์•Š์Œ ```python if len(cols) < max_columns: fh = _full_height_pane(cols[-1], area_h) if fh is not None: if fh.width > 0 and fh.width // 2 < min_cols: return _overflow("column_width_overflow", fh) # โ† ์ฆ‰์‹œ ๋ฐ˜ํ™˜ return _right("new_column_right", fh) # โ‘ก ์„ธ๋กœ ์ฑ„์šฐ๊ธฐ์— ๋„๋‹ฌํ•˜์ง€ ๋ชปํ•จ ``` ์ƒˆ ์—”์ง„์€ **1์—ด ร— Kํ–‰ ๋ฐฐ์น˜๋ฅผ ๊ตฌ์กฐ์ ์œผ๋กœ ๋งŒ๋“ค ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.** ๊ตฌ ์—”์ง„์˜ `single_pane_split_down` ์ด ๋‹ด๋‹นํ•˜๋˜ ๊ฒฝ๋กœ๊ฐ€ ์‚ฌ๋ผ์กŒ์Šต๋‹ˆ๋‹ค. ### ์ฑ…์ž„ ์†Œ์žฌ **์ด๊ฒƒ์€ ๊ตฌํ˜„ ๊ฒฐํ•จ์ด ์•„๋‹ˆ๋ผ ์ œ ์‚ฌ์–‘์˜ ๊ฒฐํ•จ์ž…๋‹ˆ๋‹ค.** Rev.2 ยง4.1 ์˜์‚ฌ์ฝ”๋“œ๊ฐ€ ์ •ํ™•ํžˆ `return OVERFLOW("column_width_overflow", fh)` ๋กœ ์ ํ˜€ ์žˆ์—ˆ๊ณ , ๊ตฌํ˜„์€ ๊ทธ๋Œ€๋กœ ๋”ฐ๋ž์Šต๋‹ˆ๋‹ค. ํญ ๋ถ€์กฑ ์‹œ ์„ธ๋กœ ํด๋ฐฑ์„ ๋ช…์‹œํ•˜์ง€ ์•Š์€ ๊ฒƒ์€ ์ œ ๋ˆ„๋ฝ์ž…๋‹ˆ๋‹ค. ### ์‹ค๋ฌด ์˜ํ–ฅ ๊ธฐ๋ณธ๊ฐ’ `min_cols=15` ์—์„œ๋Š” ํญ 30 ๋ฏธ๋งŒ์ด์–ด์•ผ ๋ฐœ๋™ํ•˜๋ฏ€๋กœ **์‚ฌ์‹ค์ƒ ๋„๋‹ฌ ๋ถˆ๊ฐ€**ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋งŒ `MAM_MIN_PANE_COLS` ๊ธฐ๋ณธ๊ฐ’์€ 60 โ†’ 40 โ†’ 15 ๋กœ ๋ณ€ํ•ด ์™”๊ณ , `.mam.env` ๋Š” **gitignore ๋Œ€์ƒ์ด๋ผ ์ž๋™ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.** ๊ตฌ ์„ค์ •(`=60`)์„ ์ง€๋‹Œ ๊ธฐ์กด ์„ค์น˜๋Š” 120์นธ ๋ฏธ๋งŒ ํ„ฐ๋ฏธ๋„์—์„œ **์—์ด์ „ํŠธ๋งˆ๋‹ค ์›Œํฌ์ŠคํŽ˜์ด์Šค๊ฐ€ ํ•˜๋‚˜์”ฉ** ์ƒ๊ธฐ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ### ๊ฐœ์„  ๋ฐฉํ–ฅ (๊ตฌ์ฒด) ํญ ๊ฒŒ์ดํŠธ๋ฅผ **ํด์Šค๋ฃจ**๋กœ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค: ```python if len(cols) < max_columns: fh = _full_height_pane(cols[-1], area_h) if fh is not None and not (fh.width > 0 and fh.width // 2 < min_cols): return _right("new_column_right", fh) # ํญ์ด ์ƒˆ ์—ด์„ ๊ฐ๋‹นํ•˜์ง€ ๋ชปํ•˜๋ฉด โ‘ก(์„ธ๋กœ ์ฑ„์šฐ๊ธฐ)๋กœ ๋‚ด๋ ค๊ฐ„๋‹ค ``` ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด 80ร—60/min_cols=60 ์€ `down / fill_column` โ†’ `80ร—30` 2๊ฐœ๊ฐ€ ๋˜๊ณ , ํญยทํ–‰์ด ๋ชจ๋‘ ์†Œ์ง„๋œ ๋’ค์—์•ผ โ‘ข์—์„œ ์˜ค๋ฒ„ํ”Œ๋กœํ•ฉ๋‹ˆ๋‹ค. ํšŒ๊ท€ ๊ฐ€๋“œ: ```python def test_narrow_terminal_falls_back_to_vertical_stacking(): d = compute_2xk_layout(_one(80, 60), min_cols=60) assert d.direction == "down" and not d.is_overflow ``` **์ฃผ์˜**: ์ด ๋ณ€๊ฒฝ์€ `test_b19` ์˜ tall ์ผ€์ด์Šค ๋‹จ์–ธ์„ ๋‹ค์‹œ ๋’ค์ง‘์Šต๋‹ˆ๋‹ค(ํ˜„์žฌ `overflow` โ†’ `down`). ์›๋ž˜ ๊ทธ ํ…Œ์ŠคํŠธ๊ฐ€ ์ง€ํ‚ค๋˜ ๊ณ„์•ฝ์ด ๋ฐ”๋กœ ์ด ์„ธ๋กœ ํด๋ฐฑ์ด์—ˆ์œผ๋ฏ€๋กœ, ์‚ฌ์‹ค์ƒ **์›๋ณต**์ž…๋‹ˆ๋‹ค. --- ## 5. ํŒ์ • | ํ•ญ๋ชฉ | ํŒ์ • | |---|---| | W1~W5 ์‚ฌ์–‘ ์ถฉ์กฑ | โœ… ์ „๊ฑด. W4 ๋Š” ์‚ฌ์–‘๋ณด๋‹ค ๊ฒฌ๊ณ  | | 4 ์—์ด์ „ํŠธ 2ร—2 | โœ… ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ ์‹ค์ธก | | GUI/ํ—ค๋“œ๋ฆฌ์Šค ํŒจ๋ฆฌํ‹ฐ | โœ… ๋ฐฉํ–ฅยทํƒ€๊นƒ ๋ชจ๋‘ ์ผ์น˜ | | ์ „์ฒด ํ…Œ์ŠคํŠธ | โœ… **393 passed, 0 failed** | | F-1 ์„ธ๋กœ ํด๋ฐฑ ์ƒ์‹ค | ๐ŸŸ  **์ œ ์‚ฌ์–‘ ๋ˆ„๋ฝ** โ€” ํ›„์† ์ˆ˜์ • | | F-2 `MAX_*=0` ํ•จ์ • | ๐ŸŸก ํ›„์† ์ˆ˜์ • | ๊ตฌํ˜„์€ ์Šน์ธ๋œ ์‚ฌ์–‘์„ **์ •ํ™•ํžˆ, ๊ทธ๋ฆฌ๊ณ  ์ผ๋ถ€๋Š” ๋” ๊ฒฌ๊ณ ํ•˜๊ฒŒ** ์ถฉ์กฑํ–ˆ์œผ๋ฉฐ ํ•ต์‹ฌ ๋ชฉํ‘œ๊ฐ€ ์‹ค์ธก์œผ๋กœ ์ฆ๋ช…๋˜์—ˆ์Šต๋‹ˆ๋‹ค. F-1ยทF-2 ๋Š” ์ด๋ฒˆ ๋ณ€๊ฒฝ์ด ๋งŒ๋“  ์ƒˆ ๊ฒฐํ•จ์ด ์•„๋‹ˆ๋ผ **์‚ฌ์–‘์˜ ๋ฏธ๋น„**๋กœ, ๊ฐ๊ฐ 3~5์ค„ ์ˆ˜์ •์œผ๋กœ ํ•ด์†Œ๋ฉ๋‹ˆ๋‹ค. ์„ค๊ณ„ ์žฌ์ž‘์—… ์‚ฌ์œ ๊ฐ€ ์•„๋‹ˆ๋ฏ€๋กœ `[ESCALATE: PLANNER]` ๋Š” ๋ถ€์—ฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. **ํ›„์† ์žก ๊ถŒ๊ณ **: F-1(์„ธ๋กœ ํด๋ฐฑ) + F-2(0 ๊ฐ’ ํด๋žจํ”„) ๋ฅผ ๋ฌถ์–ด ํ•œ ์ปค๋ฐ‹์œผ๋กœ. F-1 ์€ ๊ตฌ `.mam.env` ๋ฅผ ์ง€๋‹Œ ๊ธฐ์กด ์„ค์น˜์— ์‹ค์ œ ์˜ํ–ฅ์ด ์žˆ์œผ๋ฏ€๋กœ ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์Šต๋‹ˆ๋‹ค. [VERDICT: PASS]