# A.1 能力點樹（T-1.6 合併定稿）

> 變更紀錄：2026-10-06 T-1.6 合併定稿（Notion CM-2516）。
>
> 這份把五份 A.1 盤點（`a1-grc.md`、`a1-oscal-flow.md`、`a1-detection-evidence-survey.md`、`a1-system-iam.md`、`a1-platform.md`）的「定案結論」合成一棵能力點樹。主體照側邊選單逐頁走，告訴你每個畫面上每個按鈕要哪一個能力點；後面是能力點總表、出貨角色怎麼對上這棵樹，技術對照（API 路徑）放附錄。資料來源：五份盤點的定案結論、design.md §6.1、DEV 本機庫（`localhost:5432/guidant_ai_dev`，2026-10-06 查）的 `capabilities`（123 列）、`ui_routes`（49 列）、`route_capabilities`，以及前端選單中文名（`compliance-manager-fe/src/config/locales/i18n/zh-tw/menu.json`）。主表與定案結論不一致時以定案結論為準，衝突處列在附錄 D。

## 怎麼讀這張表（給決策者）

- **名字三段**：`模組.資源.動詞`，例 `grc.project.update`＝「專案稽核模組／專案／修改」。前兩段就是角色畫面上的兩層分組。
- **四個基本動詞**每個資源都有：`read`（看）、`create`（新增）、`update`（修改）、`delete`（刪除）。今天沒有對應按鈕的也照建（標「空殼」），唯一破例是「同一資源的另一種看法」只開 `read`（例：`workspace.feedback-review`）。
- **獨立動詞只有四類**，給「能改不等於能做這件事」的動作：狀態轉換（`approve`／`close`／`publish`）、對外送出（`export`）、指派（`assign`）、匯入（`import`）。
- **三條情境通則**：A＝在任務／專案頁做的事看任務／專案的權限；B＝挑選用的下拉看呼叫頁面的權限；C＝一支 API 服務多種資源時先判資源歸屬再查單一權限。
- **萬用字元角色**：角色存的是 pattern，`grc.*.*`＝整個專案稽核模組全部，`*.*.read`＝所有模組只看，`*.*.*`＝全部（系統管理員）。對照方式見第三部分。

## 第一部分：照選單逐頁核對（功能主軸）

依 DEV `ui_routes` 的側邊選單順序，八個分組、41 個選單頁全列（選單樹共 49 列＝8 個分組節點＋41 頁）。分組節點本身沒有功能，只當小標。每個畫面列出使用者會按到的動作；「通則」欄的 A／B／C 見開頭說明。原廠層（`is_platform`）的頁面一律兩道門：平台管理員判定＋能力點，兩道都要過。

### 選單分組「專案與任務」

#### 畫面：專案儀表板（專案與任務 > 專案儀表板，`/project/dashboard`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看自己參與專案的統計卡片 | `grc.project.read` | 個人視角，只算自己參與的 |
| 看自己的待辦任務區塊 | `grc.job.read` | 個人視角 |
| 看自己的稽核區塊 | `grc.audit.read` | 個人視角 |

#### 畫面：待辦任務（專案與任務 > 待辦任務，`/project/task-manage`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看我被指派的任務清單 | `grc.job.read` | 個人視角 |
| 用專案下拉篩選 | `grc.project.read` | 只回自己被指派的專案 |
| 批次完成自己的任務 | `grc.job.update` | 另有專案成員檢查 |
| 頁首待辦數字 | `grc.job.read` | 全站頂列也用 |

#### 畫面：專案管理（專案與任務 > 專案管理，`/project/projects`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看專案清單 | `grc.project.read` | 只列自己參與的 |
| 新增專案 | `grc.project.create` | 精靈第一步挑資源庫、挑流程範本、預覽範本也靠這顆（通則 B） |
| 新增專案時挑人、挑部門 | 豁免 | 挑人／挑部門下拉只驗登入 |
| 編輯專案 | `grc.project.update` | |
| 刪除、批次刪除專案 | `grc.project.delete` | 另有專案 owner／manager 檢查 |
| 看雲端整合連線狀態 | `evidence.cloud-integration.read` | 出貨一般成員組要帶 |

進入單一專案後的各子頁（不在側邊選單，從專案清單點進去）：

**專案總覽／專案設定**

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看專案明細 | `grc.project.read` | 另需是專案成員 |
| 改專案基本資料 | `grc.project.update` | 專案 manager |
| 看專案成員 | `grc.project.read` | |
| 新增、改角色、移除專案成員 | `grc.project.assign` | 專案 manager |
| 建立雲端資料夾、檢查並修復資料夾 | `grc.project.update` | 通則 A；授權照仍要有雲端整合包 |
| 看雲端資料夾 | `grc.project.read` | 通則 A |

**專案規劃（含 SSP 分頁、任務設置）**

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看 SSP 各分頁（系統特性、元件、資產、沿用授權、人員、受評標的、控制實作、程序書池） | `oscal.ssp.read` | 控制項樹也被稽核頁、證據分類頁共用，一般成員組要帶 |
| 改 SSP 各分頁內容（含新增、刪除子項目） | `oscal.ssp.update` | 專案 manager 且輪次仍在規劃階段 |
| SSP 匯入（Excel 九分頁、Word、SoA Excel） | `oscal.ssp.import` | 整條匯入流程同一顆 |
| SSP 匯出（docx／pdf／odt、SoA Excel、帶入內容的匯入範本） | `oscal.ssp.export` | |
| SSP 挑設備、挑資訊系統 | 跟呼叫頁權限 | 通則 B：看的是 `oscal.ssp.read`／`update` |
| 看任務清單、任務明細 | `grc.job.read` | |
| 新增任務 | `grc.job.create` | 專案 manager |
| 改任務 | `grc.job.update` | 專案 manager |
| 刪任務 | `grc.job.delete` | 專案 manager |
| 指派任務執行人、啟動任務執行、強制開始卡住的任務 | `grc.job.assign` | 派工 |
| 看任務執行進度 | `grc.project.read` | |
| 任務匯出 | `grc.job.export` | |
| 任務匯入（上傳、驗證、確認） | `grc.job.import` | |
| 開啟查核項目流程圖（`/workflow/workflow-setup`） | `grc.project.read`＋專案成員 | 通則 C：流程定義端點先查這張流程圖屬專案 |
| 任務設置裡挑檢測工具、工具參數、掃描設定檔、遠端代理、問卷、設備 | 跟呼叫頁權限 | 通則 B：看的是 `grc.job.read`／`update`，不要求被挑模組的 read |
| 新增稽核輪次、發起覆核輪 | `grc.audit.create` | |

**任務執行抽屜（從任務清單點開）**

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 提交任務、退回上一關、審核關卡通過／退回 | `grc.job.update` | 另需是該任務被指派人或專案 manager |
| 看、新增、改、刪自己的留言 | `grc.job-comment.read`／`create`／`update`／`delete` | 改、刪只限作者本人 |
| 看、上傳、改、刪佐證檔 | `grc.job-evidence.read`／`create`／`update`／`delete` | |
| 開始掃描、取消、重跑、立即開始、刪失敗紀錄 | `grc.job.update` | 通則 A；授權照仍要有檢測包 |
| 看掃描執行紀錄 | `grc.job.read` 或 `grc.job-evidence.read` | 通則 A 例外：掃描紀錄一產生就是任務證據 |
| 設定這個任務用哪份問卷、要不要審核 | `grc.job.update` | 通則 A |
| 填問卷、暫存、提交、還原舊版答案、Excel 匯入答案 | `grc.job.update` | 通則 A；授權照仍要有問卷包 |
| 看問卷內容、答案、歷史、討論 | `grc.job.read`；已完成問卷另認 `grc.job-evidence.read` | 通則 A 例外：結案問卷視為任務證據；未結案只持證據權限回 404 |
| 在問卷上留言、改或刪自己的留言 | `grc.job.update` | 通則 A |
| 審閱打勾（控制項層、AO 層）、取消打勾 | `grc.audit.approve` | 專案 manager／reviewer |

**稽核輪次各頁（專案總覽 > 輪次：稽核計畫填寫、稽核審查、改善計畫）**

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看輪次、評估計畫、評估結果、風險、矯正計畫 | `grc.audit.read` | |
| 改評估計畫（受評控制項、受評標的、任務、人員）、判定符合／不符合、改觀察事項、改風險、改里程碑 | `grc.audit.update` | AP／AR 給 auditor／manager，POA&M 給 manager |
| 新增觀察事項、風險、矯正措施、里程碑 | `grc.audit.create` | |
| 刪除觀察事項、風險、里程碑、矯正措施 | `grc.audit.delete` | |
| 評估計畫 Word 匯入、評估結果 Excel 匯入 | `grc.audit.import` | 預覽、放棄、確認同一顆 |
| 推進稽核階段、退回上一階段 | `grc.audit.update` | 階段指定角色或 manager |
| 看階段資訊、異動紀錄 | `grc.audit.read` | |
| 結束輪次 | `grc.audit.close` | |
| 看問卷本體（稽核頁引用控制項問卷） | `survey.survey.read` | 讀的是問卷內容本體，不是挑選名單（通則 B 判準） |

**AI 自動分類證據（專案總覽 > 輪次 > 自動分類證據）**

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看批次清單、批次內容、分類狀態、預覽檔、驗證與裁決報表 | `evidence.classification.read` | 另需是專案成員 |
| 建批次 | `evidence.classification.create` | 專案 manager |
| 上傳／移出檔案、封存、人工審閱、歸檔進任務佐證 | `evidence.classification.update` | 專案 manager |
| 送 AI 分類 | `evidence.classification.execute` | 專案 manager；會花 AI 額度、起背景工作，故與 update 分開 |
| 刪批次、清暫存檔 | `evidence.classification.delete` | 專案 manager |
| 挑分類用的 AI 模型 | 跟呼叫頁權限 | 通則 B，看 `evidence.classification.read`（附錄 D 首腦補充 ②） |
| 看 AI 額度黃條 | 豁免 | 一般成員也要看 |

#### 畫面：我的稽核（專案與任務 > 我的稽核，`/project/audit-manage`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看我身為稽核員被指派的評估計畫 | `grc.audit.read` | 個人視角 |

本頁沒有寫入按鈕；稽核的建立／修改／刪除／結案／匯入在專案底下的稽核計畫頁勾選。

#### 畫面：專案調查結果（專案與任務 > 專案調查結果，`/project-summary-report`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看報告清單、明細、歷史版本 | `grc.summary-report.read` | 只列自己參與專案的；挑專案下拉跟 `grc.project.read` |
| 新增報告 | `grc.summary-report.create` | |
| 編輯報告、還原成舊版 | `grc.summary-report.update` | |
| 刪除報告 | `grc.summary-report.delete` | |
| 匯出 PDF | `grc.summary-report.export` | |

### 選單分組「合規與稽核」

#### 畫面：合規資源庫（合規與稽核 > 合規資源庫，`/module-frame/module-frame`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看資源庫清單、明細、範本 SSP 各分頁、控制項預設值、程序書池 | `oscal.resource-library.read` | |
| 新增資源庫、複製資源庫、用框架版本建資源庫 | `oscal.resource-library.create` | |
| 用檔案（Excel、Word）新建資源庫 | `oscal.resource-library.create` | 不開 import |
| 改資源庫；增刪改範本內所有子項目（查核項目、元件、資產、沿用授權、人員、受評標的、預設值、程序書與其關聯） | `oscal.resource-library.update` | 子物件寫入一律歸 update |
| 匯入內容到既有資源庫（Excel、Word、控制項預設值四步驟） | `oscal.resource-library.update` | |
| 刪除資源庫 | `oscal.resource-library.delete` | |
| 匯出範本內容 Excel、下載空白範本、範本 SSP 匯出 docx／pdf | `oscal.resource-library.read` | 資源庫匯出歸 read |
| 編輯查核項目流程圖（`/workflow/workflow-setup`） | 讀：`oscal.resource-library.read`；存：`oscal.resource-library.update` | 通則 C：先查這張流程圖屬資源庫 |
| 挑合規框架、挑控制項 | 跟呼叫頁權限 | 通則 B：看資源庫頁的 `oscal.resource-library.read／create`（附錄 D 裁 5） |
| 挑設備、資訊系統、人、部門 | 跟呼叫頁權限／豁免 | 通則 B；挑人挑部門豁免 |

#### 畫面：合規框架管理（合規與稽核 > 合規框架管理，`/compliance-framework/compliance-framework-manage`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看框架、版本、控制項目錄 | `oscal.framework.read` | |
| 下載 OSCAL 檔 | `oscal.framework.read` | 守在發下載憑證那支 |
| 看進行中匯入的提示條 | `oscal.framework.read` | |
| 新增框架 | `oscal.framework.create` | 原廠層，兩道門 |
| 改框架；新增、改、刪版本；改、刪控制項群組／控制項／評估方法 | `oscal.framework.update` | 原廠層，兩道門；子物件歸 update |
| 刪框架 | `oscal.framework.delete` | 原廠層，兩道門 |
| PDF 匯入框架版本（上傳、預覽、放棄、確認） | `oscal.framework.import` | 原廠層，兩道門 |

#### 畫面：檢測工具管理（合規與稽核 > 檢測工具管理，`/plugin/tool-plugin-manage`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看工具目錄、租戶工具設定、被幾個任務引用 | `detection.plugin.read` | |
| 新增工具設定 | `detection.plugin.create` | |
| 改設定、清空憑證、測試連線 | `detection.plugin.update` | 測試連線會解密憑證送主機，維持寫入級 |
| 挑遠端代理 | 跟呼叫頁權限 | 通則 B |

#### 畫面：掃描設定檔管理（合規與稽核 > 掃描設定檔管理，`/plugin/detection-profile-manage`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看設定檔、版本、控制項、抽取結果、被誰引用、分類下拉 | `detection.profile.read` | |
| 新增設定檔、建新版本、複製、複製到其他工具、手動重抽、補來源檔 | `detection.profile.create` | |
| 改設定檔 | `detection.profile.update` | |
| 刪設定檔、停用、刪版本 | `detection.profile.delete` | 停用＝下架，套件設計守 delete |
| 維護設定檔分類字典 | 原廠層（平台管理員） | 全域字典，見附錄 D 待裁 2 |

#### 畫面：流程範本管理（合規與稽核 > 流程範本管理，`/flow/template-manage`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看範本清單、明細、屬性面板下拉 | `flow.template.read` | 建專案時挑範本另由 `grc.project.create` 放行（通則 B） |
| 新增、複製範本 | `flow.template.create` | |
| 編輯範本、驗證 | `flow.template.update` | |
| 發布、取消發布 | `flow.template.publish` | |
| 刪除範本 | `flow.template.delete` | |

### 選單分組「溝通與互動」

#### 畫面：公告（溝通與互動 > 公告，`/bulletin/bulletin-list`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看發給自己部門的公告清單、打開單篇公告 | `workspace.bulletin.read` | 讀者模式：只列發送範圍含自己部門的 |

#### 畫面：公告管理（溝通與互動 > 公告管理，`/bulletin/bulletin-manage`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 進入管理頁、看自己建的公告清單 | `workspace.bulletin.create` | 選單改綁 create；管理模式由後端依能力點判，不吃前端旗標 |
| 新增公告 | `workspace.bulletin.create` | |
| 編輯公告 | `workspace.bulletin.update` | |
| 刪除公告 | `workspace.bulletin.delete` | |
| 挑發送部門 | 豁免 | 挑部門下拉只驗登入 |

#### 畫面：問卷管理（溝通與互動 > 問卷管理，`/survey/manage`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看資料夾、問卷清單、問卷內容、預覽 | `survey.survey.read` | |
| 新增問卷、複製問卷、新增資料夾 | `survey.survey.create` | 資料夾不另開資源 |
| 改問卷、改資料夾、搬移問卷；在設計器加、改、刪、排序、搬移題目與頁面 | `survey.survey.update` | 題目與頁面是問卷內容，改它們＝改問卷 |
| 刪問卷、刪資料夾 | `survey.survey.delete` | |
| 發布、取消發布 | `survey.survey.publish` | |
| Excel 匯入問卷、下載匯入範本 | `survey.survey.import` | 範本下載先換短期憑證，憑證那支守 import |

#### 畫面：回饋（溝通與互動 > 回饋，`/feedback/system-feedback-manage`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看自己送的回饋清單、單筆 | `workspace.feedback.read` | 沒有 feedback-review 時只回自己送的 |
| 送一筆新回饋 | `workspace.feedback.create` | |
| 改自己的回饋、刪附件 | `workspace.feedback.update` | 只能改自己送的 |
| 刪自己的回饋 | `workspace.feedback.delete` | 只能刪自己的 |
| 匯出回饋 | `workspace.feedback.export` | 匯出不分本人，等於整個公司的回饋；只配給有 `workspace.feedback-review.read` 的人（附錄 D 首腦補充 ①）；前端匯出鈕要補權限判斷 |
| 類別下拉 | 跟 `workspace.feedback.read` | 通則 B |

#### 畫面：系統回饋管理（溝通與互動 > 系統回饋管理，`/feedback/system-feedback-view`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看全公司所有人送的回饋 | `workspace.feedback-review.read` | 範圍型讀取，只開 read；出貨一般成員不帶 |
| 單筆檢視 | `workspace.feedback-review.read` | 與上同一支列表／單筆端點，由能力點切範圍 |

### 選單分組「租戶與組織」

#### 畫面：租戶管理（租戶與組織 > 租戶管理，`/tenant/tenant-manage`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看租戶清單、單筆、租戶下拉 | `iam.tenant.read` | 帳號、權限、部門管理頁的租戶篩選下拉也吃這顆 |
| 新增租戶 | `iam.tenant.create` | 建總部層租戶另需平台管理員 |
| 改租戶 | `iam.tenant.update` | 兩道門：平台管理員判定保留＋能力點 |
| 刪租戶 | `iam.tenant.delete` | 不能刪自己所在的租戶 |

#### 畫面：機關（構）單位管理（租戶與組織 > 機關（構）單位管理，`/department/department-manage`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看部門清單、單筆 | `iam.org-unit.read` | |
| 新增部門 | `iam.org-unit.create` | |
| 改部門 | `iam.org-unit.update` | |
| 刪部門 | `iam.org-unit.delete` | |
| 上層部門下拉 | 豁免 | 挑部門下拉只驗登入 |

#### 畫面：帳號管理（租戶與組織 > 帳號管理，`/auth/user-manage`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看帳號清單、看別人的帳號明細 | `iam.user.read` | 看自己的明細不需要 |
| 新增帳號 | `iam.user.create` | 同時帶角色指派另要 `iam.user.assign`；角色下拉要 `iam.role.read` |
| 改帳號、停用、啟用 | `iam.user.update` | 停用／啟用今天守 create，改為 update；存檔時角色指派與現況不同另要 `iam.user.assign` |
| 指派頁：新增、改範圍與起訖、刪除角色指派 | `iam.user.assign` | 看指派列表 `iam.user.read`；檢查存取看別人 `iam.user.read`、看自己不需要 |
| 刪帳號 | `iam.user.delete` | |
| Excel 批次匯入（上傳、驗證、確認）、下載匯入範本 | `iam.user.import` | |
| 替別人綁定、解除第三方登入帳號 | `iam.user.update` | 本人自己綁不需要 |

#### 畫面：權限管理（租戶與組織 > 權限管理，`/auth/role-manage`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看角色清單、單筆、角色下拉 | `iam.role.read` | |
| 角色矩陣的欄（能力點清單）與列（選單樹） | `iam.role.read` | 兩支輔助端點今天只驗登入 |
| 新增角色 | `iam.role.create` | |
| 改角色內容、啟用／停用角色 | `iam.role.update` | |
| 刪角色 | `iam.role.delete` | |

### 選單分組「系統管理」

#### 畫面：選單管理（系統管理 > 選單管理，`/system/system-menu-manage`）

原廠層，兩道門。這裡維護的是全站下拉選項字典。

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看字典清單、分類下拉 | `system.system-menu.read` | 今天只守平台管理員，補 read |
| 新增字典項 | `system.system-menu.create` | |
| 改字典項 | `system.system-menu.update` | |
| 刪字典項 | `system.system-menu.delete` | |
| 全站各頁讀字典（例如狀態下拉） | 豁免 | 全站字典，只驗登入 |

#### 畫面：資訊系統管理（系統管理 > 資訊系統管理，`/information-system/manage`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看清單、單筆 | `asset.information-system.read` | |
| 新增 | `asset.information-system.create` | |
| 改 | `asset.information-system.update` | |
| 刪 | `asset.information-system.delete` | |
| 被 SSP、資源庫頁挑選 | 跟呼叫頁權限 | 通則 B |
| 挑負責人、挑部門 | 豁免 | |

#### 畫面：設備管理（系統管理 > 設備管理，`/device/device-manage`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看清單、單筆、被誰引用（刪除前警示） | `asset.device.read` | |
| 新增 | `asset.device.create` | |
| 改 | `asset.device.update` | |
| 刪 | `asset.device.delete` | |
| Excel 匯入（下載範本、驗證、確認） | `asset.device.import` | 前端匯入鈕今天判 `device.update`，要換成 import |
| 匯出 | `asset.device.export` | 今天有 read 就能匯出 |
| 被 SSP、任務頁挑選 | 跟呼叫頁權限 | 通則 B |

#### 畫面：授權掃描網段（系統管理 > 授權掃描網段，`/system/scan-zone`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看網段清單 | `detection.scan-zone.read` | |
| 新增網段、從 Agent 產生建議 | `detection.scan-zone.create` | 今天守 update |
| 改網段、確認建議 | `detection.scan-zone.update` | |
| 刪網段 | `detection.scan-zone.delete` | 今天守 update |

