# 盤點 B.1：專案能力點清單定稿

> 唯讀盤點。把專案內每一個「看角色決定能不能做」的地方——後端守門、讀模型 SQL、通知收件人、流程站、前端按鈕——各對到一個 `proj.*` 能力點，作為 T-2.1 seed 與 T-3.x／T-4.x 改碼的對照表。
> 路徑縮寫：`$S` = `.venv/lib/python3.11/site-packages`；`FE` = `compliance-manager-fe/src`。
> 角色縮寫：M＝manager（負責人）、R＝reviewer（審核者）、A＝auditor（稽核員）、V＝viewer（瀏覽者）；「全員」＝四值任一的參與者。
> 查法：**fb**＝走 `get_user_role` 由 control → group → project 往上找第一筆指派；**exact**＝只看專案層 `project_participants.role` 一列。

## 1. 讀法與通則

- **所有「全員可讀」的守門一律對 `proj.project.read`**。每個專案角色都必含它（D1），所以這類守門改完後行為等於「是不是參與者」，非參與者照舊 404。
- **查法欄是改碼時要保留的語意**：fb 的守門改成「往上找第一筆指派 → 展開該角色能力點」（D5）；exact 的守門改成「專案層那一列的角色能力點」。兩種都不可互換——exact 換成 fb 會讓群組層的負責人突然能改專案層設定。
- **「指派人 ∪ 負責人」型守門**（`assert_job_operator`、問卷 writer、偵測操作）保留「是不是被指派人」那條路，只把「負責人可代為操作」那半換成 `proj.job.manage`。任務被指派人在 DEV 有 148 筆是瀏覽者，指派人那條路若改成要能力點，這些人會全部失去自己任務的操作權。
- **流程站**（`main_role`）改存能力點名後，可推進＝持有該站任一 `main_caps`，或持有 `proj.stage.advance-any`；`force` 只認 `proj.stage.advance-any`（D8）。
- 主專案 `common/authz/project.py` 的四支守門是所有守門的實作出口：套件端（jedi_task_platform／jedi_compliance_audit／jedi_survey／jedi_evidence_classification／jedi_detection）經 `core/plugins/*.py` adapter 轉進來，所以套件只改呼叫參數（D9），判定在主專案一處改。

## 2. 表 A：接入點對照

### A.1 判定層出口與換算（T-3.1）

| file:line | 白話動作 | 現行允許角色 | 查法 | 對到的 `proj.*` | 哪張卡改 |
|---|---|---|---|---|---|
| `common/authz/project.py:28` `assert_project_manager` | 「必須是負責人」守門 | M | fb | 改收能力點名參數；呼叫端各自指定（見 A.2～A.6） | T-3.1 CM-2982 |
| `common/authz/project.py:47` `assert_project_role_fallback` | 多角色版守門 | 呼叫端給 | fb | 改收能力點名參數 | T-3.1 CM-2982 |
| `common/authz/project.py:75` `assert_project_role` | 只看專案層的多角色守門 | 呼叫端給，預設 M | exact | 改收能力點名參數 | T-3.1 CM-2982 |
| `common/authz/project.py:118` `assert_project_participant` | 是不是參與者 | 全員 | fb | `proj.project.read` | T-3.1 CM-2982 |
| `common/authz/workflow.py:71` | 以流程實例反查專案後判參與者 | 全員 | fb | `proj.project.read` | T-3.1 CM-2982 |
| `common/authz/ssp.py:96` `require_participant`、`:212` `require_read_access` | SSP 讀 | 全員 | exact | `proj.project.read` | T-3.1 CM-2982 |
| `common/authz/ssp.py:110` `require_manager`、`:232` `require_write_access`（判定在 `:176` `_require_user_is_manager`） | SSP 寫 | M | exact | `proj.ssp.update` | T-3.1 CM-2982 |
| `common/authz/__init__.py:28-35` | 守門決策表軸③ | — | — | 改寫成能力點版 | T-3.1 CM-2982 |
| `$S/jedi_task_platform/participant/app/service/participant_role_service.py:34` `get_user_role` | fb 查角色的唯一實作 | — | fb | 新增 `get_user_project_capabilities`；`get_user_role` 保留做相容 | T-3.1 CM-2982 |
| `$S/jedi_task_platform/participant/app/service/participant_role_service.py:86` `get_reviewers_for_task` | 找某任務的審核者 | R | — | 無呼叫端，見待裁 13 | T-3.1 CM-2982 |
| `core/plugins/compliance_audit.py:85`（exact）、`:92`（fb），預設 `("manager",)` | 稽核套件守門 adapter | 呼叫端給 | exact／fb | 轉發能力點名 | T-3.1 CM-2982 |
| `core/plugins/participant.py:100` `assert_manager`、`:107` `assert_participant` | 參與者套件守門 adapter | M／全員 | fb | `proj.participant.manage`／`proj.project.read` | T-3.1 CM-2982 |
| `core/plugins/evidence_classification.py:88` `is_project_manager` | 證據分類套件「是負責人」 | M | exact | `proj.evidence.manage` | T-3.1 CM-2982 |
| `core/plugins/evidence_classification.py:113` | 證據分類套件「是參與者」 | 全員 | fb | `proj.project.read` | T-3.1 CM-2982 |
| `infra/survey/adapters.py:54`、`:65` | 問卷套件守門 adapter | M／全員 | fb | `proj.job.manage`／`proj.project.read` | T-3.1 CM-2982 |
| `$S/jedi_task_platform/task/api/guards.py:129,142`、`task/common/guard.py:54,66`、`participant/common/guard.py:50,71` | 套件內守門轉發點（只轉交主專案 adapter） | 呼叫端給 | — | 參數改能力點名，判定不在此 | T-3.1 CM-2982 |

### A.2 專案、參與者、任務（T-3.1）

