FR-156 · 需求討論稿 v1 · 2026-10-21(D1~D7 已於對話中拍板,本稿把定案展開並補 D8~D12 待裁)

客戶程式碼不進主系統,弱點資料天天自己更新

第三方元件掃描的執行位置從主系統沙箱搬到客戶機房的 Agent;弱點資料由我們每日發布、主系統自動抓、Agent 自動同步

FR-134 做出來的「第三方元件風險」目前是顧問把客戶原始碼壓縮檔上傳到主系統,由主系統的沙箱跑掃描工具。PM 判定這不行:掃公司程式碼的東西不能預設放在我們的主系統。本案把掃描搬到客戶機房那台 Agent 上,原始碼直接從瀏覽器傳到 Agent、不經主系統;回主系統的只有元件清單與弱點結果。同時把現在要人手上傳的弱點資料改成每日自動:我們在 build 機排程產包蓋章、放到 Cloudflare,主系統每天自己抓,Agent 透過既有心跳通道跟著同步。FR-134 尚未進版、沒有客戶裝到伺服器端掃描版,現在改成本最低。

D1~D7 對話中拍板 D8~D12 待裁 FR-134 未進版,改執行位置零客戶影響 跨 4 repo:BE/FE/jedi-python-package/evidence-agent 陷阱:工具 bundle 全 amd64,Agent 機要 x86_64 陷阱:每台 Agent 多 5GB 弱點資料

狀態:討論稿,等決策者審 D8~D12|日期:2026-10-21|前作 FR-134(功能完成、未進版、休眠) 雛形:prototype/index.html(四幕:精靈選 Agent、Agent 清單弱點資料欄、系統設定弱點資料頁、檢測工具任務頁)


1. 需求背景

1.1 PM 的三個意見(2026-10-21)

# PM 說什麼 白話翻譯 本稿對應
① 第三方套件掃描做在主系統不行,掃公司程式碼的東西不能預設放在我們主系統,要改到 Agent 端掃 客戶的原始碼不該離開客戶自己的機器 §3 執行位置搬 Agent
② 掃描工具都不能自動更新;弱點更新太快,叫 user 自己更新庫或我們一直派人出去都不可能 弱點資料要自己每天更新,不靠人 §4 弱點資料自動同步
③ 掃描工具的設定(帳密)都在主系統,想改到 Agent 那台機器開 Web UI 設定、用主系統帳號登入、設定存 Agent 端 客戶機敏的連線帳密也不該放我們這 獨立成 FR-157,本稿不展開

1.2 現況哪裡痛

FR-134 的設計(2026-10-10 定案)把 Syft/Trivy/Grype/OSV 四支工具併進主系統的 guidant-sandbox 容器,顧問上傳的源碼包存進主系統儲存(SeaweedFS),worker 送沙箱掃。當時排除「做成 Agent 執行器」只有一個理由:Agent 要帶 4.7GB 弱點資料且每台都要更新。

這條理由被 PM 意見②反過來解掉:弱點資料本來就要有自動更新機制,有了機制,Agent 帶資料就不是障礙。

另外兩個現況事實讓搬家變便宜:

  • Agent 已經在跑同型工作:FR-058.7 的 SonarQube 掃描就是「源碼包下載到 Agent 本機、安全解壓、跑 sonar-scanner、報告回雲端」。FR-134 搬過去是照先例做第七個執行器。
  • FR-039 的原始不變式本來就寫「雲端任何路徑不得把 binary 寫進雲端磁碟」。FR-134 把源碼包存進主系統儲存,與這條精神相悖;PM 的意見與原始架構一致。

1.3 不做什麼(對話中已裁)

不做 原因
Agent 程式本體自動升級、「版本過舊提示」 決策者裁「不做,先做弱點掃描庫自動更新」。工具版本換等於檢測行為換,應釘版隨 Agent 發版
保留主系統沙箱掃描當選項 兩套執行位置兩套弱點資料投遞,維護翻倍;沙箱 image 也不用再被出貨弱點閘掃三支工具
Agent 直連網路抓弱點資料 守 FR-039「Agent 只連雲端」不變式,封閉網路客戶同一條路
磁碟用量優化(拿掉 Grype 等) 決策者裁「先不管」;只做切換後刪舊版

