# 套件 ↔ 頁面 ↔ group ↔ 能力點 對照表（CM-1762，2026-09-14 盤點）

來源：DEV（`localhost:5432/guidant_ai_dev`，唯讀）現況 `ui_routes` / `route_capabilities`
/ `capabilities`，比對各套件 `plugin/contract.py` 的 `CAPABILITIES` 宣告，反推「這個
`resource_type` 是哪支套件宣告的」。判準：**能力點名字掛在哪支套件的 `CAPABILITIES`
清單，這個頁面就歸哪支套件**（守門邏輯也在那支套件的 route）。

## 有頁面、要補 ui_routes + route_capabilities 的套件（23 個路由，12 支套件）

| 套件 | route name | url | pid（group name） | sort | 能力點（requirement） |
|---|---|---|---|---|---|
| jedi-asset | device-manage | /device/device-manage | group-system-admin | 30 | device.{create,delete,update}(ANY) / device.read(ALL) |
| jedi-asset | information-system-manage | /information-system/manage | group-system-admin | 20 | information-system.{create,delete,update}(ANY) / .read(ALL) |
| jedi-bulletin | bulletin-list | /bulletin/bulletin-list | group-communication | 10 | bulletin-list.read(ALL) |
| jedi-bulletin | bulletin-manage | /bulletin/bulletin-manage | group-communication | 20 | bulletin.{create,delete,update}(ANY) / bulletin.read(ALL) |
| jedi-detection | tool-plugin-manage | /plugin/tool-plugin-manage | group-compliance-audit | 30 | plugin.{create,delete,update}(ANY) / plugin.read(ALL) |
| jedi-detection | detection-profile-manage | /plugin/detection-profile-manage | group-compliance-audit | 35 | detection-profile.{create,delete,update}(ANY) / .read(ALL) |
| jedi-file-upload | storage-config | /system/storage-config | group-system-admin | 40 | storage-config.{create,delete,update}(ANY) / .read(ALL) |
| jedi-remote-agent | remote-agent-manage | /system/remote-agent-manage | group-system-admin | 45 | remote-agent-manage.{create,delete,update}(ANY) / .read(ALL) |
| jedi-system-core | system-menu-manage | /system/system-menu-manage | group-system-admin | 10 | system-menu.{create,delete,update}(ANY，is_platform) / .read(ALL) |
| jedi-log（api-log 半） | user-log | /log/user-log | group-system-config | 40 | log.read(ALL，is_platform) |
| jedi-log（forwarding 半） | log-forwarding | /system/log-forwarding | group-system-config | 35 | log-forwarding.read(ALL) / .update(ANY) |
| jedi-license-runtime | license-manage | /license/manage | group-license | 15 | license.read(ALL，is_platform) |
| jedi-license-runtime | license-status | /license/status | group-license | 16 | **刻意 fail-open**（見 CM-1760 白名單），不補綁定 |
| jedi-issue | issue-integrate-config | /system/issue-integrate-config | group-communication | 60 | issue-integrate-config.{create,delete,update}(ANY，is_platform) / .read(ALL，is_platform) |
| jedi-survey | survey-manage | /survey/manage | group-communication | 30 | survey.{create,delete,update}(ANY) / .read(ALL) |
| jedi-notification | smtp-config | /system/smtp-config-manage | group-system-config | 10 | smtp-config.{create,delete,update}(ANY) / .read(ALL) |
| jedi-ai-dashboard | ai-dashboard | /dashboard/ai-dashboard | group-ai-analytics | 10 | ai-dashboard.read(ALL) |
| jedi-iam | user-manage | /auth/user-manage | group-tenant-org | 30 | user.{create,delete,update}(ANY) / .read(ALL) |
| jedi-iam | role-manage | /auth/role-manage | group-tenant-org | 40 | role.{create,delete,update}(ANY) / .read(ALL) |
| jedi-iam | tenant-manage | /tenant/tenant-manage | group-tenant-org | 10 | tenant.{create,delete,update}(ANY) / .read(ALL) |
| jedi-iam | department-manage | /department/department-manage | group-tenant-org | 20 | department.{create,delete,update}(ANY) / .read(ALL) |
| jedi-iam | ldap-config | /system/ldap-config | group-system-config | 20 | ldap-config.{create,delete,update}(ANY) / .read(ALL) |
| jedi-iam | security-policy | /system/security-policy | group-system-config | 15 | security-policy.read(ALL) / .update(ANY)（**已由 `2026-08-29-cm1423-security-policy-page.sql` 在主專案補過**，本卡不重補——見下方「已在主專案補過、不重複」段） |
| jedi-compliance-audit | audit-manage | /project/audit-manage | group-project-task | 40 | audit.{create,delete,update}(ANY) / .read(ALL) |

**`license-status` 特殊處理**：CM-1760 白名單已判定它是「全租戶可見的自己狀態頁，
刻意 fail-open」（`2026-08-10-fr062-8-license-menu-restructure.sql` 的既定設計）。
jedi-license-runtime 的 `ui_routes.sql` 只補 `license-manage`，`license-status` 若要
一併補進套件（讓套件自己也擁有這個 route），**只插 `ui_routes` 不綁
`route_capabilities`**，並在守衛白名單新增一筆 `(檔案, "license-status")`（見下方
守衛白名單更新段）。

