換 session Handoff — 資安掃描 arc 後續優化 Runner(2026-07-25)

項目 內容
緣由 資安掃描主體修正已驗收(見 6d10fdfb),剩「品質債/優化」後續四工作用 runner loop 自動消化。本 session 跑完 20 輪,四工作全部到「修正待驗證」,交棒給下個 session 收尾(等 user 手測 → push → 收官)。
branch BE main、FE main兩 repo 都不切 branch,維持 user 當下 branch
接手前必讀 ① 本檔全部 ② docs/features/security-scan-2607/runner-loop-log.md(20 輪逐輪紀錄)③ 四個 Notion case 內文的「已完成修正(白話)」comment
預估時間 純收尾(等 user 手測回報 → push)約 0.5h;若 user 要接著做 backlog / jedi 線另計
狀態 四工作全部 = 修正待驗證,全部 commit 未 push。下個 session 不是修 bug,是「等 user 手測結果 → 按指示 push / 補 backlog」

🧭 原始需求 / WHY(置頂)

這整件事要解決什麼:2026-07-24 資安掃描(SonarQube + Trivy + Semgrep)主體洞已修完驗收。追查過程順帶盤出四類「非安全洞」的品質債/優化,開成 Notion case 排 backlog,交給一個自動 runner loop(就是本 session)分批、保守地消化,不混進資安主流程

  1. 小件:FE preact direct dep 掛 HIGH CVE-2026-22028,升版即可。
  2. CM-874 FE Sonar 品質債:SonarQube FE 1065 條,安全面無真實洞(唯一 VULNERABILITY 是 sessionShare Math.random 只產 tab id 誤報);其餘是品質債——2 條 CRITICAL bug + a11y label 缺失大宗 + S2486 靜默吞例外等。
  3. CM-876 富文本編輯器收斂:FE 同時養三套編輯器(quill EOL 掛 XSS CVE / ckeditor5 掛 MEDIUM CVE + GPL 授權疑慮 / TipTap 乾淨),收斂到單一 TipTap 拔掉前兩者 CVE 面。
  4. CM-873 BE Sonar 品質債:SonarQube BE 831 條 code smell(Quality Gate 通過、非安全洞),分批消化。

目標模型:runner 每輪照各 case 內文的「🔧 Runner 動工指引」段(授權範圍/禁區/分批/驗證/commit 規範)嚴格保守執行——只做指引明確授權的,禁區碰都不碰,拿不準一律跳過留 backlog,不追求 Sonar 歸零,只求「能安全清的都清完」。每 case 完成定義都是「修正待驗證」等 user 手測,runner 絕不自動標 Done

本棒在大圖的位置:runner 已跑完 20 輪、四工作全到「修正待驗證」。下一棒 = 收官:等 user 手測各 case → 按 user 指示 push(目前全 local)→ 決定要不要接著清 backlog / 動 jedi 線(那條不在 runner 清單)。


§0 接手讀序(按序讀,附冷接自檢)

🔒 硬 gate:先懂需求再碰任何 code / push

  1. 本檔「🧭 原始需求 / WHY」+ 本節 —— 搞懂「這是 runner 收尾不是修 bug」
  2. docs/features/security-scan-2607/runner-loop-log.md —— 20 輪逐輪紀錄(每輪:規則/目錄/條數/commit hash/跳過項),是本 arc 的完整帳本
  3. 四個 Notion case(見 §5 座標)內文各自的「## ✅ 已完成修正(白話說明)」comment —— 每 case 做了什麼、跳過什麼、待 user 手測什麼

gate 後才進 §6 pre-flight。

冷接自檢 4 問(答不出回去讀,別碰 code / 別 push)

  1. 這四工作現在是什麼狀態?(答:全部「修正待驗證」,全部 commit 未 push)
  2. 為什麼 runner 沒把它們標 Done?(答:完成定義是等 user 手測;runner 保守不自動關)
  3. 下個 session 該做什麼、不該做什麼?(答:該—等 user 手測結果按指示 push / 補 backlog;不該—自作主張 push、自動標 Done、動禁區/jedi 線)
  4. 為什麼一堆條目被「跳過」而不是修?(答:BE 無測試網 + 保守原則,設計意圖註解/介面綁定參數/需改邏輯者一律留 backlog,見各 case 白話說明)

§1 現況(四工作逐一)

① preact 升版 ✅

  • FE package.jsonpreact ^10.24.3^10.29.7(npm 解析至 10.29.7 ≥ 修復門檻 10.28.2,HIGH CVE-2026-22028 direct dep)
  • build:DEV 過。FE commit 2df15a1(單獨一 commit)。

