本卡屬 FR-091(母卡 CM-1690)三張大卡之一,與其他兩張不同:形狀要先定。jedi-task-platform 底下有三個子套件 participant/task/project,前兩個各有自己的 plugin.py(279/242 行),project 沒有。標準形狀是「一支套件一個 plugin/」,這支天生是「一支套件多個子插件」——照 jedi-log(CM-1713)的判例,每個子插件各自一組
plugin/五檔、頂層不另建。runner 動手前先把「定形」寫成差異表回寫,首腦確認後再做(本卡唯一一處要等令)。主專案側 participant 接線已在core/plugins/participant.py(CM-1689);task 的接線在api/flow_control/__init__.py:37,183(與 compliance-audit 共用檔,CM-1715 只搬 compliance-audit 與 flow-engine,task 那段留給本卡)。等 CM-1715 收回再派。
jedi-task-platform(任務平台:參與者、任務指派、專案)三個子套件各長各的:participant 有 20 條 route、ctx 32 處、12 個 entity、6 張表;task 有 10 條 route、ctx 18 處、3 個 entity、4 張表;project 沒 route、2 個 entity、1 張表。logger 四種名(__name__ 7、"app" 7、common.jedi_task_platform 3、jedi_task_platform.participant 1)。111 處施工日誌。只有 participant 的 harness 有 --smoke,task 的沒有。主專案 77 檔 import(全部套件最多),flow_control/oscal/associations 大量直接用它的 domain service。
首腦核對(2026-09-13):participant/plugin.py 279 行 6 dataclass、task/plugin.py 242 行 6 dataclass、project 無;route 30(20+10);ctx() 50;entity 檔 17(1 dataclass);表 11;migration 2;tests 93 passed 15 skipped(baseline 已跑,skipped 是什麼 runner 看);harness participant_dev_app.py(有 --smoke)+task_dev_app.py(無)+compose 只有 participant 的;施工日誌 111 處;不直接 import jedi_iam;有吐 created_user_name(6 處,participant 已走 IUserDirectory port——這張是 CM-1484 立的 canonical 名冊,不是 D8 identity,不要合併,survey/detection 的部門名冊都靠它);PACKAGE_ROOT = parents[1](指套件根,不中坑)。venv 指工作樹。
套件:/Users/chouraymond/Projects/Jedicogy/module/jedi-python-package/jedi-task-platform/
jedi_task_platform/participant/{plugin.py,api/,domain/,app/,infra/}
jedi_task_platform/task/{plugin.py,api/,domain/,app/,infra/}
jedi_task_platform/project/{domain/,app/,infra/}(無 plugin、無 api)
jedi_task_platform/migrations/(2 支,頂層)
harness/participant_dev_app.py(--smoke 範本,本套件自己的)、harness/task_dev_app.py
多子插件判例:jedi-log CM-1713(api_log/forwarding 各一組,頂層不另建;forwarding 不拆的三個理由與反悔條件在 README)
SOP:extraction-sop.md §4.3/§5.2
主專案(本卡 G 組允許動):
api/flow_control/__init__.py:37,183 → attach_task(bp, TaskAdapters(...)) 那段搬去 core/plugins/task.py(CM-1715 做完後此檔剩主專案自己的 route+這段)
core/plugins/task.py → 新建三段
core/plugins/participant.py → 已有,只確認不用動
core/plugins/__init__.py → PLUGINS 加 task 一列
test/test_module_boundaries.py → 守衛清單
主專案 import 面:grep -rn "jedi_task_platform" compliance-manager-be --include='*.py' --exclude-dir=.venv(77 檔)
plugin/ 五檔(migrations.py 只在其中一個或頂層?兩支子插件共用頂層 migrations/,建議 jedi_task_platform/plugin/migrations.py 一份、兩個子插件的 __init__ re-export);project/ 不建 plugin(沒 route 沒 register),只做 A/C/D;頂層 jedi_task_platform/__init__.py 要不要 re-export 兩個子插件的 register。寫完回寫,首腦回覆後才動 B 組。A 組清註解可先做。from jedi_task_platform.task.plugin import TaskAdapters, attach_task、from jedi_task_platform.participant.plugin import ...、from jedi_task_platform.participant.domain.ports import IUserDirectory(survey/detection 靠它),77 檔 AST 掃逐一實跑。common.jedi_task_platform(子插件不另分名);命名統一。IUserDirectory 名冊 port 不動。task_dev_app.py 補 --smoke+compose(照 participant 那支);pyproject.toml 加 addopts;README 補三子套件結構。core/plugins/task.py 三段,api/flow_control/__init__.py 的 attach_task 段搬走;PLUGINS 加一列(順序:participant 之後);守衛清單更新。