| file:line | 白話動作 | 現行允許角色 | 查法 | 對到的 `proj.*` | 哪張卡改 |
|---|---|---|---|---|---|
| `app/flow_control/service/project_service.py:388` `update_project` | 改專案設定 | M | fb | `proj.project.update` | T-3.1 CM-2982 |
| `app/flow_control/service/project_service.py:590` `delete_project` | 刪專案 | 擁有者 或 M | exact | `proj.project.update`（擁有者放行保留；拆不拆見待裁 4） | T-3.1 CM-2982 |
| `app/flow_control/service/project_service.py:630` `batch_delete_projects` | 批次刪專案 | 擁有者 或 M | exact | 同上 | T-3.1 CM-2982 |
| `app/flow_control/service/project_service.py:464` | 改專案時同步參與者，沒給角色預設瀏覽者 | 預設 V | — | 預設改「租戶最小專案角色」（只含 `proj.project.read`） | T-3.1 CM-2982 |
| `app/flow_control/service/project_read_guard.py:22` | 專案讀取 | 全員 | fb | `proj.project.read` | T-3.1 CM-2982 |
| `app/flow_control/service/participant_org_unit_app_service.py:29` | 參與者組織單位讀 | 全員 | fb | `proj.project.read` | T-3.1 CM-2982 |
| `app/project/service/project_start_app_service.py:133-148` `_add_participants`（`:146` 建立者） | 建專案寫參與者；建立者自動成負責人 | 建立者 M、其他預設 V | — | 建立者寫 `is_default_owner` 角色；其他預設最小角色 | T-3.1 CM-2982 |
| `$S/jedi_task_platform/participant/app/service/project_participant_service.py:96,120,140` | 增／改／刪專案參與者 | M | fb | `proj.participant.manage` | T-3.1 CM-2982 |
| `$S/jedi_task_platform/participant/app/service/project_participant_service.py:49,164` | 參與者列表、下拉 | 全員 | fb | `proj.project.read` | T-3.1 CM-2982 |
| `$S/jedi_task_platform/participant/app/service/project_control_participant_service.py:44,66` | 控制項參與者讀 | 全員 | fb | `proj.project.read` | T-3.1 CM-2982 |
| `$S/jedi_task_platform/participant/app/service/task_assignee_service.py:102,188,224` | 增／改／刪任務指派人 | M | fb | `proj.participant.manage` | T-3.1 CM-2982 |
| `$S/jedi_task_platform/participant/app/service/task_assignee_service.py:88,93` | 指派人讀 | 全員 | fb | `proj.project.read` | T-3.1 CM-2982 |
| `app/flow_control/service/review_step_assign_service.py:95` `_resolve_editable`、`:110` `_apply_skip_reason` | 指派審閱步驟、填略過原因 | M | fb | `proj.participant.manage`（見待裁 7） | T-3.1 CM-2982 |
| `app/flow_control/service/review_step_service.py:148` | 審閱步驟讀 | 全員 | fb | `proj.project.read` | T-3.1 CM-2982 |
| `app/flow_control/service/job_service.py:159` `_require_manager` → `create_job:221`、`update_job:352`、`delete_job:273` | 增／改／刪任務 | M | fb | `proj.job.manage` | T-3.1 CM-2982 |
| `app/flow_control/service/job_service.py:194` `get_job`、`:312` `list_jobs` | 任務讀 | 全員 | fb | `proj.project.read` | T-3.1 CM-2982 |
| `app/flow_control/service/job_import_service.py:96` `_check_manager_role` | 匯入任務 | M | exact | `proj.job.manage` | T-3.1 CM-2982 |
| `app/flow_control/service/job_import_service.py:111` `_assert_plan_in_project` | 匯入前確認計畫屬於本專案 | 全員 | fb | `proj.project.read` | T-3.1 CM-2982 |
| `app/flow_control/service/job_batch_complete_service.py:64` | 批次完成任務（基本門檻） | 全員且是指派人 | fb | `proj.project.read`＋指派人 | T-3.1 CM-2982 |
| `app/flow_control/service/job_batch_complete_service.py:65` | 負責人批次完成不必是指派人 | M | fb | `proj.job.manage`（見待裁 1） | T-3.1 CM-2982 |
| `app/flow_control/service/flow_apply_to_tasks_service.py:195` `_require_source` | 把流程套用到任務 | M | fb | `proj.job.manage` | T-3.1 CM-2982 |
| `app/flow_control/service/workflow_xml_sync_service.py:140,157` `_assert_project_manager_if_owned` | 同步專案擁有的流程 XML | M | fb | `proj.job.manage` | T-3.1 CM-2982 |
| `$S/jedi_task_platform/task/app/service/task_execution_service.py:57` `_check_manager` → `start_task_execution:72` | 啟動任務執行 | M | exact | `proj.job.manage` | T-3.1 CM-2982 |
| `$S/jedi_task_platform/task/app/service/task_execution_service.py:147` `get_prep_job_progress` | 準備任務進度讀 | 全員 | fb | `proj.project.read` | T-3.1 CM-2982 |
| `$S/jedi_task_platform/task/app/service/job_comment_service.py:35` | 任務留言 | 全員（以流程實例判） | fb | `proj.project.read` | T-3.1 CM-2982 |
| `app/task_alert/service/task_alert_notification_app_service.py:42` `list_notifications` | 專案任務提醒列表 | 全員 | fb | `proj.project.read` | T-3.1 CM-2982 |
| `app/task_alert/service/manual_job_due_reminder_service.py:90` `_guard` | 手動寄到期提醒 | M | fb | `proj.job.manage`（見待裁 8） | T-3.1 CM-2982 |
| `app/flow_control/service/drive_sync_admin_service.py:150` `_require_project_manager` | 觸發雲端硬碟同步 | 擁有者 或 M | exact | `proj.project.update` | T-3.1 CM-2982 |
| `app/flow_control/service/drive_project_verify_service.py:160` `_collect_for_verify` | 雲端硬碟同步核對 | 擁有者 或 M | exact | `proj.project.update` | T-3.1 CM-2982 |

### A.3 流程執行（T-3.1／T-3.3）

| file:line | 白話動作 | 現行允許角色 | 查法 | 對到的 `proj.*` | 哪張卡改 |
|---|---|---|---|---|---|
| `app/flow_engine/service/workflow_execution_service.py:137` `assert_project_participant` | 流程實例讀 | 全員 | fb | `proj.project.read` | T-3.1 CM-2982 |
| `app/flow_engine/service/workflow_execution_service.py:148` `assert_job_operator`（實作 `job_operator_guard`） | 任務操作：完成 `complete_job:636`、撤回 `revert_job:812` | 指派人 ∪ M | fb | 指派人 ∪ `proj.job.manage`（見待裁 11） | T-3.1 CM-2982 |
| `app/flow_engine/service/job_evidence_service.py:62,83` | 任務佐證讀 | 全員 | fb | `proj.project.read` | T-3.1 CM-2982 |
| `app/flow_engine/service/job_evidence_service.py:98,165,191` | 任務佐證新增／修改／刪除 | 全員 | fb | 指派人 ∪ `proj.job.manage`（見待裁 6） | T-3.1 CM-2982 |
| `app/flow_engine/service/job_force_start_service.py:62` `inspect` | 強制開始前檢查 | 全員 | fb | `proj.project.read` | T-3.1 CM-2982 |
| `app/flow_engine/service/job_force_start_service.py:69,131` `force_start` | 強制開始任務 | M | fb | `proj.job.manage` | T-3.1 CM-2982 |
| `app/flow_engine/service/stage_advance_service.py:113` `get_current_stage_info` | 目前階段資訊讀 | 全員 | exact | `proj.project.read` | T-3.3 CM-2984 |
| `app/flow_engine/service/stage_advance_service.py:152` `user_can_advance` | 回傳「你能不能推進」給畫面 | 站上 `main_roles` 或 M | exact | `caps & main_caps` 或 `proj.stage.advance-any` | T-3.3 CM-2984 |
| `app/flow_engine/service/stage_advance_service.py:348` `advance_stage` | 推進階段 | 站上 `main_roles` 或 M | exact | `caps & main_caps` 或 `proj.stage.advance-any` | T-3.3 CM-2984 |
| `app/flow_engine/service/stage_advance_service.py:359` | 強制推進（`force`） | M | exact | `proj.stage.advance-any` | T-3.3 CM-2984 |
| `app/flow_engine/service/stage_advance_service.py:672-679` `_resolve_main_roles` | 讀站上 `main_role`（逗號多值） | — | — | `_resolve_main_caps`：舊四值換算、其餘當能力點名 | T-3.3 CM-2984 |
| `app/flow_engine/service/stage_rollback_service.py:99` `rollback_stage` | 退回上一階段 | M | exact | `proj.stage.advance-any` | T-3.3 CM-2984 |

### A.4 稽核：AP／AR／輪次／判定（T-3.1）

