# INV-3: Entrypoint Inventory

**版本**：v1.0 初稿
**日期**：2026-05-03（台北）
**範圍**：`apps/api/src/main.py` + 所有 webhook / CLI / cron 入口點
**用途**：Phase 2 Bootstrap Paradox 修補的 31 個 background loop 分類

---

## 1. 標記定義（ADR-111）

| 標記 | 意義 |
|------|------|
| `platform_internal` | 平台本身的維護工作，不屬於任何 tenant，帶 `project_id=__platform__` |
| `legacy_awoooi_default` | 過渡期：暫時 fallback 到 `project_id=awoooi`，有退場時程 |
| `requires_project_id` | 必須帶 project_id 才能運行，Phase 2 改造重點 |
| `multi_tenant_ready` | 已支援 project_id（Phase 2 後才能設定）|

---

## 2. API Webhook 入口（同步接收）

| 入口 | 檔案 / 路由 | 標記 | project_id 來源 |
|------|------------|------|----------------|
| `POST /v1/webhooks/telegram` | `api/v1/webhooks.py:679` | `legacy_awoooi_default` | 固定 awoooi，Phase 7 後改為 principal mapping |
| `POST /v1/webhooks/alertmanager` | `api/v1/webhooks.py` | `legacy_awoooi_default` | 固定 awoooi |
| `POST /v1/webhooks/gitea` | `api/v1/webhooks.py` | `legacy_awoooi_default` | 固定 awoooi |
| `GET /v1/health` | `api/v1/health.py` | `platform_internal` | `__platform__` |
| `GET /v1/metrics` | `api/v1/metrics.py` | `platform_internal` | `__platform__` |
| `POST /v1/decisions/` | `api/v1/decisions.py` | `legacy_awoooi_default` | 固定 awoooi，Phase 4 後改為 contract lookup |
| `POST /v1/incidents/` | `api/v1/incidents.py` | `legacy_awoooi_default` | 固定 awoooi |

---

## 3. Background Loops（main.py asyncio.create_task，共 31 個）

> 來源：`apps/api/src/main.py` grep `asyncio.create_task`，行號已驗證

