FR-172 · 需求討論稿 v1 · 2026-11-01(與 FR-171 同週期拍板)

修 Agent 不必再出一包主系統

安裝包、CI、R2 路徑、更新站版本線全部分家;主系統更新中心與 Agent 主控台都能發動 Agent 更新;進度與結果當下回報

今天修一個 Agent 的小 bug,要重出一包 1.7 GB 的主系統、客戶停機 7 分鐘升主系統,再等心跳推 Agent,升完又等 5 分鐘才知道結果,畫面上的八格進度還停在第一格。原因只有一個:Agent 的包、版本線、推送、回報全部掛在主系統身上。本稿把它們一件件拆開——Agent 自己出包上傳、更新站多一條版本線、主系統更新中心能單獨抓 Agent 新版、Agent 主控台多一頁「更新」、進度與結果走 FR-171 定的專用通道。四個決策者已先裁的題目直接寫進設計,其餘 D1~D12 等拍板。

決策者已裁:Agent 不連外網、包只從主系統拿 決策者已裁:主控台按一下=主系統幫這台更新 D1~D12 待裁 與 FR-171 一起拍板、兩棵卡樹 跨 5 repo:update-center/BE/FE/evidence-agent/jedi-agent-protocol 陷阱:Agent 的章與主系統的章不可互相冒充

0. 分工概述(30 秒版)

整案一句話:Agent 的「貨」(安裝包、版本線、下載、推送畫面)從主系統身上拆下來自己走,「線」(主系統叫 Agent 升級、Agent 回報進度)用 FR-171 定的通道,不再借心跳。

階段 做什麼 產出 完成怎麼判定(決策者檢查法)
P1 出貨分家 Agent repo 自己 CI 出包、登記更新站、上 R2 自己的路徑;主系統包不再帶 agent/;更新站多一條 Agent 版本線;蓋章 CLI 多 --product agent Agent .gitlab-ci.yml、更新站 D1 加欄+後台 Agent 分頁、CLI 更新站後台看到「主系統」「Agent」兩個版本分頁,各自列各自的版號;R2 多一個 agent/v1/ 資料夾;主系統包解開沒有 agent/ 目錄、小了 1.7 GB
P2 主系統側 Agent 區 更新中心 Agent 區改成自己查 Agent 新版、先下載再推、相容兩向檢查、移到 agent-bundles/<Agent 版>/ BE product_update Agent 線、FE Agent 區 v3(照雛形第 1~5 頁) 主系統不升版,Agent 區按「立即檢查」看到 Agent 新版、按「預先下載」、按「更新選取的台」,整段不碰主系統版本
P3 進度與結果即時 Agent 升級每一步當下送事件給主系統;畫面八格跟著走;失敗能看到主機端的原因 Agent 事件推送元件(用 FR-171 專用端點)、BE 收事件寫表、FE 八格改讀表 推一台,八格在 3 秒內開始往前走;拔網路線再插回,事件補送、最後一格仍會亮;故意塞滿磁碟推一次,「看原因」顯示 no space left on device
P4 Agent 主控台更新頁 主控台新增「更新」頁:看版本、看主系統上有沒有新版、按「請主系統更新這一台」、離線上傳更新包 主控台 Update.vue(照雛形第 6~9 頁)、Agent 兩支端點、主系統一支端點 登入 Agent 主控台按更新,主系統更新中心同時出現這一台的進度;拔掉主系統、在主控台上傳離線包,Agent 自己升上去
P5 收尾 更新站後台 Agent 三欄改比 Agent 版本線;舊客戶過渡;相容矩陣四格測試;文件 後台修正、過渡文件、e2e 後台「Agent 在版」數字等於 Agent 區實際台數

依賴一句:P1 與 P2 不依賴 FR-171,可立刻開;P3 與 P4 的「主系統→Agent 叫升級」「Agent→主系統送事件」兩條線用 FR-171 批 1~2 定的通道與契約,等它合回才開。決策者功課:裁 D1~D12;其中 D1(更新站存法)與 D2(章怎麼分)影響 P1 第一張卡。


1. 為什麼要做

