本卡屬 FR-091(母卡開卡後補號)第一批。輕量:plugin.py 262 行、1 條 route、0 個 entity、無 DB 表。範例是 jedi-asset,照它做。
jedi-ai-bot 的結構是抽出時的舊形狀:plugin.py 一檔塞 5 個 dataclass,守門函式叫 ctx(),logger 有三種名字("app"、common.jedi_ai_bot、name),其中 "app" 會跟主專案撞名。本卡整成 jedi-asset 那個樣子。
首腦核對(2026-09-12 掃描):plugin.py 262 行 5 dataclass;api/init.py 5 行;route 1 條;entity 0 檔;migration 0;tests 26 支;harness 有;施工日誌命中 5 處;ctx() 3 處;logger 三種;API 不吐 created_user_name → 不開 identity port;tests/integration 無 → 不補。
套件:/Users/chouraymond/Projects/Jedicogy/module/jedi-python-package/jedi-ai-bot/
範例:/Users/chouraymond/Projects/Jedicogy/module/jedi-python-package/jedi-asset/
SOP:compliance-manager-be/docs/features/FR-069-2608-jedi-module-extraction/extraction-sop.md §4.3
主專案 import 面:grep -rn "from jedi_ai_bot" compliance-manager-be --include='*.py' 排除 .venv
grep -rnE "第 ?[0-9]+ ?棒|CM-[0-9]{4}|等發版|逐字未改" jedi_ai_bot 零命中。plugin.py → plugin/{__init__,contract,runtime,assembly,migrations}.py(無 migration 就不建 migrations.py);api/__init__.py → guards.py(runtime()+lazy decorator)+routing.py;__init__ 只 re-export,__all__ 列齊。對外 from jedi_ai_bot.plugin import X 一字不改。contract.py 不 import flask;Blueprint import_name 寫死 "jedi_ai_bot.plugin"。ctx() 全改 runtime()(route 內變數 rt);logger 三種全改 logging.getLogger("common.jedi_ai_bot"),刪頂層 __init__ 的 logger 定義;domain/app service 屬性名統一 _repo/_domain_service。tests/unittest/test_plugin_layout.py(照 jedi-asset 那支):__all__ 凍結集合比對、逐個 getattr、AST 掃 contract.py 無 flask import。突變:__all__ 少列一個 → 紅。cd jedi-ai-bot && pytest tests/;python harness/dev_app.py --smoke(先起 compose);主專案 pytest test/test_module_boundaries.py;主專案每一處 from jedi_ai_bot 在 shell 逐一 import。jedi-ai-bot/。主專案不動(接線由 CM-1689 統一收);若主專案 import 路徑必須變,回寫問首腦。絕不發版、絕不推 Nexus。