#### 畫面：Agent 管理（系統管理 > Agent 管理，`/system/remote-agent-manage`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看代理清單（含停用）、單筆、健康檢查、看註冊碼摘要 | `detection.remote-agent.read` | |
| 新增代理、產生註冊碼 | `detection.remote-agent.create` | 註冊碼明文只顯示一次 |
| 改代理、啟用／停用、撤銷、恢復、核准新報到代理、重新綁定、對帳 | `detection.remote-agent.update` | 核准不另開 approve |
| 刪代理、停用所有註冊碼 | `detection.remote-agent.delete` | |
| 被工具設定、儲存設定、任務設置挑選 | 跟呼叫頁權限 | 通則 B |

今天 15 支管理端點全守 `remote-agent-manage.create`，要等套件守門插槽拆成讀寫兩個才能照上表分（det 定案 5）。

#### 畫面：操作日誌（系統管理 > 操作日誌，`/log/user-log`）

原廠層，兩道門。

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看操作紀錄 | `platform.api-log.read` | 今天後端只看平台管理員 |
| 匯出 | `platform.api-log.export` | |

#### 畫面：AI 用量（系統管理 > AI 用量，`/system/ai-call-log`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看呼叫紀錄清單、單筆明細、用量彙總 | `ai.call-log.read` | 依租戶篩選限平台管理員 |
| 匯出呼叫紀錄、匯出用量彙總 | `ai.call-log.export` | 今天跟 read 同一顆 |

#### 畫面：支援（系統管理 > 支援，`/system/support`）

原廠層，兩道門。

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看最近錯誤 | `platform.support.read` | 選單改綁這顆，拆掉借用的 `storage-config.*` |
| 下載診斷包 | `platform.support.export` | 診斷包含跨租戶資料 |

### 選單分組「系統設定」

設定頁的「測試送出」（測試信、通知測試、Log 轉發測試、LDAP 連線測試）一律歸該設定的 `update`。設定讀取今天多數只驗登入，改名時一起補 read（附錄 D 已知缺口）。

#### 畫面：郵件伺服器設定（系統設定 > 郵件伺服器設定，`/system/smtp-config-manage`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看設定 | `system.smtp-config.read` | 今天只驗登入，補 read |
| 新增設定 | `system.smtp-config.create` | |
| 改設定、寄測試信 | `system.smtp-config.update` | |
| 刪設定 | `system.smtp-config.delete` | |

#### 畫面：安全政策設定（系統設定 > 安全政策設定，`/system/security-policy`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看設定 | `system.security-policy.read` | |
| 改設定 | `system.security-policy.update` | 另限總部層級 |

#### 畫面：LDAP 伺服器設定（系統設定 > LDAP 伺服器設定，`/system/ldap-config`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看設定 | `system.ldap-config.read` | 今天只驗登入，補 read |
| 新增設定 | `system.ldap-config.create` | |
| 改設定、連線測試 | `system.ldap-config.update` | 連線測試今天守 create，改為 update |
| 刪設定 | `system.ldap-config.delete` | |

#### 畫面：通知設定（系統設定 > 通知設定，`/system/notify-config`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看設定 | `system.notify-config.read` | 今天只驗登入，補 read |
| 新增、改、刪頻道設定，送測試訊息 | `system.notify-config.update` | 泛用設定端點把這組的新增、刪除都對到 update；`create`／`delete` 是空殼，要不要讓新增、刪除改守空殼由 A.2 定 |

#### 畫面：Log 轉發設定（系統設定 > Log 轉發設定，`/system/log-forwarding`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看設定 | `system.log-forwarding.read` | |
| 改設定、送測試訊息 | `system.log-forwarding.update` | 另限總部層級 |

#### 畫面：儲存設備設定（系統設定 > 儲存設備設定，`/system/storage-config`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看設定、看有沒有出廠快照 | `system.storage-config.read` | |
| 新增設定 | `system.storage-config.create` | |
| 改設定、恢復出廠儲存 | `system.storage-config.update` | |
| 刪設定 | `system.storage-config.delete` | |
| 挑遠端代理 | 跟呼叫頁權限 | 通則 B |

#### 畫面：AI 服務設定（系統設定 > AI 服務設定，`/system/ai-service-config`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看各家 AI 服務設定（金鑰只顯示「已設」）、模型下拉 | `ai.ai-provider-config.read` | 選單改綁這顆，拆掉借用的 `storage-config.*`；今天另鎖平台管理員（程式常數，日後可開放給客戶自填） |
| 新增、改、清除金鑰 | `ai.ai-provider-config.update` | create／delete 照四個基本動詞建，今天沒有獨立按鈕 |
| 看 AI 證據分類設定 | `evidence.classification-profile.read` | 同一頁的分頁；今天讀也要 `storage-config.update` |
| 新增、改、刪 AI 證據分類設定 | `evidence.classification-profile.create`／`update`／`delete` | |

#### 畫面：AI 額度設定（系統設定 > AI 額度設定，`/system/ai-quota`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看本租戶與每位使用者的額度 | `ai.quota.read` | 守門在 service 層 |
| 改額度、還原預設 | `ai.quota.update` | 還原預設的 HTTP 是 DELETE，語意是改回繼承 |
| 看各租戶上限總覽、單一租戶上限 | `platform.ai-quota-ceiling.read` | 原廠層，兩道門；頁內區塊只有平台管理員看得到 |
| 改各租戶上限 | `platform.ai-quota-ceiling.update` | 原廠層，兩道門 |

#### 畫面：雲端空間整合（系統設定 > 雲端空間整合，`/settings/cloud-integrations`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看連線狀態、同步工作紀錄 | `evidence.cloud-integration.read` | 連線狀態今天刻意不掛，改掛 read，出貨一般成員組要帶 |
| 連接 Google Drive（取得授權網址） | `evidence.cloud-integration.create` | |
| 重試同步、重建全部資料夾、註冊變更通知 | `evidence.cloud-integration.update` | 重建全部是破壞性操作；這顆今天沒綁選單 |
| 中斷連線 | `evidence.cloud-integration.delete` | |

#### 畫面：回饋整合設定（系統設定 > 回饋整合設定，`/system/issue-integrate-config`）

原廠層，兩道門。

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看設定 | `system.issue-integrate-config.read` | 今天只驗登入，補 read |
| 新增、改、刪設定 | `system.issue-integrate-config.create`／`update`／`delete` | |

#### 畫面：Google Drive 應用程式設定（系統設定 > Google Drive 應用程式設定，`/system/drive-app-config`）

原廠層，兩道門。這裡設的是全站共用一份的 Google 應用程式帳號。

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看設定（密鑰遮罩）、驗證憑證能不能用 | `platform.drive-app-credential.read` | 驗證不改值，取 read；選單改綁這顆，拆掉借用的 `storage-config.*` |
| 存設定 | `platform.drive-app-credential.update` | 今天走未登記設定群組的兜底（`system_config.update`）；把這個設定群組正式登記到這顆 |
| 新增、刪除 | `platform.drive-app-credential.create`／`delete` | 照四個基本動詞建，今天沒有獨立按鈕 |

### 選單分組「AI 與分析」

#### 畫面：AI 動態儀表板（AI 與分析 > AI動態儀表板，`/dashboard/ai-dashboard`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 產生儀表板 | `ai.dashboard.read` | 每次會打外部 AI；授權照仍要有 AI 儀表板包 |
| 小幫手上線狀態 | 豁免 | 免登入（頁面載入時還沒拿到登入憑證也要能問） |

### 選單分組「授權管理」

#### 畫面：License 授權管理（授權管理 > License 授權管理，`/license/manage`）

原廠層，兩道門。

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看各租戶授權總覽、單一租戶、異動紀錄、方案下拉 | `platform.license.read` | |
| 指派或換發授權照、向 License Center 請新照 | `platform.license.assign` | |
| 停權、解除停權、展延 | `platform.license.update` | |
| 上傳照檔 | `platform.license.import` | |

#### 畫面：我的授權狀態（授權管理 > 我的授權狀態，`/license/status`）

| 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|
| 看本租戶授權狀態 | 豁免 | 只驗登入：授權過期時還要能進來自救 |
| 開通頁：抄機器碼、上傳照檔、線上開通 | 豁免 | 同上，防死鎖 |

選單樹裡這一頁沒有綁任何能力點，維持不綁。

### 沒有選單的功能

| 功能 | 按鈕／動作 | 需要的能力點 | 備註 |
|---|---|---|---|
| 個人資料（右上角） | 看、改自己的基本資料，改兩階段驗證方式 | 豁免（本人） | 角色、租戶、部門不採信送上來的值 |
| 個人資料 | 綁定、解除自己的第三方登入帳號 | 豁免（本人） | 替別人綁要 `iam.user.update` |
| 個人資料 | 看自己綁了哪些第三方登入帳號 | 豁免（本人） | 今天沒有本人檢查，任何人帶別人 uid 都看得到，要補（附錄 D 已知缺口） |
| 個人資料 | 設定兩階段驗證（取密鑰、QR code、驗證） | 豁免（本人） | |
| 登入流程 | 登入、換發登入憑證、登出、兩階段驗證碼驗證與重寄、忘記密碼、重設密碼 | 豁免（免登入） | |
| 側邊選單 | 載入自己的選單與能力點清單 | 豁免（本人） | 角色矩陣改了之後重抓也走這支 |
| 頁首 | 待辦數字 | `grc.job.read` | 個人視角 |
| 頁首 | 切換租戶 | 豁免（本人） | 重抓選單 |
| AI 小幫手（右下角，全站） | 聊天、清除自己的對話紀錄 | `ai.assistant.read` | 每次聊天都花 AI 錢；出貨範本一般成員帶 read |
| AI 額度黃條（小幫手、自動分類頁） | 看自己用了多少額度 | 豁免 | 不掛能力點，一般成員也要看到 |
| 檔案上傳、下載、預覽（全站） | 上傳檔案、換下載憑證、下載、PDF 預覽、刪自己上傳的暫存檔 | 不開能力點 | 由檔案所屬功能自己的守門代判（附錄 C） |
| 查核項目流程圖（`/workflow/workflow-setup`） | 讀流程圖 | 依歸屬：專案→`grc.project.read`＋專案成員；資源庫→`oscal.resource-library.read` | 通則 C，見專案規劃、合規資源庫兩節 |
| 查核項目流程圖 | 存流程圖 | `oscal.resource-library.update` | 只有資源庫能存 |
| 關於 | 版本資訊 | 豁免（免登入） | |
| 安裝精靈 | 首次開站查狀態、開通 | 豁免 | 一次性設定碼＋已開通就封 |

## 第二部分：能力點樹（資源 × 動詞總表）

✓＝今天有端點或選單會用到；**殼**＝今天沒有對應端點，照「固定四個」建出來；—＝不建。`license_module` 欄寫的是舊 `resource_type` 原值（授權照判定用，客戶手上的照檔不重簽）；「新」＝今天沒有舊能力點，新建時的填值。`is_platform`＝true 的能力點不會給非原廠租戶。

| 模組 | 資源 | read | create | update | delete | 獨立動詞 | is_platform | license_module | 白話說明 |
|---|---|---|---|---|---|---|---|---|---|
| grc | project | ✓ | ✓ | ✓ | ✓ | `assign` | false | `project` | 專案本身與專案成員 |
| grc | job | ✓ | ✓ | ✓ | ✓ | `assign`、`import`、`export` | false | 新：`project` | 任務；含檢測執行、問卷填答、任務問卷設定（通則 A） |
| grc | job-comment | ✓ | ✓ | ✓ | ✓ | — | false | 新：`project` | 任務留言 |
| grc | job-evidence | ✓ | ✓ | ✓ | ✓ | — | false | 新：`project` | 任務佐證檔 |
| grc | audit | ✓ | ✓ | ✓ | ✓ | `import`、`close`、`approve` | false | `audit` | 稽核輪次、評估計畫、評估結果（含風險）、矯正計畫、稽核階段推進 |
| grc | summary-report | ✓ | ✓ | ✓ | ✓ | `export` | false | `project-summary-report` | 專案總結報告 |
| oscal | framework | ✓ | ✓ | ✓ | ✓ | `import` | create／update／delete／import 為 true，read 為 false | `compliance-framework` | 合規框架、版本、控制項目錄 |
| oscal | resource-library | ✓ | ✓ | ✓ | ✓ | — | false | `module-frame` | 合規資源庫（範本） |
| oscal | ssp | ✓ | **殼** | ✓ | **殼** | `import`、`export` | false | 新：`project` | 專案的系統安全計畫（SSP 隨建專案產生，沒有新增／刪除鈕） |
| flow | template | ✓ | ✓ | ✓ | ✓ | `publish` | false | `flow_template` | 流程範本 |
| detection | remote-agent | ✓ | ✓ | ✓ | ✓ | — | false | `remote-agent-manage` | 遠端 Agent |
| detection | plugin | ✓ | ✓ | ✓ | **殼** | — | false | `plugin` | 檢測工具外掛設定 |
| detection | profile | ✓ | ✓ | ✓ | ✓ | — | false | `detection-profile` | 掃描設定檔（檢測基準） |
| detection | scan-zone | ✓ | ✓ | ✓ | ✓ | — | false | `scan-zone` | 授權掃描網段（基礎設施，不受授權照管制） |
| evidence | cloud-integration | ✓ | ✓ | ✓ | ✓ | — | false | `cloud_integration` | 雲端空間（Google Drive）整合 |
| evidence | classification | ✓ | ✓ | ✓ | ✓ | `execute` | false | 新：`evidence-classification` | AI 證據分類批次與結果 |
| evidence | classification-profile | ✓ | ✓ | ✓ | ✓ | — | false | 新：`evidence-classification` | AI 證據分類設定 |
| survey | survey | ✓ | ✓ | ✓ | ✓ | `import`、`publish` | false | `survey` | 問卷設計（填答歸 `grc.job`） |
| system | smtp-config | ✓ | ✓ | ✓ | ✓ | — | false | `smtp-config` | 郵件伺服器設定 |
| system | ldap-config | ✓ | ✓ | ✓ | ✓ | — | false | `ldap-config` | LDAP 伺服器設定 |
| system | notify-config | ✓ | **殼** | ✓ | **殼** | — | false | `notify_config` | 通知設定 |
| system | security-policy | ✓ | **殼** | ✓ | **殼** | — | false | `security-policy` | 安全政策設定 |
| system | log-forwarding | ✓ | **殼** | ✓ | **殼** | — | false | `log-forwarding` | Log 轉發設定 |
| system | system-config | ✓（新補） | ✓ | ✓ | ✓ | — | true | `system_config` | 未登記設定群組的兜底門（不綁任何頁） |
| system | system-menu | ✓ | ✓ | ✓ | ✓ | — | true | `system-menu` | 系統下拉字典（選單管理） |
| system | storage-config | ✓ | ✓ | ✓ | ✓ | — | false | `storage-config` | 儲存設備設定 |
| system | issue-integrate-config | ✓ | ✓ | ✓ | ✓ | — | true | `issue-integrate-config` | 回饋整合設定 |
| iam | user | ✓ | ✓ | ✓ | ✓ | `import`、`assign` | false | `user` | 帳號 |
| iam | role | ✓ | ✓ | ✓ | ✓ | `export`、`import` | false | `role` | 權限（角色） |
| iam | org-unit | ✓ | ✓ | ✓ | ✓ | — | false | `department` | 部門（機關（構）單位） |
| iam | tenant | ✓ | ✓ | ✓ | ✓ | — | false | `tenant` | 租戶 |
| platform | api-log | ✓ | **殼** | **殼** | **殼** | `export` | true | `log` | 操作日誌 |
| platform | support | ✓ | **殼** | **殼** | **殼** | `export` | true | 新：`support` | 支援頁（最近錯誤、診斷包） |
| platform | ai-quota-ceiling | ✓ | **殼** | ✓ | **殼** | — | true | 新：`ai-quota` | 原廠設定各租戶 AI 額度上限 |
| platform | license | ✓ | **殼** | ✓ | **殼** | `assign`、`import` | true | `license` | 原廠管理各租戶授權照 |
| platform | drive-app-credential | ✓ | ✓ | ✓ | ✓ | — | true | 新：`storage-config` | Google Drive 應用程式憑證（全站共用 OAuth 帳號） |
| asset | device | ✓ | ✓ | ✓ | ✓ | `import`、`export` | false | `device` | 設備 |
| asset | information-system | ✓ | ✓ | ✓ | ✓ | — | false | `information-system` | 資訊系統 |
| ai | dashboard | ✓ | **殼** | **殼** | **殼** | — | false | `ai-dashboard` | AI 動態儀表板（加值包） |
| ai | assistant | ✓ | **殼** | **殼** | **殼** | — | false | 新：`ai-assistant` | AI 小幫手 |
| ai | call-log | ✓ | **殼** | **殼** | **殼** | `export` | false | `ai-call-log` | AI 用量（呼叫紀錄） |
| ai | quota | ✓ | **殼** | ✓ | **殼** | — | false | `ai-quota` | 租戶自己的 AI 額度 |
| ai | ai-provider-config | ✓ | ✓ | ✓ | ✓ | — | false | 新：`storage-config` | AI 服務設定（供應商金鑰、模型）＋ AI 證據分類設定的模型清單 |
| workspace | bulletin | ✓ | ✓ | ✓ | ✓ | — | false | `bulletin` | 公告 |
| workspace | feedback | ✓ | ✓ | ✓ | ✓ | `export` | false | `feedback` | 意見回饋（送自己的） |
| workspace | feedback-review | ✓ | — | — | — | — | false | `feedback-view` | 收集全公司回饋（範圍型讀取，只開 read） |

**合計**：12 模組、46 個資源（grc 6、oscal 3、flow 1、detection 4、evidence 3、survey 1、system 9、iam 4、platform 5、asset 2、ai 5、workspace 3）。design.md §6.1 模組定稿表的 system 列沒寫 `system-menu`，本表補上（附錄 D 統一處）。

**本部分「新」license_module 的填法**：今天沒有舊能力點的資源，`license_module` 照「它實際受哪一道授權照守門」填，讓 A.2 新建時不必再查：
- `grc.job`、`grc.job-comment`、`grc.job-evidence`、`oscal.ssp` 填 `project`：這些端點今天守 `require_license("project")`（SSP 今天沒有授權照守門，跟著專案）。
- `evidence.classification`、`evidence.classification-profile` 填 `evidence-classification`（det 定案 6，視為基礎包）。
- `platform.support` 填 `support`；`platform.ai-quota-ceiling` 填 `ai-quota`（基礎設施豁免清單內）。
- `ai.assistant` 填 `ai-assistant`。
- `platform.drive-app-credential`、`ai.ai-provider-config` 填 `storage-config`：今天借用它，它是基礎包，填它不會讓任何租戶突然被判「沒買」。

以上「新」填值是本檔依現行守門推導的，**待首腦確認**（見附錄 D 待裁 1）。

## 第三部分：出貨角色怎麼對上樹

角色存的是 pattern，不是一顆顆能力點。判定時把 pattern 跟第二部分的能力點清單逐段比對，三段都對上的就算持有。`*` 只能佔整段。出貨四個角色的內容在 `a1-shipped-roles.json`，以下說明三種寫法各會展開成什麼。數字以第二部分的清單計：12 模組、46 個資源、206 個能力點，其中 `is_platform` 40 個。

**1. `*.*.*`（系統管理員）**

- 等於清單上全部 204 個，日後新增的能力點自動涵蓋，不必回頭補角色。
- 總部租戶（原廠）拿到全部 204 個。
- 其他租戶展開時先扣掉 `is_platform` 的 40 個（`platform.*` 24 個、`oscal.framework` 寫入 4 個、`system.issue-integrate-config.*`、`system.system-config.*`、`system.system-menu.*` 各 4 個），剩 164 個。原廠層端點另有平台管理員判定，就算誤配也開不了門。
- 授權照沒買的模組不在展開時扣，而是使用時由授權照那一道擋（客戶補買後不必改角色）。
- 這個角色每個租戶都有、不能改也不能刪，保證至少有一個人能進來修權限。

**2. `grc.*.*`（業務模組整包）**

- 展開成該模組所有資源的所有動詞。以 `grc.*.*` 為例是 32 個：專案、任務、留言、佐證、稽核、摘要報告六個資源的四個基本動詞，加上 `grc.project.assign`、`grc.job.assign／import／export`、`grc.audit.import／close／approve`、`grc.summary-report.export`。
- 模組日後新增資源或動詞，自動跟著涵蓋。這正是「模組＝客戶會當一組授權的功能」的原因：給整包時，客戶心裡想的就是「這一整塊都交給他」。
- `oscal.*.*` 雖然含 `oscal.framework` 的四個寫入，那幾個是 `is_platform`，非總部租戶照樣扣掉。
- `flow` 刻意不跟 `grc` 合在一起：流程範本改壞了，之後所有新專案都受影響，不應因為給了專案主管 `grc.*.*` 就順帶拿到。

**3. 列舉 read（`*.*.read`、`oscal.*.read`、`grc.project.read`）**

- `*.*.read` 展開成每個資源的 read，共 46 個；非總部租戶扣掉 8 個原廠層 read，剩 38 個。
- `oscal.*.read` 這種「某模組全部 read」的寫法，給的是該模組每個資源的看權限，不含任何獨立動詞——所以 `oscal.*.read` 拿不到 `oscal.ssp.export`。只看不帶走，是刻意的。
- 單一 `grc.project.read` 就是那一個，不展開。
- 「看」不等於「看得到每一筆」：個人視角頁（我的任務、我的稽核）只回自己參與的；專案內的資料另由專案成員身分決定；部門隔離開啟時再依部門收窄。

**出貨四角色一覽**

