1. 結論
FR-059 把檢測工具(第一期 CINC Auditor / GCB)的 profile / content 維運,從「四步人工鏈」(profile 進 repo → 人工 rsync 到每台 agent 主機 → 寫 migration 改 param_schema options → 依環境鐵律逐環境套)收斂為後台一頁搞定:管理者在「掃描設定檔管理」頁上傳 / 登記 profile,任務抽屜下拉即時動態列出,agent 派工時透過 FR-058.7 的 mTLS 取檔通道拉檔+本機 cache。agent 只升級一次(0.2.27),之後 content 的新增 / 改版 / 停用全部在後台完成——不再重建 agent image、不再人工 rsync、不再為選項寫 migration。
design.md §7 的十條端到端驗收全數在 DEV 通過(§5),含封閉網路情境驗證(CM-992 限制①的直接解除)。三 repo 的 commit 全部保留本地未 push;STG / POC 的 migration / seed / agent / FE 部署一律等決策者明示放行(D10 環境異動鐵律),放行後照 deploy-runbook.md 執行。
2. 改動範圍與行為差異
2.1 新舊對照
2.2 各 repo 落地面
- BE:新表
config.detection_tool_profiles(雙軌 + P4 版本模型 + RLS 四段 policy)、管理 API 六動作(列表 / menu / 上傳登記 / 版更 / fork+複製到另一工具 / 停用)、上傳驗證管線(四格式偵測、slip / bomb / entry 數 / 解壓比防護、inspec.yml 結構驗證——全 repo 首個壓縮檔安全處理實作)、搬遷 seed(10 筆 SYSTEM 公版)、param_schema 升版(v2 拿掉靜態 options)、派工展開、profile_ref 授權 resolver(append 進 058.7 可插拔清單)、選單路由登記。
- FE:系統管理下新頁「掃描設定檔管理」(雙軌列表 + 六動作,靠 scope 區分能力,公版對非 root 唯讀);任務抽屜下拉偵測
options_source 宣告改走 menu API(無宣告欄位維持靜態行為,機制 tool-agnostic)。
- agent(evidence-agent):profile cache+拉檔(通道取檔 / sha256 對帳 / 四格式統一安全解壓)、inspec connector 接
_profile 三路分流(file 型餵 cache 解壓目錄;url 型 / 手填維持現行為)、部署前置(cache 掛載點)+封閉網路驗證,版號 0.2.25 → 0.2.27。
3. Commits 清單(三 repo,全部未 push)
3.1 BE(compliance-manager-be,branch feature/FR-058)— 12 個
3.2 FE(compliance-manager-fe)— 2 個
3.3 agent(evidence-agent)— 5 個
4. 與 design.md 的偏差紀錄(三條)
實作與設計定稿有三處刻意偏差,皆屬「實作期發現更優落點 / 實測發現的缺口」,設計意圖不變:
- 派工展開點:
_collect_pending_tasks() → start_execution()。design.md §5.4 原定在心跳組 payload 階段(agent_enrollment_service._collect_pending_tasks())展開庫參照;實作改在 detection_orchestration_service.start_execution() 建任務時展開一次、_profile 直接落 agent_tasks.params。理由:展開結果不隨時間變(uid / version / sha256 在建任務當下即凍結),建任務時做一次優於每次心跳重查 DB;心跳路徑零改動、零額外查詢。params.profile 原值照常保留(使用者選了什麼的紀錄),_profile 靠 _ 前綴既有剝除機制不落 FE 執行紀錄與稽核 log。
- D2 契約抽成共用模組
common/util/detection_profile_ref.py(單一真相)。profile: 前綴的組裝(build_profile_ref())與解析(extract_profile_uid())、_profile key 名,收斂在這一個模組;menu DTO、seed script、派工展開全部 import 它,不允許任何呼叫端自己寫 startswith("profile:")——避免前綴契約散落成多份真相。
- 驗證期發現 macOS zip 根目錄 bug → agent 補
resolve_profile_root() 使用時解析(0.2.27)。使用者實測上傳 macOS 打包的 zip:BE 驗證通過入庫(結構驗證容忍「頂層或一層內有 inspec.yml」),但 agent 端 CINC 拿到 cache 根目錄時因多包一層目錄+__MACOSX 垃圾而報「Don't understand inspec profile」——兩端對「一層深」的容忍度不對齊。修法:agent 在使用時解析實際 profile 根目錄(跳過垃圾 entry、下探一層找 inspec.yml),不改 cache 落地結構、不回頭收緊 BE 驗證(收緊會擋掉合法的 macOS 使用者)。
5. 驗收結果
design.md §7 十條端到端驗收全數通過(DEV):四格式上傳+惡意樣本全擋(①)、下拉即選+分池(②)、派工取檔全鏈(③)、cache 命中與版更失效(④)、sha256 對帳防線(⑤)、三層取值相容(⑥)、雙軌守門+RLS(⑦)、封閉網路情境(⑧)、下拉零回歸(⑨)、三環境節奏遵守(⑩——即本文「未上 STG / POC」的現況)。
重點佐證:
- 封閉網路驗證(⑧,CM-992 限制①直接解除):斷外網的 agent 僅靠平台 mTLS 通道取得 file 型 profile,完成 825 項實檢的 GCB 掃描全鏈;過程零外網請求;同 profile 再派cache 命中零重拉(agent log 佐證)。
- 使用者實測:macOS zip 上傳 → 入庫 → 派工 → 掃描成功(§4 偏差③的修復即出自此輪實測)。
- 下拉零回歸(⑨):搬遷 seed 的 10 筆 SYSTEM 公版 name 逐字沿用原 param_schema options label,menu 集合與移除的靜態集合一一對應(seed script 內建零回歸驗證段,執行時實測通過)。
8. 部署 handover
STG / POC 上版(migration 四支 + seed + agent 0.2.27 + FE 新版)為上版動作,一律等決策者當次明確放行。放行後由部署執行者照 ../deploy-runbook.md 執行——該文件自包含(前提 / 指令 / 順序 / 驗收 checklist / 回滾要點),不需回讀 design.md 或本文。
執行順序骨幹(細節見 runbook):BE 程式碼更新 → migration fr059-1 → fr059-2 → fr059-3(選單)→ seed script → fr059-3(param_schema 升版,必須在 seed 之後)→ agent 0.2.27(cache 掛載點先建)→ FE 新版 → 驗收 checklist。