FR-058 第二批(InSpec/CINC → GCB)實作 session 派工交接(2026-07-30)

項目 內容
緣由 FR-058 分批出貨。第一批(ID 解耦 + 任務層敏感參數 + ZAP,CM-958〜970)實作已完成、agent 已 bump 0.2.12 部署 DEV 中。本文是第二批(InSpec/CINC → GCB)實作 session 的派工單
Branch BE:feature/FR-058(不切 branch);evidence-agent:當下 branch(HEAD c775fc8 bump 0.2.12)
本棒角色 實作者。 完成 FR-058.2(InSpec/CINC connector)與 FR-058.3(GCB),依 T-2.1〜T-2.4 + T-3.1〜T-3.3 順序做,每個子任務完成即 commit + 回寫 Notion 卡
接手前必讀 本文全份 + design.md §2(D5/D6/D7/D8)+ §4.3〜§4.4(InSpec 與 GCB 詳細設計)+ §5.5〜§5.6(子任務表)
上游文件 docs/features/FR-058-2607-detection-tools-expansion/handoff/2026-07-30-fr058-planning-complete-handoff.md(全案大圖與需求演變;本文已摘實作所需部分,卡住時才回頭讀)

§0 讀序

  1. 本文 §1(範圍)→ §2(硬性決策約束,逐條遵守)→ §3(第一批帶來的新事實)
  2. design.md §4.3(FR-058.2 InSpec/CINC 詳細設計)+ §4.4(FR-058.3 GCB 詳細設計)全讀
  3. design.md §2 的 D5 / D6 / D7 / D8 定案原文(本文 §2 是摘要,原文含被排除方案與理由)
  4. §4 的範本檔案——動手寫每個子任務前先開對應範本照形狀寫

§1 任務範圍與 Notion 卡

1.1 範圍

第二批 = FR-058.2(InSpec / CINC Auditor)→ FR-058.3(GCB),共 7 個子任務,序列執行(.3 依賴 .2 的 connector,不可對調)。

# 子任務 Repo 一句話
T-2.1 seed InSpec/CINC(connection_type 涵蓋 SSH 與 WinRM)+ config_field_schema(雙 transport 憑證,含條件顯示)+ param_schema + setup_guide(含 CINC 授權說明與 WinRM 啟用前提);三環境套用 BE migration
T-2.2 Dockerfile 加入 CINC Auditor + inspec.py 骨架(雙 transport 連線參數解析)+ probe()(連線 / 認證 / CINC 可執行三段檢查與錯誤分類) evidence-agent connector 骨架
T-2.3 run() 執行 profile + --reporter json 統一解析 + 逐台多檔證據 + host_failures 逐台失敗回報 + cancel_event / timeout evidence-agent connector 主體
T-2.4 結案 Notion CM-953(本 FR 吸收,於 T-2.3 完成時一併標記) Notion 結案
T-3.1 seed GCB 條目(引擎指向 .2 的 CINC,Windows 與 Linux 共用)+ param_schema(含 content 來源指定欄位)+ setup_guide;三環境套用 BE migration
T-3.2 content 外部載入接口(profile 由外部提供給 connector,不硬編、不隨 agent image 發布) evidence-agent 接口
T-3.3 一份 Windows 最小 Demo profile(必須落在 HKLM\Software\Policies 正規政策區)——端到端鏈路的驗收留到全案最後(見 §5),本子任務交付 profile 本體與載入驗證 evidence-agent Demo content

