---
title: FR-114 資安修正派工計畫
---

# FR-114 資安修正派工計畫

> **這份文件是什麼**：`docs/security-report/SUMMARY.md` 的問題總表是按嚴重度排的**檢視結果**，不是派工單。這份計畫把 145 件翻成「**一個工作區一張卡、一個工程師一次做完哪些事**」。決策者看過、裁完第 6 節後，才照它建 Notion 卡。
>
> **狀態**：🟡 計畫待審（尚未開卡）｜母卡 CM-2019｜每批的逐卡細節在 `batches/plan-b*.md`，本頁是總覽。

---

## 1. 30 秒版

**整案一句話**：145 件裡 121 件要動手（24 件已修或裁定不修），拆成 **46 張卡**，分六批；**第 1、3、4、5 批今天就能開，第 2 批要等第 1 批合回主線＋套件發版，第 6 批等程式面修完測過一版**。

| 批 | 做什麼 | 卡 | 能不能現在開 | 動哪些 repo |
|---|---|---:|---|---|
| **1 權限地基** | 把「誰有資格動這筆東西」的判斷做出來（任務完成／退回只准指派人與管理者、專案成員寫入要驗物、公告／設備／意見回饋的擁有者判斷） | 9 | ✅ 現在開 | BE、jedi-detection／task-platform／survey／bulletin／asset／issue |
| **2 只驗登入不檢查歸屬** | 29 件全是「補一行去問第 1 批」：檔案四出口、問卷六支、流程四處、名冊、摘要報告、AI 儀表板 26 支、資源庫三入口、檢測 8 支 | 10 | 🔴 等第 1 批合回＋套件發版 | 六支套件＋BE |
| **3 刪除沒人用的** | 舊版證據分類、零呼叫的任務功能、開發小工具、死開關、成員名冊死程式、快速設定畫面、快取複製品 | 5 | ✅ 現在開 | BE、FE、jedi-task-platform／common／issue |
| **4 憑證殘留** | 密碼全部已換發，清版控字串；另兩件真修（派工表明文落表、Google 金鑰） | 4＋沿用 CM-1998 | ✅ 現在開 | BE、FE、jedi-detection |
| **5 設定與信任鏈** | 代理程式身分、防竄改、客戶層級改全域、交出去要編碼、停權即時生效、上限類、AI 兩塊、儲存帳密明文 | 18（含 1 張驗證卡） | ✅ 現在開（兩張要先裁方向） | agent、BE、FE、十支套件 |
| **6 資料庫牆** | SaaS 前 53 張表補隔離、授權三張表方向、M18-8 停權復權 | 0（本棒不開） | ⏸ 程式面修完→測一版→再開 | BE migration |

**工作區怎麼開（決策者 2026-09-21 裁定：依序做、不平行；開 worktree 是為了不碰掃描線正在讀的主 checkout）**：只開**兩個常駐工作區**——BE 一個、套件 monorepo 一個——所有卡依序在裡面做，一張卡一個 commit，做完驗過再派下一張。第 3、5 批 FE／agent 那兩張卡到時各自在 FE／agent repo 開一個。

---

## 2. 工作區（worktree）配置

### 2.1 為什麼開 worktree、開幾個
- **目的是隔離，不是平行**：FR-113 掃描線正在讀 BE 主 checkout（`feature/review`），修正不能在那裡動。套件 monorepo 沒有掃描在跑，但 BE 工作區的 path dependency 要指向一個固定路徑，開一個 worktree 讓它指過去比較乾淨。
- **常駐兩個**：

| 工作區 | 開在哪 | 指令 | 誰在裡面做 |
|---|---|---|---|
| **BE** | `~/Projects/Billows/Audit-Manager/wt-fix-security`（BE repo 旁邊） | `cd compliance-manager-be && git worktree add ../wt-fix-security -b fix/security-b1` | 所有 BE 側的卡（1-1、1-8、1-9、2-5、2-7、2-8、2-9、3-1、4-1、4-2、5A-2/3 的 BE 半、5B-3 的 BE 半、5C-2、5C-7…） |
| **套件** | `~/Projects/Jedicogy/module/jedi-wt-fix-security`（monorepo 旁邊） | `cd jedi-python-package && git worktree add ../jedi-wt-fix-security -b fix/security-b1` | 所有套件側的卡；runner 只動自己那支套件的子目錄、只 `git add` 該子目錄 |

