Files
awoooi/docs/proposals/MASTER_EXECUTION_SCHEDULE.md
2026-03-30 01:21:23 +08:00

403 lines
15 KiB
Markdown
Raw 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 最終執行主排程
# Master Execution Schedule — 統帥審核版
> **文件類型**: 最終執行授權書
> **建立**: 2026-03-29 14:05 (台北)
> **狀態**: 🟢 執行中 (Wave 1 已完成,進入 Wave 2)
> **本文件為所有 RunBook 和 ADR 的執行定序總綱**
---
## 第一章:最終確認的缺口清單(代碼確認級別)
### 1.1 已確認真實存在的問題(共 16 項)
| # | 問題 | 代碼位置 | 嚴重度 | 波次 |
|---|------|---------|--------|------|
| 1 | Worker stop() timeout 只有 5 秒 | `signal_worker.py:147` | 🔴 P0 | Wave 1 |
| 2 | XCLAIM / Active Sweeper 完全缺失 | `signal_worker.py` 全文 | 🔴 P0 | Wave 1 |
| 3 | StatefulSet 自動修復無硬阻斷 | `auto_repair_service.py:159` | 🔴 P0 | Wave 1 |
| 4 | AnomalyCounter Redis 無 try/except | `anomaly_counter.py:147` | 🔴 P0 | Wave 1 |
| 5 | OpenClaw 無 Circuit Breaker | `sentry_webhook.py:289` | 🔴 P0 | Wave 1 |
| 6 | OpenClaw 無 Concurrency Semaphore | `sentry_webhook.py` | 🔴 P0 | Wave 1 |
| 7 | Global Incident Debounce 缺失 | `incident_service.py` | 🔴 P0 | Wave 1 |
| 8 | Global Auto-Repair Cooldown 缺失 | `auto_repair_service.py` | 🔴 P0 | Wave 1 |
| 9 | terminationGracePeriodSeconds 未設定 | `08-deployment-worker.yaml` | 🔴 P0 | Wave 2 |
| 10 | ESLint i18n Plugin 只有 TODO | `.eslintrc.js:20-22` | 🟠 P1 | Wave 3 |
| 11 | i18n 40+ 違規 | `TECHNICAL_DEBT_PHASE2.md` | 🟠 P1 | Wave 3 |
| 12 | Playwright ignoreHTTPSErrors 未設定 | `playwright.config.ts` | 🟠 P1 | Wave 4 |
| 13 | Visual Baseline 無 Docker 規範 | (設計空白) | 🟠 P1 | Wave 4 |
| 14 | E2E 無 Auth Bypassglobal.setup.ts 缺失)| `tests/e2e/` | 🟠 P1 | Wave 4 |
| 15 | SSE Event Sourcing 尚未實作 | `terminal.py` | 🟡 P2 | Wave 7 |
| 16 | Redis AOF/eviction 未確認 | `.188 主機` | 🔴 P0 | Wave 0 |
### 1.2 已確認不存在(稽核報告誤判)
| 項目 | 誤判內容 | 真實現況 |
|------|---------|---------|
| Worker SIGTERM 缺失 | 報告說「需要實作」| ✅ 已實作line 450-455|
| ADR-035 備援路徑 | 說「可觀測循環依賴」| ✅ Layer 3 繞過 AWOOOI 直接打 Telegram |
| Sentry Comment 缺失 | 說「尚未整合」| ✅ LOGBOOK 確認 Wave A.4 已整合 |
| CD Secret 注入 | 說「缺失」| ✅ ADR-035 確認 CD 已有自動注入 |
---
## 第二章ADR 評估
### 2.1 本次新建 ADR已建立
| ADR | 標題 | 說明 |
|-----|------|------|
| [ADR-038](file:///Users/ogt/awoooi/docs/adr/ADR-038-openclaw-concurrency-governance.md) | OpenClaw 推理引擎併發治理 | Semaphore + Circuit Breaker 雙層保護 |
| [ADR-039](file:///Users/ogt/awoooi/docs/adr/ADR-039-global-autorepair-governance.md) | 全域自動修復熔斷機制 | Global Cooldown + StatefulSet 黑名單 |
### 2.2 現有 ADR 需更新(次要)
| ADR | 需追加內容 | 優先度 |
|-----|---------|--------|
| ADR-020 E2E Verification | 加入 global.setup.ts 和 Auth Bypass 規範 | 🟡 Wave 4 前 |
| ADR-028 Failure Auto-Repair | 加入對 ADR-039 的引用說明 | 🟡 Wave 1 後 |
### 2.3 不需要新建 ADR 的項目
| 項目 | 理由 |
|------|------|
| XCLAIM / Active Sweeper | 屬於 ADR-037 Signal Worker 實作細節 |
| terminationGracePeriodSeconds | 屬於 K8s 操作規範,不是架構決策 |
| ESLint i18n | 屬於 ADR-002 設計系統的工具鏈細節 |
---
## 第三章Skills 更新評估
### 3.1 必須更新的 Skills
#### Skill 02: leWOOOgo Backend Core新增章節
```markdown
## 🛡️ OpenClaw 推理保護模式 (ADR-038, 2026-03-29)
### 鐵律:所有 OpenClaw 呼叫必須雙層保護
from src.core.circuit_breaker import get_openclaw_guard
async def call_openclaw_analyzer(...):
guard = get_openclaw_guard()
if guard.is_circuit_open(): # Layer 1: 斷路
return None
async with guard.semaphore: # Layer 2: 限流(最多 3 並發)
# ... httpx 請求 ...
## 🔴 全域修復冷卻 (ADR-039, 2026-03-29)
### 鐵律:任何自動修復前必須呼叫 check_global_repair_cooldown()
可以修復的服務: 僅無狀態服務awoooi-api, awoooi-web, awoooi-worker
絕對禁止修復: postgres, redis, clickhouse, minio, etcd
```
#### Skill 05: AWOOOI SRE & QA新增章節
```markdown
## 🎭 E2E Auth Bypass 鐵律 (2026-03-29)
### 必須在 tests/e2e/global.setup.ts 實作登入態
// global.setup.ts
async function setup() {
const { chromium } = require('@playwright/test');
const browser = await chromium.launch();
const page = await browser.newPage();
await page.request.post('/api/v1/auth/login', { data: { username: 'demo', password: process.env.E2E_PASSWORD } });
await page.context().storageState({ path: 'e2e-auth-state.json' });
}
### 絕對禁止在 Mac 本機產生 Visual Baseline
使用: pnpm test:visual:updateDocker 環境)
禁止: pnpm exec playwright test --update-snapshots本機
```
> **注意**Skills 更新將在 Wave 1 代碼合併後,由後續 Session 執行。本次記錄評估結論即可。
---
## 第四章:模組化合規驗證
### 4.1 Wave 1 新代碼的合規性
| 新代碼 | 層次 | 依賴 | 介面 | 合規狀態 |
|--------|------|------|------|---------|
| `core/circuit_breaker.py` | core 基礎設施 | stdio + structlog | 直接類(無需 Protocol| ✅ 合規 |
| `services/global_repair_cooldown.py` | Service 層 | Redis透過 get_redis()| 函數式 API | ✅ 合規 |
| `signal_worker.py` XCLAIM 補充 | Worker現有| Redis Stream | 無新依賴 | ✅ 合規 |
| `anomaly_counter.py` Degradation | Service 層 | 無新依賴 | 現有 Protocol | ✅ 合規 |
### 4.2 違規預防
| 規則 | 驗證方式 |
|------|---------|
| Router 不直接存取 Redis | Code Review所有 Webhook router 只呼叫 Service |
| Semaphore 在 core/ | `circuit_breaker.py` 放在 `src/core/`,非 `src/services/` |
| Singleton 透過工廠函數 | `get_openclaw_guard()``get_global_repair_cooldown()` |
---
## 第五章:整合工作衝突分析
### 5.1 必須串行的依賴關係
```
XCLAIM 代碼合併 → 才能部署 Worker HPA
i18n 清零完成 → 才能啟用 ESLint i18n Pluginerror 模式)
release/v1.x 建立 → 才能宣佈 Frontend Feature Freeze
global.setup.ts 實作 → 才能有效執行 E2E Visual 測試
Redis AOF 確認 → 才能實作 SSE Event Sourcing依賴 Redis 持久化)
```
### 5.2 可以並行的工作
```
Wave 1 後端代碼修改5 項)可以並行開發,捆綁一個 PR
Sentry Token 配置 與 SignOz 告警規則部署 可以並行
Storybook 建置 與 Omni-Terminal SSE Event Sourcing 可以並行(不同分支)
```
### 5.3 確認無衝突的部分
| 項目 | 衝突評估 | 結論 |
|------|---------|------|
| terminationGracePeriodSeconds | 需與 XCLAIM 同一 PR相互依賴| ✅ Wave 1 捆綁 |
| Global Cooldown + Global Debounce | 同為 Wave 1無衝突 | ✅ 同一 PR |
| ADR-038 + ADR-039 同時生效 | 需確保 auto_repair_service 引用兩者 | ✅ 已在 ADR 中指定 |
---
## 第六章:詳細實施步驟
### Wave 0: 即時止血(統帥手動確認,當天)
```bash
# 0.1 確認 Redis AOF 狀態5 分鐘)
ssh root@192.168.0.188 \
'docker exec awoooi-redis redis-cli CONFIG GET appendonly; \
docker exec awoooi-redis redis-cli CONFIG GET maxmemory-policy'
# 預期appendonly=yes, policy=volatile-ttl 或 noeviction
# 若非 yes 則立即啟用docker exec awoooi-redis redis-cli CONFIG SET appendonly yes
# 0.2 確認 Alertmanager 備援 Telegram10 分鐘)
ssh root@192.168.0.188 'docker exec alertmanager cat /etc/alertmanager/alertmanager.yml' | grep -A 5 receiver
# 0.3 建立 release/v1.x 穩定分支5 分鐘)
git checkout main && git pull
git checkout -b release/v1.x && git push origin release/v1.x
# 在 GitHub 設定 Protected Branch
# 0.4 確認 SENTRY_AUTH_TOKEN3 分鐘)
kubectl get secret awoooi-secrets -n awoooi-prod \
-o jsonpath='{.data.SENTRY_AUTH_TOKEN}' | base64 -d | wc -c
# > 0 = Phase D 已完成;= 0 = 需執行 RunBook Phase D
```
### Wave 1: 底層安全網(代碼 PR7.5h,原子性)
> **所有以下修改必須在同一個 PR 中,不可拆分!**
```
PR 標題: feat(safety): Wave 1 底層安全網ADR-038 + ADR-039
檔案清單9 個):
新建:
apps/api/src/core/circuit_breaker.py (ADR-038)
apps/api/src/services/global_repair_cooldown.py (ADR-039)
修改:
apps/api/src/services/anomaly_counter.py
→ record_anomaly() 加 try/except + graceful degrade
→ 提取 _record_anomaly_impl()
apps/api/src/workers/signal_worker.py
→ start() 加 _reclaim_task = asyncio.create_task(_reclaim_loop())
→ 新增 _claim_orphaned_tasks()XCLAIM 實作)
→ 新增 _reclaim_loop()Active Sweeper每 5 分鐘)
→ stop() timeout 從 5s 改為 75s同步取消 _reclaim_task
apps/api/src/services/auto_repair_service.py
→ evaluate_auto_repair() 開頭加 check_global_repair_cooldown()
→ execute_auto_repair() 成功後加 record_global_repair_action()
→ 常數區加 STATEFUL_SERVICE_BLACKLIST
apps/api/src/api/v1/sentry_webhook.py
→ call_openclaw_analyzer() 加雙層保護Circuit Breaker + Semaphore
apps/api/src/api/v1/signoz_webhook.py
→ 同上
apps/api/src/services/incident_service.py
→ process_signal() 前加 _check_global_incident_storm()
k8s/awoooi-prod/08-deployment-worker.yaml
→ 加入 terminationGracePeriodSeconds: 90
→ 加入 preStop: sleep 5
```
**Wave 1 PR 審核要點**
- `circuit_breaker.py``src/core/`(非 services
- `global_repair_cooldown.py``src/services/`(非 core
- 所有新代碼有 Google Style Docstring
- 所有 Singleton 透過工廠函數暴露
**Wave 1 驗收指令**
```bash
# 部署後驗證 terminationGracePeriodSeconds
kubectl get deployment awoooi-worker -n awoooi-prod \
-o jsonpath='{.spec.template.spec.terminationGracePeriodSeconds}'
# 預期90
# 驗證 Circuit Breaker + SemaphoreAlpha 測試)
curl -X POST http://192.168.0.125:32334/api/v1/webhooks/alertmanager \
-d '{"alerts": [{"labels": {"alertname": "TestAlert"}}]}'
# 觀察 API logopenclaw_semaphore_acquired / openclaw_circuit_open_skip
```
### Wave 2: Worker 擴縮容部署30 分鐘Wave 1 完成後)
```bash
# 部署 Worker HPA
kubectl apply -f k8s/awoooi-prod/12-hpa.yaml
# 驗證 HPA 建立
kubectl get hpa awoooi-worker-hpa -n awoooi-prod
# 預期TARGETS 顯示實際 CPU%MINPODS=1, MAXPODS=3
```
### Wave 3: 前端主幹手術4 天窗口Week 1
```bash
# Day 1 準備:宣佈 Feature Freeze
# Day 1-3i18n 閃電清零(依 TECHNICAL_DEBT_PHASE2.md 清單)
cd apps/web
git checkout -b fix/i18n-zero-violation
# 執行清零(依序修復 9 個違規組)
# 完成後驗證:
pnpm exec tsc --noEmit
# 安裝 ESLint Plugin先 Warn 模式)
pnpm add -D eslint-plugin-i18next
# 修改 .eslintrc.jsmarkupOnly: true先 warn
# Day 4PR 合併 → 解除 Freeze
git push origin fix/i18n-zero-violation
# PR 審核後合併到 main
# ESLint 切換為 error 模式
```
### Wave 4: CI 基礎設施1 天Wave 3 後)
```bash
# 修改 playwright.config.ts
# 加入 ignoreHTTPSErrors: true + deviceScaleFactor: 1 + threshold: 0.05
# 建立 tests/e2e/global.setup.tsE2E Auth Bypass
# 建立初始 Docker Visual Baseline
cd apps/web
pnpm test:visual:update # Docker 環境
# 部署 Weekly E2E Workflow
git add .github/workflows/e2e-weekly.yaml
git commit -m "feat(ci): weekly E2E + visual regression + Docker baseline"
```
### Wave 5: 告警後端完整化2 小時Wave 1 後即可)
```bash
# 部署 SENTRY_AUTH_TOKEN若 Wave 0.4 確認缺失)
kubectl patch secret awoooi-secrets -n awoooi-prod \
--type=merge -p='{"stringData": {"SENTRY_AUTH_TOKEN": "YOUR_TOKEN"}}'
# 部署 SignOz 告警規則到 .188
ssh root@192.168.0.188 'cat > /tmp/signoz-rules.yaml' < ops/signoz/alerting/rules.yaml
# 透過 SignOz API 套用
# 驗證告警鏈路
python ops/scripts/alert_chain_smoke_test.py
```
> **Wave 6-12**: 中長期工作,依 INTEGRATION_ARCHITECTURE_MASTER.md 執行。
---
## 第七章:最終工作排程(供統帥審核)
```
📅 2026-03-29今天- Wave 0
□ 0.1 Redis AOF + eviction policy 確認hand-on5 min
□ 0.2 Alertmanager 備援路徑確認hand-on10 min
□ 0.3 release/v1.x 分支建立 + GitHub 設為 Protectedhand-on5 min
□ 0.4 SENTRY_AUTH_TOKEN 存在確認hand-on3 min
📅 2026-03-30 (已完成) - Wave 1 ✅
□ core/circuit_breaker.py 開發2h
□ services/global_repair_cooldown.py 開發1h
□ anomaly_counter.py Graceful Degrade1h
□ signal_worker.py XCLAIM + Active Sweeper2h
□ auto_repair_service.py Guardrail 整合1h
□ sentry_webhook.py + signoz_webhook.py 雙層保護0.5h
□ incident_service.py Global Debounce1.5h
□ 08-deployment-worker.yaml terminationGracePeriodSeconds0.5h
□ Wave 1 PR 提交 → 審核 → 合併 → CD 部署 → 驗收
📅 2026-04-01Wave 1 完成後)- Wave 2
□ Worker HPA YAML 部署30 min
📅 2026-04-02~04-054 天)- Wave 3Feature Freeze
□ Frontend Feature Freeze 宣佈
□ i18n 閃電清零40+ 違規4h 工時)
□ ESLint i18n Plugin 安裝Warn 模式)
□ PR 合併 → Feature Unfreeze
□ ESLint 切換為 Error 模式
📅 2026-04-061 天)- Wave 4 / Wave 5
□ playwright.config.ts 修改ignoreHTTPSErrors + threshold
□ global.setup.ts E2E Auth Bypass 建立
□ Docker Visual Baseline 初始建立
□ E2E Weekly Workflow 部署
□ SignOz 告警規則部署到 .188
📅 2026-04 Week 3 - Wave 5 + 6可視 Wave 1-4 完成情況調整)
□ Prometheus Federation.110 → .188
□ Redis AOF + Sentinel 評估
□ AI Autonomy Index Metrics 建立
📅 2026-04 Week 4+ - Wave 7-9Month 2
□ Storybook 10 核心組件
□ Omni-Terminal SSE Event Sourcing
□ 監控 GenUI 卡片7 張)
□ Nexus AI 自治率 UI
📅 Q2 - Wave 10-12長期
□ CloudNativePG HA 評估
□ Kali SecurityAgentMCP Tool 化)
□ Phase 4 視覺靈魂注入
□ CI 硬阻擋正式啟用Warn → Block
```
---
## 第八章:統帥審核要點
請特別審核以下決策點:
| # | 決策內容 | 選項 | 推薦 |
|---|---------|------|------|
| D1 | Wave 1 PR 是否原子性9 個文件一次)| A. 原子 / B. 分批 | A必須原子互相依賴|
| D2 | Feature Freeze 時長 | A. 3天 / B. 5天 | B40+ 違規需要謹慎)|
| D3 | ESLint 啟用時機 | A. i18n清零後立即 / B. 一週緩衝期 | A清零後立即防新債|
| D4 | Semaphore max_concurrent | A. 2 / B. 3 / C. 5 | B3 = 60% .188 CPU|
| D5 | Global Cooldown Threshold | A. 3次/15分鐘 / B. 5次/15分鐘 | B3 次太嚴5 次合理)|
| D6 | Redis HA 策略 | A. Sentinel / B. AOF+手動 / C. 暫緩 | C暫緩Month 2 評估)|
---
*此排程基於 2026-03-29 的完整代碼審計與 16 輪沙盤推演,已閉合所有已知漏洞。* 🦞