2026-08-27 FR-067 檢測多 Agent 分派 — 全案收口 SUMMARY

項目 內容
Arc FR-067 檢測多 Agent 分派(含 .7 排程、.8 每列自足、驗收回饋兩輪、v1.16.0 進版出貨、CM-1404 安裝包 P0 根修)
期間 2026-08-23 開工 → 2026-08-27 收案(五個實作棒平行/接續+四個協調者棒)
版本 v1.16.0(BE/FE tag、含 FR-066+FR-067;agent v0.2.30);6d4ea5ee 定版,SPEC 快照 docs/specs/v1.16.0/ 已切
Notion 母案 CM-1350;子需求 CM-1351~1355/1372/1385;子任務+回饋卡 CM-1357~1405 級距,驗收卡全 Done
出貨 189(POC)v1.16.0 全新安裝;Harbor guidant-ai-*:1.16.0 六 tag;init image 經 CM-1404 根修重推
設計 ../design.md(D1–D10 決策表+§5.10 每列自足+§5.11 目標顯示);逐棒軌跡 FR-067-LOG.md

1. 全案範圍與 WHY

檢測工具平台(FR-056/FR-058)原本一次執行只派一台 agent,且是隨手挑的——_pick_agent 無排序、不驗在線,挑中離線機時工單永遠 pending 沒有回收。客戶落地環境常見多個隔離網段(辦公網/機房網/DMZ),每網段一台 agent,現況 UI 無處指定「這批目標給哪台掃」、執行紀錄也查不到「這份報告誰掃的」。

目標模型(user 拍板的模型 B):任務設置可設多組 assignment(每組=一台 agent+一批掃描目標+排程時間);按一次「開始執行」展開成 N 筆執行紀錄(維持既有「一筆執行=一張工單」1:1 不動)+一層執行群組(group)彙總;各 agent 各領各的單;全部終態才收口(彙總狀態/auto 完成/一封彙總通知);失敗的組可單組重跑。

2. 各棒 commits 清單(四 repo)

BE(compliance-manager-be,feature/FR-067 → 已併 main)