② CM-874 FE Sonar 品質債 — 🔵 修正待驗證

  • 2 CRITICAL bug95fd44c):ComplianceFrameworkVersionManage.vue 兩 Dialog 版本輸入框 id="key" 重複 → id="version"(兼修 label 關聯 + focus-on-error);AppMenuItem.vue:42 handleRouteChange(route.path)handleRouteChange()(多餘引數,no-op,未動側邊選單高亮機制
  • a11y ~215 條全清(9 批 commit 9967c77dfcb10b + iframe 98fe54e):S6853 label 未關聯 + InputWithoutLabelCheck + FrameWithoutTitle;label 補 for、控制項補 id(PrimeVue Dropdown/Calendar/MultiSelect/InputSwitch 用 inputId)、Slider/SelectButton 用 aria-labelledby、隱藏 file input + inline editor 用 aria-label、v-for 內動態綁定 id 防撞號
  • S2486 靜默吞例外 66 補 log(4 批 3808220c8d787b):空/回退/fail-closed catch 補一行 console.error 保留原 axios interceptor 行為、不加 toast 不改流程
  • 跳過留 backlog(非漏修):S6819 9 條(role=button/checkbox 掛自訂樣式 widget,改 native 需重構 markup+CSS)、a11y ~13 條(label 標的是唯讀顯示 div/區段標題/Tag 清單群,非單一控制項)、S2486 7 條(localStorage 不可用 / router.resolve 正常控制流的預期 noop)

③ CM-876 富文本收斂 TipTap — 🔵 修正待驗證

  • 五步全綠(5 commit 25ab632/c08b9e4/40987cc/fdfc7e1/1dd0aba): 1-3. 三表單(BulletinForm / SystemFeedbackForm / CruisingFeedbackForm)內文編輯器 PrimeVue Editor(quill) → 既有 TipTapEditor.vuev-model 維持輸出 HTML string(DB 存 HTML,輸出端 v-dompurify-html 不動)、必填紅框以 .tiptap-invalid wrapper 保留、scrollHeight=320px、移除 CkEditorToolBar slot 4. main.js 移除 PrimeVue Editor 全域註冊 + 刪 CkEditorToolBar.vue(實為 quill toolbar、零 live 使用)+ 清 ProjectSummaryReportForm/History 兩死 import;grep 確認全 repo 無 <Editor> 殘留 5. npm uninstall quill @ckeditor/ckeditor5-build-classic @ckeditor/ckeditor5-vue ckeditor5(package.json only,package-lock gitignored)
  • 每步 build:DEV 過。TipTapEditor 本身零改動(專案摘要報告在用,確保零回歸)

④ CM-873 BE Sonar 品質債 — 🔵 修正待驗證

  • 授權 4 安全桶,禁區 S3776/BLOCKER S3516(FR-038 stub)/regex/裸except/logging + 任何改邏輯者
  • S1481 未用區域變數 ✅ 全清(35 修 7 跳)f4312be0/77aad18e):純死變數刪、有副作用呼叫保留只刪接收變數、tuple 未用改 _、未用例外變數移 as e。跳過 workflow_execution_service×5 + oscal_audit_service:132-133(FR-038 stub)
  • S125 註解碼 ⏸ 整桶跳過(66 條):大宗設計意圖/未來用註解替代 + 掃描後行號漂移,無測試網逐條比對純死碼風險高
  • S1192 重複字面值 ✅ 安全結構類清完(2 檔 32 處)0c9d3de4/4d6fc3e1):bpmn_topology_validator 屬性 key 抽 ATTR_*bpmn_generator schema URI/exporter/錯誤訊息抽 _BPMN_*/_MSG_*。剩餘資料/i18n/分類標籤類跳過
  • S1172 未用參數 ⏸ 整桶跳過(83 條):全為介面/DI/簽名綁定(curr_user×14 / *_uid / logger / gateways)

§2 前次教訓(本 arc 踩過 / 確立的雷,下個 session 沿用)

  1. BE .env 難在 shell 直接 source.env 內 JSON 值含 }. ./.env 會 parse error。別再試 source。BE 驗證改用靜態三重檢查(見 §6);要真跑服務煙測得 user 本機環境(R17 曾在有 env 時 login 回 400 佐證 boot 正常)。
  2. Sonar 報告行號會漂移:掃描後代碼有異動(含本 arc 前輪自己的編輯)→ 報告 line number 多處對不上真實位置。改行號類(刪行/抽常數)Edit 前務必 Read 拿當前精確內容 + grep 確認範圍,不可信報告行號直接砍。
  3. BE 無測試網 = 保守優先:pytest 整包 126 collection errors 是既有環境問題(不修不理);驗證只靠煙測 + 靜態檢查。任何跨 caller / 介面對齊 / 需改邏輯的一律跳過留 backlog,不冒險。
  4. FE package-lock.json 被 gitignorenpm install/uninstall 後只 commit package.json,別 add lock。
  5. 同檔多刪會位移:一檔多處 Edit,改一個後剩下的行號變了——用「改一個後剩下的變唯一」逐步收斂,或夠長獨特上下文逐一 Edit,避免 replace_all 撞到不該動的。