| 角色 | pattern 寫法 | 展開數 | 一句話 |
|---|---|---|---|
| 系統管理員 | `*.*.*` | 204（非總部 164） | 全部；內建、不可改不可刪 |
| 稽核主管 | `grc.*.*`、`oscal.*.*`、`asset.*.*`、`evidence.*.*`、`detection.*.*`、`survey.*.*` 整包，加 `workspace.bulletin.*`、`workspace.feedback` 四動詞、`ai.dashboard.*`、`ai.assistant.read`、`ai.call-log.read`、`ai.quota.read` | 106（非總部扣 4 個框架寫入，102） | 管稽核專案全流程；不碰流程範本、系統設定、帳號角色、原廠層 |
| 稽核員 | `grc.project.read`、`grc.job.*`、`grc.job-comment.*`、`grc.job-evidence.*`、`grc.audit.read／update／import`、`grc.summary-report.read`，各業務模組 read，`workspace.bulletin.read`、`workspace.feedback` 四動詞、`ai.dashboard.read`、`ai.assistant.read` | 40 | 執行任務、寫稽核判定；不結束輪次、不打審閱勾 |
| 唯讀 | `grc.*.read`、`oscal.*.read`、`asset.*.read`、`evidence.*.read`、`detection.*.read`、`survey.*.read`、`flow.template.read`，加 `workspace.bulletin.read`、`workspace.feedback` 四動詞、`ai.dashboard.read`、`ai.assistant.read` | 27 | 全部只看；可以送自己的意見回饋 |

三個範例角色都不帶 `workspace.feedback.export`（附錄 D 首腦補充 ①）與 `workspace.feedback-review.read`（`a1-platform.md` 定案 8）。所以 `a1-shipped-roles.json` 寫的是四個基本動詞，不寫 `workspace.feedback.*`（後者會展開出 export）。三個可改範例角色加「一般成員」共五個，裁示見附錄 D 與 JSON `_meta.rulings_2026_10_06`。

## 附錄 A：技術對照（route → 能力點）

五份盤點主表的每一支 route（含 HTTP 動詞）逐列對到新名。「新名」欄已套用定案結論、首腦裁示與三條通則，與盤點主表不一致處列在附錄 D。「舊名」是今天守它的能力點（「無」＝今天沒有能力點守門）。「守門位置」是 route method 定義行；套件路徑省略 `.venv/lib/python3.11/site-packages/`；`/api/1.0` 前綴省略。豁免列的理由見附錄 C。

設定類泛用端點（`/system/config*`）一支服務多個設定頁，依設定群組判資源（通則 C）。群組對資源：STORAGE_CONFIG→`system.storage-config`、SMTP→`system.smtp-config`、THIRD_PARTY_LOGIN→`system.ldap-config`、NOTIFY_CONFIG→`system.notify-config`、ISSUE_INTEGRATE_CONFIG→`system.issue-integrate-config`、RUNTIME_CONFIG→`system.security-policy`、AI_PROVIDER_CONFIG→`ai.ai-provider-config`、GOOGLE_DRIVE_APP_CONFIG→`platform.drive-app-credential`（今天未登記、走兜底，要正式登記）、其餘→`system.system-config`。下表這幾列簡寫為「依設定群組」。

### grc 專案稽核（120 支）

| route | HTTP | 新名 | 舊名 | 守門位置 |
|---|---|---|---|---|
| `/oscal-project/start` | POST | `grc.project.create` | `project.create` | `api/project/routes/project_route.py:28` |
| `/grc/projects/list` | POST | `grc.project.read` | `project.read` | `api/flow_control/routes/project_route.py:99` |
| `/grc/project/<uid>` | GET | `grc.project.read` | `project.read` | `api/flow_control/routes/project_route.py:146` |
| `/grc/project/<uid>` | PUT | `grc.project.update` | `project.update` | `api/flow_control/routes/project_route.py:177` |
| `/grc/project/<uid>` | DELETE | `grc.project.delete` | `project.delete` | `api/flow_control/routes/project_route.py:232` |
| `/grc/projects/batch-delete` | POST | `grc.project.delete` | `project.delete` | `api/flow_control/routes/project_route.py:258` |
| `/grc/jobs/my/projects/menu` | GET | `grc.project.read` | 無 | `api/flow_control/routes/project_route.py:74` |
| `/grc/dashboard/summary` | GET | `grc.project.read` | 無 | 套件 `jedi_task_platform/task/api/routes/dashboard_route.py:28` |
| `/project-participants/menu` | GET | `grc.project.read` | 無 | 套件 `jedi_task_platform/participant/api/routes/project_participant_route.py:20` |
| `/project-participants` | POST | `grc.project.read` | 無 | 套件 `jedi_task_platform/participant/api/routes/project_participant_route.py:39` |
| `/project-participant` | POST | `grc.project.assign` | 無 | 套件 `jedi_task_platform/participant/api/routes/project_participant_route.py:55` |
| `/project-participant` | PUT | `grc.project.assign` | 無 | 套件 `jedi_task_platform/participant/api/routes/project_participant_route.py:71` |
| `/project-participant` | DELETE | `grc.project.assign` | 無 | 套件 `jedi_task_platform/participant/api/routes/project_participant_route.py:84` |
| `/grc/project/<pid>/start-task-execution` | POST | `grc.job.assign` | 無 | 套件 `jedi_task_platform/task/api/routes/task_execution_route.py:34` |
| `/grc/project/<pid>/task-execution/progress` | GET | `grc.project.read` | 無 | 套件 `jedi_task_platform/task/api/routes/task_execution_route.py:57` |
| `/projects/<pid>/audit-rounds` | POST | `grc.audit.create` | 無 | `api/project/routes/audit_round_route.py:58` |
| `/projects/<pid>/audit-rounds/list` | POST | `grc.audit.read` | 無 | `api/project/routes/audit_round_route.py:74` |
| `/audit-round/<rid>` | GET | `grc.audit.read` | 無 | `api/project/routes/audit_round_route.py:86` |
| `/audit-round/<rid>/close-round` | POST | `grc.audit.close` | 無 | `api/project/routes/audit_round_route.py:97` |
| `/audit-round/<rid>/launch-reverify` | POST | `grc.audit.create` | 無 | `api/project/routes/audit_round_route.py:110` |
| `/audits/my/list` | POST | `grc.audit.read` | 無 | 套件 `jedi_compliance_audit/api/routes/auditor_dashboard_route.py:26` |
| `/grc/project/<pid>/assessment-plans/menu` | GET | `grc.audit.read` | 無 | `api/flow_control/routes/assessment_plan_route.py:32` |
| `/grc/project/<pid>/ap/<ap>/dashboard` | GET | `grc.audit.read` | 無 | `api/flow_control/routes/assessment_plan_route.py:54` |
| `/audit-round/<rid>/ap` | GET | `grc.audit.read` | 無 | `api/project/routes/audit_round_route.py:139` |
| `/ap/<ap>/reviewed-controls` | PUT | `grc.audit.update` | 無 | `api/project/routes/audit_round_route.py:152` |
| `/ap/<ap>/assessment-subjects` | PUT | `grc.audit.update` | 無 | `api/project/routes/audit_round_route.py:167` |
| `/ap/<ap>/tasks` | PUT | `grc.audit.update` | 無 | `api/project/routes/audit_round_route.py:182` |
| `/ap/<ap>/parties` | GET | `grc.audit.read` | 無 | `api/project/routes/audit_round_route.py:198` |
| `/ap/<ap>/parties` | POST | `grc.audit.update` | 無 | `api/project/routes/audit_round_route.py:208` |
| `/ap/<ap>/docx-imports/parse` | POST | `grc.audit.import` | 無 | `api/project/routes/ap_docx_import_route.py:42` |
| `/ap-docx-import/<parse>` | GET | `grc.audit.import` | 無 | `api/project/routes/ap_docx_import_route.py:66` |
| `/ap-docx-import/<parse>` | DELETE | `grc.audit.import` | 無 | `api/project/routes/ap_docx_import_route.py:82` |
| `/ap-docx-import/<parse>/confirm` | POST | `grc.audit.import` | 無 | `api/project/routes/ap_docx_import_route.py:103` |
| `/grc/project/<pid>/ap/<ap>/control/<c>/review` | POST | `grc.audit.approve` | 無 | 套件 `jedi_compliance_audit/api/routes/review_route.py:18` |
| `/grc/project/<pid>/ap/<ap>/control/<c>/review` | DELETE | `grc.audit.approve` | 無 | 套件 `jedi_compliance_audit/api/routes/review_route.py:27` |
| `/grc/project/<pid>/ap/<ap>/control/<c>/ao/<ao>/review` | POST | `grc.audit.approve` | 無 | 套件 `jedi_compliance_audit/api/routes/review_route.py:40` |
| `/grc/project/<pid>/ap/<ap>/control/<c>/ao/<ao>/review` | DELETE | `grc.audit.approve` | 無 | 套件 `jedi_compliance_audit/api/routes/review_route.py:49` |
| `/audit-round/<rid>/ar/findings` | GET | `grc.audit.read` | 無 | `api/project/routes/audit_round_route.py:223` |
| `/audit-round/<rid>/ar/finding/<f>` | PUT | `grc.audit.update` | 無 | `api/project/routes/audit_round_route.py:235` |
| `/audit-round/<rid>/ar/observations` | POST | `grc.audit.create` | 無 | `api/project/routes/audit_round_route.py:252` |
| `/audit-round/<rid>/ar/observation/<o>` | PUT | `grc.audit.update` | 無 | `api/project/routes/audit_round_route.py:270` |
| `/audit-round/<rid>/ar/observation/<o>` | DELETE | `grc.audit.delete` | 無 | `api/project/routes/audit_round_route.py:285` |
| `/audit-round/<rid>/ar/risks` | GET | `grc.audit.read` | 無 | `api/project/routes/audit_round_route.py:299` |
| `/audit-round/<rid>/ar/risks` | POST | `grc.audit.create` | 無 | `api/project/routes/audit_round_route.py:309` |
| `/audit-round/<rid>/ar/risk/<r>` | PUT | `grc.audit.update` | 無 | `api/project/routes/audit_round_route.py:327` |
| `/audit-round/<rid>/ar/risk/<r>` | DELETE | `grc.audit.delete` | 無 | `api/project/routes/audit_round_route.py:342` |
| `/audit-round/<rid>/ar/risk/<r>/findings` | PUT | `grc.audit.update` | 無 | `api/project/routes/audit_round_route.py:357` |
| `/audit-round/<rid>/ar-imports/parse` | POST | `grc.audit.import` | 無 | `api/project/routes/ar_import_route.py:42` |
| `/ar-import/<parse>` | GET | `grc.audit.import` | 無 | `api/project/routes/ar_import_route.py:66` |
| `/ar-import/<parse>` | DELETE | `grc.audit.import` | 無 | `api/project/routes/ar_import_route.py:82` |
| `/ar-import/<parse>/confirm` | POST | `grc.audit.import` | 無 | `api/project/routes/ar_import_route.py:103` |
| `/audit-round/<rid>/poam-items` | GET | `grc.audit.read` | 無 | `api/project/routes/audit_round_route.py:373` |
| `/audit-round/<rid>/poam-item/<i>` | GET | `grc.audit.read` | 無 | `api/project/routes/audit_round_route.py:384` |
| `/audit-round/<rid>/ar/risk/<r>/remediations` | POST | `grc.audit.create` | 無 | `api/project/routes/audit_round_route.py:396` |
| `/audit-round/<rid>/remediation/<m>/milestones` | POST | `grc.audit.create` | 無 | `api/project/routes/audit_round_route.py:412` |
| `/audit-round/<rid>/poam-milestone/<ms>` | PUT | `grc.audit.update` | 無 | `api/project/routes/audit_round_route.py:432` |
| `/audit-round/<rid>/poam-milestone/<ms>` | DELETE | `grc.audit.delete` | 無 | `api/project/routes/audit_round_route.py:444` |
| `/audit-round/<rid>/remediation/<m>` | DELETE | `grc.audit.delete` | 無 | `api/project/routes/audit_round_route.py:458` |
| `/grc/project/<pid>/ap/<ap>/control-group/<g>/control/<c>/assessment-object/<ao>/jobs/list` | POST | `grc.job.read` | 無 | `api/flow_control/routes/job_route.py:52` |
| `/grc/project/<pid>/job/<job>` | GET | `grc.job.read` | 無 | `api/flow_control/routes/job_route.py:82` |
| `/grc/project/<pid>/job/<job>` | PUT | `grc.job.update` | 無 | `api/flow_control/routes/job_route.py:104` |
| `/grc/project/<pid>/job/<job>` | DELETE | `grc.job.delete` | 無 | `api/flow_control/routes/job_route.py:147` |
| `/grc/project/<pid>/assessment-object/<ao>/jobs` | POST | `grc.job.create` | 無 | `api/flow_control/routes/job_route.py:183` |
| `/grc/jobs/my/list` | POST | `grc.job.read` | 無 | `api/flow_control/routes/job_route.py:231` |
| `/grc/project/<pid>/job/<job>/blocked-status` | GET | `grc.job.read` | 無 | `api/flow_control/routes/job_force_start_route.py:41` |
| `/grc/project/<pid>/job/<job>/force-start` | POST | `grc.job.assign` | 無 | `api/flow_control/routes/job_force_start_route.py:66` |
| `/grc/project/<pid>/jobs/batch-complete` | POST | `grc.job.update` | 無 | 套件 `jedi_task_platform/task/api/routes/job_batch_complete_route.py:26` |
| `/grc/project/<pid>/ap/<ap>/jobs/export` | GET | `grc.job.export` | `project.export` | 套件 `jedi_task_platform/task/api/routes/job_import_route.py:34` |
| `/grc/project/<pid>/ap/<ap>/jobs/import` | POST | `grc.job.import` | 無 | 套件 `jedi_task_platform/task/api/routes/job_import_route.py:52` |
| `/grc/project/<pid>/ap/<ap>/jobs/import/validate` | POST | `grc.job.import` | 無 | 套件 `jedi_task_platform/task/api/routes/job_import_route.py:70` |
| `/grc/project/<pid>/ap/<ap>/jobs/import/confirm` | POST | `grc.job.import` | 無 | 套件 `jedi_task_platform/task/api/routes/job_import_route.py:86` |
| `/task-assignees` | POST | `grc.job.read` | 無 | 套件 `jedi_task_platform/participant/api/routes/task_assignee_route.py:44` |
| `/task-assignees/batch` | POST | `grc.job.assign` | 無 | 套件 `jedi_task_platform/participant/api/routes/task_assignee_route.py:20` |
| `/task-assignee` | POST | `grc.job.assign` | 無 | 套件 `jedi_task_platform/participant/api/routes/task_assignee_route.py:59` |
| `/task-assignee` | PUT | `grc.job.assign` | 無 | 套件 `jedi_task_platform/participant/api/routes/task_assignee_route.py:73` |
| `/task-assignee` | DELETE | `grc.job.assign` | 無 | 套件 `jedi_task_platform/participant/api/routes/task_assignee_route.py:95` |
| `/grc/job-executions/<je>/comments` | GET | `grc.job-comment.read` | 無 | 套件 `jedi_task_platform/task/api/routes/job_comment_route.py:25` |
| `/grc/job-executions/<je>/comments` | POST | `grc.job-comment.create` | 無 | 套件 `jedi_task_platform/task/api/routes/job_comment_route.py:35` |
| `/grc/job/comment/<c>` | PUT | `grc.job-comment.update` | 無 | 套件 `jedi_task_platform/task/api/routes/job_comment_route.py:58` |
| `/grc/job/comment/<c>` | DELETE | `grc.job-comment.delete` | 無 | 套件 `jedi_task_platform/task/api/routes/job_comment_route.py:74` |
| `/flow-engine/task/complete/<id>` | POST | `grc.job.update` | 無 | `api/flow_engine/routes/flow_engine_route.py:38` |
| `/flow-engine/task/revert/<id>` | POST | `grc.job.update` | 無 | `api/flow_engine/routes/flow_engine_route.py:63` |
| `/flow-engine/task/queue` | GET | `grc.job.read` | 無 | `api/flow_engine/routes/flow_engine_route.py:88` |
| `/flow-engine/stage-notifications/mine` | GET | `grc.job.read` | 無 | `api/flow_engine/routes/flow_engine_route.py:105` |
| `/job-evidences` | GET | `grc.job-evidence.read` | 無 | `api/flow_engine/routes/job_evidence_route.py:27` |
| `/job-evidences` | POST | `grc.job-evidence.create` | 無 | `api/flow_engine/routes/job_evidence_route.py:36` |
| `/job-evidence` | POST | `grc.job-evidence.create` | 無 | `api/flow_engine/routes/job_evidence_route.py:131` |
| `/job-evidence/<uid>` | GET | `grc.job-evidence.read` | 無 | `api/flow_engine/routes/job_evidence_route.py:64` |
| `/job-evidence/<uid>` | PUT | `grc.job-evidence.update` | 無 | `api/flow_engine/routes/job_evidence_route.py:78` |
| `/job-evidence/<uid>` | DELETE | `grc.job-evidence.delete` | 無 | `api/flow_engine/routes/job_evidence_route.py:97` |
| `/project/<pid>/audit-round/<rid>/stage/info` | GET | `grc.audit.read` | 無 | `api/flow_engine/routes/stage_advance_route.py:28` |
| `/project/<pid>/audit-round/<rid>/stage/advance` | POST | `grc.audit.update` | 無 | `api/flow_engine/routes/stage_advance_route.py:49` |
| `/project/<pid>/audit-round/<rid>/stage/rollback` | POST | `grc.audit.update` | 無 | `api/flow_engine/routes/stage_rollback_route.py:29` |
| `/project/<pid>/audit-round/<rid>/stage/transitions` | GET | `grc.audit.read` | 無 | `api/flow_engine/routes/stage_rollback_route.py:59` |
| `/project-summary-reports` | POST | `grc.summary-report.read` | `project-summary-report.read`（只綁選單） | `api/project_summary_report/routes/project_summary_report_route.py:83` |
| `/project-summary-report` | POST | `grc.summary-report.create` | `project-summary-report.create`（只綁選單） | `api/project_summary_report/routes/project_summary_report_route.py:103` |
| `/project-summary-report/<uid>` | GET | `grc.summary-report.read` | `project-summary-report.read`（只綁選單） | `api/project_summary_report/routes/project_summary_report_route.py:120` |
| `/project-summary-report/<uid>` | PUT | `grc.summary-report.update` | `project-summary-report.update`（只綁選單） | `api/project_summary_report/routes/project_summary_report_route.py:129` |
| `/project-summary-report/<uid>` | DELETE | `grc.summary-report.delete` | `project-summary-report.delete`（只綁選單） | `api/project_summary_report/routes/project_summary_report_route.py:149` |
| `/project-summary-report/export/<uid>` | GET | `grc.summary-report.export` | 無 | `api/project_summary_report/routes/project_summary_report_route.py:160` |
| `/project-summary-report/histories` | POST | `grc.summary-report.read` | `project-summary-report.read`（只綁選單） | `api/project_summary_report/routes/project_summary_report_history_route.py:28` |
| `/project-summary-report/history/<uid>` | GET | `grc.summary-report.read` | `project-summary-report.read`（只綁選單） | `api/project_summary_report/routes/project_summary_report_history_route.py:47` |
| `/project-summary-report/history-revert` | POST | `grc.summary-report.update` | `project-summary-report.update`（只綁選單） | `api/project_summary_report/routes/project_summary_report_history_route.py:61` |
| `/task-surveys` | POST | `grc.job.read`｜`grc.job-evidence.read`（任一；後者限已完成問卷） | 無 | 套件 `jedi_survey/api/routes/task_survey_route.py:28` |
| `/task-survey/<uid>` | GET | `grc.job.read`｜`grc.job-evidence.read`（任一；後者限已完成問卷） | 無 | 套件 `jedi_survey/api/routes/task_survey_route.py:40` |
| `/task-survey/<uid>` | PUT | `grc.job.update` | 無 | 套件 `jedi_survey/api/routes/task_survey_route.py:49` |
| `/task-survey/configured/<uid>` | PUT | `grc.job.update` | 無 | 套件 `jedi_survey/api/routes/task_survey_route.py:155` |
| `/task-survey/import-template/<task_uid>` | GET | `grc.job.read` | 無 | 套件 `jedi_survey/api/routes/task_survey_route.py:65` |
| `/task-survey/import-answers` | POST | `grc.job.update` | 無 | 套件 `jedi_survey/api/routes/task_survey_route.py:134` |
| `/project-survey/answers/<uid>` | GET | `grc.job.read`｜`grc.job-evidence.read`（任一；後者限已完成問卷） | 無 | 套件 `jedi_survey/api/routes/question_answer_route.py:30` |
| `/project-survey/answers/<uid>` | PUT | `grc.job.update` | 無 | 套件 `jedi_survey/api/routes/question_answer_route.py:40` |
| `/project-survey/answers/<uid>/patch` | POST | `grc.job.update` | 無 | 套件 `jedi_survey/api/routes/question_answer_route.py:59` |
| `/project-survey/answers/<uid>/checkpoint` | POST | `grc.job.update` | 無 | 套件 `jedi_survey/api/routes/question_answer_route.py:89` |
| `/project-survey/histories/menu/<uid>` | GET | `grc.job.read`｜`grc.job-evidence.read`（任一；後者限已完成問卷） | 無 | 套件 `jedi_survey/api/routes/question_answer_history_route.py:24` |
| `/project-survey/histories` | POST | `grc.job.read`｜`grc.job-evidence.read`（任一；後者限已完成問卷） | 無 | 套件 `jedi_survey/api/routes/question_answer_history_route.py:35` |
| `/project-survey/history/revert` | POST | `grc.job.update` | 無 | 套件 `jedi_survey/api/routes/question_answer_history_route.py:47` |
| `/project-survey/history-details` | POST | `grc.job.read`｜`grc.job-evidence.read`（任一；後者限已完成問卷） | 無 | 套件 `jedi_survey/api/routes/question_answer_history_detail_route.py:20` |
| `/survey-discussions` | POST | `grc.job.read`｜`grc.job-evidence.read`（任一；後者限已完成問卷） | 無 | 套件 `jedi_survey/api/routes/survey_discussion_route.py:25` |
| `/survey-discussion` | POST | `grc.job.update` | 無 | 套件 `jedi_survey/api/routes/survey_discussion_route.py:43` |
| `/survey-discussion/<uid>` | PUT | `grc.job.update` | `survey.update` | 套件 `jedi_survey/api/routes/survey_discussion_route.py:65` |
| `/survey-discussion/<uid>` | DELETE | `grc.job.update` | `survey.delete` | 套件 `jedi_survey/api/routes/survey_discussion_route.py:85` |

