本卡屬 FR-095(母卡見本 arc README front matter),第 5 棒 P3:任務留言/匯入匯出 route/執行啟動+三道守門殼(jedi 套件 repo)。只掃不修。
套件 task 那一半的 10 條對外 API(儀表板、批次完成、任務留言的讀寫刪、匯入匯出、執行啟動與進度查詢)從網址進來到 service 的那段,加上套件自己的三道守門殼(license/project_role/identity,「殼」就是套件定義形狀、實作由宿主填的那層)、套件層級的掛載檔與錯誤碼。共 32 檔。只找問題、不修問題。
task 那一半的 route 與守門殼一次看完,才能回答「10 條 API 每一條在進 service 之前有沒有經過哪一道守門」。首腦已看到任務留言的 GET 只查 uid 不查歸屬、執行進度查詢 docstring 自陳「軟 gate 唯讀」無守門——這套留言(job_execution_comments)與 FR-088 登記的那套(element_variables)是不同系統,沒登記過。
這些是首腦讀過程式碼後認為最容易出事的地方,是思考起點不是檢查清單。每條後面的「首腦核對」是首腦親自開檔的結果——✅ 屬實的不必重做核對,直接當錨點追下去;標「待 runner 核對」的才要你自己開檔確認。工具沒答的自己開檔查了再寫,標明「(工具未報,人工查證)」:
task/app/service/job_comment_service.py:27-30 list_comments(job_uid) 直接 list_by_job(job_uid) 回 DTO,沒有任何一行問「你是不是這個任務所屬專案的人」。為什麼可疑:登入+知道任務編號就能讀走別家客戶的任務討論串(2,829 筆、表無租戶欄、隔離關)。首腦核對:讀碼助手報,首腦未逐一開檔,待 runner 核對——同檔的新增/刪除留言有沒有守門也一起答(FR-088 H2 的模式是「寫有守門、讀漏掉」)。task/app/service/task_execution_service.py:139-141 get_prep_job_progress(project_uid) 直接 self._query.get_prep_job_progress(project_uid)。為什麼可疑:專案編號自填就能看別家專案「準備作業完成幾成」——資訊量小但同型。首腦核對:待 runner 核對。同檔 start_task_execution 啟動任務時的守門是哪一道、由 route 還是 service 呼叫。except Exception 吞錯(疑點 #13,非資安靜默失敗):task_execution_service.py:88(批次通知失敗不擋主流程)與 :130(型別啟動掛鉤失敗不擋發佈)。task/domain/task_type_registry.py:87 自陳後果「該自動跑的第一輪作業沒跑」看起來像業務邏輯問題。首腦核對:未開檔;報告非資安段記,重點是「吞掉之後有沒有任何人會知道」(只 warning log)。task/api/guard.py 25 行相容殼,docstring「保留一版後移除」。首腦核對:✅ grep 主專案與套件皆無 consumer,可刪。報告非資安段記一筆即可。task/common/guard.py 與 task/api/guards.py——license/project_role/identity 三道守門,宿主在 core/plugins/task.py:89-98 傳入。要答:任一道沒傳時是 raise(像 participant 半的 guard.py:45-49)還是靜默跳過?task/plugin/assembly.py/runtime.py/contract.py 有沒有讓宿主少傳一個 adapter 也能啟動。(工具未報時人工查證)task/api/routing.py 掛的每一條 route × 進 service 前經過哪一道(jwt/license/project_role/identity)——交一張表。特別看 job_import_route.py 上傳檔案有沒有大小/型別限制、dashboard_route.py 回的資料有沒有跨專案。task/api/serializers/*.py 五支——回應裡有沒有夾帶不該給前端的欄位(內部 id、其他使用者的 email/login_name)。總表 §2.9 🅴 組同型。授權判定怎麼流(首腦 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。