這邊之後要改成主系統跟 agent 要分開更新。主系統跟 Agent 要分開來,不要像現在都包在同一包裡面;要可以各別分開更新;Agent 那邊也要有更新中心,可以做離線更新,或是跟主系統發動更新需求;R2 上面的安裝包要分開來;不要再用心跳帶資料。 — 決策者原話(2026-11-01,189 推 Agent 1.4.8 時)

2026-11-01 為修兩個 Agent 問題實際走一次的帳:

20 分出 Agent 1.4.8

36 分只為帶 Agent 而重出主系統 1.27.10

7 分客戶停機升主系統(主系統本身沒事)

5 分升完等下一跳心跳才知道結果

Agent 的修正節奏被主系統綁住

Agent 包 1.8 GB 被塞進主系統包 agent/ 底下一起簽、一起上 R2 v1/<主系統版>/。更新站只有一條版本線。Agent 改一行就得重出主系統、客戶就得停機。Agent 包還占主系統包一半以上的下載量。

推送、進度、結果全靠心跳搬

推送後最長等 5 分鐘 Agent 才來拿;FR-167 補了「叫醒心跳」等於再疊一層。結果只隨心跳上報,容器一換狀態就丟。八格進度是主系統畫面刷新時去拉 Agent,結果一到就清掉,失敗時常常看不到卡在哪一步。60.167 那次真因是磁碟滿,主系統只拿到「無法讀取新映像」一句。


2. 現況:Agent 的貨怎麼走

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#E2F0F1','primaryTextColor':'#14201F','primaryBorderColor':'#0E7C86','secondaryColor':'#EEF2F3','secondaryTextColor':'#14201F','tertiaryColor':'#FBFCFC','tertiaryTextColor':'#14201F','lineColor':'#4A5A5C','textColor':'#14201F','mainBkg':'#E2F0F1','nodeBorder':'#0E7C86','nodeTextColor':'#14201F','edgeLabelBackground':'#FBFCFC','titleColor':'#14201F','clusterBkg':'#FBFCFC','clusterBorder':'#E4EAEB','actorBkg':'#E2F0F1','actorTextColor':'#14201F','actorBorder':'#0E7C86','actorLineColor':'#C7D1D2','signalColor':'#4A5A5C','signalTextColor':'#14201F','labelBoxBkgColor':'#EEF2F3','labelBoxBorderColor':'#C7D1D2','labelTextColor':'#14201F','loopTextColor':'#14201F','noteBkgColor':'#F6EBD5','noteTextColor':'#14201F','noteBorderColor':'#9C6B12','activationBkgColor':'#EEF2F3','activationBorderColor':'#C7D1D2','sequenceNumberColor':'#FFFFFF'}}}%%
flowchart LR
  subgraph build["188 build 機(人手跑)"]
    A1["evidence-agent<br/>build_all.sh --with-compose<br/>→ guidant-agent-compose-1.4.8.tar.gz"]
    B1["compliance-manager-be CI package<br/>build_bundle.sh 去抓最新一支 Agent 包<br/>塞進 guidant-ai-1.27.10/agent/"]
  end
  subgraph site["更新站(一條版本線)"]
    S1["product_releases 1.27.10<br/>min_agent_version"]
    R1["R2 v1/1.27.10/guidant-ai-1.27.10.tar.gz<br/>(內含 agent/,1.7 GB)"]
  end
  subgraph host["客戶主系統"]
    H1["升級主系統 → 解到<br/>upgrade/bundles/guidant-ai-1.27.10/agent/"]
    H2["更新中心 Agent 區<br/>只能推『這版主系統附的那個 Agent』"]
  end
  subgraph agent["客戶 Agent"]
    G1["心跳回應 update 鍵 → 下載 → 寫升級單"]
    G2["主機 systemd 升級 → 結果等下一跳心跳帶回"]
  end
  A1 --> B1 --> S1 --> R1 --> H1 --> H2 --> G1 --> G2