### oscal 合規框架、資源庫、SSP（149 支）

| route | HTTP | 新名 | 舊名 | 守門位置 |
|---|---|---|---|---|
| `/oscal-frameworks` | POST | `oscal.framework.read` | 無 | `api/oscal/routes/framework/oscal_framework_route.py:49` |
| `/oscal-frameworks/menu` | GET | 通則 B：呼叫頁權限 `oscal.resource-library.read／create`（附錄 D 裁 5） | 無 | `api/oscal/routes/framework/oscal_framework_route.py:35` |
| `/oscal-framework/<uid>` | GET | `oscal.framework.read` | 無 | `api/oscal/routes/framework/oscal_framework_route.py:68` |
| `/oscal-framework` | POST | `oscal.framework.create` | 無 | `api/oscal/routes/framework/oscal_framework_route.py:78` |
| `/oscal-framework/<uid>` | PUT | `oscal.framework.update` | 無 | `api/oscal/routes/framework/oscal_framework_route.py:92` |
| `/oscal-framework/<uid>` | DELETE | `oscal.framework.delete` | 無 | `api/oscal/routes/framework/oscal_framework_route.py:101` |
| `/oscal-framework-versions` | POST | `oscal.framework.read` | 無 | `api/oscal/routes/framework/oscal_framework_version_route.py:38` |
| `/oscal-framework-version/<uid>` | GET | `oscal.framework.read` | 無 | `api/oscal/routes/framework/oscal_framework_version_route.py:57` |
| `/oscal-framework-version` | POST | `oscal.framework.update` | 無 | `api/oscal/routes/framework/oscal_framework_version_route.py:68` |
| `/oscal-framework-version/<uid>` | PUT | `oscal.framework.update` | 無 | `api/oscal/routes/framework/oscal_framework_version_route.py:82` |
| `/oscal-framework-version/<uid>` | DELETE | `oscal.framework.update` | 無 | `api/oscal/routes/framework/oscal_framework_version_route.py:92` |
| `/oscal-framework-version/download/oscal/<uid>/token` | GET | `oscal.framework.read` | 無 | `api/oscal/routes/framework/oscal_framework_version_route.py:155` |
| `/oscal-framework-version/download/oscal/<uid>` | GET | `oscal.framework.read` | 無 | `api/oscal/routes/framework/oscal_framework_version_route.py:120` |
| `/oscal-framework-version/<uid>/catalog-tree` | GET | `oscal.framework.read` | 無 | `api/oscal/routes/framework/framework_version_edit_route.py:34` |
| `/oscal-catalog-group/<uid>` | PUT | `oscal.framework.update` | 無 | `api/oscal/routes/framework/framework_version_edit_route.py:50` |
| `/oscal-catalog-group/<uid>` | DELETE | `oscal.framework.update` | 無 | `api/oscal/routes/framework/framework_version_edit_route.py:64` |
| `/oscal-catalog-control/<uid>` | PUT | `oscal.framework.update` | 無 | `api/oscal/routes/framework/framework_version_edit_route.py:80` |
| `/oscal-catalog-control/<uid>` | DELETE | `oscal.framework.update` | 無 | `api/oscal/routes/framework/framework_version_edit_route.py:94` |
| `/oscal-catalog-control-assessment/<uid>` | PUT | `oscal.framework.update` | 無 | `api/oscal/routes/framework/framework_version_edit_route.py:110` |
| `/oscal-catalog-control-assessment/<uid>` | DELETE | `oscal.framework.update` | 無 | `api/oscal/routes/framework/framework_version_edit_route.py:124` |
| `/oscal-framework-parse-jobs` | GET | `oscal.framework.read` | 無 | `api/oscal/routes/framework/framework_parse_job_route.py:39` |
| `/oscal-framework-parse-jobs/parse` | POST | `oscal.framework.import` | 無 | `api/oscal/routes/framework/framework_parse_job_route.py:58` |
| `/oscal-framework-parse-jobs/<uid>` | GET | `oscal.framework.import` | 無 | `api/oscal/routes/framework/framework_parse_job_route.py:127` |
| `/oscal-framework-parse-jobs/<uid>` | DELETE | `oscal.framework.import` | 無 | `api/oscal/routes/framework/framework_parse_job_route.py:140` |
| `/oscal-framework-parse-jobs/<uid>/confirm` | POST | `oscal.framework.import` | 無 | `api/oscal/routes/framework/framework_parse_job_route.py:159` |
| `/oscal/resource-libraries/list` | POST | `oscal.resource-library.read` | 無 | `api/oscal/routes/resource_library_route.py:29` |
| `/oscal/resource-libraries` | POST | `oscal.resource-library.create` | `module-frame.create` | `api/oscal/routes/resource_library_route.py:45` |
| `/module-frame/<mf_uid>/template-ssp` | GET | `oscal.resource-library.read` | `module-frame.read` | `api/oscal/routes/module_frame_template_ssp_route.py:33` |
| `/module-frames/menu` | GET | `oscal.resource-library.read`；建專案挑選時 `grc.project.create`（通則 B） | `module-frame.read`、`project.create` | `api/module_frame/routes/module_frame_route.py:28` |
| `/module-frame/<uid>` | GET | `oscal.resource-library.read` | `module-frame.read` | `api/module_frame/routes/module_frame_route.py:49` |
| `/module-frame` | POST | `oscal.resource-library.create` | `module-frame.create` | `api/module_frame/routes/module_frame_route.py:60` |
| `/module-frame/<uid>` | PUT | `oscal.resource-library.update` | `module-frame.update` | `api/module_frame/routes/module_frame_route.py:76` |
| `/module-frame/<uid>` | DELETE | `oscal.resource-library.delete` | `module-frame.delete` | `api/module_frame/routes/module_frame_route.py:88` |
| `/module-frame/clone` | POST | `oscal.resource-library.create` | `module-frame.create` | `api/module_frame/routes/module_frame_route.py:99` |
| `/module-frame/item/<uid>` | GET | `oscal.resource-library.read` | `module-frame.read` | `api/module_frame/routes/module_frame_item_route.py:34` |
| `/module-frame/item` | POST | `oscal.resource-library.update` | `module-frame.create` | `api/module_frame/routes/module_frame_item_route.py:51` |
| `/module-frame/item/<uid>` | PUT | `oscal.resource-library.update` | `module-frame.update` | `api/module_frame/routes/module_frame_item_route.py:67` |
| `/module-frame/item/<uid>` | DELETE | `oscal.resource-library.update` | `module-frame.delete` | `api/module_frame/routes/module_frame_item_route.py:82` |
| `/module-frame/item/xml/<uid>` | PUT | `oscal.resource-library.update` | `module-frame.update` | `api/module_frame/routes/module_frame_item_route.py:101` |
| `/module-frame/import/verify` | POST | `oscal.resource-library.create` | `module-frame.create` | `api/module_frame/routes/module_frame_import_route.py:26` |
| `/module-frame/import` | POST | `oscal.resource-library.create` | `module-frame.create`、`module-frame.update` | `api/module_frame/routes/module_frame_import_route.py:48` |
| `/module-frame/import/yaml` | POST | `oscal.resource-library.create` | `module-frame.create` | `api/module_frame/routes/module_frame_import_route.py:79` |
| `/module-frame/<uid>/system-characteristic` | GET | `oscal.resource-library.read` | `module-frame.read` | `api/module_frame/routes/module_frame_system_characteristic_route.py:31` |
| `/module-frame/<uid>/system-characteristic` | PUT | `oscal.resource-library.update` | `module-frame.update` | `api/module_frame/routes/module_frame_system_characteristic_route.py:48` |
| `/module-frame/<uid>/components` | GET | `oscal.resource-library.read` | `module-frame.read` | `api/module_frame/routes/module_frame_components_route.py:21` |
| `/module-frame/<uid>/components` | POST | `oscal.resource-library.update` | `module-frame.create` | `api/module_frame/routes/module_frame_components_route.py:35` |
| `/module-frame/<uid>/components/<item_uid>` | PUT | `oscal.resource-library.update` | `module-frame.update` | `api/module_frame/routes/module_frame_components_route.py:53` |
| `/module-frame/<uid>/components/<item_uid>` | DELETE | `oscal.resource-library.update` | `module-frame.delete` | `api/module_frame/routes/module_frame_components_route.py:70` |
| `/module-frame/<uid>/inventory` | GET | `oscal.resource-library.read` | `module-frame.read` | `api/module_frame/routes/module_frame_inventory_route.py:21` |
| `/module-frame/<uid>/inventory` | POST | `oscal.resource-library.update` | `module-frame.create` | `api/module_frame/routes/module_frame_inventory_route.py:35` |
| `/module-frame/<uid>/inventory/<item_uid>` | PUT | `oscal.resource-library.update` | `module-frame.update` | `api/module_frame/routes/module_frame_inventory_route.py:53` |
| `/module-frame/<uid>/inventory/<item_uid>` | DELETE | `oscal.resource-library.update` | `module-frame.delete` | `api/module_frame/routes/module_frame_inventory_route.py:70` |
| `/module-frame/<uid>/leveraged` | GET | `oscal.resource-library.read` | `module-frame.read` | `api/module_frame/routes/module_frame_leveraged_route.py:32` |
| `/module-frame/<uid>/leveraged` | POST | `oscal.resource-library.update` | `module-frame.create` | `api/module_frame/routes/module_frame_leveraged_route.py:46` |
| `/module-frame/<uid>/leveraged/<item_uid>` | PUT | `oscal.resource-library.update` | `module-frame.update` | `api/module_frame/routes/module_frame_leveraged_route.py:66` |
| `/module-frame/<uid>/leveraged/<item_uid>` | DELETE | `oscal.resource-library.update` | `module-frame.delete` | `api/module_frame/routes/module_frame_leveraged_route.py:83` |
| `/module-frame/<uid>/parties` | GET | `oscal.resource-library.read` | `module-frame.read` | `api/module_frame/routes/module_frame_party_route.py:29` |
| `/module-frame/<uid>/parties` | POST | `oscal.resource-library.update` | `module-frame.create` | `api/module_frame/routes/module_frame_party_route.py:45` |
| `/module-frame/<uid>/parties/<party_uid>` | PUT | `oscal.resource-library.update` | `module-frame.update` | `api/module_frame/routes/module_frame_party_route.py:67` |
| `/module-frame/<uid>/parties/<party_uid>` | DELETE | `oscal.resource-library.update` | `module-frame.delete` | `api/module_frame/routes/module_frame_party_route.py:86` |
| `/module-frame/<uid>/ssp-resources` | GET | `oscal.resource-library.read` | `module-frame.read` | `api/module_frame/routes/module_frame_ssp_resources_route.py:36` |
| `/module-frame/<uid>/ssp-resources/items` | POST | `oscal.resource-library.update` | `module-frame.create` | `api/module_frame/routes/module_frame_ssp_resources_route.py:54` |
| `/module-frame/<uid>/ssp-resources/items/<item_uid>` | PUT | `oscal.resource-library.update` | `module-frame.update` | `api/module_frame/routes/module_frame_ssp_resources_route.py:74` |
| `/module-frame/<uid>/ssp-resources/items/<item_uid>` | DELETE | `oscal.resource-library.update` | `module-frame.delete` | `api/module_frame/routes/module_frame_ssp_resources_route.py:91` |
| `/module-frame/<uid>/control-defaults` | GET | `oscal.resource-library.read` | `module-frame.read` | `api/module_frame/routes/module_frame_control_default_route.py:53` |
| `/module-frame/<uid>/control-defaults/<ci>` | GET | `oscal.resource-library.read` | `module-frame.read` | `api/module_frame/routes/module_frame_control_default_route.py:79` |
| `/module-frame/<uid>/control-defaults/<ci>` | PUT | `oscal.resource-library.update` | `module-frame.update` | `api/module_frame/routes/module_frame_control_default_route.py:103` |
| `/module-frame/<uid>/control-defaults/<ci>` | DELETE | `oscal.resource-library.update` | `module-frame.delete` | `api/module_frame/routes/module_frame_control_default_route.py:130` |
| `/module-frame/<uid>/objective-defaults` | GET | `oscal.resource-library.read` | `module-frame.read` | `api/module_frame/routes/module_frame_control_objective_default_route.py:53` |
| `/module-frame/<uid>/objective-defaults` | PUT | `oscal.resource-library.update` | `module-frame.update` | `api/module_frame/routes/module_frame_control_objective_default_route.py:77` |
| `/module-frame/<uid>/objective-defaults/<od_uid>` | GET | `oscal.resource-library.read` | `module-frame.read` | `api/module_frame/routes/module_frame_control_objective_default_route.py:113` |
| `/module-frame/<uid>/objective-defaults/<od_uid>` | DELETE | `oscal.resource-library.update` | `module-frame.delete` | `api/module_frame/routes/module_frame_control_objective_default_route.py:138` |
| `/module-frame/<uid>/reference-documents` | GET | `oscal.resource-library.read` | `module-frame.read` | `api/module_frame/routes/module_frame_reference_document_route.py:64` |
| `/module-frame/<uid>/reference-documents` | POST | `oscal.resource-library.update` | `module-frame.create` | `api/module_frame/routes/module_frame_reference_document_route.py:87` |
| `/module-frame/<uid>/reference-documents/<doc_uid>` | PUT | `oscal.resource-library.update` | `module-frame.update` | `api/module_frame/routes/module_frame_reference_document_route.py:120` |
| `/module-frame/<uid>/reference-documents/<doc_uid>` | DELETE | `oscal.resource-library.update` | `module-frame.delete` | `api/module_frame/routes/module_frame_reference_document_route.py:149` |
| `/module-frame/<uid>/control-defaults/<ci>/reference-documents` | POST | `oscal.resource-library.update` | `module-frame.create` | `api/module_frame/routes/module_frame_reference_document_route.py:182` |
| `.../control-defaults/<ci>/reference-documents/<doc_uid>` | DELETE | `oscal.resource-library.update` | `module-frame.delete` | `api/module_frame/routes/module_frame_reference_document_route.py:208` |
| `/module-frame/<uid>/objective-defaults/<od_uid>/reference-documents` | POST | `oscal.resource-library.update` | `module-frame.create` | `api/module_frame/routes/module_frame_reference_document_route.py:244` |
| `.../objective-defaults/<od_uid>/reference-documents/<doc_uid>` | DELETE | `oscal.resource-library.update` | `module-frame.delete` | `api/module_frame/routes/module_frame_reference_document_route.py:270` |
| `/module-frame/<uid>/control-defaults/export` | GET | `oscal.resource-library.read` | `module-frame.read` | `api/module_frame/routes/module_frame_template_import_route.py:69` |
| `/module-frame/<uid>/control-defaults/template/download` | GET | `oscal.resource-library.read` | `module-frame.read` | `api/module_frame/routes/module_frame_template_import_route.py:98` |
| `/module-frame/<uid>/control-defaults/import/template` | POST | `oscal.resource-library.update` | `module-frame.create` | `api/module_frame/routes/module_frame_template_import_route.py:138` |
| `/module-frame/<uid>/control-defaults/import/verify` | POST | `oscal.resource-library.update` | `module-frame.create` | `api/module_frame/routes/module_frame_template_import_route.py:172` |
| `/module-frame/<uid>/control-defaults/import/validate` | POST | `oscal.resource-library.update` | `module-frame.create` | `api/module_frame/routes/module_frame_template_import_route.py:206` |
| `/module-frame/<uid>/control-defaults/import` | POST | `oscal.resource-library.update` | `module-frame.create` | `api/module_frame/routes/module_frame_template_import_route.py:240` |
| `/module-frame/<uid>/ssp-import-template` | GET | `oscal.resource-library.read` | `module-frame.read` | `api/module_frame/routes/ssp_import_template_route.py:57` |
| `/ssp-import-template` | GET | `oscal.resource-library.read` | `module-frame.read` | `api/module_frame/routes/ssp_import_template_route.py:142` |
| `/module-frame/<uid>/ssp-export` | GET | `oscal.resource-library.read` | `module-frame.read` | `api/module_frame/routes/mf_ssp_export_route.py:54` |
| `/ssp/<ssp_uid>/system-characteristic` | GET | `oscal.ssp.read` | 無 | `api/oscal/routes/ssp/ssp_system_characteristic_route.py:26` |
| `/ssp/<ssp_uid>/system-characteristic` | PUT | `oscal.ssp.update` | 無 | `api/oscal/routes/ssp/ssp_system_characteristic_route.py:41` |
| `/ssp/<ssp_uid>/components` | GET | `oscal.ssp.read` | 無 | `api/oscal/routes/ssp/ssp_components_route.py:30` |
| `/ssp/<ssp_uid>/components` | POST | `oscal.ssp.update` | 無 | `api/oscal/routes/ssp/ssp_components_route.py:43` |
| `/ssp/<ssp_uid>/components/<item_uid>` | PUT | `oscal.ssp.update` | 無 | `api/oscal/routes/ssp/ssp_components_route.py:61` |
| `/ssp/<ssp_uid>/components/<item_uid>` | DELETE | `oscal.ssp.update` | 無 | `api/oscal/routes/ssp/ssp_components_route.py:76` |
| `/ssp/<ssp_uid>/inventory-items` | GET | `oscal.ssp.read` | 無 | `api/oscal/routes/ssp/ssp_inventory_items_route.py:29` |
| `/ssp/<ssp_uid>/inventory-items` | POST | `oscal.ssp.update` | 無 | `api/oscal/routes/ssp/ssp_inventory_items_route.py:42` |
| `/ssp/<ssp_uid>/inventory-items/<item_uid>` | PUT | `oscal.ssp.update` | 無 | `api/oscal/routes/ssp/ssp_inventory_items_route.py:60` |
| `/ssp/<ssp_uid>/inventory-items/<item_uid>` | DELETE | `oscal.ssp.update` | 無 | `api/oscal/routes/ssp/ssp_inventory_items_route.py:75` |
| `/ssp/<ssp_uid>/leveraged` | GET | `oscal.ssp.read` | 無 | `api/oscal/routes/ssp/ssp_leveraged_route.py:23` |
| `/ssp/<ssp_uid>/leveraged` | POST | `oscal.ssp.update` | 無 | `api/oscal/routes/ssp/ssp_leveraged_route.py:36` |
| `/ssp/<ssp_uid>/leveraged/<item_uid>` | PUT | `oscal.ssp.update` | 無 | `api/oscal/routes/ssp/ssp_leveraged_route.py:54` |
| `/ssp/<ssp_uid>/leveraged/<item_uid>` | DELETE | `oscal.ssp.update` | 無 | `api/oscal/routes/ssp/ssp_leveraged_route.py:69` |
| `/ssp/<ssp_uid>/parties` | GET | `oscal.ssp.read` | 無 | `api/oscal/routes/ssp/ssp_party_route.py:24` |
| `/ssp/<ssp_uid>/parties` | POST | `oscal.ssp.update` | 無 | `api/oscal/routes/ssp/ssp_party_route.py:39` |
| `/ssp/<ssp_uid>/parties/<party_uid>` | PUT | `oscal.ssp.update` | 無 | `api/oscal/routes/ssp/ssp_party_route.py:59` |
| `/ssp/<ssp_uid>/parties/<party_uid>` | DELETE | `oscal.ssp.update` | 無 | `api/oscal/routes/ssp/ssp_party_route.py:75` |
| `/ssp/<ssp_uid>/ssp-resources` | GET | `oscal.ssp.read` | 無 | `api/oscal/routes/ssp/ssp_resources_route.py:29` |
| `/ssp/<ssp_uid>/ssp-resources/items` | POST | `oscal.ssp.update` | 無 | `api/oscal/routes/ssp/ssp_resources_route.py:46` |
| `/ssp/<ssp_uid>/ssp-resources/items/<item_uid>` | PUT | `oscal.ssp.update` | 無 | `api/oscal/routes/ssp/ssp_resources_route.py:64` |
| `/ssp/<ssp_uid>/ssp-resources/items/<item_uid>` | DELETE | `oscal.ssp.update` | 無 | `api/oscal/routes/ssp/ssp_resources_route.py:79` |
| `/ssp/<ssp_uid>/control-tree` | GET | `oscal.ssp.read` | 無 | `api/oscal/routes/ssp/ssp_control_implementation_route.py:139` |
| `/ssp/<ssp_uid>/control-implementations` | GET | `oscal.ssp.read` | 無 | `api/oscal/routes/ssp/ssp_control_implementation_route.py:109` |
| `/ssp/<ssp_uid>/control-implementation/<ci>` | GET | `oscal.ssp.read` | 無 | `api/oscal/routes/ssp/ssp_control_implementation_route.py:50` |
| `/ssp/<ssp_uid>/control-implementation/<ci>` | POST | `oscal.ssp.update` | 無 | `api/oscal/routes/ssp/ssp_control_implementation_route.py:67` |
| `/ssp/<ssp_uid>/control-implementation/<ci>` | PUT | `oscal.ssp.update` | 無 | `api/oscal/routes/ssp/ssp_control_implementation_route.py:87` |
| `/ssp/<ssp_uid>/control-implementation/<ci>/objective/<si>` | POST | `oscal.ssp.update` | 無 | `api/oscal/routes/ssp/ssp_control_implementation_route.py:156` |
| `/ssp/<ssp_uid>/control-implementation/<ci>/objective/<si>` | PUT | `oscal.ssp.update` | 無 | `api/oscal/routes/ssp/ssp_control_implementation_route.py:177` |
| `/ssp/<ssp_uid>.../objective/<si>/document/<file_id>` | DELETE | `oscal.ssp.update` | 無 | `api/oscal/routes/ssp/ssp_control_implementation_route.py:199` |
| `/ssp/<ssp_uid>/control-implementation/<ci>/reference-documents` | POST | `oscal.ssp.update` | 無 | `api/oscal/routes/ssp/ssp_control_implementation_route.py:222` |
| `/ssp/<ssp_uid>/control-implementation/<ci>/reference-document/<doc_uid>` | DELETE | `oscal.ssp.update` | 無 | `api/oscal/routes/ssp/ssp_control_implementation_route.py:243` |
| `/ssp/<ssp_uid>.../objective/<si>/reference-documents` | GET | `oscal.ssp.read` | 無 | `api/oscal/routes/ssp/ssp_control_implementation_route.py:261` |
| `/ssp/<ssp_uid>.../objective/<si>/reference-documents` | POST | `oscal.ssp.update` | 無 | `api/oscal/routes/ssp/ssp_control_implementation_route.py:278` |
| `/ssp/<ssp_uid>.../objective/<si>/reference-document/<doc_uid>` | DELETE | `oscal.ssp.update` | 無 | `api/oscal/routes/ssp/ssp_control_implementation_route.py:300` |
| `/ssp/<ssp_uid>/document-pool` | GET | `oscal.ssp.read` | 無 | `api/oscal/routes/ssp/ssp_document_pool_route.py:43` |
| `/ssp/<ssp_uid>/document-pool` | POST | `oscal.ssp.update` | 無 | `api/oscal/routes/ssp/ssp_document_pool_route.py:55` |
| `/ssp/<ssp_uid>/document-pool/<doc_uid>` | DELETE | `oscal.ssp.update` | 無 | `api/oscal/routes/ssp/ssp_document_pool_route.py:73` |
| `/ssp/<ssp_uid>/control-implementation/<ci>/document-mappings` | GET | `oscal.ssp.read` | 無 | `api/oscal/routes/ssp/ssp_document_pool_route.py:90` |
| `/ssp/<ssp_uid>/control-implementation/<ci>/document-mappings` | POST | `oscal.ssp.update` | 無 | `api/oscal/routes/ssp/ssp_document_pool_route.py:103` |
| `/ssp/<ssp_uid>.../document-mapping/<doc_uid>` | DELETE | `oscal.ssp.update` | 無 | `api/oscal/routes/ssp/ssp_document_pool_route.py:122` |
| `/ssp/<ssp_uid>.../objective/<si>/document-mappings` | GET | `oscal.ssp.read` | 無 | `api/oscal/routes/ssp/ssp_document_pool_route.py:140` |
| `/ssp/<ssp_uid>.../objective/<si>/document-mappings` | POST | `oscal.ssp.update` | 無 | `api/oscal/routes/ssp/ssp_document_pool_route.py:154` |
| `/ssp/<ssp_uid>.../objective/<si>/document-mapping/<doc_uid>` | DELETE | `oscal.ssp.update` | 無 | `api/oscal/routes/ssp/ssp_document_pool_route.py:174` |
| `/ssp/<ssp_uid>/control-implementations/export` | GET | `oscal.ssp.export` | 無 | `api/oscal/routes/ssp/ssp_control_impl_import_route.py:34` |
| `/ssp/<ssp_uid>/control-implementations/import` | POST | `oscal.ssp.import` | 無 | `api/oscal/routes/ssp/ssp_control_impl_import_route.py:57` |
| `/ssp/<ssp_uid>/control-implementations/import/validate` | POST | `oscal.ssp.import` | 無 | `api/oscal/routes/ssp/ssp_control_impl_import_route.py:80` |
| `/ssp/<ssp_uid>/control-implementations/import/confirm` | POST | `oscal.ssp.import` | 無 | `api/oscal/routes/ssp/ssp_control_impl_import_route.py:101` |
| `/ssp/<ssp_uid>/excel-import/upload` | POST | `oscal.ssp.import` | 無 | `api/oscal/routes/ssp/ssp_scoped_excel_import_route.py:42` |
| `/ssp/<ssp_uid>/excel-template` | GET | `oscal.ssp.export` | `module-frame.read` | `api/module_frame/routes/ssp_import_template_route.py:100` |
| `/ssp/<ssp_uid>/export` | GET | `oscal.ssp.export` | 無 | `api/oscal/routes/ssp/ssp_export_route.py:55` |
| `/ssp-excel-imports/parse` | POST | 依上傳目標（通則 C）：SSP→`oscal.ssp.import`；既有資源庫→`oscal.resource-library.update`；用檔案新建→`oscal.resource-library.create` | `module-frame.create`、`module-frame.update` | `api/oscal/routes/ssp/ssp_excel_import_route.py:36` |
| `/ssp-excel-import/<parse_uid>` | GET | 依上傳目標（通則 C）：SSP→`oscal.ssp.import`；既有資源庫→`oscal.resource-library.update`；用檔案新建→`oscal.resource-library.create` | 無 | `api/oscal/routes/ssp/ssp_excel_import_route.py:71` |
| `/ssp-excel-import/<parse_uid>` | DELETE | 依上傳目標（通則 C）：SSP→`oscal.ssp.import`；既有資源庫→`oscal.resource-library.update`；用檔案新建→`oscal.resource-library.create` | 無 | `api/oscal/routes/ssp/ssp_excel_import_route.py:85` |
| `/ssp-excel-import/<parse_uid>/confirm` | POST | 依上傳目標（通則 C）：SSP→`oscal.ssp.import`；既有資源庫→`oscal.resource-library.update`；用檔案新建→`oscal.resource-library.create` | `module-frame.update` | `api/oscal/routes/ssp/ssp_excel_import_route.py:103` |
| `/ssp-docx-imports/parse` | POST | 依上傳目標（通則 C）：SSP→`oscal.ssp.import`；既有資源庫→`oscal.resource-library.update`；用檔案新建→`oscal.resource-library.create` | `module-frame.create`、`module-frame.update` | `api/oscal/routes/ssp/ssp_docx_import_route.py:33` |
| `/ssp-docx-import/<parse_uid>` | GET | 依上傳目標（通則 C）：SSP→`oscal.ssp.import`；既有資源庫→`oscal.resource-library.update`；用檔案新建→`oscal.resource-library.create` | 無 | `api/oscal/routes/ssp/ssp_docx_import_route.py:64` |
| `/ssp-docx-import/<parse_uid>` | DELETE | 依上傳目標（通則 C）：SSP→`oscal.ssp.import`；既有資源庫→`oscal.resource-library.update`；用檔案新建→`oscal.resource-library.create` | 無 | `api/oscal/routes/ssp/ssp_docx_import_route.py:77` |
| `/ssp-docx-import/<parse_uid>/confirm` | POST | 依上傳目標（通則 C）：SSP→`oscal.ssp.import`；既有資源庫→`oscal.resource-library.update`；用檔案新建→`oscal.resource-library.create` | `module-frame.create`、`module-frame.update` | `api/oscal/routes/ssp/ssp_docx_import_route.py:96` |
| `/flow-engine/process-definition/<uid>` | GET | 依流程圖歸屬（通則 C）：專案→`grc.project.read`＋專案成員；資源庫→`oscal.resource-library.read` | 無 | `api/flow_engine/routes/flow_engine_route.py:27` |

