# Gateway Governance / Admin Platform

> 目標：把 **額度、權限、principal 治理、以及目前管理平台實際可用能力** 單獨固化，避免未來 update 後又忘記「現在到底有哪些後端能力、哪些前端已露出、哪些只是資料表存在」。

## 實際程式碼再確認

這份文件依下列 live 落點整理：

- `gateway/user_verification.py`
- `gateway/principal_profiles.py`
- `gateway/run.py`
- `hermes_cli/web_server.py`
- `web/src/lib/api.ts`
- `tests/hermes_cli/test_web_verification_admin.py`
- `tests/gateway/test_principal_profile_routing_phase1.py`
- `tests/gateway/test_verified_email_handoff_guard_helpers.py`

---

## 1. 目前治理資料模型

`GatewayUserStore` 目前至少維護這些核心資料：

- `principals`
  - 主帳號/主體
  - 核心欄位：`principal_id`, `email`, `status`
- `external_identities`
  - 各平台 identity 與 principal 的綁定
  - 核心欄位：`platform`, `external_user_id`, `verified_email`, `principal_id`
- `identity_enforcement`
  - 綁定驗證狀態機
  - 核心欄位：`state`, `failure_cycles`, `blocked_until`, `pending_email`
- `quota_policies`
  - 額度規則
  - 核心欄位：`daily_message_limit`, `daily_token_limit`, `notes`
- `model_policies`
  - principal 模型規則
  - 核心欄位：`allowed_models_json`, `default_model`
- `dashboard_roles`
  - 管理平台角色
  - 核心欄位：`email`, `role`, `updated_by`
- `principal_usage_daily`
  - 每日用量統計
  - 核心欄位：`message_count`, `input_tokens`, `output_tokens`, `total_tokens`, `last_model`
- `admin_audit_logs`
  - 管理操作審計記錄

---

## 2. 目前已確認存在的治理能力

### 2.1 identity / principal 治理
已確認可做：
- 查 identities
- 查 principals
- force bind identity → principal
- unbind identity
- block / unblock identity
- resend verification email

對應 API：
- `GET /api/admin/verification/identities`
- `GET /api/admin/verification/principals`
- `POST /api/admin/verification/force-bind`
- `POST /api/admin/verification/unbind`
- `POST /api/admin/verification/block`
- `POST /api/admin/verification/unblock`
- `POST /api/admin/verification/resend`

### 2.2 dashboard role / 權限治理
已確認可做：
- 查目前 session 的 verification role
- 查角色名單
- 指派角色

對應 API：
- `GET /api/admin/verification/role`
- `GET /api/admin/verification/roles`
- `POST /api/admin/verification/roles`

角色等級：
- `viewer`
- `operator`
- `admin`

### 2.3 quota / model / usage 治理
已確認可做：
- 查 quota policies
- 寫 quota policies
- 查 model policies
- 寫 model policies
- 查 principal 每日 usage

對應 API：
- `GET /api/admin/quota-policies`
- `POST /api/admin/quota-policies`
- `GET /api/admin/model-policies`
- `POST /api/admin/model-policies`
- `GET /api/admin/principal-usage`

### 2.4 audit 治理
已確認可做：
- 查最近治理操作 audit log

對應 API：
- `GET /api/admin/verification/audit`

---

## 3. 目前已被測試釘住的事實

由 `tests/hermes_cli/test_web_verification_admin.py` 已確認：

- force-bind 後，identity list 查得到綁定結果
- unbind 後，state 會回到 `new`
- resend verification endpoint 會實際走寄信流程
- public verify endpoint 可接受 token
- loopback 模式下，role endpoint 預設回 `admin`
- dashboard role assignment 可 round-trip
- quota policy / model policy 可 round-trip
- principal usage 可累積並查回 email 與 limit
- principals endpoint 可查到某 principal 底下有哪些 identities
- audit endpoint 可查到 `force_bind_identity`

由 `tests/gateway/test_principal_profile_routing_phase1.py` 已確認：
- verified principal 可穩定映射到對應 principal profile
- `principal_profile_map.json` 會寫入 mapping
- live bound email guard 會擋下錯誤系統 handoff

由 `tests/gateway/test_verified_email_handoff_guard_helpers.py` 已確認：
- Telegram / OpenWebUI 的 verified-email handoff guard 都會做 live 綁定確認
- 只有使用者明確指定其他 email 時，才可 override

## 3.1 本次實跑測試發現的現況警示

本次我另外實跑了：

```bash
venv/bin/pytest -q \
  tests/hermes_cli/test_web_verification_admin.py \
  tests/gateway/test_verified_email_handoff_guard_helpers.py
```

結果：`13 passed`

再加上：