圖 1 — 現況。Agent 包從 build 到客戶 Agent 主機,每一段都掛在主系統身上。
環節 現況 掛在主系統的哪裡
出包 Agent repo 沒有 CI,人在 188 手跑;主系統 CI package 段去 /opt/guidant-ai-agent/.build/compose/ 抓最新一支 build_bundle.sh ⑧
簽章 Agent 包沒有自己的發布章;靠主系統 release.json 的 sha256 間接涵蓋 payload_type=release_manifest 只有一種
上傳 只有主系統三個檔上 R2 v1/<主系統版>/ publish_draft.sh
更新站 product_releases 一條版本線;min_agent_version 只有「主系統要求 Agent 最低版」一向;後台 Agent 三欄拿 Agent 版號 1.4.x 比主系統版號 1.27.x 永遠 0 releases.ts
主系統本機 upgrade/bundles/guidant-ai-<主系統版>/agent/,host_version 不得比現行主系統新;刪掉就沒有復原路徑 agent_rollout_service.py
推送 寫 rollout → /update/notify 叫醒心跳 → 心跳回應 update 鍵下發 _agent_update.py、update_sync.py
進度 畫面刷新時主系統去拉 GET /update/progress,快取在 worker 行程各一份 _PROGRESS_CACHE
結果 心跳 payload upgrade_result,最晚一個心跳週期 record_upgrade_result
Agent 主控台 沒有更新頁;能力點只有 configure/files/run-local-scan/net-diag/restart/download-files CONSOLE_SCOPES
離線 只有主系統的離線單一檔;Agent 離線只能人到主機跑 install.sh --upgrade —

3. 目標設計

3.1 一句話版

  • 兩條版本線、兩個包、兩個 R2 資料夾、兩種章:主系統 v<主版>/<版>/+release_manifest;Agent agent/v<主版>/<版>/+agent_release_manifest。
  • Agent 不連外網(決策者裁):Agent 包一律由主系統從更新站拿、或由人離線上傳,主系統是唯一中繼。
  • 主系統更新中心 Agent 區自足:自己查 Agent 新版、預先下載、相容檢查、推給選定的台;不碰主系統版本。
  • Agent 主控台多一頁「更新」:看版本、看主系統那邊有沒有新版、按「請主系統更新這一台」(主系統建單推這一台)、離線上傳更新包。
  • 叫升級與回報走 FR-171 的通道:主系統 POST /update 直推;Agent 升級每一步 POST /agents/update/events 當下送,送不到進 outbox。心跳回到只表存活。
  • 相容兩向:主系統清單 min_agent_version、Agent 清單 min_host_version;不相容在畫面擋。
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#E2F0F1','primaryTextColor':'#14201F','primaryBorderColor':'#0E7C86','secondaryColor':'#EEF2F3','secondaryTextColor':'#14201F','tertiaryColor':'#FBFCFC','tertiaryTextColor':'#14201F','lineColor':'#4A5A5C','textColor':'#14201F','mainBkg':'#E2F0F1','nodeBorder':'#0E7C86','nodeTextColor':'#14201F','edgeLabelBackground':'#FBFCFC','titleColor':'#14201F','clusterBkg':'#FBFCFC','clusterBorder':'#E4EAEB','actorBkg':'#E2F0F1','actorTextColor':'#14201F','actorBorder':'#0E7C86','actorLineColor':'#C7D1D2','signalColor':'#4A5A5C','signalTextColor':'#14201F','labelBoxBkgColor':'#EEF2F3','labelBoxBorderColor':'#C7D1D2','labelTextColor':'#14201F','loopTextColor':'#14201F','noteBkgColor':'#F6EBD5','noteTextColor':'#14201F','noteBorderColor':'#9C6B12','activationBkgColor':'#EEF2F3','activationBorderColor':'#C7D1D2','sequenceNumberColor':'#FFFFFF'}}}%%
flowchart LR
  subgraph ci["兩條 CI"]
    C1["BE CI → guidant-ai-1.28.0.tar.gz<br/>(不含 agent/)"]
    C2["Agent CI(新)→ guidant-agent-compose-1.5.0.tar.gz<br/>register-draft --product agent"]
  end
  subgraph site["更新站(兩條版本線)"]
    S1["product_releases (host, 1.28.0)<br/>min_agent_version"]
    S2["product_releases (agent, 1.5.0)<br/>min_host_version"]
    R1["R2 v1/1.28.0/"]
    R2["R2 agent/v1/1.5.0/"]
  end
  subgraph mac["決策者電腦"]
    K["guidant-release publish --product host|agent<br/>兩種 payload_type,各驗各的"]
  end
  subgraph host["客戶主系統"]
    H1["更新中心:主系統卡(不變)"]
    H2["更新中心:Agent 卡<br/>立即檢查 → 預先下載 → 相容檢查 → 推選定的台<br/>upgrade/agent-bundles/1.5.0/"]
    H3["收事件表 agent_update_events<br/>八格進度、失敗原因"]
  end
  subgraph agent["客戶 Agent"]
    G1["POST /update(FR-171 直推)→ 下載 → 寫升級單"]
    G2["主機 systemd 升級每步 → 事件當下送 POST /agents/update/events"]
    G3["主控台「更新」頁<br/>請主系統更新這一台/離線上傳"]
  end
  C1 --> S1 --> R1
  C2 --> S2 --> R2
  K -.蓋章.-> S1
  K -.蓋章.-> S2
  R1 --> H1
  R2 --> H2
  H2 --> G1 --> G2 --> H3
  G3 -- "請主系統更新這一台" --> H2
