Files
awoooi/docs/HARD_RULES.md
OG T 9145faf24b
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
E2E Health Check / e2e-health (push) Has been cancelled
docs: 前端內網 IP 禁令 - RCA + Hard Rule v1.6
事故: 2026-03-30 瀏覽器區域網路權限對話框
根因: CD 用 http://192.168.0.125:32334 建置 NEXT_PUBLIC_API_URL

已更新:
- CLAUDE.md: 新增 🔴🔴🔴 前端內網 IP 禁令章節
- HARD_RULES.md: v1.6 新增 Frontend Internal IP 規則
- LOGBOOK.md: RCA 事故回顧

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-30 01:28:38 +08:00

391 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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` 索引