Files
ewoooc/docs/runbooks/aider-heal-110-setup-sop.md

7.5 KiB
Raw Blame History

AiderHeal 110 主機部署 SOPADR-020

解決 2026-05-03 發現的 AiderHeal 100% no-op 根因110 主機上 AIDER_REPO_PATH (/home/wooo/ewoooc) 不存在,所有 cd 立刻失敗,|| true 吞掉錯誤後整條 pipeline 走完卻 0 次 push。

本 SOP 設定一次後永久生效,需統帥手動執行(牽涉 SSH key 部署 + Gitea push 權限驗證)。


前置確認

# 檢查項 命令
1 110 主機可達 ssh wooo@192.168.0.110 hostname
2 110 上是否已有 ~/.ssh/autoheal_id_ed25519 ssh wooo@192.168.0.110 'ls -la ~/.ssh/autoheal*'
3 188 容器內 config/autoheal_id_ed25519 是否存在 ssh ollama@192.168.0.188 'ls -la /home/ollama/momo-pro-system/config/autoheal*'
4 Gitea 上該 ssh key 是否已加為 deploy keywrite 權限) Gitea → wooo/ewoooc → Settings → Deploy Keys

若 #2 #3 都 OK 且 #4 已加 → 直接跳到「步驟 2 clone repo」
若 #2 缺 key → 走「步驟 1 部署 SSH Key」
若 #4 沒加 → 走「步驟 3 加 Gitea Deploy Key」


步驟 1部署 SSH Key 到 110 主機

容器內已有的 key 同步到 110作為 110 push 回 Gitea 的身份。

# 從 188 取出私鑰container mount 點)
ssh ollama@192.168.0.188 'cat /home/ollama/momo-pro-system/config/autoheal_id_ed25519' \
  | ssh wooo@192.168.0.110 'umask 077 && cat > ~/.ssh/autoheal_id_ed25519'

# 取公鑰
ssh ollama@192.168.0.188 'cat /home/ollama/momo-pro-system/config/autoheal_id_ed25519.pub' \
  | ssh wooo@192.168.0.110 'cat > ~/.ssh/autoheal_id_ed25519.pub'

# 設權限
ssh wooo@192.168.0.110 'chmod 600 ~/.ssh/autoheal_id_ed25519 && chmod 644 ~/.ssh/autoheal_id_ed25519.pub'

# 在 ~/.ssh/config 加 host alias 讓 git 自動用此 key
ssh wooo@192.168.0.110 'cat >> ~/.ssh/config << "EOF"

Host gitea-autoheal
    HostName 192.168.0.110
    Port 3022
    User git
    IdentityFile ~/.ssh/autoheal_id_ed25519
    IdentitiesOnly yes
EOF
chmod 600 ~/.ssh/config'

Port 3022 確認:用 ssh wooo@192.168.0.110 'docker ps | grep gitea' 看 Gitea SSH port預設 3022 但可能不同。


步驟 2在 110 上 clone repo 到 /home/wooo/ewoooc(直接 SSH clone

注意:從一開始就用 SSH clone,避免 HTTP clone 在 private repo 卡帳密 prompt + 跟步驟 1 部署的 key 不關聯。先確認 Gitea SSH port預設 3022 但可能被改):

ssh wooo@192.168.0.110 'docker ps --format "{{.Ports}}" | grep gitea'

從輸出找到 0.0.0.0:NNN->22/tcp 的 NNN 即為 Gitea SSH port。下方用 3022 為例,請依實況替換

ssh wooo@192.168.0.110 << 'EOF'
set -e
cd ~

# 防呆:如果 ewoooc 已存在但不是 git repo可能舊垃圾先備份
if [ -d ewoooc ] && [ ! -d ewoooc/.git ]; then
    mv ewoooc ewoooc.bak.$(date +%s)
fi

# 直接 SSH clone複用步驟 1 部署的 key + ~/.ssh/config 的 gitea-autoheal alias
if [ ! -d ewoooc/.git ]; then
    git clone gitea-autoheal:wooo/ewoooc.git ewoooc
fi

cd ewoooc

# 設 git identity 讓 AiderHeal commit 有可識別作者
git config user.name "AiderHeal"
git config user.email "autoheal@wooo.work"

# 確認 remote 走 SSHgitea-autoheal alias 自帶正確 port + key
git remote -v
git log --oneline -3
EOF

驗證:應印出 origin gitea-autoheal:wooo/ewoooc.gitfetch+push 兩行)和最近 3 個 commit。

若 clone 失敗報 Permission denied (publickey):步驟 3 的 Gitea Deploy Key 還沒加或沒勾 write access先回去處理步驟 3。