圖 2 — 目標。兩條線分家;主系統仍是 Agent 包的唯一中繼。

3.2 出貨分家(P1)

項 現況 改成 repo
Agent CI 無,人手在 188 跑 新增 .gitlab-ci.yml,同 guidantai-build runner:build_all.sh --with-compose → smoke → register-draft --product agent → 上 R2 三檔(包、.sha256、未簽 release.json)。主控台前端在 node 容器內 build,不靠 188 裝 node(D4) evidence-agent
主系統包 build_bundle.sh ⑧ 收 Agent 包進 agent/ 拿掉 ⑧ 與「正式包必須帶 Agent」守門;--skip-prod-key-check 不再有 Agent 那半邊 BE
更新站資料 product_releases 一條線 加 product 欄(host/agent),主鍵改 (product, version);Agent 列多 min_host_version(D1) update-center
R2 路徑 v<主版>/<版>/ 主系統不動;Agent agent/v<主版>/<版>/<檔>,一樣只由 r2Key() 拼(主版號資料夾仍是授權邊界) update-center
章 payload_type=release_manifest Agent 用 agent_release_manifest,payload 多 min_host_version;主系統端驗 Agent 包只認 agent_release_manifest、驗主系統包只認 release_manifest(D2) update-center CLI、BE、evidence-agent
客戶端端點 /v1/check、/v1/download-url、/v1/report 三支加 product 參數,不帶=host(舊主系統不用改);/v1/report target=agent 已有,改對 Agent 版本線比 update-center
後台 一張版本表 分「主系統」「Agent」兩個分頁;Agent 三欄改比 Agent 版本線(FR-167 待辦 63) update-center
版本說明 Agent notes.json 隨包 改與主系統一樣:發布前貼更新站後台的 Agent 列 update-center
離線單一檔 只有主系統 guidant-agent-<版>.offline.tar.gz(包+簽好的 release.json),publish --product agent 順帶產 update-center CLI

3.3 主系統側 Agent 區(P2)

雛形第 1~5 頁。規則:

  • 檢查:每 6 小時那次檢查同時問 product=host 與 product=agent;「立即檢查」兩個都問。
  • 預先下載:Agent 卡的「預先下載」把 Agent 包下到 upgrade/agent-bundles/<Agent 版>/,驗章(agent_release_manifest)、驗 sha256;下載人寫稽核。保留現行版與最新版兩份,其餘清掉(D7)。
  • 相容檢查兩向:
    • Agent 新版 min_host_version 高於主系統現行版 → Agent 卡顯示「需要先把主系統升到 X」,推送鈕灰。
    • 主系統新版 min_agent_version 高於某台 Agent 現行版 → 主系統卡標「必須更新 Agent」(FR-167 D16 既有行為),該台在 Agent 卡標「必須更新」。
  • 推送:沿用 agent_update_rollouts(先 1 台、再其餘、任一失敗其餘暫停、暫停/繼續/稍後提醒),只換兩件事:包從 agent-bundles/<Agent 版>/ 拿、下發改 FR-171 的 POST /update 直推(打不通退回心跳備援一個版本,之後拔)。
  • 「隨主系統跟進」(FR-167 D16 預設勾)保留:主系統升完若 agent-bundles/ 已有相容的 Agent 新版就照舊自動建列。
  • host_version 欄位退役:Agent 包不再綁主系統版,改記 agent_bundle_version。

3.4 進度與結果即時(P3)

依 FR-171「心跳只表存活」:

