本卡屬 FR-089(母卡 CM-1688),修 arc review CM-1738 的 I-4,Important。建議 model:Sonnet 5,effort:low——review 已實測六份
_lazy行為完全等價,是零風險的合併。
主專案 20 支接線檔裡,「從 app 上拿 DI container 實例」的 _di() 有七份、「回一個呼叫時才解析的 provider」的 _lazy() 有六份,散在各檔各寫一次,差別只有 docstring 詳略。core/plugins/_host.py 已經是放共用件(host_defaults())的地方,這兩支該進去。另外 core/plugins/compliance_audit.py:55 的 _di() 全檔零呼叫,是死碼,讀者會以為那裡有用途。
_di():core/plugins/{ai_dashboard,evidence_classification,compliance_audit,detection,participant,license,remote_agent}.py
_lazy():core/plugins/{ai_dashboard,evidence_classification,compliance_audit,detection,participant,task}.py
目標:core/plugins/_host.py(host_defaults() 旁)
死碼:core/plugins/compliance_audit.py:55 _di()(grep 該檔 `_di()` 只有定義沒有呼叫)
_host.py 加 di() 與 lazy(container_name, provider_name)(去底線,因為是跨檔共用件;docstring 保留 detection.py 那版最完整的「為什麼不能在建構時解」與「存 provider 不存實例」兩段陷阱)。13 個檔改 from core.plugins._host import di, lazy,刪各自定義;compliance_audit 的死 _di 直接刪。_lazy 逐一 diff 確認真的等價(review 說是,自己 diff <(sed -n ...) 一次);有任何一份多做事(例如 cache)就不合併那份並回寫。python -c "from core.plugins import PLUGINS" 過;pytest test/test_module_boundaries.py -q 與基線同數(test_every_plugin_file_has_three_parts 不看 _di,應無影響)。core/plugins/。註解只留為什麼與陷阱(兩段陷阱搬進 _host.py 後各檔不重複)。改完重啟 BE。git add、commit -- core/plugins/;append 白話;狀態改「修正待驗證」。push 等令。feature/FR-075 不切。不派 subagent。與 I-6 那張卡(13 個 adapter 加繼承)動同一批檔,序列做:等那張收 Done 再派本張,或同一 runner 接著做。測試政策:碎片 refactor,不寫新測試。
修了什麼:七個 core/plugins/ 接線檔(ai_dashboard、evidence_classification、license、participant、remote_agent、task)各自重複定義的 _di()/_lazy() 收進 core/plugins/_host.py,改叫 di() / lazy()(去底線,因為變成跨檔共用件)。compliance_audit.py 原本那支全檔零呼叫的死 _di() 已在前一張卡(CM-1740 I-6)收斂時一併清掉,本卡實際只動七個檔。
關鍵決定:三份 docstring(detection.py/task.py/participant.py)寫得最完整的兩段陷阱說明——「不可在 mount() 當下用 Containers.xxx 取」與「存 provider 不存實例」——併進 _host.py 的 lazy(),各接線檔不再重複。