- **BE 工作區的 `pyproject.toml`**：把本卡動到的套件 pin 改成 path dependency 指向套件工作區（例：`jedi-task-platform = { path = "/Users/chouraymond/Projects/Jedicogy/module/jedi-wt-fix-security/jedi-task-platform", develop = true }`），`poetry update jedi-task-platform`。**這個改動不 commit**；一張卡做完不用還原（下一張卡接著用），整批合回前才還原 pin。BE 工作區跑服務用**另一個 port**（例 `PORT=8001`），不跟主 checkout 的 8000 撞。
- **FE 卡**（3-5、1-5 若拆出 FE 半、5A-5 的下拉）到時在 FE repo 開 `wt-fix-security`；**agent 卡**（5A-1）到時在 agent repo 開。
- **同一張 branch 累積多張卡的 commit**：branch 名不帶卡號，因為卡是依序做的；commit message 帶卡號。

### 2.2 依序做的順序（一次一張，做完驗過再派下一張）
1. **第 1 批**：1-1 → 1-3 → 1-4 → 1-5 → 1-7 → 1-8 → 1-9 → 1-6（等 1-9 的 migration 套 DEV）→ 1-2（等 1-1）
2. **第 3 批**（可插在第 1 批任何位置，互不相干）：3-1 → 3-2 → 3-3 → 3-4 → 3-5（FE）
3. **第 4 批**（同上可插）：4-3 → 4-1 → 4-2 → 4-4
4. **第 5 批**：先派方向已定的（5A-3、5A-4＋5C-7 合併、5A-5、5B-1～5B-4、5C-1～5C-5、5C-8），5A-1／5A-2 裁完方向再派，5C-6 排最後（動所有 pyproject）
5. **合回＋套件發版**（決策者下令）→ **第 2 批**：2-1 → 2-2 → 2-3 → 2-4 → 2-5 → 2-6 → 2-7 → 2-8 → 2-9 → 2-10
6. 測過一版 → **第 6 批**開卡

### 2.3 合回與發版順序（誰下令）
| 事 | 什麼時候 | 誰下令 |
|---|---|---|
| `fix/security-b1` 合回各 repo 的 `feature/review` | 一批做完、首腦驗收通過 | 決策者（合回＝對主線的變更） |
| 套件發版（bump ＋ 推 Nexus） | 第 1 批合回後（第 2 批要吃新守門） | 決策者（CLAUDE.md：絕對禁止自動發版） |
| 第 2 批開卡派工 | 套件發版、BE pin 更新後 | 決策者 |
| 第 6 批開卡 | 第 1～5 批合回、測過一版 | 決策者 |

### 2.4 先後有相依的卡（依序做時要守的順序）
| 先 → 後 | 為什麼 |
|---|---|
| 1-1 → 1-2 | 1-2 呼叫的方法是 1-1 做出來的；反過來是 AttributeError 500 |
| 1-9 → 1-6 | 1-9 的 migration 先套 DEV，否則 1-6 驗起來五個下拉選單安靜變空 |
| 2-8 → 2-9 | 2-9 照抄 2-8 的寫法 |
| 5A-4 → 5C-7 | 合併成一張（見 §6 D-X2），先套件側再 BE 接上 |
| 其他卡 → 5C-6 | 5C-6 動每一支 `pyproject.toml`，排最後 |

## 3. 各批的卡片（總表；逐卡的修法、入口清單、手測見 `batches/plan-b*.md`）

### 第 1 批 權限地基（13 件 → 9 張）→ [`batches/plan-b1.md`](batches/plan-b1.md)
| 卡 | 做什麼 | repo | # | model |
|---|---|---|---|---|
| 1-1 | 任務「完成／退回」改成只有被指派人與管理者能做（新開一道嚴守門） | BE | 37 | opus／medium |
| 1-2 | 弱點掃描八支改狀態端點改吃那道新守門 | jedi-detection | 37 | sonnet／medium |
| 1-3 | 專案成員與任務指派寫入時，反查填進來的東西是不是這個專案的 | jedi-task-platform | 41、109、110 | opus／medium |
| 1-4 | 問卷還原歷史版本要驗版本歸屬；討論改／刪要驗作者本人 | jedi-survey | 38、39 | opus／medium |
| 1-5 | 公告改／刪要驗是不是自己發的；發送對象改必選 | jedi-bulletin | 42、111 | opus／high |
| 1-6 | 設備清冊七支讀取補權限；修改請求不准夾帶停用／啟用 | jedi-asset | 43、112 | opus／medium |
| 1-7 | 意見回饋六支裸奔端點補權限，改／刪補「這筆是不是你的」，清單分兩套 | jedi-issue | 45 | opus／high |
| 1-8 | 「檢查流程圖」端點補權限與輸入上限 | BE | 40 | sonnet／medium |
| 1-9 | 兩支 migration：設備讀取權限給稽核人員角色、放寬意見回饋新增規則 | BE `scripts/sql/` | 44、43 | sonnet／medium |