| file:line | 白話動作 | 現行允許角色 | 查法 | 對到的 `proj.*` | 哪張卡改 |
|---|---|---|---|---|---|
| `app/flow_control/service/assessment_plan_app_service.py:219,223` `_check_auditor`（經 `resolve_ap_and_check_auditor:174,196`） | AP 寫：審查控制項 `:539`、評估對象 `:551`、AP 成員 `:608`、補稽核員 `:642` | A、M | exact | `proj.audit.judge` | T-3.1 CM-2982 |
| `app/flow_control/service/ap_objectives_app_service.py:89,118` | AP 評估目標寫、加受訪人 | A、M | exact | `proj.audit.judge` | T-3.1 CM-2982 |
| `app/flow_control/service/ap_overview_app_service.py:67` | AP 概要寫 | A、M | exact | `proj.audit.judge` | T-3.1 CM-2982 |
| `app/flow_control/service/ap_workbook_import_service.py:35,60,71` | AP 工作底稿上傳／確認 | A、M | exact | `proj.audit.judge` | T-3.1 CM-2982 |
| `app/flow_control/service/assessment_plan_app_service.py:514` `get_ap_for_round` | AP 讀 | 全員 | fb | `proj.project.read` | T-3.1 CM-2982 |
| `app/flow_control/service/ar_objective_app_service.py:101` `require_writable` → `ar_close_service:32`、`ar_workbook_import_service:34,69` | AR 結案、AR 工作底稿上傳／確認 | A、M | exact | `proj.audit.judge` | T-3.1 CM-2982 |
| `app/flow_control/service/ar_objective_app_service.py:117,158,168,218,234` | AR 評估目標、控制 SSP、證據池、結論、結論草稿讀 | 全員 | fb | `proj.project.read` | T-3.1 CM-2982 |
| `app/flow_control/service/ar_objective_app_service.py:365,367` `assert_project_participant_by_id` | 以四值清單判參與者 | 全員 | exact | `proj.project.read` | T-3.1 CM-2982 |
| `app/flow_control/service/ar_task_context_service.py:33` | AR 評估目標關聯任務讀 | 全員 | fb | `proj.project.read` | T-3.1 CM-2982 |
| `app/flow_control/service/pass_report_export_service.py:85,93` | 單次稽核報告匯出 | 全員 | fb | `proj.project.read` | T-3.1 CM-2982 |
| `$S/jedi_compliance_audit/.../audit_round_app_service.py:138` `_check_role`（M）→ `create_round:255`、`launch_audit:427`、`close_round:531`、`rollback_to_planning:768`、`rollback_to_audit_planning:802`、`rollback_to_auditing:825`、`audit_round_pass_rollback.py:29` | 建輪次、啟動稽核、結束輪次、各段退回 | M | exact | `proj.round.manage`（新增，見待裁 5） | T-3.1 CM-2982 |
| `$S/jedi_compliance_audit/.../audit_round_app_service.py:138`（A、M）→ `start_auditing:462`、`finalize_audit:482`、`launch_reverify:560` | 開始稽核、完成稽核、發起複查 | A、M | exact | `proj.audit.judge` | T-3.1 CM-2982 |
| `$S/jedi_compliance_audit/.../audit_round_app_service.py:235,245,863` | 輪次列表、輪次詳情、階段轉換紀錄讀 | 全員 | exact | `proj.project.read` | T-3.1 CM-2982 |
| `$S/jedi_compliance_audit/.../audit_service.py:28` `_check_role` → `update_verdict:94`、`create_finding:106`、`update_finding:128`、`delete_finding:143` | 稽核判定、發現事項增改刪 | A、M | exact | `proj.audit.judge` | T-3.1 CM-2982 |
| `$S/jedi_compliance_audit/.../assessment_result_app_service.py:114` `_check_auditor` → `resolve_round_for_import:156`、`judge_finding:511`、`create_observation:546`、`update_observation:574`、`delete_observation:605`、`add_risk:677`、`update_risk:739`、`delete_risk:753`、`link_risk_findings:768` | AR 匯入、發現判定、觀察事項、風險增改刪與連結 | A、M | exact | `proj.audit.judge` | T-3.1 CM-2982 |
| `$S/jedi_compliance_audit/.../assessment_result_app_service.py:377,690` | 發現事項、風險列表讀 | 全員 | exact | `proj.project.read` | T-3.1 CM-2982 |
| `$S/jedi_compliance_audit/.../review_service.py:35` `_require_manager` → `mark_control:89`、`unmark_control:103`、`mark_ao:117`、`unmark_ao:132` | 控制項／評估目標標記已審閱與取消 | M、R | fb | `proj.review.approve` | T-3.1 CM-2982 |
| `$S/jedi_compliance_audit/.../guard.py:49` `ANY_PARTICIPANT` | 套件內「任一參與者」常數 | 全員 | — | `proj.project.read` | T-3.1 CM-2982 |
| `core/plugins/_file_ownership.py:176` | 輪次附件寫 | A、M | exact | `proj.audit.judge` | T-3.1 CM-2982 |

### A.5 POA&M、結案報告、專案摘要、證據分類、偵測、問卷（T-3.1）

| file:line | 白話動作 | 現行允許角色 | 查法 | 對到的 `proj.*` | 哪張卡改 |
|---|---|---|---|---|---|
| `app/flow_control/service/poam_objective_app_service.py:90` `_require_writable` | POA&M 評估目標寫 | M | exact | `proj.poam.manage` | T-3.1 CM-2982 |
| `app/flow_control/service/poam_objective_app_service.py:102,237,247` | POA&M 評估目標讀、OSCAL 匯出、計畫讀 | 全員 | fb | `proj.project.read` | T-3.1 CM-2982 |
| `$S/jedi_compliance_audit/.../poam_app_service.py:97` `_check_manager` → `add_remediation:326`、`add_milestone:353`、`update_milestone:368`、`delete_milestone:389`、`delete_remediation:402` | 改善措施、里程碑增改刪 | M | exact | `proj.poam.manage` | T-3.1 CM-2982 |
| `$S/jedi_compliance_audit/.../poam_app_service.py:252,284` | POA&M 項目列表、詳情讀 | 全員 | exact | `proj.project.read` | T-3.1 CM-2982 |
| `app/closing_report/service/closing_report_app_service.py:36` `READ_ROLES`、`:68,73` `require_report` | 結案報告讀、匯出 | M、A | exact | `proj.report.read`（見待裁 3） | T-3.1 CM-2982 |
| `app/closing_report/service/closing_report_writer.py:28` `WRITE_ROLES`、`:91` | 結案報告建立、發布 | M | exact | `proj.report.manage` | T-3.1 CM-2982 |
| `app/project_summary_report/service/project_summary_report_service.py:47` | 專案摘要報告產生與讀 | 全員 | fb | `proj.project.read` | T-3.1 CM-2982 |
| `app/project_summary_report/service/project_summary_report_history_service.py:34,49,60` | 摘要報告歷史讀 | 全員 | fb | `proj.project.read` | T-3.1 CM-2982 |
| `app/project_summary_report/service/project_summary_report_history_service.py:79` | 摘要報告還原到某版 | 全員 | fb | `proj.project.read`（見待裁 9） | T-3.1 CM-2982 |
| `$S/jedi_evidence_classification/.../evidence_batch_service.py:1479` `_require_manager` → `create_batch_for_round:402`、`upload_files:507`、`delete_file:537`、`seal:552`、`archive:562`、`purge:662`、`delete_batch:720`、`put_run_state:834`、`classify:985` | 證據分類批次建立、上傳、刪檔、封存、歸檔、清除、刪批次、執行狀態、分類 | M | exact | `proj.evidence.manage` | T-3.1 CM-2982 |
| `$S/jedi_evidence_classification/.../evidence_batch_service.py:1486` `_require_participant` → `list_batches:426`、`get_batch_detail:455`、`get_run_state:822`、`preview:881`、`validation_report:912`、`adjudication_report:923` | 證據分類批次讀、預覽、驗證與裁決報告 | 全員 | fb | `proj.project.read` | T-3.1 CM-2982 |
| `$S/jedi_evidence_classification/.../evidence_classification_service.py:51` `is_any_project_manager` | 不綁專案的標準答案匯入：在任一專案當負責人即可 | 任一專案 M | exact | 見待裁 10 | T-3.1 CM-2982 |
| `$S/jedi_detection/.../detection_orchestration_service.py` `assert_job_operator` → `start_execution:185`、`cancel_execution:897`、`rerun_assignment:940`、`cancel_assignment:1055`、`cancel_group:1082`、`delete_execution:1139`、`delete_group:1181`、`start_assignment_now:1523` | 偵測任務啟動、取消、重跑、刪除 | 指派人 ∪ M | fb | 指派人 ∪ `proj.job.manage`（見待裁 11） | T-3.1 CM-2982 |
| `$S/jedi_detection/.../detection_orchestration_service.py:1715` `list_executions` | 偵測執行列表 | 全員 | fb | `proj.project.read` | T-3.1 CM-2982 |
| `$S/jedi_survey/.../task_survey_guard.py:57-78` writer → `question_answer` 更新 `:114`、`checkpoint:228`、`patch:388`、`history:82` | 填答、存檔點 | 指派人 ∪ M | fb | 指派人 ∪ `proj.job.manage`（見待裁 11） | T-3.1 CM-2982 |
| `$S/jedi_survey/.../task_survey_guard.py:147` manager → `task_survey_service:126,310,627` | 問卷設定、批次匯入答案 | M | fb | `proj.job.manage` | T-3.1 CM-2982 |
| `$S/jedi_survey/.../task_survey_guard.py:136` reader → `socketio:63`、`survey_discussion:47`、`history:58,71`、`history_detail:35`、`task_survey:82,96,109` | 問卷讀、討論、歷史 | 全員 | fb | `proj.project.read` | T-3.1 CM-2982 |

