# ADR-011: 跨專案資源隔離與 Container 管理原則

- **Status**: Accepted
- **Date**: 2026-04-19
- **Deciders**: 統帥
- **Related**: ADR-008（文件對齊實況）, ADR-010（Gitea CI/CD）

## Context

2026-04-19 發現 AI Agent 連續數日沒發任何 Telegram 通知（日報/比價/異常告警全斷）。根因調查揭露 188 主機是**多專案共享環境**，momo-pro、clawbot-v5、AWOOOI、wooo-aiops 等 5+ 個 compose project 並存，過去的部署操作缺乏隔離邊界檢查，造成下列風險：

### 實況盤點
1. `momo-pro-system` 容器**不是** compose 管理的（手動 docker run，labels 全空）
2. `momo-scheduler` / `momo-db` 是 compose 建立但 **service name 對不上現行 compose 檔**（視為 orphan）
3. `momo-telegram-bot` 容器**從未被建立**（docker ps -a 無歷史）
4. `docker compose up` 會自動建立 orphan 警告，若使用 `--remove-orphans` 會**清掉 momo-db**（資料災難）
5. `momo-pro/.env` 使用的 bot 實為 **`OpenClawAwoooI_Bot`（共用三專案）**，非 momo-pro 獨有
6. `docker-compose.yml` 部分 volume mount 指向**不存在**的根目錄檔案（如 `./run_telegram_bot.py`），docker 會自動建空目錄造成 `__main__` 錯誤
7. compose 檔宣告的 `momo-network` 與既有 `momo-pro_default` **網路分裂**，新舊容器無法互連 DNS
8. **2026-04-28 追更**: `docker-compose.yml` 遺漏了 `telegram-bot` 與 `scheduler` 的 `./routes` 掛載，導致代碼更新無效（幽靈容器問題）；且 `depends_on: postgres` 導致與 orphan `momo-db` 發生 5432 埠位衝突。

### 衝擊
- 排程容器看似在跑，但環境變數沒注入 → 靜默失敗
- 跨專案盲改可能破壞 `momo-db` 或 `openclaw` 容器
- 未來 CD 若無隔離檢查，會重複踩同樣的洞

## Decision

### ① 隔離邊界（不可跨越）

| 資源 | 歸屬 | 不可做的事 |
|------|------|------------|
| `momo-db`(pgvector/pg14) | momo-pro 獨家 | 任何其他專案不得連入 `momo-pro_default` 網路 |
| `NVIDIA_API_KEY` | momo-pro 獨家 | 不得移入其他專案的 .env |
| `services/{hermes,nemoton,openclaw}_*_service.py` | momo-pro 獨家 | AWOOOI 若要用必須透過 HTTP API 呼叫，禁止 import |
| `openclaw` 容器（port 8088） | **clawbot-v5 專案** | momo-pro CD 不得 stop/remove 該容器 |
| Container 命名 `momo-*` 前綴 | momo-pro 保留 | 其他專案禁用此前綴 |

### ② Container 操作原則

- **禁用** `docker compose down` / `--remove-orphans`（會殃及 orphan label 的 momo-db）
- **首選** `docker compose up -d --no-deps --force-recreate <service>` 精準重建單一容器
- **救急** `docker network connect momo-pro_default <container>` 處理網路分裂
- **容器操作前三句診斷**（見 `AGENTS.md` 常用指令與本 ADR References）必跑

### ③ docker-compose.yml 修正（本 ADR 同步提交）

1. `networks` 改為引用既有網路，杜絕新舊分裂：
   ```yaml
   networks:
     momo-pro_default:
       external: true
   ```
   所有 service 的 `networks:` 段落明確指向 `momo-pro_default`
2. `scheduler` / `telegram-bot` 的 `depends_on` 改為 `condition: service_started` 或移除，避免連帶觸發 `momo-pro-system` 重建衝突
3. `run_telegram_bot.py` mount 路徑從 `./run_telegram_bot.py` 改為 `./scripts/tools/run_telegram_bot.py`（或本地根目錄補檔）
4. **2026-04-28 修正**: 
    - `telegram-bot` 與 `scheduler` 的 `volumes` 段落補齊 `- ./routes:/app/routes:ro`。
    - 徹底移除 `depends_on: postgres`，改由程式碼內部的 `OllamaService` 健康檢查與 `Database` 連線重試機制處理。
    - CD 模式 B (Rebuild) 增加 `--no-cache` 以應對 Docker Snapshot 損壞。
    - CD 模式 A (Sync) 使用 `docker compose restart` 取代硬編碼容器名稱。

### ④ CD Pipeline 補強（cd.yaml）

sync 模式在 `docker restart momo-pro-system` 之後增加：
```bash
docker restart momo-scheduler momo-telegram-bot
```
rebuild 模式在 `docker compose up -d` 之後增加健康檢查三容器全綠。

### ⑤ Telegram 共用 Bot 規範

- callback_data 必加專案 prefix：`momo:pa:{id}` / `momo:pr:{id}`
- 推播訊息標頭加 `[EwoooC]` 以便群組內識別來源
- `services/openclaw_strategist_service.py:229` 的硬編碼 token fallback 移除，改為顯式 fail

## Consequences

**正面**
- 未來任何專案動作前，強制查 label 驗證歸屬，消滅「改 A 壞 B」風險
- 網路統一後，新建容器不會再因 DNS 失敗而靜默停擺
- CD 同步重啟三容器，根除「scheduler 跟不上代碼」的斷訊路徑

**負面**
- 舊有的手動 docker run 歷史債仍在（如 `momo-pro-system` 無 compose label），完整遷移需一次停機窗口
- 共用 bot 的長期策略需另立專題：拆分成 `momo-pro-bot` / `awoooi-bot` / `openclaw-bot` 三個獨立 bot

## References
- `AGENTS.md` — Codex 入口、核心容器與診斷指令
- `docs/memory/credentials_passbook.md` — 主機、服務與埠位對照
- `docs/memory/history_logs.md` — 共用 bot、部署與容器事件歷史
- `docs/memory/project_phase3f_cleanup_roadmap.md` — 3f 收尾與 ADR-011 紅線
