# AWOOOI 絕對禁止規則 (Hard Rules)

> 違反任何一條 = 重大事故

---

## 文件資訊

| 欄位 | 值 |
|------|-----|
| **版本** | v1.6 |
| **建立日期** | 2026-03-20 (台北) |
| **建立者** | Claude Code |
| **最後修改** | 2026-03-30 02:30 (台北) |
| **修改者** | Claude Code |

### 變更紀錄

| 版本 | 日期 | 執行者 | 變更內容 |
|------|------|--------|----------|
| v1.0 | 2026-03-20 | Claude Code | 初始建立 |
| v1.1 | 2026-03-23 | Claude Code | 新增 No Mock Testing |
| v1.2 | 2026-03-24 | Claude Code | 新增 Deployment Verification |
| v1.3 | 2026-03-25 | Claude Code | 新增 Timezone Taipei |
| v1.4 | 2026-03-25 | Claude Code | 新增 Change Annotation + 文件資訊區塊 |
| v1.5 | 2026-03-26 | Claude Code | 關聯紅區治理 (RED_ZONES.md) |
| v1.6 | 2026-03-30 | Claude Code | 🔴🔴🔴 前端內網 IP 禁令 (瀏覽器權限事故) |

---

## 快速索引

| 主題 | 禁止 | 正確做法 | 詳細規則 |
|------|------|---------|---------|
| CI/CD | `ubuntu-latest` | `self-hosted` | [→ GitHub Billing](#github-billing) |
| Telegram | `logOut()` | 先停後換 | [→ Telegram Token](#telegram-token) |
| 前端 | 硬編碼文字 | `next-intl` | [→ i18n](#i18n) |
| 資料庫 | SQLite | PostgreSQL | [→ DB](#database) |
| CORS | `*` | 白名單 | [→ CORS](#cors) |
| 數據 | 假數據 Demo | 真實 API | [→ No Fake Data](#no-fake-data) |
| 架構 | 刪除 OpenClaw | OpenClaw 是核心 | [→ OpenClaw](#openclaw) |
| Git | `--force` | 正常 push | [→ Git Safety](#git-safety) |
| **測試** | **Mock 測試** | **真實 DB/服務** | [→ No Mock Testing](#no-mock-testing) |
| **API** | **單獨改路徑** | **前後端同步** | [→ API Path Naming](#api-path-naming) |
| **部署** | **假設已部署** | **驗證 Pod 版本** | [→ Deployment Verification](#deployment-verification) |
| **Alertmanager** | **指向 OpenClaw** | **指向 AWOOOI API** | [→ Alertmanager Routing](#alertmanager-routing) |
| **簽核 UI** | **清空內容** | **保留原始內容** | [→ Approval Preserve Content](#approval-preserve-content) |
| **時區** | **UTC/utcnow** | **台北時區 +8** | [→ Timezone Taipei](#timezone-taipei) |
| **變更追蹤** | **無註解** | **人事物+版本+台北時區** | [→ Change Annotation](#change-annotation) |
| **🔴🔴🔴 前端建置** | **內網 IP** | **公網域名** | [→ Frontend Internal IP](#frontend-internal-ip) |

---

## 🔴🔴🔴 Frontend Internal IP

**Memory:** `feedback_docker_nextjs_api_url.md` + `feedback_sentry_local_network.md`

**絕對禁止** 在 CD 建置時使用內網 IP：

```yaml
# ❌ 禁止 - 觸發瀏覽器「存取區域網路」權限對話框
--build-arg NEXT_PUBLIC_API_URL=http://192.168.0.125:32334
--build-arg NEXT_PUBLIC_SENTRY_DSN=http://...@192.168.0.110:9000/2

# ✅ 正確 - 使用公網域名
--build-arg NEXT_PUBLIC_API_URL=https://awoooi.wooo.work
```

**為什麼這是 Hard Rule:**
- `NEXT_PUBLIC_*` 是 **build-time** 變數，會寫死到 JS Bundle
- Runtime 設定 (K8s ConfigMap/Secret) 對 Next.js 無效
- 內網 IP 會觸發瀏覽器安全機制，彈出權限對話框
- UX 極差，尤其無痕模式

**2026-03-30 事故回顧:**
CD Pipeline 使用 `http://192.168.0.125:32334` 建置，導致所有 API 請求指向內網 VIP。

---

## GitHub Billing

**Memory:** `~/.claude/projects/-Users-ogt-awoooi/memory/feedback_github_billing.md`

```yaml
# ❌ 禁止
runs-on: ubuntu-latest

# ✅ 正確
runs-on: self-hosted
```

**原因:** GitHub Actions 帳戶額度限制，必須用 192.168.0.110 的 self-hosted runner。

---

## Telegram Token

**Memory:** `~/.claude/projects/-Users-ogt-awoooi/memory/feedback_telegram_token_disaster.md`

```python
# ❌ 禁止 - 會導致 Token 永久失效
await bot.log_out()

# ✅ 正確流程
1. 先停止舊 Bot 的 Long Polling
2. 再切換新 Token
```

**原因:** 2026-03-23 災難事件，logOut 導致 Token 永久失效。

---

## i18n

**Memory:**
- `feedback_i18n_zero_hardcode.md` - 零容忍硬編碼
- `feedback_i18n_language_strategy.md` - 語言選擇標準

```tsx
// ❌ 禁止硬編碼
<button>Submit</button>
<span>STATE: IDLE</span>

// ✅ 使用 next-intl
<button>{t('common.submit')}</button>
<span>{t('agent.state')}: {t('agent.idle')}</span>
```

| 元素 | 語言 | 範例 |
|------|------|------|
| UI 文字 | 繁體中文 | 「系統穩定」 |
| 技術標識 | 英文 | `P0`, `RESOLVED` |

**原因:** 面向使用者的文字必須繁體中文。

---

## Database

**Memory:** AWOOOI 憲法

```python
# ❌ 禁止
DATABASE_URL = "sqlite:///..."

# ✅ 正確
DATABASE_URL = "postgresql+asyncpg://..."
```

**原因:** SQLite 無法支援生產環境並發。

---

## CORS

**Memory:** AWOOOI 憲法

```python
# ❌ 禁止
CORS_ORIGINS = ["*"]

# ✅ 正確
CORS_ORIGINS = ["https://awoooi.wooo.work", "http://localhost:3000"]
```

**原因:** 安全性要求。

---

## No Fake Data

**Memory:** `~/.claude/projects/-Users-ogt-awoooi/memory/feedback_no_fake_data.md`

```tsx
// ❌ 禁止
const data = DEMO_DATA

// ✅ 正確
const { data } = useRealAPI()
```

**原因:** 假數據導致用戶無法看到真實系統狀態。

---

## OpenClaw

**Memory:** `~/.claude/projects/-Users-ogt-awoooi/memory/feedback_architecture_openclaw_core.md`

```
❌ 禁止: 淘汰、取代、或刪除 OpenClaw
✅ 正確: OpenClaw 是 AWOOOI 產品核心，只能增強不能移除
```

**原因:** OpenClaw AI 是產品核心價值。

---

## Git Safety

**Memory:** 防禦性工程

```bash
# ❌ 禁止
git push --force
git reset --hard
git checkout -- .

# ✅ 正確
git push
git revert
```

**原因:** 防止資料遺失。

---

## API Path Naming

**Memory:** `~/.claude/projects/-Users-ogt-awoooi/memory/feedback_api_path_naming.md`

```python
# ❌ 禁止 - 單獨修改後端路徑
@router.get("/ai-performance")  # 改成 /incidents/ai-performance
# 但前端仍調用 /ai-performance → 404

# ✅ 正確 - 前後端同步修改
# 1. 後端: @router.get("/incidents/ai-performance")
# 2. 前端: await fetch('/api/v1/stats/incidents/ai-performance')
# 3. 測試: curl 驗證
```

**原因:** 路徑變更是破壞性變更，必須同時更新前後端。

---

## No Mock Testing

**Memory:** `~/.claude/projects/-Users-ogt-awoooi/memory/feedback_no_mock_testing.md`

```python
# ❌ 禁止 - 全面禁止 Mock 測試
from unittest.mock import Mock, AsyncMock, MagicMock, patch
mock_service = AsyncMock()
with patch("src.services.xxx", mock_service):
    ...

# ✅ 正確 - 使用真實資料庫/服務
async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as client:
    response = await client.post("/api/v1/xxx", json=payload)
```

**原因:** 統帥 2026-03-24 明確指示「全面禁止！！！」Mock 無法反映真實系統行為。

**允許例外:**
- `patch.object(settings, ...)` 修改配置值（非 Mock 服務）

---

## Deployment Verification

**Memory:** `~/.claude/projects/-Users-ogt-awoooi/memory/feedback_deployment_verification.md`

```bash
# ❌ 禁止 - 假設 git push 就是部署完成
git push && echo "已部署"

# ✅ 正確 - 必須驗證 Pod 實際運行版本
# 1. 確認 CD workflow 成功
gh run list --workflow=cd.yaml --limit 1  # 必須 ✅ success

# 2. 驗證 Pod 鏡像版本
kubectl get pods -n awoooi-prod -o jsonpath="{.items[*].spec.containers[*].image}"
# 鏡像 tag 必須與最新 commit SHA 匹配

# 3. Health check
curl -f https://api.awoooi.wooo.work/api/v1/health
```

**原因:** 2026-03-24 重大事故：代碼已提交但 CD 連續失敗，正式環境仍運行舊版本，用戶誤以為功能已修復。

---

## Alertmanager Routing

**Memory:** `~/.claude/projects/-Users-ogt-awoooi/memory/feedback_alertmanager_awoooi_flow.md`

```yaml
# ❌ 禁止 - 指向 OpenClaw (會使用舊 AIOPS 格式)
receivers:
  - name: openclaw
    webhook_configs:
      - url: 'http://192.168.0.188:8088/api/v1/webhook/alertmanager'

# ✅ 正確 - 指向 AWOOOI API (K3s)
receivers:
  - name: awoooi
    webhook_configs:
      - url: 'http://192.168.0.120:32334/api/v1/webhooks/alertmanager'
```

**職責分工:**

| 系統 | 職責 | Telegram 權限 |
|------|------|--------------|
| AWOOOI API (K3s 32334) | 告警處理 + 格式化 + 發送 | ✅ |
| OpenClaw (188:8088) | AI 大腦、LLM 分析 | ❌ |

**原因:** 2026-03-25 災難：Claude 錯誤將 Alertmanager 指向 OpenClaw，導致 Telegram 發送舊 AIOPS 格式（🤝 [協同警報]），而非 AWOOOI 格式（═══ 🚨 CRITICAL ═══）。

---

## Approval Preserve Content

**Memory:** `~/.claude/projects/-Users-ogt-awoooi/memory/feedback_approval_preserve_content.md`

```tsx
// ❌ 禁止 - 簽核後清空內容
if (approval.status === 'approved') {
  return <div>已批准</div>  // 原始內容不見了！
}

// ✅ 正確 - 保留原始內容
<Badge>已批准</Badge>
<OriginalAlertContent alert={approval} />  {/* 保留！ */}
<ExecutionResult result={approval.result} />
```

**原因:** 2026-03-25 統帥指示：簽核後必須保留原始告警內容，用戶需要回顧已處理的告警。

---

## Timezone Taipei

**Memory:** `~/.claude/projects/-Users-ogt-awoooi/memory/feedback_timezone_taipei.md`

```python
# ❌ 禁止 - UTC 時區
from datetime import UTC
datetime.now(UTC)
datetime.utcnow()

# ✅ 正確 - 台北時區
from src.utils.timezone import now_taipei, now_taipei_iso
now_taipei()           # datetime with +08:00
now_taipei_iso()       # '2026-03-25T02:08:04+08:00'
```

**原因:** 統帥在台灣，日誌和 Telegram 告警必須顯示台北時間 (UTC+8)，方便閱讀無需心算。

---

## Change Annotation

**Memory:** `~/.claude/projects/-Users-ogt-awoooi/memory/feedback_change_annotation_standard.md`

```markdown
# ❌ 禁止 - 無追蹤資訊的變更
def new_function():
    pass

# ✅ 正確 - 完整追蹤資訊
# ============================================================
# 功能: SignOz MCP Tool
# 版本: v1.0
# 建立: 2026-03-25 23:50 (台北時區)
# 建立者: Claude Code
# 最後修改: 2026-03-25 23:50 (台北時區)
# 修改者: Claude Code
# ============================================================
def new_function():
    pass
```

**必要欄位:**
- **WHO** - 執行者 (人/AI)
- **WHAT** - 變更內容說明
- **WHEN** - 日期時間 (台北 +8)
- **VERSION** - 版本號 (如適用)

**原因:** 統帥 2026-03-25 指示：專案所有變更必須有人事物註解，確保追溯性。

---

## 如何新增規則

1. 在此文件新增章節
2. 更新快速索引表
3. 在 Memory 新增對應 `feedback_*.md`
4. 更新 `MEMORY.md` 索引
