FR-058 協調者中繼交接(第三棒)— SonarQube 三棒全數 commit、待端到端驗收(2026-07-31 晚)

這是中繼交接不是收尾。四款工具(ZAP / CINC Auditor / Nmap / GCB)已全數上線實測通過、 收尾文件已完成;FR-058.5 SonarQube 的 T-5.1~5.3 已全部 commit,但端到端驗收尚未完成 (目前只有 probe 通過,detection_executions 內 sonarqube 執行紀錄仍為 0 筆)。

⚠️ 三 repo 的 push 狀態已與前一棒不同——origin 上已有 FR-058 commits(見 §1.1), 前一棒「全部未 push」的敘述已過期。

前兩棒交接文件:

  • 2026-07-31-fr058-coordinator-handoff-2.md(第二棒)—— §1 狀態盤點已過期,其 §2 教訓 / §3 裁示仍有效
  • 2026-07-31-fr058-coordinator-midarc-handoff.md(第一棒)—— 只讀 §2 教訓 / §3 決策脈絡 / §7 裁示
項目 內容
本棒角色 協調、決策、派工、抽查。不寫 code、不跑測試、不寫文件——全部派 subagent(不帶 model 參數)
Branch 三 repo 皆 feature/FR-058不切 branch
接手第一件事 跑 §6 pre-flight 重查現況(SonarQube 那條線可能仍在跑,數字會變
下一個動作 §4.1——確認 SonarQube 線是否收工,未收工則不碰 agent repo;已收工則驗收 T-5.2/5.3

🧭 原始需求 / WHY(不讀會誤解範圍)

決策者原話:「目前的檢測工具管理 /plugin/tool-plugin-manage 還需要增加下面工具——OpenSCAP for Windows 解決方案 / Nmap / GCB / SonarQube。請幫我分析跟規劃,開成新的需求放到 Notion。」

工具清單的演變(不讀會搞不清楚為何最終清單跟原話對不上):

階段 發生什麼
起點 四項:OpenSCAP for Windows / Nmap / GCB / SonarQube
中途 追加 ZAP(第五個)
裁示① SonarQube 本期不做(D10 成 tombstone)
調研 「OpenSCAP for Windows」證實不可行(官方已放棄 Windows 支援),改由 InSpec / CINC Auditor 承擔
裁示② ZAP 優先上線,其餘分批
裁示③(2026-07-31 晚) SonarQube 重新納入,立為 FR-058.5(D13–D16 定案)

本案要解決兩件事:① 接入工具(現已八款);② 補平台結構性缺口(任務層敏感參數——原本 只有租戶層憑證有加密,任務層是明文且 FE 執行紀錄會顯示)。


§0 接手讀序

  1. 本文「🧭 原始需求 / WHY」+ §1 現況 + §4 下一步 + §5 待辦(必讀)
  2. 第二棒 2026-07-31-fr058-coordinator-handoff-2.md 的 §2(教訓)——⚠️ 其 §1 狀態盤點已過期
  3. 第一棒 2026-07-31-fr058-coordinator-midarc-handoff.md 的 §2 / §3 / §7——同樣只讀這三節
  4. design.md §2 決策表 D1–D16(D13–D16 是 SonarQube 決策)
  5. 全案 SUMMARY2026-07-31-fr058-arc-SUMMARY.md
  6. 需細節才開:handoff/2026-07-31-fr058-batch4-gcb-dispatch.mdhandoff/2026-07-31-fr058-closing-dispatch.md

冷接自檢(答不出來回去讀,不要碰任何東西)

  1. CINC Auditor 與 OpenSCAP 的架構方向剛好相反,差在哪? 提示:引擎裝在哪一端、誰主動連出。這個差異決定了 content 要送到哪裡。
  2. SonarQube connector 跟其他七款在行為上有一個根本差異,是什麼?為什麼? 提示:run() 裡少了一個所有其他 connector 都有的東西。
  3. 為什麼 fr058-1~13 套進了三環境,但 14~17 只在 DEV? 提示:中間發生了一件事,導致立了一條鐵律。

§1 當前狀態(2026-07-31 20:47 實查)

1.1 🔴 三 repo —— push 狀態已變,前一棒敘述過期

Repo HEAD 相對 main 相對 origin/feature/FR-058 working tree
BE dbd57824 第二棒交接文件 43 未推 1 .claude/skills/big-feature-workflow/SKILL.md modified + 一批與本案無關的 untracked docs(別的 arc 留的,不要清理不要 commit
FE fef7e94 T-5.3 FE 微調 13 未推 1 乾淨
agent 2d92ac4 T-5.2 SonarQube connector 25 未推 1 乾淨

⚠️ 與前一棒最大的差異:前一棒寫「三 repo 全部未 push」。現在 origin 上已經有 FR-058 的 commits,三 repo 各只差 1 個未推。決策者已確認 push 是他自己做的,不需追究

裁示不變push 永遠等決策者明示,不要因為「origin 已經有了」就自己補推剩下那 1 個。

1.2 三環境現況

環境 fr058 migration sonarqube 狀態 agent image 說明
DEV 17 available 0.2.20-fr0585-verify(⚠️ 見下) 開發環境,領先是正常的
STG 13 coming_soon 0.2.18 刻意落後
POC 13 coming_soon 0.2.18 刻意落後

DEV 領先的四支 migration1417):TWGCB profile 選項 / 工具描述 v2 / GCB 下拉清理 / SonarQube seed。皆刻意只套 DEV(見 §3 鐵律)。

⚠️ DEV agent 目前跑的是驗證用臨時 tag 0.2.20-fr0585-verify,不是正式 0.2.20 這是 SonarQube 那條線為了驗 T-5.2 自建的。/opt/evidence-agent/deploy/.envAGENT_IMAGE 已指向該臨時 tag。SonarQube 驗收完成後必須決定:是要 bump 成正式版號 (如 0.2.21)重建部署,還是回退到 0.2.20不要就這樣留著臨時 tag 進入上版流程。

1.3 八款工具現況

id code 名稱 status 驗收
1 openvas OpenVAS available 既有
2 nessus Nessus coming_soon 佔位
3 sonarqube SonarQube available(僅 DEV) 🔄 probe 通過,端到端未驗(見 §1.5)
4 openscap OpenSCAP available 既有(FR-057)
5 zap ZAP available ✅ 被動/主動通過;登入後對 SPA ❌(會打掛共用 ZAP,見 D12)
6 inspec CINC Auditor available ✅ 雙 transport 實跑:151 pass 131/fail 60、160 pass 300/fail 472
7 nmap Nmap available ✅ 實跑通過,HTML 證據
8 gcb 政府組態基準(GCB) available ✅ TWGCB 708 項實跑,檔名修正已驗(見 §1.4)

1.4 本棒(第三棒)完成的事

① §4.1 agent 0.2.20 部署矛盾已釐清 + GCB 檔名實測通過

前一棒留的矛盾(commit 訊息寫「待部署」但實查已是 0.2.20已確認:commit 訊息寫在部署 之前,實際已部署,不是 tag 覆蓋。實測證據(BE log 20:09:35 的 result payload):

政府組態基準(GCB)檢測報告_192.168.50.160_20260731.html
summary: pass 397 / fail 122 / notapplicable 225 / error 0

檔名不再是 CINC檢測報告_,統計數量級與 708 項基準相符。§4.1 結案。

② 敏感參數遮蔽查核完成——FE 無洩漏,但發現一個獨立的 at-rest 曝險(詳見 §5 第 1 項)

③ GCB 報告標題調查——已裁示作罷

決策者要求把報告最上方的 Cinc Auditor Report 拿掉。已確認:那行是 html2 reporter 寫死的, 與 profile 無關;profile 的 inspec.yml title 有正確生效(顯示在它下一行)。原本「改 title 就好」的假設不成立,要動得改 reporter 那層。決策者裁示:不能改就算了,不查了。 (副帶發現:報告左上角的 Display controls that are: Passed/Failed/Skipped 篩選 UI 與 profile 標題左緣重疊,同屬 reporter 內建,一併作罷。)

④ SonarQube 免費報表方案調研(決策者提問「除了付費還有其他模式轉報表嗎」)

結論:沒有值得換的方案,現行自組 HTML 路線正確。

方案 型態 格式 對公司 26.7.0 的風險
CNES Report Java CLI 或 server 外掛 DOCX/XLSX/MD/CSV ⚠️ 已知 CE 10.4 產報表噴 500,open issue 稱 standalone 不支援 25.x
RedCoffee Python CLI 打 Web API PDF 🟢 跑在 server 外,不受外掛相容性連累
sonar-pdf-report 舊 post-job 外掛 PDF ❌ 已廢棄
bitegarden 商用外掛 PDF/ODT/XLSX 💰 付費(決策者排除)

關鍵認知:SonarQube 本身沒有任何原生報表匯出,這是多年公開痛點。所有免費方案的做法 都跟我們的 connector 一樣——打 Web API 拉數據自組報表,差別只在誰組。裝在 server 上的 外掛全都脆弱(Community Build 改滾動發版後外掛跟不上)。公司自有 server 實查為 26.7.0.124771, 很新,會篩掉一半選項。若將來要豐富報表內容,可參考 CNES Report 的 DOCX 版面編排,實作路徑不用改。

1.5 🔄 FR-058.5 SonarQube —— 三棒全 commit,端到端未驗

內容 commit 狀態
T-5.1 BE seed(UPDATE 既有佔位列不是 INSERT)+ param_schema v1 7b9d831e ✅ 已套 DEV
T-5.2 agent connector sonarqube.py(probe + 拉快照 + 自組 HTML) 2d92ac4(agent repo) ✅ 已 commit
T-5.3 FE 微調(project_key 進主要參數 + summary 中文標籤) fef7e94(FE repo) ✅ 已 commit

⚠️ 但端到端驗收尚未完成,實查證據:

  • compliance.detection_executionssonarqube 執行紀錄 0 筆——從未實際派工跑過
  • agent log 只看得到 probe(測試連線)成功
    SonarQube probe 成功 base_url=http://192.168.50.171:9000 version=26.7.0.124771
  • 另有一筆 probe 失敗,是預期中的正確行為(token 型別檢查生效):
    SonarQube Token 無效。請確認填入的是 User Token(squ_ 開頭)——
    sqp_ / sqa_ 開頭的分析用 Token 只能推送掃描結果,無法讀取資料。
  • config.tenant_detection_tool_configs 已有 1 筆 sonarqube 租戶設定

T-5.2 的設計要點(從 commit message 摘,供驗收對照):

  • 平台第一支 pull-snapshot 型 connector——run() 沒有輪詢迴圈(其他七款都有), 因為 SonarQube Server 沒有任何觸發掃描的 API,只能讀 CI 已推上去的既有結果
  • probe()api/system/status + 帶 Bearer 的 api/authentication/validate顯式檢查 valid 欄位——該端點驗的是「當前身分是否有效」,匿名也算一種身分)
  • run() 序列:project_analyses(回空則明確 raise 引導先跑 sonar-scanner)→ qualitygatesmeasuresissues+facetshotspots,逐呼叫間檢查 cancel_event,單呼叫 timeout 60 秒
  • issue severity impacts[] 優先(MQR),缺席 fallback type+severity,相容 9.9 LTS〜2026.x
  • 自包含繁中 HTML(無外部資源),summary 取自 measures 不自行加總清單

connector 檔頭記錄的三項實測修正(都是打 API 才會踩到的坑,驗收時別回頭改掉):

  1. api/issues/search 不帶篩選會連 RESOLVED/ACCEPTED 一起回,但 summary 來自 measures 只算未處理項 → 實測 guidant-ai-backend 不帶篩選 total=845、measures 全是 0,兩者放同一份 報告就是「摘要說 0 項、明細列 845 條」的自我矛盾。故一律帶 resolved=false 統一口徑
  2. 10,000 筆硬上限ps=500 第 21 頁起直接報錯 → 統計數字取自 facets/measures(全量、 一次拿到),明細只取前 200 條並標示截斷事實
  3. branch 行為與原設計假設不符:原假設「Community 填 branch 一律回錯」,實測帶 branch=main 正常回 200,只有不存在的分支才 404 → 改為不預判 edition,照使用者填的送出

1.6 Notion

母案 CM-957(修正待驗證)。相關卡:CM-986~991(平台能力與 InSpec 線)、CM-992(GCB content 產製後續案)、CM-993(收尾追蹤)、CM-994~997(FR-058.5 SonarQube)、CM-984(ZAP SPA 後續案)、 CM-985(報告呈現優化,全案驗收後才做)。

Notion free plan 不支援 SQL 查資料源,用 notion-search + notion-fetch


§2 本棒的教訓

2.1 多 session 併發是本 arc 的常態,pre-flight 必須重查而非信任交接文件

本棒接手時交接文件寫「T-5.2 未開始」,但實查 agent repo working tree 有未 commit 的 768 行 connector + 602 行測試,mtime 顯示 4 分鐘前還在寫。到本棒寫這份文件時,T-5.2 T-5.3 都已 commit 完成。

紀律

  • 交接文件的狀態盤點寫下當刻就開始過期,pre-flight 一律實查 git log / DB / 容器,不要憑文件
  • 發現另一條線在同一 repo 作業 → 完全不碰該 repo(不 commit、不跑測試、不改檔), 唯讀查看可以
  • 派 subagent 前先確認有誰在跑,dispatch 必寫「顯式 git add 檔名、禁 -am

2.2 log 裡的 ERROR 不一定是缺陷——先確認那筆資料是怎麼來的

pre-flight 在 BE log 撈到 on_scan_succeeded 找不到對應 detection_executions,時間軸看起來像 「派工當下還在、回報時就消失」的資料遺失。深入查證後:那是另一條線手動 INSERT 的驗證用 task,繞過了 start_execution,所以從來沒有 detection_executions(不是被刪)。

判別方法:compliance.agent_tasks.created_user IS NULL 只可能來自手工 INSERT(API 路徑必填 curr_user)。同一晚共 4 筆(id 49/50/51/57)都留下相同錯誤簽名。

教訓:查異常先問「這筆資料是走哪條路徑產生的」,再問「程式有沒有 bug」。順序反了會花大 成本追一個不存在的缺陷。(決策者最終裁示不追,判定為 SonarQube 那條線做一半停掉的產物。)

2.3 「已修」的宣稱要問清楚範圍

第二棒 SUMMARY 寫「任務層敏感參數已修」,本棒實查 agent_tasks.params->'_credentials' 卻是 明文 WinRM 密碼 + 完整 SSH private key,一度誤判為迴歸。查證後是兩件不同的事

FR-058 修的 我看到的
來源 job_execution_detection_tools.tool_paramssecret:true 欄位 租戶層憑證表解密後的派工快照
at-rest 加密 envelope 明文
目前實例 只有 ZAP login_password winrm_password / ssh_private_key
誰做的 FR-058 本輪 FR-056 既有

「已修」的宣稱是準確的,只是範圍不含 _credentials收尾時 SUMMARY 措辭要補範圍界定, 否則下一棒會跟本棒一樣誤判(subagent 也自述進場時同樣誤判)。

2.4 承襲前兩棒的教訓(仍然有效,不要重蹈)

  • 錯誤分類要問「這個錯誤最早能在哪裡被發現?現在是在那裡被發現的嗎?」——本 arc 兩次把 真因(image 缺 git、Ruby 3.4 訊息截斷)誤報成「檢測引擎連線失敗」,兩次都把查修方向帶去 憑證與網路
  • 協調者的假設要標明是假設、容許被實測推翻——Ruby 3.4 那個 bug,協調者給 subagent 的 三個初始假設全錯
  • subagent 自報完成不等於正確,驗收要獨立抽查(開檔 / 查 DB / fetch Notion)

§3 已定裁示(不要重新討論)

# 裁示
1 push 永遠等決策者明示——origin 上已有的 commits 是決策者自己推的,不追究;剩下未推的 1 個/repo 不要自己補推
2 開發只動 DEV,STG/POC 需當次明確指示(含 DB 與部署)——見 §2.2 of 第二棒文件
3 commit 標籤不一致不回頭修——rebase 改寫歷史風險大於整齊
4 GCB content 產製 + 後台 content 管理機制列後續案 CM-992,不在 FR-058
5 config.detection_tools 沒有 i18n 機制——先不動(平台級缺口,FR-056 建表時就有)
6 CM-985(報告呈現優化)全案驗收後才做
7 SonarQube 為 FR-058.5(D13–D16)
8 GCB 報告內的 Cinc Auditor Report 標題不處理(2026-07-31,本棒新增)——那是 html2 reporter 寫死的,要改得動 reporter 層,決策者裁示作罷
9 SonarQube 不換報表方案(2026-07-31,本棒新增)——免費方案都是同樣的「打 API 自組」路線,無值得換的

§4 下一步

4.1 🔴 立即:確認 SonarQube 那條線是否收工

本棒交接當下,SonarQube 線疑似仍在進行(20:20 commit T-5.2、20:22 commit T-5.3、20:41 容器換成驗證用 image)。接手第一件事是確認它收工了沒:

# ① agent repo 有沒有新的未 commit 檔案(有 → 那條線還在跑,不要碰該 repo)
git -C ~/Projects/Billows/Audit-Manager/evidence-agent status --short
git -C ~/Projects/Billows/Audit-Manager/evidence-agent log --oneline -3

# ② DEV 容器跑的是不是還是驗證用臨時 tag
ssh jedi@192.168.50.123 "docker ps --filter name=guidant-ai-agent --format '{{.Image}}|{{.Status}}'"
# 目前:guidant-ai-agent:0.2.20-fr0585-verify

# ③ SonarQube 有沒有實際跑過(0 筆 = 端到端還沒驗)
psql -h 192.168.50.188 -p 25432 -U cmmgr -d guidant_ai_dev -c \
  "SELECT e.uid, e.status, e.started_at FROM compliance.detection_executions e
   JOIN config.detection_tools d ON d.id=e.detection_tool_id WHERE d.code='sonarqube'
   ORDER BY e.id DESC LIMIT 5"

若那條線還在跑 → 不碰 agent repo,等它收工同步 Notion 後再更新(決策者已指示: 「sonarqube 有另一個主線在跑,他們那邊結束會同步回 notion,你再更新就好」)。

若已收工 → 進 §4.2 驗收。

4.2 SonarQube 端到端驗收(那條線收工後才做)

派 subagent(不帶 model 參數)實際派一次 SonarQube 任務,驗收重點:

  1. 證據 HTML 產出且自包含(無外部資源)、繁中、可在證據池預覽
  2. summary 數字與 SonarQube UI 對得起來——注意 connector 刻意讓明細與摘要同口徑 (皆為未處理項,resolved=false),若看到「摘要 0 項、明細 845 條」就是回歸
  3. project_key 有出現在執行紀錄的主要參數區(T-5.3 的目的),不是落在摺疊區
  4. summary 標籤顯示中文(T-5.3 補的五個 i18n key)
  5. 驗收環境:http://192.168.50.171:9000,專案 guidant-ai-backend / guidant-ai-fetoken 查本機 ~/.zshrc,絕不寫進任何檔案

4.3 ⚠️ 驗收後必做:處理 DEV 上的臨時 image tag

DEV 目前跑 0.2.20-fr0585-verify(驗證用臨時 tag),.envAGENT_IMAGE 已指向它。 驗收通過後要決定:bump 成正式版號(如 0.2.21)重建部署,或回退 0.2.20不要讓臨時 tag 進入上版流程。

4.4 待決策者裁示

# 事項 建議
1 agent_tasks.params._credentials at-rest 明文(DEV 現有 45 筆含明文 SSH 私鑰/WinRM 密碼) 選項①:改存加密 envelope、心跳組裝時才解(複用現成 common/util/detection_secret_params.py,不用新造輪子,且消除「同一張表兩種標準」)。會動派工路徑,四款工具都要回歸 → 現在做還是列後續案?
2 121/122 主機的 AGENT_VERSION 舊 pin STG/POC,依鐵律等決策者當次指示。屬顯示用版本字串不影響功能,可等上版一併處理
3 CM-985 是否納入 SonarQube CM-985 要檢討「summary 語意跨工具不一致」,SonarQube 會再加一種形狀。建議寫進 CM-985,否則做完又要再調。已提出未回覆

§5 待辦與風險

# 項目 嚴重度 說明
1 agent_tasks.params._credentials 永久明文 租戶憑證表本身加密(credentials_encrypted),但每次派工都解密後明文快照進 agent_tasks從不清除。DEV 53 筆帶憑證、其中 45 筆含明文 WinRM 密碼或完整 SSH private key。等於加密儲存的防護被派工快照繞過——拿到 DB 讀權限即可取得全部私鑰。寫入點 app/detection_tools/service/detection_orchestration_service.py:117非本輪迴歸(FR-056 既有)。對外 API 無洩漏(見下)
2 FE 是否洩漏敏感參數 ✅ 已查證無虞 執行紀錄經兩層剝除(detection_orchestration_service.py:399-400:底線開頭 key 整個拿掉 + 加密 envelope 拿掉)。api_logs 實測近 7 天:winrm_password 40 次、ssh_private_key 45 次、login_password 5 次,全部為 ***,未遮蔽 0 次BEGIN ... PRIVATE KEY 明文 0 筆
3 孤兒 execution 會讓 job 永久卡死 若出現「execution 存在但 agent_task 不見」,start_execution 見到 running 就 409,而 _cancel_running_execution 反查不到 task 直接拋 CANCEL_FAILED連 force 都繞不過。兩表間無 FK(全 soft-ref),手動刪 agent_tasks 不會連帶清。最小修法:cancel 在 task 查無時仍標 cancelled 後放行 + warning log
4 稽核 log 遮罩是欄位名 regex 低(前瞻) common/util/common_util.py:202-221mark_password() 比對 password|passphrase|secret|token|credential|authorization|api_key|private_key。未來若新工具的 secret 欄位名不含這些字(如 SNMP community_string)會靜默漏遮。目前八款工具無此類欄位
5 DEV agent 跑臨時 tag 0.2.20-fr0585-verify,見 §4.3
6 STG/POC 落後 DEV 四支 migration + 兩版 agent 低(刻意) 開發期正常。上版時一併處理,且 sonarqube 在 STG/POC 仍是 coming_soon
7 GCB profile 的角色分流用不到 profile 支援 --controls-tag role=baseline(只跑 326 項),但 InspecConnector._scan_one_host 沒傳該參數,派工一律跑全部 708 項。要支援需同時改 connector 與 param_schema
8 CM-974 第 5 條假設(SIGTERM 取消路徑)未驗 可用取消按鈕順便驗
9 ZAP 對 SPA 的登入後掃描會打掛共用 ZAP 已知 D12,後續案 CM-984。setup_guide 已標示「請勿對 SPA 使用登入後掃描」
10 detection_tools 無 i18n 中(已裁示不動) name/description/setup_guide/param_schema label 全中文寫死
11 _pick_agent 無負載平衡 / tenant_config_id 從未寫入 / 證據關聯靠 description 字串前綴 既有技術債,本案不處理
12 DEV 殘留 3 筆手工 agent_tasks(id 49/50/51,created_user IS NULL 極低 無執行紀錄、不影響 UI(執行歷史以 detection_executions 為準)。清不清都行

§6 Pre-flight(必跑)

# ① 三 repo 狀態(含 origin 落差——本 arc 已有部分 push)
for d in ~/Projects/Billows/Audit-Manager/compliance-manager-be \
         ~/Projects/Billows/Audit-Manager/compliance-manager-fe \
         ~/Projects/Billows/Audit-Manager/evidence-agent; do
  echo "=== $(basename $d) ==="; git -C "$d" branch --show-current; git -C "$d" log --oneline -1
  echo "ahead-main=$(git -C "$d" rev-list --count main..HEAD) unpushed=$(git -C "$d" rev-list --count origin/feature/FR-058..HEAD 2>/dev/null)"
  git -C "$d" status --short | head -5
done

# ② 三環境 DB(密碼查 .env 的 DB_SECRET,勿寫進任何檔案)
export PGPASSWORD=$(python3 -c "import json;from dotenv import dotenv_values;print(json.loads(dotenv_values('$HOME/Projects/Billows/Audit-Manager/compliance-manager-be/.env')['DB_SECRET'])['rds_master_password'])")
for db in "192.168.50.188|guidant_ai_dev" "192.168.50.188|guidant_ai_stg" "192.168.50.189|guidant_ai_poc"; do
  h=${db%%|*}; n=${db##*|}; echo "=== $n ==="
  psql -h $h -p 25432 -U cmmgr -d $n -tAc \
    "SELECT id||' '||code||' '||status FROM config.detection_tools ORDER BY id" | tr '\n' ' '; echo ""
  psql -h $h -p 25432 -U cmmgr -d $n -tAc \
    "SELECT count(*) FROM public.schema_migrations WHERE filename LIKE '%fr058%'"
done

# ③ SonarQube 端到端是否已驗(0 筆=未驗)
psql -h 192.168.50.188 -p 25432 -U cmmgr -d guidant_ai_dev -c \
  "SELECT e.uid, e.status, e.started_at FROM compliance.detection_executions e
   JOIN config.detection_tools d ON d.id=e.detection_tool_id WHERE d.code='sonarqube'
   ORDER BY e.id DESC LIMIT 5"

# ④ 三台 agent(⚠️ 123 目前是臨時 tag 0.2.20-fr0585-verify)
for h in 192.168.50.121 192.168.50.122 192.168.50.123; do
  echo -n "$h: "; ssh -o ConnectTimeout=6 jedi@$h \
    "docker ps --filter name=guidant-ai-agent --format '{{.Image}}|{{.Status}}'"
done

# ⑤ BE 服務(port 8000;main_socketio.py 是 socket 8002 不是 API 入口,重啟必先 kill -9)
lsof -i :8000 | head -3
tail -200 ~/Projects/Billows/Audit-Manager/compliance-manager-be/log/app.log | grep -i 'Traceback\|ERROR' | tail -10

# ⑥ agent 測試(必帶 PYTHONPATH=.,repo 缺 conftest.py)
# ⚠️ 若 agent repo working tree 有未 commit 檔案 → 另一條線在跑,不要跑測試
cd ~/Projects/Billows/Audit-Manager/evidence-agent && PYTHONPATH=. poetry run pytest test/ -q | tail -3
# 基線:435 passed, 1 skipped(0.2.20 當下,T-5.2 加入後會更多)

§7 環境座標

項目
DEV agent 192.168.50.123,容器 deploy-guidant-ai-agent-1,deploy 目錄 /opt/evidence-agent/deploy(⚠️ 不是 ~/deploy),ssh jedi
STG / POC agent 192.168.50.122 / 192.168.50.121
測試目標 192.168.50.151(Linux/SSH,audit-scan 已設 NOPASSWD sudo)、192.168.50.160(Windows Server 2025/WinRM)
SonarQube http://192.168.50.171:9000(實查版本 26.7.0.124771;token 查 ~/.zshrc絕不入檔
DB DEV/STG 192.168.50.188、POC 192.168.50.189,port 25432,帳號 cmmgr
content 投放 主機 /opt/evidence-agent/deploy/content/ → 容器 /data/content/(唯讀掛載)
profile 版控 BE repo content/detection-profiles/不放 agent repo——Dockerfile 最後一行 COPY . . 會讓它進 image,違反 D7)

§8 行為規範

  • 不切 branch——永遠在 feature/FR-058;branch 不對停下問決策者
  • push 永遠等明示——即使 origin 上已有部分 commits
  • 顯式 git add 檔名,禁 -am——BE working tree 有一批無關的 untracked docs
  • 收尾等命令——plan approve ≠ 自動收尾
  • 憑證禁入版控
  • BE 出錯先看 logtail -200 log/app.log | grep -A 30 -i 'Traceback\|ERROR'
  • 改 service/serializer 後 BE 必重啟kill -9 舊 pid,use_reloader=False 不會自動重載)
  • subagent 一律不帶 model 參數(繼承 1M context);文件類派工必寫「分段寫檔
  • 測試一律 headless
  • 任務發佈後最長等 300 秒才開跑(心跳週期,正常行為不是故障)
  • agent image 重建必帶 --platform linux/amd64,build 完 docker inspect 確認
  • docker compose up 必指定 service 名guidant-ai-agent),否則連帶 recreate agent-db/nginx
  • 已知現象:本機 docker image inspect <tag> 對新 tag 可能報 No such image,用 image ID 可以 (Docker Desktop containerd 多平台索引行為,非損壞)
  • 另一條線在同一 repo 作業時,完全不碰該 repo(唯讀查看可以)