步驟 3在 Gitea 加 Deploy Key若 #4 沒加)

  1. 取公鑰:
    ssh wooo@192.168.0.110 'cat ~/.ssh/autoheal_id_ed25519.pub'
    
  2. Gitea Web UI
    • http://192.168.0.110:3001/wooo/ewoooc/settings/keys
    • Add Deploy Key
    • Title: AiderHeal 110 host
    • Key: 貼上 #1 的公鑰
    • 勾選 Allow write access(必要!否則只能 fetch 不能 push
    • Add Key

步驟 4端到端驗證

4a. 110 上手動測試 push 鏈

ssh wooo@192.168.0.110 << 'EOF'
cd ~/ewoooc
git fetch origin main
git status
EOF

預期:fetch 不報錯,status 顯示 Your branch is up to date

4b. 從 188 容器測試 SSH 鏈(模擬 AiderHeal preflight

早期版本曾用 docker exec ... bash -c "ssh ... \"...\"" 三層引號,內層雙引號會被中層吃掉,導致 && echo PREFLIGHT_OK 變成本地 echo 而非 remote echo —— 永遠 false positive。改用 heredoc + 單引號嵌套保護:

ssh ollama@192.168.0.188 << 'OUTER'
docker exec momo-pro-system bash -c '
  ssh -i /app/config/autoheal_id_ed25519 \
      -o StrictHostKeyChecking=no \
      wooo@192.168.0.110 "test -d /home/wooo/ewoooc/.git && echo PREFLIGHT_OK"
'
OUTER

預期輸出:PREFLIGHT_OK從遠端 110 印出,非本地)。

驗證真假:故意把 path 寫錯一個字母,應該 0 輸出(不該印 PREFLIGHT_OK

4c. 觸發 AiderHeal pipeline 觀察

任意推一個會被 Hermes 找到 finding 的 commit或統帥 push 一個下次自然有 finding 的 commit等 2 分鐘後查:

# 看是否有 AiderHeal 簽名的新 commit
git fetch origin main && git log --pretty='%h | %an | %s' origin/main -5

預期:看到 author 是 AiderHeal 或 commit message 開頭 fix(autoheal): 的新 commit。

4d. 看容器 log

ssh ollama@192.168.0.188 'docker logs momo-pro-system --since 10m 2>&1 | grep -E "event=(heal_start|aider_exec|push_ok|preflight_failed|setup_failed)"'

預期:event=heal_startevent=aider_exec(停 1060sevent=push_ok 連貫出現,不應看到 event=preflight_failed


故障排除

症狀 可能原因 排查
event=preflight_failed 110 上 ~/ewoooc 不存在 / 不是 git repo 重跑步驟 2
event=setup_failed 顯示 Permission denied (publickey) Gitea deploy key 未加 / write 權限沒勾 檢查步驟 3
event=push_failed 顯示 remote: hook declined Gitea 設 protected branch 在 Gitea 把 main 從 protected 移除(或加 deploy key 為例外)
event=no_diff 但 aider 確實看到問題 aider 模型品質不佳qwen2.5-coder:7b 太小) AIDER_MODEL env例如 ollama/deepseek-coder-v2:16b;需 110 上有對應 model
event=diff_too_large 連續發生 finding 牽涉檔案 > 50 行修改 調 AIDER_MAX_DIFF_LINES env但建議保留 50 作 ADR-020 安全網

安全護欄回顧ADR-020

L 機制 觸發點
L0 preflight 路徑檢查 aider_heal_executor.py:execute_code_fix 白名單通過後
L1 檔案白名單 ^(services|routes|database)/(?:[a-zA-Z0-9_]+/)*[a-zA-Z0-9_]+\.py$,允許子目錄但不允許 tests/ ALLOWED_FILE_PATTERN
L2 diff > 50 行拒絕 push AIDER_MAX_DIFF_LINES
L3 每小時最多 5 次 CODE_FIX _enforce_rate_limit
L4 health check 失敗自動 git revert _revert_last_commit
L5 Telegram 通知(成功/失敗/回滾) _notify_telegram → EventRouter

主開關:CODE_REVIEW_AUTO_FIX_ENABLED=falsedocker-compose env即時切斷整條鏈。


完成後更新

  • 110 上 ~/ewoooc 存在且 git remote -v 顯示走 SSH push
  • Gitea deploy key 已加write access 勾選
  • 步驟 4b 印出 PREFLIGHT_OK
  • 至少一次自然觸發 AiderHeal 後看到 fix(autoheal): commit
  • 通知 Claude 把 memory feedback_code_review_autoheal.md 的「待觀察」段刪掉,標記 AiderHeal 執行層也驗證完成