### flow 流程範本（10 支）

| route | HTTP | 新名 | 舊名 | 守門位置 |
|---|---|---|---|---|
| `/flow-engine/flow-templates` | GET | `flow.template.read`；建專案挑選時 `grc.project.create`（通則 B） | `flow_template.read`、`project.create` | `api/flow_engine/routes/flow_template_route.py:39` |
| `/flow-engine/flow-templates` | POST | `flow.template.create` | `flow_template.create` | `api/flow_engine/routes/flow_template_route.py:55` |
| `/flow-engine/flow-templates/<uid>` | GET | `flow.template.read`；建專案預覽時 `grc.project.create`（通則 B） | `flow_template.read`、`project.create` | `api/flow_engine/routes/flow_template_route.py:69` |
| `/flow-engine/flow-templates/<uid>` | PUT | `flow.template.update` | `flow_template.update` | `api/flow_engine/routes/flow_template_route.py:77` |
| `/flow-engine/flow-templates/<uid>` | DELETE | `flow.template.delete` | `flow_template.delete` | `api/flow_engine/routes/flow_template_route.py:87` |
| `/flow-engine/flow-templates/<uid>/duplicate` | POST | `flow.template.create` | `flow_template.create` | `api/flow_engine/routes/flow_template_route.py:99` |
| `/flow-engine/flow-templates/<uid>/publish` | PUT | `flow.template.publish` | `flow_template.update` | `api/flow_engine/routes/flow_template_route.py:117` |
| `/flow-engine/flow-templates/<uid>/unpublish` | PUT | `flow.template.publish` | `flow_template.update` | `api/flow_engine/routes/flow_template_route.py:130` |
| `/flow-engine/flow-templates/validate` | POST | `flow.template.update` | `flow_template.update` | `api/flow_engine/routes/flow_template_route.py:147` |
| `/flow-engine/stage-objects` | GET | `flow.template.read`；建專案預覽時 `grc.project.create`（通則 B） | 無 | `api/flow_engine/routes/stage_object_route.py:16` |

### detection 檢測工具（66 支）

| route | HTTP | 新名 | 舊名 | 守門位置 |
|---|---|---|---|---|
| `/remote-agents` | GET | 跟呼叫頁權限（通則 B）：工具設定看 `detection.plugin.read`，儲存設定看 `system.storage-config.read`，任務設置看 `grc.job.read`（管理頁列表走 `/remote-agents/all`） | `remote-agent-manage.create` | 套件 `jedi_remote_agent/api/routes/remote_agent_route.py:58` |
| `/remote-agents` | POST | `detection.remote-agent.create` | `remote-agent-manage.create` | 套件 `jedi_remote_agent/api/routes/remote_agent_route.py:66` |
| `/remote-agents/all` | GET | `detection.remote-agent.read` | `remote-agent-manage.create` | 套件 `jedi_remote_agent/api/routes/remote_agent_route.py:90` |
| `/remote-agents/health-check` | POST | `detection.remote-agent.read` | `remote-agent-manage.create` | 套件 `jedi_remote_agent/api/routes/remote_agent_route.py:75` |
| `/remote-agents/<uid>/reconcile` | POST | `detection.remote-agent.update` | `remote-agent-manage.create` | 套件 `jedi_remote_agent/api/routes/remote_agent_route.py:82` |
| `/remote-agents/<uid>` | GET | `detection.remote-agent.read` | `remote-agent-manage.create` | 套件 `jedi_remote_agent/api/routes/remote_agent_route.py:98` |
| `/remote-agents/<uid>` | PUT | `detection.remote-agent.update` | `remote-agent-manage.create` | 套件 `jedi_remote_agent/api/routes/remote_agent_route.py:105` |
| `/remote-agents/<uid>` | DELETE | `detection.remote-agent.delete` | `remote-agent-manage.create` | 套件 `jedi_remote_agent/api/routes/remote_agent_route.py:112` |
| `/remote-agents/<uid>/revoke` | POST | `detection.remote-agent.update` | `remote-agent-manage.create` | 套件 `jedi_remote_agent/api/routes/remote_agent_route.py:119` |
| `/remote-agents/<uid>/unrevoke` | POST | `detection.remote-agent.update` | `remote-agent-manage.create` | 套件 `jedi_remote_agent/api/routes/remote_agent_route.py:127` |
| `/remote-agents/<uid>/approve` | POST | `detection.remote-agent.update` | `remote-agent-manage.create` | 套件 `jedi_remote_agent/api/routes/remote_agent_route.py:135` |
| `/remote-agents/<uid>/rebind` | POST | `detection.remote-agent.update` | `remote-agent-manage.create` | 套件 `jedi_remote_agent/api/routes/remote_agent_route.py:144` |
| `/agents/enroll-token` | GET | `detection.remote-agent.read` | `remote-agent-manage.create` | 套件 `jedi_remote_agent/api/routes/remote_agent_route.py:154` |
| `/agents/enroll-token` | POST | `detection.remote-agent.create` | `remote-agent-manage.create` | 套件 `jedi_remote_agent/api/routes/remote_agent_route.py:160` |
| `/agents/enroll-token/revoke` | POST | `detection.remote-agent.delete` | `remote-agent-manage.create` | 套件 `jedi_remote_agent/api/routes/remote_agent_route.py:168` |
| `/agents/register` | POST | 豁免（附錄 C） | 無 | 套件 `jedi_remote_agent/api/routes/remote_agent_route.py:177` |
| `/agents/heartbeat` | POST | 豁免（附錄 C） | 無 | 套件 `jedi_remote_agent/api/routes/remote_agent_route.py:187` |
| `/agents/tasks/<uid>/ack` | POST | 豁免（附錄 C） | 無 | 套件 `jedi_remote_agent/api/routes/remote_agent_route.py:194` |
| `/agents/tasks/<uid>/result` | POST | 豁免（附錄 C） | 無 | 套件 `jedi_remote_agent/api/routes/remote_agent_route.py:200` |
| `/agents/files/<uid>` | GET | 豁免（附錄 C） | 無 | `api/remote_agent/routes/agent_file_route.py:40` |
| `/detection-tools` | GET | `detection.plugin.read` | 無 | 套件 `jedi_detection/api/routes/detection_tool_route.py:30` |
| `/detection-tools/<uid>` | GET | `detection.plugin.read` | 無 | 套件 `jedi_detection/api/routes/detection_tool_route.py:43` |
| `/detection-tools/configs` | GET | 管理頁 `detection.plugin.read`；任務設置挑選時看 `grc.job.read`（通則 B） | 無 | 套件 `jedi_detection/api/routes/detection_tool_route.py:56` |
| `/detection-tools/configs` | POST | `detection.plugin.create` | `plugin.update` | 套件 `jedi_detection/api/routes/detection_tool_route.py:70` |
| `/detection-tools/configs/<uid>` | PUT | `detection.plugin.update` | `plugin.update` | 套件 `jedi_detection/api/routes/detection_tool_route.py:91` |
| `/detection-tools/configs/<uid>/reset` | POST | `detection.plugin.update` | `plugin.update` | 套件 `jedi_detection/api/routes/detection_tool_route.py:108` |
| `/detection-tools/configs/<uid>/test-connection` | POST | `detection.plugin.update` | `plugin.update` | 套件 `jedi_detection/api/routes/detection_tool_route.py:132` |
| `/detection-tools/configs/<uid>/referencing-tasks-count` | GET | `detection.plugin.read` | 無 | 套件 `jedi_detection/api/routes/detection_tool_route.py:152` |
| `/detection-tools/<uid>/param-schema` | GET | 跟呼叫頁權限（通則 B）：任務設置看 `grc.job.read` | 無 | 套件 `jedi_detection/api/routes/detection_tool_route.py:164` |
| `/detection-tools/jobs/<job_uid>/execute` | POST | `grc.job.update` | 無 | 套件 `jedi_detection/api/routes/detection_tool_route.py:186` |
| `/detection-tools/jobs/<job_uid>/cancel` | POST | `grc.job.update` | 無 | 套件 `jedi_detection/api/routes/detection_tool_route.py:218` |
| `/detection-tools/jobs/<job_uid>/executions` | GET | `grc.job.read`｜`grc.job-evidence.read`（任一） | 無 | 套件 `jedi_detection/api/routes/detection_tool_route.py:354` |
| `/detection-tools/execution-groups/<g>/assignments/<a>/rerun` | POST | `grc.job.update` | 無 | 套件 `jedi_detection/api/routes/detection_tool_route.py:237` |
| `/detection-tools/execution-groups/<g>/assignments/<a>/cancel` | POST | `grc.job.update` | 無 | 套件 `jedi_detection/api/routes/detection_tool_route.py:258` |
| `/detection-tools/execution-groups/<g>/assignments/<a>/start-now` | POST | `grc.job.update` | 無 | 套件 `jedi_detection/api/routes/detection_tool_route.py:279` |
| `/detection-tools/execution-groups/<g>/cancel` | POST | `grc.job.update` | 無 | 套件 `jedi_detection/api/routes/detection_tool_route.py:299` |
| `/detection-tools/execution-groups/<g>` | DELETE | `grc.job.update` | 無 | 套件 `jedi_detection/api/routes/detection_tool_route.py:335` |
| `/detection-tools/executions/<uid>` | DELETE | `grc.job.update` | 無 | 套件 `jedi_detection/api/routes/detection_tool_route.py:317` |
| `/detection-tool-profiles/list` | POST | `detection.profile.read` | `detection-profile.read` | 套件 `jedi_detection/api/routes/detection_profile_route.py:141` |
| `/detection-tool-profiles/menu` | GET | 跟呼叫頁權限（通則 B）：任務設置看 `grc.job.read` | `detection-profile.read` | 套件 `jedi_detection/api/routes/detection_profile_route.py:170` |
| `/detection-tool-profiles` | POST | `detection.profile.create` | `detection-profile.create` | 套件 `jedi_detection/api/routes/detection_profile_route.py:191` |
| `/detection-tool-profiles/<uid>` | GET | `detection.profile.read` | `detection-profile.read` | 套件 `jedi_detection/api/routes/detection_profile_route.py:219` |
| `/detection-tool-profiles/<uid>` | PUT | `detection.profile.update` | `detection-profile.update` | 套件 `jedi_detection/api/routes/detection_profile_route.py:238` |
| `/detection-tool-profiles/<uid>` | DELETE | `detection.profile.delete` | `detection-profile.delete` | 套件 `jedi_detection/api/routes/detection_profile_route.py:266` |
| `/detection-tool-profiles/<uid>/versions` | GET | `detection.profile.read` | `detection-profile.read` | 套件 `jedi_detection/api/routes/detection_profile_route.py:283` |
| `/detection-tool-profiles/<uid>/referencing-usage` | GET | `detection.profile.read` | `detection-profile.read` | 套件 `jedi_detection/api/routes/detection_profile_route.py:313` |
| `/detection-tool-profiles/<uid>/new-version` | POST | `detection.profile.create` | `detection-profile.create` | 套件 `jedi_detection/api/routes/detection_profile_route.py:421` |
| `/detection-tool-profiles/<uid>/fork` | POST | `detection.profile.create` | `detection-profile.create` | 套件 `jedi_detection/api/routes/detection_profile_route.py:450` |
| `/detection-tool-profiles/<uid>/copy-to-tool` | POST | `detection.profile.create` | `detection-profile.create` | 套件 `jedi_detection/api/routes/detection_profile_route.py:471` |
| `/detection-tool-profiles/<uid>/deactivate` | PUT | `detection.profile.delete` | `detection-profile.delete` | 套件 `jedi_detection/api/routes/detection_profile_route.py:495` |
| `/detection-tool-profile-versions/<uid>/controls` | GET | `detection.profile.read` | `detection-profile.read` | 套件 `jedi_detection/api/routes/detection_profile_route.py:519` |
| `/detection-tool-profile-versions/<uid>/extraction` | GET | `detection.profile.read` | `detection-profile.read` | 套件 `jedi_detection/api/routes/detection_profile_route.py:540` |
| `/detection-tool-profile-versions/<uid>/extraction` | POST | `detection.profile.create` | `detection-profile.create` | 套件 `jedi_detection/api/routes/detection_profile_route.py:555` |
| `/detection-tool-profile-versions/<uid>/referencing-usage` | GET | `detection.profile.read` | `detection-profile.read` | 套件 `jedi_detection/api/routes/detection_profile_route.py:339` |
| `/detection-tool-profile-versions/<uid>/source` | PATCH | `detection.profile.create` | `detection-profile.create` | 套件 `jedi_detection/api/routes/detection_profile_route.py:370` |
| `/detection-tool-profile-versions/<uid>` | DELETE | `detection.profile.delete` | `detection-profile.delete` | 套件 `jedi_detection/api/routes/detection_profile_route.py:403` |
| `/detection-profile-taxonomies` | GET | `detection.profile.read` | 無 | 套件 `jedi_detection/api/routes/detection_profile_taxonomy_route.py:62` |
| `/detection-profile-taxonomies` | POST | `detection.profile.update`＋平台管理員兩道（附錄 D 裁 2） | 無 | 套件 `jedi_detection/api/routes/detection_profile_taxonomy_route.py:84` |
| `/detection-profile-taxonomies/<uid>` | PUT | `detection.profile.update`＋平台管理員兩道（附錄 D 裁 2） | 無 | 套件 `jedi_detection/api/routes/detection_profile_taxonomy_route.py:111` |
| `/detection-profile-taxonomies/<uid>` | DELETE | `detection.profile.update`＋平台管理員兩道（附錄 D 裁 2） | 無 | 套件 `jedi_detection/api/routes/detection_profile_taxonomy_route.py:135` |
| `/detection-profile-taxonomies/<uid>/referencing-profiles-count` | GET | `detection.profile.read` | 無 | 套件 `jedi_detection/api/routes/detection_profile_taxonomy_route.py:150` |
| `/scan-zones` | GET | `detection.scan-zone.read` | `scan-zone.read` | 套件 `jedi_detection/api/routes/scan_zone_route.py:38` |
| `/scan-zones` | POST | `detection.scan-zone.create` | `scan-zone.update` | 套件 `jedi_detection/api/routes/scan_zone_route.py:47` |
| `/scan-zones/<uid>` | PUT | `detection.scan-zone.update` | `scan-zone.update` | 套件 `jedi_detection/api/routes/scan_zone_route.py:60` |
| `/scan-zones/<uid>` | DELETE | `detection.scan-zone.delete` | `scan-zone.update` | 套件 `jedi_detection/api/routes/scan_zone_route.py:70` |
| `/scan-zones/suggest-from-agents` | POST | `detection.scan-zone.create` | `scan-zone.update` | 套件 `jedi_detection/api/routes/scan_zone_route.py:81` |

### evidence 證據（34 支）

