| 項目 | 內容 |
|---|---|
| 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 |
檢測工具平台(FR-056/FR-058)原本一次執行只派一台 agent,且是隨手挑的——_pick_agent 無排序、不驗在線,挑中離線機時工單永遠 pending 沒有回收。客戶落地環境常見多個隔離網段(辦公網/機房網/DMZ),每網段一台 agent,現況 UI 無處指定「這批目標給哪台掃」、執行紀錄也查不到「這份報告誰掃的」。
目標模型(user 拍板的模型 B):任務設置可設多組 assignment(每組=一台 agent+一批掃描目標+排程時間);按一次「開始執行」展開成 N 筆執行紀錄(維持既有「一筆執行=一張工單」1:1 不動)+一層執行群組(group)彙總;各 agent 各領各的單;全部終態才收口(彙總狀態/auto 完成/一封彙總通知);失敗的組可單組重跑。
feature/FR-067 → 已併 main)| 棒 | commits | 內容 |
|---|---|---|
| 第一棒 .1 地基 | 9f83973b |
Agent 清單補 capabilities/在線+修自動挑機(新 canonical get_dispatchable_agents()) |
| 第二棒 .2 資料層 | 9bcd02f5/69e6906d |
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() 兩處共用)+回歸測試 |
| 驗收第一輪 | c408814f/5ec85bee/06e98031/8c24e212 |
目標欄依 param_schema 分流、profile 純下拉、測試連線可指定 agent、同 agent 多列+per 列 profile 覆寫(+migration 拿掉唯一約束) |
| 驗收續輪+.8 | 5ca869e7(內含 T-8.1)等 |
transport per 列、CIDR/range 展開(依欄位語意分流)、每列 params 完整化 |
| 顯示回饋 1395/96/97 | 571b5b9e/f630282d/1be843a7 等 |
台數 BE 供+targets 欄位、檢測設定卡逐組分塊、重跑前置收窄到 assignment 線層 |
| 進版+收尾 | 6d4ea5ee(v1.16.0)/9ae28f68(CM-1402 SPEC)/b0a468e2 |
進版三件套+SPEC 四頁補行為+交接 |
| CM-1404 根修 | 3b795703/1a79c3f0/de95b831/ccb647df+eccc9204 |
基線庫補套→regenerate 產物→build gate→重出 bundle+裝機驗 SOP;CLAUDE.md DB 清單改版 |
feature/FR-067)996ed22(.3 Agent 分派 UI)/cb458a6(.5 群組卡片+.7 執行端排程 UX)/055d9c2(設定端排程 chip)/80e1c29(十支 error code+App.vue 明細併陳)/9809d29・8633ed6・fe10773・3a9a213・d10ab5a(第一輪 UX 五波)/4081e58(測試連線指定 agent)/83248dc(同 agent 多列)/da33373(.8 整份 param_schema 渲染)等。
6fdd541(stderr 帶出+Rocky 檔名推 rl)/ae9f4c9(bump 0.2.29)/re-enroll 指令(0.2.30,CM-1376)。v0.2.30 tag 已推。
CM-1403 半成品(factory 擴充+project-task-agent-dispatch.feature+traceability)——runner 額度中斷未 commit,收案時裁定併入 follow-up(見 §8)。
| 決策 | 定案 | 一句話理由 |
|---|---|---|
| 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 透傳)。
出貨: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 完好)。
先查再動手類
驗證紀律類
is_latest 缺陷(10 筆 legacy 9 筆消失)——單元測試綠 ≠ 真資料形狀對;把 FE helper 抽出來餵真 API 回應跑,比讀 code 想像有效。平行作業類
git log -- <path> 再 Edit 併入,不 cat > 整檔覆寫(.2 差點蓋掉 .1 的版本)。git status 出現不認得的檔先比 mtime 判定是否平行 session 產物;顯式 add 也擋不住「別人已 stage 的一起進 commit」(協調者 5ca869e7 事故)——commit 前必看 staged 區。結構性改動類
t(code, {default}) 有翻譯就蓋掉 default,明細被吞。環境/維運類
systemctl list-units 確認,別假設。後續優化池六件(user 2026-08-26 全數定調「後續優化」不開卡):
agent_enroll_token_service.py:62 回含 /api/1.0 的原值,使用者照抄必 404(agent 端會再補路徑)。修法二擇一:BE 顯示時剝路徑,或 agent enroll 正規化容忍。is_latest 語意:legacy 筆(assignment_uid 全 NULL)被算同一條 latest 線;FE 保底已擋住消失問題、D8 資料會重置,影響低。rl,50 台客戶場景逐台手放不可維運。其他 follow-up:
project-task-agent-dispatch.feature(CM-1403 半成品在 test repo working tree:factory 擴充+feature+traceability,斷尾訊息說 C-1 單跑綠、失敗是 CM-1105 類平行負載 flake 非回歸)。render_html.py 自製輪維護貴;features-site 已有 MkDocs+Material 前例。遷移要盤點:版本凍結快照多版導覽、link_manual_refs、Cloudflare webroot。