§9 收尾流程(全案驗收通過、決策者下令才做)

  1. SPEC 三頁補 SonarQube(writing-feature-specs skill)
  2. 使用手冊補 SonarQube 段
  3. design.md §11 對應段標 closed
  4. 全案 SUMMARY 更新——⚠️ 「任務層敏感參數已修」必須補範圍界定(見 §2.3), 否則下一棒會誤判 _credentials 明文為迴歸
  5. Notion CM-994~997 標 Done + 母案 CM-957 更新
  6. memory:本 arc 教訓濃縮(候選:多 session 併發 pre-flight 紀律、log ERROR 先問資料來源路徑)
  7. commit 收尾文件(顯式 git add

§10 不在本期 scope

  • GCB content 產製 + 後台 content 管理機制(CM-992)
  • ZAP 對 SPA 的登入後掃描(CM-984)
  • 報告呈現優化(CM-985,全案驗收後)
  • detection_tools i18n(已裁示不動)
  • GCB 報告內的 Cinc Auditor Report 標題(裁示 8,作罷)
  • SonarQube 換報表方案(裁示 9,作罷)

§11 給 fresh session 的短 prompt

接手 FR-058(檢測工具擴充)的協調與決策工作。

交接文件:
docs/features/FR-058-2607-detection-tools-expansion/handoff/2026-07-31-fr058-coordinator-handoff-3.md

先讀該文的「🧭 原始需求 / WHY」+ §0 讀序,讀完回答 §0 的冷接自檢三問,再跑 §6 pre-flight。
⚠️ 前兩棒交接文件的 §1 狀態盤點都已過期,只讀它們的教訓 / 決策脈絡 / 裁示三節。

現況:四款工具(ZAP / CINC Auditor / Nmap / GCB)全數上線實測通過。FR-058.5 SonarQube
的 T-5.1~5.3 已全部 commit,但端到端驗收未做(detection_executions 內 sonarqube 0 筆,
只有 probe 通過)。⚠️ 三 repo 的 origin 上已有 FR-058 commits(決策者自己推的),
各只差 1 個未推——但 push 仍永遠等我明示。

你的下一個動作是 §4.1——確認 SonarQube 那條線是否收工(它在本文寫成當下疑似仍在跑)。
還在跑就完全不碰 agent repo,等它同步 Notion 後再更新;已收工則進 §4.2 端到端驗收。
另注意 §4.3:DEV agent 目前跑的是驗證用臨時 tag 0.2.20-fr0585-verify,不是正式版號。

你的角色是協調、決策、派工、抽查。不寫 code、不跑測試、不寫文件——全部派 subagent
(不帶 model 參數)。收尾類動作等我下令。
🔴 開發只動 DEV,STG/POC 要我當次明確指示才能碰(含 DB 與部署)。