### A.6 SSP 與檔案歸屬（T-3.1）

SSP 寫入全部經 `common/authz/ssp.py` 的 `require_manager`／`require_write_access`（→ `proj.ssp.update`），讀取經 `require_participant`／`require_read_access`（→ `proj.project.read`）；改 `ssp.py` 一處即全部生效，下表列呼叫端供核對。

| file:line | 白話動作 | 現行允許角色 | 查法 | 對到的 `proj.*` | 哪張卡改 |
|---|---|---|---|---|---|
| `app/oscal/service/ssp_risk_scope_*.py:69`；讀 `:55` | 風險範圍寫／讀 | M／全員 | exact | `proj.ssp.update`／`proj.project.read` | T-3.1 CM-2982 |
| `app/oscal/service/*inventory_items*.py:75,102,128`；讀 `:66` | 資產清冊增改刪／讀 | M／全員 | exact | 同上 | T-3.1 CM-2982 |
| `app/oscal/service/*excel_import*.py:641`；讀 `:651` | SSP Excel 匯入／預覽 | M／全員 | exact | 同上 | T-3.1 CM-2982 |
| `app/oscal/service/*document_pool*.py:65,119,157,164,195,202`；讀 `:59,149,187` | 程序書池、控制項對應、AO 對應增刪／讀 | M／全員 | exact | 同上 | T-3.1 CM-2982 |
| `app/oscal/service/*system_characteristic*.py:54`；讀 `:46` | 系統特性寫／讀 | M／全員 | exact | 同上 | T-3.1 CM-2982 |
| `app/oscal/service/*resources*.py:38,45,51`；讀 `:33` | 參考資源增改刪／讀 | M／全員 | exact | 同上 | T-3.1 CM-2982 |
| `app/oscal/service/*leveraged*.py:75,102,132`；讀 `:67` | 外部授權增改刪／讀 | M／全員 | exact | 同上 | T-3.1 CM-2982 |
| `app/oscal/service/*party*.py:78,99,117`；讀 `:69` | SSP 人員增改刪／讀 | M／全員 | exact | 同上 | T-3.1 CM-2982 |
| `app/oscal/service/*components*.py:71,103,133`；讀 `:60` | 元件增改刪／讀 | M／全員 | exact | 同上 | T-3.1 CM-2982 |
| `app/oscal/service/*control_org_unit*.py:94` `_batch_set`；讀 `:37`（含資源庫讀者） | 控制項負責單位寫／讀 | M／全員 | exact | 同上 | T-3.1 CM-2982 |
| `app/oscal/service/*control_impl_import*.py:399`；讀 `:116,239,359` | 控制項實作匯入確認／匯出、驗證 | M／全員 | exact | 同上 | T-3.1 CM-2982 |
| `app/oscal/service/ssp_docx_import_app_service.py:575`；讀 `:585` | SSP docx 匯入／預覽 | M／全員 | exact | 同上 | T-3.1 CM-2982 |
| `app/oscal/service/ssp_control_implementation_service.py:107,692,710`；讀 `:95,127,188` | 控制項實作與評估目標寫、移除程序書／讀、樹 | M／全員 | exact | 同上 | T-3.1 CM-2982 |
| `app/oscal/service/governance/raci_subject_resolvers.py:92`；讀 `:96` | RACI 主體寫／讀 | M／全員 | exact | 同上 | T-3.1 CM-2982 |
| `api/oscal/__init__.py:102` `create_module` | 建 SSP 模組 | M | exact | `proj.ssp.update` | T-3.1 CM-2982 |
| `app/oscal/service/*ao_evidence_source*.py:88`、`*cra_legal_docs_export*.py:109`、`ssp_export*.py:85`、`app/module_frame/service/*ssp_import_template*.py:279`、`*form_settings*.py:25` | AO 證據來源、CRA 法規文件匯出、SSP 匯出、匯入範本、表單設定讀 | 全員 | exact | `proj.project.read` | T-3.1 CM-2982 |
| `core/plugins/_file_ownership.py:112`；`:115` | SSP 附件刪／讀 | M／全員 | exact | `proj.ssp.update`／`proj.project.read` | T-3.1 CM-2982 |
| `core/plugins/_file_ownership.py:277`；`:279` | 流程任務附件寫／讀 | 指派人 ∪ M／全員 | fb | 指派人 ∪ `proj.job.manage`／`proj.project.read` | T-3.1 CM-2982 |
| `core/plugins/_file_ownership.py:310`（判準說明 `:287-288`） | 證據分類批次檔刪／讀 | M／全員 | exact／fb | `proj.evidence.manage`／`proj.project.read` | T-3.1 CM-2982 |
| `core/plugins/file_upload.py:124,132` | 任務佐證檔刪／讀 | 指派人 ∪ M／全員 | fb | 指派人 ∪ `proj.job.manage`／`proj.project.read` | T-3.1 CM-2982 |
| `core/plugins/file_upload.py:217,219` | 樣板 SSP 附件寫／讀 | M／全員 | exact | `proj.ssp.update`／`proj.project.read` | T-3.1 CM-2982 |

### A.7 字面值、enum、serializer（T-3.1）

