本卡屬 FR-095(母卡見本 arc README front matter),第 2 棒 H1:專案 CRUD+成員同步+接線(plugin/DI)(BE repo)。只掃不修。
主專案這一側怎麼「把任務平台套件接進來」:給它什麼守門函式、什麼身分查詢、哪些服務在 DI 容器(就是「程式啟動時把各個服務組裝起來」的那份清單)裡組裝、專案的新增/修改/啟動時怎麼同步成員、以及哪些成員查詢被申報給 AI 儀表板。共 34 檔。只找問題、不修問題。
套件那一半的守門全是「宿主有給我守門函式我才檢查」——所以「套件到底拿到什麼守門、什麼身分」的唯一答案在宿主的 core/plugins/ 與 di_containers/,這兩處漏一條線,套件側再嚴謹也是空的。首腦已核對到一支服務漏注入、四處主動繞過守門、七支查詢直接曝給 AI 儀表板。
這些是首腦讀過程式碼後認為最容易出事的地方,是思考起點不是檢查清單。每條後面的「首腦核對」是首腦親自開檔的結果——✅ 屬實的不必重做核對,直接當錨點追下去;標「待 runner 核對」的才要你自己開檔確認。工具沒答的自己開檔查了再寫,標明「(工具未報,人工查證)」:
di_containers/flow_engine/project_participant_containers.py:113-117 建 ProjectGroupParticipantService 時只傳 user_service 與 domain service,沒傳 participant_role_service;套件那支服務的守門寫法是「有注入才檢查」。為什麼可疑:不報錯、不留 log,寫入端點若日後掛上 route 就是零守門。首腦核對:✅ 屬實(DI 建構式沒傳;套件檔 grep 零守門)。要追:同檔其他五支有沒有全部傳到、還有沒有別的容器(task_assignee_containers.py、flow_control_containers.py)也建了同款服務卻沒傳。di_containers/dashboard_apis/participant.py:19-64 申報 participant.get_project_participants/get_process_participants/get_task_assignees 等,parameters=[PARAM_KWARGS]、optional_params 只有 project_id/user_id。為什麼可疑:AI 儀表板那條路已證實 27 支零守門(FR-083 D2)、**kwargs 會讓租戶過濾被默默丟掉(FR-079 F13)——這裡是同型問題的新位置:用自然語言問 AI「列出專案 X 的成員」就能拿到別家客戶的名冊。首腦核對:✅ 屬實。要追:這 7 支各自呼叫的套件方法有沒有任何歸屬檢查、儀表板呼叫時帶的是哪個身分。enforce_role=False 主動繞過套件守門,而依賴的上游守門又是條件式(疑點 #6):app/flow_control/service/project_service.py:460/467/474(:460 註解自陳「授權由 update_project 自身把關(另列 follow-up)」)、app/module_frame/service/module_frame_service.py:242。首腦另查 update_project :373-375 的守門是 if self._participant_role_service is not None: 才 assert_project_manager——與上一條同款「有注入才檢查」。為什麼可疑:兩層都是條件式,DI 漏一條就整段開放。首腦核對:✅ 屬實(前三處+update_project);module_frame_service.py:242 的上游守門未核對,本棒要答。core/plugins/participant.py:90-102 _ProjectRoleGuardAdapter.assert_manager → common.authz.project.assert_project_manager;core/plugins/task.py:89-98 傳三道守門(license/project_role/identity)。要追:adapter 有沒有吞掉例外、有沒有把「查不到角色」轉成放行;core/plugins/license.py/evidence_classification.py 同款 adapter 有沒有不一致。(工具未報時人工查證)common/authz/project.py 四支(:16-30/:33-57/:60-98/:101-120),首腦核對過沒有 fail-open、沒有 super_admin 短路。本棒再確認一次「role_service 為 None 時會怎樣」與「group_id/control_id 傳了但查不到時往上 fallback 的邏輯有沒有讓『控制項層不是 manager 但專案層是』通過」——這是設計(三層往上找),本棒只記錄行為,不判對錯。此檔同時在 H2 scope,重複報由首腦挑掉。app/project/service/project_start_app_service.py 與 project_service.py 同步 participants 時走的是套件哪支方法、有沒有守門、同步來源的 uid 清單(p_uid)有沒有驗證屬於同租戶。與疑點 #6 同一段程式,一起看。domain/oscal/service/ssp_project_resolver.py、app/cloud_integration/service/drive_project_verify_service.py——它們拿專案編號查資料時有沒有帶身分、查到的專案有沒有回頭比對呼叫者。(工具未報時人工查證)授權判定怎麼流(首腦 2026-09-14 開檔核對,行號可直接打開):
common/authz/project.py(120 行):assert_project_manager :16-30/assert_project_role_fallback :33-57/assert_project_role :60-98/assert_project_participant :101-120。守門函式本身沒有 fail-open(fail-open 就是「查不到就放行」的壞習慣):查不到角色就 raise、沒有拿租戶代替專案、沒有 super_admin 短路。participant/app/service/participant_role_service.py:33-83,三層往上找:project_control_participants → control_group_participants → project_participants → 都沒有就回 None。core/plugins/participant.py:90-102 的 adapter → 套件 participant/common/guard.py:26-52 的 configure();沒接線時 :45-49 直接 raise、不放行(這一段是好的)。task 那一半的三道守門(license/project_role/identity)在 core/plugins/task.py:89-98,與 jedi-compliance-audit 共用同一組 adapter。