事件 誰送 送到哪 內容
下載進度 Agent 容器(每 5% 或每 10 秒) POST /agents/update/events {job_id, kind:"download", bytes_done, bytes_total}
主機每一步開始/結束 Agent 容器監看 upgrade-progress.json 變動即送 同上 {job_id, kind:"step", n, name, status, started, ended, detail}
最終結果 新容器啟動時讀升級單結果即送(容器換掉那幾步由新容器補) 同上 {job_id, kind:"result", status, version, error, detail}
送不到 進 Agent 既有 outbox(新 kind update_event),連上就補送、順序照 created_at — —
  • 主系統收進 agent_update_events(每台每 job 一列 upsert,存最後進度與全部步驟),畫面 3 秒輪詢改讀這張表,不再去拉 Agent;_PROGRESS_CACHE 與 GET /update/progress 退役。
  • 失敗細節回得來:upgrade_order.sh 不再丟 stderr,每步失敗把 stderr 最後 20 行寫進進度檔 detail(≤ 4 KB);主系統存、畫面「看原因」顯示;仍過濾不可列印字元(D8)。
  • 心跳 payload 的 upgrade_result 與回應的 update 鍵:主系統接受但不再依賴,留一個版本給舊 Agent,下一 minor 拔(跟 FR-171 的 /update/notify 同節奏)。

3.5 Agent 主控台「更新」頁(P4)

雛形第 6~9 頁。決策者已裁「按一下=主系統幫這一台更新」。

畫面元素 資料從哪來 動作
目前版本、上次更新時間與結果 Agent 本機(升級單結果檔) —
「主系統上有 Agent 新版 X」/「已是最新」/「主系統不相容,要先升主系統」 Agent 向主系統 GET /agents/update/available(控制面通行證),主系統回 agent-bundles/ 裡相容的最新版與版本說明 按「請主系統更新這一台」→ Agent 打主系統 POST /agents/update/request → 主系統建一張 manual rollout 只含這台(按更新的人記 agent-console:<操作者>)→ 走 P2/P3 同一條路
進度八格、失敗原因 Agent 本機進度檔(與送給主系統的是同一份) —
離線上傳 上傳 guidant-agent-<版>.offline.tar.gz → Agent 驗章(agent_release_manifest,公鑰隨 Agent 包帶 release-keys/)、驗 sha256、寫升級單 → 主機 systemd 照舊接手 要先過「主系統不相容」檢查:Agent 端拿不到主系統版本時只提示不擋(D5)
權限 新能力點 update(D6) 預設 local-admin 有;離線操作者可由主系統勾給

Agent 主控台事件(誰按了更新、上傳了什麼)照既有 console_events 送主系統稽核。


4. 與 FR-171 的分工

FR-171 管「線」 FR-172 管「貨」
做什麼 主系統→Agent 指令直推(派工/重啟/升級/換證/取消)、Agent→主系統事件專用端點、心跳只表存活、憑證自動換、守門與 client 收一份 出包/CI/R2/更新站版本線分家、相容兩向、主系統 Agent 區改版、進度事件的內容與畫面、Agent 主控台更新頁、離線上傳
172 直接用 171 的 POST /update 指令端點與 AgentDataPlaneClient;Agent→主系統事件端點的簽章與守門規則;契約套件 jedi-agent-protocol 的版號 —
172 自己定的 — agent_release_manifest 章、min_host_version、agent_update_events 表與事件形狀、GET /agents/update/available、POST /agents/update/request、主控台頁與能力點
順序 批 1 守門與 client 收斂 → 批 2 指令通道與事件端點 P1、P2 立刻開(不等 171);P3、P4 等 171 批 2 合回
不互踩 171 不動 agent_rollout_service 的包來源與畫面 172 不另開第二條直推 client、不自己定事件簽章

兩案同一個討論週期拍板、各自一棵卡樹(兩張母卡)、工作坊可同時跑兩個;172 的 P3/P4 卡在 Stage 排在 171 批 2 之後。


5. 待決策

已裁(2026-11-01 決策者)

  • Agent 不直接連更新站;包只從主系統拿、離線靠主控台上傳。
  • Agent 主控台「向主系統發動更新」=主系統幫這一台下載並推送,不是跳轉連結。
  • 171 與 172 討論稿一起看、一起拍板。
  • 172 討論稿附可點的雛形。