| # | 函數名 | main.py 行號 | 類別 | 標記 | 備註 |
|---|--------|-------------|------|------|------|
| 1 | `seed_playbooks_from_rules()` | 331 | 啟動一次性 | `legacy_awoooi_default` | playbook seed，只跑一次 |
| 2 | `get_playbook_repository().backfill_redis_to_pg()` | 341 | 啟動一次性 | `legacy_awoooi_default` | Redis → PG backfill，只跑一次 |
| 3 | `ensure_playbook_embeddings_indexed()` | 348 | 啟動一次性 | `legacy_awoooi_default` | embedding index，只跑一次 |
| 4 | `get_decision_manager().resend_stale_ready_tokens()` | 362 | 持續 loop | `legacy_awoooi_default` | stale approval token 重送 |
| 5 | `run_incident_analysis_sweeper()` | 373 | 持續 loop | `legacy_awoooi_default` | incident 週期分析 |
| 6 | `run_asset_scanner_loop()` | 383 | 持續 loop | `legacy_awoooi_default` | K8s asset 掃描（ADR-090）|
| 7 | `run_rule_catalog_sync_loop()` | 393 | 持續 loop | `legacy_awoooi_default` | 告警規則 catalog 同步 |
| 8 | `run_capacity_scanner_loop()` | 403 | 持續 loop | `legacy_awoooi_default` | 容量掃描 |
| 9 | `run_compliance_scanner_loop()` | 413 | 持續 loop | `legacy_awoooi_default` | 合規掃描 |
| 10 | `run_aider_event_processor_loop()` | 423 | 持續 loop | `legacy_awoooi_default` | aider 事件處理 |
| 11 | `run_coverage_evaluator_loop()` | 432 | 持續 loop | `legacy_awoooi_default` | 覆蓋率評估 |
| 12 | `run_rule_stats_updater_loop()` | 442 | 持續 loop | `legacy_awoooi_default` | 規則統計更新 |
| 13 | `run_asset_change_tracker_loop()` | 452 | 持續 loop | `legacy_awoooi_default` | 資產變更追蹤 |
| 14 | `run_hermes_rule_quality_loop()` | 462 | 持續 loop | `legacy_awoooi_default` | Hermes 規則品質 |
| 15 | `run_capacity_forecaster_loop()` | 472 | 持續 loop | `legacy_awoooi_default` | 容量預測 |
| 16 | `run_daily_report_loop()` | 481 | 持續 loop | `legacy_awoooi_default` | 每日報告 |
| 17 | `run_approval_timeout_resolver()` | 490 | 持續 loop | `legacy_awoooi_default` | 🔴 P1-15：無 trace_id |
| 18 | `run_evolver_loop()` | 499 | 持續 loop | `legacy_awoooi_default` | playbook 進化 |
| 19 | `run_playbook_generation_governance_loop()` | 507 | 持續 loop | `legacy_awoooi_default` | playbook 生成治理 |
| 20 | `run_knowledge_decay_loop()` | 519 | 持續 loop | `legacy_awoooi_default` | KM 知識衰退 |
| 21 | `run_km_backfill_reconciler_loop()` | 529 | 持續 loop | `legacy_awoooi_default` | KM backfill 核對 |
| 22 | `run_aol_writeback_loop()` | 540 | 持續 loop | `legacy_awoooi_default` | AOL writeback（飛輪）|
| 23 | `_run_kb_rot_cleaner_loop()` | 585 | 持續 loop | `legacy_awoooi_default` | KB 腐敗清理 |
| 24 | `run_finetune_export_loop()` | 594 | 持續 loop | `legacy_awoooi_default` | finetune 資料匯出 |
| 25 | `run_proactive_inspector_loop()` | 605 | 持續 loop | `legacy_awoooi_default` | 主動巡檢 |
| 26 | `run_offline_replay_loop()` | 614 | 持續 loop | `legacy_awoooi_default` | 離線重放 |
| 27 | `run_ai_slo_watchdog_loop()` | 623 | 持續 loop | `platform_internal` | SLO watchdog — 監控本平台健康，project_id=__platform__ |
| 28 | `run_governance_loop()` | 632 | 持續 loop | `legacy_awoooi_default` | AI 治理主循環 |
| 29 | `run_governance_dispatcher_loop()` | 640 | 持續 loop | `legacy_awoooi_default` | 治理事件派送 |
| 30 | `_run_model_version_tracker_loop()` | 701 | 持續 loop | `platform_internal` | AI model 版本追蹤 — platform_resource |
| 31 | （需確認 main.py 701 後是否還有）| 701+ | TBD | TBD | grep 計數 = 31，確認後補 |

---

## 4. 遷移策略（依 ADR-123）

### platform_internal（2 個，#27、#30）
- 帶 `project_id=__platform__`
- 不受 project RLS 限制
- 但必須寫 audit log（標記 `platform_resource=true`）

### legacy_awoooi_default（29 個，其餘所有）
- 過渡期：帶 `project_id=awoooi`
- 退場時程：Phase 4 完成後 90 天內逐一改造為 `requires_project_id`
- 每個 loop 改造後從 `legacy_awoooi_default` → `multi_tenant_ready`

### 特別注意
- `run_approval_timeout_resolver()`（#17）：改造時必須同步補入 trace_id（P1-15）
- `run_aol_writeback_loop()`（#22）：改造時確認 KM 雙路徑寫入（feedback_km_dual_path_design.md）

---

## 5. CLI / Script 入口

| 入口 | 類別 | 標記 |
|------|------|------|
| `python -m apps.api` / `uvicorn apps.api.src.main:app` | 主程序啟動 | `platform_internal` |
| `python -m alembic upgrade head` | DB migration | `platform_internal` |
| `python scripts/seed_*.py`（若有）| 資料 seed | `platform_internal` |

---

## 6. 驗收標準

- [ ] 31 個 background loop 全部有標記
- [ ] `platform_internal` loop 帶 `project_id=__platform__`（可在 logging context 確認）
- [ ] `legacy_awoooi_default` loop 帶 `project_id=awoooi`（fallback，不是最終形態）
- [ ] 退場時程寫入 ADR-123

*最後更新：2026-05-03（台北）*
