# FR-048 Phase 2b 交接 prompt（照矩陣補資源層守門・軸③）

> 下面整段是給執行 session 的 prompt。**前置：Phase 1 已 merge、Phase 2a 矩陣已產出且 user 已定調**——缺任一就停下回報，不要自己往下做。

---

【接手主題】FR-048 統一授權守門 Phase 2b — 照端點授權矩陣補**專案域（軸③）**守門

必讀（照順序）：
1. `docs/features/FR-048-2607-unified-auth-guard/endpoint-authz-matrix.md`（工作清單＝矩陣中軸③且 Phase=2b 的列；**只做 user 已定調的列**，「需 user 定調」的跳過）
2. `docs/analysis/2026-07-07-unified-auth-guard-design.md` §2 軸模型、§5.1 補法、§7 Phase 2b 注意事項
3. `common/authz/__init__.py` 決策表（Phase 1 產物）

【branch】fix/v1.8.0-bugs，禁止切 branch。

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
【每條的做法（三步，全在 app service 層）】

1. 找到該端點的 app service 寫入 method。
2. method 開頭加守門（**一律從 `common.authz` 新路徑 import**，不用舊 shim 路徑）：
   - 有 project_id 維度 → `assert_project_manager(role_service, project_id, ...)`（需要 role_service 就走 DI `__init__` 注入＋container wiring，不要在 method 內自建）
   - ssp_uid 維度 → `SspPermissionChecker.require_write_access(ssp_uid)`（AP 狀態前置一起帶到）
   - 角色要求照矩陣該列（manager-only vs 任一參與者），**不要自己升降級**
3. 補單測：非 manager（或非參與者）打 → 403 對應 error code；manager 照舊通過。測試放 `test/`，注意 app service 測試要 patch logger（DBLogHandler 對 SessionLocal=None 會炸，見 memory 慣例）。

【順手項（矩陣 §4 A 類）】已用 canonical 守門的模組（participant/SSP/framework），把 import 從舊 shim 路徑換成 `common.authz`，零行為變更。
【不要動（矩陣 §4 B 類）】audit-round 家族 7 份私有 `_check_role`/`_check_manager`/`_check_auditor` **本波不收編**——那是 Phase 2c 的事（泛化 assert_project_role 後委派），現在動純屬回歸風險。

【鐵則】
- 守門放 service 層，**不掛 route decorator**（那是 Phase 3 主體層的事）。
- 該 method 必須已在 `@transaction` scope（guard 需要 session）；沒有就照 CLAUDE.md DB Transaction 規範補。
- 不動 jedi-* 套件。
- 逐列銷帳：每完成一列，矩陣該列狀態改「已修待驗」＋ commit hash。

【flow_engine 守門復活（本 phase 壓軸，量大可拆下個 session）】
`common/authz/workflow.py` 的 `assert_workflow_project_participant` 目前函式開頭 `return`（FR-038 v2 暫拔）。要用 v2 鏈重建反查：workflow_execution → 輪次/SSP → project（v1 的 AP-task mapping 已 dark，不能用）。參考 memory：v2 job→輪次反查走 `task_assignees.project_id`，別比對 workflow_execution_uid。判定邏輯不變（任一參與者放行、fail-closed、admin 放行）——**它是軸③的第三個解析器，不准另立新軸**。改完移除開頭 `return`、補測試。

【驗收】
- `pytest test/` 全綠
- 矩陣 2b 列全數「已修待驗」（或明列哪些留待下 session＋原因）
- 給 user 手測 checklist：挑 3-5 支代表端點（跨模組），用非 manager 帳號打寫入 API 應 403

【commit】按模組分批 commit（顯式 add、禁 -am、不 push），message 格式：`fix(FR-048): <模組> 寫入端點補專案角色守門（軸③）`。收尾等 user 下令。