| route | HTTP | 新名 | 舊名 | 守門位置 |
|---|---|---|---|---|
| `/integrations/google-drive` | GET | `evidence.cloud-integration.read` | 無 | `api/cloud_integration/routes/google_drive_integration_route.py:56` |
| `/integrations/google-drive` | DELETE | `evidence.cloud-integration.delete` | `cloud_integration.delete` | `api/cloud_integration/routes/google_drive_integration_route.py:71` |
| `/integrations/google-drive/auth-url` | POST | `evidence.cloud-integration.create` | `cloud_integration.create` | `api/cloud_integration/routes/google_drive_integration_route.py:90` |
| `/integrations/google-drive/callback` | GET | 豁免（附錄 C） | 無 | `api/cloud_integration/routes/google_drive_integration_route.py:110` |
| `/integrations/google-drive/verify-credentials` | POST | `platform.drive-app-credential.read` | `storage-config.read` | `api/cloud_integration/routes/drive_app_credential_verify_route.py:32` |
| `/integrations/google-drive/sync-jobs` | GET | `evidence.cloud-integration.read` | `cloud_integration.read` | `api/cloud_integration/routes/google_drive_sync_route.py:43` |
| `/integrations/google-drive/sync-jobs/<uid>/retry` | POST | `evidence.cloud-integration.update` | `cloud_integration.update` | `api/cloud_integration/routes/google_drive_sync_route.py:90` |
| `/integrations/google-drive/projects/<p>/init-folders` | POST | `grc.project.update` | 無 | `api/cloud_integration/routes/google_drive_sync_route.py:111` |
| `/integrations/google-drive/projects/<p>/verify-and-repair-folders` | POST | `grc.project.update` | 無 | `api/cloud_integration/routes/google_drive_sync_route.py:143` |
| `/integrations/google-drive/projects/<p>/folders` | GET | `grc.project.read`（通則 A） | `cloud_integration.read` | `api/cloud_integration/routes/google_drive_sync_route.py:177` |
| `/integrations/google-drive/tenant/rebuild-all` | POST | `evidence.cloud-integration.update` | `cloud_integration.update` | `api/cloud_integration/routes/google_drive_sync_route.py:209` |
| `/integrations/google-drive/webhook/register` | POST | `evidence.cloud-integration.update` | `cloud_integration.update` | `api/cloud_integration/routes/google_drive_sync_route.py:239` |
| `/webhooks/google-drive/<tenant_id>` | POST | 豁免（附錄 C） | 無 | `api/cloud_integration/routes/google_drive_webhook_route.py:39` |
| `/evidence-batches` | POST | `evidence.classification.create` | 無 | 套件 `jedi_evidence_classification/api/routes/evidence_batch_route.py:51` |
| `/evidence-batches` | GET | `evidence.classification.read` | 無 | 套件 `jedi_evidence_classification/api/routes/evidence_batch_route.py:75` |
| `/evidence-batches/<b>` | GET | `evidence.classification.read` | 無 | 套件 `jedi_evidence_classification/api/routes/evidence_batch_route.py:101` |
| `/evidence-batches/<b>` | DELETE | `evidence.classification.delete` | 無 | 套件 `jedi_evidence_classification/api/routes/evidence_batch_route.py:115` |
| `/evidence-batches/<b>/files` | POST | `evidence.classification.update` | 無 | 套件 `jedi_evidence_classification/api/routes/evidence_batch_route.py:122` |
| `/evidence-batches/<b>/files/<f>` | DELETE | `evidence.classification.update` | 無 | 套件 `jedi_evidence_classification/api/routes/evidence_batch_route.py:137` |
| `/evidence-batches/<b>/seal` | POST | `evidence.classification.update` | 無 | 套件 `jedi_evidence_classification/api/routes/evidence_batch_route.py:145` |
| `/evidence-batches/<b>/classify` | POST | `evidence.classification.execute`（只記錄） | 無 | 套件 `jedi_evidence_classification/api/routes/evidence_batch_route.py:153` |
| `/evidence-batches/<b>/archive` | POST | `evidence.classification.update` | 無 | 套件 `jedi_evidence_classification/api/routes/evidence_batch_route.py:176` |
| `/evidence-batches/<b>/purge` | POST | `evidence.classification.delete` | 無 | 套件 `jedi_evidence_classification/api/routes/evidence_batch_route.py:183` |
| `/classification-run/<r>/state` | GET | `evidence.classification.read` | 無 | 套件 `jedi_evidence_classification/api/routes/evidence_batch_route.py:197` |
| `/classification-run/<r>/state` | PUT | `evidence.classification.update` | 無 | 套件 `jedi_evidence_classification/api/routes/evidence_batch_route.py:202` |
| `/classification-run/<r>/file/<f>/preview` | GET | `evidence.classification.read` | 無 | 套件 `jedi_evidence_classification/api/routes/evidence_batch_route.py:212` |
| `/classification-run/<r>/report/validation` | GET | `evidence.classification.read` | 無 | 套件 `jedi_evidence_classification/api/routes/evidence_batch_route.py:230` |
| `/classification-run/<r>/report/adjudication` | GET | `evidence.classification.read` | 無 | 套件 `jedi_evidence_classification/api/routes/evidence_batch_route.py:236` |
| `/classification-ground-truth` | POST | `evidence.classification.update` | 無 | 套件 `jedi_evidence_classification/api/routes/evidence_classification_route.py:19` |
| `/classification-profiles` | GET | `evidence.classification-profile.read` | `storage-config.update` | 套件 `jedi_evidence_classification/api/routes/classification_profile_route.py:51` |
| `/classification-profiles` | POST | `evidence.classification-profile.create` | `storage-config.update` | 套件 `jedi_evidence_classification/api/routes/classification_profile_route.py:65` |
| `/classification-profiles/<p>` | PUT | `evidence.classification-profile.update` | `storage-config.update` | 套件 `jedi_evidence_classification/api/routes/classification_profile_route.py:72` |
| `/classification-profiles/<p>` | DELETE | `evidence.classification-profile.delete` | `storage-config.update` | 套件 `jedi_evidence_classification/api/routes/classification_profile_route.py:77` |
| `/classification/available-models` | GET | 跟呼叫頁權限（通則 B）：自動分類頁看 `evidence.classification.read` | 無 | 套件 `jedi_evidence_classification/api/routes/classification_profile_route.py:84` |

### survey 問卷設計（29 支）

| route | HTTP | 新名 | 舊名 | 守門位置 |
|---|---|---|---|---|
| `/survey-folders/menu` | GET | `survey.survey.read` | 無 | 套件 `jedi_survey/api/routes/survey_folder_route.py:33` |
| `/survey-folders` | POST | `survey.survey.read` | 無 | 套件 `jedi_survey/api/routes/survey_folder_route.py:45` |
| `/survey-folder/<uid>` | GET | `survey.survey.read` | 無 | 套件 `jedi_survey/api/routes/survey_folder_route.py:60` |
| `/survey-folder` | POST | `survey.survey.create` | `survey.create` | 套件 `jedi_survey/api/routes/survey_folder_route.py:73` |
| `/survey-folder/<uid>` | PUT | `survey.survey.update` | `survey.update` | 套件 `jedi_survey/api/routes/survey_folder_route.py:90` |
| `/survey-folder/<uid>` | DELETE | `survey.survey.delete` | `survey.delete` | 套件 `jedi_survey/api/routes/survey_folder_route.py:109` |
| `/surveys/menu` | GET | 跟呼叫頁權限（通則 B）：任務設置看 `grc.job.read` | 無 | 套件 `jedi_survey/api/routes/survey_route.py:34` |
| `/surveys` | POST | `survey.survey.read` | 無 | 套件 `jedi_survey/api/routes/survey_route.py:59` |
| `/survey/<uid>` | GET | 無 task_survey_uid：`survey.survey.read`；帶 task_survey_uid：`grc.job.read`｜`grc.job-evidence.read`（結案）＋專案參與者，通則 C | 無 | 套件 `jedi_survey/api/routes/survey_route.py:88` |
| `/survey` | POST | `survey.survey.create` | `survey.create` | 套件 `jedi_survey/api/routes/survey_route.py:105` |
| `/survey/<uid>` | PUT | `survey.survey.update` | `survey.update` | 套件 `jedi_survey/api/routes/survey_route.py:133` |
| `/survey/<uid>` | DELETE | `survey.survey.delete` | `survey.delete` | 套件 `jedi_survey/api/routes/survey_route.py:156` |
| `/survey/excel-import` | POST | `survey.survey.import` | `survey.create` | 套件 `jedi_survey/api/routes/survey_route.py:175` |
| `/survey/import-template/token` | GET | `survey.survey.import` | 無 | 套件 `jedi_survey/api/routes/survey_route.py:201` |
| `/survey/import-template` | GET | 豁免（附錄 C） | 無 | 套件 `jedi_survey/api/routes/survey_route.py:209` |
| `/survey/move` | POST | `survey.survey.update` | `survey.create` | 套件 `jedi_survey/api/routes/survey_route.py:221` |
| `/survey/<uid>/clone` | POST | `survey.survey.create` | `survey.create` | 套件 `jedi_survey/api/routes/survey_route.py:242` |
| `/survey/<uid>/release` | PUT | `survey.survey.publish` | `survey.update` | 套件 `jedi_survey/api/routes/survey_route.py:265` |
| `/survey/<uid>/release` | DELETE | `survey.survey.publish` | `survey.delete` | 套件 `jedi_survey/api/routes/survey_route.py:279` |
| `/survey-question` | POST | `survey.survey.update` | `survey.create` | 套件 `jedi_survey/api/routes/survey_question_route.py:33` |
| `/survey-question/<uid>` | PUT | `survey.survey.update` | `survey.update` | 套件 `jedi_survey/api/routes/survey_question_route.py:62` |
| `/survey-question/<uid>` | DELETE | `survey.survey.update` | `survey.delete` | 套件 `jedi_survey/api/routes/survey_question_route.py:98` |
| `/survey-questions/reorder` | POST | `survey.survey.update` | `survey.create` | 套件 `jedi_survey/api/routes/survey_question_route.py:113` |
| `/survey-question/move` | POST | `survey.survey.update` | `survey.create` | 套件 `jedi_survey/api/routes/survey_question_route.py:134` |
| `/survey-page` | POST | `survey.survey.update` | `survey.create` | 套件 `jedi_survey/api/routes/survey_page_route.py:33` |
| `/survey-page/<uid>` | PUT | `survey.survey.update` | `survey.update` | 套件 `jedi_survey/api/routes/survey_page_route.py:61` |
| `/survey-page/<uid>` | DELETE | `survey.survey.update` | `survey.delete` | 套件 `jedi_survey/api/routes/survey_page_route.py:88` |
| `/survey-pages/reorder` | POST | `survey.survey.update` | `survey.create` | 套件 `jedi_survey/api/routes/survey_page_route.py:102` |
| `/survey-page/move` | POST | `survey.survey.update` | `survey.create` | 套件 `jedi_survey/api/routes/survey_page_route.py:123` |

### system 系統設定（31 支）

| route | HTTP | 新名 | 舊名 | 守門位置 |
|---|---|---|---|---|
| `/file/upload` | POST | 豁免（附錄 C） | 無 | 套件 `jedi_file_upload/api/routes/upload_file_route.py:88` |
| `/file/upload/<uid>` | DELETE | 豁免（附錄 C） | 無 | 套件 `jedi_file_upload/api/routes/upload_file_route.py:113` |
| `/file/uploads` | POST | 豁免（附錄 C） | 無 | 套件 `jedi_file_upload/api/routes/upload_file_route.py:124` |
| `/file/access-token/<uid>` | GET | 豁免（附錄 C） | 無 | 套件 `jedi_file_upload/api/routes/upload_file_route.py:153` |
| `/file/download/<uid>` | GET | 豁免（附錄 C） | 無 | 套件 `jedi_file_upload/api/routes/upload_file_route.py:165` |
| `/file/pdf-preview/<uid>` | GET | 豁免（附錄 C） | 無 | 套件 `jedi_file_upload/api/routes/upload_file_route.py:200` |
| `/system/config/<group>/<key>` | GET | 依設定群組（通則 C）的 `read` | 無 | `api/system_config/routes/system_config_route.py:149` |
| `/system/config/<group>/<key>` | PUT | 依設定群組（通則 C）的 `update` | 依設定群組的 `.update`（Drive 與未登記群組＝`system_config.update`） | `api/system_config/routes/system_config_route.py:160` |
| `/system/config/<group>/<key>` | DELETE | 依設定群組（通則 C）的 `delete` | 依設定群組的 `.delete` | `api/system_config/routes/system_config_route.py:173` |
| `/system/configs/<group>` | GET | 依設定群組（通則 C）的 `read` | 無 | 套件 `jedi_system_core/api/routes/system_config_route.py:39` |
| `/system/config/<uid>` | GET | 依設定群組（通則 C）的 `read` | 無 | 套件 `jedi_system_core/api/routes/system_config_route.py:54` |
| `/system/config/<uid>` | PUT | 依設定群組（通則 C）的 `update` | 依設定群組 | 套件 `jedi_system_core/api/routes/system_config_route.py:64` |
| `/system/config/<uid>` | DELETE | 依設定群組（通則 C）的 `delete` | 依設定群組 | 套件 `jedi_system_core/api/routes/system_config_route.py:79` |
| `/system/config` | POST | 依設定群組（通則 C）的 `create` | 依設定群組的 `.create` | 套件 `jedi_system_core/api/routes/system_config_route.py:98` |
| `/mail/test` | POST | `system.smtp-config.update` | `smtp-config.update` | 套件 `jedi_notification/api/routes/mail_route.py:20` |
| `/ldap/connect-test` | POST | `system.ldap-config.update` | `ldap-config.create` | 套件 `jedi_iam/api/routes/ldap_route.py:17` |
| `/notify-config/<channel>/test` | POST | `system.notify-config.update` | `notify_config.update` | `api/notify_config/routes/notify_config_route.py:23` |
| `/system/security-policy` | GET | `system.security-policy.read` | `security-policy.read` | `api/system_config/routes/security_policy_route.py:51` |
| `/system/security-policy` | PUT | `system.security-policy.update` | `security-policy.update` | `api/system_config/routes/security_policy_route.py:59` |
| `/log-forwarding` | GET | `system.log-forwarding.read` | `log-forwarding.read` | 套件 `jedi_api_log/forwarding/api/routes/log_forwarding_route.py:49` |
| `/log-forwarding` | PUT | `system.log-forwarding.update` | `log-forwarding.update` | 套件 `jedi_api_log/forwarding/api/routes/log_forwarding_route.py:57` |
| `/log-forwarding/test` | POST | `system.log-forwarding.update` | `log-forwarding.update` | 套件 `jedi_api_log/forwarding/api/routes/log_forwarding_route.py:73` |
| `/system/config/ai-provider/model-options` | GET | `ai.ai-provider-config.read`（自動分類頁也呼叫，見附錄 D 待裁 4） | `storage-config.read` | `api/system_config/routes/system_config_route.py:100` |
| `/system/config/storage/restore-default` | GET | `system.storage-config.read` | `storage-config.read` | `api/system_config/routes/system_config_route.py:119` |
| `/system/config/storage/restore-default` | POST | `system.storage-config.update` | `storage-config.update` | `api/system_config/routes/system_config_route.py:127` |
| `/system/menu/<group>` | GET | 豁免（附錄 C） | 無 | 套件 `jedi_system_core/api/routes/system_menu_route.py:36` |
| `/system/menus` | POST | `system.system-menu.read` | 無 | 套件 `jedi_system_core/api/routes/system_menu_route.py:53` |
| `/system/category-menu` | GET | `system.system-menu.read` | 無 | 套件 `jedi_system_core/api/routes/system_menu_route.py:75` |
| `/system-menu` | POST | `system.system-menu.create` | `system-menu.create` | 套件 `jedi_system_core/api/routes/system_menu_route.py:94` |
| `/system-menu/<id>` | PUT | `system.system-menu.update` | `system-menu.update` | 套件 `jedi_system_core/api/routes/system_menu_route.py:114` |
| `/system-menu/<id>` | DELETE | `system.system-menu.delete` | `system-menu.delete` | 套件 `jedi_system_core/api/routes/system_menu_route.py:126` |

### iam 身分與存取（50 支）

| route | HTTP | 新名 | 舊名 | 守門位置 |
|---|---|---|---|---|
| `/users/menu` | GET | 豁免（附錄 C） | 無 | 套件 `jedi_iam/api/routes/user_route.py:67` |
| `/users` | POST | `iam.user.read` | `user.read` | 套件 `jedi_iam/api/routes/user_route.py:80` |
| `/user` | POST | `iam.user.create`（帶 user_roles 另要 `iam.user.assign`，service 層） | `user.create` | 套件 `jedi_iam/api/routes/user_route.py:107` |
| `/user/<uid>` | GET | `iam.user.read`（本人豁免） | `user.read` | 套件 `jedi_iam/api/routes/user_route.py:129` |
| `/user/<uid>` | PUT | `iam.user.update`（user_roles 與現況不同另要 `iam.user.assign`，service 層） | `user.update` | 套件 `jedi_iam/api/routes/user_route.py:154` |
| `/user/<uid>` | DELETE | `iam.user.delete` | `user.delete` | 套件 `jedi_iam/api/routes/user_route.py:172` |
| `/role-assignments` | POST | `iam.user.read` | 無 | 套件 `jedi_iam/api/routes/role_assignment_route.py` |
| `/role-assignment` | POST | `iam.user.assign` | 無 | 同上 |
| `/role-assignment/<id>` | PUT／DELETE | `iam.user.assign` | 無 | 同上 |
| `/users/<uid>/effective-access` | GET | `iam.user.read`（本人豁免） | 無 | 同上 |
| `/users/me/capabilities` | GET | 豁免（附錄 C） | 無 | 同上 |
| `/user/change-status/<uid>` | POST | `iam.user.update` | `user.create` | 套件 `jedi_iam/api/routes/user_route.py:211` |
| `/user/web-menu` | GET | 豁免（附錄 C） | 無 | 套件 `jedi_iam/api/routes/user_route.py:186` |
| `/user-profile/<uid>` | PUT | 豁免（附錄 C） | 無 | 套件 `jedi_iam/api/routes/user_route.py:224` |
| `/user-mfa-type` | PUT | 豁免（附錄 C） | 無 | 套件 `jedi_iam/api/routes/user_route.py:278` |
| `/users/upload` | POST | `iam.user.import` | `user.create` | 套件 `jedi_iam/api/routes/user_import_route.py:27` |
| `/user/validate` | POST | `iam.user.import` | `user.create` | 套件 `jedi_iam/api/routes/user_import_route.py:41` |
| `/user/batch-upload` | POST | `iam.user.import` | `user.create` | 套件 `jedi_iam/api/routes/user_import_route.py:74` |
| `/user/download/sample` | GET | `iam.user.import` | `user.read` | 套件 `jedi_iam/api/routes/user_import_route.py:57` |
| `/auth-providers/user/<user_uid>` | GET | `iam.user.read`（本人豁免） | 無 | 套件 `jedi_iam/api/routes/user_auth_provider_route.py:20` |
| `/auth-provider` | POST | `iam.user.update`（本人豁免） | `user.update` | 套件 `jedi_iam/api/routes/user_auth_provider_route.py:49` |
| `/auth-provider/<uid>` | DELETE | `iam.user.update`（本人豁免） | `user.update` | 套件 `jedi_iam/api/routes/user_auth_provider_route.py:31` |
| `/roles/menu` | GET | `iam.role.read` | `role.read` | 套件 `jedi_iam/api/routes/role_route.py:26` |
| `/roles` | POST | `iam.role.read` | `role.read` | 套件 `jedi_iam/api/routes/role_route.py:38` |
| `/role` | POST | `iam.role.create` | `role.create` | 套件 `jedi_iam/api/routes/role_route.py:61` |
| `/role/<uid>` | GET | `iam.role.read` | `role.read` | 套件 `jedi_iam/api/routes/role_route.py:78` |
| `/role/<uid>` | PUT | `iam.role.update` | `role.update` | 套件 `jedi_iam/api/routes/role_route.py:88` |
| `/role/<uid>` | DELETE | `iam.role.delete` | `role.delete` | 套件 `jedi_iam/api/routes/role_route.py:101` |
| `/role/status/<uid>` | PUT | `iam.role.update` | `role.update` | 套件 `jedi_iam/api/routes/role_route.py:113` |
| `/roles/export` | POST | `iam.role.export` | 無 | 套件 `jedi_iam/api/routes/role_route.py`（`RoleExportRoute`） |
| `/roles/import` | POST | `iam.role.import` | 無 | 套件 `jedi_iam/api/routes/role_route.py`（`RoleImportRoute`） |
| `/capabilities/menu` | GET | `iam.role.read` | 無 | 套件 `jedi_iam/api/routes/capability_route.py:13` |
| `/ui-routes` | GET | `iam.role.read` | 無 | 套件 `jedi_iam/api/routes/ui_route_route.py:13` |
| `/org-units/menu` | GET | 豁免（附錄 C） | 無 | 套件 `jedi_iam/api/routes/org_unit_route.py:23` |
| `/org-units` | POST | `iam.org-unit.read` | `department.read` | 套件 `jedi_iam/api/routes/org_unit_route.py:36` |
| `/org-unit` | POST | `iam.org-unit.create` | `department.create` | 套件 `jedi_iam/api/routes/org_unit_route.py:61` |
| `/org-unit/<uid>` | GET | `iam.org-unit.read` | `department.read` | 套件 `jedi_iam/api/routes/org_unit_route.py:77` |
| `/org-unit/<uid>` | PUT | `iam.org-unit.update` | `department.update` | 套件 `jedi_iam/api/routes/org_unit_route.py:86` |
| `/org-unit/<uid>` | DELETE | `iam.org-unit.delete` | `department.delete` | 套件 `jedi_iam/api/routes/org_unit_route.py:98` |
| `/tenants/menu` | GET | 豁免（附錄 C 挑租戶；首腦 2026-10-07 T-4.7c 裁） | 無 | 套件 `jedi_iam/api/routes/tenant_route.py:26` |
| `/tenants` | POST | `iam.tenant.read` | `tenant.read` | 套件 `jedi_iam/api/routes/tenant_route.py:38` |
| `/tenant` | POST | `iam.tenant.create` | `tenant.create` | 套件 `jedi_iam/api/routes/tenant_route.py:59` |
| `/tenant/<uid>` | GET | `iam.tenant.read` | `tenant.read` | 套件 `jedi_iam/api/routes/tenant_route.py:93` |
| `/tenant/<uid>` | PUT | `iam.tenant.update` | 無 | 套件 `jedi_iam/api/routes/tenant_route.py:103` |
| `/tenant/<uid>` | DELETE | `iam.tenant.delete` | `tenant.delete` | 套件 `jedi_iam/api/routes/tenant_route.py:115` |
| `/login` | POST | 豁免（附錄 C） | 無 | 套件 `jedi_iam/api/routes/login_route.py:37` |
| `/refresh` | POST | 豁免（附錄 C） | 無 | 套件 `jedi_iam/api/routes/login_route.py:86` |
| `/logout` | POST | 豁免（附錄 C） | 無 | 套件 `jedi_iam/api/routes/login_route.py:97` |
| `/otp-verify` | POST | 豁免（附錄 C） | 無 | 套件 `jedi_iam/api/routes/otp_route.py:112` |
| `/otp-resend` | POST | 豁免（附錄 C） | 無 | 套件 `jedi_iam/api/routes/otp_route.py:147` |
| `/otp-qrcode/<uid>` | GET | 豁免（附錄 C） | 無 | 套件 `jedi_iam/api/routes/otp_route.py:76` |
| `/otp-qrcode-token` | GET | 豁免（附錄 C） | 無 | 套件 `jedi_iam/api/routes/otp_route.py:67` |
| `/totp-secret` | POST | 豁免（附錄 C） | 無 | 套件 `jedi_iam/api/routes/otp_route.py:45` |
| `/totp-verify` | POST | 豁免（附錄 C） | 無 | 套件 `jedi_iam/api/routes/otp_route.py:99` |
| `/forget-password` | POST | 豁免（附錄 C） | 無 | 套件 `jedi_iam/api/routes/change_password_route.py:47` |
| `/user/change-pwd-req/<uid>` | GET | 豁免（附錄 C） | 無 | 套件 `jedi_iam/api/routes/change_password_route.py:84` |
| `/user/change-pwd-by-req` | POST | 豁免（附錄 C） | 無 | 套件 `jedi_iam/api/routes/change_password_route.py:20` |