1.2 Notion 卡對照(完成後逐卡回寫,母案 CM-957:https://app.notion.com/p/3ad346da4cd081859d2ed8b21ca2697c

對應 Notion URL
CM-971(FR-058.2 母卡) InSpec / CINC Auditor https://app.notion.com/p/3ad346da4cd0811faa85fd15a38df059
CM-972 T-2.1 從母卡 CM-971 子卡清單進入
CM-973 T-2.2 同上
CM-974 T-2.3 同上
CM-975 T-2.4(結案 CM-953) 同上
CM-976(FR-058.3 母卡) GCB https://app.notion.com/p/3ad346da4cd08120b9f1cf9b1f976847
CM-977 T-3.1 從母卡 CM-976 子卡清單進入
CM-978 T-3.2 同上
CM-979 T-3.3 同上

CM-953https://app.notion.com/p/3ac346da4cd0819390d2c5b85c754bf8,「FR-057 後續:異質 OS 環境的檢測支援方案」):規劃階段已先標 Done 並指向 CM-971;T-2.4 時確認其結案敘述指向實際落地的 commit 與 connector,補上一段白話結案說明(InSpec/CINC 即該案選項 2 的具體答案,「一任務一工具、多任務處理異質環境」模型沿用未改)。


§2 硬性決策約束(design.md §2 已拍板,實作不得偏離)

逐條列出,違反任一條即為錯誤實作:

  1. D5 授權紅線:必須用 CINC Auditor(Apache 2.0 自由重建版,Progress 官方認可的 drop-in 替代品),不可用官方 InSpec 6+ 商業 binary(需接受 Chef EULA 並持有 license key)。打包方式可自由選(apt / 直接下載 binary),授權來源不可換setup_guide 與部署文件都要寫明這一點。
  2. D6 雙 transport 一次到位:SSH(Linux)+ WinRM(Windows)都做,同一套 CLI 與 profile 格式,結果解析統一走 --reporter json(兩個 transport 輸出格式一致,connector 只寫一套解析)。不要只做 WinRM——GCB 的 Linux 線之後就要回頭補一次。
  3. D7 GCB 不另立引擎、不另寫 connector:GCB 跑的就是 inspec.py,T-3.x 不新增任何 connector 檔案。content 只做一份 Windows 最小 Demo profile;驗收條件是「鏈路可運作」,不是「涵蓋多少規則」——不要做 content 工程。
  4. D7 content 必須可外部載入:profile 不可硬編進 connector、不可打包進 agent image。理由:content 會持續變動,打包等於每次更新 content 都要重新發版並更新所有客戶站點 agent。T-3.2 的驗收就是「更換 content 不需重建 image、不需改 connector 程式碼」。
  5. D8 content 格式 = InSpec profile(Ruby DSL)。不引入 XCCDF + OVAL 第二套格式——引擎統一的真正目的是 content 格式統一。
  6. WinRM 憑證預設走租戶層tenant_detection_tool_configs 加密鏈(與 SSH 同模型)。只有「每台主機不同帳密」的情境才走 FR-058.0 的任務層敏感參數(平台能力已就緒,見 §3.3),不要一開始就往任務層推。
  7. Windows GPO tattoo settings 陷阱:Demo profile 的檢查規則必須讀 HKLM\Software\Policies 正規政策區。非 Policies 路徑的設定套用前不會被清空、會殘留(tattoo settings),讀到殘留舊值會誤判為通過——稽核情境屬嚴重問題。Demo 選題時就要挑正規政策區的項目。
  8. 多目標處理沿用 FR-057 模式:逐台掃、每台一個證據檔(result_ref.upload_uids 多檔回收鏈直接沿用),host_failures 逐台失敗回報——其中一台失敗不可拖垮其他台,也不可靜默假成功。
  9. connection_typeWinRM 為新值SSH 已存在);detection_tools.connection_type 需涵蓋兩種型態,seed 時注意欄位值與 FE 渲染相容。

遇到 D1–D11 沒涵蓋的新決策:停下來回報,不要自己開新方向(判斷原則見 design.md §2 各條的「被排除方案與原因」欄)。


§3 第一批帶來的新事實(第二批直接受益 / 必須遵守)