§3 下個 session 該做什麼(明確步驟)

這不是修 bug,是收官。按此順序:

  1. 跑 §6 pre-flight 確認兩 repo branch/working tree/未 push 狀態如預期
  2. 等 user 手測回報(§4 是給 user 的手測 checklist)。user 沒回報前不要 push
  3. user 手測 pass → 問 user push 規模(哪些 repo、要不要一起 push 資安主體那批),得明示才 push。push 永遠等 user 明確指示
  4. user 手測發現問題 → 按問題對應 case 修(各 case 白話說明有列改動範圍與檔案),修完重新煙測 + 更新該 case
  5. 收官後可選:問 user 要不要接著清 backlog(見 §7)或動 jedi 線(見 §7,不在 runner 清單,需 user 明示才走 jedi-package-dev skill

§4 給 user 的手測 checklist(各 case 待驗)

CM-874 FE Sonar

  • 框架版本管理:新增/編輯版本 Dialog → 版本欄可輸入、必填驗證觸發時焦點正確跳該欄
  • 側邊選單:各層級點擊導頁正常、當前頁高亮正常(AppMenuItem 改動區)
  • 表單頁抽測(SSP 基本資訊 / 專案建立 / 稽核 AP 編輯 / 問卷設計器 / 各匯入 Dialog):輸入/下拉/日期/多選/儲存如常
  • console:先前靜默失敗的操作現在會印 [模組] xxx failed log(畫面行為不變)

CM-876 TipTap(重點=相容性):

  1. 開一則既有公告/回饋(quill 產的舊 HTML)→ 進 TipTap 編輯 → 粗體/清單/連結 render 不爆版 → 再存 → 輸出仍合法 HTML
  2. 四處複測:公告發佈/編輯、系統回饋送出、巡檢回饋送出、專案摘要報告(TipTap 共用無回歸)
  3. 必填留空按儲存 → 紅框 + 錯誤訊息
  • 驗不過(舊 HTML 爆版)→ 回報,不硬轉

CM-873 BE Sonar

  • 本機載 .envpython main_app.py(port 8000)→ login POST 空 body 回 400 + tail log/app.log 無 Traceback
  • 回歸抽測動到的模組:公告/回饋 CRUD、匯入流程(module_frame/AP/AR docx)、稽核輪次、問卷、BPMN 產生/校驗(bpmn_generator / bpmn_topology_validator)

§5 Notion case 座標 + commit 對照

Case Notion page id 狀態 主要 commits
① preact (無 case,小件) FE 2df15a1
② CM-874 FE Sonar 3a7346da-4cd0-81ab-87d6-eeb43735e487 修正待驗證 FE 95fd44c + a11y 9 批 + 98fe54e + S2486 4 批
③ CM-876 TipTap 3a7346da-4cd0-81c8-af28-d2f115bda773 修正待驗證 FE 25ab632/c08b9e4/40987cc/fdfc7e1/1dd0aba
④ CM-873 BE Sonar 3a7346da-4cd0-81f3-b551-d567d1d7dec5 修正待驗證 BE f4312be0/77aad18e/0c9d3de4/4d6fc3e1

各 case 內文均有「## ✅ 已完成修正(白話說明)」comment(做了什麼/跳過什麼/待手測什麼),作業人員=小弟。


§6 Pre-flight Command(必跑)

# BE
cd ~/Projects/Billows/Audit-Manager/compliance-manager-be
git branch --show-current              # 應 main(不切 branch)
git status --short                     # 我的 commit 都已進版;只剩 pre-existing untracked(docx/png 等)
git rev-list --count origin/main..HEAD # 應 ~34(全未 push)

# FE
cd ~/Projects/Billows/Audit-Manager/compliance-manager-fe
git branch --show-current              # 應 main
git status --short                     # 應乾淨
git rev-list --count origin/main..HEAD # 應 ~27(全未 push)

# BE 靜態驗證法(.env 難 source,改用這組——這是本 case 認可的驗證)
cd ~/Projects/Billows/Audit-Manager/compliance-manager-be
python -m py_compile <改過的檔...>                                  # 要 OK
python -m pyflakes  <改過的檔...> 2>&1 | grep -i 'undefined name'   # 要空
# 若 user 本機 env 齊:載 .env 起 python main_app.py,curl -s -o /dev/null -w "%{http_code}" \
#   -X POST localhost:8000/api/1.0/login -H 'Content-Type: application/json' -d '{}' 應 400

§7 不在本期 scope(別順手做)

  • jedi-*:HEAD commit 969983f0 提到「新發現 jedi-issue wheel 憑證外洩 P1 + 開 4 條 Notion case」+ jedi 發版 4 CVE 歸零——這條不在 runner 四工作清單內,照 handoff 規範要 user 明示才動,走 jedi-package-dev skill。runner 沒碰。
  • CI/CD case:user 指示擱置,Notion 維持原狀,runner 沒碰。
  • 各 case 跳過的 backlog(要清需 user 決策 / 主 session 人工判斷,不是 runner 自動能安全做的):
    • CM-874:S6819(9,自訂 widget 需重構 markup+CSS)、a11y 唯讀/區段標題 label(~13)
    • CM-873:S125(66,建議重跑 Sonar 拿新行號 + 人工逐檔判斷)、S1172(83,介面/DI 綁定)、S1192 資料/i18n/分類標籤類、S3776 認知複雜度 207(本就禁區)、BLOCKER S3516 7(FR-038 stub 等 2B 重建)
  • push:全 local,等 user 明確指示才 push,別自作主張。

§8 行為規範重要提醒(本收尾適用)

  • 不切 branch / 不自動 push:兩 repo 都在 main,push 永遠等 user 明示
  • BE、FE 分開 commit,顯式 git add 檔名(禁 -A/-am);FE package-lock.json gitignored 不 add
  • 改 BE service/route 後要煙測 + 提醒重啟(BE 重啟 2026-07-22 起由 Claude 負責)
  • 收尾等 user 下令:user 手測 pass 前不標 Done、不 push;「修正待驗證」是等 user verify 的正確狀態
  • 憑證不寫入任何 commit 檔
  • Notion 作業人員:Claude 做的填「小弟」

§9 前次 session(本 runner)commits 清單

FE repo(compliance-manager-fe,origin/main..HEAD 共 27,本 runner 貢獻 21)— 全未 push

1dd0aba chore(deps): 拔除 quill + ckeditor5
fdfc7e1 refactor(editor): 移除 PrimeVue Editor 全域註冊 + 刪 CkEditorToolBar
40987cc refactor(editor): 巡檢回饋表單 quill 換 TipTap
c08b9e4 refactor(editor): 系統回饋表單 quill 換 TipTap
25ab632 refactor(editor): 公告表單 quill 換 TipTap
c8d787b fix(sonar): S2486 批次 4 收尾(11 檔 11)
0b4d128 fix(sonar): S2486 批次 3(12 檔 27)
babd000 fix(sonar): S2486 批次 2(4 檔 15)
3808220 fix(sonar): S2486 CLI/FrameworkImport(2 檔 13)
98fe54e chore(sonar): a11y iframe title(3 檔 3)
dfcb10b / 0b17245 / 2cbc1b4 / 3c4a0ed / 7155458 / eaa1c7a / 378a143 / c6c0734 / 9967c77  chore(sonar): a11y 9 批
2df15a1 chore(security): preact 升 10.29.7

BE repo(compliance-manager-be,origin/main..HEAD 共 34)— 全未 push

969983f0 docs(security-scan): 半夜三工具重掃 MEDIUM 分析(★非 runner,jedi 線相關,見 §7)
547471d6 docs: runner loop log R20(+ 收官)
4d6fc3e1 chore(sonar): S1192 bpmn_generator(4 字面值 19 處)
0c9d3de4 chore(sonar): S1192 bpmn_topology_validator(3 字面值 13 處)
77aad18e chore(sonar): S1481 api/common/core/domain/scripts(19 條 14 檔)
f4312be0 chore(sonar): S1481 app(16 條 9 檔)
+ runner loop log R1~R20 docs commits(每輪一支)

其餘 BE commit(969983f0 之前更早的 9fb4a111/15d19e3a... 資安主體升版)是本 arc 之前的資安主體修正,已驗收,非 runner 產出。


§10 給 fresh session 的超短 prompt

資安掃描 arc 後續優化的 runner 已跑完(4 工作全「修正待驗證」,全 commit 未 push)。
請先讀 docs/features/security-scan-2607/handoff/2026-07-25-security-optimization-runner-session-handoff.md
全部(先懂 WHY:這是 runner 收尾不是修 bug)+ 答冷接自檢 4 問,再跑 §6 pre-flight。
接手任務=等 user 手測各 case(§4 checklist)→ 按 user 明示 push(目前全 local);
user 沒下令前不 push、不標 Done、不碰 §7 禁區/jedi 線。手測若發現問題再對應修。

§11 附:runner loop log 位置

完整 20 輪帳本:docs/features/security-scan-2607/runner-loop-log.md(每輪:時間/作業 case/批次內容/commit hash/跳過項)。此檔是本 arc 唯一「逐輪原始紀錄」,本 handoff 是其收口摘要。