2. 分工概述(30 秒版)

整案一句話:顧問在精靈多選一台 Agent,原始碼直接傳到那台機器上掃,結果照舊回主系統看;弱點資料我們每天自動發、主系統自動抓、Agent 自動跟上,沒有人需要按任何按鈕。

子需求 做什麼 產出 完成怎麼判定(決策者檢查法)
A 每日發布鏈 188 的 GitLab runner 每日排程:產弱點包 → License Center 蓋章 → 上傳 Cloudflare R2 → 更新 latest.json CI 排程 pipeline、R2 bucket、公開下載網址 隔天早上開瀏覽器打 https://<站台>/vulndb/latest.json,日期是昨天;下載的包用產品驗章工具驗得過
B 主系統自動抓 既有「每日自動檢查更新」預設開、更新站預設指我們的 R2;抓到新包驗章、寫入 volume、留紀錄(沿用 FR-134 B3/B4) 設定預設值調整、紀錄表多一種來源 一台連網的 DEV 什麼都不按,隔天系統設定頁「弱點資料日期」自己前進,紀錄多一列來源寫「自動下載」
C Agent 同步 心跳回應帶「雲端現有弱點資料日期+sha256」;Agent 比對本機較舊就走控制面通道下載、驗章、原子切換、刪舊;Agent 清單每台顯示資料日期 Agent 端 vulndb 同步模組、心跳契約擴充、清單欄位 主系統更新後五分鐘內,Agent 清單那台的「弱點資料」欄日期跟上;拔掉 Agent 機的外網線照樣跟上
D Agent 掃描執行器 Agent 加 sbom_scan 執行器:取源碼包/SBOM 檔 → 安全解壓 → Syft → Trivy/Grype/OSV 離線 → 回傳 SBOM 多格式與三家原始 JSON;工具四支進 Agent 的 tools-manifest Agent 執行器、tools-manifest 四列、能力宣告 sbom_scan 派一筆掃描給 Agent,Agent 機上 ps 看得到 syft/trivy 在跑;主系統結果頁數字與 FR-134 伺服器端掃同一包的結果一致
E 源碼直傳 Agent 精靈「掃描來源」頁多一步選 Agent;瀏覽器直接 PUT 檔到那台 Agent 的資料面(8443);主系統只收到檔案 uid 與 sha256;掃完源碼包留在 Agent 本機可設保留天數 精靈改版、Agent 資料面新端點、主系統契約 瀏覽器開發者工具看上傳請求目的地是 Agent 的 IP 不是主系統;主系統儲存裡找不到那個 zip
F 收掉伺服器端路徑 沙箱 image 拔四支工具、/v1/scan 端點退役、server_side_dispatch 分岔收掉、檢測工具「SBOM 弱點掃描」改回一般 Agent 執行器(任務頁出現 Agent 指派欄) 沙箱瘦身、派工分岔刪除、工具目錄列改值 沙箱容器裡 which syft 找不到;建檢測工具任務選「SBOM 弱點掃描」會出現 Agent 指派欄,與 OpenSCAP 一樣
G 收尾 SPEC 三頁改寫、手冊「弱點資料怎麼更新」整段改寫成「不用做任何事」、安裝文件磁碟需求、FR-134 的 vulndb 設定頁保留但降為「狀態與紀錄」 文件 手冊找不到「請上傳更新包」這句當主要路徑

依賴:A → B → C 串行;D 可與 A 平行開工(開發期用手動放的弱點資料);E 要 D;F 要 D+E 驗過;G 最後。先讓決策者看到畫面的順序:E 的精靈改版與 C 的清單欄位是最先看得見的,雛形已含。


3. 執行位置搬 Agent