| file:line | 白話動作 | 現行值 | 對到的 `proj.*` | 哪張卡改 |
|---|---|---|---|---|
| `api/project/serializers/project.py:26-30` | 建／改專案收參與者角色，預設瀏覽者 | OneOf 四值 | 改收專案角色 uid | T-3.1 CM-2982 |
| `$S/jedi_task_platform/.../serializers/project_participant*.py:17,23` | 參與者 API 收角色 | OneOf 四值 | 改收專案角色 uid | T-3.1 CM-2982 |
| `$S/jedi_task_platform/.../serializers/process_participant*.py:15,20` | 流程參與者 API 收角色 | OneOf 四值 | 改收專案角色 uid | T-3.1 CM-2982 |
| `$S/jedi_compliance_audit/.../serializers/project.py:77` | 稽核套件參與者角色 | OneOf 四值 | 改收專案角色 uid | T-3.1 CM-2982 |
| `app/oscal/service/excel_parser/validators.py:9,39` `VALID_PARTICIPANT_ROLES` | SSP Excel 匯入驗參與者角色欄 | 四值 | 改驗「租戶內專案角色名」 | T-3.1 CM-2982 |
| `common/enum/participant_enum.py`、`$S/jedi_task_platform/.../participant_enum.py:13-14` | 四值 enum（已單一來源） | 四值 | 保留做舊值換算表 | T-3.1 CM-2982 |
| `app/readmodel/service/audit_plan_list_service.py:30-33` | 稽核計畫列表 `can_edit`（規劃中且 A／M）、`needs_assign`（沒 AP 或沒稽核員且 M） | A、M／M | `can_edit`→`proj.audit.judge`；`needs_assign`→見待裁 12 | T-3.1 CM-2982 |
| `app/flow_control/service/project_service.py:678-681` `_notify_project_started` | 專案開始通知信裡的角色標籤 | 四值對中文 | 改顯示專案角色名稱 | T-3.1 CM-2982 |

### A.8 讀模型 SQL（T-3.2）

全部直接比對 `project_participants.role`（exact）；改為 `project_role_id = ANY(:role_ids)`，`role_ids` 由「本租戶含能力點 X 的專案角色」helper 算出。

| file:line | 白話用途 | 現行條件 | 對到的 `proj.*` | 哪張卡改 |
|---|---|---|---|---|
| `infra/readmodel/tasks/job_due_reminder_query.py:55` | 到期提醒收件人（指派人＋負責人） | M | 指派人 ∪ `proj.job.manage` | T-3.2 CM-2983 |
| `infra/readmodel/tasks/job_batch_complete_query.py:239` | 批次完成「請審閱」信收件人 | M、R | `proj.review.approve` | T-3.2 CM-2983 |
| `infra/readmodel/detection/detection_job_notify_query.py:156` | 偵測完成／失敗通知收件人（另加指派人） | M、R | 指派人 ∪ `proj.review.approve` ∪ `proj.job.manage`（見待裁 14） | T-3.2 CM-2983 |
| `infra/readmodel/detection/support_end_query.py:52` | 系統版本支援終止提醒收件人 | M | `proj.project.update` | T-3.2 CM-2983 |
| `infra/readmodel/audit/auditor_dashboard_query.py:60` | 「我的稽核」列表範圍 | A、M | `proj.audit.judge` | T-3.2 CM-2983 |
| `infra/readmodel/audit/auditor_dashboard_query.py:157` | 列表上顯示的稽核員名字 | A | `proj.audit.judge`（見待裁 15） | T-3.2 CM-2983 |
| `infra/readmodel/audit/poam_dashboard_query.py:61` | 「我的 POA&M」列表範圍 | M | `proj.poam.manage` | T-3.2 CM-2983 |
| `infra/readmodel/audit/audit_plan_list_query.py:47` | 稽核計畫列表「我參與的」 | A、M、R | `proj.audit.judge` ∪ `proj.review.approve` | T-3.2 CM-2983 |
| `infra/readmodel/audit/audit_plan_list_query.py:53` | 列表顯示負責人名字 | M | 預設負責人角色（見待裁 15） | T-3.2 CM-2983 |
| `infra/readmodel/audit/audit_plan_list_query.py:196` | 待處理件數 | A、M | `proj.audit.judge` | T-3.2 CM-2983 |
| `infra/readmodel/audit/audit_plan_list_query.py:310` `_managers_by_project` | 每專案負責人帳號清單 | M | 預設負責人角色（見待裁 15） | T-3.2 CM-2983 |
| `infra/readmodel/audit/closing_report_list_query.py:27` | 結案報告列表「我參與的」 | A、M | `proj.report.read` | T-3.2 CM-2983 |
| `infra/readmodel/audit/closing_report_list_query.py:32` | 列表顯示負責人名字 | M | 預設負責人角色（見待裁 15） | T-3.2 CM-2983 |

### A.9 通知收件人與流程站（T-3.2／T-3.3）

| file:line | 白話用途 | 現行規則 | 對到的 `proj.*` | 哪張卡改 |
|---|---|---|---|---|
| `app/flow_engine/service/stage_entered_recipients.py` `resolve_stage_recipients` | 進入新階段通知收件人 | 負責人永遠收；站上 `main_roles` 的參與者收（稽核員再依 `audit_scope` 過濾）；沒有任何主責人時負責人收「未指派」 | `main_caps` 任一持有者（`audit_scope` 只套在持 `proj.audit.judge` 者）∪ `proj.stage.advance-any`；沒有主責人時 `advance-any` 持有者收「未指派」 | T-3.2 CM-2983 |
| `app/flow_engine/service/stage_entered_notify_service.py:44-55` | 寄出進站通知 | 呼叫上一列 | 同上 | T-3.3 CM-2984 |
| `$S/jedi_detection/.../detection_orchestration_service.py:1594` `on_scan_failed` | 偵測失敗通知（與成功同一組收件人） | 指派人 ∪ M、R | 同 A.8 偵測那列 | T-3.2 CM-2983 |
| `compliance.stage_objects.default_main_roles` `planning` | 規劃站 | manager | `proj.stage.advance-any` | T-2.2 CM-2981 |
| 同上 `ap_authoring` | AP 撰寫站 | auditor | `proj.audit.judge` | T-2.2 CM-2981 |
| 同上 `task_execution` | 任務執行站 | manager | `proj.stage.advance-any` | T-2.2 CM-2981 |
| 同上 `review` | 審閱站 | reviewer | `proj.review.approve` | T-2.2 CM-2981 |
| 同上 `audit` | 稽核站 | auditor | `proj.audit.judge` | T-2.2 CM-2981 |
| 同上 `poam` | 改善站 | manager | `proj.stage.advance-any` | T-2.2 CM-2981 |
| `compliance.flow_templates.bpmn_xml` 的 `main_role`（DEV：auditor 20、reviewer 11、manager 44） | 設計器範本各站主責 | 舊四值 | 同上換算 | T-2.2 CM-2981 |
| `compliance.workflow_templates.xml`（DEV：auditor 14、manager 12） | 已開跑的流程快照 | 舊四值 | 不改資料，讀取時由 `_resolve_main_caps` 換算 | T-3.3 CM-2984 |

### A.10 前端：角色頁與參與者選擇（T-4.1／T-4.2）

