FR-095 · 需求索引 · 本頁由 build 掃資料夾生成
🟡 已開卡待派(2026-09-14)。母卡 CM-1779;子卡 CM-1780~1786 七張一次建完連號。套件 163 檔+宿主 54 檔=七棒 217 檔,按「可利用門檻」排序:P1 → H1 → P2 → H2 → P3 → P4 → P5,一次只派一棒。決策者 2026-09-14 裁四支合併套件解除暫緩、第一支掃這支;detection/remote-agent 維持暫緩。
尚未開掃,首腦讀碼疑點如下。
這支套件管的是「誰是這個專案的人、他是什麼角色、哪個任務指派給誰」——系統每次要判斷「你在這個專案能做什麼」,最後都是來查它管的表。前面 FR-086(檔案)、FR-088(流程引擎)找到的「只驗身分不驗歸屬」問題,修法都是「補一行去問任務平台」;如果任務平台這一層自己有洞,前面所有修法都建在沙上。
首腦親自開檔核對過、確認屬實的六個疑點(未經工具面板驗證,行號可直接打開):
participant/app/service/project_participant_service.py:43-45 直接 get_all(**kwargs))。登入+知道任一專案編號就能讀走別家客戶的成員名單。這是本專案「讀端點漏守門」第五次出現。di_containers/flow_engine/project_participant_containers.py:113-117 建 ProjectGroupParticipantService 時沒傳 participant_role_service,套件那支檔 grep 零守門)。DI 漏一條線=該服務靜默全開,不報錯不留 log。目前它沒掛 route,但 AI 儀表板讀得到。process_participant_service.py:55-56、task_assignee_service.py:213-214)。拿一個不存在的編號就不會被檢查。app/flow_control/service/job_batch_complete_service.py:50-56 is_manager = True,註解自陳「沿用舊守門『context 不齊就跳過檢查』」)。這正是跨 arc 總表第 59 條當時寫「未核對」的那個點。enforce_role=False 主動繞過套件守門(project_service.py:460/467/474、module_frame_service.py:242),而它們依賴的上游守門 update_project :373-375 又是同款「有注入才檢查」條件式。di_containers/dashboard_apis/participant.py:19-64)——用自然語言問 AI「列出專案 X 的成員」就能拿名冊,與總表第 8/10 條同型、位置不同。資料庫層實況(DEV 唯讀實查):這支套件管的 11 張表沒有一張隔離是開的,9 張連租戶欄都沒有。套件自己的 migration 檔頭寫「沒有 RLS 是刻意的,租戶隔離由專案層擋」——但 projects 表的隔離也是關的,前提已被總表第 43 條推翻。與 FR-086「四層全空」同一形狀。
產品裡每一個稽核專案都有成員:管理者、稽核員、審核者、只能看的人。每個任務(例如「檢查某條控制項」)會指派給某個成員去做。「任務平台」這支套件(jedi-task-platform)就是管這些的:誰是成員、他是什麼角色、哪個任務指派給誰、任務怎麼啟動、任務下面的留言。
它分三個子模組:participant(成員與角色、任務指派,10 條對外 API)、task(任務留言/匯入匯出/批次完成/執行啟動/儀表板,10 條 API)、project(專案資料存取,沒有 API)。
這個 arc 要回答三個問題:① 有沒有辦法讀到或改掉別家客戶(或別的專案)的成員名冊與任務指派?② 守門是不是「有接線才檢查、沒接線就放行」——接漏一條就整段開放?③ 這 11 張表在資料庫層有沒有隔離兜底?
git ls-files 實數):套件 195 檔(tests 外全部)/8,551 行;宿主接線 git grep -l jedi_task_platform 命中 63 檔/約 13,850 行,另 3 檔(common/authz/project.py、common/authz/workflow.py、di_containers/dashboard_apis/participant.py)不 import 套件、手動帶入。participant/api/guards.py:10-12 CAPABILITIES 空 tuple),入口只有宿主注入的 jwt_required;六支成員服務的寫入方法全是 if enforce_role and self._participant_role_service: 才檢查。「套件拿到什麼守門、什麼身分」的唯一答案在宿主的 core/plugins/ 與 di_containers/。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(查不到角色就 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 那一半的三道守門在 core/plugins/task.py:89-98,與 jedi-compliance-audit 共用。| 表(compliance schema) | 隔離開關 | 規則 | 有租戶欄 | 筆數 | 備註 |
|---|---|---|---|---|---|
projects |
❌ 關 | 4 | 有 | 226 | 已登記總表 §3.1 第 5/43,FR-094 CM-1768 接走 |
project_participants |
❌ 關 | 0 | 無 | 757 | 總表第 43 條提過一句,FR-094 未收 |
task_assignees |
❌ 關 | 0 | 無 | 10,743 | 本 arc 新增實況,FR-087/094 都沒盤 |
job_executions |
❌ 關 | 0 | 有 | 11,788 | 總表第 43/46 條,FR-094 CM-1770 接走 |
job_execution_comments |
❌ 關 | 0 | 無 | 2,829 | 本 arc 新增實況 |
job_execution_devices |
❌ 關 | 0 | 無 | 3,016 | 本 arc 新增實況 |
job_execution_org_units |
❌ 關 | 0 | 無 | 3,019 | 本 arc 新增實況 |
job_execution_surveys |
❌ 關 | 0 | 無 | 0 | 本 arc 新增實況 |
control_group_participants/process_participants/project_control_participants/project_group_participants |
❌ 關 | 0 | 無 | 0~11 | 套件 migration 001-participant-tables.sql:16-21 自陳「沒有 RLS 是刻意的,租戶隔離由專案層擋」——但 projects 的隔離是關的,前提已被總表第 43 條推翻 |
11 張表沒有一張隔離是開的,9 張連租戶欄都沒有。「隔離開關」=RLS(就是「每個客戶只能看自己資料」的資料庫隔離機制);「有租戶欄」=這張表有沒有一欄寫著資料屬於哪個客戶——沒有的話資料庫層想擋也擋不了,只能靠程式檢查。
scanRoot 兩個:套件=~/Projects/Jedicogy/module/jedi-python-package/jedi-task-platform/jedi_task_platform;宿主=BE repo 根。
| 順序 | 棒 | repo | 檔數 | 為什麼獨立一棒/為什麼排這 | 對應疑點 |
|---|---|---|---|---|---|
| 1 | P1 專案成員新增/移除/角色指派+守門入口+掛載契約 | 套件 | 39 | 門檻最低:登入+自填 project_id 就能讀成員名冊;common/guard.py 是所有守門單一入口,要與六支 service 同棒才看得出誰有接誰沒接 |
1、2(套件側)、3 |
| 2 | H1 專案 CRUD+成員同步+接線(plugin/DI) | 宿主 | 35 | 「套件拿到什麼守門、什麼身分」的唯一答案在 core/plugins/;AI 儀表板繞守門;四處 enforce_role=False |
2(DI 側)、5、6 |
| 3 | P2 任務指派+六張參與者表資料存取+migration | 套件 | 35 | repo 查詢有沒有 project 範圍條件、表無租戶欄,放同棒一眼看完 | 1(task-assignees 那支)、3 |
| 4 | H2 任務 CRUD/匯入匯出/批次完成/執行查詢 | 宿主 | 19 | 數千行大檔;批次完成 fail-open 是第 59 條的未核對點;匯入三步只有最後一步有守門 | 4 |
| 5 | P3 任務留言/匯入匯出 route/執行啟動+三道守門殼 | 套件 | 32 | task 半 10 條 route 與守門殼一次看完;任務留言 GET 無歸屬(與第 51 條是不同留言系統) | — |
| 6 | P4 任務領域模型+任務型別登記簿+四張 job_execution_ 表* | 套件 | 20 | task_type_registry.py 是「拔一行某型別就消失」總開關;四張表資料庫實況已查 |
— |
| 7 | P5 專案 CRUD+人員指派剩餘領域層 | 套件 | 37 | 收尾棒;projects 是套件唯一帶租戶欄的表,驗證「租戶隔離由專案層擋」前提 |
— |
一次只派一棒。合理停損點在第 4 棒之後(P1/H1/P2/H2 共 128 檔已涵蓋全部門檻最低的點),但沒跑完七棒不能宣稱「jedi-task-platform 掃過了」。
接縫:common/authz/project.py 同時放進 H1 與 H2(刻意重疊,重複報由首腦挑掉);P2/P3 可越界讀 participant/common/guard.py 但不報(那是 P1 的);H2 可讀 app/flow_engine/service/workflow_execution_service.py 交叉參照但不報(FR-088 H4 已掃)。
檔數核對(2026-09-14 開卡時 git ls-files 逐檔驗證存在):
__init__.py(25 支 0 行、7 支 1~19 行純 re-export)。P1 的 39=brief 列的 30+participant/app/dto/ 下 9 支非 task_assignee 的 DTO;P4 的 20=brief 列的 20(task/domain/**、task/infra/<strong> 其餘全是 0 行 __init__.py,不硬湊);P5 的 37=project/ 13+participant/domain/ 未入 P2 的 24,排除 0 行 __init__.py。沒有任何一棒超過 40,未觸發搬移規則。**di_containers/flow_engine/workflow_excution_containers.py 已補進 H1(它 import 套件的 TaskAssigneeDomainService/TaskAssigneeRepoImpl 建 provider,屬 DI 接線);其餘 4 檔——api/project/serializers/project.py、config/app_modules.py、core/plugins/asset.py、scripts/deliverables/plugin_metrics.py——只是註解或 docstring 提到套件名,不入棒。| 棒 | 卡 | 檔 | 面板 | 發現 | 報告 |
|---|---|---|---|---|---|
| P1 專案成員新增/移除/角色指派+守門入口+掛載契約 | CM-1780 | 39 | ⬜ | ⬜ | ⬜ |
| H1 專案 CRUD+成員同步+接線(plugin/DI) | CM-1781 | 35 | ⬜ | ⬜ | ⬜ |
| P2 任務指派+六張參與者表資料存取+migration | CM-1782 | 35 | ⬜ | ⬜ | ⬜ |
| H2 任務 CRUD/匯入匯出/批次完成/執行查詢 | CM-1783 | 19 | ⬜ | ⬜ | ⬜ |
| P3 任務留言/匯入匯出 route/執行啟動+三道守門殼 | CM-1784 | 32 | ⬜ | ⬜ | ⬜ |
| P4 任務領域模型+任務型別登記簿+四張 job_execution_* 表 | CM-1785 | 20 | ⬜ | ⬜ | ⬜ |
| P5 專案 CRUD+人員指派剩餘領域層 | CM-1786 | 37 | ⬜ | ⬜ | ⬜ |
不開。依決策者裁定(只掃不修、全部掃完再一起排修正順序),發現登記進跨 arc 總表 §3。
~/Projects/Jedicogy/module/jedi-python-package/jedi-task-platform/jedi_task_platform/(scanRoot 指此子目錄,與 FR-086 B1/FR-088 同做法)core/plugins/participant.py、core/plugins/task.py、di_containers/flow_engine/、di_containers/dashboard_apis/participant.py、app/flow_control/、api/flow_control/、infra/flow_control/、common/authz/project.pyprojects/job_executions 隔離由 CM-1768/1770 接走).claude/skills/security-scan-lead/SKILL.mdsecurity-scan-consolidated/FR-075/handoff/security-scan-STATE.mdfeature/FR-075(2026-09-14 查)。不切 branch。卡片內容(決策紀錄、驗收條件)以 Notion 為準,本頁只記座標。
| 關係 | 卡號 | 標題 | 狀態 |
|---|---|---|---|
| 母案 | CM-1779 | FR-095 掃任務平台(jedi-task-platform:專案成員、任務指派、任務執行)資安掃描(七棒 216 檔,只掃不修) | — |
| 子卡 | CM-1780 | P1 專案成員新增/移除/角色指派+守門入口+掛載契約(39 檔,jedi 套件) | Not started |
| 子卡 | CM-1781 | H1 專案 CRUD+成員同步+接線 plugin/DI(35 檔,BE repo) | Not started |
| 子卡 | CM-1782 | P2 任務指派+六張參與者表資料存取+migration(35 檔,jedi 套件) | Not started |
| 子卡 | CM-1783 | H2 任務 CRUD/匯入匯出/批次完成/執行查詢(19 檔,BE repo) | Not started |
| 子卡 | CM-1784 | P3 任務留言/匯入匯出 route/執行啟動+三道守門殼(32 檔,jedi 套件) | Not started |
| 子卡 | CM-1785 | P4 任務領域模型+任務型別登記簿+四張 job_execution_* 表(20 檔,jedi 套件) | Not started |
| 子卡 | CM-1786 | P5 專案 CRUD+人員指派剩餘領域層(37 檔,jedi 套件) | Not started |