Files
awoooi/docs/awooop/inventory/INV-1-redis-keys.md
Your Name 8629ac709b
Some checks failed
run-migration / migrate (push) Failing after 59s
Code Review / ai-code-review (push) Successful in 1m8s
Type Sync Check / check-type-sync (push) Successful in 2m27s
feat(awooop): Phase 1-8 完整實作 — AwoooP Agent Platform 六平面架構
## Phase 1-3: Control Plane + Contract System
- awooop_phase1_control_plane_2026-05-04.sql: 12 張核心表 + RLS
- awooop_phase1_batch1_rls_2026-05-04.sql: 全部 FORCE RLS + GRANT
- packages/awooop-contracts/: 六合約 JSON Schema + golden fixtures
- src/models/awooop_contracts.py: Pydantic v2 contract models(extra=forbid)
- src/repositories/contract_repository.py: contract lifecycle(draft→published→active)
- src/services/contract_service.py: HMAC publish sig + Redis multi-sig activate
- src/services/schema_validator.py: LLM output validator(retry×3, E-SCHEMA-001)

## Phase 2: Tenant Isolation
- awooop_phase2_budget_ledger_2026-05-04.sql: budget_ledger + RLS
- src/services/budget_service.py: Token Budget Hard Kill 三層防線
- src/core/context.py: PROJECT_ID ContextVar(31 background loop 自動繼承)
- src/db/base.py + models.py: project_id 欄位 + RLS set_config 注入
- src/hermes/nl_gateway.py: project_id Redis key 前綴(Phase A 雙寫)
- src/services/anomaly_counter.py: per-project 改造(Phase A fallback)

## Phase 4: Platform Shell in Shadow Mode
- awooop_phase4_run_state_2026-05-04.sql: run_state + step_journal + idempotency
- src/services/run_state_machine.py: 8-state FSM + SKIP LOCKED + stale reaper
- src/services/platform_runtime.py: UUID v7 + W3C trace_id + shadow_execute
- src/services/audit_sink.py: PII/secret redaction 9 patterns
- src/api/v1/platform/runs.py: POST/GET /v1/platform/runs(Router→Service 架構)
- src/workers/platform_worker.py: SKIP LOCKED worker + heartbeat + reaper loop
- src/main.py: platform router + lifespan worker start/stop

## Phase 5: MCP Gateway 五閘門
- awooop_phase5_mcp_gateway_2026-05-04.sql: 4 表 + RLS
- src/plugins/mcp/gateway.py: McpGateway(Gate 1~5, E-MCP-GATE-001~009)
- src/plugins/mcp/redaction_middleware.py: 雙層 redaction + 16K 截斷
- src/plugins/mcp/registry.py: __provider name mangling(ADR-116)
- src/plugins/mcp/credential_resolver.py: k8s secret ref 解析
- tests/test_mcp_credential_isolation.py: 10 個迴歸測試(secret leak 防再現)

## Phase 6-8: EwoooC + Channel Hub + Approval Token
- awooop_phase6_ewoooc_onboarding_2026-05-04.sql: ewoooc tenant + 4 read-only MCP tools
- awooop_phase7_channel_hub_2026-05-04.sql: conversation_event + outbound_message
- src/services/provider_proxy.py: ProviderProxy + PlatformEnvelope(ADR-115)
- src/services/channel_hub.py: Telegram inbound mirror + Progressive Feedback(30s)
- src/services/awooop_approval_token.py: HS256 + jti NX replay 防護 + suggest mode

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 19:31:53 +08:00