3.1 factory 已改依 code 取 connector(agent commit f17a311,D11)

  • get_connector() 現在優先吃 detection_tool_codedetection_tool_id 降為 fallback(走 fallback 記 warning log)。
  • 新 connector 的註冊方式:在 core/task_executor_connectors/__init__.py 加一個 _build_inspec() builder(import 留在 builder 內部,維持 lazy import 慣例——某支 connector 的第三方相依缺失時只有該工具不可用),並在 _CONNECTOR_BUILDERS dict 加 "inspec": _build_inspec(實際 code 以 T-2.1 seed 的 detection_tools.code 為準)。
  • 絕不把新工具加進 _LEGACY_TOOL_ID_TO_CODE——檔頭註解已明訂該表只涵蓋 FR-056/057 已出貨四筆,新工具加入等於把剛移除的脆弱性種回去。ZAP 已照此模式(參考 _build_zap)。

3.2 BE 派工 payload 已夾帶 detection_tool_code(BE commit 5151fb2c,T-X.1 已上線)

_collect_pending_tasks() 已加欄位,第二批不需要動 BE 派工鏈——seed 進 detection_tools 後派工自然帶 code,agent 端照 §3.1 註冊即可接上。

3.3 任務層敏感參數平台能力已就緒(同 commit 5151fb2c,T-0.1〜0.3)

param_schema 欄位標 secret: true 即自動走 Fernet 加密落庫 / 派工解密下發 / FE 與稽核 log 剝除(實作在 common/util/detection_secret_params.py)。第二批預設用不到(WinRM 憑證走租戶層,見 §2 第 6 條),但若真遇到「每台主機不同帳密」需求,直接標 secret: true 即可,不需自建機制。

3.4 D4 教訓通則化:報告取得 API 必須先驗「回傳內容 bytes」

ZAP 原定用 reports.generate 產 PDF,實作時發現該 API 只把檔案寫進工具主機磁碟、回傳路徑字串,官方沒有回傳檔案內容的端點(zaproxy issue #7821)——遠端部署模型下 agent 拿不到,被迫改案(改 core.htmlreport 取 bytes)。

通則:任何「工具端產檔」的設計,動手前都必須先驗證取得管道回的是內容本體而不是「對方主機上的路徑」。InSpec 走 CLI --reporter json 輸出 stdout / agent 本機檔,天然沒有此問題——但若 T-3.2 content 載入或任何環節出現「由目標主機/工具主機產檔再取回」的設計,先驗這一點再寫。

3.5 agent 版號

第一批已 bump 0.2.12(部署 DEV 中)。第二批出貨版 bump 0.2.13,bump pattern 照 evidence-agent commit c46aeeb——四處版號同步pyproject.toml / config/config.pyAGENT_VERSION 預設值)/ deploy/docker-compose.ymlAGENT_IMAGE + AGENT_VERSION 兩處)/ rebuild.sh(註解範例)。注意依 §5 測試紀律,開發期間不重建 image、不部署,bump commit 做完留著等全案端到端才出貨。

3.6 第一批可照抄的實作水準基準

  • seed SQL:scripts/sql/2026-07-30-fr058-1-zap-seed.sql(見 §4)——檔頭把決策背景寫成註解、ON CONFLICT DO NOTHING、用 nextval 自然拿 id 且註明「code 派工後 id 不影響正確性」、schema_migrations 收尾。
  • mock 單元測試:test/test_zap_connector.py(485 行,47 項全 mock + 突變測試驗斷言真咬)——InSpec connector 測試照此水準寫 test_inspec_connector.py

§4 實作範本座標(照形狀寫,不重新發明)

4.1 BE seed 範本(T-2.1 / T-3.1)

檔案 用法
/Users/chouraymond/Projects/Billows/Audit-Manager/compliance-manager-be/scripts/sql/2026-07-30-fr058-1-zap-seed.sql 最新範本,優先照抄——nextval 拿 id + 「code 派工後 id 不影響正確性」註解、ON CONFLICT (code) DO NOTHING、param_schema 的 condition / secret / default 寫法、setup_guide 的 E'' 多行 markdown 寫法、schema_migrations 收尾
/Users/chouraymond/Projects/Billows/Audit-Manager/compliance-manager-be/scripts/sql/2026-07-28-fr057-1-openscap-seed.sql FR-057 版範本,SSH 型工具的 config_field_schema(SSH 帳號 / 金鑰欄位)可參考

