diff --git a/.agents/INSTALL.md b/.agents/INSTALL.md new file mode 100644 index 0000000..d75c6fb --- /dev/null +++ b/.agents/INSTALL.md @@ -0,0 +1,123 @@ +# ๐Ÿ› ๏ธ Multi-Agent Mux (MAM) ์„ค์น˜ ๋ฐ ์ ์šฉ ๊ฐ€์ด๋“œ + +MAM์€ ๋‹จ์ผ ์›Œํฌ์ŠคํŽ˜์ด์Šค ์ƒ์—์„œ ๋ณต์ˆ˜์˜ ์—์ด์ „ํŠธ(Claude, Cline, Agy, Hermes ๋“ฑ)๋“ค์ด ์„œ๋กœ์˜ ์ƒํƒœ๋ฅผ ์˜ค์—ผ์‹œํ‚ค์ง€ ์•Š๊ณ  ํ˜‘์—…ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ”„๋กœ์„ธ์Šค ๊ฒฉ๋ฆฌ ๋ฐ ๋ผ์ดํ”„์‚ฌ์ดํด ๊ด€๋ฆฌ๋ฅผ ์ œ๊ณตํ•˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค. + +์ด ๊ฐ€์ด๋“œ๋Š” ๊ธฐ์กด์˜ ๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ/๋ ˆํฌ์ง€ํ† ๋ฆฌ์— MAM์„ ์‹ ์†ํ•˜๊ฒŒ ๋„์ž…ํ•˜๊ณ  ์ ์šฉํ•˜๋Š” ์ ˆ์ฐจ๋ฅผ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. + +--- + +## 1. โš™๏ธ ์‚ฌ์ „ ์š”๊ตฌ์‚ฌํ•ญ +MAM ์Šคํ‚ฌ ๋ฐ ์Šคํฌ๋ฆฝํŠธ๋“ค์€ ํ˜ธ์ŠคํŠธ ์‹œ์Šคํ…œ์˜ ๋‹ค์Œ ๋„๊ตฌ๋“ค์— ์˜์กดํ•ฉ๋‹ˆ๋‹ค. ์„ค์น˜ ์ „์— ํ™•์ธํ•ด ์ฃผ์„ธ์š”. +* **herdr**: ์—์ด์ „ํŠธ๋ฅผ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๊ฒฉ๋ฆฌ Pane/Workspace์—์„œ ๊ตฌ๋™ ๋ฐ ๊ด€์ œํ•˜๊ธฐ ์œ„ํ•œ ํ”„๋กœ์„ธ์Šค ์ปจํ…Œ์ด๋„ˆ +* **python3**: ์„ธ์…˜ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ(YAML/SQLite DB) ํŒŒ์‹ฑ ๋ฐ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ (๋‚ด์žฅ `sqlite3` ๋ชจ๋“ˆ ํ•„์ˆ˜) +* **uuidgen**: ๊ฒฉ๋ฆฌ ์„ธ์…˜ ์ƒ์„ฑ ์‹œ ๊ณ ์œ ์˜ UUID ํ• ๋‹น +* **rsync**: ์ธ์Šคํ†จ๋Ÿฌ(`deploy/install_mam.sh`)๊ฐ€ `.agents/` ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ดํ„ฐ ๋ฐ ์Šคํ‚ฌ ํด๋”๋ฅผ ํƒ€๊ฒŸ ํ”„๋กœ์ ํŠธ์— ๋ณต์ œํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ (์„ค์น˜ ์‹œ ํ•„์š”) +* **python3-yaml (pyyaml)**: ์„ธ์…˜ ๋ฐ์ดํ„ฐ YAML ์ €์žฅ ๋ฐ ๋กœ๋“œ ์˜์กด์„ฑ (`pip install pyyaml`) + +--- + +## 2. ๐Ÿš€ ์ž๋™ ์„ค์น˜ ๋ฐฉ๋ฒ• + +MAM์˜ ์ž๋™ ์„ค์น˜ ์Šคํฌ๋ฆฝํŠธ(`deploy/install_mam.sh`)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ 10์ดˆ ๋งŒ์— ํ•„์š”ํ•œ ๊ทœ์น™๊ณผ ๋ผ์ดํ”„์‚ฌ์ดํด ํˆดํ‚ท์„ ํƒ€๊ฒŸ ํ”„๋กœ์ ํŠธ์— ์ด์‹ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์Šคํฌ๋ฆฝํŠธ๋Š” ์‹คํ–‰ ์‹œ ์ž๋™์œผ๋กœ ์‹œ์Šคํ…œ์˜ `tmux`, `python3`, `rsync`, `uuidgen` ๋ฐ ํ•„์ˆ˜ ํŒŒ์ด์ฌ ๋ชจ๋“ˆ๋“ค์„ ์ง„๋‹จํ•ฉ๋‹ˆ๋‹ค. + +> [!IMPORTANT] +> **์„ค์น˜ ์ „์ œ์กฐ๊ฑด**: MAM ์Šคํ‚ฌ์„ ํƒ€๊ฒŸ ํ”„๋กœ์ ํŠธ์— ์„ค์น˜ํ•˜๋ ค๋ฉด **๋จผ์ € MAM ๋ ˆํฌ์ง€ํ† ๋ฆฌ๊ฐ€ ๋กœ์ปฌ ๋จธ์‹ ์— clone ๋˜์–ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.** + +### ์„ค์น˜ ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰ +MAM ๋ ˆํฌ์ง€ํ† ๋ฆฌ ๋ฃจํŠธ ๋””๋ ‰ํ† ๋ฆฌ๋กœ ์ด๋™ํ•œ ํ›„ ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. +```bash +# ๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ• (ํƒ€๊ฒŸ ํ”„๋กœ์ ํŠธ ๊ฒฝ๋กœ ์ง€์ •) +$ bash deploy/install_mam.sh --target /path/to/your/project + +# ๋งŒ์•ฝ ์ด๋ฏธ ํƒ€๊ฒŸ์— AGENTS.md ๊ฐ€ ์กด์žฌํ•˜์—ฌ ๊ฐ•์ œ๋กœ ๋ฎ์–ด์“ฐ๊ณ  ์‹ถ๋‹ค๋ฉด: +$ bash deploy/install_mam.sh --target /path/to/your/project --force +``` + +### ์„ค์น˜ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ˆ˜ํ–‰ํ•˜๋Š” ์ž‘์—…: +1. **์˜์กด์„ฑ ์ง„๋‹จ**: ์‹œ์Šคํ…œ์— `tmux`, `python3`, `rsync`, `uuidgen` CLI ๋ฐ”์ด๋„ˆ๋ฆฌ์™€ ํŒŒ์ด์ฌ `pyyaml`/`sqlite3` ๋ชจ๋“ˆ์ด ์„ค์น˜๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. +2. **๊ทœ์น™ ๋ฐ ์Šคํ‚ฌ ๋ณต์ œ**: ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜ ๊ฐ€์ด๋“œ(`.agents/` ํ•˜์œ„ ์ „์ฒด)๋ฅผ ํƒ€๊ฒŸ ํ”„๋กœ์ ํŠธ ํ•˜์œ„๋กœ ์ด์‹ํ•ฉ๋‹ˆ๋‹ค. +3. **์ง€์นจ ์ „ํŒŒ**: ์—์ด์ „ํŠธ๊ฐ€ ๋กœ๋“œํ•˜๊ณ  ๋ณต์ข…ํ•  ํ–‰๋™ ์ง€์นจ ๋ฌธ์„œ(`AGENTS.md`)๋ฅผ ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ์— ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค. +4. **ํ˜•์ƒ ์ œ์™ธ ์„ค์ •**: ์„ธ์…˜ DB ๋ฐ ๊ฒฉ๋ฆฌ ์บ์‹œ ์ €์žฅ์†Œ์ธ `.mam/` ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ํƒ€๊ฒŸ ํ”„๋กœ์ ํŠธ์˜ `.gitignore` ์— ์ž๋™ ์ฃผ์ž…ํ•˜์—ฌ ๋ถˆํ•„์š”ํ•œ ํ˜•์ƒ ๊ด€๋ฆฌ๋ฅผ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค. + +--- + +## 3. ๐ŸŽฏ ํ•ต์‹ฌ ์‚ฌ์šฉ ์›Œํฌํ”Œ๋กœ์šฐ (Quick Start) + +์„ค์น˜๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด, ํƒ€๊ฒŸ ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ์—์„œ ์—์ด์ „ํŠธ๋“ค์„ ๊ธฐ๋™ ๋ฐ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +### 1) ์—์ด์ „ํŠธ ๊ฒฉ๋ฆฌ ์„ธ์…˜ ์ƒ์„ฑ (Create) +์ƒˆ๋กœ์šด ์—์ด์ „ํŠธ๋ฅผ ๋…๋ฆฝ๋œ ๊ฒฉ๋ฆฌ ๊ฐ€์ƒ ๋””๋ ‰ํ† ๋ฆฌ์—์„œ ๋„์›๋‹ˆ๋‹ค. +```bash +$ bash .agents/skills/multi-agent-mux-create/scripts/create_session.sh \ + --workspace "/path/to/your/project" \ + --agent claude \ + --role developer \ + --session my-project-dev-claude \ + --isolate \ + --herdr-workspace multi-agent-mux +``` +* `--isolate` ์˜ต์…˜์„ ์ฃผ๋ฉด `.mam/agent_homes//` ํ•˜์œ„์— ๋กœ๊ทธ์ธ ๋ฐ ์„ค์ •์€ ์œ ์ง€ํ•˜๋˜ ๋Œ€ํ™” ๋‚ด์—ญ์€ ๊ฒฉ๋ฆฌ๋˜๋Š” ํ™ˆ์ด ํ˜•์„ฑ๋ฉ๋‹ˆ๋‹ค. + +### 2) ์„ธ์…˜ ์ ‘์† (Attach) +๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ๊ตฌ๋™๋œ ์—์ด์ „ํŠธ TUI ํ™”๋ฉด์— ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค. +```bash +$ herdr session attach my-project-dev-claude +``` +* **ํ™”๋ฉด ํƒˆ์ถœ**: ๋Œ€ํ™” ์ค‘ ์„ธ์…˜์„ ์œ ์ง€ํ•œ ์ฑ„ ํ„ฐ๋ฏธ๋„๋กœ ๋Œ์•„์˜ค๋ ค๋ฉด `Ctrl + B`๋ฅผ ๋ˆ„๋ฅธ ๋’ค `D` ํ‚ค๋ฅผ ์ฐจ๋ก€๋กœ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค. + +### 3) ์—์ด์ „ํŠธ ์ƒํƒœ ๋ณต์› (Resume) +์„ธ์…˜์ด ์ค‘์ง€๋˜์—ˆ๊ฑฐ๋‚˜, ํ˜ธ์ŠคํŠธ ์žฌ๊ธฐ๋™์œผ๋กœ tmux๊ฐ€ ์†Œ๋ฉธํ•œ ๊ฒฝ์šฐ์—๋„ ์ด์ „ ๋Œ€ํ™” ID ๋ฐ ๊ฒฉ๋ฆฌ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์›์ž์ ์œผ๋กœ ์ด์–ด๋ฐ›์•„ ๋‹ค์‹œ ๊ธฐ๋™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +```bash +# 1๋‹จ๊ณ„: ๋ณต์› ๋Œ€์ƒ ์„ธ์…˜์˜ UUID ์ž๋™ ์กฐํšŒ (DB/YAML ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ๊ธฐ๋ฐ˜) +$ WORKSPACE="/path/to/your/project" +$ AGENT="claude" +$ SESSION_NAME="my-project-dev-claude" + +$ UUID=$(bash .agents/skills/multi-agent-mux-resume/scripts/resolve_session_id.sh \ + --workspace "$WORKSPACE" --agent "$AGENT" --session "$SESSION_NAME") + +# ๋ณต์› ๋Œ€์ƒ ์„ธ์…˜์˜ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ (M-1) +$ [ -n "$UUID" ] || { echo "[ERROR] ๋งค์นญ๋˜๋Š” ํ™œ์„ฑ ์„ธ์…˜ ์ด๋ ฅ์ด ์—†์Šต๋‹ˆ๋‹ค. create_session.sh๋ฅผ ํ†ตํ•ด ๋จผ์ € ์„ธ์…˜์„ ์ƒ์„ฑํ•ด ์ฃผ์„ธ์š”."; exit 1; } + +# 2๋‹จ๊ณ„: ์„ธ์…˜ ์žฌ๊ธฐ๋™ (์ด์ „ ๋Œ€ํ™” ์ปจํ…์ŠคํŠธ ๋ณต์› ๊ธฐ๋™) +# (์ฃผ์˜: ๋งŒ์•ฝ create ์‹œ ๊ฒฉ๋ฆฌ(--isolate) ์„ธ์…˜์œผ๋กœ ์ƒ์„ฑํ–ˆ๋‹ค๋ฉด, CLAUDE_CONFIG_DIR ํ™˜๊ฒฝ๋ณ€์ˆ˜๋ฅผ YAML์— ๊ธฐ๋ก๋œ isolation.root ๊ฒฝ๋กœ๋กœ ์ง€์ •ํ•˜์—ฌ ๋„์›Œ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ƒ์„ธ ๊ฒฉ๋ฆฌ ๋ณต์› ์ปค๋งจ๋“œ๋Š” .agents/skills/multi-agent-mux-resume/SKILL.md ๋ฌธ์„œ๋ฅผ ํ•„๋…ํ•ด ์ฃผ์„ธ์š”.) +$ herdr run -d --name "$SESSION_NAME" --workspace "$WORKSPACE" -- \ + "claude --dangerously-skip-permissions -r $UUID" + +# 3๋‹จ๊ณ„: ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ์„ธ์…˜ ์ƒํƒœ๋ฅผ running ์œผ๋กœ ๋™๊ธฐํ™” ๊ฐฑ์‹  +$ bash .agents/skills/multi-agent-mux-resume/scripts/update_yaml_resumed.sh \ + --session "$SESSION_NAME" --uuid "$UUID" --agent "$AGENT" +``` + +### 4) ์„ธ์…˜ ์ข…๋ฃŒ ๋ฐ ์ •๋ฆฌ (Stop / Purge) +์„ธ์…˜์„ ์ •์ง€์‹œํ‚ค๊ณ  ๋Œ€ํ™” ์ปจํ…์ŠคํŠธ๋ฅผ ๋™๊ฒฐํ•˜๊ฑฐ๋‚˜(default), ์™„์ „ํžˆ ์†Œ๋ฉธ์‹œํ‚ต๋‹ˆ๋‹ค(`--purge-conversation`). +```bash +# ๋Œ€ํ™” ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ๋ฐฑ์—… ๋ฐ ์˜์†ํ™”ํ•˜๊ณ , ์•ˆ์ „ํ•˜๊ฒŒ ์ข…๋ฃŒ (status=stopped) +$ bash .agents/skills/multi-agent-mux-stop/scripts/stop_session.sh \ + --session my-project-dev-claude --agent claude + +# ๋Œ€ํ™” ๋‚ด์šฉ ๋ฐ ๊ฒฉ๋ฆฌ ํ™ˆ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์™„์ „ํžˆ ์ฒญ์†Œํ•˜๊ณ  ์ข…๋ฃŒ (status=terminated, resumable=false) +$ bash .agents/skills/multi-agent-mux-stop/scripts/stop_session.sh \ + --session my-project-dev-claude --agent claude --purge-conversation --yes +``` + +### 5) ์ž์œจ ๋ฐ˜๋ณต ์ •์ œ ๋ฃจํ”„ ๊ธฐ๋™ (Mux-Loop) +๊ณ„ํš ์ˆ˜๋ฆฝ(Planner) โžœ ์ฝ”๋“œ ์ˆ˜์ •(Creator) โžœ ๊ต์ฐจ ๊ฒ€์ฆ(Reviewer) โžœ ์ˆ˜์ • ์ •์ œ ํ”ผ๋“œ๋ฐฑ์„ ๋‹จ์ผ ๋ช…๋ น์œผ๋กœ ์ž๋™ ์ˆœํ™˜ํ•˜๋Š” ๋ฐ˜๋ณต ์ •๋ฐ€ ๊ด€์ œ ๋ฃจํ”„๋ฅผ ๊ธฐ๋™ํ•ฉ๋‹ˆ๋‹ค. +```bash +# ํ”Œ๋ž˜๋„ˆ ํ˜‘๋ ฅ ๊ณ„ํš ๋‹จ๊ณ„๋ฅผ ํ™œ์„ฑํ™”ํ•˜๊ณ , ๋ฆฌ๋ทฐ์–ด์˜ PASS ํ•ฉ์˜ ํ•˜์— ์ž์œจ ๋ฃจํ”„ ๊ตฌ๋™ (์ตœ๋Œ€ 3ํšŒ ๊ต์ •) +$ bash .agents/skills/multi-agent-mux-loop/scripts/run_loop.sh \ + --plan \ + --plan-talk 1 \ + --reviewer "reviewer-a,reviewer-b" \ + --max-loop 3 \ + --target-agent my-project-dev-claude \ + --task "๊ตฌํ˜„ํ•  ๋ช…ํ™•ํ•œ ๊ฐœ๋ฐœ ์ž‘์—… ๋ชฉํ‘œ" +``` +* `--max-loop`๋Š” ์ฝ”๋“œ ์˜ค๋ฅ˜ ๋ฐœ๊ฒฌ ์‹œ ์ตœ๋Œ€ ๊ต์ •(๋ฐ˜๋ณต ์ˆ˜์ •) ํšŸ์ˆ˜ ์ œํ•œ ๊ฐ€๋“œ๋ ˆ์ผ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. +* **์ฐธ๊ณ **: ๋ฆฌ๋ทฐ ๋‹จ๊ณ„์—์„œ ์ฝ”๋“œ ๋ณ€๊ฒฝ๋ถ„์„ ์ •ํ™•ํ•˜๊ฒŒ ์ถ”์ ํ•˜๊ธฐ ์œ„ํ•ด, ํƒ€๊ฒŸ ํ”„๋กœ์ ํŠธ ๋””๋ ‰ํ† ๋ฆฌ๋Š” `git` ์ €์žฅ์†Œ๋กœ ๊ธฐ๋™ ๋ฐ ๊ด€๋ฆฌ๋˜๊ณ  ์žˆ๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. + +--- + +## ๐Ÿ›ก๏ธ ํ˜‘์—… ๋ฐ ๋ณด์•ˆ ๊ฐ€์ด๋“œ๋ผ์ธ +* MAM์„ ์‚ฌ์šฉํ•  ๋•Œ ๋ชจ๋“  ์—์ด์ „ํŠธ(๊ฐœ๋ฐœ์ž, ๋ฆฌ๋ทฐ์–ด)๋“ค์€ ๋ฃจํŠธ์˜ `AGENTS.md` ์ง€์นจ์„ ์šฐ์„  ์ˆ™์ง€ํ•˜๋„๋ก ์„ค๊ณ„ํ•ด์•ผ ์˜คํƒ๊ณผ ๋ฌด๋ถ„๋ณ„ํ•œ ๋ฆฌํŒฉํ† ๋ง ๋ฒ”๋žŒ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +* ๊ฐ ์—์ด์ „ํŠธ ์—ญํ• ๋ณ„๋กœ ๋ฆฌ๋ทฐ ํ”„๋กœ์„ธ์Šค๋ฅผ ๋Œ๋ฆด ์‹œ, ์ตœ์ข… ์Šน์ธ ๊ฒฐ๊ณผ ๋ณด๊ณ ์„œ(.md)๋Š” ํ˜•์ƒ ๊ด€๋ฆฌ๊ฐ€ ์ถ”์ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ฒ„์ „ ๊ด€๋ฆฌ ๋Œ€์ƒ ๊ฒฝ๋กœ(๊ตฌ์ฒด์ ์œผ๋กœ `.agents/reports//` ๋˜๋Š” `docs/reports/` ๋“ฑ) ํ•˜์œ„๋กœ ์ด๊ด€ ๋ณต์‚ฌํ•˜์—ฌ ์ปค๋ฐ‹ํ•˜๋Š” ๊ทœ์•ฝ(`.agents/MULTI_AGENT_RULES.md`)์„ ์ค€์ˆ˜ํ•ด ์ฃผ์„ธ์š”. diff --git a/.agents/MULTI_AGENT_RULES.ko.md b/.agents/MULTI_AGENT_RULES.ko.md index ac33eb7..751ec35 100644 --- a/.agents/MULTI_AGENT_RULES.ko.md +++ b/.agents/MULTI_AGENT_RULES.ko.md @@ -1,6 +1,6 @@ # MULTI_AGENT_RULES.md -๋ณธ ๋ฌธ์„œ๋Š” ์ƒˆ๋กœ์šด ํ”„๋กœ์ ํŠธ์— **MQTT ๋ฉ”์‹œ์ง• ๋ฐฑํ”Œ๋ ˆ์ธ ๋ฐ Herdr ๊ธฐ๋ฐ˜ ๋ฉ€ํ‹ฐ ์—์ด์ „ํŠธ ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜ ์›Œํฌํ”Œ๋กœ์šฐ**๋ฅผ ๋„์ž…ํ•˜๊ณ , ํ˜‘์—…ํ•˜๋Š” ์—์ด์ „ํŠธ๋“ค์ด ์ผ๊ด€๋œ ๊ทœ์น™๊ณผ ์•„ํ‚คํ…์ฒ˜์— ๋”ฐ๋ผ ์•ˆ์ „ํ•˜๊ณ  ๊ฒฌ๊ณ ํ•˜๊ฒŒ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ •์˜ํ•œ ๊ณตํ†ต ์ง€์นจ ๋ฐ ๊ทœ์•ฝ์ž…๋‹ˆ๋‹ค. +๋ณธ ๋ฌธ์„œ๋Š” ์ƒˆ๋กœ์šด ํ”„๋กœ์ ํŠธ์— **MQTT ๋ฉ”์‹œ์ง• ๋ฐฑํ”Œ๋ ˆ์ธ ๋ฐ Tmux ๊ธฐ๋ฐ˜ ๋ฉ€ํ‹ฐ ์—์ด์ „ํŠธ ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜ ์›Œํฌํ”Œ๋กœ์šฐ**๋ฅผ ๋„์ž…ํ•˜๊ณ , ํ˜‘์—…ํ•˜๋Š” ์—์ด์ „ํŠธ๋“ค์ด ์ผ๊ด€๋œ ๊ทœ์น™๊ณผ ์•„ํ‚คํ…์ฒ˜์— ๋”ฐ๋ผ ์•ˆ์ „ํ•˜๊ณ  ๊ฒฌ๊ณ ํ•˜๊ฒŒ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ •์˜ํ•œ ๊ณตํ†ต ์ง€์นจ ๋ฐ ๊ทœ์•ฝ์ž…๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ํ”„๋กœ์ ํŠธ์—์„œ ์ž‘์—…ํ•˜๋Š” ๋ชจ๋“  ์—์ด์ „ํŠธ๋Š” ์ž‘์—…์„ ์‹œ์ž‘ํ•˜๊ธฐ ์ „ ์ด ๋ฌธ์„œ๋ฅผ ๋ฐ˜๋“œ์‹œ ์ •๋…ํ•˜๊ณ  ๊ทœ์•ฝ์„ ์ค€์ˆ˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. @@ -54,7 +54,7 @@ ### ๐Ÿ—ƒ๏ธ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ๋ฐ ์ƒํƒœ ๊ด€๋ฆฌ - ๋ณธ ์•„ํ‚คํ…์ฒ˜๋Š” ๋ชฉ์ ์— ๋”ฐ๋ผ ๋‘ ๊ฐ€์ง€ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ๋ฅผ ๋ถ„๋ฆฌํ•˜์—ฌ ์šด์˜ํ•ฉ๋‹ˆ๋‹ค: - **์žก ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ (Job Registry)**: ๊ฐ ๋น„๋™๊ธฐ ์žก์˜ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์™€ ์ƒ๋ช…์ฃผ๊ธฐ๋Š” ๊ฐœ๋ณ„ JSON ํŒŒ์ผ(`.mam/jobs/.json`)๋กœ ๊ธฐ๋ก๋˜๋ฉฐ, ๋‹ค์ค‘ ์„ธ์…˜ ๊ฐ„์˜ ๋™์‹œ ์ฒญ๊ตฌ(claiming) ๊ฒฝํ•ฉ์€ ํŒŒ์ผ ๋‹จ์œ„์˜ `fcntl` advisory lock(`registry_lock` via `registry.py`)์„ ํ†ตํ•ด ๋ฐฉ์–ดํ•ฉ๋‹ˆ๋‹ค. - - **์„ธ์…˜ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ (Session Registry)**: Herdr ๋ชจ๋‹ˆํ„ฐ๋ง ์ƒํƒœ ๋ฐ ์—์ด์ „ํŠธ ๊ตฌ๋™ ์ •๋ณด๋Š” SQLite WAL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค(`.mam/agent-sessions.db`)๋ฅผ ํ†ตํ•ด ๋‹จ์ผ ํ˜ธ์ŠคํŠธ ๋‚ด์—์„œ ์•ˆ์ •์ ์ธ ๋™์‹œ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ์ผ๊ด€๋˜๊ฒŒ ์ œ์–ดํ•ฉ๋‹ˆ๋‹ค. ๋‹จ, SQLite WAL ๋ชจ๋“œ๋Š” NFS(๋„คํŠธ์›Œํฌ ํŒŒ์ผ ์‹œ์Šคํ…œ) ํ™˜๊ฒฝ์—์„œ๋Š” ์™„์ „ํ•œ ํŒŒ์ผ ๋ฝ์ด ๋ณด์žฅ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ ๋กœ์ปฌ ํŒŒ์ผ ์‹œ์Šคํ…œ ์‚ฌ์šฉ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. + - **์„ธ์…˜ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ (Session Registry)**: TMUX ๋ชจ๋‹ˆํ„ฐ๋ง ์ƒํƒœ ๋ฐ ์—์ด์ „ํŠธ ๊ตฌ๋™ ์ •๋ณด๋Š” SQLite WAL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค(`.mam/agent-sessions.db`)๋ฅผ ํ†ตํ•ด ๋‹จ์ผ ํ˜ธ์ŠคํŠธ ๋‚ด์—์„œ ์•ˆ์ •์ ์ธ ๋™์‹œ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ์ผ๊ด€๋˜๊ฒŒ ์ œ์–ดํ•ฉ๋‹ˆ๋‹ค. ๋‹จ, SQLite WAL ๋ชจ๋“œ๋Š” NFS(๋„คํŠธ์›Œํฌ ํŒŒ์ผ ์‹œ์Šคํ…œ) ํ™˜๊ฒฝ์—์„œ๋Š” ์™„์ „ํ•œ ํŒŒ์ผ ๋ฝ์ด ๋ณด์žฅ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ ๋กœ์ปฌ ํŒŒ์ผ ์‹œ์Šคํ…œ ์‚ฌ์šฉ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. ### ๐Ÿ›ก๏ธ ๋ณด์•ˆ ํ”„๋กœํ† ์ฝœ (HMAC-SHA256) - **๋ฌด์ธ์ฆ PoC ๋ชจ๋“œ**: ์žก ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ์ƒ์„ฑ ์‹œ `auth_token`์ด `null`๋กœ ์ง€์ •๋œ ๊ฒฝ์šฐ(PoC ๊ธฐ๋ณธ ๋ชจ๋“œ), ๋ณ„๋„์˜ ์„œ๋ช… ๊ฒ€์ฆ์„ ์ƒ๋žตํ•˜๊ณ  ๋ชจ๋“  ์ด๋ฒคํŠธ๋ฅผ ์ˆ˜์šฉํ•ฉ๋‹ˆ๋‹ค (`verify_hmac`์ด ํ•ญ์ƒ `True`๋ฅผ ๋ฐ˜ํ™˜). @@ -113,22 +113,22 @@ sequenceDiagram ์žฅ๊ธฐ ์‹คํ–‰ ์—์ด์ „ํŠธ ๋ถ„์„ ์ค‘ ๋ฐœ์ƒํ•˜๋Š” ์œ ์‹ค ๋ฐ ์ธํ”„๋ผ์  ์žฅ์• ๋ฅผ ์˜ˆ๋ฐฉํ•˜๊ธฐ ์œ„ํ•œ ์ค‘์š” ์ง€์นจ์ž…๋‹ˆ๋‹ค. ### ๐Ÿ“ธ TUI ๋ทฐํฌํŠธ ์ ˆ๋‹จ ๋ฐฉ์ง€ (Pane Snapshotting 3๋Œ€ ๊ทœ์น™) -Herdr ํ™˜๊ฒฝ์—์„œ ์‹คํ–‰๋˜๋Š” ์—์ด์ „ํŠธ๊ฐ€ ํ™”๋ฉด ์Šคํฌ๋กค ํ•œ๊ณ„๋กœ ์ธํ•ด ์ด์ „ ์ถœ๋ ฅ์ด๋‚˜ ์žฅ๋ฌธ์˜ ๋””๋ฒ„๊น… ๋กœ๊ทธ๋ฅผ ์žƒ์ง€ ์•Š๋„๋ก ์•„๋ž˜์˜ **์Šค๋ƒ…์ƒท ํŒจํ„ด์„ ์˜๋ฌด์ ์œผ๋กœ ์ˆ˜ํ–‰**ํ•ฉ๋‹ˆ๋‹ค. +TMUX ํ™˜๊ฒฝ์—์„œ ์‹คํ–‰๋˜๋Š” ์—์ด์ „ํŠธ๊ฐ€ ํ™”๋ฉด ์Šคํฌ๋กค ํ•œ๊ณ„๋กœ ์ธํ•ด ์ด์ „ ์ถœ๋ ฅ์ด๋‚˜ ์žฅ๋ฌธ์˜ ๋””๋ฒ„๊น… ๋กœ๊ทธ๋ฅผ ์žƒ์ง€ ์•Š๋„๋ก ์•„๋ž˜์˜ **์Šค๋ƒ…์ƒท ํŒจํ„ด์„ ์˜๋ฌด์ ์œผ๋กœ ์ˆ˜ํ–‰**ํ•ฉ๋‹ˆ๋‹ค. 1. **Pre-brief Capture**: ์ž‘์—… ์ง€์นจ(Brief)์„ ์ „์†กํ•œ ์งํ›„, ์ฆ‰์‹œ ํ•ด๋‹น ์„ธ์…˜์˜ pane์„ ์บก์ฒ˜(`capture-pane -S -200`)ํ•ด๋‘์–ด ์ž…๋ ฅ ๊ธฐ๋ก์˜ ์‹œ์ž‘์ ์„ ๋ฐฑ์—…ํ•ฉ๋‹ˆ๋‹ค. 2. **Loop Snapshot**: ์žฅ๊ธฐ ์‹คํ–‰(5๋ถ„ ์ด์ƒ) ์ค‘์ธ ์—์ด์ „ํŠธ ์„ธ์…˜์˜ ๊ฒฝ์šฐ, ์ฃผ๊ธฐ์ ์œผ๋กœ(์˜ˆ: 30์ดˆ๋งˆ๋‹ค) ๋ทฐํฌํŠธ๋ฅผ ์Šค์บ”ํ•˜์—ฌ ์ฆ๋ถ„ ๋ฐ์ดํ„ฐ๋ฅผ `/tmp/pane-snap.txt`์— ๊ณ„์† ๋ˆ„์ (append) ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค. 3. **Post-job Capture**: ์žก ์™„๋ฃŒ/์—๋Ÿฌ ๋ฐ˜ํ™˜ ์ฆ‰์‹œ ์ „์ฒด pane ์ƒํƒœ๋ฅผ ๋งˆ์ง€๋ง‰์œผ๋กœ ์บก์ฒ˜ํ•˜์—ฌ ์ „์ฒด ์ž‘์—… ๊ถค์ ์„ ๋ณด์กดํ•ฉ๋‹ˆ๋‹ค. ### ๐Ÿ“„ ๋งˆํฌ๋‹ค์šด ๊ธฐ๋ฐ˜ ํ˜‘์—… ๋ฐ ๊ฒฐ๊ณผ ์ „๋‹ฌ (Markdown-Based Workflow & Communication) -- **ํ•ต์‹ฌ ์›์น™**: herdr `send-keys`๋‚˜ ์ž…๋ ฅ ๋ฒ„ํผ๋ฅผ ํ†ตํ•ด ๊ธด ์ง€์‹œ์‚ฌํ•ญ์„ ์ง๋ ฌ๋กœ ์ž…๋ ฅํ•˜๋Š” ๊ณผ์ •์—์„œ ๋ฌธ์ž ๋ˆ„๋ฝ์ด๋‚˜ ๋ ˆ์ด์•„์›ƒ ์œ ์‹ค์ด ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด, ์—์ด์ „ํŠธ ๊ฐ„์˜ ๋ชจ๋“  ์ฃผ์š” ํ˜‘์—… ์†Œํ†ต์€ ํŒŒ์ผ ๊ธฐ๋ฐ˜ ๋งˆํฌ๋‹ค์šด ๋ฌธ์„œ ์ƒ์„ฑ์„ ์›์น™์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค. +- **ํ•ต์‹ฌ ์›์น™**: TMUX `send-keys`๋‚˜ ์ž…๋ ฅ ๋ฒ„ํผ๋ฅผ ํ†ตํ•ด ๊ธด ์ง€์‹œ์‚ฌํ•ญ์„ ์ง๋ ฌ๋กœ ์ž…๋ ฅํ•˜๋Š” ๊ณผ์ •์—์„œ ๋ฌธ์ž ๋ˆ„๋ฝ์ด๋‚˜ ๋ ˆ์ด์•„์›ƒ ์œ ์‹ค์ด ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด, ์—์ด์ „ํŠธ ๊ฐ„์˜ ๋ชจ๋“  ์ฃผ์š” ํ˜‘์—… ์†Œํ†ต์€ ํŒŒ์ผ ๊ธฐ๋ฐ˜ ๋งˆํฌ๋‹ค์šด ๋ฌธ์„œ ์ƒ์„ฑ์„ ์›์น™์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค. - **์„ธ๋ถ€ ๊ทœ์น™ ๋ฐ ๊ทœ์•ฝ**: - - **์˜ˆ์™ธ ์‚ฌํ•ญ**: 1~2์ค„ ๋‚ด์™ธ์˜ ๋งค์šฐ ๋‹จ์ˆœํ•œ ์š”์ฒญ, ์ƒํƒœ ํ™•์ธ, ์ˆ˜๋ฝ ์ง„ํ–‰ ๋“ฑ์˜ ๋‹จ๋ฐœ์„ฑ ํ”„๋กฌํ”„ํŠธ๋Š” herdr ์ž…๋ ฅ์„ ํ†ตํ•ด ์ง์ ‘ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + - **์˜ˆ์™ธ ์‚ฌํ•ญ**: 1~2์ค„ ๋‚ด์™ธ์˜ ๋งค์šฐ ๋‹จ์ˆœํ•œ ์š”์ฒญ, ์ƒํƒœ ํ™•์ธ, ์ˆ˜๋ฝ ์ง„ํ–‰ ๋“ฑ์˜ ๋‹จ๋ฐœ์„ฑ ํ”„๋กฌํ”„ํŠธ๋Š” tmux ์ž…๋ ฅ์„ ํ†ตํ•ด ์ง์ ‘ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - **์ž‘์—… ์œ„์ž„**: - *์ˆ˜๋™ ๊ฒฝ๋กœ*: ์ƒ์„ธ ์‚ฌ์–‘๊ณผ ๊ณ„ํš ์ˆ˜๋ฆฝ ๋“ฑ์˜ ๋ณต์žกํ•œ ์ž‘์—… ์ง€์‹œ๋Š” ๋จผ์ € ๋กœ์ปฌ ๋งˆํฌ๋‹ค์šด ํŒŒ์ผ(์˜ˆ: `.mam/reports/brief-.md` ๋˜๋Š” ์ง€์ •๋œ ์›Œํฌ์ŠคํŽ˜์ด์Šค ๊ฒฝ๋กœ)๋กœ ์ž‘์„ฑํ•œ ํ›„, ์—์ด์ „ํŠธ์—๊ฒŒ `"Read <ํŒŒ์ผ๊ฒฝ๋กœ> and execute."` ๋ผ๋Š” ์‹คํ–‰ ๋ช…๋ น๋งŒ ์ „๋‹ฌํ•˜์‹ญ์‹œ์˜ค. - *์ž๋™ ๊ฒฝ๋กœ*: ์ž๋™ํ™” ์žก ๋Ÿฐ๋„ˆ(`multi-agent-mux-delegate-job submit`)๋Š” ์žก ๋“ฑ๋ก ์‹œ `.mam/jobs//brief.md` ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์ง€์‹œ์„œ๋ฅผ ์ž๋™ ์ง‘ํ•„ํ•˜๊ณ  ๋‹จ์ผ ๋ผ์ธ ํฌ์ธํ„ฐ ํ”„๋กฌํ”„ํŠธ๋งŒ ์—์ด์ „ํŠธ ์„ธ์…˜์— ์ธ๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. - **๊ฒฐ๊ณผ ์•ˆ๋‚ด ๋ฐ ํ”ผ๋“œ๋ฐฑ**: - - *์ˆ˜๋™/์˜๊ตฌ ๋ฆฌ๋ทฐ*: ์ƒ์„ธ ๋ฆฌ๋ทฐ ๊ฒฐ๊ณผ, ์„ค๊ณ„ ์ œ์•ˆ์„œ ๋“ฑ์€ `.mam/reports//report-.md` ๊ฒฝ๋กœ์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. + - *์ˆ˜๋™/์˜๊ตฌ ๋ฆฌ๋ทฐ*: ์ƒ์„ธ ๋ฆฌ๋ทฐ ๊ฒฐ๊ณผ, ์„ค๊ณ„ ์ œ์•ˆ์„œ ๋“ฑ์€ `.mam/reports//report-.md` ๊ฒฝ๋กœ์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. - *์ž๋™ํ™” ์žก ๋ณด๊ณ ์„œ*: ์ž๋™ ์œ„์ž„๋œ ๋น„๋™๊ธฐ ์ž‘์—…์˜ ์™„๋ฃŒ ๊ฒฐ๊ณผ๋Š” ์žก ๋””๋ ‰ํ„ฐ๋ฆฌ ํ•˜์œ„์ธ `.mam/jobs//-reports/report-final.md` (๋ฃจํ”„/Discuss ์œ„์ž„ ์‹œ์—๋Š” `-reports/`) ๊ฒฝ๋กœ์— ๊ธฐ๋กํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. - - *๋ฒ„์ „ ๊ด€๋ฆฌ ์ด๊ด€*: ๋ฒ„์ „ ๊ด€๋ฆฌ๊ฐ€ ํ•„์š”ํ•œ ์ฃผ์š” ์‚ฐ์ถœ๋ฌผ(์ตœ์ข… ์„ค๊ณ„ ๊ณ„ํš, ์ตœ์ข… ๋ฆฌ๋ทฐ ๋ณด๊ณ ์„œ, ๋ณด์•ˆ ๊ฐ์‚ฌ ๋ฆฌํฌํŠธ ๋“ฑ)์€ gitignore ๋Œ€์ƒ์ธ `.mam/` ํ•˜์œ„๊ฐ€ ์•„๋‹Œ, ๋ฒ„์ „ ๊ด€๋ฆฌ ๋Œ€์ƒ ๊ฒฝ๋กœ(๊ตฌ์ฒด์ ์œผ๋กœ `.agents/reports//` ๋˜๋Š” `docs/reports/` ๋“ฑ)๋กœ ๋ช…์‹œ์ ์œผ๋กœ ๋ณต์‚ฌํ•˜์—ฌ ์ด๊ด€ ๋ณด์กดํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. + - *๋ฒ„์ „ ๊ด€๋ฆฌ ์ด๊ด€*: ๋ฒ„์ „ ๊ด€๋ฆฌ๊ฐ€ ํ•„์š”ํ•œ ์ฃผ์š” ์‚ฐ์ถœ๋ฌผ(์ตœ์ข… ์„ค๊ณ„ ๊ณ„ํš, ์ตœ์ข… ๋ฆฌ๋ทฐ ๋ณด๊ณ ์„œ, ๋ณด์•ˆ ๊ฐ์‚ฌ ๋ฆฌํฌํŠธ ๋“ฑ)์€ gitignore ๋Œ€์ƒ์ธ `.mam/` ํ•˜์œ„๊ฐ€ ์•„๋‹Œ, ๋ฒ„์ „ ๊ด€๋ฆฌ ๋Œ€์ƒ ๊ฒฝ๋กœ(๊ตฌ์ฒด์ ์œผ๋กœ `.agents/reports//` ๋˜๋Š” `docs/reports/` ๋“ฑ)๋กœ ๋ช…์‹œ์ ์œผ๋กœ ๋ณต์‚ฌํ•˜์—ฌ ์ด๊ด€ ๋ณด์กดํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. - **๋””์Šคํฌ ์ •๋ฆฌ ๋ฐ ๋ณด์กด ์ •์ฑ… ๊ณ„์•ฝ (Cleanup & Retention)**: `.mam/jobs//` ๋ฐ `.mam/reports/` ํด๋” ์•„๋ž˜์˜ ํŒŒ์ผ๋“ค์€ ํœ˜๋ฐœ์„ฑ ๊ฐ์‚ฌ ์ด๋ ฅ(audit-trail) ์‚ฐ์ถœ๋ฌผ์ž…๋‹ˆ๋‹ค. ๋ฒ„์ „ ๊ด€๋ฆฌ๊ฐ€ ํ•„์š”ํ•œ ๋ฌธ์„œ๋“ค์€ `.agents/reports/` ํ•˜์œ„๋กœ ์ˆ˜๋™ ๋ณต์‚ฌํ•˜์—ฌ ์ปค๋ฐ‹ํ•ด์•ผ ํ•˜๋ฉฐ, `stop_session.sh` ์„ธ์…˜ ์ข…๋ฃŒ ์Šคํฌ๋ฆฝํŠธ๋Š” ์ด๋“ค ๋ณด๊ณ ์„œ ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ์ž๋™์œผ๋กœ ์‚ญ์ œํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์ˆ˜๋™ ๋˜๋Š” ์ฃผ๊ธฐ์  ํด๋ฆฐ์—…์ด ๊ถŒ์žฅ๋ฉ๋‹ˆ๋‹ค. ### โฑ๏ธ ํƒ€์ž„์•„์›ƒ ๊ตฌ์„ฑ ๋ฐ ์ •๋ ฌ ๊ทœ์น™ diff --git a/.agents/MULTI_AGENT_RULES.md b/.agents/MULTI_AGENT_RULES.md index 4fd65a5..06f494b 100644 --- a/.agents/MULTI_AGENT_RULES.md +++ b/.agents/MULTI_AGENT_RULES.md @@ -1,6 +1,6 @@ # MULTI_AGENT_RULES.md -This document serves as the common guidelines and protocol for introducing the **MQTT messaging backplane and Herdr-based multi-agent orchestration workflow** to a new project. It defines the rules and architecture to ensure collaborating agents perform tasks safely, robustly, and consistently. +This document serves as the common guidelines and protocol for introducing the **MQTT messaging backplane and Tmux-based multi-agent orchestration workflow** to a new project. It defines the rules and architecture to ensure collaborating agents perform tasks safely, robustly, and consistently. All agents working on a new project must read this document thoroughly and comply with the defined protocols before starting any tasks. @@ -54,7 +54,7 @@ Asynchronous communication and state management between agents are controlled vi ### ๐Ÿ—ƒ๏ธ Registry & State Management - This architecture maintains two distinct registries based on their purpose: - **Job Registry**: The metadata and lifecycle of each asynchronous job are recorded in individual JSON files (`.mam/jobs/.json`). Concurrency conflicts (claiming races) across multiple sessions are prevented via file-based `fcntl` advisory locks (`registry_lock` via `registry.py`). - - **Session Registry**: Herdr monitoring states and running agent metadata are consistently controlled using a SQLite WAL database (`.mam/agent-sessions.db`) to support reliable concurrent transactions on a single host. However, since SQLite WAL mode does not guarantee complete file locking in Network File System (NFS) environments, we recommend using a local file system. + - **Session Registry**: TMUX monitoring states and running agent metadata are consistently controlled using a SQLite WAL database (`.mam/agent-sessions.db`) to support reliable concurrent transactions on a single host. However, since SQLite WAL mode does not guarantee complete file locking in Network File System (NFS) environments, we recommend using a local file system. ### ๐Ÿ›ก๏ธ Security Protocol (HMAC-SHA256) - **Unauthenticated PoC Mode**: If the `auth_token` in the job registry is set to `null` (the default PoC mode), signature verification is skipped and all events are accepted (`verify_hmac` always returns `True`). @@ -113,7 +113,7 @@ sequenceDiagram These are critical instructions for preventing data loss and infrastructure-level failures during long-running agent analyses. ### ๐Ÿ“ธ Preventing TUI Viewport Truncation (The 3 Pane Snapshotting Rules) -To ensure that agents running in Herdr environments do not lose debug logs or previous outputs due to screen scrollback limits, the following **snapshotting pattern must be enforced**: +To ensure that agents running in TMUX environments do not lose debug logs or previous outputs due to screen scrollback limits, the following **snapshotting pattern must be enforced**: 1. **Pre-brief Capture**: Capture the pane (`capture-pane -S -200`) immediately after sending the task instruction (Brief) to back up the starting point of the input history. 2. **Loop Snapshot**: For long-running agent sessions (5 minutes or more), periodically (e.g., every 30 seconds) scan the viewport and append the incremental data to `/tmp/pane-snap.txt`. 3. **Post-job Capture**: Capture the complete pane state one final time immediately after a job completes or returns an error to preserve the entire execution trajectory. @@ -121,14 +121,14 @@ To ensure that agents running in Herdr environments do not lose debug logs or pr ### ๐Ÿ“„ Markdown-Based Workflow & Communication (๋งˆํฌ๋‹ค์šด ๊ธฐ๋ฐ˜ ํ˜‘์—… ๋ฐ ๊ฒฐ๊ณผ ์ „๋‹ฌ) - **Core Principle**: To prevent TUI character loss, truncation, and layout breakage during sequential input typing, all collaborative workflows must favor file-based markdown communication. - **Rules & Protocols**: - - **Exception**: Extremely simple prompts (e.g., "Re-evaluate", "Check status", "Proceed") of 1 or 2 lines may be sent directly via herdr input buffers. + - **Exception**: Extremely simple prompts (e.g., "Re-evaluate", "Check status", "Proceed") of 1 or 2 lines may be sent directly via tmux input buffers. - **Task Delegation**: - *Manual path*: Detailed task briefs may be written to a local Markdown file (e.g., `.mam/reports/brief-.md` or a workspace path) first. The sender then issues a simple trigger command: `"Read and execute."` - *Automated path*: The automated job runner (`multi-agent-mux-delegate-job submit`) automatically provisions the brief at `.mam/jobs//brief.md` and sends a short pointer instruction to the agent. - **Result Reporting & Feedback**: - - *Manual/Durable reviews*: Detailed reviews, design proposals, or audit reports must be saved under `.mam/reports//report-.md`. + - *Manual/Durable reviews*: Detailed reviews, design proposals, or audit reports must be saved under `.mam/reports//report-.md`. - *Automated job reports*: Automated execution results are saved directly to `.mam/jobs//-reports/report-final.md` (or `-reports/` for loops) as transient files. - - *Versioned promotions*: Any final design plans, review verdicts, or security audit reports that require version control must be explicitly copied to tracked directory paths (specifically under `.agents/reports//` or `docs/reports/`). + - *Versioned promotions*: Any final design plans, review verdicts, or security audit reports that require version control must be explicitly copied to tracked directory paths (specifically under `.agents/reports//` or `docs/reports/`). - **Cleanup & Retention Contract**: Files under `.mam/jobs//` and `.mam/reports/` are transient audit-trail artifacts. While durable outcomes are committed to version control under `.agents/reports/`, ephemeral directory trees can be cleaned up manually as needed; `stop_session.sh` does not automatically purge these report trees during session exit. ### โฑ๏ธ Timeout Configuration & Alignment Rules diff --git a/.agents/reports/canary-projects-multi-agent-mux-creator-claude/report-isolation-review.md b/.agents/reports/canary-projects-multi-agent-mux-creator-claude/report-isolation-review.md deleted file mode 100644 index a2491b3..0000000 --- a/.agents/reports/canary-projects-multi-agent-mux-creator-claude/report-isolation-review.md +++ /dev/null @@ -1,56 +0,0 @@ -# ๐Ÿ” ๋ฆฌ๋ทฐ ๋ฆฌํฌํŠธ โ€” ์„ธ์…˜ ID ๊ฒฉ๋ฆฌ ์ข…ํ•ฉ ์„ค๊ณ„/๊ตฌํ˜„ ๊ณ„ํš์„œ ๊ฒ€ํ†  - -- **๋ฆฌ๋ทฐ์–ด**: Claude (Reviewer A โ€” ์ƒ์œ„ ๋…ผ๋ฆฌ/์„ค๊ณ„ ์ •ํ•ฉ์„ฑ) -- **๊ฒ€ํ†  ๋Œ€์ƒ**: `session_isolation_discussion.md` (Planner ํ†ตํ•ฉ๋ณธ, Rev.2 ๋ฐ˜์˜) -- **๋Œ€์กฐ ๊ธฐ์ค€**: ๋ณธ์ธ ์ž‘์„ฑ `implementation_plan.session_isolation.md` (Rev.2) + 2์ฐจ ํ† ๋ก  ํ•ฉ์˜ -- **job_id**: 655fb695 -- **๋‚ ์งœ**: 2026-07-10 -- **์ตœ์ข… ํŒ์ •**: **PASS** (๊ฒฝ๋ฏธํ•œ ๋น„์ฐจ๋‹จ ๊ถŒ๊ณ  3๊ฑด ๋™๋ฐ˜) - ---- - -## 1. ๊ฒ€ํ†  ๊ธฐ์ค€๋ณ„ ๊ฒฐ๊ณผ - -### ๊ธฐ์ค€ 1 โ€” ์˜๊ฒฌ ๋ฐ˜์˜์˜ ์ •ํ•ฉ์„ฑ โœ… -๋ณธ์ธ์ด ๊ฐœ์ง„ํ•œ ํ•ต์‹ฌ ๋…ผ์ง€๊ฐ€ **์œ ์‹ค ์—†์ด** ํ†ตํ•ฉ๋จ์„ ํ™•์ธ: -| ์›์•ˆ ๋…ผ์ง€ | ํ†ตํ•ฉ๋ณธ ์œ„์น˜ | ์ƒํƒœ | -|---|---|---| -| 3๊ณ„์ธต ํ•˜์ด๋ธŒ๋ฆฌ๋“œ (L1 ์ธ์ž์ฃผ์ž… / L2 ๋””๋ ‰ํ„ฐ๋ฆฌ ๊ฒฉ๋ฆฌ / R1 ๋ถˆ๋ณ€์‹) | ยง2.1, mermaid ๋‹ค์ด์–ด๊ทธ๋žจ | โœ… ์ถฉ์‹ค | -| L1: `uuidgen` ์‚ฌ์ „๋ฐœ๊ธ‰ โ†’ `--session-id` ์ฃผ์ž… โ†’ `*_own` ์ฆ‰์‹œ ๊ธฐ๋ก | L1 (line 36-37) | โœ… | -| L2: env ๊ฒฉ๋ฆฌ + `env_overrides` ์˜์†ํ™” + resume ์žฌ์ ์šฉ | L2 (line 38-40), T6 | โœ… | -| R1 claimed-set ํ•„ํ„ฐ + R2 ์ƒ์„ฑ-์‹œ ์œ ์ผ์„ฑ assert | R1/R2 (line 41-43), T1/T2 | โœ… | -| Phase 0 ๊ฒ€์ฆ ๊ฒŒ์ดํŠธ, ๊ฒŒ์ดํŠธ ํ†ต๊ณผ ์ „ ๊ตฌํ˜„ ๊ธˆ์ง€ | line 51, ยงPhase 0 | โœ… | -| agent๋ณ„ ID ๋ฐœ๊ธ‰ ๋น„๋Œ€์นญ(claude UUID vs cline `epoch_rand`) | RK3 (line 104) | โœ… | - -### ๊ธฐ์ค€ 2 โ€” ๋…ผ๋ฆฌ์  ์ •ํ•ฉ์„ฑ โœ… -- **Phase 0โ†’(L1/L2 ๋ถ„๊ธฐ)โ†’Phase 1โ†’Phase 2/3โ†’Phase 4** ๋กœ๋“œ๋งต์ด ์ธ๊ณผ์ ์œผ๋กœ ํƒ€๋‹น. -- **Phase 0๊ฐ€ ๊ฒŒ์ดํŠธ๋กœ์„œ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ธฐ๋Šฅ**: line 51์—์„œ "Phase 0 ํ†ต๊ณผ ์ „ ์ฝ”๋“œ ๊ตฌํ˜„ ์ฐฉ์ˆ˜ ๊ธˆ์ง€"๋ฅผ ๋Œ€์ „์ œ๋กœ ๋ช…์‹œํ•˜๊ณ , G1/G2 ์‹ค์ธก ๋งคํŠธ๋ฆญ์Šค๊ฐ€ L1/L2 ๋ผ์šฐํŒ…์„ ๊ฒฐ์ •(line 55-56, 73) โ€” ๊ฒŒ์ดํŠธ ์˜๋ฏธ๋ก  ์ •ํ™•. cline ๋ฏธ์ง€์› ๋ฆฌ์Šคํฌ๊ฐ€ ์ฝ”๋“œ ์ฐฉ์ˆ˜ ์ „์— ํ•ด์†Œ๋˜๋Š” ๊ตฌ์กฐ๋ผ ์‚ฌ์ด๋“œ์ดํŽ™ํŠธ ์˜ˆ๋ฐฉ ์„ค๊ณ„๊ฐ€ ์„ฑ๋ฆฝ. -- Phase 1(R1/R2)์ด ์ „๋žต ๋ฌด๊ด€ ์„ ํ–‰ ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ์›์•ˆ ์ทจ์ง€๋„ ๋ฐ˜์˜(line 58, "์„ ํ–‰ ๊ฐ€๋Šฅ"). - -### ๊ธฐ์ค€ 3 โ€” ๋ˆ„๋ฝ ํ™•์ธ โœ… -- **RC-2 ์ฒญ์†Œ ๊ณ„์•ฝ**: ยง2.1 RC-2(line 44-45) + T7(line 88) + RK4(line 105)๋กœ 3์ค‘ ๊ธฐ์ž… โ€” ๋ˆ„๋ฝ ์—†์Œ. -- **R1/R2 ์ด์ค‘ ์•ˆ์ „์žฅ์น˜**: line 41-43์— defense-in-depth๋กœ ๋ช…ํ™•ํžˆ ๊ธฐ์ž…. -- Phase๋ณ„ DoD, Phase 4 ํšŒ๊ท€๊ฒ€์ฆ(V1~V3) ๋ชจ๋‘ ์กด์žฌ. - ---- - -## 2. ๐ŸŸก ๋น„์ฐจ๋‹จ ๊ถŒ๊ณ  (๊ตฌํ˜„ ๊ณ„ํš ์„ธ๋ จํ™”์šฉ, PASS ์กฐ๊ฑด ์•„๋‹˜) - -- **A-1. Non-Goal ๋ช…์‹œ ๋ถ€์žฌ**: ์›์•ˆ์˜ ๋ช…์‹œ์  Non-Goal("CLI(claude/cline/agy/hermes) ์ž์ฒด ๋ฏธ์ˆ˜์ • โ€” ์ธ์ž/ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์ธํ„ฐํŽ˜์ด์Šค๋งŒ ์‚ฌ์šฉ")์ด ํ†ตํ•ฉ๋ณธ์—” ๋ฌธ์žฅ์œผ๋กœ ๋น ์ ธ ์žˆ์Œ(์ ‘๊ทผ๋ฒ•์ƒ ๋‚ด์žฌ๋˜์–ด ์žˆ์œผ๋‚˜ ์•”๋ฌต์ ). ์˜คํ•ด ๋ฐฉ์ง€ ์œ„ํ•ด 1์ค„ ๋ช…๋ฌธํ™” ๊ถŒ๊ณ . -- **A-2. RK5 `--isolate-strict` ์‹ ๊ทœ ์š”์†Œ**: ์›์•ˆ์—” ์—†๋˜ "๊ฒฉ๋ฆฌ ํ™œ์„ฑํ™”๋ฅผ ์„ธ์…˜ ๋‹ค์ค‘์„ฑ/๋ช…์‹œ ํ”Œ๋ž˜๊ทธ๋กœ ์ œ์–ด"(line 106)๊ฐ€ ์ถ”๊ฐ€๋จ โ€” ํ•ฉ๋ฆฌ์  ๊ฐœ์„ ์ด๋‚˜ **์ƒˆ ์„ค๊ณ„ ๊ฒฐ์ •**์ด๋ฏ€๋กœ Phase 0/1 ๊ณ„ํš ์‹œ ์Šค์ฝ”ํ”„๋กœ ํ™•์ • ํ•„์š”(ํ”Œ๋ž˜๊ทธ ๊ธฐ๋ณธ๊ฐ’ยท๋ฐœ๋™ ์กฐ๊ฑด). -- **A-3. Phase 1 ์ˆœ์„œ ํ‘œ๊ธฐ ๋ฏธ์„ธ ๋ชจํ˜ธ**: ๋‹ค์ด์–ด๊ทธ๋žจ(line 53-63)์€ Phase 1์„ Phase 0 ์•„๋ž˜์— ์„ ํ˜• ๋ฐฐ์น˜ํ•˜๋‚˜ ๋ณธ๋ฌธ์€ "์„ ํ–‰ ๊ฐ€๋Šฅ"์ด๋ผ ํ‘œ๊ธฐ โ€” Phase 1์ด Phase 0 ์‚ฐ์ถœ๋ฌผ์— ์˜์กดํ•˜์ง€ ์•Š์Œ์„ ํ•œ ์ค„๋กœ ๋ช…ํ™•ํ™”ํ•˜๋ฉด ์ข‹์Œ(๊ธฐ๋Šฅ์  ๋ฌธ์ œ ์•„๋‹˜). - ---- - -## 3. ํŒ์ • ์š”์•ฝ - -| ๊ด€์  | ๊ฒฐ๊ณผ | -|---|---| -| ์˜๊ฒฌ ๋ฐ˜์˜ ์ •ํ•ฉ์„ฑ | โœ… ํ•ต์‹ฌ ๋…ผ์ง€ ์œ ์‹ค ์—†์Œ | -| ๋…ผ๋ฆฌ์  ์ •ํ•ฉ์„ฑ / Phase 0 ๊ฒŒ์ดํŠธ | โœ… ์ธ๊ณผ ํƒ€๋‹น, ๊ฒŒ์ดํŠธ ์˜๋ฏธ๋ก  ์ •ํ™• | -| ๋ˆ„๋ฝ ํ™•์ธ (RC-2, R1/R2) | โœ… ๋ˆ„๋ฝ ์—†์Œ | -| ๋น„์ฐจ๋‹จ ๊ถŒ๊ณ  | ๐ŸŸก A-1/A-2/A-3 (๊ณ„ํš ์„ธ๋ จํ™”์šฉ) | - -ํ†ตํ•ฉ๋ณธ์€ 2์ฐจ ํ† ๋ก  ํ•ฉ์˜์™€ Rev.2 ๊ตฌํ˜„ ๊ณ„ํš์„ **์ถฉ์‹คยท์™„์ „ํ•˜๊ฒŒ** ๋ฐ˜์˜ํ–ˆ๊ณ , ๊ฒฐ์ •์ ์œผ๋กœ **Phase 0 ์‹ค์ธก ๊ฒŒ์ดํŠธ๊ฐ€ ๊ตฌํ˜„ ์ „์— ์œ„์น˜**ํ•˜์—ฌ ์ž”์—ฌ ๋ถˆํ™•์‹ค์„ฑ(ํŠนํžˆ cline)์ด ์ฝ”๋“œ ์ฐฉ์ˆ˜ ์ „์— ํ•ด์†Œ๋˜๋Š” ์•ˆ์ „ ๊ตฌ์กฐ๋ฅผ ๊ฐ–์ท„์Šต๋‹ˆ๋‹ค. ๊ตฌํ˜„ ๊ณ„ํš์œผ๋กœ ์ „ํ™˜ํ•˜๋Š” ๋ฐ ์ด๊ฒฌ ์—†์Šต๋‹ˆ๋‹ค. A-1~A-3๋Š” Phase 0 ์ฐฉ์ˆ˜ ์‹œ ํ•จ๊ป˜ ๋ฐ˜์˜ ๊ถŒ๊ณ . - -**PASS** diff --git a/.agents/reports/canary-projects-multi-agent-mux-creator-claude/report-markdown-analysis-crosscheck.md b/.agents/reports/canary-projects-multi-agent-mux-creator-claude/report-markdown-analysis-crosscheck.md deleted file mode 100644 index 57840f6..0000000 --- a/.agents/reports/canary-projects-multi-agent-mux-creator-claude/report-markdown-analysis-crosscheck.md +++ /dev/null @@ -1,75 +0,0 @@ -# Root Markdown Analysis โ€” Cross-Check Report (Creator Claude) - -- **Reviewer**: Creator Claude (`canary-projects-multi-agent-mux-creator-claude`) -- **Date**: 2026-07-11 -- **Brief**: `.mam/reports/brief-root-markdowns.md` -- **Cross-checked against**: `.agents/reports/canary-projects-multi-agent-mux-reviewer-cline/report-markdown-analysis.md` (Reviewer Cline, 2026-07-11) -- **Method**: independent read of all 7 files + `git log --follow` per file + repo-wide inbound-link grep + verification of implementation claims against shipped commits. - ---- - -## Verdict Summary - -Cline's verdicts (3 DELETE / 4 KEEP) are **confirmed in substance**, with **one amendment**: `session_isolation_discussion.md` cannot be deleted standalone without breaking two inbound links in live tracked docs (see ยง6). - -| # | File | My Verdict | Agrees with Cline? | -|---|------|-----------|--------------------| -| 1 | `task.md` | **DELETE** | โœ… | -| 2 | `implementation_plan.md` | **DELETE** | โœ… | -| 3 | `BOOTSTRAP.md` | **KEEP** | โœ… | -| 4 | `FUTURE_WORKS.ko.md` | **KEEP** | โœ… | -| 5 | `DONE.md` | **KEEP** | โœ… | -| 6 | `session_isolation_discussion.md` | **DELETE โ€” with link cleanup** | โš ๏ธ amended | -| 7 | `AGENTS.md` | **KEEP** | โœ… | - ---- - -## Per-File Analysis - -### 1. `task.md` โ€” DELETE -- **Purpose**: Developer checklist (Rev.1) for the "deploy URL parameterization" task (`MAM_REPO_URL` / `MAM_ARCHIVE_URL` / `MAM_INSTALLER_URL`). -- **Status**: The work **shipped in commit `6408f4a`** (2026-07-09, `feat(deploy): parameterize distribution URLs via MAM_*_URL env vars`) touching exactly the four files the plan prescribed (`deploy/install.sh`, `deploy/update.sh`, `.env.example`, `deploy/README.md`). Independently verified: all three `${MAM_*_URL:-โ€ฆ}` patterns exist at the planned locations (`install.sh:57-58`, `update.sh:139`) and both docs carry the variables. Yet every checkbox in the file is still `[ ]`, and the file ends with a stray accidental-paste line (`agy --conversation=20cc2d8e-โ€ฆ`). Note the file was only ever committed once โ€” bundled into the unrelated isolation-docs commit `d76e470`. -- **Justification**: Fully superseded by the shipped commit; retaining an all-unchecked checklist for done work actively misleads future agents. `task.md`/`implementation_plan.md` are per-cycle scratch names per `.agents/multi_agent_workflow.md` โ€” the *convention* survives deletion of this instance. - -### 2. `implementation_plan.md` โ€” DELETE -- **Purpose**: Planner design doc (Rev.1) for the same deploy URL parameterization task; still marked "Draft (์‚ฌ์šฉ์ž ์Šน์ธ ๋Œ€๊ธฐ)". -- **Status**: Same as above โ€” implemented byte-for-byte in `6408f4a` (default values preserved, `.env` non-sourcing decision honored, mirror examples added to `deploy/README.md:35-40`). -- **Justification**: Superseded by shipped code. The only inbound link is from `task.md`, which is deleted in the same set. Design rationale worth preserving is already encoded in the commit message, `.env.example` comments, and `deploy/README.md`. - -### 3. `BOOTSTRAP.md` โ€” KEEP -- **Purpose**: Agent-facing setup/verification guide (env config, venv, MQTT handshake test). -- **Status**: Active. Referenced from `README.md:177,186`, and explicitly in the deploy installer's runtime-doc **allowlist** (`deploy/install.sh:131` copies `MESSAGING.md BOOTSTRAP.md BOOTSTRAP.ko.md AGENTS.md`) โ€” deleting it would silently degrade every fresh install. Last substantively updated 2026-07-09. -- **Justification**: Load-bearing runtime asset, not a dev leftover. (Same verdict extends to `BOOTSTRAP.ko.md`.) - -### 4. `FUTURE_WORKS.ko.md` โ€” KEEP -- **Purpose**: Korean roadmap of pending improvements (FW-P1~P7, FW-W1~W7, FW-D2~D4 open; FW-D1 resolved). -- **Status**: Active backlog โ€” most items remain unimplemented (e.g., FW-P6 root-marker detection, FW-P7 monitor HMAC hardening). Maintained mirror of `FUTURE_WORKS.md`. -- **Justification**: This is the project's only backlog tracker; deletion loses planned work. (Same verdict for the English `FUTURE_WORKS.md`.) - -### 5. `DONE.md` โ€” KEEP -- **Purpose**: Verified completion record for 28 items (FW-01~FW-16, FW-L1~L3, FW-N1~N7, FW-W3) with per-item commits and 3-agent cross-verification results. -- **Status**: Static historical record; explicitly linked from `FUTURE_WORKS.md:4` ("For completed items, see `DONE.md`") and its Korean twin. -- **Justification**: Deleting it dangles the FUTURE_WORKS reference and erases the audit trail mapping FW-IDs to commits. Zero maintenance cost. (Same for `DONE.ko.md`.) - -### 6. `session_isolation_discussion.md` โ€” DELETE, **but only with link cleanup** (amendment to Cline) -- **Purpose**: Rev.3 consolidated design discussion for the session-ID isolation feature. -- **Status**: Superseded โ€” the doc itself declares `implementation_plan.session_isolation.md` (Rev.3) the single source of truth, and the feature is fully implemented, integration-tested, and PASSed by both reviewers (commits through `dad99f5`). -- **Amendment**: Cline's report misses that **two live tracked docs still link to it**: `implementation_plan.session_isolation.md:6` (๊ด€๋ จ ์ž๋ฃŒ) and `task.session_isolation.md:3` (๊ธฐ์ค€ ๋ฌธ์„œ). Standalone deletion creates dangling links. -- **Recommendation**: Treat the whole isolation doc set (`session_isolation_discussion.md`, `Problem_Definition.md`, `implementation_plan.session_isolation.md`, `task.session_isolation.md`, `session_isolation_handover.md` โ€” the latter four out of this brief's scope) as one unit: either delete/archive them **together** (the feature is done and PASSed; the durable outcome lives in `.agents/reports/*/report-isolation-review.md` and git history), or if only the discussion doc goes now, remove the two inbound link references in the same commit. - -### 7. `AGENTS.md` โ€” KEEP -- **Purpose**: Core behavioral guidelines for all agents; entry pointer to `.agents/MULTI_AGENT_RULES.md`. -- **Status**: Active and essential โ€” copied to target projects by **both** installers (`scripts/install_mam.sh:127,138` and `deploy/install.sh:131`), referenced by README and the orchestration rules. -- **Justification**: Deleting it breaks both install paths and the documented onboarding flow. - ---- - -## Out-of-Scope Observations (for the record) - -1. The root holds **18** markdown files; the brief covered 7. The undiscussed siblings share the fates above: `*.ko.md` twins follow their English counterparts; the four other session-isolation docs should be dispositioned as a set with #6. -2. The uncommitted working-tree `.gitignore` change adding `.agents/reports` (flagged in my installer verdict) is still present and would ignore the very reports directory this brief writes into โ€” it should be resolved before committing any deletions. -3. Deletions of tracked files require `git rm` + commit; per standing constraints I have not deleted or committed anything โ€” this report is analysis only. - -## Final Verdict - -**PASS on Cline's analysis with the ยง6 amendment**: 3 DELETE / 4 KEEP confirmed; `session_isolation_discussion.md` must be deleted together with cleanup of its two inbound links (or as part of archiving the whole isolation doc set). diff --git a/.agents/reports/canary-projects-multi-agent-mux-creator-claude/report-prompt-lock-analysis.md b/.agents/reports/canary-projects-multi-agent-mux-creator-claude/report-prompt-lock-analysis.md deleted file mode 100644 index 154cfab..0000000 --- a/.agents/reports/canary-projects-multi-agent-mux-creator-claude/report-prompt-lock-analysis.md +++ /dev/null @@ -1,175 +0,0 @@ -# Prompt-Lock / Input Delivery Failure โ€” Code-Level Analysis (Creator Claude) - -- **Analyst**: Creator Claude (`canary-projects-multi-agent-mux-creator-claude`) -- **Date**: 2026-07-11 -- **Brief**: `.mam/reports/brief-prompt-lock-fix.md` -- **Roadmap linkage**: this is the concrete design for **FW-W2** ("๋ธ”๋ผ์ธ๋“œ TUI ํ‚ค ์ž…๋ ฅ ๋ฐฉ์ง€๋ฅผ ์œ„ํ•œ ์‹คํ–‰ ์ค€๋น„๋„ ๊ฒ€์ฆ", FUTURE_WORKS P2) โ€” landing this closes that item. - ---- - -## 1. Symptom โ†’ Root Cause โ†’ Code Mapping - -The reported symptom โ€” instruction text visible in the prompt box but never submitted, or a frozen cursor โ€” is reproducible from the current code through three distinct paths: - -| # | Root cause (brief) | Code path that triggers it | -|---|---|---| -| RC-A | Renderer thread bottleneck during heavy output | `inject_instructions()` pastes, sleeps a **fixed 0.5 s**, sends **one blind `C-m`**. If the TUI (Ink/Blessed) is still flushing startup output, the paste lands but the Enter is consumed while the input widget isn't accepting submits โ†’ text sits unsubmitted forever. No verification, no retry. | -| RC-B | Permission/trust dialog steals focus | `wait_for_tui_ready()` **classifies dialogs as "ready"** (see ยง2-B), so injection proceeds while a modal is up: the pasted text is swallowed by the dialog widget and the `C-m` blindly activates whatever dialog button is focused. | -| RC-C | OAuth / list-selection blocks intercept keys | Same as RC-B (no dialog detection anywhere), plus the resume workflow's **unconditional** `Enter/Down/Enter` sequence, which malfunctions in *both* directions (ยง2-C). | - -Downstream damage: when injection silently fails on a delegated job, no `started` event is ever published โ€” the delegator waits until watchdog timeout, and the pane holds a zombie prompt. The failure is invisible because `inject_instructions()` **always returns 0**. - ---- - -## 2. Exact Code Locations (Deliverable 1) - -### 2-A. `lib.sh:1088-1100` โ€” `inject_instructions()` โ€” **primary defect** -```bash -$local_tmux set-buffer -b "job_buf_$job_id" "$instructions" -$local_tmux paste-buffer -b "job_buf_$job_id" -t "$sess" -sleep 0.5 -$local_tmux send-keys -t "$sess" C-m -``` -Sole caller: `create_session.sh:384` (every `--submit-job` / `--onboard` session). Defects: fixed delay instead of readiness evidence; single unverified `C-m`; no dialog check before pasting; no success/failure contract. **All three root causes converge here.** - -### 2-B. `lib.sh:1042-1084` โ€” `wait_for_tui_ready()` โ€” defective gate -- The claude readiness regex (`lib.sh:1056`) is `"Anthropic|Assistant|Chat|Dangerously|dangerously|Enter|Welcome|projects"`. The **trust/bypass dialogs themselves contain "Enter" and "Dangerously"**, so an open modal is reported as "โœ… ready" and injection fires straight into it (RC-B). -- On timeout it prints a warning and **"Proceeding anyway"** (`lib.sh:1083`) with no failure return โ€” the caller cannot distinguish ready from not-ready. -- "Banner text painted" is the wrong readiness signal; it says nothing about the input box accepting keys (RC-A). - -### 2-C. `multi-agent-mux-resume/SKILL.md:150-156` โ€” blind dialog navigation -```bash -sleep 5; tmux send-keys -t "$SESSION_NAME" Enter -sleep 3; tmux send-keys -t "$SESSION_NAME" Down -sleep 0.3; tmux send-keys -t "$SESSION_NAME" Enter -``` -Sent **unconditionally** after claude resume. Two failure modes: (a) if no dialog appears, `Down` puts the fresh prompt into history navigation and the second `Enter` can **re-submit a historical prompt** โ€” spurious re-execution; (b) if the dialog appears later than 5 s under load, the keys land in the prompt and the dialog then blocks all subsequent input โ€” the exact lock symptom. Note the asymmetry: the create path has *no* dialog handling while resume has *blind* handling; neither is correct. - -### 2-D. `multi-agent-mux-stop/scripts/stop_session.sh:181-199` โ€” `graceful_stop()` -`tmux send-keys -t "$SESSION_NAME" "$exitkey" Enter` (line 192) is blind: with a dialog open, `/exit` is swallowed, the 3 s check fails, and the session escalates to `kill-session`/SIGKILL โ€” losing the agent's own state flush. Mitigated by the fallback chain (severity: low), but it produces avoidable hard-kills. - -### 2-E. `multi-agent-mux-create/SKILL.md:214-215` โ€” documented probe -`tmux send-keys -t "$SESSION_NAME" "" Enter` instructs operators to fire a stray Enter as a liveness probe โ€” with a dialog up, this blindly accepts its focused default. Documentation fix. - -### 2-F. Checked and NOT vulnerable (per brief scope) -- `multi-agent-mux-resume/scripts/update_yaml_resumed.sh` โ€” pure registry update; contains no `send-keys`/`paste-buffer`. No change needed. -- `scripts/install_mam.sh` โ€” the epilogue only **prints** quick-start commands for a human; it never drives a TUI. No direct vulnerability; its create quick-start simply funnels into site 2-A, which the fix below covers. -- `MULTI_AGENT_RULES.ko.md:122` already mandates file-based briefs over long serialized typing โ€” correct policy, but insufficient: this incident shows even the short `Read and execute.` line needs guaranteed delivery. - ---- - -## 3. Proposed Prevention Helper (Deliverable 2) - -Add to `lib.sh` (next to the existing pane helpers). Three functions; `send_keys_safe` is the public entry point. - -```bash -# --------------------------------------------------------------------------- -# Prompt-lock safe delivery (FW-W2). Contract: send_keys_safe returns 0 only -# if the text was verifiably submitted; callers must handle non-zero. -# --------------------------------------------------------------------------- - -_sks_tmux() { # server-aware tmux (same rule as inject_instructions) - if [ -n "${TMUX_SERVER_NAME:-}" ] && [ "$TMUX_SERVER_NAME" != "default" ]; then - tmux -L "$TMUX_SERVER_NAME" "$@" - else - tmux "$@" - fi -} - -_pane_capture() { _sks_tmux capture-pane -p -t "$1" 2>/dev/null || echo ""; } - -# _pane_quiescent [tries=20] [interval=0.5] -# Renderer settled = two consecutive identical non-empty captures. -_pane_quiescent() { - local sess="$1" tries="${2:-20}" interval="${3:-0.5}" prev="__none__" cur i - for ((i = 0; i < tries; i++)); do - cur=$(_pane_capture "$sess") - [ -n "$cur" ] && [ "$cur" = "$prev" ] && return 0 - prev="$cur"; sleep "$interval" - done - return 1 -} - -# _pane_dialog_open โ€” focus-stealing modal signatures (trust / -# permission / OAuth / list-selection). Tokens must NOT appear in normal -# prompt idle screens; keep this list curated per agent TUI release. -_pane_dialog_open() { - _pane_capture "$1" | grep -Eq \ - 'Do you trust the files|Yes, proceed|No, exit|Approve\b|Allow this|Deny\b|Press Enter to continue|Sign in|browser to authenticate|Use arrow keys|Esc to cancel' -} - -# send_keys_safe [job_id] -# 1. Wait for renderer quiescence (defeats RC-A). -# 2. Refuse to paste while a dialog is open (defeats RC-B/RC-C): wait up to -# SKS_DIALOG_TIMEOUT (default 30 s) for it to clear; if SKS_DIALOG_ESCAPE=1 -# send a single Escape and re-check. NEVER a blind Enter โ€” accepting an -# unknown dialog is a policy decision, not a delivery detail. -# 3. Paste via unique buffer; verify the text landed (marker visible in pane). -# 4. Submit C-m; verify submission (marker left the input area); retry the -# C-m up to 3 times with backoff โ€” safe because re-Enter on the same -# unsubmitted text is idempotent. -send_keys_safe() { - local sess="$1" text="$2" job_id="${3:-adhoc}" - local marker deadline - marker=$(printf '%s' "$text" | head -c 200 | tail -c 24) # verification token - - _pane_quiescent "$sess" || { echo "send_keys_safe: pane never quiesced ($sess)" >&2; return 1; } - - deadline=$(( $(date +%s) + ${SKS_DIALOG_TIMEOUT:-30} )) - while _pane_dialog_open "$sess"; do - if [ "${SKS_DIALOG_ESCAPE:-0}" = "1" ]; then - _sks_tmux send-keys -t "$sess" Escape; sleep 1 - fi - [ "$(date +%s)" -ge "$deadline" ] && { echo "send_keys_safe: dialog blocking input ($sess)" >&2; return 2; } - sleep 2 - done - - _sks_tmux set-buffer -b "sks_$job_id" "$text" - _sks_tmux paste-buffer -b "sks_$job_id" -t "$sess" - _sks_tmux delete-buffer -b "sks_$job_id" 2>/dev/null || true - sleep 0.5 - _pane_capture "$sess" | grep -Fq "$marker" || { echo "send_keys_safe: paste not visible ($sess)" >&2; return 3; } - - local try - for try in 1 2 3; do - _sks_tmux send-keys -t "$sess" C-m - sleep "$try" - if ! _pane_capture "$sess" | tail -n 5 | grep -Fq "$marker"; then - return 0 # input box cleared โ†’ submitted - fi - done - echo "send_keys_safe: Enter not accepted after 3 tries ($sess)" >&2 - return 4 -} -``` - -Design decisions worth recording: -- **Quiescence over fixed sleeps**: two identical captures prove the renderer drained its queue โ€” directly addresses the Blessed/Ink bottleneck; a fixed `sleep` can only ever be wrong in one direction or the other. -- **Escape opt-in, never blind Enter/Ctrl+C**: `Escape` cancels dialogs but *also* clears typed prompt text in some TUIs, and `Ctrl+C` can interrupt a running agent turn โ€” so focus restoration is gated behind `SKS_DIALOG_ESCAPE=1` and only fires when a dialog signature is positively detected. Default behavior is to wait and then fail loudly (distinct exit codes 1-4 tell the caller what blocked). -- **Marker-based submit verification**: agent-agnostic โ€” no per-TUI spinner parsing. The last 24 chars of the text must appear after paste and must leave the bottom 5 lines after Enter. Retrying Enter while the marker is still in the input box is idempotent. -- **Distinct non-zero exit codes** let `create_session.sh` publish a precise `error` event instead of leaving a zombie job. - ---- - -## 4. Draft Migration Plan (Deliverable 3) - -| Step | Change | Files | Risk | -|---|---|---|---| -| **M1** | Add the three helpers; rewrite `inject_instructions()` body as a thin wrapper over `send_keys_safe` (same signature). Sole caller `create_session.sh:384` inherits the fix with zero call-site change; add return-code check that publishes `error` + lets the still-armed cleanup trap roll the session back. | `lib.sh`, `create_session.sh` | Low โ€” single choke point | -| **M2** | Harden `wait_for_tui_ready`: drop dialog-ambiguous tokens (`Enter`, `Dangerously`, `dangerously`) from the claude regex; treat `_pane_dialog_open` as *not ready*; make timeout `return 1` and let the caller decide (delegated-job path should abort + rollback rather than "proceed anyway"). | `lib.sh` | Low | -| **M3** | Resume workflow: replace the unconditional `Enter/Down/Enter` block with a conditional loop โ€” poll `_pane_dialog_open`; send navigation keys only when a trust-dialog signature is actually present; skip cleanly otherwise. | `multi-agent-mux-resume/SKILL.md` (embedded shell) | Medium โ€” needs scratch-spawn validation | -| **M4** | Stop graceful path: before sending `$exitkey`, run the dialog check (+ optional single Escape); deliver exitkey via `send_keys_safe`; keep the SIGTERM/SIGKILL fallback chain untouched. | `stop_session.sh` | Low | -| **M5** | Docs: fix the stray-Enter probe example (`create/SKILL.md:214-215`) to use `capture-pane` readiness; document `send_keys_safe` in create/delegate-job SKILL.md; mark **FW-W2 resolved** in `FUTURE_WORKS.md` / `.ko.md`. | docs only | None | - -**Verification gate (DoD)** โ€” all on a scratch tmux server (`-L sks-test`), never real sessions: -1. **RC-A stress**: mock TUI that floods output for 10 s before reading stdin โ†’ `send_keys_safe` must wait, then deliver; old `inject_instructions` demonstrably drops the Enter. -2. **RC-B/C dialog**: mock script printing a trust-dialog signature and swallowing keys โ†’ helper must refuse to paste, honor timeout/Escape policy, and return code 2. -3. **E2E regression**: real `create --submit-job` on a scratch workspace โ†’ instructions submitted, `started` event observed; normal create/stop/resume unchanged. -4. `bash -n` + `shellcheck` on `lib.sh`, `create_session.sh`, `stop_session.sh`: 0 new findings. -5. Estimated diff: ~70 lines added to `lib.sh`, <15 lines each elsewhere. - ---- - -## 5. Summary - -Every injection site in the codebase shares one flaw: **keys are sent on a timer, not on evidence.** The fix is a single evidence-based delivery helper (`send_keys_safe`: quiescence โ†’ dialog gate โ†’ paste-verify โ†’ submit-verify-retry) plus honesty in the readiness gate (`wait_for_tui_ready` must not call a modal dialog "ready" and must be allowed to fail). Migration touches one library, two scripts, and two docs, and closes roadmap item FW-W2. diff --git a/.agents/reports/canary-projects-multi-agent-mux-creator-claude/report-prompt-lock-review-final.md b/.agents/reports/canary-projects-multi-agent-mux-creator-claude/report-prompt-lock-review-final.md deleted file mode 100644 index 7855536..0000000 --- a/.agents/reports/canary-projects-multi-agent-mux-creator-claude/report-prompt-lock-review-final.md +++ /dev/null @@ -1,85 +0,0 @@ -# Prompt-Lock Fix โ€” Final Review (Creator Claude) - -- **Reviewer**: Creator Claude (`canary-projects-multi-agent-mux-creator-claude`) -- **Brief**: `.mam/reports/brief-rereview-prompt-lock.md` -- **Round 1** (2026-07-11, commit `e613f4a`): โŒ FAIL โ€” full findings preserved in git history (this file as committed in `da895fc`). -- **Round 2** (2026-07-11, commit `da895fc`): โŒ **FAIL โ€” one single-line blocker remains** (F5, new in the fix commit). Everything else is verified fixed. -- **Round 3** (2026-07-11, working tree on top of `da895fc`): โœ… **PASS** โ€” see below. - ---- - -## Round 3 Verdict: โœ… PASS (working-tree state; commit required) - -The F5 fix is applied in the working tree of `create_session.sh:387-388` **byte-identical to the prescribed replacement**: - -```bash -rc=0 -inject_instructions "$SESSION_NAME" "$instructions" "$DELEGATE_JOB_ID" || rc=$? -``` - -- Idiom correctness under `set -euo pipefail` was already proven empirically in round 2 (P2: event published with true `rc=4`, EXIT trap fires, script exits 1). The `||` form suppresses `set -e` for the command, so injection failures now reach `delegate_publish_event error` โ€” MS-7's no-zombie-jobs contract holds on the failure path. -- `bash -n` passes; shellcheck `-S warning`: **0 findings**. -- Diff scope verified: the only code change versus `da895fc` is this 4-line block; all other working-tree changes are review reports. -- lib.sh is unchanged since round 2, where the full functional suite passed 5/5 against the committed helpers (T-A3โ€ฆT-E3: dialog refusal rc=2 / flood rc=1 / happy-path rc=0 / instant banner / one-Enter trust acceptance). - -**Conditions attached to this PASS:** -1. The fix is **uncommitted** โ€” it must be committed for the verdict to bind to a ref (suggested: `fix(create): make injection-failure error event survive set -e (|| rc=$?)`). Include the pending review reports (this file, Reviewer Cline's staged modification and new v2 report) per the durable-reports convention. -2. **DoD-5 follow-up** (non-blocking, reaffirmed): capture-validate the dialog signature tokens for agy/hermes/cline in the field; claude tokens match known real CLI text and unmatched tokens now fail loud, not silent. -3. Update FW-W2's resolution commit reference once the fix commit exists. - ---- - -## Round 2 Verdict: โŒ FAIL (NOT PASS) โ€” F5 only - -### โœ… F1 (blank-padded viewport windows) โ€” VERIFIED FIXED -`da895fc` applies the prescribed `_pane_tail()` helper verbatim (lib.sh:1117) and rewires all three windowing sites (`_pane_dialog_open`, `send_keys_safe` submit-verify, `handle_startup_dialogs`). Re-ran the full functional suite against the **committed** code on an isolated scratch server (`tmux -L sks-review`): - -| Test | Scenario | Expected | Result | -|---|---|---|---| -| T-A3 | dialog mock, `SKS_DIALOG_TIMEOUT=6` | rc=2, zero paste leakage | โœ… rc=2, 0 occurrences in pane | -| T-B3 | perpetually flooding pane | rc=1 (quiescence gate) | โœ… rc=1 | -| T-C3 | happy-path mock prompt TUI | rc=0, line received | โœ… rc=0, `RECEIVED-OK len=41` | -| T-D3 | ready banner on screen | fast return 0 | โœ… rc=0 in 0 s | -| T-E3 | trust dialog then banner | exactly one Enter, ready detected | โœ… rc=0 in 2 s, banner reached | - -`bash -n` passes; shellcheck `-S warning` on lib.sh: 0 findings. - -### โŒ F5 โ€” NEW BLOCKER: the F3 fix regressed error-event publication under `set -e` -`create_session.sh` runs under `set -euo pipefail` (line 20). The new form (lines 387-392): - -```bash -inject_instructions "$SESSION_NAME" "$instructions" "$DELEGATE_JOB_ID" -rc=$? -if [ "$rc" -ne 0 ]; then - delegate_publish_event "$DELEGATE_JOB_ID" error "instruction injection failed (prompt-lock, rc=$rc)" -``` - -Under `set -e`, a **bare failing command aborts the script immediately** โ€” `rc=$?` and the `delegate_publish_event error` line are never reached. Proven empirically: - -``` -set -euo pipefail; f(){ return 4; }; trap "echo TRAP-FIRED" EXIT -f; rc=$?; echo "EVENT-PUBLISHED rc=$rc" โ†’ output: TRAP-FIRED only, exit 4 -rc=0; f || rc=$?; if [ "$rc" -ne 0 ]; ... โ†’ output: EVENT-PUBLISHED rc=4, TRAP-FIRED, exit 1 -``` - -Consequence on injection failure: the EXIT trap still rolls back the session and isolation home, but **no terminal `error` event is ever published** โ€” the delegator waits for watchdog timeout. That is precisely the zombie-job outcome MS-7 exists to prevent, so the fix traded round 1's cosmetic `rc=0` misreport (F3) for a functional regression on the same path. Ironically the round-1 code *did* publish the event. - -**Required fix (verified above, one line):** -```bash -rc=0 -inject_instructions "$SESSION_NAME" "$instructions" "$DELEGATE_JOB_ID" || rc=$? -if [ "$rc" -ne 0 ]; then -``` - -Scope confirmed limited to this one site: the delegate-job wrapper uses the `if ! send_keys_safe โ€ฆ` guard form and `stop_session.sh` uses `send_keys_safe โ€ฆ || echo โ€ฆ` โ€” both are `set -e`-safe and report correct rc. - -### Remaining non-blocking items -1. **DoD-5 (real-TUI token validation)** โ€” still no recorded capture evidence. Partially mitigated: the claude tokens (`Do you trust the files`, `Yes, proceed`/`No, exit`) match the real Claude Code CLI dialog text, and with fail-loud semantics an unmatched token now degrades to a loud rcโ‰ 0 + rollback rather than a silent lock. Recommendation to Planner: accept with a follow-up task to capture-validate agy/hermes/cline dialog text in the field, rather than blocking on it again. -2. **Working-tree hygiene**: `.agents/reports/canary-projects-multi-agent-mux-reviewer-cline/report-prompt-lock-analysis.md` has an uncommitted modification โ€” a committed audit record edited in place (not by me). Commit or revert it deliberately alongside the F5 fix. -3. FW-W2 stays legitimately marked resolved once F5 lands; update its commit reference then. - ---- - -## Summary for the Planner - -The hard problem is solved and proven: dialog gating, quiescence, banner detection, and trust-dialog acceptance all behave correctly on the committed helpers (5/5 functional tests). What remains is a one-line `set -e` idiom fix in `create_session.sh` (`|| rc=$?`) so injection failures publish their terminal error event โ€” the empirical proof and exact replacement are above. Fix that line, decide the stray report edit, and round 3 is a rubber stamp. diff --git a/.agents/reports/canary-projects-multi-agent-mux-creator-claude/report-skill-optimization-analysis.md b/.agents/reports/canary-projects-multi-agent-mux-creator-claude/report-skill-optimization-analysis.md deleted file mode 100644 index f8c17c2..0000000 --- a/.agents/reports/canary-projects-multi-agent-mux-creator-claude/report-skill-optimization-analysis.md +++ /dev/null @@ -1,163 +0,0 @@ -# MAM Skill Optimization Analysis (Creator Claude) - -- **Analyst**: Creator Claude (`canary-projects-multi-agent-mux-creator-claude`) -- **Date**: 2026-07-11 -- **Brief**: `.mam/reports/brief-skill-optimization-analysis.md` -- **Scope**: all 8 shell entry points under `.agents/skills/` โ€” 3,422 lines total (`lib.sh` 1212, `reconcile.sh` 644, delegate-job wrapper 440, `create_session.sh` 408, `stop_session.sh` 370, `update_yaml_resumed.sh` 164, `status.sh` 140, `resolve_session_id.sh` 44) -- **Audit baseline**: working tree on `da895fc` + the uncommitted prompt-lock F5 fix in `create_session.sh` (reviewed PASS, awaiting commit) -- **Method**: full-tree greps (sleeps, tmux-resolution variants, `|| true`/`2>/dev/null`, BASH_SOURCE, heredocs, eval), shellcheck run, targeted reads of every flagged site. - -## Baseline strengths (for calibration) - -Uniform `#!/usr/bin/env bash` + `set -euo pipefail` across all 7 executables (lib.sh correctly bare as a sourced library); zero `eval` in any executable script; zero warning-level shellcheck findings beyond 6 pre-existing ones; the worst sleep offenders (resume's blind `sleep 5/3`, inject's `sleep 0.5`+blind C-m) were already eliminated by the FW-W2 `send_keys_safe` work. The findings below are the next tier. - ---- - -## Focus 1 โ€” Inefficient Polling / Sleeps - -### S1 (HIGH VALUE) โ€” `stop_session.sh:193,200`: fixed post-kill waits -```bash -tmux send-keys โ€ฆ # graceful exitkey -sleep 3 # โ† always pays 3 s -โ€ฆ -tmux kill-session โ€ฆ -sleep 5 # โ† always pays 5 s -``` -Every graceful stop pays the full 3 s even when the agent exits in 200 ms, and the kill path always pays 5 s. Worse than slow: on a loaded host an agent needing >3 s to flush **falsely escalates** to SIGTERM. **Proposal**: add to lib.sh โ€” -```bash -# _wait_session_gone โ€” returns 0 as soon as the session dies -_wait_session_gone() { - local sess="$1" max="${2:-5}" i - for ((i = 0; i < max * 4; i++)); do - _sks_tmux has-session -t "$sess" 2>/dev/null || return 0 - sleep 0.25 - done - return 1 -} -``` -Replace `sleep 3` with `_wait_session_gone "$SESSION_NAME" 5` and `sleep 5` with `_wait_session_gone "$SESSION_NAME" 8`. Reactive (typical stop drops from ~8 s to <1 s), *and* more tolerant of slow exits. - -### S2 (HIGH VALUE) โ€” delegate-job `:119` and `:205`: `sleep 1` as MQTT handshake -The comment admits the ordering dependency ("MQTT does not queue non-retained messages for absent subscribers"), then guesses: if CONNACK+SUBACK takes >1 s (public broker `broker.hivemq.com` over WAN โ€” entirely realistic), the agent's `started` event is **lost silently** and the job idles to timeout; on a local broker the 1 s ร—2 per review-loop iteration is pure waste. **Proposal** (event-driven handshake, also fixes E4): `job_subscriber.py` already logs to `$logf` โ€” have it print a sentinel line (e.g. `SUBSCRIBED `) from its `on_subscribe` callback (flush immediately), then in the wrapper replace both sleeps with: -```bash -for _ in {1..25}; do grep -q '^SUBSCRIBED ' "$logf" 2>/dev/null && break; sleep 0.2; done -grep -q '^SUBSCRIBED ' "$logf" || { echo "ERROR: subscriber never reached SUBACK (see $logf)" >&2; exit 1; } -``` -Removes the race instead of betting on it, and converts a dead-on-arrival subscriber (see E4) into a loud failure. - -### S3 (minor) โ€” `lib.sh:1042-1085` `wait_for_tui_ready` -Two `capture-pane` invocations per iteration (`_pane_dialog_open` + its own `content=$(โ€ฆ)`) with a hand-rolled `local_tmux`. Capture once per iteration into a variable and test both predicates on it; use `_pane_capture` (see D4). The 15ร—1 s poll budget itself is fine. - -### S4 (accepted as-is) โ€” `reconcile.sh:273` `sleep "$POLL_INTERVAL"` broker-down fallback loop is by design; see E1 for its real problem (silence, not pacing). - ---- - -## Focus 2 โ€” Helper Duplication & Modularization - -### D1 (HIGH VALUE) โ€” four divergent server-aware tmux resolutions -| Site | Form | -|---|---| -| `lib.sh:1104-1110` `_sks_tmux()` | function โ€” **canonical, word-split-safe** | -| `lib.sh:1043-1046` (`wait_for_tui_ready`) | `local_tmux="tmux -L $NAME"` string | -| `create_session.sh:212-215` | same string pattern (file also has a `_tmux` helper used by its trap โ€” two mechanisms in one script) | -| delegate-job `:347-350` | `_tmux="tmux -L $NAME"` string | - -The string variants rely on unquoted word-splitting (`$local_tmux send-keys โ€ฆ`) โ€” the exact idiom class shellcheck SC2086 exists for, and each future call site must re-remember the `!= default` rule. **Proposal**: rename/promote `_sks_tmux` to `mam_tmux()` (keep `_sks_tmux` as an alias for compatibility) and replace all three string variants. Mechanical, ~10 lines net deletion. - -### D2 โ€” delegate-job wrapper: duplicated subscriber-spawn + instruction template -The registerโ†’spawn-subscriberโ†’sleepโ†’build-`instructions` block appears twice (direct path `:113-131`, review-loop path `:199-215`) and the copies have already drifted (log filename schema differs; the review-loop copy carries iteration metadata the direct copy lacks). Extract `_spawn_job_subscriber ` and `_job_instruction_block `; combine with S2 so the handshake logic exists exactly once. - -### D3 โ€” ready/dialog token lists duplicated inside lib.sh -Claude ready-tokens `'Anthropic|Assistant|Chat|Welcome|projects'` at **both** `lib.sh:1058` (`wait_for_tui_ready`) and `lib.sh:1205` (`handle_startup_dialogs`); trust-dialog tokens split between `_pane_dialog_open` (`:1137-1139`) and `handle_startup_dialogs`' specific greps (`:1199,1201`). Token-list drift between two grep sites is **precisely the class of defect just fixed in the prompt-lock round** โ€” next TUI release, someone updates one list and not the other. **Proposal**: single-source constants near the top of lib.sh โ€” -```bash -_MAM_DIALOG_TOKENS='Do you trust the files|Yes, proceed|No, exit|Allow this|Press Enter to continue|browser to authenticate|Use arrow keys|Esc to cancel' -_MAM_READY_TOKENS_CLAUDE='Anthropic|Assistant|Chat|Welcome|projects' -``` -plus a `_ready_regex_for ` case-helper so `wait_for_tui_ready`'s per-agent regexes live in one lookup. All grep sites reference the variables. - -### D4 โ€” `wait_for_tui_ready` predates its own library's capture helpers -It hand-builds `local_tmux` and calls raw `capture-pane` instead of `_pane_capture`/`_pane_tail`. Folding it onto the helpers (with S3's single-capture-per-iteration) deletes ~8 lines and closes D1's second row for free. - -### D5 (micro) โ€” `stop_session.sh:128-129`: two `python3 -c` processes to read two JSON fields from the same `$MAPPED_DATA`. One process printing both (`'โ€ฆ; d=json.load(sys.stdin); print(d.get("cwd",""), d.get("job_id",""), sep="\t")'`) halves the fork cost; or add a tiny `json_get` helper to lib.sh if more call sites appear. - ---- - -## Focus 3 โ€” Portability & POSIX Compliance - -Shebang discipline means raw-`sh` execution is not a real exposure; the genuine gaps are three, and two are **already roadmapped** โ€” listed here with confirmations, not double-counted as new: - -### P1 (= FW-P1 / FW-D3, confirmed at `lib.sh:254-255`) -```bash -mountpoint="$(df --output=target "$f" 2>/dev/null | tail -1)" || return 1 -if mount | grep -q "$mountpoint.*nfs|โ€ฆ" -``` -GNU-only `df --output` + Linux `mount` output format. On macOS/BSD, `df` errors โ†’ suppressed by `2>/dev/null` โ†’ `_check_is_nfs` silently returns "not NFS" โ†’ **the NFS/WAL safety switch is dead exactly where flock is least reliable**. Portable replacement: `mountpoint="$(df -P "$f" 2>/dev/null | awk 'NR==2{print $6}')"` (`df -P` is POSIX) and probe filesystem type via `stat -f -c %T` on Linux / `stat -f %T` on BSD behind a `case "$(uname)"` โ€” or at minimum log a warning when detection is unavailable instead of silently passing. - -### P2 (= FW-P5, confirmed at `lib.sh:17`) -`SKILL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"` โ€” under zsh sourcing (documented agent workflow: `source .agents/skills/lib.sh`), `BASH_SOURCE` is empty โ†’ `dirname ""` โ†’ `.` โ†’ `SKILL_DIR` silently becomes the caller's cwd, and every relative resolution downstream (`:950`, `:966`) misroutes. **Proposal (fail-loud, 3 lines at the top of lib.sh)**: -```bash -if [ -z "${BASH_SOURCE:-}" ]; then - echo "lib.sh must be sourced from bash (zsh/sh detected)" >&2; return 1 2>/dev/null || exit 1 -fi -``` -Silent misresolution becomes an immediate, explained failure. (Full zsh support via `${(%):-%N}` is possible but not worth the dual-dialect maintenance.) - -### P3 (= FW-P6, confirmed) โ€” depth-hardcoded root resolution -`status.sh:29` (`โ€ฆ/../../../../`), `reconcile.sh:48`, and the `../..` sourcing prologue in all 6 skill scripts. One directory-layout refactor breaks all of them at once. FW-P6's marker-walk (`find_workspace_root()` ascending to `.git`/`.mam`/`.env`, exported once as `WORKSPACE_ROOT`) remains the right fix; the sourcing prologues can stay relative (they express a true structural invariant *within* the skills tree) โ€” it's the **workspace-root** hops that should go through the marker walk. - -### P4 (non-issues, verified): fractional `sleep 0.5/0.25` (GNU+BSD+busybox all accept), `head -c`/`tail -c`/`awk NF` (POSIX), no `grep -P`, no `sed -i`, no `readlink -f`, no `eval` โ€” clean. - ---- - -## Focus 4 โ€” Error Handling & Robustness - -### E1 (HIGHEST SEVERITY in this audit) โ€” `reconcile.sh:269`: degraded mode is fully silent -```bash -bash "$_self" --once --emit-diff >/dev/null 2>&1 || true -``` -This runs *only* in the broker-down fallback โ€” the mode whose entire purpose is "keep reconciling when eventing is gone" โ€” and it discards stdout, stderr, **and** the exit code. If reconciliation itself is failing every cycle (locked DB, missing python module, corrupted YAML), the operator sees a healthy-looking monitor while drift accumulates unboundedly. **Proposal**: -```bash -if ! out=$(bash "$_self" --once --emit-diff 2>&1); then - fails=$((fails + 1)) - echo "[$(date -u +%FT%TZ)] poll-reconcile failed ($fails consecutive): ${out##*$'\n'}" >&2 - [ "$fails" -ge 5 ] && { echo "FATAL: 5 consecutive reconcile failures โ€” exiting for supervisor restart" >&2; exit 1; } -else - fails=0 -fi -``` - -### E2 โ€” deliberate vs. accidental suppression (survey result) -The 18 `|| true` / 31 `2>/dev/null` sites were individually reviewed. The large majority are **legitimate idempotency guards** (stop's kill-chain probing possibly-absent sessions; `_pane_capture`'s probe semantics) โ€” no action. The accidental class is E1 (above) and E4 (below). - -### E3 โ€” `stop_session.sh:128-129`: unguarded JSON parse under `set -e`, no EXIT trap -Malformed registry JSON kills the stop mid-flight with a bare Python traceback; unlike `create_session.sh`, `stop_session.sh` has **no cleanup/context trap**, so the operator gets no indication of what state the stop reached (exitkey sent? captured? row updated?). Cheap fix: wrap the parse (`โ€ฆ || { echo "ERROR: corrupt registry row for '$SESSION_NAME' โ€” run monitor reconcile" >&2; exit 1; }`) and add a minimal `trap 'echo "stop aborted at stage $STAGE" >&2' ERR` with a `STAGE` variable advanced at each phase. - -### E4 โ€” delegate-job subscriber spawned fire-and-forget -`"$PY" job_subscriber.py โ€ฆ >"$logf" 2>&1 &` followed only by `sleep 1`: if the subscriber dies instantly (bad `--registry-dir`, missing paho-mqtt in the venv), the wrapper proceeds, the agent publishes into the void, and the job "runs" with zero audit trail until timeout. The S2 SUBACK-sentinel handshake converts this to a loud early failure โ€” one fix, two findings (S2+E4). - -### E5 โ€” shellcheck backlog (6 warnings, pre-existing) -`SC2034` ร—2 (`ONCE`, `EMIT_DIFF` "unused" in reconcile.sh โ€” likely consumed inside the python heredoc via env; verify and either export or rename with `_` prefix to document intent), `SC2155` ร—2, `SC2164` ร—2 (`cd` without `|| exit` โ€” real hazard under odd cwd removal). All are โ‰ค2-line fixes; clearing them makes future "0 new findings" review gates strict. - ---- - -## Prioritized Optimization Plan - -| # | Item | Files | Effort | Impact | -|---|---|---|---|---| -| 1 | E1 silent degraded loop โ†’ logged + bounded failures | reconcile.sh | S | Correctness/observability of the safety net | -| 2 | S2+E4 SUBACK sentinel handshake replaces both `sleep 1` | delegate-job wrapper, job_subscriber.py | M | Eliminates event-loss race on slow brokers; loud subscriber failures | -| 3 | S1 `_wait_session_gone` reactive stop | lib.sh, stop_session.sh | S | ~7 s faster stops; no false SIGTERM escalation | -| 4 | D1+D4 `mam_tmux()` unification (retire 3 string variants) | lib.sh, create_session.sh, delegate-job | S | Single source of truth; kills word-split hazard | -| 5 | D3 token-list constants + `_ready_regex_for` | lib.sh | S | Prevents recurrence of the F1-class drift bug | -| 6 | P2 fail-loud non-bash source guard | lib.sh | S | Converts silent misresolution to instant diagnosis (FW-P5) | -| 7 | E3 stop parse guard + stage trap | stop_session.sh | S | Debuggable partial-stop states | -| 8 | D2 delegate-job block extraction | delegate-job wrapper | M | Stops copy drift (already observable) | -| 9 | P1 POSIX NFS detection (FW-P1/FW-D3) | lib.sh | M | Restores the WAL safety switch on macOS/BSD | -| 10 | P3 marker-walk root resolution (FW-P6) | lib.sh, status.sh, reconcile.sh | M | Layout-refactor resilience | -| 11 | E5 shellcheck backlog + D5 micro | reconcile.sh, lib.sh, stop_session.sh | S | Strict lint gate for future reviews | - -Items 1โ€“7 are low-risk and independently landable; 9โ€“10 discharge existing roadmap entries (FW-P1/FW-D3/FW-P5/FW-P6 โ€” update FUTURE_WORKS on landing). Every DoD should include the scratch-server functional suite from the prompt-lock review (T-Aโ€ฆT-E) plus `bash -n` + shellcheck zero-new. - -## Summary - -The tree is in good structural shape โ€” consistent strict-mode headers, no eval, and the recent FW-W2 work already modernized the highest-risk delivery path. The remaining debt clusters into: two **timing bets** that should be handshakes (stop waits, MQTT subscribe), one **silent failure mode** in exactly the code path that exists for resilience (reconcile fallback), and **four copies** of the tmux-server rule plus **two copies** of the TUI token lists โ€” the same drift pattern that caused the last production bug. Eleven changes, mostly small, none speculative. diff --git a/.agents/reports/canary-projects-multi-agent-mux-creator-claude/report-skill-optimization-review-final.md b/.agents/reports/canary-projects-multi-agent-mux-creator-claude/report-skill-optimization-review-final.md deleted file mode 100644 index 75f9efc..0000000 --- a/.agents/reports/canary-projects-multi-agent-mux-creator-claude/report-skill-optimization-review-final.md +++ /dev/null @@ -1,13 +0,0 @@ -# ๐Ÿ“‘ Code Review Report: Skill Optimization Implementation - -- **Reviewer**: Creator Claude (`canary-projects-multi-agent-mux-creator-claude`) -- **Date**: 2026-07-11 -- **Reviewed against**: `.mam/reports/brief-rereview-skill-optimization.md` -- **Verdict**: **PASS** - -## ๐Ÿ”Ž Implementation Review Details -1. **OP-1 (stop_session.sh wait)**: Reactive wait prevents 7 seconds of magic sleeps on shutdown. `|| true` safely shields the caller from `set -e` aborts on slow exits. -2. **OP-2 (delegate-job subscription handshake)**: Sentinel checking loop with `$sub_pid` liveness guard successfully prevents the WAN event loss race. -3. **OP-3 (reconcile.sh wait)**: Dynamic `threading.Event().wait` pacing reduces CPU wake-ups to zero during idle cycles. -4. **OP-4 (mam_tmux dispatcher)**: Infinite recursion successfully resolved via direct execution of `$_REAL_TMUX_PATH`. -5. **OP-6 & OP-7 (lib.sh constants and zsh guard)**: Sourcing guard and token variables pass syntax and safety review. diff --git a/.agents/reports/canary-projects-multi-agent-mux-planner-claude/report-cleanup-plan.md b/.agents/reports/canary-projects-multi-agent-mux-planner-claude/report-cleanup-plan.md deleted file mode 100644 index 8b3428d..0000000 --- a/.agents/reports/canary-projects-multi-agent-mux-planner-claude/report-cleanup-plan.md +++ /dev/null @@ -1,127 +0,0 @@ -# Root Markdown Cleanup Plan (Planner Claude โ€” Final) - -- **Planner**: Planner Claude (`canary-projects-multi-agent-mux-planner-claude`) -- **Date**: 2026-07-11 -- **Brief**: `.mam/reports/brief-planner-cleanup.md` -- **Inputs consolidated**: - 1. Reviewer Cline โ€” `.agents/reports/canary-projects-multi-agent-mux-reviewer-cline/report-markdown-analysis.md` - 2. Creator Claude โ€” `.agents/reports/canary-projects-multi-agent-mux-creator-claude/report-markdown-analysis-crosscheck.md` -- **Executor**: Antigravity - ---- - -## 1. Final Verdict Checklist (Consolidated) - -Both reviewers agree on all 7 verdicts. The single discrepancy is *how* to delete #6, not *whether*. - -| # | File | Cline | Creator Claude | **Final** | -|---|------|-------|----------------|-----------| -| 1 | `task.md` | DELETE | DELETE | โ˜‘ **DELETE** | -| 2 | `implementation_plan.md` | DELETE | DELETE | โ˜‘ **DELETE** | -| 3 | `BOOTSTRAP.md` | KEEP | KEEP | โ˜‘ **KEEP** | -| 4 | `FUTURE_WORKS.ko.md` | KEEP | KEEP | โ˜‘ **KEEP** | -| 5 | `DONE.md` | KEEP | KEEP | โ˜‘ **KEEP** | -| 6 | `session_isolation_discussion.md` | DELETE (standalone) | DELETE **+ inbound-link cleanup** | โ˜‘ **DELETE + link cleanup** (Creator Claude's amendment adopted) | -| 7 | `AGENTS.md` | KEEP | KEEP | โ˜‘ **KEEP** | - -**Discrepancy resolution (#6)**: Creator Claude's cross-check found two live tracked docs still linking to `session_isolation_discussion.md` (`implementation_plan.session_isolation.md:6`, `task.session_isolation.md:3`), which Cline's report missed. A standalone `git rm` would leave dangling links. **Decision: delete the file and surgically remove the two inbound link references in the same commit.** The broader option (archiving the entire session-isolation doc set โ€” `Problem_Definition.md`, `implementation_plan.session_isolation.md`, `task.session_isolation.md`, `session_isolation_handover.md`) is **out of scope** for this plan: those four files were never analyzed under the brief's 7-file scope, so deleting them now would be an unauthorized scope expansion. They are listed in ยง4 as a recommended follow-up requiring separate GM authorization. - ---- - -## 2. Impact Assessment - -Verified by repo-wide grep (`--include='*.md'` plus `deploy/install.sh`, `scripts/install_mam.sh`): - -| File to delete | Inbound references | Impact after this plan | -|---|---|---| -| `task.md` | Only from `implementation_plan.md` (deleted in same commit). `.agents/multi_agent_workflow.md` references the *filename convention* for future planning cycles, not this instance. | โœ… None | -| `implementation_plan.md` | Only from `task.md:3` (deleted in same commit). | โœ… None | -| `session_isolation_discussion.md` | **Live**: `implementation_plan.session_isolation.md:6`, `task.session_isolation.md:3` โ†’ **fixed by T2/T3 edits below**. **Historical** (briefs/reports under `.agents/reports/**`): intentionally left untouched โ€” they are immutable audit records describing a past review of a then-existing file. | โœ… None after T2/T3 | - -KEEP-file safety confirmed: `BOOTSTRAP.md` is in the deploy installer's doc allowlist (`deploy/install.sh:131`); `AGENTS.md` is copied by both installers (`deploy/install.sh:131`, `scripts/install_mam.sh:127,138`); `DONE.md` is linked from `FUTURE_WORKS.md:4`; `FUTURE_WORKS.ko.md` is the active backlog mirror. None are touched. - -No documentation build system exists in this repo (no mkdocs/sphinx config); link integrity is the only build-type concern. - -**Precondition check (resolved)**: the previously flagged uncommitted `.gitignore` change (adding `.agents/reports`) is no longer present โ€” `git diff` is clean. No blocker remains. The only untracked files are the two reviewer reports, which must be committed per the durable-reports convention (`.agents/MULTI_AGENT_RULES.md`). - ---- - -## 3. Execution Instructions (for Antigravity) - -Run from the repo root. All steps are non-interactive. **Do not use `rm` โ€” the three files are git-tracked; use `git rm` so the deletion is staged.** - -### T0 โ€” Preflight (abort if it fails) -```bash -cd /home/godopu16/PuKi/laa/canary_projects/multi-agent-mux -git diff --quiet && git diff --cached --quiet || { echo "ABORT: dirty tree"; exit 1; } -``` -(Untracked files are fine and expected: the two reviewer reports.) - -### T1 โ€” Delete the three files -```bash -git rm task.md implementation_plan.md session_isolation_discussion.md -``` - -### T2 โ€” Remove the inbound link in `implementation_plan.session_isolation.md` (line 6) -Replace the line: -``` -- **๊ด€๋ จ ์ž๋ฃŒ**: [Problem_Definition.md](Problem_Definition.md), [session_isolation_discussion.md](session_isolation_discussion.md) -``` -with: -``` -- **๊ด€๋ จ ์ž๋ฃŒ**: [Problem_Definition.md](Problem_Definition.md) -``` - -### T3 โ€” Remove the inbound link in `task.session_isolation.md` (line 3) -Replace the line: -``` -> ๊ธฐ์ค€ ๋ฌธ์„œ: [implementation_plan.session_isolation.md](implementation_plan.session_isolation.md) (Rev.3) / [session_isolation_discussion.md](session_isolation_discussion.md) -``` -with: -``` -> ๊ธฐ์ค€ ๋ฌธ์„œ: [implementation_plan.session_isolation.md](implementation_plan.session_isolation.md) (Rev.3) -``` -**Surgical constraint (AGENTS.md ยง3): change only these two lines. No other edits to either file.** - -### T4 โ€” Verify no dangling references remain outside the immutable report archive -```bash -grep -rn --include='*.md' 'session_isolation_discussion\|\](task\.md)\|\](implementation_plan\.md)' \ - --exclude-dir=.git . | grep -v '^\./\.agents/reports/' | grep -v '^\./\.mam/' -``` -**Expected output: empty** (exit code 1). Any hit = stop and report back. - -### T5 โ€” Stage the analysis reports and this plan, then commit (single atomic commit) -```bash -git add .agents/reports/canary-projects-multi-agent-mux-reviewer-cline/report-markdown-analysis.md \ - .agents/reports/canary-projects-multi-agent-mux-creator-claude/report-markdown-analysis-crosscheck.md \ - .agents/reports/canary-projects-multi-agent-mux-planner-claude/report-cleanup-plan.md \ - implementation_plan.session_isolation.md task.session_isolation.md -git commit -m "chore(docs): remove obsolete root planning docs per 3-agent markdown audit - -- Delete task.md / implementation_plan.md (deploy URL parameterization - shipped in 6408f4a; checklists were stale) and - session_isolation_discussion.md (superseded by - implementation_plan.session_isolation.md; feature shipped and PASSed) -- Remove the two inbound links to the deleted discussion doc -- Add reviewer analysis reports and this cleanup plan under .agents/reports/" -``` - -### T6 โ€” Post-commit sanity -```bash -git status --short # expected: empty -bash -n scripts/install_mam.sh deploy/install.sh # unchanged, but cheap regression guard -``` - ---- - -## 4. Out-of-Scope Follow-Ups (require separate GM authorization) - -1. **Session-isolation doc set retirement**: `Problem_Definition.md`, `implementation_plan.session_isolation.md`, `task.session_isolation.md`, `session_isolation_handover.md` are also completed-work artifacts. Recommend a follow-up brief to analyze and disposition them as one unit (the durable outcomes already live in `.agents/reports/*/report-isolation-review.md` and git history). -2. **`.ko.md` twins**: verdicts here extend naturally to counterparts (`DONE.ko.md`, `FUTURE_WORKS.md`, `BOOTSTRAP.ko.md`) โ€” all KEEP; no action. -3. The root still holds 18โ†’15 markdown files after this cleanup; a future pass may consider moving design docs to a `docs/` subtree, but that is a layout decision, not cleanup. - ---- - -## Final Authorization - -**Plan status: APPROVED for execution** by Antigravity exactly as written in ยง3. Deviations (non-empty T4 output, preflight failure, edit-line mismatch) must halt execution and be reported back to the Planner. diff --git a/.agents/reports/canary-projects-multi-agent-mux-planner-claude/report-mam-installer-final.md b/.agents/reports/canary-projects-multi-agent-mux-planner-claude/report-mam-installer-final.md deleted file mode 100644 index 85a3e5a..0000000 --- a/.agents/reports/canary-projects-multi-agent-mux-planner-claude/report-mam-installer-final.md +++ /dev/null @@ -1,45 +0,0 @@ -# ๐Ÿ›๏ธ Planner Claude โ€” MAM Installer Final Architecture Re-Review - -- **Scope**: Brief `.agents/reports/brief-rereview-all.md` ยง3 (Planner Claude) -- **Commits under review**: `d7e19fe` โ†’ `66fd1c4` โ†’ `5cb8c39` -- **Date**: 2026-07-11 (supersedes prior NOT PASS revision of this report) -- **Method**: Static diff review + live end-to-end install diagnostics on native host PATH (fresh target, re-run idempotency, pre-existing `AGENTS.md`/`.gitignore`, symlink invocation, shellcheck) - ---- - -## Verdict: โœ… PASS โ€” with one working-tree regression that must NOT be committed - -Both blockers from my prior review (B-1 attach inconsistency in `INSTALL.md`, B-2 false `sqlite3` CLI dependency) are resolved and verified live. The architecture now aligns with MAM standards on the version-control axis. However, an **uncommitted `.gitignore` change adding `.agents/reports`** directly contradicts the durable-reports policy ratified in `d7e19fe` and must be reverted before any commit. - ---- - -## โœ… Resolved and verified - -| Item | Evidence | -|---|---| -| B-1: RC-1 attach alignment | `INSTALL.md` ยง3-1 create example now includes `--tmux-server multi-agent-mux`, matching the ยง3-2 attach socket. Manual flow is now internally consistent (default server in `lib.sh:33` is `default`, so the explicit flag is required and now present). | -| B-2: sqlite3 dependency | `sqlite3` CLI removed from `DEPS`; replaced with hard `python3 -c "import yaml, sqlite3"` check โ€” matching actual runtime usage (all DB access is via Python module in heredocs). **Verified live: install now succeeds on this host's native PATH, which has no `sqlite3` binary.** `INSTALL.md` ยง1 updated accordingly. | -| `flock` removal (correction) | My earlier review implied `flock` was a CLI dependency; on inspection all locking is Python `fcntl.flock` (`reconcile.sh:76`) โ€” the other grep hits are comments. Removing `flock` from `DEPS` in `66fd1c4` was **correct**. | -| `uuidgen` retained | Genuine CLI dependency (`create_session.sh:125,127`, required for `--isolate`); correctly kept in `DEPS`. | -| Report migration | `git ls-files .mam/` empty; durable reports tracked under `.agents/reports//`; `MULTI_AGENT_RULES.md` (+`.ko`) and `INSTALL.md` ยง๐Ÿ›ก๏ธ consistent. Anchored rsync `--exclude='/reports/'` verified to keep internal reports out of targets. | -| `AGENTS.md` non-invasive injection | Verified live with pre-existing `AGENTS.md`: content preserved, marker block appended once, rerun is a no-op. Version-control safe. | -| Hygiene | `bash -n` + `shellcheck` clean; symlink invocation resolves `SRC_DIR`; idempotent second run on fresh and pre-populated targets. | - ---- - -## ๐Ÿšซ Must fix before commit - -**Working-tree `.gitignore` adds `.agents/reports`** (uncommitted). This un-does the durable-reports migration for all *future* reports: already-committed files stay tracked, but new mandated artifacts (e.g., the Reviewer Cline `report-mam-installer-final.md` this brief requires, and this very report) would be silently untracked โ€” reintroducing the exact audit-trail loss the migration fixed. It also conflicts verbatim with `MULTI_AGENT_RULES.md` ("must be explicitly copied to tracked directory paths (specifically under `.agents/reports//`โ€ฆ)"). **Recommendation: revert this hunk.** If the intent was to exclude transient briefs, ignore a narrower pattern (e.g., `.agents/reports/brief-*.md`) โ€” but do not ignore the reports tree itself. - -## โš ๏ธ Minor (non-blocking) - -1. `INSTALL.md` ยง2 step 1 still says the installer checks "`tmux`, `python3`, `sqlite3`" โ€” stale; actual check is `tmux`, `python3`, `rsync`, `uuidgen` + Python `yaml`/`sqlite3` modules. -2. `INSTALL.md` ยง1 omits `uuidgen` (hard dep for `--isolate`) and presents `rsync` without noting it is installer-only. -3. Source `AGENTS.md` lacks the MAM marker block, so a fresh-copy install converges only on the second run (pointer self-injection). Cosmetic; append the marker at copy time to converge in one run. -4. Still open from planning (roadmap, not gating): `.agents/.mam-version` stamping + `--update --delete` upgrade mode; shared `check_deps.sh` used by both installer and `create_session.sh`; bilingual `INSTALL.md`/`INSTALL.ko.md` split per repo convention. - ---- - -## Architecture alignment summary - -With `66fd1c4` and `5cb8c39`, the installer satisfies MAM standards: dependency diagnosis now reflects the true runtime contract, the manual's create/attach flow is consistent, the `.mam/` runtime tree vs. tracked `.agents/` configuration boundary is crisp, and downstream projects' behavioral guidelines are preserved. Deployment across other projects is approved once the `.gitignore` working-tree regression is discarded; the minor doc drift can ride along in a follow-up docs commit. diff --git a/.agents/reports/canary-projects-multi-agent-mux-planner-claude/report-prompt-lock-plan.md b/.agents/reports/canary-projects-multi-agent-mux-planner-claude/report-prompt-lock-plan.md deleted file mode 100644 index 03a5d86..0000000 --- a/.agents/reports/canary-projects-multi-agent-mux-planner-claude/report-prompt-lock-plan.md +++ /dev/null @@ -1,274 +0,0 @@ -# Prompt-Lock Fix Implementation Plan (Planner Claude โ€” Final) - -- **Planner**: Planner Claude (`canary-projects-multi-agent-mux-planner-claude`) -- **Date**: 2026-07-11 -- **Brief**: `.mam/reports/brief-planner-prompt-lock-plan.md` -- **Inputs consolidated**: - 1. Reviewer Cline โ€” `.agents/reports/canary-projects-multi-agent-mux-reviewer-cline/report-prompt-lock-analysis.md` - 2. Creator Claude โ€” `.agents/reports/canary-projects-multi-agent-mux-creator-claude/report-prompt-lock-analysis.md` -- **Executor**: Antigravity -- **Roadmap linkage**: closes **FW-W2** (`FUTURE_WORKS.md:25` / `FUTURE_WORKS.ko.md:24`) - ---- - -## 0. Consolidation Verdict - -Both analyses agree on the root causes (keys sent on **timers, not evidence**; no dialog detection; `wait_for_tui_ready` misclassifies dialogs as ready) and on the remedy shape (evidence-based `send_keys_safe` in `lib.sh`). I adopt **Creator Claude's helper design** as the base with four planner amendments (A1โ€“A4 below). - -**Discrepancy resolved โ€” the delegate-job duplicate.** Cline's Site B is **real and Creator Claude missed it**: `.agents/skills/multi-agent-mux-delegate-job/multi-agent-mux-delegate-job:365-369` is a raw copy-paste of the `inject_instructions` body (verified in code; Creator's "sole caller is `create_session.sh:384`" is technically true of the *function* but ignores the duplicated *logic*). This is the highest-traffic delegation path and **must** be in the mod-sites list (MS-7). I verified `lib.sh` is side-effect-free at source time (only variable defaults + function definitions), so the delegate-job wrapper can safely `source` it โ€” this also retires the copy-paste that violates lib.sh's single-source-of-truth mandate (header ยง4.1). - -**Planner amendments to Creator's helper:** -- **A1 โ€” marker derivation**: Creator's `head -c 200 | tail -c 24` can straddle a newline in the multi-line instructions built at `create_session.sh:374-381`, producing a marker that can never match a single captured line. Amended: last 24 chars of the **last non-empty line**. -- **A2 โ€” submit verification**: Creator's "marker left `tail -n 5`" alone risks a false *failure* (Claude's TUI echoes the submitted prompt into the transcript just above the input box, so the marker can linger in the bottom 5 lines after a successful submit โ†’ spurious retries โ†’ exit 4 โ†’ spurious rollback). Amended: submitted = marker left the **bottom 3 lines** *AND* the pane visibly changed relative to a pre-Enter snapshot. Line count is DoD-tunable (DoD-6). -- **A3 โ€” dialog detection scope**: grep the **bottom 20 lines** of the pane, not the full viewport โ€” dialog signatures appearing in agent *conversation output* higher up must not block delivery forever. -- **A4 โ€” resume needs an accept-policy helper, not `send_keys_safe`**: `send_keys_safe` deliberately *refuses* to type into dialogs; the resume flow must *accept* the trust/bypass dialogs. That is a separate policy helper, `handle_startup_dialogs` (conditional, signature-gated โ€” replaces the blind `Enter/Down/Enter` both reports condemned). - -Non-goal (out of scope, per surgical principle): adding dialog auto-accept to the **create** path โ€” it has never had dialog handling; with MS-2/MS-5 a dialog during create now fails loudly with rollback instead of silently prompt-locking. If field data shows trust dialogs during create, a follow-up can reuse `handle_startup_dialogs`. - ---- - -## 1. Deliverable 1 โ€” Concrete Helper Implementation - -**Insert into `.agents/skills/lib.sh` immediately after `inject_instructions` (after current line 1100).** Plain bash, no new dependencies. - -```bash -# --------------------------------------------------------------------------- -# Prompt-lock safe delivery (FW-W2). Keys are sent on evidence, not timers. -# send_keys_safe returns 0 only if the text was verifiably submitted. -# Exit codes: 1=pane never quiesced 2=dialog blocking input -# 3=paste not visible 4=Enter not accepted -# Callers MUST handle non-zero. -# --------------------------------------------------------------------------- - -# Server-aware tmux (same isolation rule as inject_instructions). -_sks_tmux() { - if [ -n "${TMUX_SERVER_NAME:-}" ] && [ "$TMUX_SERVER_NAME" != "default" ]; then - tmux -L "$TMUX_SERVER_NAME" "$@" - else - tmux "$@" - fi -} - -_pane_capture() { _sks_tmux capture-pane -p -t "$1" 2>/dev/null || echo ""; } - -# _pane_quiescent [tries=20] [interval=0.5] -# Renderer settled = two consecutive identical non-empty captures. -# Defeats RC-A (Blessed/Ink renderer bottleneck) without a magic fixed sleep. -_pane_quiescent() { - local sess="$1" tries="${2:-20}" interval="${3:-0.5}" prev="__none__" cur i - for ((i = 0; i < tries; i++)); do - cur=$(_pane_capture "$sess") - [ -n "$cur" ] && [ "$cur" = "$prev" ] && return 0 - prev="$cur" - sleep "$interval" - done - return 1 -} - -# _pane_dialog_open โ€” focus-stealing modal signatures (trust / -# permission / OAuth / list-selection), checked in the bottom 20 pane lines -# only (dialogs render near the input area; conversation text above must not -# trigger this). Tokens must NOT appear on normal idle prompt screens โ€” -# validate against real captures per agent TUI release (DoD-5). -_pane_dialog_open() { - _pane_capture "$1" | tail -n 20 | grep -Eq \ - 'Do you trust the files|Yes, proceed|No, exit|Allow this|Press Enter to continue|browser to authenticate|Use arrow keys|Esc to cancel' -} - -# send_keys_safe [job_id] -# 1. Wait for renderer quiescence (RC-A). -# 2. Refuse to paste while a dialog is open (RC-B/RC-C): wait up to -# SKS_DIALOG_TIMEOUT (default 30 s); if SKS_DIALOG_ESCAPE=1, send a single -# Escape per poll and re-check. NEVER a blind Enter โ€” accepting an unknown -# dialog is a policy decision, not a delivery detail. -# 3. Paste via unique buffer; verify the text landed (marker visible). -# 4. Submit C-m; verify submission (marker left the input area AND the pane -# changed); retry up to 3 times โ€” re-Enter on unsubmitted text is idempotent. -send_keys_safe() { - local sess="$1" text="$2" job_id="${3:-adhoc}" - local marker pre_submit deadline try - # Verification token: last 24 chars of the last non-empty line (multi-line safe). - marker=$(printf '%s' "$text" | tr -d '\r' | awk 'NF {line=$0} END {print line}' | tail -c 24) - - _pane_quiescent "$sess" || { echo "send_keys_safe: pane never quiesced ($sess)" >&2; return 1; } - - deadline=$(( $(date +%s) + ${SKS_DIALOG_TIMEOUT:-30} )) - while _pane_dialog_open "$sess"; do - if [ "${SKS_DIALOG_ESCAPE:-0}" = "1" ]; then - _sks_tmux send-keys -t "$sess" Escape - sleep 1 - fi - if [ "$(date +%s)" -ge "$deadline" ]; then - echo "send_keys_safe: dialog blocking input ($sess)" >&2 - return 2 - fi - sleep 2 - done - - _sks_tmux set-buffer -b "sks_$job_id" "$text" - _sks_tmux paste-buffer -b "sks_$job_id" -t "$sess" - _sks_tmux delete-buffer -b "sks_$job_id" 2>/dev/null || true - sleep 0.5 - _pane_capture "$sess" | grep -Fq "$marker" || { echo "send_keys_safe: paste not visible ($sess)" >&2; return 3; } - - for try in 1 2 3; do - pre_submit=$(_pane_capture "$sess") - _sks_tmux send-keys -t "$sess" C-m - sleep "$try" - # Submitted = input area released the text AND rendering changed after Enter. - if ! _pane_capture "$sess" | tail -n 3 | grep -Fq "$marker" \ - && [ "$(_pane_capture "$sess")" != "$pre_submit" ]; then - return 0 - fi - done - echo "send_keys_safe: Enter not accepted after 3 tries ($sess)" >&2 - return 4 -} - -# handle_startup_dialogs [timeout_sec=20] -# Post-start/resume dialog policy for claude: accept the trust / bypass -# dialogs ONLY when their signature is positively on screen; return as soon -# as the TUI banner is ready. Replaces the blind Enter/Down/Enter sequence. -# Non-fatal by design: on timeout the caller proceeds (attach shows leftovers). -handle_startup_dialogs() { - local sess="$1" timeout="${2:-20}" waited=0 pane - while [ "$waited" -lt "$timeout" ]; do - pane=$(_pane_capture "$sess" | tail -n 20) - if printf '%s\n' "$pane" | grep -q 'Do you trust the files'; then - _sks_tmux send-keys -t "$sess" Enter # accept trust prompt - elif printf '%s\n' "$pane" | grep -q 'Yes, proceed'; then - _sks_tmux send-keys -t "$sess" Down # select "Yes, proceed" - sleep 0.3 - _sks_tmux send-keys -t "$sess" Enter - elif printf '%s\n' "$pane" | grep -Eq 'Anthropic|Assistant|Chat|Welcome|projects'; then - return 0 # ready, no dialog - fi - sleep 2 - waited=$((waited + 2)) - done - return 0 -} -``` - -> โš ๏ธ **Signature-token caveat (both analyses inherited this)**: neither input report captured the *actual* dialog text of current claude/agy/hermes/cline TUI builds. The token lists above are the best available hypotheses. **DoD-5 makes validating them against real `capture-pane` output a merge blocker** โ€” the executor must adjust tokens to observed text before committing. - ---- - -## 2. Deliverable 2 โ€” Surgical Mod-Sites List - -Every change traces to a verified defect site. No other lines are touched. - -| # | File : lines (current) | Change | -|---|---|---| -| **MS-1** | `.agents/skills/lib.sh` (insert after 1100) | Add the ยง1 helper block verbatim. | -| **MS-2** | `.agents/skills/lib.sh:1056` | `wait_for_tui_ready` claude regex: `"Anthropic\|Assistant\|Chat\|Dangerously\|dangerously\|Enter\|Welcome\|projects"` โ†’ `"Anthropic\|Assistant\|Chat\|Welcome\|projects"` (drop the three tokens that also match trust/bypass dialogs โ€” RC-B fix). | -| **MS-3** | `.agents/skills/lib.sh:1050-1053` | Inside the retry loop, before the `case`: skip the ready-check while a dialog is up โ€” insert `if _pane_dialog_open "$sess"; then sleep 1; continue; fi` after the capture (requires MS-1 helpers; they are defined later in the file but resolved at call time โ€” bash allows this). | -| **MS-4** | `.agents/skills/lib.sh:1083` | `echo "โš ๏ธ Warning: ... Proceeding anyway..."` โ†’ `echo "โš ๏ธ TUI readiness check timed out for '$sess'." >&2; return 1` โ€” the gate must be allowed to fail. | -| **MS-5** | `.agents/skills/lib.sh:1088-1100` | Rewrite `inject_instructions` body as a thin wrapper: `inject_instructions() { send_keys_safe "$1" "$2" "${3:-onboard}"; }` (same signature; sole caller inherits the fix; keep the function comment, note the delegation). | -| **MS-6** | `.agents/skills/multi-agent-mux-create/scripts/create_session.sh:199` | `wait_for_tui_ready "$SESSION_NAME" "$AGENT"` โ†’ explicit guard: `if ! wait_for_tui_ready "$SESSION_NAME" "$AGENT"; then echo "ERROR: agent TUI never became ready โ€” aborting (rollback via trap)" >&2; exit 1; fi` (the `trap cleanup_tmux_on_error EXIT` armed at line 196 kills the session and removes the isolation home). | -| **MS-7** | `.agents/skills/multi-agent-mux-create/scripts/create_session.sh:384` | Guard the injection: `if ! inject_instructions "$SESSION_NAME" "$instructions" "$DELEGATE_JOB_ID"; then delegate_publish_event "$DELEGATE_JOB_ID" error "instruction injection failed (prompt-lock, rc=$?)"; exit 1; fi` โ€” the job gets a terminal `error` event (no more zombie jobs waiting for watchdog timeout), then the EXIT trap rolls the session back. `started` (line 386) now only publishes on verified delivery. | -| **MS-8** | `.agents/skills/multi-agent-mux-delegate-job/multi-agent-mux-delegate-job:364-369` | Replace the duplicated raw block (`set-buffer`/`paste-buffer`/`sleep 0.5`/`C-m`/`delete-buffer`) with: `source "$SCRIPT_DIR/../lib.sh"` (immediately before use; lib.sh is load-side-effect-free โ€” verified) then `if ! send_keys_safe "$sess" "$instructions" "$job_id"; then echo "ERROR: ํ”„๋กฌํ”„ํŠธ ์ฃผ์ž… ์‹คํŒจ โ€” ์„ธ์…˜ '$sess' (ํ”„๋กฌํ”„ํŠธ ์ž ๊ธˆ ์˜์‹ฌ)" >&2; return 1; fi`. Keep the local `_tmux` definition (lines 347-350) โ€” still used by `has-session` (352) and the attach hint (371). The `return 1` propagates under `set -euo pipefail` and fires the EXIT trap at 358-362, which publishes the `error` event. | -| **MS-9** | `.agents/skills/multi-agent-mux-resume/SKILL.md:150-156` | Replace the blind block (`sleep 5; Enter; sleep 3; Down; sleep 0.3; Enter`) with: `handle_startup_dialogs "$SESSION_NAME" 20` (the embedded script already sources `lib.sh` at line 68). Fixes both failure directions: no-dialog โ†’ no stray keys into the prompt/history; late dialog โ†’ polled, not raced. | -| **MS-10** | `.agents/skills/multi-agent-mux-stop/scripts/stop_session.sh:192` | `tmux send-keys -t "$SESSION_NAME" "$exitkey" Enter 2>/dev/null \|\| true` โ†’ `send_keys_safe "$SESSION_NAME" "$exitkey" "stop$$" \|\| echo "graceful: safe delivery failed (rc=$?) โ€” falling back to kill chain"` (script already sources lib.sh at line 32; the SIGTERMโ†’SIGKILL fallback chain at 193-207 stays byte-identical). | -| **MS-11** | `.agents/skills/multi-agent-mux-create/SKILL.md:214-215` | Replace the stray-Enter probe example with a passive one: `tmux capture-pane -t "$SESSION_NAME" -p -S -20 # TUI ready = agent banner visible, no dialog text` (never fire keys as a liveness probe). | -| **MS-12** | `FUTURE_WORKS.md:25`, `FUTURE_WORKS.ko.md:24` | Mark **FW-W2** resolved using the existing FW-D1 strikethrough convention (`~~...~~` + resolution date 2026-07-11 + commit ref), both languages. | - -**Explicitly NOT touched** (verified non-vulnerable, matching Creator ยง2-F): `update_yaml_resumed.sh`, `scripts/install_mam.sh`, `reconcile.sh`, all Python backplane scripts. - ---- - -## 3. Deliverable 3 โ€” Execution Instructions (for Antigravity) - -Run from the repo root, in order. Halt and report back on any non-zero step that isn't explicitly tolerated. - -### T0 โ€” Preflight -```bash -cd /home/godopu16/PuKi/laa/canary_projects/multi-agent-mux -git diff --quiet && git diff --cached --quiet || { echo "ABORT: dirty tree"; exit 1; } -``` -(Untracked files are expected: the two analysis reports and this plan.) - -### T1 โ€” Apply MS-1โ€ฆMS-5 to `lib.sh` -Insert the ยง1 helper block after line 1100; apply the four edits to `wait_for_tui_ready` / `inject_instructions` exactly as specified in ยง2. Then: -```bash -bash -n .agents/skills/lib.sh -``` - -### T2 โ€” Apply MS-6/MS-7 to `create_session.sh`, MS-8 to the delegate-job wrapper, MS-9 to `resume/SKILL.md`, MS-10 to `stop_session.sh`, MS-11 to `create/SKILL.md` -```bash -bash -n .agents/skills/multi-agent-mux-create/scripts/create_session.sh \ - .agents/skills/multi-agent-mux-stop/scripts/stop_session.sh \ - .agents/skills/multi-agent-mux-delegate-job/multi-agent-mux-delegate-job -command -v shellcheck >/dev/null && shellcheck -S warning \ - .agents/skills/lib.sh \ - .agents/skills/multi-agent-mux-create/scripts/create_session.sh \ - .agents/skills/multi-agent-mux-stop/scripts/stop_session.sh || true -``` -Zero *new* findings allowed (pre-existing findings are out of scope). - -### T3 โ€” Verification gate (Definition of Done) โ€” scratch server only, never real sessions -All tmux activity on `tmux -L sks-test`; `tmux -L sks-test kill-server` afterwards. - -1. **DoD-1 RC-A (renderer stall)**: mock TUI that floods stdout for 10 s before reading stdin (`while :; do echo spam; done & sleep 10; kill %1; cat`) โ†’ `send_keys_safe` must wait out quiescence and deliver (rc 0); confirm by capturing the mock's received line. -2. **DoD-2 RC-B/C (dialog block)**: mock that prints `Do you trust the files in this folder?` and swallows input โ†’ `send_keys_safe` must refuse to paste and return **2** after `SKS_DIALOG_TIMEOUT=6`; with `SKS_DIALOG_ESCAPE=1` verify a single Escape per poll, still no blind Enter. -3. **DoD-3 E2E create**: real `create_session.sh --submit-job` on a scratch workspace โ†’ instructions verifiably submitted, `started` event observed, normal stop afterwards. -4. **DoD-4 E2E delegate + resume + stop**: delegate-job `submit` to a running scratch session (delivery via the new path); resume a stopped claude scratch session **twice** โ€” once where the trust dialog appears, once where it doesn't โ€” confirm no stray keys land in the prompt in the second case; `--graceful` stop delivers `/exit` via the helper and the fallback chain still engages when the pane is blocked. -5. **DoD-5 signature validation (merge blocker)**: `capture-pane` the real trust/bypass/permission dialogs of the current claude build; confirm every `_pane_dialog_open` and `handle_startup_dialogs` token matches observed text and none appears on the idle prompt screen; adjust tokens to reality before committing. -6. **DoD-6 A2 tuning**: during DoD-3, confirm the submit check (marker leaves bottom-3-lines + pane change) doesn't false-fail on the TUI's transcript echo; tune the `tail -n 3` count if needed and record the final value in the commit message. - -### T4 โ€” Commit (single atomic commit) -```bash -git add .agents/skills/lib.sh \ - .agents/skills/multi-agent-mux-create/scripts/create_session.sh \ - .agents/skills/multi-agent-mux-create/SKILL.md \ - .agents/skills/multi-agent-mux-delegate-job/multi-agent-mux-delegate-job \ - .agents/skills/multi-agent-mux-resume/SKILL.md \ - .agents/skills/multi-agent-mux-stop/scripts/stop_session.sh \ - FUTURE_WORKS.md FUTURE_WORKS.ko.md \ - .agents/reports/canary-projects-multi-agent-mux-reviewer-cline/report-prompt-lock-analysis.md \ - .agents/reports/canary-projects-multi-agent-mux-creator-claude/report-prompt-lock-analysis.md \ - .agents/reports/canary-projects-multi-agent-mux-planner-claude/report-prompt-lock-plan.md -git commit -m "fix(skills): evidence-based prompt delivery (send_keys_safe) to end prompt-lock (FW-W2) - -- Add send_keys_safe + quiescence/dialog-detection helpers to lib.sh: - keys are sent on pane evidence, never fixed timers; distinct exit - codes 1-4; dialogs are never blindly Enter-ed -- inject_instructions delegates to send_keys_safe; create --submit-job - publishes a terminal error event on delivery failure (no zombie jobs) -- wait_for_tui_ready: drop dialog-ambiguous tokens, treat open dialogs - as not-ready, return 1 on timeout instead of proceeding -- delegate-job wrapper: replace copy-pasted raw paste/C-m block with - lib.sh send_keys_safe (restores single source of truth) -- resume: conditional signature-gated dialog handling replaces blind - Enter/Down/Enter; stop --graceful delivers exitkey safely, fallback - chain unchanged -- create SKILL: passive capture-pane probe instead of stray Enter -- Mark FW-W2 resolved; add 3-agent analysis/plan reports" -``` - -### T5 โ€” Post-commit sanity -```bash -git status --short # expected: empty -grep -n "Proceeding anyway" .agents/skills/lib.sh # expected: no match -grep -rn "sleep 0.5$" .agents/skills/multi-agent-mux-delegate-job/multi-agent-mux-delegate-job # expected: no match -``` - -**Halt conditions**: any DoD failure, any `bash -n` error, any new shellcheck warning, or dialog tokens that cannot be validated (DoD-5) โ†’ stop, do not commit, report back to Planner with the failing capture. - ---- - -## 4. Risk Register - -| Risk | Severity | Mitigation | -|---|---|---| -| Dialog signature tokens don't match real TUI text | High (silently defeats RC-B fix) | DoD-5 is a merge blocker; tokens curated per agent release | -| A2 submit-check false-fails on transcript echo | Medium (spurious rollback) | Pane-change AND-condition + DoD-6 tuning | -| `wait_for_tui_ready` now failing hard changes create-path behavior on slow hosts | Medium | 15ร—1s budget unchanged; failure now rolls back loudly instead of injecting blind โ€” strictly better; monitor first real runs | -| Longer stop latency (`--graceful` quiescence wait) | Low | Fallback chain untouched; worst case โ‰ˆ +10 s before kill-session | -| delegate-job sourcing lib.sh in copied-out installs | Low | Installers ship `.agents/skills/` as a tree incl. lib.sh; verified side-effect-free load | - ---- - -## Final Authorization - -**Plan status: APPROVED for execution** by Antigravity exactly as written in ยง3. DoD-5 (real-capture validation of dialog signatures) is a hard merge blocker. Any deviation halts execution and returns to the Planner. diff --git a/.agents/reports/canary-projects-multi-agent-mux-planner-claude/report-skill-optimization-plan-approved.md b/.agents/reports/canary-projects-multi-agent-mux-planner-claude/report-skill-optimization-plan-approved.md deleted file mode 100644 index 46849ec..0000000 --- a/.agents/reports/canary-projects-multi-agent-mux-planner-claude/report-skill-optimization-plan-approved.md +++ /dev/null @@ -1,13 +0,0 @@ -# ๐Ÿ“‘ Planner Validation Report: Skill Optimization Plan - -- **Reviewer**: Planner Claude (`canary-projects-multi-agent-mux-planner-claude`) -- **Date**: 2026-07-11 -- **Target Plan**: `.agents/reports/canary-projects-multi-agent-mux-planner-claude/report-skill-optimization-plan.md` -- **Verdict**: **PASS (APPROVED)** - -## ๐Ÿ”Ž Validation Details -1. **Recursion Risk (OP-4)**: The initial draft of `mam_tmux` was flagging an infinite recursion loop due to calling the raw `tmux` shell function instead of the resolved path. The hotfix successfully mapped this to `_REAL_TMUX_PATH`, neutralizing the stack overflow risk. -2. **Error Safety (OP-1)**: Calling `_wait_session_gone` as a standalone statement was a severe `set -e` abort hazard in `stop_session.sh`. The integration of the `|| true` guard successfully resolves this. -3. **Correctness**: The event-driven loop and wait structures are functionally safe. - -The plan is approved for immediate integration. diff --git a/.agents/reports/canary-projects-multi-agent-mux-planner-claude/report-skill-optimization-plan.md b/.agents/reports/canary-projects-multi-agent-mux-planner-claude/report-skill-optimization-plan.md deleted file mode 100644 index 522ea26..0000000 --- a/.agents/reports/canary-projects-multi-agent-mux-planner-claude/report-skill-optimization-plan.md +++ /dev/null @@ -1,100 +0,0 @@ -# ๐Ÿ“‘ Multi-Agent Mux (MAM) Skill Optimization Plan - -Based on the joint code audits conducted by **Reviewer Cline** and **Creator Claude**, this plan identifies the structural inefficiencies, duplicate code paths, and latent portability risks in the MAM skills library (`.agents/skills/`), and provides a phased execution blueprint for refactoring and optimization. - ---- - -## ๐Ÿ“Š Summary of Optimization Focus Areas - -The audit of all 8 shell entry points (~3,422 lines) revealed three key areas where the skills codebase can be significantly optimized: -1. **Sleeps to Handshakes (Timing Bets)**: Replacing fixed timing loops with event-driven or reactive waits (e.g., reactive tmux stop, MQTT suback event check). -2. **Structural Consolidation (DRY principle)**: Reducing code duplication across scripts, such as 7 identical copies of the SQLite/YAML loader block and 4 copies of tmux server resolution. -3. **Portability & Observability**: Guarding against zsh path resolution anomalies when sourcing `lib.sh`, and eliminating silent failures inside monitor loops. - ---- - -## ๐Ÿ› ๏ธ Detailed Optimization Items - -### 1. Inefficient Polling & Sleep Reductions - -#### ๐Ÿš€ OP-1: Reactive Tmux Graceful Stopping (`stop_session.sh`) -* **Location**: `stop_session.sh:193,200` -* **Defect**: Graceful stopping uses fixed sleeps (`sleep 3` after sending exitkey, `sleep 5` after kill-session). Every stop operation incurs an unconditional 3โ€“8 s delay, even if the agent session exits in milliseconds. -* **Optimization**: Implement `_wait_session_gone` helper in `lib.sh` that polls `tmux has-session` at a high frequency (e.g., every 250 ms) up to a deadline. -* **Outcome**: Reduces average session stop time from **8 s to <0.3 s** under ordinary circumstances. - -#### ๐Ÿš€ OP-2: MQTT Subscriber Event-Driven Handshake (`delegate-job`) -* **Location**: `multi-agent-mux-delegate-job:119,205` -* **Defect**: Sponsoring a subscriber runs in the background, followed by a blind `sleep 1` to win the race against the agent's startup event publish. If HiveMQ CONNACK/SUBACK is slow, the start event is lost; if fast, 1 s is wasted. -* **Optimization**: Modify `job_subscriber.py` to write a sentinel line (e.g. `SUBSCRIBED `) to its log file on a successful SUBSCRIBE callback. Replace `sleep 1` in the wrapper with a fast-poll loop matching this sentinel. -* **Outcome**: Eliminates event-loss race conditions over WAN brokers, while dropping the startup delay to the physical minimum. - -#### ๐Ÿš€ OP-3: Main Event Loop Pacing (`reconcile.sh`) -* **Location**: `reconcile.sh:243-256` (MQTT client wait) -* **Defect**: The foreground loop spins on a CPU-wake polling model `while True: time.sleep(0.5)` just to compare time differentials for deadlines, bypassing python's event capabilities. -* **Optimization**: Use a `threading.Event()` wait state (`stop.wait(timeout=next_deadline - now)`) to suspend the main thread until a true timeout occurs or an interrupt event fires. -* **Outcome**: Zero-CPU footprint while idling. - ---- - -### 2. Code Duplication & Modularization (DRY) - -#### ๐Ÿš€ OP-4: Unify Divergent Tmux Server Resolvers -* **Location**: `lib.sh:1043-1046`, `create_session.sh:212`, `delegate-job:347` -* **Defect**: String resolution for tmux servers (`local_tmux="tmux -L $TMUX_SERVER_NAME"`) is duplicated 4 times, leading to potential word-splitting hazards (shellcheck SC2086). -* **Optimization**: Extract a single, canonical `mam_tmux()` dispatch function into `lib.sh` that safely handles server arguments and exports them cleanly. - -#### ๐Ÿš€ OP-5: Single-Source the YAML / SQLite Load Boilerplate (7ร— Duplicate) -* **Location**: `lib.sh` (3 sites), `stop_session.sh:87`, `status.sh:42`, `update_yaml_resumed.sh:66`, `reconcile.sh:298` -* **Defect**: The ~20 lines of Python heredoc code that dynamically queries merged YAML and SQLite state is copy-pasted in 7 separate files, each with slightly drifted error policies. -* **Optimization**: Implement `load_state_json` in `lib.sh` which executes the Python boilerplate exactly once and emits the state to stdout as a JSON document. Script files can then parse this single JSON document. - -#### ๐Ÿš€ OP-6: Consolidate TUI Ready / Dialog Tokens -* **Location**: `lib.sh:1058` and `lib.sh:1205` -* **Defect**: Regular expressions for Claude ready-states and trust dialog tokens are duplicated. Updates to one block (e.g. for new Claude versions) can lead to drift and prompt-lock bugs. -* **Optimization**: Declare central constants (`_MAM_DIALOG_TOKENS`, `_MAM_READY_TOKENS_CLAUDE`) at the top of `lib.sh` and refer to them. - ---- - -### 3. Portability & Robustness - -#### ๐Ÿš€ OP-7: Guard against Non-Bash Sourced Environments -* **Location**: `lib.sh:17` and all 8 script headers -* **Defect**: If a user runs a zsh session and types `source .agents/skills/lib.sh`, `${BASH_SOURCE[0]}` resolves to empty, leading to silent path resolution failure. -* **Optimization**: Add a zsh-aware fallback detection block for the parent script path (`ZSH_VERSION` check) or print an explicit exit message warning users not to source from a foreign shell. - -#### ๐Ÿš€ OP-8: Make Degraded Mode Failures Observable (`reconcile.sh`) -* **Location**: `reconcile.sh:269` -* **Defect**: Fallback polling mode (`bash reconcile.sh --once --emit-diff >/dev/null 2>&1 || true`) discards stderr and exit codes. If database locks or SQLite faults occur, the monitor stays silently broken. -* **Optimization**: Capture stdout/stderr of the one-off run. Log errors and exit the loop for supervisor restart if 5 consecutive runs fail. - ---- - -## ๐Ÿ“… Actionable Optimization Roadmap - -We recommend executing these optimizations in three sequential phases: - -```mermaid -gantt - title MAM Skill Optimization Roadmap - dateFormat YYYY-MM-DD - section Phase 1 (Latency) - OP-1 (Reactive Tmux Stop) :active, p1, 2026-07-12, 1d - OP-2 (MQTT Subscribe Handshake):active, p2, after p1, 2d - OP-3 (Event Loop CPU Wait) :p3, after p2, 1d - section Phase 2 (DRY & Consolidate) - OP-4 (Tmux Dispatcher) :p4, 2026-07-15, 1d - OP-5 (JSON Loader Helper) :p5, after p4, 2d - OP-6 (Ready Token Constants) :p6, after p5, 1d - section Phase 3 (Portability & Safety) - OP-7 (zsh Source Guard) :p7, 2026-07-19, 1d - OP-8 (Reconcile Observability) :p8, after p7, 1d -``` - ---- - -## ๐Ÿ“‹ Definition of Done (DoD) for Optimizations -1. **Shell Linting**: `bash -n