23 KiB
AWOOOI 絕對禁止規則 (Hard Rules)
違反任何一條 = 重大事故
文件資訊
| 欄位 | 值 |
|---|---|
| 版本 | v2.1 |
| 建立日期 | 2026-03-20 (台北) |
| 建立者 | Claude Code |
| 最後修改 | 2026-05-06 (台北) |
| 修改者 | Codex + ogt (新增文件語言鐵律) |
變更紀錄
| 版本 | 日期 | 執行者 | 變更內容 |
|---|---|---|---|
| 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 禁令 (瀏覽器權限事故) |
| v1.7 | 2026-04-02 | Claude Code | Phase 24 AI Router 重構規範 (DI/隱私/絞殺者) |
| v1.8 | 2026-04-03 | Claude Code | 🔴🔴🔴 費用變更強制審批 (統帥指示) |
| v1.9 | 2026-04-15 | Claude Code + ogt | 🔴🔴🔴 AI 自主化飛輪 Phase 退出條件鐵律 (ADR-080) |
| v2.0 | 2026-04-16 | Claude Code + ogt | 新增 No Island Coding / 主動執行熔斷機制 / 自循環工作流 / 狀態機驗證鐵律 |
| v2.1 | 2026-05-06 | Codex + ogt | 🔴 文件語言鐵律:Markdown/ADR/LOGBOOK/Runbook/交接文件一律繁體中文 |
快速索引
| 主題 | 禁止 | 正確做法 | 詳細規則 |
|---|---|---|---|
| CI/CD | ubuntu-latest |
self-hosted |
→ GitHub Billing |
| Telegram | logOut() |
先停後換 | → Telegram Token |
| 前端 | 硬編碼文字 | next-intl |
→ i18n |
| 文件 | 英文主文 | 繁體中文 | → 文件語言規範 |
| 資料庫 | SQLite | PostgreSQL | → DB |
| CORS | * |
白名單 | → CORS |
| 數據 | 假數據 Demo | 真實 API | → No Fake Data |
| 架構 | 刪除 OpenClaw | OpenClaw 是核心 | → OpenClaw |
| Git | --force |
正常 push | → Git Safety |
| 測試 | Mock 測試 | 真實 DB/服務 | → No Mock Testing |
| API | 單獨改路徑 | 前後端同步 | → API Path Naming |
| 部署 | 假設已部署 | 驗證 Pod 版本 | → Deployment Verification |
| Alertmanager | 指向 OpenClaw | 指向 AWOOOI API | → Alertmanager Routing |
| 簽核 UI | 清空內容 | 保留原始內容 | → Approval Preserve Content |
| 時區 | UTC/utcnow | 台北時區 +8 | → Timezone Taipei |
| 變更追蹤 | 無註解 | 人事物+版本+台北時區 | → Change Annotation |
| 🔴🔴🔴 前端建置 | 內網 IP | 公網域名 | → Frontend Internal IP |
| AI Router | Router import 具體 Provider | 只依賴 Protocol | → OpenClaw |
| 🔴🔴🔴 費用變更 | 擅自切換/新增付費 AI Provider | 先讀憲法第五章,再請統帥批准 | → Cost Change Approval |
| 🔴🔴🔴 AI 飛輪 Phase | 未過退出條件就宣告完成 | 必須逐條驗收 exit conditions | → AI Phase Exit Conditions |
| 🔴🔴 孤島開發 | 局部最佳化不查 Callers | grep 全域掃描後才動手 | → No Island Coding |
| 🔴🔴 熔斷機制 | 不確定就停下來問 | 主動做完,爆炸半徑 >3 模組才熔斷 | → 主動執行與熔斷 |
| 🔴🔴 工作流節奏 | 每步都來回報 | 內部自循環,全局單次回報 | → 自循環工作流 |
| 🟡 狀態機驗證 | 不查中間狀態卡死 | 必驗 TTL + Cleanup + Fallback | → State & Flow Validation |
🔴🔴🔴 Cost Change Approval — 費用變更強制審批
統帥指示 2026-04-03: 所有涉及費用產生的變更,必須先看憲法規定,再經統帥批准。
定義:什麼是「涉及費用的變更」
| 類型 | 範例 | 是否需審批 |
|---|---|---|
| 新增/切換付費 AI Provider | 改用 Claude API、新增 GPT-4 | ✅ 必須審批 |
| 增加現有 Provider 呼叫頻率 | 告警觸發改為每分鐘 | ✅ 必須審批 |
| 取消 feature flag 限制 | 關掉 token 上限 | ✅ 必須審批 |
| 新增外部付費 API 整合 | Sentry、Langfuse 付費功能 | ✅ 必須審批 |
| 修改現有 Provider timeout | 45s → 90s(延遲但不增費用) | ❌ 不需審批 |
| 純粹程式邏輯優化 | Prompt 精簡、快取策略 | ❌ 不需審批 |
強制流程
發現需要涉及費用的變更
↓
1. 閱讀憲法第五章 (費用治理)
↓
2. 評估: 月費用影響估算 (USD)
↓
3. 停下來,向統帥說明:
- 為什麼需要這個變更
- 預估費用影響
- 替代方案評估
↓
4. 等待統帥明確批准 ("好" / "同意" / "執行")
↓
5. 執行變更,並在 commit 備註批准日期
🔴 絕對禁止
❌ 未獲批准,擅自切換到新的付費 AI Provider
❌ 未獲批准,增加現有 Provider 的呼叫頻率或 token 上限
❌ 以「暫時測試」為由繞過審批流程
❌ 在沒有費用評估的情況下上線新的 AI 功能
今日違規案例 (2026-04-03,教訓記錄)
Claude Code 未經批准將 ChatManager 的 OpenClaw 替換為 Gemini Flash, 理由是「Ollama 卡死」。這是錯誤的 — 應先報告統帥,等待批准, 再評估是否切換。費用影響未經評估,架構決策未經統帥核可。
🔴🔴🔴 Frontend Internal IP
Memory: feedback_docker_nextjs_api_url.md + feedback_sentry_local_network.md
絕對禁止 在 CD 建置時使用內網 IP:
# ❌ 禁止 - 觸發瀏覽器「存取區域網路」權限對話框
--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
# ❌ 禁止
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
# ❌ 禁止 - 會導致 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- 語言選擇標準
// ❌ 禁止硬編碼
<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 |
原因: 面向使用者的文字必須繁體中文。
文件語言規範
統帥指示 2026-05-06:所有文件必須使用繁體中文。
適用範圍
| 類型 | 規範 |
|---|---|
| Markdown 文件 | 主文、標題、表格說明、結論一律繁體中文 |
| ADR / LOGBOOK / Runbook | 一律繁體中文,避免英文段落混入 |
| 交接文件 / implementation plan | 一律繁體中文,讓跨 session 接手時不再重譯 |
| 前端使用者可見文字 | 仍遵守 i18n,不得硬編碼 |
可保留英文的內容
| 類型 | 範例 |
|---|---|
| 程式符號與路徑 | project_id, apps/api/src, MCPToolResult |
| API / 指令 / 錯誤碼 | GET /v1/platform/runs, kubectl, E-MCP-GATE-001 |
| 服務與產品名稱 | Alertmanager, Sentry, ClickHouse, Gemini |
| 原始 log / trace / commit message | 保留原文,必要時在下方補繁中解釋 |
絕對禁止
❌ 新增英文主文的 ADR、Runbook、LOGBOOK 或 handoff 文件
❌ 將中文文件改成中英混雜但沒有必要技術原因
❌ 用英文標題包裝中文專案狀態,造成後續 session 還要重譯
Database
Memory: AWOOOI 憲法
# ❌ 禁止
DATABASE_URL = "sqlite:///..."
# ✅ 正確
DATABASE_URL = "postgresql+asyncpg://..."
原因: SQLite 無法支援生產環境並發。
CORS
Memory: AWOOOI 憲法
# ❌ 禁止
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
// ❌ 禁止
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 是產品核心價值。
Phase 24 AI Router 重構規範 (ADR-052, 2026-04-02)
❌ 禁止: 在 AIRouter (router.py) 中 import 具體 Provider 實作類別
✅ 正確: Router 只依賴 AIProvider Protocol,Provider 在 main.py DI 註冊
❌ 禁止: 將 ConsensusEngine (P0/P1) 納入 AIRouter
✅ 正確: ConsensusEngine 是獨立決策層,走 Claude Agent SDK
❌ 禁止: DIAGNOSE/CODE_REVIEW 意圖路由到 cloud Provider
✅ 正確: privacy_level="local" 強制本地 (零信任 ADR-023)
❌ 禁止: 遷移期間刪除 openclaw.py 舊 fallback chain
✅ 正確: USE_AI_ROUTER 絞殺者開關,新舊並存至 Phase B4
Memory: project_phase24_ai_router.md
Git Safety
Memory: 防禦性工程
# ❌ 禁止
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
# ❌ 禁止 - 單獨修改後端路徑
@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
# ❌ 禁止 - 全面禁止 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
# ❌ 禁止 - 假設 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
# ❌ 禁止 - 指向 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
// ❌ 禁止 - 簽核後清空內容
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
# ❌ 禁止 - 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
# ❌ 禁止 - 無追蹤資訊的變更
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 指示:專案所有變更必須有人事物註解,確保追溯性。
AI Phase Exit Conditions
ADR-080 鐵律 2026-04-15: 禁止在未通過 Phase N 退出條件前宣告 Phase N 完成。
Reference: docs/adr/ADR-080-ai-autonomy-flywheel-overview.md / MASTER §5
核心規則
禁止宣告「Phase N 完成」,除非:
✅ MASTER §5 Phase N 退出條件清單全部打勾
✅ 相關測試通過(pytest 綠燈)
✅ 架構師評審 Gate N 已完成(ADR-080 §架構師評審框架)
✅ LOGBOOK 已記錄完成項目
7 Phase 退出條件速查
| Phase | 最關鍵退出條件 | ADR |
|---|---|---|
| P0 | feature_flags.py 建立 + baseline_snapshot.py 建立 + HARD_RULES v1.9 |
ADR-080 |
| P1 | MCP 呼叫次數/24h > 0;EvidenceSnapshot 寫入 DB | ADR-081 |
| P2 | 5 Agent 全部有 unit test;Coordinator 熔斷測試通過 | ADR-082 |
| P3 | 學習閉環觸發率 ≥ 99%;fire-and-forget bug 消滅 | ADR-083 |
| P4 | 動態基線覆蓋率 ≥ 80%;general 告警 < 10% | ADR-084 |
| P5 | Blast Radius check 100% 覆蓋;dry-run 強制通過 | ADR-085 |
| P6 | SLO 計算可用;自我降級觸發後不得自動反向升級 | ADR-086 |
違規後果
宣告 Phase 完成但退出條件未達到 = 技術債爆炸風險,等同於在不穩定地基上繼續建樓。統帥發現違規 → 立即回滾至上一個已驗收 Phase。
🔴🔴 No Island Coding — 禁止孤島開發
任何程式碼修改,必定影響上下游。未經全域檢視的局部最佳化,視為嚴重失職。
三條鐵律
| 情境 | 必做動作 |
|---|---|
| 變更函數簽名 | grep -rn "函數名" apps/ packages/ 找出所有 Callers,一併更新 |
| 變更資料模型 (DB/Pydantic) | 同步確認 Write 層、Read 層、Redis Cache 序列化/反序列化邏輯一致 |
| 任何局部修改 | 禁止「假設它會動」,必須全域掃描才能動手 |
# 修改函數前的強制指令
grep -rn "target_function_name" apps/ packages/ --include="*.py"
# 列出所有 Caller,逐一確認影響範圍
與積木化的關係: No Island Coding 是「橫向」掃描(找所有呼叫者),leWOOOgo 積木化是「縱向」邊界(Router 不能越界)。兩者並行,缺一不可。
🔴🔴🔴 Prompt-Model 同步鐵律 — LLM Schema Drift 禁令
血的教訓 (2026-04-17):
prompts.py列了 6 個suggested_action值,models/ai.py只有 4 個。 NemoTron 輸出"investigate"→ Pydantic ValidationError →analysis_result = None→ 全系統 fallback,所有 Telegram 卡片顯示「待分析」,持續數週未被察覺。
強制鐵律
| 情境 | 必做動作 |
|---|---|
修改 prompts.py 的 Enum/格式/欄位 |
同步檢查並更新 models/ai.py Pydantic Schema,確保兩者完全一致 |
| 新增 LLM 輸出欄位 | 先在 Pydantic 加上 field_validator 含 fallback,再改 Prompt |
| 任何接收 LLM JSON 的 Model | 必須有 mode="before" validator 處理:大小寫/別名/未知值 fallback |
三層防護缺一不可
@field_validator("suggested_action", mode="before")
@classmethod
def normalize_suggested_action(cls, v):
if isinstance(v, str):
normalized = v.upper().replace("-", "_")
# 1. 別名映射
alias_map = {"DIAGNOSE": "INVESTIGATE", "MONITOR": "OBSERVE", ...}
normalized = alias_map.get(normalized, normalized)
# 2. 未知值 fallback — 絕不讓 Pydantic 爆炸導致 analysis_result = None
try:
MyEnum(normalized)
return normalized
except ValueError:
return "NO_ACTION" # 安全預設值
return v
禁止靜默死亡
Pydantic ValidationError 時,log 必須明確印出:
- 哪個欄位失敗
- LLM 實際輸出了什麼值
pydantic_validation_failedevent(已實作於openclaw.py)
違反此鐵律 = 破壞生產環境,必須立即 revert。
🔴🔴 Proactive Execution & Circuit Breaker — 主動執行與熔斷機制
整合
feedback_proactive_execution.md(主動執行,2026-04-05)與孤島開發停問規則。 主動執行為絕對預設,停下問是唯一例外。
預設:主動狂奔
看到任務與規格後,一口氣實作到底:
✅ 自己寫 Code
✅ 自己跑測試
✅ 自己修 Error
✅ 全部跑通後才回報
❌ 禁止:列出步驟然後問「統帥可不可以開始」
❌ 禁止:把「不確定」當作不寫 Code 的藉口
❌ 禁止:拿中間的 Error 來打斷統帥
唯一熔斷條件(Circuit Breaker)
必須同時滿足以下兩個條件,才可暫停並請求裁示:
- 修改的檔案是 Tier 3 核心紅區(如
decision_manager.py、db/base.py) - 透過
grep發現這個修改會直接導致 超過 3 個以上未關聯模組發生不可預期的 Crash
熔斷時的回報格式:
發現連鎖爆炸半徑,涉及 [A, B, C],請求裁示
其餘所有情況,全部自己解決。
🔴🔴 Self-Loop Workflow — 自循環工作流與全局回報
四步工作流是 AI 的內部背景作業,不是與統帥的來回節奏。
內部自循環(不對外打斷)
[1. 影響評估] → [2. 實作] → [3. 串接驗證]
↓ Error
[4. 自動修復] → 回到 [3. 串接驗證]
遇到驗證腳本報錯,必須自動遞迴修復,不得中斷統帥。
全局單次回報(唯一一次)
當整個任務 100% 通過時,進行唯一一次成果彙報,必須包含:
1. 修改了哪些檔案(逐一列出)
2. 最終成功的終端機輸出(Console Output)
3. 是否有潛在副作用
等待統帥批准後,才能執行 git commit 與 push。
驗證腳本規範 — Live-Fire Only(實彈演習)
根據 No Mock Testing 鐵律,verify_script.py 絕對禁止使用任何 Mock 套件:
# ❌ 禁止 — 自己 mock 自己測,驗證毫無意義
from unittest.mock import MagicMock
db = MagicMock()
# ✅ 正確 — 打真實 PostgreSQL / Redis / HTTP
async with get_session() as session:
result = await session.execute(select(MyModel).where(...))
# 驗證完畢後必須 Teardown,清理測試資料
await session.execute(delete(MyModel).where(MyModel.id == test_id))
🟡 State & Flow Validation — 狀態機與流程驗證
修改涉及 async、background jobs、DB 狀態轉換 的邏輯時,必須驗證以下清單。
必查斷點
| 風險類型 | 必查項目 |
|---|---|
| 中間狀態卡死 | PENDING 是否有機制轉為 EXPIRED?PROCESSING 超時後誰負責撿起? |
| Fire-and-forget 無聲失敗 | 異步任務失敗時,Exception 是否被吞掉?有無 dead letter / retry? |
| 新增資料實體 | TTL 多長?Cleanup Job 是什麼?錯誤降級策略(Fallback)定義了嗎? |
| 生命週期完整性 | 建立 → 處理 → 結案 → 清理,四個階段必須全部有對應的程式碼 |
# 新增資料實體的最低要求
class MyEntity(Base):
expires_at: datetime # TTL 必填
# 對應 Cleanup Job: scheduler/cleanup_expired_entities.py
# 降級策略: 超時 → status = EXPIRED → Telegram 告警
如何新增規則
- 在此文件新增章節
- 更新快速索引表
- 在 Memory 新增對應
feedback_*.md - 更新
MEMORY.md索引