105 lines
7.2 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.
# INV-1: Redis Key Inventory
**版本**v1.0 初稿
**日期**2026-05-03台北
**範圍**`apps/api/src/` 全 codebase grep
**用途**Phase 2 三階段雙寫遷移的完整 Redis key 清單
---
## 使用方式
本 INV 列出所有 Redis key pattern、TTL、用途、寫入點、讀取點、是否硬碼跨兩處。
Phase 2 遷移按批次執行P0Critical→ P1高風險→ P2業務資料→ P3低影響
---
## 1. P0 — Critical必須優先遷移
| Key Pattern | 用途 | TTL | 寫入點 | 讀取點 | 問題 | 新 PatternPhase 2 後)|
|-------------|------|-----|--------|--------|------|------------------------|
| `ollama:current_primary` | Ollama primary URL 選擇 | 無 | `ollama_auto_recovery.py` (兩處!) | `ollama_failover_manager.py` | 🔴 P0-11第二定義 at ollama_auto_recovery.py:230三層 GCP 拓撲無法塞入單一 URL | `platform:ollama:topology`JSONprimary/secondary/fallback|
| `ollama:gemini_daily_count:{date}` | Gemini 每日使用計數 | 24h | `ollama_auto_recovery.py` | same | 🔴 無 project 前綴,多 tenant 共用 | `platform:ollama:gemini_daily_count:{date}` |
| `telegram:polling:leader` | Telegram polling pod 鎖 | ~30s | `telegram_gateway.py:55` | same | 🔴 platform_resource應明確標記 | `platform:telegram:polling:leader` |
| `telegram_silence:{target}` | 告警靜默控制 | 設定值 | `telegram_gateway.py:4079`(用 SILENCE_KEY_PREFIX| `decision_manager.py:240`(🔴 硬碼 `telegram_silence:{target}`,未 import 常數)| P1-24兩處定義不一致 | `{project_id}:telegram:silence:{target}` |
| `ai_rate:total_cost:{provider}` | 費用上限控制 | 無 | `ai_rate_limiter.py` | `ai_router.py` | 🔴 無 project 前綴AWOOOI 費用計數會與 EwoooC 混算 | `{project_id}:ai_rate:total_cost:{provider}` |
## 2. P1 — 高風險Phase 2 第二批)
| Key Pattern | 用途 | TTL | 寫入點 | 讀取點 | 問題 | 新 Pattern |
|-------------|------|-----|--------|--------|------|------------|
| `approval:{run_id}:*` | approval 審核狀態 | 15min | `multi_sig_redis.py` | same | 🔴 P1-15無 trace_idapproval_token 未簽章 | `{project_id}:approval:{run_id}:*`Phase 8 後加 jti|
| `incident:{incident_id}` | incident working memory | 24h | `incident_service.py` | `incident_service.py:603`SCAN `incident:*`| 🔴 P1-18SCAN 無 prefix 篩選 | `{project_id}:incident:{incident_id}` |
| `consensus:{*}` | consensus engine 狀態 | varies | `consensus_engine.py`CONSENSUS_PREFIX="consensus:"| same | 🔴 P0-12無 project 前綴multi-tenant 共用 | `{project_id}:consensus:{*}` |
| `playbook:{playbook_id}` | playbook cache | 1h | `playbook_repository.py` | same | 🟠 無 project但目前 AWOOOI 只有一個 tenant | `{project_id}:playbook:{playbook_id}` |
| `playbook:embedding:index` | embedding index | 無 | `playbook_repository.py` | same | 🟠 無 project | `{project_id}:playbook:embedding:index` |
| `playbook:index:alert:{alert_name}` | alert → playbook 映射 | 1h | `playbook_repository.py` | same | 🟠 無 project | `{project_id}:playbook:index:alert:{alert_name}` |
| `playbook:embedding:{playbook_id}` | embedding vector | 無 | `playbook_repository.py` | same | 🟠 無 project | `{project_id}:playbook:embedding:{playbook_id}` |
| `km:backfill:dlq` | KM backfill dead letter queue | 無 | `km_service.py` | same | 🟠 無 project | `{project_id}:km:backfill:dlq` |
## 3. P2 — 業務資料Phase 2 第三批)
| Key Pattern | 用途 | TTL | 寫入點 | 讀取點 | 問題 | 新 Pattern |
|-------------|------|-----|--------|--------|------|------------|
| `anomaly:disposition:{alert_id}` | 告警處置決定 | 7d | `anomaly_counter.py:790` | same | 🔴 P1-17AnomalyCounter 全域單例6 個 prefix 無 tenant | `{project_id}:anomaly:disposition:{alert_id}` |
| `anomaly:metadata:{alert_id}` | 告警 metadata | 7d | `anomaly_counter.py` | same | 同上 | `{project_id}:anomaly:metadata:{alert_id}` |
| `anomaly:permanent_fix:{alert_id}` | 永久修復紀錄 | 30d | `anomaly_counter.py` | same | 同上 | `{project_id}:anomaly:permanent_fix:{alert_id}` |
| `anomaly:repair_count:{alert_id}` | 修復計數 | 7d | `anomaly_counter.py` | same | 同上 | `{project_id}:anomaly:repair_count:{alert_id}` |
| `anomaly:repair_history:{alert_id}` | 修復歷史 | 30d | `anomaly_counter.py` | same | 同上 | `{project_id}:anomaly:repair_history:{alert_id}` |
| `anomaly:timeline:{alert_id}` | 告警時間線 | 7d | `anomaly_counter.py` | same | 同上 | `{project_id}:anomaly:timeline:{alert_id}` |
| `hermes:session:{chat_id}:{user_id}` | Hermes 對話狀態 | 30min | `hermes/nl_gateway.py:146` | same | 🔴 P1-16無 project 前綴 | `{project_id}:hermes:session:{chat_id}:{user_id}` |
| `hermes:rl:{chat_id}` | Hermes rate limit | 1min | `hermes/nl_gateway.py:163` | same | 🔴 P1-16 | `{project_id}:hermes:rl:{chat_id}` |
| `hermes:approvers` | Hermes 審核者清單 | 無 | `hermes/nl_gateway.py:7` | same | 🔴 P1-16 | `{project_id}:hermes:approvers` |
| `session:{session_id}` | agent session | varies | `agent_sessions service` | same | 🟠 無 project | `{project_id}:session:{session_id}` |
| `tg_sent:{fingerprint}` | Telegram 去重 dedup | 10min | `telegram_gateway.py` | same | 🟢 ADR-109 已定dedup 相容性);注意 EwoooC Telegram 需要不同 fingerprint scope | `{project_id}:tg_sent:{fingerprint}` |
| `telegram:{user_id}:{*}` | Telegram session / callback | varies | `telegram_gateway.py` | same | 🟠 無 project | `{project_id}:telegram:{user_id}:{*}` |
## 4. P3 — 低影響Phase 2 最後)
| Key Pattern | 用途 | TTL | 問題 | 新 Pattern |
|-------------|------|-----|------|------------|
| `playbook:*`SCAN| playbook 全量掃描 | — | 🟠 SCAN 無 prefix 篩選 | 禁止裸 SCAN`SCAN {project_id}:playbook:*` |
| `approval:123:lock`(測試用)| 測試 key | — | 🔵 hardcode 測試字串,清理 | 移除 |
---
## 5. Platform Resource不按 project 隔離,明確標記)
| Key Pattern | 理由 | 備註 |
|-------------|------|------|
| `platform:telegram:polling:leader` | 全域 polling leader 鎖,不屬於任何 tenant | ADR-111 platform_resource |
| `platform:ollama:topology` | GCP-A/GCP-B/Local 三層路由狀態,所有 tenant 共用 | ADR-111 + ADR-110 |
| `platform:ollama:gemini_daily_count:{date}` | 全 platform Gemini 緊急路由計數 | ADR-111 |
---
## 6. 遷移執行順序(三階段)
```
Phase A雙寫30 天觀察):
新 key 寫入 + 舊 key 繼續寫入
讀取仍以舊 key 為主
監控:舊 key 讀取次數 / 新 key 命中次數
Phase B雙讀14 天):
新 key 為主,舊 key 為 fallback
讀不到新 key → 讀舊 key並回填新 key
監控:舊 key fallback 率必須 < 1%
Phase C移除舊 key 寫入):
停止寫入舊 key
舊 key 自然過期
監控:確認舊 key 0 讀取後才進行
```
---
## 7. 驗收標準
- [ ] 所有 P0 key 完成 Phase A 雙寫
- [ ] `decision_manager.py:240` 改為 import `telegram_gateway.SILENCE_KEY_PREFIX`
- [ ] `ollama:current_primary` 改為 `platform:ollama:topology`JSON 格式)
- [ ] 無任何裸 `SCAN *``SCAN prefix:*`(改為 `SCAN {project_id}:prefix:*`
*最後更新2026-05-03台北*