D1 — 更新站怎麼存 Agent 版本線:加 product 欄,還是另開一張表?

建議:加欄。product_releases 加 product TEXT NOT NULL DEFAULT 'host',主鍵改 (product, version),Agent 列多 min_host_version。visibleReleases、releaseAdoption、後台、CLI 全部多一個 product 條件。另開表會讓發布流程、撤回、保留期、下載紀錄每支都寫兩份。

D2 — Agent 的章怎麼分:同 payload_type 加 product 欄,還是另一個 payload_type?

建議:另一個 agent_release_manifest。理由:已出貨的主系統 1.27.x 驗章只認 release_manifest,拿到 Agent 清單會直接 bad_signature 拒收;若共用型別只加欄位,舊主系統會把 Agent 1.5.0 當成「主系統 1.5.0」走到版號比較才擋,差一道門。同一把發布私鑰簽兩種型別,不用多一把章。

D3 — 相容矩陣兩向的擋法

Agent 新版 min_host_version > 主系統現行版 → 擋推送(灰鈕+說明);主系統新版 min_agent_version > 某台 Agent → 標「必須更新」但不擋主系統升級(FR-167 D16 既有)。

建議:照此。Agent 比主系統新是允許的(兩條線不綁版,FR-171 相容矩陣同一精神),只擋「Agent 要求的主系統最低版沒到」。min_host_version 由 Agent repo scripts/build/min_host_version 一行檔決定,沒有=不限。

D4 — Agent CI 跑在哪、主控台前端怎麼 build

188 runner 沒有 node,主控台前端現在在 Mac build 再傳過去(runbook 2.2)。

建議:Agent CI 跑同一台 188 runner(guidantai-build tag),主控台前端在 node:20 容器內 build(跟 BE CI 的 build_fe_image.sh 同手法),FE repo 以 submodule 或 CI 變數指定 commit 拉進來。188 不裝 node。

D5 — Agent 主控台離線上傳的驗證與相容檢查

Agent 端要能驗 agent_release_manifest 的章,公鑰要隨 Agent 包帶(現在只在主系統包 release-keys/)。相容檢查需要主系統版本,離線時拿不到。

建議:Agent compose 包加 release-keys/(與主系統同一批公鑰與 PROD_KIDS),升級時換新;離線上傳時 Agent 拿不到主系統版本就只提示「無法確認相容性,請確認主系統 ≥ X」不擋——離線場景本來就是人在現場。

D6 — 主控台權限:新能力點 update,還是沿用 restart?

建議:新 update。重啟是分鐘級可逆、更新是換版本不可逆,給離線操作者的授權面不同;CONSOLE_SCOPES 加一項、主系統 Agent 管理頁勾選清單多一格、local-admin 預設有。

D7 — 主系統本機 Agent 包目錄與保留

upgrade/bundles/guidant-ai-<主系統版>/agent/ → upgrade/agent-bundles/<Agent 版>/。

建議:保留「各台現行版中最舊的那版」與「最新版」兩份,其餘清;升級到 1.28 時把舊 bundles/<版>/agent/ 裡的那支搬過去當第一份。這同時解掉 FR-167 待辦 42(被刪就重下載)。

D8 — 失敗原因回多少

建議:每步 detail ≤ 4 KB、只收 stderr 最後 20 行、過濾不可列印字元、主系統再截一次;畫面預設收起、「看原因」展開;診斷包照舊收全量 journal。不送整段 journal(主機路徑與帳號會進主系統稽核表)。

D9 — Agent 區「預先下載」要不要獨立成一步

主系統卡現在是「預先下載 → 更新」兩步(FR-167 已裁名稱不改)。Agent 卡現況是「推送」一步,包早就在主系統包裡。

建議:對齊成兩步。Agent 包 1.8 GB 不小,下載誰按、何時下載要有紀錄;且離線客戶走上傳到主系統這條路時本來就分兩步。雛形第 1~2 頁照這樣畫。

D10 — 舊客戶怎麼過渡

現場 1.27.10 的主系統包裡還有 agent/;下一版主系統 1.28.0 不帶。