commits 內容
第一棒 .1 地基 9f83973b Agent 清單補 capabilities/在線+修自動挑機(新 canonical get_dispatchable_agents()
第二棒 .2 資料層 9bcd02f569e6906d migration 兩新表+擴欄補索引;DDD 四層+compute_group_status 彙總函式
第四棒 .4 展開收口 e6283532 展開+D3 逐台驗證、列鎖收口+auto gate+409 地雷解除、重跑/取消三端點
第三棒 .3 綁定設置 f6e27786 agent_assignments diff-sync+enrich+兩條讀取路徑(含 control-tree raw SQL)
第五棒 .5/.7 BE 0dc088d9 執行紀錄 group 化(順修兩處 N+1)+彙總通知一封+per-assignment 排程(D10)
第六棒補修 b205e07a legacy 卡片分組鍵統一(_execution_card_key() 兩處共用)+回歸測試
驗收第一輪 c408814f5ec85bee06e980318c24e212 目標欄依 param_schema 分流、profile 純下拉、測試連線可指定 agent、同 agent 多列+per 列 profile 覆寫(+migration 拿掉唯一約束)
驗收續輪+.8 5ca869e7(內含 T-8.1)等 transport per 列、CIDR/range 展開(依欄位語意分流)、每列 params 完整化
顯示回饋 1395/96/97 571b5b9ef630282d1be843a7 台數 BE 供+targets 欄位、檢測設定卡逐組分塊、重跑前置收窄到 assignment 線層
進版+收尾 6d4ea5ee(v1.16.0)/9ae28f68(CM-1402 SPEC)/b0a468e2 進版三件套+SPEC 四頁補行為+交接
CM-1404 根修 3b7957031a79c3f0de95b831ccb647dfeccc9204 基線庫補套→regenerate 產物→build gate→重出 bundle+裝機驗 SOP;CLAUDE.md DB 清單改版

FE(compliance-manager-fe,feature/FR-067

996ed22(.3 Agent 分派 UI)/cb458a6(.5 群組卡片+.7 執行端排程 UX)/055d9c2(設定端排程 chip)/80e1c29(十支 error code+App.vue 明細併陳)/9809d298633ed6fe107733a9a213d10ab5a(第一輪 UX 五波)/4081e58(測試連線指定 agent)/83248dc(同 agent 多列)/da33373(.8 整份 param_schema 渲染)等。

agent(evidence-agent)

6fdd541(stderr 帶出+Rocky 檔名推 rl)/ae9f4c9(bump 0.2.29)/re-enroll 指令(0.2.30,CM-1376)。v0.2.30 tag 已推

test(compliance-manager-test)

CM-1403 半成品(factory 擴充+project-task-agent-dispatch.feature+traceability)——runner 額度中斷未 commit,收案時裁定併入 follow-up(見 §8)。

3. 關鍵設計決策(濃縮自 design.md D1–D10+各棒 LOG)

決策 定案 一句話理由
D1 內部模型 維持「一筆執行=一張工單」1:1,往上加 group 層 1:1 是回報鏈/報告/FE 渲染的大量隱含依賴,反轉成本高風險大
D2 assignment 載體 新子表(每列有 uid) 單列 CRUD/按列稽核/兩入口併發不互蓋;JSONB 陣列做不到
D3 失效語意 執行前逐台驗證,任一不過整次 400、一次列全所有不合格機與原因 部分派出=掃描殘缺卻顯示完成,比不派更糟;一次列全避免修一台再撞下一台
D4 彙總語意 succeeded/partial_failed/failed/running 四態,單一真相函式 compute_group_status 所有入口共用 收口、重跑、取消、列表四個入口算同一件事,分散必漂移
D5 auto 完成 group 全 succeeded 才 complete_job;partial 留人工;收口列鎖只收一次 部分網段沒掃到任務不該自動關;順解多筆各自觸發 409 的地雷
D6 通知 group 收口發一封彙總(每 assignment 一列),三通道同步 N 台 N 封是轟炸;單台情境體感不變
D7 執行粒度 整組啟動+單組重跑+單組/整組取消;彙總以每 assignment 最新一筆計 失敗只重掃失敗那台(掃描動輒數十分鐘);後由 CM-1397 把重跑前置收窄到 assignment 線層
D8 相容 不 backfill 存量;無 assignment 走 fallback 隱含單組(仍建 group,收口只有一套) 開發驗證階段資料會重置;fallback 讓簡單場景零設定可用且不再挑到離線機
D9 地基缺口併入 remote-agents API 補 capabilities/在線、執行紀錄 enrich agent、test_connection 對齊、_pick_agent 濾離線 四項都是本功能可用性的前置,拆開徒增協調
D10 排程 assignment 加 scheduled_at,「group 照常立即建,延後的是 agent 領得到單的時間」——領單查詢加時間過濾,無背景 job 展開/收口全沿用既有機制,D3 驗證仍在人在場當下做;無 APScheduler tenant context 坑
.8 每列自足 廢「任務層參數+列覆寫」兩層模型,每列=完整獨立工作設定(secret 跟列走、零列 fallback 廢掉、複製列+新列帶預設值) 混合 OS 各掃各基準下兩層覆寫講不清楚哪列在做什麼;「重用」靠 profile 庫引用對齊業界

實作層值得留名的細節決策:diff-sync 配對 uid 優先、agent_uid 次之(與 DB 唯一性語意同源);agent_assignments None=不動/[]=清空;軟刪排在新增前(flush 順序);scheduled_at 時區契約收斂 common/util/scheduled_time.py(naive 視為 UTC,FE 必帶 offset);領單過濾另開 list_dispatchable_for_agent 不動 FR-058.7 下載授權那支;取消排程短路要同時看 execution scheduled+工單 pending 兩條件;CIDR/range 展開依欄位語意分流(Nmap hosts 是執行主機要展開、targets 透傳)。

4. 行為差異(使用者視角)

  • 任務可綁多組 agent+目標:任務設置的「Agent 分派」區可加多列(agent 下拉+掃描目標+per 列完整參數+排程),同 agent 可開多列各掃各基準;不設=自動挑一台健康的(不再挑到離線機)。
  • 群組化執行紀錄:一次執行一張群組卡(彙總徽章:綠/黃 partial/紅/執行中/排程中),每台一列帶 agent 名稱與掃描目標;單組重跑、單組取消、整組取消、排程組「立即開始」;重跑歷史收合。
  • 一封彙總通知:整組收口才發一封(每台一列:agent/目標/狀態/發現數/時間/失敗原因),三通道同步;不再 N 台 N 封。
  • per-assignment 排程:每組可設「幾點才開跑」(排程 chip),時間到 agent 才領單;排程中可取消(不打 agent)或立即開始。
  • 失敗訊息帶 stderr(agent 0.2.29 起),不再空白訊息要上機重現。
  • 掃描目標支援 CIDR 與末段範圍,執行紀錄印原始寫法+台數。

5. 驗收歷程

  • 11 張子任務卡(T-1.1~T-7.2,CM-1357~1374 區段)逐卡協調者驗收通過。
  • 端到端驗收兩輪(188 stack、雙 agent 雙網段):第一輪六回饋卡(CM-1375 UX 五波/1377 測試連線指定/1378 stderr/1379 同 agent 多列/1380 重布);續輪四卡(1376 re-enroll/1381 文件/1382 transport/1383 CIDR);.8 三卡(1386~1388)+文件二輪(1393);最後三卡(1395 目標顯示/1396 逐組分塊/1397 重跑放寬)。全部 user 逐張手測收 Done
  • 進版鏈四卡:1398(進版三件套)/1399(出包)/1400(189 主產品 user 親裝)/1401(189 LC 更新)皆 Done。
  • CM-1402(.6 SPEC 四頁)/CM-1404(安裝包根修)收案時修正待驗證;CM-1403(E2E)半成品轉 follow-up。

6. v1.16.0 出貨與 CM-1404 安裝包事故

出貨:v1.16.0=FR-066+FR-067(branch 已含 FR-066,merge 一次帶齊);發版 gate user 明示豁免。bundle 891M+agent onepack 1.3G(含 seaweedfs);189 POC 全新安裝(舊 postgres 原地封存,不遷舊資料);189 LC 同步更新 main。

P0 事故(CM-1404):189 裝出來 DB 缺 8 支 migration——agent 心跳 500、capabilities 寫不進、檢測功能全殘。根因:init image 的 02-schema/99-stamp 是「generate 後 commit 進 repo」的產物,8/18 後未 regenerate,出包驗證驗了烙印 commit/Harbor digest/tar 內容卻沒驗「裝出來的 schema 到 head」——generate-then-commit 產物天生漂移,build 無 gate 抓不到。根修:基線庫補套→regenerate 三支產物→build gate(stamp vs manifest 比對,突變測試驗過會紅)→重出 bundle 同版 1.16.0→乾淨環境實裝驗 schema 到 head(136 支),SOP 寫進 scripts/init/README.md

t20 攔雷(runner 順手攔下更大的雷):一次性清理腳本 t20 放在 migration 目錄會被當可重跑,重跑會清光檢測 Profile 庫——已加「偵測已就位即中止」防呆+移除與 CM-1322 決策矛盾的段落;未流出(已出貨的 189 實裝驗過 Profile 完好)。

7. 教訓彙整(五實作棒+四協調者棒)

先查再動手類

  • 「兩處各寫一套」的卡先 grep 是不是早就共用了(.1:FR-056.5 早收斂到 domain service,只需換一支)。
  • 協調者開卡的環境/版本斷言連續三次被 runner 實查推翻(Nmap hosts 透傳假設/bump 1.15 已發過/CM-1404 基線庫實況相反)——開卡先查現況或明標「假設,實作前查證」;runner 的煞車(停下回報不硬做)是救命機制。
  • 設計文件的舉例數字(900s 門檻)≠ 環境實值(DEV 60s×3=180s),驗收拿文件數字對會誤判。

驗證紀律類

  • 突變測試抓到真漏網(.5 legacy 分組鍵改成常數測試照綠)——「跑綠了」≠「守住了」。
  • FE 拿真實資料實跑抓到 BE is_latest 缺陷(10 筆 legacy 9 筆消失)——單元測試綠 ≠ 真資料形狀對;把 FE helper 抽出來餵真 API 回應跑,比讀 code 想像有效。
  • 批次驗證的價值實證(.3 九情境一輪暴露兩坑);best-effort 端點 FE 要讀回應內容不是只看 200。
  • 出包驗證必驗「裝出來的 schema 到 head」,不能只驗烙印(§6)。
  • 補套 migration 後 BE 必須重啟——psycopg cached plan 讓症狀與「沒套進去」一模一樣。

平行作業類

  • 交接雙檔在平行 session 下要當共享檔:先 git log -- <path> 再 Edit 併入,不 cat > 整檔覆寫(.2 差點蓋掉 .1 的版本)。
  • commit 前逐檔認領:git status 出現不認得的檔先比 mtime 判定是否平行 session 產物;顯式 add 也擋不住「別人已 stage 的一起進 commit」(協調者 5ca869e7 事故)——commit 前必看 staged 區。

結構性改動類

  • 群組化會「引入」新迴歸不只是新增功能(既有 job 層取消鈕群組化後變成只取消第一台)——要問「哪些原本對的會因此變錯」。
  • response 形狀改了要主動 grep FE 有沒有讀;同一分組概念的兩面(分卡 vs 判最新)鍵只能有一份,抽共用函式而非改其中一支。
  • 「補上翻譯」不是無害動作:msg 帶動態明細的 error code,t(code, {default}) 有翻譯就蓋掉 default,明細被吞。

環境/維運類

  • agent 交付包有兩形態(systemd 原生/compose),排錯先 systemctl list-units 確認,別假設。
  • endpoint 設定「含不含路徑」的契約要顯示端與接收端對齊(enroll token 照抄必 404)。
  • ZAP 掃 SPA 會自噬(ajaxSpider 灌爆佇列連 OpenVAS 陪葬);ajaxSpider 全域互斥=同 daemon 必序列。
  • 查 DB 先確認查的是哪套 PG(188 有老 25432 與 docker 兩套);安裝包形態環境 DB 實況以容器內為準。
  • 驗證用的寫入要挑自己建的資料或先記原值(.5 改了真任務名稱,走 API 還原)。

8. Follow-up 清單

後續優化池六件(user 2026-08-26 全數定調「後續優化」不開卡)

  1. enroll token endpoint 顯示 bugagent_enroll_token_service.py:62 回含 /api/1.0 的原值,使用者照抄必 404(agent 端會再補路徑)。修法二擇一:BE 顯示時剝路徑,或 agent enroll 正規化容忍。
  2. legacy is_latest 語意:legacy 筆(assignment_uid 全 NULL)被算同一條 latest 線;FE 保底已擋住消失問題、D8 資料會重置,影響低。
  3. OpenSCAP content 平台派發(規模 M,正解方向已定):沿 FR-059 file 型派發擴到 openscap——Ubuntu 24.04 apt 倉 content 停 0.1.71、26.04 只有 nightly、Rocky 檔名前綴 rl,50 台客戶場景逐台手放不可維運。
  4. Windows 無域憑證:共用帳號模式只對有 AD 環境成立;短/中/長三層方案材料在 LOG 協調者棒 block(短期手冊+前置腳本/中期 per-分派列憑證組復用 1379 地基/長期 PAM)。
  5. ZAP 排隊重試:ajaxSpider 全域互斥下並發直接失敗不排隊。
  6. 掃描設定下放指派人員(等 PM)。

其他 follow-up

  • 190 E2E 專機未部署 FR-067——部署後要回歸 project-task-agent-dispatch.feature(CM-1403 半成品在 test repo working tree:factory 擴充+feature+traceability,斷尾訊息說 C-1 單跑綠、失敗是 CM-1105 類平行負載 flake 非回歸)。
  • 既有測案綁死 190 環境座標(另案處理):detection-profile-manage steps 硬寫工具 UID、tool-plugin-manage 需 blsemp1 帳號——188 跑必紅 18 條。
  • SPEC 站評估遷 MkDocsrender_html.py 自製輪維護貴;features-site 已有 MkDocs+Material 前例。遷移要盤點:版本凍結快照多版導覽、link_manual_refs、Cloudflare webroot。
  • STG(188)是否遷 bundle 形態未拍板。
  • PROD LC:正式出版時找一台設備架(已裁示),連 PROD 簽章鑰四步組([[feedback_multi_env_signing_key_pairs_with_public_key_commit]])同時做。
  • 安裝手冊發布前更新:兩本客戶手冊(onprem 主產品+agent)內容停在 1.15.0/0.2.28,發布前對齊版號字串+多 agent 敘述+升級章範例,md+html 兩份重 build。
  • CM-1404 user 複測項:拿 188 新 bundle 乾淨機實裝→接 agent 驗心跳/capabilities/Profile 10 筆/階段橫幅。
  • FR-068 系統 Log 轉發:設計定案(D1–D6)+CM-1389~1392 四卡就緒,user 裁示 FR-067 收完再派——即本案收口後的下一棒