| file:line | 白話動作 | 現行判斷 | 對到的 `proj.*` | 哪張卡改 |
|---|---|---|---|---|
| `FE/components/grc/ParticipantPicker.vue:93,103-106,161-162,173` | 參與者角色下拉四個寫死選項 | 四值 | 讀 `GET /project-roles` | T-4.2 CM-2987 |
| `FE/components/grc/ParticipantPicker.vue:178,185` | `audit_scope` 欄只對稽核員顯示 | `role === 'auditor'` | 角色含 `proj.audit.judge` 才顯示 | T-4.2 CM-2987 |
| `FE/composables/useParticipantAuditScopeOptions.js:29` | 稽核範圍選項 | `role === 'auditor'` | 同上 | T-4.2 CM-2987 |
| `FE/components/grc/project/ProjectParticipantsPanel.vue:57` | 新增參與者預設瀏覽者 | 預設 V | 預設最小專案角色 | T-4.2 CM-2987 |
| `FE/components/grc/project/ProjectParticipantsPanel.vue:75` | 至少要有一位負責人才能存 | 有 M | 至少一位持 `proj.participant.manage` | T-4.2 CM-2987 |
| `FE/views/project/ProjectCreateView.vue:177,489-490` | 建專案時建立者為負責人、角色下拉 | `'manager'`、四值 | 預設負責人角色、讀 `GET /project-roles` | T-4.2 CM-2987 |
| 角色頁（新） | 專案角色列表、詳情、勾能力點 | — | 表 B 全部 | T-4.1 CM-2986 |

### A.11 前端：專案內按鈕（T-4.2）

| file:line | 白話動作 | 現行判斷 | 對到的 `proj.*` | 哪張卡改 |
|---|---|---|---|---|
| `FE/composables/useSurveyParticipantRole.js:12-20` `resolveSurveyRole`、`isProjectManagerOf` | 問卷頁判誰能填、誰能設定 | `p.role === 'manager'` | 指派人 ∪ `proj.job.manage` | T-4.2 CM-2987 |
| `FE/views/survey-v2/SurveyPreview.vue:348-372,508,565-575` | 問卷填答／核對按鈕 | 由上一列得角色 | 同上 | T-4.2 CM-2987 |
| `FE/views/survey-v2/SurveyPreview.vue:1297` | 審核者看不到歷史 | 角色為 R | `proj.project.read`（見待裁 16） | T-4.2 CM-2987 |
| `FE/composables/useApPlan.js:50` `isWriter` | AP 編輯頁唯讀與否 | A、M | `proj.audit.judge` | T-4.2 CM-2987 |
| `FE/composables/useArResult.js:69` `isWriter` | AR 結果頁唯讀與否 | A、M | `proj.audit.judge` | T-4.2 CM-2987 |
| `FE/composables/usePoamPlan.js:57-62` `isManager` | POA&M 頁唯讀與否 | M | `proj.poam.manage` | T-4.2 CM-2987 |
| `FE/components/grc/JobExecutionDrawer.vue:215,1582` | 任務抽屜強制開始、改期限（吃呼叫頁算好的 `canForceStart`） | M | 指派人 ∪ `proj.job.manage` | T-4.2 CM-2987 |
| `FE/components/grc/FlowPhaseBanner.vue:255` `isManager`；`:37` | 階段列「退回」按鈕 | M | `proj.stage.advance-any` | T-4.2 CM-2987 |
| `FE/components/grc/FlowPhaseBanner.vue:501` | 階段主責角色標籤 | 四值 i18n | 能力點 display_name | T-4.2 CM-2987 |
| `FE/components/grc/ssp/SspTabPanel.vue:97,105` | SSP 各區塊可編輯 | M | `proj.ssp.update` | T-4.2 CM-2987 |
| `FE/views/project/ProjectSettingsView.vue:54` | 專案設定頁可編輯 | M | `proj.project.update` | T-4.2 CM-2987 |
| `FE/views/project/ProjectListView.vue:93-97,366` | 列表「雲端同步」 | 擁有者 或 M，加 `v-can CAP.GRC_PROJECT_UPDATE` | `proj.project.update`（租戶 `v-can` 見待裁 17） | T-4.2 CM-2987 |
| `FE/views/project/ProjectListView.vue:372` | 列表「編輯」 | 同上 | `proj.project.update` | T-4.2 CM-2987 |
| `FE/views/project/ProjectListView.vue:377` | 列表「刪除」 | 擁有者 或 M，加 `v-can CAP.GRC_PROJECT_DELETE` | `proj.project.update`（見待裁 4） | T-4.2 CM-2987 |
| `FE/views/project/ProjectPlanningView.vue:450-453,461` `isProjectManager` | 規劃頁「是負責人」 | M | 拆成下面各按鈕的能力點 | T-4.2 CM-2987 |
| `FE/views/project/ProjectPlanningView.vue:796-799` `canEditCtrl` | 控制項層可編輯（含群組／控制項層負責人） | M（fb） | `proj.job.manage` | T-4.2 CM-2987 |
| `FE/views/project/ProjectPlanningView.vue:812-818` `canEdit` | 規劃頁可編輯 | M | `proj.job.manage` | T-4.2 CM-2987 |
| `FE/views/project/ProjectPlanningView.vue:1968` | 「指派」按鈕 | M | `proj.participant.manage` | T-4.2 CM-2987 |
| `FE/views/project/ProjectPlanningView.vue:2393` `can-force-start` | 「強制開始」 | M | `proj.job.manage` | T-4.2 CM-2987 |
| `FE/views/project/ProjectPlanningView.vue:2430,2441,2457` `can-edit` | 子元件可編輯 | M | `proj.job.manage` | T-4.2 CM-2987 |
| `FE/views/project/ProjectAuditorOverview.vue:187-191` `isProjectManager`、`:195-199` `isAuditor` | 稽核總覽角色判斷 | M／A | 拆成下面各按鈕的能力點 | T-4.2 CM-2987 |
| `FE/views/project/ProjectAuditorOverview.vue:210-213` `canEditApAuthoring` | AP 撰寫可編輯 | A、M | `proj.audit.judge` | T-4.2 CM-2987 |
| `FE/views/project/ProjectAuditorOverview.vue:224,232-234` `hasReviewRole`、`canReviewControl` | 標記已審閱 | M、R | `proj.review.approve` | T-4.2 CM-2987 |
| `FE/views/project/ProjectAuditorOverview.vue:1118` | 「指派稽核員」 | M | `proj.participant.manage` | T-4.2 CM-2987 |
| `FE/views/project/ProjectAuditorOverview.vue:1128` | 「自動分類證據」 | M | `proj.evidence.manage` | T-4.2 CM-2987 |
| `FE/views/project/ProjectAuditorOverview.vue:1141` | 「進入規劃頁」 | M | `proj.job.manage` | T-4.2 CM-2987 |
| `FE/views/project/ProjectAuditorOverview.vue:1147` | 「寄到期提醒」 | M | `proj.job.manage` | T-4.2 CM-2987 |
| `FE/views/project/ProjectAuditorOverview.vue:1170` | 「開始稽核」 | A、M | `proj.audit.judge` | T-4.2 CM-2987 |
| `FE/views/project/ProjectAuditorOverview.vue:1181` | 「進入 POA&M」 | M | `proj.poam.manage` | T-4.2 CM-2987 |
| `FE/views/project/ProjectAuditorOverview.vue:1338-1339` | 參與者角色標籤 | 四值 i18n | 專案角色名稱 | T-4.2 CM-2987 |
| `FE/views/project/ProjectAuditorOverview.vue:2065` `can-force-start` | 「強制開始」 | M | `proj.job.manage` | T-4.2 CM-2987 |
| `FE/views/project/MyTasksView.vue:229-254` `isReviewer`、`isProjectManager` | 我的任務角色判斷 | R／M | 拆成下兩列 | T-4.2 CM-2987 |
| `FE/views/project/MyTasksView.vue:601` `canReturn` | 「退回」任務 | M、R | `proj.review.approve` | T-4.2 CM-2987 |
| `FE/views/project/MyTasksView.vue:602` `canForceStart` | 「強制開始」 | M | `proj.job.manage` | T-4.2 CM-2987 |
| `FE/views/project/ProjectApListView.vue:36-43,211` | 手動建輪次（`ALLOW_MANUAL_ROUND_CREATE=false`，另掛 `v-can GRC_AUDIT_CREATE`） | M | `proj.round.manage` | T-4.2 CM-2987 |
| `FE/views/project/ProjectApListView.vue:283` | 「發起複查」 | A、M | `proj.audit.judge` | T-4.2 CM-2987 |
| `FE/views/evidence-classification/AutoClassifyBatch.vue:96-103,500` | 批次頁操作按鈕 | M | `proj.evidence.manage` | T-4.2 CM-2987 |
| `FE/views/evidence-classification/AutoClassifyList.vue:62-66,144,296,361,462` | 批次列表建立／刪除／歸檔 | M | `proj.evidence.manage` | T-4.2 CM-2987 |
| `FE/views/workflow/WorkflowSetupEditor.vue:93-97,503` `isProjectLevelManager` | 流程設定編輯（另掛租戶 `v-can requiredCap`） | M（專案層） | `proj.job.manage` | T-4.2 CM-2987 |