### 第 2 批 只驗登入不檢查歸屬（29 件 → 10 張，等第 1 批）→ [`batches/plan-b2.md`](batches/plan-b2.md)
| 卡 | 做什麼 | repo | # | model |
|---|---|---|---|---|
| 2-1 | 檔案四個出口取檔前先問「這個檔掛在哪、你碰不碰得到」（新增共用通道＋登記表） | jedi-file-upload＋BE＋jedi-issue | 3 | opus／high |
| 2-2 | 問卷六支讀取補「編號必填＋你是這個專案的人」，含共編房間 | jedi-survey | 5、6、48～51 | opus／medium |
| 2-3 | 稽核流程四處補歸屬檢查，流程範本讀取補權限 | jedi-flow-engine＋BE＋jedi-compliance-audit | 7、8、52、53、115 | opus／high |
| 2-4 | 專案名冊與任務指派清單四支補「編號必填＋成員」（#59 在此結案） | jedi-task-platform | 54、55、58、59 | sonnet／medium |
| 2-5 | 專案摘要報告五支讀取與稽核輪次選單補參與者檢查 | BE＋jedi-compliance-audit | 56、57 | sonnet／medium |
| 2-6 | AI 儀表板 26 支查詢加「要什麼權限」欄位並在呼叫前檢查，拿掉視同管理員後門 | jedi-ai-dashboard＋BE＋jedi-common | 60、61、62、114 | opus／high |
| 2-7 | 查任務詳細資料補「屬不屬於網址上那個專案」，改與刪也補 | BE | 63 | sonnet／medium |
| 2-8 | 合規資源庫三入口補歸屬檢查、建立入口補權限與用量上限 | BE（oscal） | 46、65 | opus／high |
| 2-9 | 刪佐證文件／文件庫文件時核對「要刪的屬不屬於你管的那份計畫」 | BE（oscal） | 64 | sonnet／medium |
| 2-10 | 弱點檢測「測試連線」補權限，八支讀取補權限 | jedi-detection | 4、47、113 | opus／medium |

### 第 3 批 刪除沒人用的（11 件＋M13-10 → 5 張）→ [`batches/plan-b3.md`](batches/plan-b3.md)
| 卡 | 做什麼 | repo | # | model |
|---|---|---|---|---|
| 3-1 | M13 快取連線複製品刪除、改用套件那份（**M07 舊線那半見 §6 D-X1**） | BE | M13-10（＋9、66、67 待裁） | sonnet／medium |
| 3-2 | 拆掉三組零呼叫的任務管理功能 | jedi-task-platform | 68、69、120 | sonnet／medium |
| 3-3 | 刪開發小工具＋刪死開關 | jedi-common | 116、117 | sonnet／medium |
| 3-4 | 刪全站成員名冊死程式 | jedi-issue | 121 | sonnet／medium |
| 3-5 | 拆除「快速設定」獨立畫面兩個入口 | FE | 119 | sonnet／medium |

⚠️ 這批材料檔沒有程式座標，**11 個入口全部要在開卡前補查**（首腦派 opus 一支補，不佔 runner）。

### 第 4 批 憑證殘留（10 件 → 4 張＋沿用 CM-1998）→ [`batches/plan-b4.md`](batches/plan-b4.md)
| 卡 | 做什麼 | repo | # | model |
|---|---|---|---|---|
| 4-1 | 清版控裡的憑證殘留字串（外部平台通行證／AI 金鑰／管理員密碼／交接文件帳密） | BE | 10、11、72、73、122 | sonnet／medium |
| 4-2 | 資料庫管理員密碼 249 檔殘留＋堵住還在寫入的路徑 | BE（初判） | 12 | sonnet／medium |
| 4-3 | 開始掃描時不再把明文帳密多存一份進派工表（程式修正） | jedi-detection | 70 | sonnet／medium |
| 4-4 | Google 雲端硬碟金鑰清殘留字串（金鑰重設另裁，見 D-b4-3） | 待補查 | 74 | sonnet／medium |
| 沿用 | 打包前端映像檔腳本內嵌 Nexus 帳密 | BE＋FE | 75 | 既有卡 CM-1998 |