建議:1.28.0 主系統升級第 7 步把 bundles/1.27.10/agent/ 那支搬到 agent-bundles/1.4.8/;更新站 Agent 版本線第一筆登 1.4.8(補登既有包,不重出);1.5.0 起走新 CI。舊主系統 1.27.x 問 /v1/check 不帶 product 照舊拿主系統線,不受影響。

D11 — FR-167 搬過來的小待辦哪些併入本案

待辦 內容 建議
60 八格讀錯欄位(FE 已修未出包)、結果晚 5 分 併入 P3,整段重做
63 更新站後台 Agent 三欄永遠 0 併入 P1
42 刪掉 bundles/<版>/agent/ 沒復原路徑 D7 順帶解
58 Agent 主控台檔案頁把 PDF 快取列成證據 併入本案當一張 Agent repo 小卡(同 repo、不撞檔)
61 主控台 CINC 網址型 Profile 下拉空 不併:B 方向要改主系統 Profile 匯入(解析時留檔),屬檢測 Profile 功能,另開小 FR 或掛 FR-060 續作
62 升級換接後 compose 標籤指舊目錄 不併:主系統自升級的事,留 FR-167 下一版

建議:照表。

D12 — 拆卡順序與批(約 18 張、5 repo)

P1:更新站 D1 加欄+端點 product 參數(1)→ CLI --product+agent_release_manifest+離線檔(1)→ 後台兩分頁+三欄(1)→ Agent CI+min_host_version+release-keys/(1)→ BE 拿掉 ⑧(1)。 P2:BE Agent 線(檢查/下載/相容/agent-bundles//host_version 退役)(2)→ FE Agent 區 v3(1)→ 主系統升級第 7 步搬包(1)。 P3(等 171 批 2):契約加事件形狀(1)→ Agent 事件推送元件+outbox kind+upgrade_order.sh detail(2)→ BE 收事件表+退役拉進度(1)→ FE 八格改讀表+看原因(1)。 P4(等 171 批 2):主系統 available/request 兩支(1)→ Agent 兩支端點+能力點(1)→ 主控台 Update.vue(1)。 P5:e2e+文件+結案出包(1~2)。

建議:照此。釘版套件 jedi-agent-protocol 有改動,P3 批 1 前要環境卡(可與 171 共用同一張)。詳細拆卡表等裁完在 design.md 用 cards.py 驗過再寫。


6. 不做什麼

不做 理由
Agent 直接連更新站 決策者裁;Agent 是客戶內網掃描機,不出網是賣點也是資安前提
Agent 差異包、只換單顆容器 FR-167 已裁不做;Agent 包本來就是整組映像
Agent 自動裝新版 與主系統同原則:任何版本都不自動裝,要人按
主系統版本線改名或搬 R2 資料夾 已有 10 版在 v1/,搬了舊主系統找不到
第二把發布私鑰專給 Agent 一把章兩種 payload_type 已能防互相冒充;多一把章多一個保管問題
心跳備援長期並存 心跳的 update/upgrade_result 只留一個版本給舊 Agent,與 FR-171 /update/notify 同節奏拔

7. 風險與陷阱

風險 怎麼防
兩條版本線被互相冒充(拿 Agent 1.5.0 清單餵給主系統) 兩種 payload_type 各驗各的;R2 路徑不同;更新站 product 欄進主鍵
171 通道卡延後,172 的 P3/P4 跟著卡 P1、P2 先跑;P3/P4 卡在 Stage 排 171 批 2 之後,工作坊自己等
容器換掉那幾步事件沒人送 新容器啟動時讀進度檔補送「步驟+結果」;主系統按 job_id upsert 不怕重送
事件送到但主系統多 worker 各寫各的 寫 DB 不寫行程快取;畫面只讀 DB
Agent CI 跟 BE CI 同時在 188 build 互撞(Nuitka linker crash) CI 設 resource_group: build-188,兩條 CI 串行
1.28 主系統沒帶 Agent,客戶以為「Agent 不見了」 第 7 步搬包+更新站補登 1.4.8;Agent 卡文案「隨主系統附帶」改「由主系統下載」
離線上傳的包被人塞假的 Agent 端驗章+sha256,公鑰隨包帶;PROD_KIDS 同一批
登記型共用檔(CONSOLE_SCOPES、result_outbox kind、contract pyproject、BE 路由表、FE console router.js)同批撞 拆卡時各自不同批,或最早那張卡一次掛完

8. 參考