```bash
venv/bin/pytest -q tests/gateway/test_principal_profile_routing_phase1.py
```

目前已通過，代表：
- `GatewayConfig` 已接上 `principal_profile_routing`
- `GatewayConfig` 已接上 `principal_profile_map_path`
- verified source 進入 `_handle_message(...)` 時，會在 session lookup 前先吃到 principal profile routing
- verified source 也已納入授權判定，不會先死在 unauthorized 分支

所以更精確的現況應寫成：
- **principal profile routing 的輔助模組、config 接線、以及 phase1 測試目前已打通**
- **它現在可視為健康功能，但屬高耦合路徑：一旦改 config / authz / run / principal mapping 任一端，都要重跑 phase1 測試**

---

## 4. 目前不要誤判成「已完整存在」的能力

這幾點要特別小心，不然以後很容易又踩坑：

### 4.1 quota policy ≠ 已完整 runtime enforcement
目前我在 live code 裡確認到的是：
- policy 可存
- usage 可記
- admin 可查

但我**沒有把它寫成「所有 gateway runtime path 都已經會依 quota 強制拒絕」**，因為這次檢查沒有看到足夠證據可以這樣宣稱。

所以比較準確的描述是：
- 現況已具備 **治理資料層、查詢層、對帳層**
- 若要保證 **強制執行層** 無誤，仍需額外補 runtime 驗證與測試矩陣

### 4.2 model policy ≠ 已完整 routing enforcement
同理：
- `allowed_models` / `default_model` 已可保存與查詢
- 但若要聲稱「某 principal 一定只能用某些模型」，仍需 runtime enforcement 證據

### 4.3 有 admin API ≠ 前端 UI 全部可用
我這次有在 `web/src/lib/api.ts` 看到 dashboard 是一個 **machine-level management surface** 的設定，也看得到一般 dashboard/messaging/platform 管理 API。

但對於上述 governance API：
- 我沒有在這次檢查中找到足夠明確的前端頁面證據，能證明這些治理能力全部已有完整 SPA 操作頁

所以務實說法是：
- **governance 後端 API 已存在且有測試覆蓋**
- **前端是否完整提供這些治理操作，需要再做一次 UI 對照盤點**

---

## 5. 目前管理平台能力盤點（保守版說法）

如果要寫給未來維護者，我建議用這種保守但準確的說法：

### 5.1 已確認的後端治理能力
- 身分綁定治理
- principal 治理
- verification resend
- dashboard role 治理
- quota / model policy 治理
- principal usage 查詢
- admin audit 查詢

### 5.2 已確認的一般管理平台能力
從 `web/src/lib/api.ts` 可看出 dashboard 還有這些一般管理能力：
- management profile scope 切換
- skills / toolsets 管理
- messaging platforms 管理
- Telegram / WhatsApp onboarding
- gateway restart / Hermes update / action status
- dashboard plugins 管理
- OAuth provider 管理

### 5.3 尚需另外盤點 / 驗證的部分
- governance 專用前端頁面是否完整存在
- 權限畫面是否有完整角色操作 UI
- quota / model / usage 是否已有完整表格與編輯互動
- admin audit 是否已有前端可視化

---

## 6. 更新後必做 governance smoke

每次 Hermes update、gateway restart、或改動 `gateway/user_verification.py` / `hermes_cli/web_server.py` 後，至少確認：

### 6.1 API / data smoke
- [ ] `GET /api/admin/verification/role`
- [ ] `GET /api/admin/verification/identities`
- [ ] `GET /api/admin/verification/principals`
- [ ] `GET /api/admin/quota-policies`
- [ ] `GET /api/admin/model-policies`
- [ ] `GET /api/admin/principal-usage`
- [ ] `GET /api/admin/verification/audit`

### 6.2 行為 smoke
- [ ] force-bind 一筆測試 identity 後查得到
- [ ] role assignment round-trip 正常
- [ ] quota policy round-trip 正常
- [ ] model policy round-trip 正常
- [ ] usage 仍會隨一次真實對話累積
- [ ] Telegram / OpenWebUI / LINE 的 live bound-email guard 仍正常
- [ ] principal profile mapping 未漂移

---

## 7. 推薦後續補件

接下來若要把這包文件做得更抗更新，我建議再補兩份：

1. `gateway-change-impact-checklist.md`
   - 改哪個模組，就強制勾哪些治理/交付驗收

2. `gateway-admin-ui-inventory.md`
   - 真正盤點：
     - 哪些治理能力只有 API
     - 哪些已有完整 UI
     - 哪些只有半套頁面

這樣未來就不會再發生：
- 以為有 quota 治理，其實只有表
- 以為有權限治理，其實 UI 沒接
- 以為有管理平台功能，其實只有 API 還沒露出來