⚠️ 249 檔與 15 檔清單要在開卡前盤點附卡（唯讀 grep，首腦做；**不把憑證印進卡**，只列檔案路徑）。

### 第 5 批 設定與信任鏈（54 件 → 18 張）
**A 子集** → [`batches/plan-b5A.md`](batches/plan-b5A.md)
| 卡 | 做什麼 | repo | # | model |
|---|---|---|---|---|
| 5A-1 | 代理程式每次打進來都要證明身分，「撤銷」真的斷乾淨 | evidence-agent＋jedi-remote-agent | 1 | fable／high（先裁方向） |
| 5A-2 | 驗簽工具與鎖定紀錄變成拔不掉的 | jedi-integrity＋BE | 17、18、90、91、133 | fable／high（先裁方向） |
| 5A-3 | 「改全公司共用設定」收到客戶總部那一層，儲存設定密鑰遮蓋 | jedi-system-core＋jedi-log＋BE | 19、22、134 | opus／high |
| 5A-4 | 交出去統一編碼：匯出試算表不被當公式、日誌不被讀成兩筆（共用函式放 jedi-common） | jedi-common＋jedi-log＋jedi-issue | 20、93 | opus／high |
| 5A-5 | 停權當下通行證立刻失效；日誌轉送加密選項 | jedi-iam＋jedi-log＋FE | M13-17、92 | opus／medium |

**B 子集** → [`batches/plan-b5B.md`](batches/plan-b5B.md)
| 卡 | 做什麼 | repo | # | model |
|---|---|---|---|---|
| 5B-1 | 規則包解析前先看內容；三道防炸彈上限搬到所有來源都經過的那層 | jedi-detection | 15、76、77、78 | opus／high |
| 5B-2 | 弱點檢測三處資源上限：測試連線收斂、重新解析去重、換工具用生效值重查 | jedi-detection | 79、80、81 | opus／high |
| 5B-3 | 流程圖走訪記路＋補上限；範本新增修改與起輪次一定過檢查 | jedi-flow-engine＋BE | 16、87、88、128 | opus／high |
| 5B-4 | 問卷資料夾與即時填答：身分改用登入身分、送進來的欄位逐一收掉 | jedi-survey | 85、86、126、127 | opus／high |
| 5B-5 | **驗證卡**：確認 M07 五件是否已隨舊線退役消失（第 3 批之後） | jedi-evidence-classification | 89、129～132 | opus／medium |

**C 子集** → [`batches/plan-b5C.md`](batches/plan-b5C.md)
| 卡 | 做什麼 | repo | # | model |
|---|---|---|---|---|
| 5C-1 | 別人點預覽時跑不起攻擊者的程式；存檔前先洗檔名 | jedi-file-upload＋jedi-detection | 13、123 | opus／high |
| 5C-2 | 儲存空間帳密不再回傳前端，連線改加密（M22-2 那側在 5A-3） | BE＋FE | 14、124 | opus／high |
| 5C-3 | AI 助手與儀表板補逾時、次數上限，停止整包送出密碼材料 | jedi-ai-dashboard＋jedi-ai-bot＋jedi-common | 21、94、95 | opus／high |
| 5C-4 | 共用底層五處小修：密碼遮乾淨、清單筆數上限、設定打錯字往嚴的倒、寫日誌失敗不連累請求、紀錄等級 | jedi-common | 82、83＝136、84、103、125 | opus／high |
| 5C-5 | 意見回饋：連 GitHub 恢復身分驗證；刪附件用上算好的過濾結果 | jedi-issue | 100、135 | sonnet／medium |
| 5C-6 | 內部套件倉庫全面改走加密連線，版本鎖定檔納版控（**先查 Nexus 有沒有 TLS**） | monorepo 28 支＋BE＋FE | 101 | sonnet／medium |
| 5C-7 | 匯出 Word／Excel 把使用者填的字當資料處理（**與 5A-4 合併見 D-X2**） | BE | 102 | opus／high |
| 5C-8 | 自動產生密碼補回少的那個字元；清兩支零引用複製品 | jedi-survey＋jedi-log | 137 | sonnet／medium |
| 不開 | #98 安裝程式同一組最高權限帳密（裁定暫不調整）、#99 三環境共用公鑰（等正式簽發站） | — | 98、99 | — |