### platform 原廠層（22 支）

| route | HTTP | 新名 | 舊名 | 守門位置 |
|---|---|---|---|---|
| `/license/status` | GET | 豁免（附錄 C） | 無 | 套件 `jedi_license_runtime/api/routes/license_route.py:64` |
| `/license/activation/machine-code` | GET | 豁免（附錄 C） | 無 | 套件 `jedi_license_runtime/api/routes/license_route.py:87` |
| `/license/activation/upload` | POST | 豁免（附錄 C） | 無 | 套件 `jedi_license_runtime/api/routes/license_route.py:104` |
| `/license/activation/online` | POST | 豁免（附錄 C） | 無 | 套件 `jedi_license_runtime/api/routes/license_route.py:120` |
| `/license/upload` | POST | `platform.license.import` | 無 | 套件 `jedi_license_runtime/api/routes/license_route.py:48` |
| `/license/tenants` | GET | `platform.license.read` | 無 | 套件 `jedi_license_runtime/api/routes/license_admin_route.py:42` |
| `/license/tenants/<uid>` | GET | `platform.license.read` | 無 | 套件 `jedi_license_runtime/api/routes/license_admin_route.py:50` |
| `/license/tenants/<uid>/events` | GET | `platform.license.read` | 無 | 套件 `jedi_license_runtime/api/routes/license_admin_route.py:58` |
| `/license/lc/plans` | GET | `platform.license.read` | 無 | 套件 `jedi_license_runtime/api/routes/license_admin_route.py:140` |
| `/license/tenants/<uid>/assign` | POST | `platform.license.assign` | 無 | 套件 `jedi_license_runtime/api/routes/license_admin_route.py:66` |
| `/license/tenants/<uid>/lc-issue` | POST | `platform.license.assign` | 無 | 套件 `jedi_license_runtime/api/routes/license_admin_route.py:106` |
| `/license/tenants/<uid>/lc-extend` | POST | `platform.license.update` | 無 | 套件 `jedi_license_runtime/api/routes/license_admin_route.py:127` |
| `/license/tenants/<uid>/lock` | POST | `platform.license.update` | 無 | 套件 `jedi_license_runtime/api/routes/license_admin_route.py:80` |
| `/license/tenants/<uid>/unlock` | POST | `platform.license.update` | 無 | 套件 `jedi_license_runtime/api/routes/license_admin_route.py:93` |
| `/version` | GET | 豁免（附錄 C） | 無 | `api/version/routes/version_route.py:28` |
| `/csp-report` | POST | 豁免（附錄 C） | 無 | `api/version/routes/browser_report_route.py:25` |
| `/setup/status` | GET | 豁免（附錄 C） | 無 | `api/setup/routes/setup_route.py:91` |
| `/setup/provision` | POST | 豁免（附錄 C） | 無 | `api/setup/routes/setup_route.py:113` |
| `/log/api-logs` | POST | `platform.api-log.read` | `log.read`（只綁選單） | 套件 `jedi_api_log/api_log/api/routes/api_log_route.py:27` |
| `/log/api-logs/export` | GET | `platform.api-log.export` | `log.read`（只綁選單） | 套件 `jedi_api_log/api_log/api/routes/api_log_route.py:54` |
| `/support/recent-errors` | GET | `platform.support.read` | 無 | `api/support/routes/recent_error_route.py:35` |
| `/support/diagnostic-bundle` | POST | `platform.support.export` | 無 | `api/support/routes/diagnostic_bundle_route.py:37` |

### asset 資產（17 支）

| route | HTTP | 新名 | 舊名 | 守門位置 |
|---|---|---|---|---|
| `/information-systems/menu` | GET | 跟呼叫頁權限（通則 B）：SSP 頁看 `oscal.ssp.read`，資源庫頁看 `oscal.resource-library.read` | `information-system.read` | 套件 `jedi_asset/api/routes/information_system_route.py:44` |
| `/information-systems/list` | POST | `asset.information-system.read` | `project-summary-report.read`（只綁選單） | 套件 `jedi_asset/api/routes/information_system_route.py:62` |
| `/information-systems` | POST | `asset.information-system.create` | `project-summary-report.create`（只綁選單） | 套件 `jedi_asset/api/routes/information_system_route.py:85` |
| `/information-system/<uid>` | GET | `asset.information-system.read` | `project-summary-report.read`（只綁選單） | 套件 `jedi_asset/api/routes/information_system_route.py:106` |
| `/information-system/<uid>` | PUT | `asset.information-system.update` | `project-summary-report.update`（只綁選單） | 套件 `jedi_asset/api/routes/information_system_route.py:118` |
| `/information-system/<uid>` | DELETE | `asset.information-system.delete` | `project-summary-report.delete`（只綁選單） | 套件 `jedi_asset/api/routes/information_system_route.py:139` |
| `/devices` | POST | `asset.device.read` | `device.read` | 套件 `jedi_asset/api/routes/device_route.py:39` |
| `/devices/menu` | GET | 跟呼叫頁權限（通則 B）：SSP 頁看 `oscal.ssp.read`，資源庫頁看 `oscal.resource-library.read`，任務設置看 `grc.job.read` | `device.read` | 套件 `jedi_asset/api/routes/device_route.py:59` |
| `/device` | POST | `asset.device.create` | `device.create` | 套件 `jedi_asset/api/routes/device_route.py:129` |
| `/device/<uid>` | GET | `asset.device.read` | `device.read` | 套件 `jedi_asset/api/routes/device_route.py:72` |
| `/device/<uid>` | PUT | `asset.device.update` | `device.update` | 套件 `jedi_asset/api/routes/device_route.py:82` |
| `/device/<uid>` | DELETE | `asset.device.delete` | `device.delete` | 套件 `jedi_asset/api/routes/device_route.py:94` |
| `/device/<uid>/references` | GET | `asset.device.read` | `device.read` | 套件 `jedi_asset/api/routes/device_route.py:111` |
| `/devices/import-template` | GET | `asset.device.import` | `device.create` | 套件 `jedi_asset/api/routes/device_import_route.py:50` |
| `/devices/import/verify` | POST | `asset.device.import` | `device.create` | 套件 `jedi_asset/api/routes/device_import_route.py:65` |
| `/devices/import/confirm` | POST | `asset.device.import` | `device.create` | 套件 `jedi_asset/api/routes/device_import_route.py:82` |
| `/devices/export` | POST | `asset.device.export` | `device.read` | 套件 `jedi_asset/api/routes/device_import_route.py:102` |

### ai AI 相關（16 支）

| route | HTTP | 新名 | 舊名 | 守門位置 |
|---|---|---|---|---|
| `/ai-dashboard/health` | GET | 豁免（附錄 C） | 無 | 套件 `jedi_ai_dashboard/api/routes/ai_dashboard_route.py:71` |
| `/ai-dashboard/auto-generate` | POST | `ai.dashboard.read` | `ai-dashboard.read` | 套件 `jedi_ai_dashboard/api/routes/ai_dashboard_route.py:110` |
| `/ai-chatbot` | POST | `ai.assistant.read` | 無 | 套件 `jedi_ai_bot/api/routes/ai_bot_route.py:39` |
| `/ai-chatbot` | DELETE | `ai.assistant.read` | 無 | 套件 `jedi_ai_bot/api/routes/ai_bot_route.py:71` |
| `/system/ai-call-logs` | POST | `ai.call-log.read` | `ai-call-log.read` | `api/ai_call_log/routes/ai_call_log_route.py:46` |
| `/system/ai-call-logs/<uid>` | GET | `ai.call-log.read` | `ai-call-log.read` | `api/ai_call_log/routes/ai_call_log_route.py:58` |
| `/system/ai-call-logs/export` | POST | `ai.call-log.export` | `ai-call-log.read` | `api/ai_call_log/routes/ai_call_log_route.py:68` |
| `/system/ai-call-logs/usage` | POST | `ai.call-log.read` | `ai-call-log.read` | `api/ai_call_log/routes/ai_call_log_route.py:91` |
| `/system/ai-call-logs/usage/export` | POST | `ai.call-log.export` | `ai-call-log.read` | `api/ai_call_log/routes/ai_call_log_route.py:102` |
| `/system/ai-quota` | GET | `ai.quota.read` | `ai-quota.read` | `api/ai_quota/routes/ai_quota_route.py:28` |
| `/system/ai-quota` | PUT | `ai.quota.update` | `ai-quota.update` | `api/ai_quota/routes/ai_quota_route.py:34` |
| `/system/ai-quota` | DELETE | `ai.quota.update` | `ai-quota.update` | `api/ai_quota/routes/ai_quota_route.py:40` |
| `/system/ai-quota/me` | GET | 豁免（附錄 C） | 無 | `api/ai_quota/routes/ai_quota_route.py:70` |
| `/system/ai-quota/tenants` | GET | `platform.ai-quota-ceiling.read` | 無 | `api/ai_quota/routes/ai_quota_route.py:48` |
| `/system/ai-quota/tenants/<id>/ceiling` | GET | `platform.ai-quota-ceiling.read` | 無 | `api/ai_quota/routes/ai_quota_route.py:56` |
| `/system/ai-quota/tenants/<id>/ceiling` | PUT | `platform.ai-quota-ceiling.update` | 無 | `api/ai_quota/routes/ai_quota_route.py:62` |

### workspace 協作（13 支）

| route | HTTP | 新名 | 舊名 | 守門位置 |
|---|---|---|---|---|
| `/bulletins` | POST | 讀者模式 `workspace.bulletin.read`；管理模式 `workspace.bulletin.create`（後端依能力點判模式） | 無 | 套件 `jedi_bulletin/api/routes/bulletin_route.py:37` |
| `/bulletin/<uid>` | GET | `workspace.bulletin.read` | 無 | 套件 `jedi_bulletin/api/routes/bulletin_route.py:58` |
| `/bulletin` | POST | `workspace.bulletin.create` | `bulletin.create` | 套件 `jedi_bulletin/api/routes/bulletin_route.py:103` |
| `/bulletin/<uid>` | PUT | `workspace.bulletin.update` | `bulletin.update` | 套件 `jedi_bulletin/api/routes/bulletin_route.py:70` |
| `/bulletin/<uid>` | DELETE | `workspace.bulletin.delete` | `bulletin.delete` | 套件 `jedi_bulletin/api/routes/bulletin_route.py:81` |
| `/feedbacks` | POST | `workspace.feedback.read`；看全部要 `workspace.feedback-review.read` | `feedback.read`、`feedback-view.read` | 套件 `jedi_issue/api/routes/feedback_route.py:50` |
| `/feedback/<uid>` | GET | `workspace.feedback.read`；看別人的要 `workspace.feedback-review.read`（今天沒有本人檢查，附錄 D 已知缺口） | `feedback.read`、`feedback-view.read` | 套件 `jedi_issue/api/routes/feedback_route.py:73` |
| `/feedback` | POST | `workspace.feedback.create` | `feedback.create` | 套件 `jedi_issue/api/routes/feedback_route.py:81` |
| `/feedback/<uid>` | PUT | `workspace.feedback.update` | `feedback.update` | 套件 `jedi_issue/api/routes/feedback_route.py:97` |
| `/feedback/<uid>` | DELETE | `workspace.feedback.delete` | `feedback.delete` | 套件 `jedi_issue/api/routes/feedback_route.py:115` |
| `/feedback/file/<uid>/<file_uid>` | DELETE | `workspace.feedback.update` | `feedback.update` | 套件 `jedi_issue/api/routes/feedback_route.py:127` |
| `/feedback/export/<type>` | POST | `workspace.feedback.export` | `feedback.export` | 套件 `jedi_issue/api/routes/feedback_route.py:141` |
| `/labels/menu/<scope>` | GET | 跟 `workspace.feedback.read`（通則 B） | 無 | 套件 `jedi_issue/api/routes/label_route.py:14` |

**合計**：559 支（route＋HTTP 動詞；含角色匯出匯入兩支，不在五份盤點主表內）。算法：五份盤點主表共 553 列；其中 8 列兩份都記了（流程定義、階段物件、儲存出廠還原兩支、AI 模型下拉、回饋類別下拉、支援頁兩支），各只留在歸屬那份，剩 545；再加 `a1-system-iam.md`「免登入與本人端點」小表另列的 12 支登入類端點。

## 附錄 B：123 個現有能力點 → 新名／刪除

DEV `public.capabilities` 逐列，依舊名排序。`is_platform` 是舊值。新名欄的 `license_module` 一律等於該列的舊 `resource_type`。「來源」指五份盤點：grc＝`a1-grc.md`、oscal＝`a1-oscal-flow.md`、det＝`a1-detection-evidence-survey.md`、sys＝`a1-system-iam.md`、plat＝`a1-platform.md`。

| # | 舊名 | resource_type | action | is_platform | 新名 或「刪除」 | 來源 | 備註 |
|---|---|---|---|---|---|---|---|
| 1 | `ai-call-log.read` | ai-call-log | read | f | `ai.call-log.read` | plat | 兩支匯出端點改守新開的 `ai.call-log.export` |
| 2 | `ai-dashboard.read` | ai-dashboard | read | f | `ai.dashboard.read` | plat | |
| 3 | `ai-quota.read` | ai-quota | read | f | `ai.quota.read` | plat | |
| 4 | `ai-quota.update` | ai-quota | update | f | `ai.quota.update` | plat | |
| 5 | `audit.create` | audit | create | f | `grc.audit.create` | grc | |
| 6 | `audit.delete` | audit | delete | f | `grc.audit.delete` | grc | |
| 7 | `audit.read` | audit | read | f | `grc.audit.read` | grc | |
| 8 | `audit.update` | audit | update | f | `grc.audit.update` | grc | |
| 9 | `bulletin-list.read` | bulletin-list | read | f | `workspace.bulletin.read` | plat | |
| 10 | `bulletin.create` | bulletin | create | f | `workspace.bulletin.create` | plat | |
| 11 | `bulletin.delete` | bulletin | delete | f | `workspace.bulletin.delete` | plat | |
| 12 | `bulletin.read` | bulletin | read | f | 刪除 | plat | 併入 `workspace.bulletin.read`；公告管理頁改綁 `workspace.bulletin.create` |
| 13 | `bulletin.update` | bulletin | update | f | `workspace.bulletin.update` | plat | |
| 14 | `cloud_integration.create` | cloud_integration | create | f | `evidence.cloud-integration.create` | det | `license_module` 保留底線原值 `cloud_integration` |
| 15 | `cloud_integration.delete` | cloud_integration | delete | f | `evidence.cloud-integration.delete` | det | 同上 |
| 16 | `cloud_integration.read` | cloud_integration | read | f | `evidence.cloud-integration.read` | det | 同上 |
| 17 | `cloud_integration.update` | cloud_integration | update | f | `evidence.cloud-integration.update` | det | 同上；有 route 守，只是沒綁選單 |
| 18 | `compliance-framework.create` | compliance-framework | create | t | `oscal.framework.create` | oscal | |
| 19 | `compliance-framework.delete` | compliance-framework | delete | t | `oscal.framework.delete` | oscal | |
| 20 | `compliance-framework.read` | compliance-framework | read | f | `oscal.framework.read` | oscal | |
| 21 | `compliance-framework.update` | compliance-framework | update | t | `oscal.framework.update` | oscal | |
| 22 | `department.create` | department | create | f | `iam.org-unit.create` | sys | |
| 23 | `department.delete` | department | delete | f | `iam.org-unit.delete` | sys | |
| 24 | `department.read` | department | read | f | `iam.org-unit.read` | sys | |
| 25 | `department.update` | department | update | f | `iam.org-unit.update` | sys | |
| 26 | `detection-profile.create` | detection-profile | create | f | `detection.profile.create` | det | |
| 27 | `detection-profile.delete` | detection-profile | delete | f | `detection.profile.delete` | det | |
| 28 | `detection-profile.read` | detection-profile | read | f | `detection.profile.read` | det | |
| 29 | `detection-profile.update` | detection-profile | update | f | `detection.profile.update` | det | |
| 30 | `device.create` | device | create | f | `asset.device.create` | det | 匯入三支改守新開的 `asset.device.import` |
| 31 | `device.delete` | device | delete | f | `asset.device.delete` | det | |
| 32 | `device.read` | device | read | f | `asset.device.read` | det | 匯出改守新開的 `asset.device.export` |
| 33 | `device.update` | device | update | f | `asset.device.update` | det | |
| 34 | `feedback-view.read` | feedback-view | read | f | `workspace.feedback-review.read` | plat | 從一般成員出貨範本拿掉 |
| 35 | `feedback.create` | feedback | create | f | `workspace.feedback.create` | plat | |
| 36 | `feedback.delete` | feedback | delete | f | `workspace.feedback.delete` | plat | |
| 37 | `feedback.export` | feedback | export | f | `workspace.feedback.export` | plat | 匯出不濾 owner，等於匯出全公司回饋，只應配給有 `feedback-review.read` 的人（附錄 D 首腦補充 ①） |
| 38 | `feedback.read` | feedback | read | f | `workspace.feedback.read` | plat | |
| 39 | `feedback.update` | feedback | update | f | `workspace.feedback.update` | plat | |
| 40 | `flow_template.create` | flow_template | create | f | `flow.template.create` | oscal | |
| 41 | `flow_template.delete` | flow_template | delete | f | `flow.template.delete` | oscal | |
| 42 | `flow_template.read` | flow_template | read | f | `flow.template.read` | oscal | |
| 43 | `flow_template.update` | flow_template | update | f | `flow.template.update` | oscal | 發布／取消發布改守新開的 `flow.template.publish` |
| 44 | `information-system.create` | information-system | create | f | `asset.information-system.create` | grc | |
| 45 | `information-system.delete` | information-system | delete | f | `asset.information-system.delete` | grc | |
| 46 | `information-system.read` | information-system | read | f | `asset.information-system.read` | grc | |
| 47 | `information-system.update` | information-system | update | f | `asset.information-system.update` | grc | |
| 48 | `issue-integrate-config.create` | issue-integrate-config | create | t | `system.issue-integrate-config.create` | sys | |
| 49 | `issue-integrate-config.delete` | issue-integrate-config | delete | t | `system.issue-integrate-config.delete` | sys | |
| 50 | `issue-integrate-config.read` | issue-integrate-config | read | t | `system.issue-integrate-config.read` | sys | |
| 51 | `issue-integrate-config.update` | issue-integrate-config | update | t | `system.issue-integrate-config.update` | sys | |
| 52 | `ldap-config.create` | ldap-config | create | f | `system.ldap-config.create` | sys | LDAP 連線測試改守 `system.ldap-config.update` |
| 53 | `ldap-config.delete` | ldap-config | delete | f | `system.ldap-config.delete` | sys | |
| 54 | `ldap-config.read` | ldap-config | read | f | `system.ldap-config.read` | sys | |
| 55 | `ldap-config.update` | ldap-config | update | f | `system.ldap-config.update` | sys | |
| 56 | `license.read` | license | read | t | `platform.license.read` | sys | 從 system 移到 platform |
| 57 | `log-forwarding.read` | log-forwarding | read | f | `system.log-forwarding.read` | sys | |
| 58 | `log-forwarding.update` | log-forwarding | update | f | `system.log-forwarding.update` | sys | |
| 59 | `log.read` | log | read | t | `platform.api-log.read` | plat | |
| 60 | `module-frame.create` | module-frame | create | f | `oscal.resource-library.create` | oscal | 子物件新增改守 update |
| 61 | `module-frame.delete` | module-frame | delete | f | `oscal.resource-library.delete` | oscal | 子物件刪除改守 update |
| 62 | `module-frame.read` | module-frame | read | f | `oscal.resource-library.read` | oscal | `/ssp/<uid>/excel-template` 改守 `oscal.ssp.export` |
| 63 | `module-frame.update` | module-frame | update | f | `oscal.resource-library.update` | oscal | |
| 64 | `notify_config.read` | notify_config | read | f | `system.notify-config.read` | sys | 底線改連字號；`license_module` 保留原值 |
| 65 | `notify_config.update` | notify_config | update | f | `system.notify-config.update` | sys | 同上 |
| 66 | `plugin.create` | plugin | create | f | `detection.plugin.create` | det | 工具設定建立改守此動詞（今天守 update） |
| 67 | `plugin.delete` | plugin | delete | f | `detection.plugin.delete` | det | |
| 68 | `plugin.read` | plugin | read | f | `detection.plugin.read` | det | |
| 69 | `plugin.update` | plugin | update | f | `detection.plugin.update` | det | |
| 70 | `project-summary-report.create` | project-summary-report | create | f | `grc.summary-report.create` | grc | |
| 71 | `project-summary-report.delete` | project-summary-report | delete | f | `grc.summary-report.delete` | grc | |
| 72 | `project-summary-report.read` | project-summary-report | read | f | `grc.summary-report.read` | grc | |
| 73 | `project-summary-report.update` | project-summary-report | update | f | `grc.summary-report.update` | grc | PDF 匯出改守新開的 `grc.summary-report.export` |
| 74 | `project.approve` | project | approve | f | `grc.audit.approve` | grc | 舊名沒有任何對應功能，名字移給審閱標記。今天審閱標記沒有能力點守門，持有者怎麼轉由 A.2 依「行為零變化」處理 |
| 75 | `project.assign` | project | assign | f | `grc.project.assign` | grc | 接專案成員新增／改角色／移除 |
| 76 | `project.create` | project | create | f | `grc.project.create` | grc | 同時是建專案時挑資源庫、挑流程範本的放行條件（通則 B） |
| 77 | `project.delete` | project | delete | f | `grc.project.delete` | grc | |
| 78 | `project.export` | project | export | f | `grc.job.export` | grc | 接任務匯出 |
| 79 | `project.read` | project | read | f | `grc.project.read` | grc | |
| 80 | `project.update` | project | update | f | `grc.project.update` | grc | |
| 81 | `remote-agent-manage.create` | remote-agent-manage | create | f | `detection.remote-agent.create` | det | 今天 15 支管理端點全守這顆；套件插槽拆讀寫後依動詞分 |
| 82 | `remote-agent-manage.delete` | remote-agent-manage | delete | f | `detection.remote-agent.delete` | det | |
| 83 | `remote-agent-manage.read` | remote-agent-manage | read | f | `detection.remote-agent.read` | det | |
| 84 | `remote-agent-manage.update` | remote-agent-manage | update | f | `detection.remote-agent.update` | det | |
| 85 | `role.create` | role | create | f | `iam.role.create` | sys | |
| 86 | `role.delete` | role | delete | f | `iam.role.delete` | sys | |
| 87 | `role.read` | role | read | f | `iam.role.read` | sys | |
| 88 | `role.update` | role | update | f | `iam.role.update` | sys | |
| 89 | `scan-zone.read` | scan-zone | read | f | `detection.scan-zone.read` | det | |
| 90 | `scan-zone.update` | scan-zone | update | f | `detection.scan-zone.update` | det | 新增、刪除、產生建議改守新開的 create／delete；今天持有 update 的角色升級時要一併給 create／delete，行為才不變（A.2） |
| 91 | `security-policy.read` | security-policy | read | f | `system.security-policy.read` | sys | |
| 92 | `security-policy.update` | security-policy | update | f | `system.security-policy.update` | sys | |
| 93 | `smtp-config.create` | smtp-config | create | f | `system.smtp-config.create` | sys | |
| 94 | `smtp-config.delete` | smtp-config | delete | f | `system.smtp-config.delete` | sys | |
| 95 | `smtp-config.read` | smtp-config | read | f | `system.smtp-config.read` | sys | |
| 96 | `smtp-config.update` | smtp-config | update | f | `system.smtp-config.update` | sys | |
| 97 | `storage-config.create` | storage-config | create | f | `system.storage-config.create` | det、sys | 只管儲存設定頁；借用它的 AI 服務設定、Drive 應用程式憑證、支援頁、AI 分類設定改用各自的新資源 |
| 98 | `storage-config.delete` | storage-config | delete | f | `system.storage-config.delete` | det、sys | 同上 |
| 99 | `storage-config.read` | storage-config | read | f | `system.storage-config.read` | det、sys | 同上 |
| 100 | `storage-config.update` | storage-config | update | f | `system.storage-config.update` | det、sys | 同上 |
| 101 | `survey.create` | survey | create | f | `survey.survey.create` | det | 匯入改守新開的 `survey.survey.import`；搬移、題目／頁面增刪改守 update |
| 102 | `survey.delete` | survey | delete | f | `survey.survey.delete` | det | 取消發布改守 `survey.survey.publish`；刪自己的留言改守 `grc.job.update` |
| 103 | `survey.read` | survey | read | f | `survey.survey.read` | det | |
| 104 | `survey.update` | survey | update | f | `survey.survey.update` | det | 發布改守新開的 `survey.survey.publish`；改自己的留言改守 `grc.job.update` |
| 105 | `system_config.create` | system_config | create | t | `system.system-config.create` | sys | 未登記設定群組的兜底門；另補 `system.system-config.read` |
| 106 | `system_config.delete` | system_config | delete | t | `system.system-config.delete` | sys | 同上 |
| 107 | `system_config.update` | system_config | update | t | `system.system-config.update` | sys | 同上 |
| 108 | `system-menu.create` | system-menu | create | t | `system.system-menu.create` | sys | |
| 109 | `system-menu.delete` | system-menu | delete | t | `system.system-menu.delete` | sys | |
| 110 | `system-menu.read` | system-menu | read | t | `system.system-menu.read` | sys | |
| 111 | `system-menu.update` | system-menu | update | t | `system.system-menu.update` | sys | |
| 112 | `tenant.create` | tenant | create | f | `iam.tenant.create` | sys | |
| 113 | `tenant.delete` | tenant | delete | f | `iam.tenant.delete` | sys | |
| 114 | `tenant.read` | tenant | read | f | `iam.tenant.read` | sys | |
| 115 | `tenant.update` | tenant | update | f | `iam.tenant.update` | sys | 改租戶 PUT 改守此名，平台管理員判定保留 |
| 116 | `user.create` | user | create | f | `iam.user.create` | sys | 停用／啟用改守 update；匯入三支改守新開的 `iam.user.import` |
| 117 | `user.delete` | user | delete | f | `iam.user.delete` | sys | |
| 118 | `user.read` | user | read | f | `iam.user.read` | sys | 範本下載改守 `iam.user.import` |
| 119 | `user.update` | user | update | f | `iam.user.update` | sys | |
| 120 | `workflow.create` | workflow | create | f | 刪除 | grc | 沒有任何 route 或選單用到 |
| 121 | `workflow.delete` | workflow | delete | f | 刪除 | grc | 同上 |
| 122 | `workflow.read` | workflow | read | f | 刪除 | grc | 同上 |
| 123 | `workflow.update` | workflow | update | f | 刪除 | grc | 同上 |