### A.12 前端：流程編輯器（T-4.3）

| file:line | 白話動作 | 現行判斷 | 對到的 `proj.*` | 哪張卡改 |
|---|---|---|---|---|
| `FE/views/flow-template/FlowTemplateEditorView.vue:130-132` `roleOptions` | 站「主要角色」下拉 | 四值 | 下拉列 `proj.*`（建議只列表 B「可當流程站」欄打勾者） | T-4.3 CM-2988 |
| `FE/views/flow-template/FlowTemplateEditorView.vue:376-389,594`、`FlowTemplatePreviewDialog.vue` | 存檔驗證、預覽顯示主要角色 | 四值 | 驗能力點名、顯示 display_name | T-4.3 CM-2988 |
| `app/flow_control/service/workflow_xml_sync_service.py` 存檔驗證 | 後端存流程範本時驗 `main_role` | 無驗證 | 每個值必須在 `proj.*` 清單內，舊四值拒收 | T-4.3 CM-2988 |

## 3. 表 B：能力點定稿

| # | name | display_name | 白話 | 可當流程站 | 負責人 | 審核者 | 稽核員 | 瀏覽者 | 備註 |
|---|---|---|---|---|---|---|---|---|---|
| 1 | `proj.project.read` | `capability.proj.project.read` | 看專案內所有內容、下載匯出 | | ✓ | ✓ | ✓ | ✓ | 所有專案角色必含 |
| 2 | `proj.project.update` | `capability.proj.project.update` | 改專案設定、刪專案、雲端硬碟同步、收支援終止提醒 | | ✓ | | | | 刪除是否拆出見待裁 4 |
| 3 | `proj.participant.manage` | `capability.proj.participant.manage` | 增刪參與者、指派任務與審閱步驟 | | ✓ | | | | 舊 manager 守門語意的換算目標 |
| 4 | `proj.job.execute` | `capability.proj.job.execute` | 執行任務、上傳佐證、填答 | | ✓ | | | | 目前找不到需要它的接入點，見待裁 2 |
| 5 | `proj.job.manage` | `capability.proj.job.manage` | 增刪改任務、匯入任務、套用流程、強制開始、啟動執行、代被指派人操作、問卷設定、寄到期提醒 | | ✓ | | | | |
| 6 | `proj.review.approve` | `capability.proj.review.approve` | 標記已審閱、退回、收「請審閱」通知 | ✓ | ✓ | ✓ | | | reviewer 換算目標 |
| 7 | `proj.audit.judge` | `capability.proj.audit.judge` | AP 撰寫、稽核判定、發現與觀察事項、風險、開始／完成稽核、發起複查 | ✓ | ✓ | | ✓ | | auditor 換算目標；`audit_scope` 只套在此 |
| 8 | `proj.stage.advance` | `capability.proj.stage.advance` | 推進自己負責的階段 | | ✓ | ✓ | ✓ | | 判定改看站上 `main_caps` 後沒有接入點，見待裁 1 |
| 9 | `proj.stage.advance-any` | `capability.proj.stage.advance-any` | 推進任何階段、強制推進、退回上一階段、收「未指派」進站通知 | ✓ | ✓ | | | | 舊 manager 流程語意的換算目標 |
| 10 | `proj.round.manage` | `capability.proj.round.manage` | 建立輪次、啟動稽核、結束輪次、各段退回 | | ✓ | | | | **新增**，見待裁 5 |
| 11 | `proj.poam.manage` | `capability.proj.poam.manage` | 改善計畫、改善措施、里程碑建立與結案 | | ✓ | | | | |
| 12 | `proj.report.read` | `capability.proj.report.read` | 看結案報告、匯出 | | ✓ | | ✓ | | 見待裁 3 |
| 13 | `proj.report.manage` | `capability.proj.report.manage` | 建立與發布結案報告 | | ✓ | | | | |
| 14 | `proj.evidence.manage` | `capability.proj.evidence.manage` | 證據分類批次建立、上傳、分類、封存、歸檔、刪除 | | ✓ | | | | |
| 15 | `proj.ssp.update` | `capability.proj.ssp.update` | SSP 各區塊寫入、SSP 附件刪除、建 SSP 模組 | | ✓ | | | | |

**合併判斷**：只在「沒有合理的自訂角色會把兩者拆開」時合併。表中只有負責人打勾的九個能力點在範例角色裡總是同時出現，但各自對應客戶常見的分工（例如只管 SSP 的顧問、只管證據分類的助理），因此不合併。唯一符合合併條件的是 `proj.stage.advance` 與 `proj.job.execute`——兩者都沒有實際接入點，處理方式見待裁 1、2，而非併入別的能力點。

**定稿數量**：設計稿 14 個＋新增 1 個（`proj.round.manage`）＝15 個；若待裁 1、2 都裁「刪」則為 13 個。

**可當流程站**：流程編輯器下拉建議只列打勾的三個（`proj.review.approve`／`proj.audit.judge`／`proj.stage.advance-any`），它們恰好是舊四值換算後會出現在站上的值；列全部 15 個會讓設計者選到「看專案」當主責，導致所有參與者都能推進。

## 4. 表 C：通知與待辦收件規則

| 通知／待辦 | 出處 | 收件人（新規則） |
|---|---|---|
| 進入新階段 | `stage_entered_recipients.py`、`stage_entered_notify_service.py:44-55` | 有該站 `main_caps` 任一的參與者（持 `proj.audit.judge` 者再依 `audit_scope` 過濾）＋有 `proj.stage.advance-any` 的參與者；站上沒有任何主責人時，有 `proj.stage.advance-any` 的參與者收「未指派」 |
| 批次完成「請審閱」 | `job_batch_complete_query.py:239` | 有 `proj.review.approve` 的參與者 |
| 偵測完成 | `detection_job_notify_query.py:156` | 被指派人＋有 `proj.review.approve` 或 `proj.job.manage` 的參與者 |
| 偵測失敗 | `detection_orchestration_service.py:1594` | 同偵測完成 |
| 任務到期提醒（排程與手動） | `job_due_reminder_query.py:55` | 被指派人＋有 `proj.job.manage` 的參與者 |
| 系統版本支援終止 | `support_end_query.py:52` | 有 `proj.project.update` 的參與者 |
| 專案開始 | `project_service.py:678` `_notify_project_started` | 收件人不變（全體參與者），信中角色欄改顯示專案角色名稱 |
| 我的稽核待辦 | `auditor_dashboard_query.py:60`、`audit_plan_list_query.py:47,196` | 有 `proj.audit.judge` 的參與者（稽核計畫列表另含 `proj.review.approve`） |
| 我的 POA&M 待辦 | `poam_dashboard_query.py:61` | 有 `proj.poam.manage` 的參與者 |
| 結案報告列表 | `closing_report_list_query.py:27` | 有 `proj.report.read` 的參與者 |
| 列表顯示的「負責人」名字 | `audit_plan_list_query.py:53,310`、`closing_report_list_query.py:32` | 角色為租戶預設負責人（`is_default_owner`）的參與者 |
| 列表顯示的「稽核員」名字 | `auditor_dashboard_query.py:157` | 有 `proj.audit.judge` 且不是預設負責人的參與者 |

