| 項目 | 內容 |
|---|---|
| 緣由 | 前一棒(本 session)走完 big-feature-workflow Step 1(五支平行探脈)+ Step 2(HTML 討論稿產出並發 Artifact)。接手棒次負責:協助決策者逐項拍板 D1–D18 → Step 3 落地 design.md → Step 4 Notion 母子 case 樹 → Step 5 交接 prompt |
| Branch | feature/e2e-env-build(不要切 branch,發現不對停下問決策者) |
| 角色定位 | 分析決策 / 協調者 —— 實作與文件產出一律外包(派 subagent 或開 case),本體只做需求釐清、決策討論、拍板、派工、抽查 |
| 接手前必讀 | 本文件 §0 讀序(討論稿 Artifact 為主,一次讀完) |
| 預估時間 | 拍板討論 1–2 小時(視決策者節奏);Step 3–5 各派一支 subagent |
| 現況 | Step 2 完成,等拍板。討論稿已發 Artifact,尚未 commit(docs/features/FR-060-.../ 整個資料夾是 untracked) |
「目前只有項目,user 完全不知道這個東西會驗證什麼,我怎麼知道我要選什麼?哪些基準可以參考,我可以先請負責人去判斷、提前先處理,而不是等報告出來才去處理。」
FR-059 做完了「掃描設定檔管理」(/plugin/detection-profile-manage)—— 把 profile 打包檔收進平台庫、agent 拉檔執行。但平台把 profile 當成 opaque binary,完全不理解內容:使用者在管理頁與任務下拉看到的只有一個名字(如「TWGCB-01-014 Ubuntu 22.04 LTS v1.2」),不知道它會驗什麼、驗幾項、哪些項目其實跑不出結果。
一個支撐急迫性的實測數字:TWGCB-01-014 共 234 條控制項,其中 199 條是人工待判項(impact 0.0,跑起來是 skip),實際自動檢查只有 35 條。使用者現在完全看不到這件事 —— 他選了、掃了、拿到一份 85% 是 skip 的報告,才發現。
決策者要的是提前判斷:選之前就看得到內容,可以先請負責人評估、先處理,而不是等報告出來才補救。
決策者在討論過程中明確要求:「你要拿出你專業設計師的模式,而不是每次都用最快達到要求的模式把功能做出來,底層設計很重要。」
技術上的必然性:現在 config.detection_tool_profiles 是單表,版本鏈靠 (detection_tool_id, tenant_id, name) 三值推斷 —— 拿 name 當身分,這正是改名改不動的根因;而分類三軸(標的類型/產品/基準體系)是「這支 profile 是什麼」的屬性,不是「這一版是什麼」的屬性,存在單表會每版重複、版更漏帶就漂移。
而且現在是最便宜的時機:13 筆資料、FR-059 上線才兩天、沒有租戶真的在用。等 FR-061(選用範圍/豁免)把設定綁上去再拆,成本是現在的好幾倍。
FR-060(本案)
.1 資料模型重構 主從拆表 + controls 表 + 13 筆搬遷 + RLS 移位 + 派工鏈兩處破口修補
.2 分類體系 + 基本資料編輯(含改名)
.3 控制項抽取 + 瀏覽 BE 裝 CINC + 非同步抽取管線 + 詳細頁
────── 以上第一批:全在管理面,不碰 agent、不動派工參數
FR-061(下一案,本案只定模型契約不做實作)
.4 選用範圍 + 豁免(--controls / --tags / --waiver-file)
.5 人工判定那 199 條 / 自訂檢查項(wrapper profile)
切線在管理面/執行面之間:.1–.3 最壞情況是詳細頁少一塊,既有掃描零影響;.4 起動掃描參數,改錯會讓結果不對(GRC 系統裡使用者以為自己合規是嚴重問題)。
docs/features/FR-060-2608-detection-profile-content-management/discussion.htmldocs/features/FR-059-2608-detection-profile-library/design.md §3 決策表(P1–P7 + D1–D10)—— 本案疊在它上面,D2(profile:<uid> 前綴契約)、P4(版本模型)、D8(驗證深度界線)三項與本案直接相關docs/specs/current/system-admin/detection-profile-manage.md §12 邊界情況與已知坑(13 條)—— 現況坑清單,其中坑 2「detection-profile.update capability 是預留孤兒」正是本案 D8 要消費的.claude/skills/big-feature-workflow/SKILL.md —— 本棒要接著跑 Step 3–5profile:<uid> 這個契約為什麼不能動?動了會壞什麼?| # | 範圍 | 關鍵產出 |
|---|---|---|
| 1 | BE 拆表影響面 | 全部讀寫點盤點、四個自訂查詢改寫方向、fork/copy 語意重想、派工鏈兩處破口 |
| 2 | frameworks 主從前例 |
完整實作模式;發現該前例的 main_version_id FK 已被官方認錯廢棄 |
| 3 | inspec json 實跑 |
真實輸出形狀、體積與耗時、錯誤形狀、推翻「必須解壓成目錄」的假設 |
| 4 | FE 現況 | 管理頁改動量、PrimeVue 分組能力實查、控制項清單可複用元件 |
| 5 | migration / RLS | 13 筆資料、RLS 四段全文、遷移三段式路徑、發現 STG 已服役 |
docs/features/FR-060-2608-detection-profile-content-management/discussion.html(1,003 行)%%{init:...}%% 單行、D1–D18 齊全、無憑證洩漏這四項都是前一棒先講了、探脈才發現講錯的。接手時若看到舊說法(例如在對話摘要裡),以這裡為準:
| 錯誤說法 | 實測真相 | 影響 |
|---|---|---|
| 「當前版本用 FK 指標,不是布林旗標」 | oscal.frameworks 的 main_version_id FK 已被官方認錯並事實廢棄(2026-06-16 改字串欄、列入待 DROP)。三個傷害:循環 FK 逼拆兩段 DDL/刪除流程被綁死/DB 保證不了唯一 |
應保留 FR-059 現行的 is_current 布林 + partial unique index |
| 「拆表對派工鏈零影響」 | 兩處會壞:_load_profile() 的 is_active 守門(拆表後在主檔)→ AttributeError 或靜默失效(已停用 profile 照樣派得出去,無聲授權漏洞);_humanize_profile_param() 的 getattr(profile,"name",None) → 通知信 profile 名稱靜默退化成 uuid,且現在沒有任何測試會抓到 |
需新增 get_version_with_profile(uid) 回主+從合成 entity |
| 「CINC 吃目錄,必須解壓,與不落地驗收條件衝突」 | CINC 直接吃 .tar.gz / .zip(實測 exit 0、234 條、輸出與讀目錄一致)。衝突根本不存在 —— T-1.3 禁的是「解壓成目錄樹」,不禁「把壓縮檔本身寫成臨時檔」 |
抽取管線設計大幅簡化 |
| 「FR-059 只在 DEV」 | STG 已服役:STG(188 的 guidant_ai_stg)與 DEV 同為 125 筆 migration,config.detection_tool_profiles 存在且有 10 筆(全 SYSTEM 無 TENANT),RLS 四段齊全 |
拆表是要 rename 一張 STG 正在服役的表;且 STG 無 TENANT 資料 → 「STG 跑得順」不能當驗收 |
決策者 2026-08-03 明確選擇(看過實測數據後仍維持)。
curl -fsSL https://omnitruck.cinc.sh/install.sh | bash -s -- -P cinc-auditor -v 7docs/claude/host-dependencies.md 加第三項inspec-core gem 是 Chef 官方發布受 EULA 影響,同樣不可用CINC_AUDITOR_CMD → PATH → 絕對路徑 fallback),不要硬編 /usr/bin/cinc-auditor任務綁版本 uid(現行行為,D2 契約零變動、10 筆既有綁定零轉換)。
但純鎖版有合規漏洞:TWGCB 發新版、排程任務無聲繼續掃舊版,使用者以為合規實際不是 —— 在 GRC 系統裡這是正確性問題不是 UX 瑕疵。故要配「此基準已有新版 vN,目前使用 v1」徽章 + 一鍵換版,換不換是使用者決定,但必須知情。
拆表後「是不是現行版」就是主檔 current_version_id 一次比對,menu API 順手帶回,成本極低。BE 側留 FR-060;FE 徽章與一鍵換版若範圍太肥可移 FR-061(BE 先備好)。
被排除:跟隨現行版(同任務前後跑出不同結果、稽核無法回溯、破壞凍結契約 + 要轉換既有資料)。
18 項全在討論稿 §3,每項已含「我的建議」+ 利弊 + 被排除方案。接手要做的是陪決策者逐項確認,不是重新分析。
| 優先 | D 項 | 為什麼先問 |
|---|---|---|
| 1 | D1 主從欄位歸屬 | 定了之後 D2(當前版指標)、D3(從檔 RLS)、D15(is_active 放哪)大半跟著定 |
| 2 | D5 分類三軸定義 | 決策者最核心的需求;enum 值域、「標的產品/基準體系」要不要合併都在這 |
| 3 | D14 主列表 vs 版本歷史 | 決定 FE 重構範圍,也影響 D10(extraction_status 落點) |
| 其餘 | D2–D4、D6–D13、D15–D18 | 多為技術取捨,決策者沒異議就照建議走 |
impact == 0.0 —— 用 tags.check_type == 'pending' 會漏 6 條(twgcb_01_014_0079~0084 標 check_type: 'service' 但實為 impact 0.0 + 只有 skip)。impact 是 InSpec 原生語意,外來 profile 也一定有is_active 守門靜默失效屬無聲授權漏洞照 big-feature-workflow skill:
docs/features/FR-060-2608-detection-profile-content-management/design.mddocs/features/FR-057-2607-openscap-ssh-connector/design.md):檔頭狀態列 → 變更紀錄表 → 需求背景與端到端流程 → 決策定案表 D1–D18(每項含定案理由與被排除方案)→ 現況接入點盤點 → 詳細設計 → 拆分表 → 端到端驗收docs/features/README.md FR 登記表加一列collection://23c346da-4cd0-8041-955e-000bb6976dd2CM/來源 雷門/作業人員 小弟/狀態 Not started/需求編號 FR-060(母案)或 FR-060.x(子卡)per 子需求一份可複製 code block,含實際 Case No + 必讀清單 + 關鍵約束 + 回寫規則 + 「停下等驗收」結尾。
cd ~/Projects/Billows/Audit-Manager/compliance-manager-be
# ① branch 必須是 feature/e2e-env-build(不對就停下問決策者,不要自己切)
git branch --show-current
# ② FR-060 資料夾狀態(預期:整個資料夾 untracked,尚未 commit)
git status --short docs/features/FR-060-2608-detection-profile-content-management/
# ③ 討論稿存在且完整(預期 1003 行、4 張 mermaid、D1-D18)
wc -l docs/features/FR-060-2608-detection-profile-content-management/discussion.html
grep -c 'class="mermaid"' docs/features/FR-060-2608-detection-profile-content-management/discussion.html
grep -o 'D1[0-8]\|D[1-9][^0-9]' docs/features/FR-060-2608-detection-profile-content-management/discussion.html | grep -o 'D[0-9]*' | sort -u -V | tr '\n' ' '
# ④ FR 編號未被佔用(預期:README 最大整數號仍是 059)
grep -c "FR-060" docs/features/README.mdDB 唯讀盤點(密碼取自 .env 的 DB_SECRET,不要寫進任何檔案):
export PGPASSWORD=$(python3 -c "
import json
for line in open('.env'):
line=line.strip()
if line.startswith('DB_SECRET='):
print(json.loads(line.split('=',1)[1])['rds_master_password']); break
")
# 預期 13 筆(10 SYSTEM / 3 TENANT),全部 version=1
psql -h 192.168.50.188 -p 25432 -U cmmgr -d guidant_ai_dev -c \
"SELECT scope, count(*) FROM config.detection_tool_profiles GROUP BY scope;"model override)git add 檔名,禁用 -am;不 push(永遠等決策者明示);不切 branch.env」)| 項目 | 為什麼不做 |
|---|---|
| HTML 轉換機制/討論稿改 md | 🔴 已切成獨立案 CM-1049(https://app.notion.com/p/3b1346da4cd081b48d09e80c3f5389fb),決策者會另開專門 session 處理。本棒完全不碰 —— 不要自己去改 render_html.py、不要研究 pandoc、不要動 big-feature-workflow skill 的產出定義。若需要產 HTML 文件,照現行方式(手刻 + 分段寫入)即可 |
| FR-061 的實作(選用範圍/豁免/人工判定/自訂項) | 本案只寫模型契約,不做實作。形狀應由 .1–.3 上線後的實際使用決定 |
| 既有手刻 html 回頭轉 | 屬 CM-1049 範圍 |
| profile 內容線上編輯 | 與 InSpec 設計哲學逆行(上游不可變、疊加物獨立),已在討論過程排除 |
| 順手修 FR-059 的其他坑 | spec §12 有 13 條坑,只處理與本案直接相關的(坑 2 update capability 孤兒、坑 4 停用降 is_current) |
本 session 沒有為 FR-060 做任何 commit —— docs/features/FR-060-2608-detection-profile-content-management/ 整個資料夾是 untracked。
| 產出 | 狀態 |
|---|---|
discussion.html(1,003 行) |
已寫入、已發 Artifact、未 commit |
| 本交接文件 | 已寫入、未 commit |
| CM-1049(HTML 轉換另案) | 已建卡,內容自足 |
工作 branch 最近三個 commit(與 FR-060 無關,是前面別條線的):
1d8d8b6c fix(detection-profile): 停用後無法以同名再建(CM-1047)
13a3720b docs(handoff): 首腦中繼交接——E2E 測案 arc 現況與三張待派 case
6feaa0ab docs(e2e): 190 部署真 agent 方案(CM-1048)+ 凌晨驗收巡檢報告
注意
1d8d8b6c是 FR-059 的 bug 修復(停用後同名無法再建),與本案 D15(is_active歸屬)相關 —— 拆表後那個 bug 的修法可能要重新檢視。
接手 FR-060(檢測 Profile 內容管理)。
先讀交接文件:
docs/features/FR-060-2608-detection-profile-content-management/handoff/2026-08-03-fr060-discussion-to-design-handoff.md
照它的 §0 讀序走:先讀「🧭 原始需求/WHY」段,再全讀討論稿 Artifact
https://claude.ai/code/artifact/223cf4dd-72c7-43a7-8215-6067b02e601e
(1,003 行、18 項待決策、4 張圖),然後答 §0 末的冷接自檢 4 問。
答完跑 §6 pre-flight(全唯讀)。
⚠️ HTML 轉換機制已切成獨立案 CM-1049 由別的 session 處理,你不要碰
(不改 render_html.py、不研究 pandoc、不動 skill 產出定義)。
讀取與盤點完成後不做任何事——不派工、不跑測試、不改檔,
回報「自檢答案 + 現況盤點 + 待辦已就緒」後等我下指令才開始作業。