4.2 agent connector 範本(T-2.2 / T-2.3)

檔案 用法
~/Projects/Billows/Audit-Manager/evidence-agent/core/task_executor_connectors/openscap.py(578 行) InSpec 最像它——SSH 多目標多檔型:逐台掃、每台一個證據檔、host_failures 逐台失敗回報、SSH 私鑰暫存處理、probe() 分段檢查與錯誤分類。InSpec 在它之上多一個 WinRM transport 分支
~/Projects/Billows/Audit-Manager/evidence-agent/core/task_executor_connectors/zap.py(480 行,剛出爐) 第一批的新 connector——cancel_event / timeout 輪詢寫法、summary 解析容錯、log 紀律(憑證絕不進 log)的最新範例
~/Projects/Billows/Audit-Manager/evidence-agent/core/task_executor_connectors/base.py DetectionConnector ABC、ScanResultScanCancelledErrorcancel_event / host_failures / content_mismatch_hosts 注入點——介面不動

4.3 factory 註冊(T-2.2 的一部分)

~/Projects/Billows/Audit-Manager/evidence-agent/core/task_executor_connectors/__init__.py——f17a311 之後改依 code 註冊(見 §3.1)。照 _build_zap 的形狀加 builder + _CONNECTOR_BUILDERS 一列,不動 _LEGACY_TOOL_ID_TO_CODE。factory 迴歸測試在 test/test_connector_factory.py(90 行),新 code 註冊後補對應 case。

4.4 其他座標

檔案 用途
~/Projects/Billows/Audit-Manager/evidence-agent/Dockerfile T-2.2 加入 CINC Auditor(授權紅線見 §2 第 1 條)
~/Projects/Billows/Audit-Manager/evidence-agent/test/(跑法 PYTHONPATH=. poetry run pytest test/ -q,repo 缺 conftest.py 必帶 PYTHONPATH) 單元測試落點
BE app/remote_agent/service/agent_enrollment_service.py 派工鏈(只讀參考,第二批預期不動——code 夾帶已上線)

§5 測試紀律(決策者 2026-07-30 裁示,取代原「批次結束測一次」)

5.1 端到端驗收整批延後

端到端驗收延後到全案最後一次做(與第一批、第三批合併驗收)。開發期間:

  • 不重建 agent image
  • 不部署(121 / 122 / 123 三台都不動)
  • 不跑真實掃描(不對真實 Linux / Windows 目標發動 InSpec 掃描)

版號 bump 0.2.13 的 commit 照做(§3.5),但不出貨。

5.2 做中持續做的便宜檢查(照舊,每個子任務完成前必過)

檢查 做法
import / 語法檢查 PYTHONPATH=. poetry run python -c "from core.task_executor_connectors.inspec import ..." 之類,改完即驗
mock 單元測試 全 mock、不碰網路與真實主機;水準對齊第一批 test/test_zap_connector.py(47 項全 mock + 突變測試驗斷言真咬——刻意改壞被測邏輯確認測試會紅,避免寫出永遠綠的假測試)
SQL 套 DEV 後 SELECT 驗證 seed 檔套 DEV 後 SELECT id, code, connection_type, status FROM config.detection_tools ORDER BY id + 查 detection_tool_param_schemas 確認 schema 進去且 is_current 正確

5.3 seed migration 三環境都要套

DEV → STG → POC 三環境(指令照 CLAUDE.md「DB 環境清單」段;密碼請查 .envDB_SECRET 或部署文件,禁入任何版控檔案):

# DEV
psql -h 192.168.50.188 -p 25432 -U cmmgr -d guidant_ai_dev \
  --single-transaction -v ON_ERROR_STOP=1 -f scripts/sql/<fr058-2 seed 檔>.sql
# STG(同台不同 DB)
psql -h 192.168.50.188 -p 25432 -U cmmgr -d guidant_ai_stg \
  --single-transaction -v ON_ERROR_STOP=1 -f <同上>