3.1 搬完之後的端到端

%%{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'}}}%%
sequenceDiagram
    participant U as 顧問(瀏覽器)
    participant API as 主系統 api
    participant AG as Agent(客戶機房)
    participant DB as 主系統 DB
    U->>API: 精靈:建掃描對象、選 Agent
    API->>DB: 建 source_scans(queued,agent_uid)
    API-->>U: 回「上傳票」(短效、綁這台 Agent)
    U->>AG: PUT 源碼包 到 Agent 8443(帶上傳票)
    AG->>AG: 落本機 /data/scan-input,算 sha256
    AG-->>U: 回 file_uid、sha256
    U->>API: 送 file_uid、sha256 → 開始掃描
    API->>DB: 建 agent_tasks(sbom_scan)
    AG->>API: 心跳 → 領走 pending_tasks
    AG->>AG: 安全解壓 → syft → trivy/grype/osv(離線,讀本機 vulndb)
    AG->>API: 回傳 SBOM 多格式+三家原始 JSON(不含源碼)
    API->>API: 正規化:配對、KEV/EPSS、六區塊統計、NTIA
    API->>DB: 寫 components/findings/summary(done)
    U->>API: 看結果、匯出報表(與現在完全相同)
圖 1 — 掃描時序(搬家後):源碼不經主系統,只有結果回來

守住的邊界:主系統從頭到尾沒有碰過原始碼。回來的是 SBOM(套件名與版本清單)與弱點比對結果。D1 已裁這兩樣留雲端。

3.2 現況接入點盤點(可複用 vs 要新寫)

元件 現況 本案動作
Agent 檢測執行器框架 evidence-agent/core/task_executor.py + task_executor_connectors/ 六支(openvas/openscap/zap/inspec/nmap/sonarqube);sonarqube.py 已有「下載源碼包 → 安全解壓 → 跑 CLI → 回報」整條 新增第七支 sbom_scan.py,解壓與限額直接借 sonarqube 那段(D13 借檢查器不借流程的精神)
Agent 工具 bundle scripts/build/tools-manifest.txt 釘版+sha256,fetch_bundle_tools.sh 拉、啟動驗簽章;全 amd64 加 syft/trivy/grype/osv-scanner 四列(版本與 FR-134 沙箱同:syft 1.54.0/trivy 0.75.0/grype 0.120.0),單檔靜態二進位、零系統依賴
Agent 能力宣告 common/util/agent_capabilities.py 兩個:file_storage、detection_scan,隨心跳自報 加 sbom_scan;雲端派工資格條件多看這個
Agent 資料面 8443 mTLS,端點 /blob(證據上傳)、/detection/probe、/detection/cancel 加 /scan-input(PUT 源碼包、回 uid+sha256);瀏覽器沒有客戶端憑證,見 §3.3
Agent 心跳契約 回應帶 pending_tasks、error_tracking、allowed_targets(core/enroll.py:322-335 兩個 observer) 加 vulndb observer(§4.3)
雲端正規化層 jedi_source_scan/app/service/normalize/(trivy/grype/osv parser、merge、summary、ntia、risk_rating)吃三家原始 JSON 原樣沿用,輸入從「沙箱回傳」改成「Agent 回傳的檔」
雲端掃描 job jedi_source_scan/app/jobs/sbom_scan_job.py:取檔 → 送沙箱 → 存產物 → 正規化 → 寫表 拆成兩半:派工半(建 agent_task)+結果半(收 Agent 回傳後正規化)。沙箱那步刪掉
雲端派工分岔 jedi_detection/app/service/server_side_dispatch.py(is_server_side → 不派 Agent) 退役;「SBOM 弱點掃描」工具目錄列 execution_mode 改回一般
精靈 FE SourceScanWizard.vue 三頁:基本資料/掃描來源/掃描設定 掃描來源頁加「選 Agent」(有 sbom_scan 能力且在線的才列;只有一台自動選);上傳目的地改 Agent
Agent 清單 FE RemoteAgentManage.vue 欄位:名稱、位址、狀態、能力、版本 加「弱點資料」欄(日期+距今天數,30 天黃 90 天紅)
沙箱 guidant-sandbox image 含四支工具、/v1/scan 拔掉,回到只拆檔;守衛測試不變

3.3 瀏覽器怎麼直傳到 Agent(E 的關鍵問題)

Agent 的 8443 強制驗客戶端憑證(mTLS),瀏覽器沒有憑證,直接 PUT 會被擋。三個選項:

選項 做法 優 劣
**a. 上傳票(建議) 主系統簽一張短效票(JWT,5 分鐘、綁 agent_uid+scan_uid+使用者),瀏覽器帶票 PUT 到 Agent 另一個單向 TLS 埠**(例 8444);Agent 用雲端公鑰驗票(既有 verify_data_plane_jwt 路徑) 源碼真的不經主系統;Agent 零新信任關係(公鑰註冊時就有);FR-157 的登入也走同一套票 要開第二個埠;自簽憑證瀏覽器會警告(§3.4)
b. 經主系統串流 relay 瀏覽器照舊傳主系統,主系統邊收邊轉給 Agent,不落磁碟 瀏覽器零改動、無新埠 原始碼仍「經過」我們的機器,PM 問起說不清;大檔 relay 吃 api 連線
c. 8443 加白名單路徑免驗客戶端憑證 同一個埠,/scan-input 不要求 client cert 不開新埠 TLS 層的 client cert 驗證是整個 listener 的設定,Python ssl 做不到按路徑放行;要改成 CERT_OPTIONAL 等於全埠降級

D8 瀏覽器直傳 Agent 走哪條

建議:a 上傳票+第二埠。守住「不經主系統」這句話,也是 FR-157 登入要用的同一把機制,做一次用兩次。

3.4 自簽憑證與瀏覽器警告

Agent 的 TLS 憑證是我們自己的 CA 簽的(註冊時由雲端發),瀏覽器第一次連會跳「不安全」。處理方式:

  • 安裝精靈結尾印出 CA 憑證檔路徑與一句「匯入瀏覽器信任可消除警告」;手冊同步。
  • 精靈畫面在跳轉上傳前顯示一行提示:「檔案將直接傳到 Agent 機器 192.168.x.x,瀏覽器可能提示憑證警告,屬正常」。
  • 顧問要在客戶內網才連得到 Agent。這本來就是「程式碼不離開客戶機」的必然結果,手冊寫明。

D9 自簽憑證警告第一版接受嗎

建議:接受,手冊與畫面提示處理。替代方案是客戶自備該機器的正式憑證掛進 Agent,列第二期選配。

3.5 Agent 機的新前提

項目 數字 來源
弱點資料磁碟 約 5GB(4.7GB 常駐+切換時短暫並存) DEV 實測:grype 3.0G/trivy 1.5G/osv 287M/kev+epss 4M
四支工具二進位 約 250MB 單檔靜態 binary
掃描工作區 源碼包 100MB × 12 係數=約 1.2GB 暫用 沿用 FR-058.7 磁碟預留公式
記憶體 Grype 比對大 SBOM 峰值約 2~3GB FR-134 D12 沙箱 4g 的依據
CPU 架構 x86_64 only 工具 bundle 全 amd64(既有限制,不新增)

安裝文件的磁碟需求從現行數字加 7GB。


4. 弱點資料自動同步

4.1 三段式供應鏈

%%{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 JT["我們(每日 03:00,GitLab 排程 → 188 runner)"]
    UP["上游公開資料<br/>Trivy DB/Grype DB/OSV/KEV/EPSS"] --> BUILD["build_vulndb_bundle.sh<br/>(既有)"]
    BUILD --> LC["License Center 蓋章<br/>(既有 vulndb_manifest 型)"]
    LC --> R2["Cloudflare R2<br/>guidant-vulndb-YYYYMMDD.tar.zst<br/>latest.json"]
  end
  subgraph CUST["客戶(連網)"]
    R2 -->|"每日 GET latest.json<br/>較新才下載"| API["主系統 api/worker<br/>驗章 → volume → 紀錄"]
    API -->|"心跳回應:date+sha256"| AG1["Agent A"]
    API -->|"心跳回應"| AG2["Agent B"]
    AG1 -->|"GET /agents/vulndb/bundle<br/>(控制面通道)"| API
  end
  subgraph CLOSED["客戶(封閉網路)"]
    ADMIN["管理員上傳更新包<br/>(既有設定頁)"] --> API2["主系統"]
    API2 -->|同一條心跳機制| AG3["Agent C"]
  end
圖 2 — 弱點資料供應鏈:我們每日發布 → 主系統自動抓 → Agent 跟著同步

4.2 A 段:每日發布鏈(我們這邊的營運承諾)

項目 定案/建議
排程在哪跑 GitLab CI 排程 pipeline,tag guidantai-build(188 runner)。既有 .gitlab-ci.yml 已是「GitLab → 188 執行」模型,加一條 schedule 觸發的 job;Cloudflare 自己做不到(要抓數 GB 上游並跑 docker)
產包 既有 scripts/build/build_vulndb_bundle.sh,零改
簽章 License Center 既有 vulndb_manifest 型(決策者裁「有的話就從 188 跑」);LC 在 188 本機,產包腳本已接
存放與流量 Cloudflare R2,走 Cloudflare 網路對外,出站流量不計費;與官網同帳號
契約 latest.json:{bundle_date, file, sha256, size_bytes, sources{...}, tool_versions{...}};包本體 guidant-vulndb-<date>.tar.zst;保留最近 30 天
失敗怎麼知道 pipeline 紅 → 既有通知;連三天沒新包 → 主系統設定頭「更新站無新資料」黃字
時間 每日 03:00(台北);上游 Trivy/Grype 約 UTC 每 6 小時更新,03:00 抓到的是前一天完整資料

D10 R2 bucket 與公開網址

建議:bucket guidant-vulndb,自訂網域 vulndb.jedicotech.com(Cloudflare 同帳號一鍵綁);主系統 VULNDB_UPDATE_URL 預設值改成這個網址(現況預設空字串=不連網)。正式網域名由決策者定。

4.3 B 段:主系統自動抓

FR-134 B3/B4 已經做好:VulndbCheckUpdateRoute(向更新站檢查)、VulndbAutoUpdateRoute(每日自動開關)、驗章、日期不倒退、原子切換、vulndb_updates 紀錄表。本案只改三件事:

  1. VULNDB_UPDATE_URL 預設值改成我們的站(D10)。
  2. 「每日自動檢查更新」預設開(現況預設關);封閉網路客戶連不到站台時紀錄一列失敗、設定頁黃字提示改用上傳,不彈錯誤。
  3. 切換到新版後刪舊版目錄(現況保留;D7 裁「先不管」磁碟,但這一步零成本)。

4.4 C 段:Agent 同步

項目 設計
怎麼知道有新的 心跳回應 data 多一個 vulndb: {bundle_date, sha256, size_bytes}(雲端現行那份)。Agent core/enroll.py 加第三個 observer _observe_vulndb,比對本機 current/manifest.json 的 bundle_date
怎麼拿 新控制面端點 GET /api/1.0/agents/vulndb/bundle(通行證驗身、串流回包);Agent 走既有 _get_stream(FR-059.3 profile 投遞同款,含 sha256 對帳)
怎麼放 Agent 本機 /data/vulndb/<date>/,驗章(Agent 已帶出貨公鑰表 common/integrity/public_keys.py,加認 vulndb_manifest 型)→ 逐檔 sha256 → 原子切 current symlink → 刪舊
下載中掃描怎麼辦 掃描讀 current symlink 解析後的實路徑,切換是原子 rename,進行中的掃描繼續用舊版到結束
多台 Agent 同時抓 每台各自抓一次(4.7GB 解開、約 480MB 壓縮);同租戶多台就是 N × 480MB 內網流量,一天一次可接受
Agent 回報 心跳 payload 多 vulndb_date;雲端 remote_agents 加一欄 vulndb_date;清單顯示
掃描時的日期 source_scans.vulndb_date 改記Agent 回報的那次資料日期(Agent 結果 payload 帶),結果頁與報表照舊顯示
沒有弱點資料的 Agent 能力仍宣告 sbom_scan,但派工資格多一條「vulndb_date 非空」;精靈不列它,並在 Agent 清單標「弱點資料尚未同步」

D11 Agent 弱點資料從主系統拉還是主系統推

建議:拉(心跳得知 → Agent 自己 GET)。Agent 永遠是發起方,與 FR-039/059.3 一致;推要雲端主動連 Agent 資料面、要處理 Agent 離線重試,多一套狀態機。

4.5 FR-134 的「弱點資料」設定頁怎麼變

保留,但角色從「主要操作入口」變成「狀態與紀錄」:日期、來源五項、更新紀錄照舊;「上傳更新包」按鈕保留給封閉網路客戶;「檢查更新」保留當手動觸發;新增一塊 「Agent 同步狀態」(每台 Agent 的資料日期、最後同步時間),雛形第三幕。


5. 檢測工具入口怎麼變

FR-134 H 群把「SBOM 弱點掃描」做成工具目錄裡唯一的「伺服器端執行」工具,任務頁刻意不出現 Agent 指派欄。搬家後它變回一般 Agent 執行器:

現況(FR-134 H) 本案
config.detection_tools 該列 execution_mode=server 改回一般
建任務選它不出現 Agent 指派欄 出現,與 OpenSCAP/SonarQube 一樣(FR-067 多 Agent 派工照用)
start_execution 分岔到 server_side_dispatch 分岔刪除,走一般派工
源碼包隨任務執行時上傳到主系統儲存(FR-058.7 _source_file) 上傳改直傳 Agent(§3.3 同一條票),_source_file 改帶 Agent 本機 uid;FR-058.7 的 SonarQube 掃描順便一起改,不然同一個任務頁兩種工具兩種上傳目的地
結果經 DetectionResultForwarder 轉任務證據 原樣

D12 FR-058.7 SonarQube 的源碼上傳要不要一起改成直傳 Agent

建議:一起改。同一條「客戶程式碼不進主系統」的理由對 SonarQube 掃描完全成立,PM 的意見①字面就是「第三方套件掃描」但精神涵蓋所有掃源碼的工具。不改的話主系統儲存裡仍會躺著客戶源碼包,PM 問起要解釋兩套規則。成本是精靈外多一處上傳元件改目的地。


6. 決策彙整

6.1 對話中已拍板(2026-10-21)

# 問題 定案 理由
D1 SBOM 與弱點結果留雲端? 留 不留就沒有報表、歷次比對、任務證據
D2 主系統沙箱掃描保留當選項? 拔掉 兩套執行位置維護翻倍;沙箱不再被出貨弱點閘掃工具
D3 弱點資料雲端中繼還是 Agent 直連? 雲端中繼 守 FR-039 不變式,封閉網路同一條路
D4 Agent 程式自動升級/過舊提示? 都不做 先做弱點掃描庫自動更新
D5 憑證搬 Agent、多台各設一次? 可做;一個網段通常一台,或資料台與掃描台分開,各設正常 併入 FR-157
D6 產包/簽章/發布在哪 188 runner 排程產包、LC 蓋章、Cloudflare R2 發布 CI 跑的地方就是 188,LC 已接;R2 零出站費
D7 每台 Agent 多 5GB? 先不管 只做切換後刪舊

6.2 本稿待裁

# 問題 建議
D8 瀏覽器直傳 Agent 走哪條 a 上傳票+第二埠
D9 自簽憑證警告第一版接受? 接受,手冊與畫面提示
D10 R2 bucket 與公開網域 vulndb.jedicotech.com,預設寫進 config
D11 Agent 弱點資料拉還是推 拉
D12 FR-058.7 SonarQube 上傳一起改直傳? 一起改

7. 拆棒草案(design.md 定稿後開卡)

批 卡 改哪個 repo 依賴
1 A1 GitLab 每日排程 pipeline:產包→LC 簽→上傳 R2→更新 latest.json BE .gitlab-ci.yml、scripts/build/ —
1 D1 Agent 工具 bundle 加四支工具、能力宣告 sbom_scan evidence-agent —
1 D2 Agent sbom_scan 執行器(借 sonarqube 的下載解壓段) evidence-agent D1
2 B1 主系統:更新站預設值、自動更新預設開、切換後刪舊、連不到站的黃字 BE、jedi-source-scan、FE A1
2 C1 心跳契約加 vulndb、控制面 bundle 端點、remote_agents.vulndb_date、清單欄 jedi-remote-agent、jedi-source-scan、FE B1
2 C2 Agent 端 vulndb 同步模組(observer、下載、驗章、原子切換、刪舊、心跳回報) evidence-agent C1
3 E1 上傳票簽發與 Agent 第二埠+/scan-input BE、jedi-remote-agent、evidence-agent D2
3 E2 精靈改版:選 Agent、直傳、憑證提示;掃描 job 拆派工半/結果半 FE、jedi-source-scan E1
4 F1 收掉伺服器端:沙箱拔工具、/v1/scan 退役、server_side_dispatch 刪、工具目錄列改值、任務頁 Agent 欄 jedi-evidence-classification、jedi-detection、jedi-source-scan、FE、migration E2
4 F2 FR-058.7 SonarQube 源碼上傳改直傳 Agent(D12 裁了才開) FE、jedi-detection、evidence-agent E1
5 G1 SPEC/手冊/安裝文件 BE docs 全部

8. 風險與陷阱

風險 怎麼擋
Agent 機磁碟不夠,同步到一半爆 下載前 shutil.disk_usage 檢查(FR-058.7 既有公式),不夠就心跳回報「磁碟不足」、清單紅字,不嘗試下載
弱點資料驗章失敗(公鑰表沒有簽章用的那把鑰) FR-134 已踩:出貨公鑰表只認 189 正式鑰,DEV 開發鑰簽的包會被拒。Agent 端公鑰表要與產品端同一份;CI 一律用正式鑰簽
排程 pipeline 與人手跑的 build 在 188 撞 既有 pgrep 守門沿用;弱點包產製不碰 .venv/Nuitka,撞的機率低;排 03:00 避開人
Trivy Java 專案要 trivy-java-db FR-134 已註記:產品走 syft 產 SBOM 再 trivy 掃 SBOM,java-db 用不到;維持不包
上傳票被截走拿去傳別的檔 票綁 scan_uid+agent_uid+5 分鐘,一票一用(Agent 記 jti);檔 sha256 由主系統另外收一份,與 Agent 回報比對
Agent 回傳的 SBOM 不含源碼,但 Syft 的 SBOM 會帶檔案路徑 正規化層已處理(FR-134 元件清單攤原檔);路徑是相對路徑、不含內容,PM 可接受範圍要在 design 寫明
FR-134 的 source_scans.vulndb_date 現在記主系統那份日期 改記 Agent 回報的;舊資料為空的列照舊顯示

9. 這份文件的定位

你想知道 看
PM 說了什麼、對話裡裁了什麼 本稿 §1、§6.1
搬家後畫面長什麼樣 雛形
FR-134 原本怎麼設計、為什麼當時不派 Agent FR-134 design.md D4/D9
Agent 怎麼跑檢測、工具怎麼打包 FR-056、FR-066
檢測 profile 怎麼走控制面投遞(本案弱點資料同款) evidence-agent core/profile_cache.py 檔頭
帳密搬 Agent 端的 Web UI FR-157