---

## 4. 第 6 批：資料庫最後一道牆（本棒不開卡）
| # | 件 | 開卡條件 |
|---|---|---|
| 105 | SaaS 前 53 張表補隔離（併 M11） | 第 1～5 批合回、測過一版、決策者裁「開牆」 |
| 104 | 隔離規則方向寫反 11 條（8 張改方向、授權 3 張讀保持寫要擋） | 同上；授權那 3 張的裁定見交接文件「M03 那 11 張表要分兩組改」 |
| 23 | 被停權客戶用子單位帳號刪停權紀錄復權（M18-8） | 同上（是 #104 授權三張表那組的直接後果） |
| 24 | 13 張表隔離牆「部分修」（M20-1） | 同上 |

---

## 5. 報告頁八處不一致的歸屬（CM-2020 併入本棒）
| 處 | 是什麼 | 誰改 |
|---|---|---|
| ① | M15 第 6 條狀態 vs M17 第 10 條（同一組帳密）：M15 改「已修正、殘留待清」 | 卡 4-1 runner（#73） |
| ② | M17 第 135 行「27 支」→ 26 支 | 首腦 |
| ③ | M17 第 8 條 vs M23 第 1 條：以 M23 🟠 高為準，狀態統一「密碼已換發、249 檔殘留待清」，M23 修法第三步標已完成 | 卡 4-2 runner（#12） |
| ④ | M16 第 100 行指向：三頁統一「同一組密碼、總表只計一次」 | 卡 4-2 runner |
| ⑤ | M10 第 86 行「12 條其中 3 條刪除」範圍措辭 | 首腦 |
| ⑥ | M19 統計表 4/2/1 與問題表 3 列對不上 | 首腦 |
| ⑦ | M20 統計表「未修 0 條」→「2 條只修一半」 | 首腦 |
| ⑧ | 掃描總表 §3.3 兩項已過期（S7 重掃、R1b 補掃已完成） | 首腦 |

---

## 6. 決策者要裁的事

七份批次計畫共列了 **42 項待裁**（各批檔末段），**大多數是 runner 動手時才要選的細節、且每項都附了建議**。這裡只把「**不裁就不能開卡**」的抓出來；其餘照各卡建議走，runner 卡上會寫「先回寫問決策者再動手」。

### 我自己查出來的兩個跨批衝突（先裁這兩個）

**D-X1 舊版證據分類退役已有人在管，第 3 批要不要再開？**
第 3 批 3-1 卡把 #9／#66／#67「M07 舊線退役」排進去，但 Notion 已有 **CM-1849（FR-107.6 舊線退場＋收口，4 張子任務卡，Not started）** 在管這件事，且 M07 模組頁第 77～87 行寫明退役要照完整清單逐支做（含被鎖定的網址清單要一起改、否則自動測試會失敗）。
- 我的建議：**第 3 批不再開退役卡，3-1 只做 M13 快取複製品那半；#9／#66／#67 在 SUMMARY 標「由 CM-1849 處理」**，5B-5 驗證卡改成「等 CM-1849 做完再驗」。兩張卡做同一件事只會互撞。

**D-X2 「匯出時把 = + - @ 開頭的字標成純文字」這支共用函式，只准有一份**
5A-4（jedi-common 抽一支，給 jedi-log 與 jedi-issue 的匯出用）與 5C-7（BE 抽一支，給 Word／Excel 匯出用）會各自長一份。5C 子集實查過：FR-113 README 說「早就抽過、三個出口沿用」的那支函式**不存在**。
- 我的建議：**合併成一張卡**，函式放 jedi-common（BE 與所有套件都拿得到），先做套件側再回 BE 接上，序列 5A-4 → 5C-7 同一個 runner。

### 各批「動手前必裁」的（其餘見各批檔）