**`security-policy` 特殊處理**：這個路由與能力點已由主專案
`2026-08-29-cm1423-security-policy-page.sql` 補過（掛 `group-system-config` id=47，
sort=15），DEV 現況已存在（見上表）。它的能力點宣告已在 jedi-iam 的 `CAPABILITIES`
清單內（`security-policy.{read,update}`），依 D7 判準理應歸 jedi-iam 補，但主專案
那支 SQL 檔案已經把 `ui_routes` + `route_capabilities` 都做好、且**已在守衛白名單外
正常通過**（同檔內有綁定，非 fail-open）。本卡**不在 jedi-iam 重複新增**這個路由
（`WHERE NOT EXISTS` 本身是安全的，但重複宣告同一個 route 在兩處檔案會讓「這個路由
歸誰維護」變得含糊，且會被 D3「表／頁面往後只在套件改」原則說不通——主專案已經改過
一次，收斂到套件由本卡負責 user／role／tenant／department／ldap-config 四頁，
security-policy 留在主專案檔案，於 `docs/features/.../inventory/` 這裡記一筆說明即可）。

## 沒有頁面、不開檔的套件（9 支）

| 套件 | 說明 |
|---|---|
| jedi-common | 無 CAPABILITIES、無頁面 |
| jedi-task-platform | `CAPABILITIES = ()`（participant／task 兩半皆空），無頁面 |
| jedi-evidence-classification | `CAPABILITIES = ()`，無頁面（有 route 但走專案內權限，非全域選單） |
| jedi-integrity | `CAPABILITIES = ()`，無 API 層 |
| jedi-ai-bot | `CAPABILITIES = ()`，無頁面（chatbot 是嵌入元件不是選單頁） |
| jedi-flow-engine | `workflow.*` 四個能力點掛 `workflow-setup`／`workflow-view`，**但兩個 route 的 `enable=0`（停用中）**——design.md 已註明「這四項綁的頁面目前 enable=0，照現況列，頁面停用不影響宣告」；**本卡不補**（頁面本身未上線，選單看不到不是漏洞，等日後真的啟用再由 jedi-flow-engine 補一支新號 SQL） |
| jedi-oscal-v2 | `compliance-framework.*`／`module-frame.*`／`project.*`／`project-summary-report.*` 這幾組能力點在 `_capabilities.sql` 有宣告，但**查無任何一支 jedi 套件的 `contract.py` 宣告它們**——它們的能力點與對應頁面守門邏輯目前都在**主專案** `app/`／`api/`（`module_frame`、`compliance_framework`、`project`、`project_summary_report`、`flow_control` 幾個模組），不屬於任何套件的 `CAPABILITIES` 清單。**這些路由不在本卡範圍**（不歸任何 jedi 套件，維持現況由主專案 seed 管理） |
| jedi-license-runtime（`cloud_integration`、`notify_config`、`feedback`、`feedback-view` 幾組能力點） | 同上，查無宣告來源，維持主專案管理，不歸套件 |

## 首腦核對事項回應

- **cm1423 樣板 ③ 的 `pid` 寫死問題**：所有新檔一律改 `(SELECT id FROM public.ui_routes
  WHERE name = 'group-xxx')` 反查，不寫死數字 id（本卡新增檔案已依此規則）。
- **read=ALL／update=ANY**：所有新增 route_capabilities 綁定遵守同一 requirement 規則
  （write 類動作含 create/update/delete 皆 `ANY`，`read` 皆 `ALL`），與現有 DEV 綁定
  一致（見上表能力點欄位）。

## 對守衛白名單（CM-1760 `_INTENTIONAL_FAIL_OPEN_ROUTES`）的追加

新增一筆：`(jedi_license_runtime/migrations/00N-license-menu-route.sql,
"license-status")` — 理由同既有 `license-status` 三筆白名單條目（全租戶可見的自己
狀態頁，刻意不綁能力點）。

## 序號分配（各套件目前最大號 + 1；.4a／.4b／.4c 平行棒可能已用掉部分號碼，開檔前
以 `ls` 現況為準，此處記錄的是本棒盤點當下的分配）

| 套件 | 既有最大號 | 本卡新檔號 |
|---|---|---|
| jedi-asset | 002 | 003 |
| jedi-bulletin | 002 | 003 |
| jedi-detection | 004（.4a 剛新增） | 005 |
| jedi-file-upload | 002 | 003 |
| jedi-remote-agent | 003 | 004 |
| jedi-system-core | 004（.4c 剛新增） | 005 |
| jedi-log（api_log 目錄） | 003 | 004 |
| jedi-license-runtime | 003 | 004 |
| jedi-issue | 001（.4c 剛新增） | 002 |
| jedi-survey | （無 migrations/ 目錄，首開） | 001 |
| jedi-notification | （無 migrations/ 目錄，首開） | 001 |
| jedi-ai-dashboard | （無 migrations/ 目錄，首開） | 001 |
| jedi-iam | （無 migrations/ 目錄，首開） | 001 |
| jedi-compliance-audit | （無 migrations/ 目錄，首開） | 001 |

**五支首開 `migrations/` 的套件**（jedi-survey／jedi-notification／jedi-ai-dashboard／
jedi-iam／jedi-compliance-audit）都已在各自 `pyproject.toml` 有 `packages = [...]`
宣告，但**沒有 `include` 明確納入 `*.sql`**——本卡逐一補上該行（比照
`jedi-detection`／`jedi-file-upload` 等既有寫法），否則 wheel 只會有 `.py`，
`iter_migrations()`／攤平腳本會靜默看不到新檔（SOP §4.2 規則 5 同型坑）。