## 5. 待決策者裁

每項格式：問題 → 建議 → 理由。

1. **`proj.stage.advance` 沒有接入點**
   - 問題：推進判定改成「持有站上 `main_caps` 任一」後，`proj.stage.advance` 沒有任何守門或畫面會讀它。
   - 建議：從清單拿掉。
   - 理由：留著會讓管理員以為勾了它就能推進，實際沒效果；能推進哪一站由站上指定的能力點決定。
2. **`proj.job.execute` 怎麼用**
   - 問題：現在「誰能操作某任務」看的是「是不是被指派人」，與角色無關；DEV 有 148 筆指派落在瀏覽者身上。若改成「被指派人且持 `proj.job.execute`」，這些人會失去自己任務的操作權；若不接，它就沒有接入點。
   - 建議：從清單拿掉，任務操作維持「被指派人 ∪ `proj.job.manage`」。
   - 理由：指派本身已是「這件事交給你」的授權，再疊能力點只會讓「指派了卻不能做」的組合出現。
3. **結案報告讀要不要獨立能力點**
   - 問題：`proj.report.read` 在範例角色與 `proj.audit.judge` 同一組人。
   - 建議：保留獨立。
   - 理由：客戶常要讓高階主管只看結案報告、不碰稽核判定。
4. **刪專案要不要從 `proj.project.update` 拆出**
   - 問題：現在刪專案與改設定同一批人（擁有者或負責人）；前端刪除鈕另掛租戶 `GRC_PROJECT_DELETE`。
   - 建議：不拆，專案層用 `proj.project.update`，刪除的額外門檻交給租戶 `GRC_PROJECT_DELETE`。
   - 理由：刪除已有租戶層把關，專案層再拆一個能力點只增加勾選負擔。
5. **輪次生命週期用新能力點還是併入 `proj.stage.advance-any`**
   - 問題：建輪次、啟動稽核、結束輪次、各段退回目前只認負責人，設計稿 14 個裡沒有對應。
   - 建議：新增 `proj.round.manage`。
   - 理由：`advance-any` 是「流程站推進」，輪次是「稽核週期開關」，兩者在套件裡是不同的服務；併在一起會讓想給「流程推進員」權限的人順帶能結束整個稽核輪次。
6. **任務佐證新增／修改／刪除目前任一參與者都能做**
   - 問題：`job_evidence_service.py:98,165,191` 只驗參與者，瀏覽者也能改別人任務的佐證；檔案刪除那條（`file_upload.py:124`）卻已是「被指派人 ∪ 負責人」。
   - 建議：統一成「被指派人 ∪ `proj.job.manage`」。
   - 理由：同一份佐證兩條路徑判準不同，是現存的權限破口，趁這次統一。
7. **指派審閱步驟歸哪個能力點**
   - 問題：`review_step_assign_service.py:95,110` 現在是負責人。
   - 建議：`proj.participant.manage`。
   - 理由：動作本質是「把人放到某個位置」，與指派任務同類。
8. **手動寄到期提醒歸哪個能力點**
   - 問題：`manual_job_due_reminder_service.py:90` 現在是負責人。
   - 建議：`proj.job.manage`。
   - 理由：催任務屬於任務管理，與排程提醒收件人一致。
9. **摘要報告「還原到某版」目前任一參與者都能做**
   - 問題：`project_summary_report_history_service.py:79` 是寫入動作但只驗參與者。
   - 建議：改要 `proj.report.manage`。
   - 理由：唯讀成員不應能改報告內容；若要維持現狀則對 `proj.project.read`。
10. **不綁專案的標準答案匯入**
    - 問題：`evidence_classification_service.py:51` 判「在任一專案當負責人」，沒有專案可展開專案能力點。
    - 建議：改用租戶層能力點（`grc.*` 下既有的證據分類管理權）。
    - 理由：D4 規定 `proj.*` 只在專案內有意義，跨專案判斷屬租戶層。
11. **「被指派人 ∪ 負責人」中負責人那半**
    - 問題：任務操作、問卷填答、偵測操作都允許負責人代被指派人操作。
    - 建議：換成 `proj.job.manage`，被指派人那條路不動。
    - 理由：見通則第三點。
12. **稽核計畫列表 `needs_assign` 誰會看到「待指派」**
    - 問題：`audit_plan_list_service.py:30-33` 現在只對負責人亮「需指派稽核員」。
    - 建議：`proj.participant.manage`。
    - 理由：提示的是「請去指派人」，能指派的人才需要看到。
13. **`get_reviewers_for_task` 沒有呼叫端**
    - 問題：`participant_role_service.py:86` 依 reviewer 找人，但整個 codebase 沒人呼叫。
    - 建議：T-3.1 刪除。
    - 理由：改成能力點版只是維護一支沒人用的函式。
14. **偵測通知要不要寄給審核者**
    - 問題：偵測完成與失敗目前都寄負責人＋審核者＋被指派人。
    - 建議：維持，對 `proj.review.approve` ∪ `proj.job.manage` ∪ 被指派人。
    - 理由：維持現行收件範圍，避免升級後有人突然收不到。
15. **列表上「負責人／稽核員名字」欄跟哪個條件**
    - 問題：這些欄位是顯示用，不是授權；改成「持 `proj.participant.manage`」會把自訂的「副負責人」也列進去。
    - 建議：負責人欄跟 `is_default_owner` 角色，稽核員欄跟 `proj.audit.judge`（排除預設負責人）。
    - 理由：顯示的是「這個專案誰掛名負責」，與預設負責人的概念一致。
16. **問卷歷史對審核者隱藏**
    - 問題：`SurveyPreview.vue:1297` 審核者看不到填答歷史，其他角色都看得到；後端歷史讀取對全員開放。
    - 建議：移除這個前端特例，歷史跟 `proj.project.read`。
    - 理由：後端沒擋，前端藏只是爛體驗；若是刻意不讓審核者看到修改軌跡，需另開能力點並讓後端一起擋。
17. **租戶層 `v-can` 與專案層判斷並存**
    - 問題：專案列表的編輯／刪除／同步、手動建輪次、流程設定編輯，前端同時掛租戶 `v-can`（`GRC_PROJECT_UPDATE`／`GRC_PROJECT_DELETE`／`GRC_AUDIT_CREATE`／`requiredCap`）與專案角色判斷。
    - 建議：兩層都保留，專案層換成 `v-can-project`。
    - 理由：租戶層管「這個功能你的公司給不給你用」，專案層管「這個專案你是什麼角色」，兩者語意不同，拿掉任一層都會放寬權限。