**統計**：123 列＝改名 118 個＋刪除 5 個（`bulletin.read`、`workflow.*` 四個）。`project.approve` 算改名（名字移給 `grc.audit.approve`），不算刪除。

**本表沒有待首腦裁的列。**

## 附錄 C：豁免 route 清單（只驗登入或免登入）

豁免＝不掛任何能力點。分兩種：**免登入**（連登入都不驗，靠別的憑證或根本不需要身分）與**只驗登入**（登入的人都能用，因為資料只跟本人有關、或是全站共用的挑選名單）。守門位置見附錄 A。共 50 支。

| 類別 | route | 守的是什麼 | 理由 |
|---|---|---|---|
| 免登入：登入第一關 | `POST /login`、`POST /refresh` | 帳密；refresh token | 還沒登入，沒有身分可判 |
| 免登入：兩階段驗證 | `POST /otp-verify`、`POST /otp-resend` | 登入第一關發的短期憑證；重寄有節流 | 登入第二關，還沒拿到正式登入憑證 |
| 免登入：兩階段驗證 QR code 圖 | `GET /otp-qrcode/<uid>` | 簽章短期憑證，uid 須等於發放者 | 網頁 `<img>` 帶不了登入憑證 |
| 免登入：忘記密碼 | `POST /forget-password`、`GET /user/change-pwd-req/<uid>`、`POST /user/change-pwd-by-req` | 重設信裡的請求 uid，後端驗有效期 | 忘記密碼的人登不進來 |
| 免登入：版本與瀏覽器回報 | `GET /version`、`POST /csp-report` | 無 | 關於頁；瀏覽器自動送安全政策違規回報，只記 log |
| 免登入：安裝精靈 | `GET /setup/status`、`POST /setup/provision` | 安裝時終端機印的一次性設定碼；已開通就回 409、查不出狀態也當已開通 | 首次開站一個帳號都沒有 |
| 免登入：AI 小幫手上線狀態 | `GET /ai-dashboard/health` | 無 | 頁面載入時還沒拿到登入憑證也要能問；套件與套件測試焊死這個分工 |
| 免登入：遠端代理呼入 | `POST /agents/register`、`POST /agents/heartbeat`、`POST /agents/tasks/<uid>/ack`、`POST /agents/tasks/<uid>/result`、`GET /agents/files/<uid>`、`GET /agents/vulndb/bundle`、`GET /agents/tool-schemas`、`POST /agents/local-runs`、`POST /agents/source-scans` | 註冊碼；代理通行證；下載任務檔另驗任務綁定；回傳的自主執行紀錄與第三方元件結果只認通行證上的租戶與 Agent，body 帶的不採信 | 呼叫者是機器上的代理程式，不是使用者 |
| 免登入：Google 呼入 | `GET /integrations/google-drive/callback`、`POST /webhooks/google-drive/<tenant_id>` | OAuth state＋瀏覽器 nonce cookie；Google 推送帶的通道 token 比對 | 呼叫者是 Google，不帶使用者身分 |
| 免登入：問卷匯入範本下載 | `GET /survey/import-template` | 短期下載憑證 | 憑證由 `GET /survey/import-template/token` 發，那支守 `survey.survey.import` |
| 只驗登入：本人 | `POST /logout`、`GET /otp-qrcode-token`、`POST /totp-secret`、`POST /totp-verify`、`GET /user/web-menu`、`GET /users/me/capabilities`、`PUT /user-profile/<uid>`、`PUT /user-mfa-type` | 只處理本人的資料；改個人資料不採信角色、租戶、部門欄 | 每個人都要能管自己的登入方式與個人資料、載入自己的選單與權限名（前端據此決定按鈕顯示） |
| 只驗登入：授權自救 | `GET /license/status`、`GET /license/activation/machine-code`、`POST /license/activation/upload`、`POST /license/activation/online` | 登入 | 授權過期時系統只剩這幾支能用，掛任何能力點都可能把整個租戶鎖死（防死鎖） |
| 只驗登入：全站字典 | `GET /system/menu/<group>` | 登入 | 全站下拉選項（狀態、類別）的來源，十幾頁共用 |
| 只驗登入：挑人、挑部門、挑租戶 | `GET /users/menu`、`GET /org-units/menu`、`GET /tenants/menu` | 登入；只回名字 | 跨模組挑選名單，任何會指派人或部門的頁都要用；租戶下拉帳號管理頁與部門管理頁都呼叫，掛 `iam.tenant.read` 會擋掉 IT Manager／PM（CM-1588 已鎖只驗登入） |
| 只驗登入：前端錯誤回報 | `GET /error-tracking/config`、`POST /error-tracking/tunnel` | 登入（轉送另收 Agent 通行證）；使用者只能送前端專案、Agent 只能送 Agent 專案，大小 1 MiB、每個呼叫者每分鐘次數有上限 | 任何登入者踩到的前端錯誤都要收；免登入版已因資安項 U3-⑤ 拆除，不可回復（FR-133 D4） |
| 只驗登入：AI 額度黃條 | `GET /system/ai-quota/me` | 登入；只回自己的用量 | 一般成員也要看到自己快用完額度 |
| 只驗登入：檔案 | `POST /file/upload`、`POST /file/uploads`、`DELETE /file/upload/<uid>`、`GET /file/access-token/<uid>`、`GET /file/download/<uid>`、`GET /file/pdf-preview/<uid>` | 登入＋檔案歸屬（讀寫權由檔案所屬功能自己的守門代判）；下載另可用短期憑證 | 同一支服務十幾種功能的檔案，掛單一能力點會讓其他功能的檔案打不開 |

**不算豁免、但本人可以免能力點**：`GET /user/<uid>`（看自己的明細）、`GET /auth-providers/user/<user_uid>`（看自己的第三方登入綁定）、`POST /auth-provider`、`DELETE /auth-provider/<uid>`（綁定、解除自己的）。看別人的要 `iam.user.read`，替別人綁要 `iam.user.update`。其中 `GET /auth-providers/user/<user_uid>` 今天沒做本人檢查（附錄 D 已知缺口）。

## 附錄 D：裁示紀錄與本檔統一處

### 首腦裁示（T-1.6）

五份盤點各自的定案結論照原文有效，這裡只列 T-1.6 合併時首腦另外裁的。

1. **`survey.survey` 不改名**（不換成 `survey.questionnaire`）。
2. **`platform.license` 動詞**：`read`、`assign`（指派、向 License Center 請新照）、`update`（停權、解除、展延）、`import`（上傳照檔），另補 `create`／`delete` 空殼。
3. **Google Drive 應用程式憑證的資源名＝`platform.drive-app-credential`**，四個基本動詞，`is_platform`＝true。
4. **「範圍型讀取只開 read」是四個基本動詞規則的唯一破例**，目前只有 `workspace.feedback-review`。範圍型讀取＝同一份資料的另一種看法（看自己的 vs 看全部人的），不是另一個可以新增、修改、刪除的東西。
5. **`license_module` 存舊 `resource_type` 原值**，客戶手上的授權照不必重簽。
6. **刪除 5 個舊能力點**：`workflow.*` 四個（沒有任何 route 或選單用到）、`bulletin.read`（併入 `workspace.bulletin.read`，公告管理頁改綁 `workspace.bulletin.create`）。
7. **兩個舊名移給新功能**：`project.approve` → `grc.audit.approve`（審閱標記）；`project.export` → `grc.job.export`（任務匯出）。

**首腦補充**

- ① **`workspace.feedback.export` 實際匯出的是全公司回饋**（匯出端點不分本人），等於繞過 `workspace.feedback-review` 的限制。決定：能力點照建，但只配給持有 `workspace.feedback-review.read` 的人；三個出貨範例角色改列 `workspace.feedback` 四個基本動詞，不給 export。
- ② **`GET /classification/available-models` 走通則 B**：它是自動分類頁的模型下拉，看呼叫頁的 `evidence.classification.read`，不在角色上補 `ai.ai-provider-config.read`。

### 本檔統一處（盤點主表與定案或通則不一致時怎麼寫）

盤點主表是逐支當下填的，定案結論與三條通則是事後裁的，兩者不一致時本檔照定案與通則寫。下表列出本檔改寫的地方，A.2 照本檔做，不要回頭照盤點主表。

| # | 盤點主表寫的 | 本檔寫的 | 依據 |
|---|---|---|---|
| 1 | design.md §6.1 模組定稿表 system 列沒有 `system-menu` | 第二部分 system 模組補 `system.system-menu` | `a1-system-iam.md` 新名總覽與定案 |
| 2 | `a1-detection-evidence-survey.md` 主表 `/classification-profiles` 四支寫 `evidence.classification.*` | `evidence.classification-profile.read／create／update／delete` | 同份定案 6（拆兩個資源） |
| 3 | 同份主表 `/classification/available-models` 寫 `evidence.classification.read`，同份缺口 3 寫 `ai.ai-provider-config.read` | 跟呼叫頁權限，自動分類頁看 `evidence.classification.read` | 首腦補充 ② |
| 4 | 同份主表 `/integrations/google-drive/projects/<p>/folders` 寫 `evidence.cloud-integration.read` | `grc.project.read` | 同份定案 8（專案頁三支歸 `grc.project`，folders 歸 read） |
| 5 | 同份主表 `/integrations/google-drive/verify-credentials` 寫「隨 storage-config 新名」 | `platform.drive-app-credential.read` | `a1-system-iam.md` 定案 2＋首腦裁示 3 |
| 6 | 同份「儲存設定與檔案」段寫 `<storage-config>.*`、AI 模型下拉寫「見定案」 | 儲存出廠還原兩支＝`system.storage-config.read／update`；AI 模型下拉＝`ai.ai-provider-config.read` | 同份定案 7 |
| 7 | 同份主表 `/devices/menu` 以外的挑選端點（`/detection-tool-profiles/menu`、`/detection-tools/<uid>/param-schema`、`/surveys/menu`、`/remote-agents` GET）寫被挑模組的 read；`a1-grc.md` 主表 `/information-systems/menu` 寫 `asset.information-system.read` | 跟呼叫頁權限，附錄 A 逐支寫出呼叫頁看哪一顆 | 通則 B |
| 8 | `a1-system-iam.md` 主表 `/labels/menu/<scope>` 寫 `platform.feedback.read` | 跟 `workspace.feedback.read` | `a1-platform.md` 定案 3（回饋歸 workspace） |
| 9 | `a1-grc.md` 主表流程定義、階段物件兩支寫「待 T-1.2 定」 | 流程定義依歸屬判（通則 C）；階段物件＝`flow.template.read`，建專案預覽時 `grc.project.create` | `a1-oscal-flow.md` 定案 6、通則 B |
| 10 | `a1-platform.md` 主表 `POST /bulletins` 寫 `workspace.bulletin.read` | 讀者模式 read、管理模式 create，由後端依能力點判 | 同份定案 7 |
| 11 | `a1-system-iam.md` 主表 `GET /system/config/<group>/<key>` 等泛用端點寫 `system.<group 對應資源>.*` | 群組對資源表多登記 `AI_PROVIDER_CONFIG`→`ai.ai-provider-config`、`GOOGLE_DRIVE_APP_CONFIG`→`platform.drive-app-credential` | 同份定案 1、2 |
| 12 | `a1-shipped-roles.json` 三個範例角色寫 `workspace.feedback.*` | 改列四個基本動詞，展開數各少 1 | 首腦補充 ① |

### T-1.6 新查到的缺口

- **單筆意見回饋沒有本人檢查**：`GET /feedback/<uid>`（套件 `jedi_issue/api/routes/feedback_route.py:73`）只要求 `feedback.read` 或 `feedback-view.read` 任一，service `get_feedback`（`jedi_issue/app/feedback/service/feedback_service.py:228`）直接用 uid 查，不比對送件人。只有「送自己回饋」權限的一般成員，帶別人的 uid 就能讀到別人的回饋。`a1-platform.md` 主表標「未逐行核」，此處已核實。建議併入 T-4.6：沒有 `workspace.feedback-review.read` 時只回本人的。

其他已知缺口在各盤點的「確認要補的守門缺口」段，大多已併入 T-4.6（CM-2542）；第一部分備註寫「附錄 D 已知缺口」的，指的是設定類讀取沒守 read（`a1-system-iam.md` 缺口 1）與第三方登入綁定查詢沒本人檢查（同份缺口 2）。

### 待首腦裁（已全部裁定，2026-10-06）

1. **「新」`license_module` 的填值**：照本檔第二部分推導。`evidence-classification`、`ai-assistant` 加進 `INFRASTRUCTURE_MODULES`（`common/authz/license.py`）——今天這兩塊本來就沒有授權照守門，加進去行為不變；`support` 是原廠層不處理。落點 T-2.1。
2. **掃描設定檔分類字典寫入三支**（`/detection-profile-taxonomies*`）：守 `detection.profile.update`＋平台管理員兩道，不新開資源。
3. **出貨範例角色**：決策者裁補第五個「一般成員」（受稽方人員）；稽核員 `grc.job` 列舉 read／update／assign／import／export，`grc.audit` 加 create 不給 delete；三個可改角色不給 `workspace.feedback.export`；稽核主管可發公告、可看 AI 呼叫紀錄與額度。定稿見 `a1-shipped-roles.json`。
4. **`GET /system/config/ai-provider/model-options`**：自動分類頁呼叫時走通則 B 看 `evidence.classification.read`；AI 服務設定頁才看 `ai.ai-provider-config.read`。
5. **`GET /oscal-frameworks/menu`**：走通則 B 看資源庫頁權限（`oscal.resource-library.read／create`），與其他挑選下拉一致。
6. **`iam.role.export`／`iam.role.import`（角色 JSON 匯出匯入，design §6.7）**：新增兩顆，與 ssp／job 的匯出匯入動詞一致；`license_module`＝`role`、直接 enforce；出貨範例角色不給，只有系統管理員 `*.*.*` 拿得到。
7. **`iam.user.assign`、`evidence.classification.execute`（2026-10-07，T-1.7 高優先兩項，落 T-3.8）**：指派是提權入口、送分類花 AI 額度，都與 update 分開授權。`iam.user.assign` 直接 enforce；`evidence.classification.execute` 先只記錄（既有稽核主管 `evidence.*.*` 自動涵蓋）。兩顆都不給出貨範例角色。`PUT /user/<uid>` 只在角色指派與現況不同時才另要 assign——前端存檔整包回送 user_roles，若「帶了就要」，只有 update 的 IT Manager、PM 連改暱稱都會被擋。`evidence.cloud-integration.execute`（Drive 重建）這版不做。

**部門資料隔離（D12）決策者裁示（2026-10-06）**：**這一版不擋任何資料、不改任何 RLS policy、不做隔離開關與預覽頁**——設計（design §6.4）與挑選表清單（`a1-d12-tables.md`）留作下一版輸入。連帶延後：T-3.6 policy migration、T-5.6 隔離設定頁、T-3.8 的預覽與切換 API、T-4.4 的挑選表寫入掛 `require_capability_on`、T-2.3 的 `org_unit_isolation` 開關欄。**不延後**：T-3.5 的 `require_capability_on`（部門範圍判定本身）與 T-2.3 的 `org_units.path` 回填。
