本卡屬 FR-091(母卡 CM-1690),版面殘留回補第三張。動三支已 Done 的套件;主專案只有一處測試 import 要跟著改。建議 model:Sonnet 5,effort:medium。可與 CM-1731/1732 平行。
決策者 2026-09-13 說「結構可能都要統一」。首腦掃 21 支的 api/ 內部:範例 jedi-asset 是四件固定——guards.py、routing.py、routes/(一資源一檔)、serializers/(一資源一檔)。多數已整理的套件照這樣長,但有三處把 route 檔與 serializers.py 直接平鋪在 api/ 頂層:license-runtime(CM-1701 Done)、remote-agent(CM-1694 Done)、jedi-log 的 forwarding 子插件(CM-1713 Done,當時 runner 說「forwarding 不拆」,首腦以「有理由的偏離」收了)。決策者現在裁全部統一,這三處回頭收。SOP §4.3 今天補了「api/ 四件」規則。
另外三支(ai-bot、evidence-classification、issue)api/ 沒有 serializers/,route 直接 request.get_json() 拿 dict,沒有 marshmallow schema 驗 request。這不是版面問題是設計缺口(沒驗證等於任何 payload 都收)。本卡不補 schema(那是行為變更),只把三支各有幾條 route、各收什麼 payload 列成表回寫,決策者裁要不要另開卡補。
jedi_license_runtime/api/:license_admin_route.py 141 行、license_route.py 129 行、serializers.py 101 行平鋪;guards.py、routing.py 已有。主專案 test/test_license_status_job_types.py:25 import jedi_license_runtime.api.serializers.TenantLicenseResponse——搬完在 api/serializers/__init__.py re-export 即可,主專案那行不改也通;但順手把那行改成新路徑(測試檔不是契約)。jedi_remote_agent/api/:remote_agent_route.py 192 行、serializers.py 86 行平鋪;guards.py、routing.py 已有。主專案零 import 這兩檔。jedi_api_log/forwarding/:api/log_forwarding_route.py、api/serializers.py 平鋪,沒有 guards.py/routing.py(守門與 URL 表在哪 runner 查,多半在 plugin.py 或 route 檔內);forwarding/plugin.py 是單檔沒拆五檔。同套件的 api_log/ 子插件已是標準形狀,照它抄。request.get_json 1 處、evidence-classification 3 處、issue 的 api/ 內 grep 不到 Schema 也不到 get_json(runner 查它怎麼收 payload)。guard.py→guards.py+補 routing.py(CM-1726 B 組已含);task-platform participant/task 的 api 缺 guards/routing(CM-1727 已 append);flow-engine api/ 只有 guards.py 沒 routes——它是引擎,route 在主專案 flow_control,不是缺口;integrity/oscal-v2/task-platform 頂層無 api 是設計。git mv 兩支 route 進 api/routes/,serializers.py 拆成 api/serializers/license.py+license_admin.py(照 route 對應),api/serializers/__init__.py re-export 全部符號;api/__init__.py、routing.py、plugin/assembly.py 的 import 改新路徑;主專案測試那一行改新路徑。api/routes/remote_agent_route.py、api/serializers/remote_agent.py。plugin.py 拆 plugin/ 五檔(照 api_log/ 那支與 asset);api/ 補 guards.py(runtime()+守門)與 routing.py(URL 表,並把 URL 進凍結測試);route 進 routes/、schema 進 serializers/。對外 import 一字不改:jedi_api_log.forwarding.plugin 的公開符號要全部 re-export,主專案 core/plugins/ 對 forwarding 的接線 runner 先 grep 列出用到的符號。api/ 頂層 ls *.py 只允許 __init__.py、guards.py、routing.py(凍結集合)。forwarding 加 plugin 公開符號凍結集合。api/ 頂層放回一支 foo_route.py → 紅。forwarding 的 URL 凍結集合,突變:改一條 URL → 紅。