| 批 | 項 | 一句話 | 我的建議 |
|---|---|---|---|
| 1 | D-b1-1 | 任務完成／退回的嚴守門：新開一支，還是把既有那支收嚴（收嚴會連帶改到佐證上傳那三支） | 新開一支，佐證那三支留給後續照同一支接 |
| 1 | D-b1-2 | 公告發送對象改必選後，既有「發送對象是空的」舊公告怎麼辦 | 多一個「發送範圍」欄位，舊資料一律標全公司（它們現在實際就是全公司可見）；卡 1-5 因此拆成套件＋migration＋FE 三張 |
| 1 | D-b1-3 | 意見回饋「我的」與「管理頁」後端怎麼分辨 | 同一支入口多一個範圍參數（原則二：不為情境各開路由） |
| 2 | D-b2-3 | 流程範本到底要不要權限（還是人人可看） | 補權限（同一家客戶內沒被授權的人不該看到階段設計與判斷條件） |
| 2 | D-b2-5 | 合規資源庫開放哪些角色建 | 專案管理者＋客戶管理員，一般成員不開 |
| 4 | D-b4-1 | 清殘留字串要不要改寫 git 歷史 | 只清現存檔案，不改歷史（憑證已失效，改歷史動到所有人的 commit） |
| 4 | D-b4-3 | Google 金鑰重設＋重新加密既有通行證要不要併進第 4 批 | 另開一張獨立卡排在 4-4 後面 |
| 5A | D-b5A-1 | 代理程式拿什麼當身分證明：短效通行證 vs 客戶端憑證 | 短效通行證當主軸（不必動客戶機房設備） |
| 5A | D-b5A-3 | 驗簽工具怎麼變成拔不掉的（三方案） | 方案①：在產生防竄改清單的工具裡新增「安全關鍵」分層 |
| 5A | D-b5A-4 | 鎖定紀錄治本：開機查資料庫，還是補同步反向補回；DB 連不上時擋不擋開機 | 開機查 DB＋反向補同步當輔助；連不上時**放行並記警示**（原則十一） |
| 5C | D-b5C-2 | 內建物件儲存有沒有開加密——沒有的話 5C-2 要連帶做 | runner 第一步只唯讀查證回報，不先改 |
| 5C | D-b5C-8 | Nexus 有沒有 TLS——沒有的話 5C-6 動不了 | 同上，先查再說 |

### 不用裁、我會直接照建議進卡的
D-b2-1／2／4／6／7／8、D-b3-1（由 D-X1 取代）、D-b4-2（首腦盤點）、D-b5A-2／5／6／7／8／9／10、D-b5B-1～6、D-b5C-1／3／4／5／6／7／9／10（由 D-X2 取代）／11——各項的問題與建議在對應批次檔末段，**你若對哪項有意見再點名**。

---

## 7. 開卡前首腦要補的（決策者點頭後、建卡前做）
1. 第 3 批 11 個入口座標（派 opus 一支補查，唯讀）
2. 第 4 批 249 檔與 15 檔清單（唯讀 grep，只列路徑）
3. 第 1 批 5 個待補：detection `complete_job` 要不要跟著收嚴、`batch_add_task_assignees` 是否經過單筆、`project_group_participant_service.py` 三支寫入整支無守門是不是 #109 漏記的、`survey_discussions` 有沒有軟刪欄位、內建範本有沒有超過 100 節點
4. 第 5 批 A/B 共 5 個待補（FE 日誌轉送下拉元件、`_read_entries()`、重抽入口、`if entity.xml:`）
5. 第 2 批 1 個：稽核輪次同檔統計功能要不要一次補完

---

## 8. 共同紀律（每張卡都會帶）
- runner 做完程式後**順手把該條在模組頁（`docs/security-report/M<NN>-*.md`）與 `SUMMARY.md` 的狀態改「已修」＋修法一句，重 build（`python scripts/deliverables/render_index.py docs/security-report/ --site-root docs/security-report/`），再 Notion 回寫**。只動狀態欄與修法那句，不重寫段落。
- 每個入口 file:line 都是驗收項，**每個入口都改了才收**（同一個問題常有 route＋service＋FE 三個入口）。
- 功能不能壞（原則三）、安全措施不可擋正常客戶（原則十一）、刪除前零引用（原則十五）。
- 套件 path dependency 改動不 commit；顯式 `git add`；做完立刻 commit＋回寫＋狀態改「修正待驗證」；**不 push、不切 branch、不發版**。
- 檔案內註解只寫「為什麼」與「陷阱」，做了什麼進 commit message。
- 動到已超過 800 行的檔（例：`workflow_execution_service.py` 1,374 行）新邏輯一律新開檔。
