#!/bin/bash # ============================================================ # AWOOOI Red Zone Pre-Commit Hook # Version: 1.3 # Created: 2026-03-26 12:30 (台北時區) # Created by: Claude Code # Last modified: 2026-03-26 16:45 (台北時區) # Last modified by: Claude Code # Description: 紅區變更警告 + leWOOOgo 積木化違規檢查 # ============================================================ # 顏色定義 RED='\033[0;31m' YELLOW='\033[1;33m' GREEN='\033[0;32m' CYAN='\033[0;36m' NC='\033[0m' # No Color BOLD='\033[1m' # ============================================================ # 紅區定義函數 # ============================================================ get_tier3_info() { local file="$1" case "$file" in "apps/api/src/services/decision_manager.py") echo "決策狀態機" echo "OpenClaw AI 的決策核心,控制 PENDING→APPROVED→EXECUTED 狀態流轉" echo "AI 無法做出決策|審批流程卡死|所有待處理告警無法推進" ;; "apps/api/src/services/trust_engine.py") echo "信任評分引擎" echo "計算操作的信任分數,決定是否需要 Multi-Sig 審批" echo "危險操作被自動執行|低風險操作被過度審批|Multi-Sig 機制失效" ;; "apps/api/src/services/consensus_engine.py") echo "共識引擎" echo "Multi-Sig 多方簽核邏輯,確保關鍵操作需多人同意" echo "單點簽核繞過安全機制|審批人數計算錯誤|共識達成判斷失靈" ;; "apps/api/src/services/incident_engine.py") echo "事件處理引擎" echo "告警接收、分類、派發的核心引擎" echo "告警無法被接收|事件分類錯誤|Telegram 通知失敗" ;; "apps/api/src/services/multi_sig_redis.py") echo "分散式鎖服務" echo "Redis 分散式鎖,防止併發競爭" echo "同一事件被多次處理|死鎖導致系統卡死|資料不一致" ;; "apps/api/src/services/security_interceptor.py") echo "安全攔截器" echo "權限驗證、危險操作攔截" echo "權限繞過漏洞|危險操作未被攔截|安全審計失效" ;; "apps/api/src/core/config.py") echo "環境配置中心" echo "所有服務的連線配置 (Redis/PostgreSQL/Ollama/Telegram)" echo "所有外部連線中斷|服務無法啟動|環境變數解析失敗" ;; "apps/api/src/core/telemetry.py") echo "OTEL 監控核心" echo "OpenTelemetry 追蹤與指標收集" echo "SignOz 無法收到追蹤數據|系統可觀測性失明|問題排查極度困難" ;; *) echo "" ;; esac } get_tier2_info() { local file="$1" case "$file" in k8s/awoooi-prod/*) echo "K8s 正式環境配置" echo "Kubernetes 正式環境部署檔案" echo "正式環境部署失敗|NetworkPolicy 錯誤導致服務隔離|Pod 無法啟動" ;; "apps/api/src/db/models.py") echo "資料庫 Schema" echo "SQLAlchemy ORM 模型定義" echo "資料庫結構不一致|Migration 衝突|資料遺失風險" ;; .github/workflows/*) echo "CI/CD Pipeline" echo "GitHub Actions 自動化流程" echo "自動部署中斷|測試流程失效|可能產生 GitHub 帳單費用" ;; "apps/api/src/core/redis_client.py") echo "Redis 連線池" echo "Redis 連線管理與 Stream 操作" echo "快取服務中斷|Stream 訊息無法消費|Worker 無法接收任務" ;; "apps/api/src/services/telegram_gateway.py") echo "Telegram 閘道" echo "Telegram Bot 訊息收發" echo "告警通知無法送達|審批按鈕失效|統帥無法收到即時通知" ;; *) echo "" ;; esac } # ============================================================ # 顯示警告函數 # ============================================================ show_tier3_warning() { local file="$1" local info info=$(get_tier3_info "$file") if [ -z "$info" ]; then return 1 fi local name=$(echo "$info" | sed -n '1p') local desc=$(echo "$info" | sed -n '2p') local impacts=$(echo "$info" | sed -n '3p') echo "" echo "╔══════════════════════════════════════════════════════════════╗" echo -e "║ ${RED}${BOLD}🔴 TIER 3 紅區變更警告${NC} ║" echo "╚══════════════════════════════════════════════════════════════╝" echo "" echo -e "${RED}${BOLD}[Tier 3 紅區] ${name}${NC}" echo "" echo -e "${CYAN}功能:${NC} ${desc}" echo "" echo -e "${YELLOW}修改錯誤將導致:${NC}" IFS='|' read -ra IMPACT_ARRAY <<< "$impacts" for impact in "${IMPACT_ARRAY[@]}"; do echo " - $impact" done echo "" echo -e "${RED}風險等級: 極高${NC}" echo "" echo -e "${BOLD}變更檔案:${NC} $file" echo "" echo "╔══════════════════════════════════════════════════════════════╗" echo -e "║ ${RED}${BOLD}🏛️ 首席架構師審查必要${NC} ║" echo "╠══════════════════════════════════════════════════════════════╣" echo "║ 1. 停止 commit,呼叫首席架構師介入 ║" echo "║ 2. 首席架構師進行架構與代碼 Review ║" echo "║ 3. 確認變更必要性、影響範圍、替代方案 ║" echo "║ 4. 首席架構師簽核後,方可繼續 ║" echo "╚══════════════════════════════════════════════════════════════╝" return 0 } show_tier2_warning() { local file="$1" local info info=$(get_tier2_info "$file") if [ -z "$info" ]; then return 1 fi local name=$(echo "$info" | sed -n '1p') local desc=$(echo "$info" | sed -n '2p') local impacts=$(echo "$info" | sed -n '3p') echo "" echo "╔══════════════════════════════════════════════════════════════╗" echo -e "║ ${YELLOW}${BOLD}🟠 TIER 2 橙區變更警告${NC} ║" echo "╚══════════════════════════════════════════════════════════════╝" echo "" echo -e "${YELLOW}${BOLD}[Tier 2 橙區] ${name}${NC}" echo "" echo -e "${CYAN}功能:${NC} ${desc}" echo "" echo -e "${YELLOW}可能影響:${NC}" IFS='|' read -ra IMPACT_ARRAY <<< "$impacts" for impact in "${IMPACT_ARRAY[@]}"; do echo " - $impact" done echo "" echo -e "${BOLD}變更檔案:${NC} $file" return 0 } # ============================================================ # leWOOOgo 積木化違規檢查 (2026-03-26 審計後新增) # ============================================================ check_lewooogo_violations() { local has_violation=false local staged_files=$(git diff --cached --name-only) # 檢查 1: Router 層禁止直接引用 redis_client # Phase 16 R3.4 修正: 只檢查新增行 (^+),忽略刪除行 (^-) 和註解行 (#) if echo "$staged_files" | grep -q "^apps/api/src/api/"; then if git diff --cached -- 'apps/api/src/api/*.py' | grep "^+" | grep -v "^+++" | grep -v "^+.*#" | grep -q "from src.core.redis_client"; then echo "" echo "╔══════════════════════════════════════════════════════════════╗" echo -e "║ ${RED}${BOLD}🔴 leWOOOgo 積木化違規${NC} ║" echo "╚══════════════════════════════════════════════════════════════╝" echo "" echo -e "${RED}${BOLD}違規: Router 層禁止直接引用 redis_client${NC}" echo "" echo -e "${CYAN}原則:${NC} Router 層只做 HTTP 路由,不應直接存取資料層" echo -e "${YELLOW}正確做法:${NC} 透過 Service 層存取 Redis" echo "" echo " ❌ from src.core.redis_client import get_redis" echo " ✅ from src.services.xxx_service import XxxService" echo "" has_violation=true fi fi # 檢查 2: Router 層禁止直接引用 db session # Phase 16 R3.4 修正: 只檢查新增行 (^+),忽略刪除行 (^-) 和註解行 (#) if echo "$staged_files" | grep -q "^apps/api/src/api/"; then if git diff --cached -- 'apps/api/src/api/*.py' | grep "^+" | grep -v "^+++" | grep -v "^+.*#" | grep -q "from src.db.base import"; then echo "" echo "╔══════════════════════════════════════════════════════════════╗" echo -e "║ ${RED}${BOLD}🔴 leWOOOgo 積木化違規${NC} ║" echo "╚══════════════════════════════════════════════════════════════╝" echo "" echo -e "${RED}${BOLD}違規: Router 層禁止直接引用 DB Session${NC}" echo "" echo -e "${CYAN}原則:${NC} Router 層只做 HTTP 路由,不應直接存取資料庫" echo -e "${YELLOW}正確做法:${NC} 透過 Service/Repository 層存取" echo "" echo " ❌ from src.db.base import get_session" echo " ✅ from src.services.xxx_service import XxxService" echo "" has_violation=true fi fi # 檢查 3: 新增 services/ 檔案時提醒檢查 packages/ if echo "$staged_files" | grep -q "^apps/api/src/services/.*\.py$"; then local new_services=$(echo "$staged_files" | grep "^apps/api/src/services/.*\.py$") for svc in $new_services; do # 檢查是否為新建檔案 if ! git ls-files --error-unmatch "$svc" > /dev/null 2>&1; then echo "" echo "╔══════════════════════════════════════════════════════════════╗" echo -e "║ ${YELLOW}${BOLD}⚠️ leWOOOgo 積木化提醒${NC} ║" echo "╚══════════════════════════════════════════════════════════════╝" echo "" echo -e "${YELLOW}${BOLD}新增 Service 檔案: ${svc}${NC}" echo "" echo -e "${CYAN}修改前必問 5 題:${NC}" echo " 1. 這個邏輯是否已存在於 packages/?" echo " 2. 是否可被其他模組重用?(應放 packages/)" echo " 3. 是否使用 Interface 定義通訊契約?" echo " 4. 是否遵循依賴注入原則?" echo " 5. 是否避免與其他 Service 緊耦合?" echo "" echo -e "${CYAN}參考:${NC} packages/lewooogo-brain/ 和 packages/lewooogo-data/" echo "" fi done fi if [ "$has_violation" = true ]; then echo "═══════════════════════════════════════════════════════════════" echo "" echo -e "${RED}${BOLD}🔴 leWOOOgo 積木化鐵律${NC}" echo "" echo "架構層次: Router → Service → packages/lewooogo-*/" echo "" echo "Memory: feedback_lewooogo_modular_enforcement.md" echo "Skill: 02-lewooogo-backend-core.md" echo "" echo "═══════════════════════════════════════════════════════════════" # 違規則阻止 commit return 1 fi return 0 } # ============================================================ # 主要檢查邏輯 # ============================================================ main() { local has_warning=false local staged_files=$(git diff --cached --name-only) # === leWOOOgo 積木化違規檢查 (硬性阻擋) === if ! check_lewooogo_violations; then echo "" echo -e "${RED}${BOLD}Commit 被阻止: 請先修復 leWOOOgo 積木化違規${NC}" echo "" exit 1 fi for file in $staged_files; do # 檢查 Tier 3 if show_tier3_warning "$file"; then has_warning=true # 檢查 Tier 2 elif show_tier2_warning "$file"; then has_warning=true fi done if [ "$has_warning" = true ]; then echo "" echo "═══════════════════════════════════════════════════════════════" echo "" echo -e "${RED}${BOLD}🏛️ 首席架構師審查流程${NC}" echo "" echo "此變更涉及紅區/橙區,必須經過以下流程:" echo "" echo " 1. Claude Code 停止自動 commit" echo " 2. 呼叫首席架構師進行架構 Review" echo " 3. 首席架構師確認:" echo " - 變更必要性" echo " - 影響範圍評估" echo " - 替代方案評估" echo " - 回滾計畫" echo " 4. 首席架構師簽核 → 方可繼續 commit" echo "" echo "參考文件: docs/RED_ZONES.md" echo "" echo "═══════════════════════════════════════════════════════════════" fi # 警告但允許繼續 (統帥指示) return 0 } # 執行 main