# POC(另一台)
psql -h 192.168.50.189 -p 25432 -U cmmgr -d guidant_ai_poc \
  --single-transaction -v ON_ERROR_STOP=1 -f <同上>

SQL 撰寫鐵則:檔頭 -- Date:、每個語句加日期註解、收尾 INSERT public.schema_migrations(本批只 seed 不建表,若意外需建表則必加 GRANT ... TO cm_app + sequence 權限)。


§6 行為規範(實作 session 會踩到的,逐條遵守)

  • 不切 branch:任何 git checkout <branch> / git switch <branch> 一律不執行。BE 永遠在 feature/FR-058 工作;發現 branch 不對停下回報,不自己 fix(「為了在正確 branch commit 而切 branch」也不允許)
  • push 永遠等決策者明示,不自動 push;階段性 commit(子任務完成後)直接做,毋需停下問
  • 顯式 git add 檔名,禁用 -am——避免誤 add 其他 arc 留下的 untracked / modified 檔案
  • 跨 repo 各自分開 commit:BE 與 evidence-agent 的改動不混在一個 commit 敘事裡
  • 憑證禁入版控:密碼、token、API key 絕不寫進任何會 commit 的檔案(含 SQL migration、docs、handoff)。連線資訊只寫帳號 / host / port / db 名,密碼一律寫「請查 .env 或部署文件」
  • 收尾類動作等命令:SPEC / SUMMARY / memory / Notion 母案收尾一律等決策者明確下令,子任務 commit 完只回報 status,不往收尾跑
  • Notion 卡回寫格式(每個子任務完成後):狀態改「修正待驗證」+ 補一段白話說明(做了什麼、怎麼驗證的)+ commit hash + 執行紀錄(跑了哪些檢查、結果)。格式參考第一批 CM-967〜970 的回寫
  • BE 出錯先看 logtail -200 log/app.log | grep -A 30 -i 'Traceback\|ERROR',log 沒線索才回報
  • 不要晶晶體(中英夾雜語法),不用「速贏」一詞

§7 給 fresh session 的超短派工 prompt(直接複製貼上)

接手 FR-058 第二批(InSpec/CINC → GCB)的實作工作。

完整讀序入口:
/Users/chouraymond/Projects/Billows/Audit-Manager/compliance-manager-be/docs/features/FR-058-2607-detection-tools-expansion/handoff/2026-07-30-fr058-batch2-dispatch.md
先讀它全份(含 §2 硬性決策約束與 §3 第一批新事實),再照它的 §0 讀序開 design.md §4.3-§4.4。

範圍:T-2.1〜T-2.4(CM-972〜975,母卡 CM-971)+ T-3.1〜T-3.3(CM-977〜979,母卡 CM-976),
序列執行,T-2.4 完成時一併結案 CM-953。

硬紅線速記:CINC Auditor 不可換官方 InSpec 商業版(D5);SSH+WinRM 雙 transport 一次到位、
--reporter json 統一解析(D6);GCB 複用 inspec.py 不另寫 connector、content 必須可外部
載入不打包進 image、只做一份 Windows 最小 Demo profile(D7/D8);Demo 規則必讀
HKLM\Software\Policies 正規政策區;新 connector 依 code 註冊、絕不加 _LEGACY_TOOL_ID_TO_CODE。

測試紀律:端到端驗收整批延後到全案最後,開發期間不重建 image、不部署、不跑真實掃描;
只做 import 檢查 + 全 mock 單元測試 + SQL 套 DEV 後 SELECT 驗證;seed 三環境都要套。

BE 在 feature/FR-058 工作,不切 branch、不 push、顯式 git add 禁 -am;每個子任務完成即
commit 並回寫 Notion 卡(修正待驗證 + 白話說明 + commit hash + 執行紀錄);收尾動作等我下令。

📌 寫完自檢:下個 session 只看這一份 + design.md §4.3-§4.4,能不能不回頭問任何人就開工?——本文所有路徑 / 卡號 / commit hash / SQL 指令皆可直接使用;密碼類資訊一律指向 .env