# 資安檢視總報告 — 內化第五棒交接

> 🔴 **內化 23/23 與收尾（CM-2018，產出 `SUMMARY.md`）都已完成。下一棒是「修正派工首腦」——卡 CM-2019，見下方第零節。不是內化、不是收尾。**
> 這份取代 `_handoff-internalize-4.md`（那份留著當歷史，**不要再照它開場**）。

---

## 你的角色

陪決策者把這份資安檢視報告**讀懂、想清楚、做出判斷**。

他是這份報告的講者——要拿它去對客戶、對老闆、對稽核方解釋。所以他需要的不是你幫他寫完，是**你講給他聽，他提問，你回答，然後把他的判斷記下來**。

**你是輔佐他理解的技術人員**：幫他查問題、解惑、給建議。**不是替他做決定的人。**

工作目錄：`/Users/chouraymond/Projects/Billows/Audit-Manager/compliance-manager-be`
報告原始碼在 `docs/security-report/`（md 是源，html 是產物）。

---

## 先讀這些

1. `docs/security-report/README.md` — 總報告首頁
2. `docs/security-report/_module-page-spec.md` — 模組頁撰寫規格（了解格式即可）
3. **本文件第五節「決策者已拍板的原則」** — 那是最重要的一節，遇到同類問題直接援引，不要重新討論
4. 下一塊要過的報告（見第三節）

**不必讀 GUIDE-01**（方法與工具），除非決策者問到方法可信度。

---

## 這份報告是什麼

PM 的要求原話：既有的技術報告「都放小弟原生產出的文件，所有過程皆需保存」，另外開一個連結放「**你內化過後的版本**」。

| | 需求中心的 21 個站 | 這份 |
|---|---|---|
| 誰的產出 | 檢視工具直接吐出的技術報告 | **決策者消化過、認可的版本** |
| 讀者 | 要查細節的工程師 | **客戶、老闆、稽核方** |

**它會被當成稽核證據**——所以每頁都有「檢視軌跡」段，證明確實查過。

23 塊報告都寫好了。**還沒做的是「內化」——也就是決策者的判斷。**

---

## 🔴 第四棒最重要的發現：報告寫的是「當時」，事實後來變了

**第四棒過的 12 塊裡，有六塊查出「報告與現在的事實不符」，而且形狀一致：**

| 塊 | 報告寫 | 實際 |
|---|---|---|
| **M04** | 「已搜尋四個紀錄檔確認明文零筆」 | ❌ **十個檔有明文**（決策者當場清掉了） |
| **M10** | 兩個招牌數字 751 / 12,494 筆 | ❌ **現在是 0**（報告寫完四小時後補了牆） |
| **M15** | 招牌例子「打字就拿到全公司帳號名冊」 | ❌ **現在打不通**（被一個不相干的改動意外擋住） |
| **M17** | 第 2 條「正在外洩」 | ❌ **會當場出錯**（同上） |
| **M16** | 兩條標「已修」 | ❌ **只修一半**（決策者後來裁定全部已換發） |
| **M18** | 第 1 條「已修」 | ❌ **從資料庫那層又開回來** |

🔴 **所以每一塊都要派查證，不要照抄報告。** 第四棒十二塊全部派過，**每一塊都抓到數字或描述錯誤**。

🔴 **而且「被意外擋住」不等於「修好了」**——M15 與 M17 那兩條都是被無關的改動擋住的，**哪天有人把那個改動修回去，洞立刻恢復**。這個講法要寫進報告。

---

## 進度

**23 塊全部過完。** 五張改稿卡（CM-1987／2014／2015／2016／2017）文件組已全部改完，第五棒驗收 2015／2016／2017 通過（派 sonnet 逐項核＋本體抽查）。

| 塊 | 狀態 | 卡號 |
|---|---|---|
| M02 檔案上傳下載 | ✅ | CM-1981 |
| M01 遠端代理程式 | ✅ | CM-1982 |
| M08 防竄改 | ✅ | CM-1984 |
| M22 系統設定 | ✅ | CM-1985 |
| M09 系統日誌 | ✅ | CM-1987 |
| M06 稽核流程 | ✅ | CM-1989 |
| **M05 問卷** | ✅ 第四棒 | CM-1990 |
| **M07 證據自動分類** | ✅ 第四棒 | CM-1991 |
| **M03 弱點檢測** | ✅ 第四棒 | CM-1993 |
| **M14 AI 聊天助手** | ✅ 第四棒 | （prompt，無卡） |
| **M19 設備清冊** | ✅ 第四棒 | CM-1996 |
| **M23 意見回饋 ＋ M21 重新檢視** | ✅ 第四棒 | CM-1997（兩頁合一） |
| **M15 AI 儀表板** | ✅ 第四棒 | CM-1999 |
| **M16 寄信與通知** | ✅ 第四棒 | CM-2011 |
| **M18 授權管理** | ✅ 第四棒 | CM-2012 |
| **M17 公告** | ✅ 第四棒 | CM-2013 |
| **M04 共用基礎** | ✅ 第四棒 | CM-2014 |
| **M10 任務與成員管理** | ✅ 第五棒 | CM-2015 |
| **M20 客戶資料隔離** | ✅ 第五棒 | CM-2016 |
| **M13 登入與權限** | ✅ 第五棒 | CM-2017 |

**另有兩張非模組卡**：CM-1994 全站裁定、CM-1992 Google 硬碟紀錄、CM-1995 分頁工具產品行為。

---

## 第五棒過的三塊（摘要，細節在各卡）

### M10 任務與成員管理 — ✅ 第五棒過完（CM-2015），下方查證結果留作歷史

**第五棒裁定摘要**：第 1、5 降中（跨客戶不成立、同公司內仍 2,237／12,573 筆）；第 7 降低改寫（沒有原廠公版，資源庫是客戶自己維護的）；第 10 逐支補底層不動；第 8、9（=16、17）、19 沒人用的寫入功能刪；第 14「專案任務設置」整頁拆（有兩個快速設定，只改了一頁）；第 15 留到修正卡。**第五棒每一組都派 opus 核對＋本體抽查，A 組 8 條、B 組 4 條「仍在」全部屬實，但 A 組又抓到三處報告誤判**（資料庫牆已蓋、前端呼叫已確認零空白、第 7 條目標不存在）。

**第五棒被決策者糾正三次，下一棒務必避免**：①「一堆誤判不要再想跳著過」——A 組我先套既有裁定只留一條給他裁，他要的是逐組 review；②「全部好了？所以你都訂好了？」——不要把 subagent 查證結果直接當定案整理成卡；③「我全不知道是在哪邊發生什麼事情」→ 原則十六。

<details><summary>第四棒查證結果（歷史）</summary>

**這塊是全產品權限判斷的地基**——其他模組「只驗登入不檢查歸屬」的修法幾乎都是「補一行去問這一塊」。

**查證結果（第四棒已跑完，可直接用）**：

- 🔴 **兩個招牌數字現在是 0**：報告寫「空白查詢撈到 751 筆成員、12,494 筆任務指派」，**今天實測都是 0**——報告寫完**四小時後**另一批工作補上了資料庫那道牆（六張表、每張四條規則）。**報告第 3 條的括號有提到，但第 1 條與結論沒跟著改。**
- **反證做過三道**：換成最上層的鑰匙看得到 2,238 筆與 12,573 筆，**資料還在，是牆擋住了**。
- 🔴 **但問題沒消失**：同一個客戶內的鑰匙，空白查詢照樣回 2,237 筆／12,573 筆。**「任何登入者一次撈光」在同一家公司內仍然完全成立。** 第 1 條標「高」的理由（跨客戶）不存在了，**問題本身還在，範圍縮成同客戶內跨專案**。
- **那六張表的寫法是對的**，**沒有**踩到 M03 查出的「方向寫反」那一套。
- **其他要改的**：第 3 條內文寫「四支」、修法欄寫「五支」（**實際六支無檢查、其中五支有對外入口**）；第 18 條「第五處」（**實際四處**，三個文件三個數字）；檔數「50 個零內容」（**真正零內容的 30 個**，有內容 163 個，沒查的約 89 個）；「剩 84 個檔可能有別種問題」**更準的講法是「task 與 project 兩整塊功能完全沒碰過」**。
- **第 10 條與 CM-1995 那張分頁工具卡不是同一支函式**（同檔不同病），**要分兩張卡**。

</details>

### M20 客戶資料隔離 — ✅ 第五棒過完（CM-2016）

**裁定**：第 5 條「盤點死角」實查是 102 張表沒牆、要補的 53 張（合規文件核心 45＋零散 8、4 個主檔接點、只有資源庫那個接點要想主人是誰）；**風險維持中、狀態改「SaaS 版上線前必做」**（落地版一家一套不受影響，SaaS 短期不上）；**決策者定順序：程式面先修→測一版→再開資料庫牆**，併 M11 當第一個具體待辦。第 2 條改「2 補設定 2 刪除」。

<details><summary>第四棒查證結果（歷史）</summary>

**這塊不是掃描出來的，是決策者自己實測撞到的**（切換到子客戶後還是看得到別家的待辦與專案），後來裁定併進資安線。

**查證結果**：

- ✅ **四個招牌數字確實全歸零**（專案 213→0、待辦 39→0、任務執行 11,065→0、工作流程 11,016→0），反證也做了。
- ✅ 13 張表全部已開隔離、各 4 條規則，**而且沒踩到「方向寫反」那個坑**（建議補一句，這是加分）。
- 🔴 **第 5 條的死角比報告寫的大得多**：報告說「這類表可能還有其他張」，**實際是 88 張表完全沒有資料庫層阻擋**，含**系統安全計畫 639 筆、稽核發現 525 筆**——產品最核心的稽核資料。**同一把鑰匙，專案表看到 0 筆、系統安全計畫看到 639 筆。**
- **第 2 條「四個畫面都加上設定」不準**：實際 2 個加設定、2 個直接刪除（查無任何程式在用）。
- **第 3 條報告兩句話都準確**，一字不用改。

</details>

### M13 登入與權限 — ✅ 第五棒過完（CM-2017）

**16 條逐條開程式實證**：15 修好、1 部分修（第 10 條快取連線——套件修了、主專案有一份複製品沒修，AI 助手與問卷在用，裁刪複製品改用套件）、**1 條漏登記且沒修**（新第 17 條：停權後通行證仍有效，S7 重跑找到的、追蹤表停更沒人開卡；裁補進報告標未修，修正批次處理）。「全案唯一全部修完」招牌拿掉；「還沒發版」整段依原則十拿掉（實際 9/13 已出版 jedi-iam 1.0.0）。

---

## 🔴 決策者的工作偏好（前四棒踩過，務必照做）

### 回答要短
他明講過：「**之前都太長了，雖然很詳細但很容易失焦**」。先給結論再給依據、一次回答一個問題、表格優於長段落。

### 🔴 分組講，不要逐條（第四棒被當場糾正）
**條數多的塊**：先講這塊做什麼 → **把問題按形狀分組** → 只展開真正需要他判斷的那幾條 → 其餘列表帶過。

**第四棒在 M17 違反過這條**，決策者當場說：「**我們應該是用分類來看不是？目前是逐條審閱嗎？畫面一直洗看不出來有什麼東西可以看。**」

**能套既有原則的直接套，不重新討論。**

### 🔴 不要附和（第四棒被當場抓到）
決策者質疑時，**先想清楚他對不對，再回答**。

**第四棒犯過**：建議「設定值讀不到就拒絕啟動」→ 決策者一質疑就馬上改口說「你講的才是正解」→ **決策者問「你有思考過嗎？」**

**正確做法**：真的重新想一遍，**包括他可能錯的地方也要講**。第四棒後來照做，結論是「你對了一半，另一半不成立」——**那才是他要的**。

### 🔴 已裁過的不要再問（第四棒犯過，而且第三棒也犯過）
**第四棒問了第二次「那些 token 換了沒」**，決策者回：「**token 都已經撤銷了，不要再問我這個了，早就都換掉了。**」

**進入前務必讀完本文件第五節的「已拍板原則」與第六節「已結清的事」。**

### 事實一定要回程式碼查，不要只信文件
**這是最重要的一條。** 前四棒在十二塊裡抓到三十幾條文件錯誤。

**三個查證手段，按有效性排序**：
1. **查 commit message**——常常直接回答「當初為什麼這樣做」
2. **登入實機看**——188/189/190 三台
3. **開檔看程式**——不要憑報告或印象

### 白話
讀者是 PM 與老闆。**「白話」不是把句子講得口語，是讀者完全不需要技術背景就能懂。**

**禁止寫**「已確認安全」「沒有漏洞」「全面檢視」。

### 不要自己改結論
可以說「這條我覺得評太輕／太重」並說理由，**但改不改由決策者決定**。

### 🔴 長工作結束要發桌面通知（2026-09-21 決策者要求）
subagent 回報、一塊過完、有事等他裁——都要發：
```
terminal-notifier -title "資安報告內化" -subtitle "<一句主旨>" -message "<白話一句>" -sound Glass
```
**不要用 `osascript`**（在 PyCharm 終端機裡會靜默失敗）。小動作不必發。

### 三個 repo + 實機 + 資料庫
- 主專案：工作目錄
- 套件：`/Users/chouraymond/Projects/Jedicogy/module/jedi-python-package/`
- 前端：`/Users/chouraymond/Projects/Billows/Audit-Manager/compliance-manager-fe`
- agent：`/Users/chouraymond/Projects/Billows/Audit-Manager/evidence-agent`
- License Center：`/Users/chouraymond/Projects/Billows/Audit-Manager/license_center`
- 實機：`ssh jedi@192.168.50.189`（POC）、`ssh jedi@192.168.50.190`（E2E）
- 資料庫：本機 `localhost:5432` / `guidant_ai_dev` / `.env` 裡的 `cmmgr`

🔴 **實機只能唯讀**（CLAUDE.md 環境異動鐵律）。**DEV 可以寫**（第四棒經決策者指示清空過紀錄表）。

---

## 🔴 決策者已拍板的原則（跨模組適用，遇到同類問題直接援引）

### 一～七（前三棒立的，仍有效）
1. **密碼類欄位預設不回傳**（標記制，不是名單制）
2. **權限檢查走「一條路由 ＋ 登記」**，不為每個情境各開路由
3. **所有修法都要先判斷「功能不能壞」**
4. **「帶出公司」這類論述要驗證再寫**
5. **不要相信呼叫方自報的東西，自己去查**（收編號、後端查網址）
6. **落地版的設定，客戶自己要管得到**（子公司層級不能改全公司設定）
7. **交出去的資料要編碼，不是刪掉**（資訊一個位元都不能少）

### 八、🆕 止損定調（第四棒立）
**這一波掃描到此為止，有掃到什麼就修什麼，不硬掃完。** 根因是檢視工具本身不可靠（一批打 17 小時換 25 次人零產出、紀錄被誤刪）。

**對外的講法**：不是「時間不夠」（聽起來像便宜行事），是「**工具不可靠，我們判斷繼續投入不划算，改成針對已發現的修**」——**那是專業判斷，而且我們有證據**。

### 九、🆕 憑證外流一律已修正（第四棒立，**全站適用**）
**所有外流的 token、金鑰、密碼都已經撤銷／換發完畢。報告一律標「已修正」，剩下的只有清版控殘留字串。**

🔴 **不要再問決策者「那些換了沒」。**

### 十、🆕 環境差異不列入狀態判斷（第四棒立）
**上線前會有一次大更新，全部替換成最新版本**——所以「開發環境已修」就等於「這個問題解決了」。

**報告要回答的是「這個問題我們有沒有解決」，不是「每台機器現在跑到哪一版」。**

### 十一、🆕 安全措施不可以擋住正常客戶（第四棒立）
決策者原話：「**你不能因為設定錯誤就不讓啟動了，客服會瘋掉。**」

**判準**：安全措施如果會讓正常客戶用不了，**那個措施本身就是問題**。往安全那邊倒（用安全的預設值），不要擋住啟動。

### 十二、🆕 落地版是一家客戶裝一套（第四棒立）
**「跨客戶看得到」這件事在落地版根本不存在**——整座資料庫就是那家客戶的。

**這條解掉了 M04 第 4 條**（紀錄表要不要做客戶隔離 → 不用）。

### 十三、🆕 「部分能分」等於「不能分」（第四棒立）
決策者原話：「**會變成有的可以分、有的不能分。**」

**判準**：如果一批資料裡有些標得了、有些標不了（例如登入失敗、系統啟動、背景排程都沒有客戶），**那個隔離就做不成**——標不了的要嘛留空（規則會把它們全擋掉，資料等於廢掉）、要嘛塞假值（追查更混亂）。

### 十四、🆕 讓意圖變明確，模糊地帶就消失（第四棒立，M17 第 3、4 條）
**問題不是「沒選的人看得到全部」，是系統分不出「你刻意選全部」跟「你忘了選」。**

**修法**：把「沒選」變成不合法，強制選一個明確的值（例如「全公司」或「指定部門」）。**一個設計解掉三個問題。**

### 十五、🆕 沒人用的東西不要留著（第四棒重申，已是第四次）
**現在無害的唯一理由是「沒人用它」→ 只要有人接上去就憑空多出沒有檢查的入口。**

**四處裁定一致，都是「直接刪掉」**：M06 兩條、M23 成員名冊、M04 那支開發工具。

🔴 **但刪之前一定要確認全系統全套件零引用**（決策者要求）——第四棒查 M04 那支時查了七個面向（套件、主專案、四個 repo、隔離規則、函式、檢視表、觸發程序、出貨基線、migration）。第五棒 M10 又裁三處刪（第 8、9、19 條）＋一整頁前端舊頁拆除（第 14 條）。

### 十六、🆕 每條問題先講「在哪裡、誰做什麼、發生什麼」（第五棒立，全站適用，🔴 最高優先）
決策者原話：「**我發現你跟我說問題的時候，我全不知道是在哪邊發生什麼事情，這樣我沒辦法判斷。**」「**html 那份內化的報告要重寫清楚問題發生在哪邊，不然我同事不知道你在講什麼。**」

**兩層都適用**：
- **講給決策者聽時**：每條先講場景——哪個畫面／功能、什麼身分的人做什麼動作、發生什麼本來不該發生的事——再講判斷。不要從「第幾條、幾筆、哪支程式」開始。
- **報告內文**：每條問題（問題一覽的「問題」欄與展開段）固定四件：在哪裡／誰做什麼／發生什麼／怎麼修。**驗收標準：沒看過程式的同事讀完要知道在講什麼。**

**此規則寫進之後每張改稿卡的施工要求**。已改完的頁不回頭大掃。

### 十七、🆕 任務操作的角色規則（第五棒立，M10 第 6 條與 M06 第 7 條修正時要守）
| 操作 | 誰能做 |
|---|---|
| 完成／退回任務、上傳／刪除佐證 | 被指派的人＋管理者 |
| 問卷「填寫中」填答 | 填寫者本人＋管理者 |
| 問卷「審核中」填答與通過／退回 | 審核者本人＋管理者 |
| 任務留言新增 | 專案參與者都可以；讀取要補「是參與者」檢查 |

**「完成任務」那道檢查弱點掃描模組 8 支也在吃，修的時候一起改。**「批次完成」那支已是正確寫法，單筆照抄。

---

## 🔴 已結清的事（不要重列成待決）

| 事 | 結果 |
|---|---|
| 所有 token／金鑰／密碼換發 | **已全部撤銷換發**（原則九），只剩清版控殘留 |
| 公開網站資料庫密碼 | **不換**（只有測試機在用） |
| 測試機密碼 | **不用換** |
| Google 硬碟那三件 | **不歸我們管**（客戶自己提供應用程式設定）；CM-1992 留作紀錄 |
| M18 第 7 條（三環境共用公鑰） | **不管**（沒有正式站，架上去就好） |
| M04 第 13 條（黏字串） | **不動**（值都是乾淨的，部門路徑沒人填） |
| M04 第 6 條（Redis 不驗憑證） | **不修**（跑在容器內部，要攔線得先進主機，而那時直接讀設定檔更快） |
| M04 第 5 條（完整出錯內容進表） | **維持原樣**（那張表沒開放給外面，讀的都是維運人員） |
| M16 第 1 條（測試寄信） | **不是我們的問題**（客戶最上游自行管控權限分配） |

---

## 🔴 第四棒修正過的既有裁定（下一棒要知道）

### M03 那 11 張表要分兩組改（不是一律照同一套）

**原本的裁定**：11 張隔離規則寫反的表集中處理、出貨前完成、改用正確寫法。

**M18 查證後修正為**：

| | 怎麼改 |
|---|---|
| **8 張** | 改成正確方向 |
| **3 張授權表** | 🔴 **讀保持現狀、寫要擋掉** |

**為什麼**：授權的設計是「照綁在最頂層，底下子單位共用」——**「子單位看得到母公司的授權」正是設計要的**。改成跟其他八張一樣，**每個子單位查不到頭上那張照，會被判成「沒買」，打任何功能都被擋掉**。

🔴 **CM-1993（M03 那張卡）已經做完了，報告上現在還是舊說法**——**文件首腦已回報這個風險，下一棒要確認有沒有修正**。

---

## 派工紀律

- **一定帶 `model` 參數**，prompt 第一行寫「model：X／effort：Y／理由一句」
- 機械性查證 `sonnet`，要判斷 `opus`
- **只讀不改**的查證要在 prompt 裡寫死
- 回報只要結論，不要貼文件內容回來
- 顯式 `git add <檔名>`，禁用 `-am`
- **push 一律等決策者明確指示**。不要切 branch
- 🔴 **subagent 的回報要自己核對過再講給決策者聽**

### 🔴 查證 prompt 一定要問的三件（第四棒的經驗）
1. **每一個數字都要重數**——十二塊裡十二塊都有數字錯
2. **標「已修」的要實際驗**——M16 兩條、M18 一條都是標已修實際沒修
3. **跨頁重複要比對**——M17 第 8 條 ＝ M23 第 1 條（同一件事），**收尾總表會重複計數**

---

## 與文件首腦的分工

還有一個 session 是**文件產出線的首腦**，負責格式、事實驗證、build。

**分界：它動格式與事實，你動內容與結論。** 那 23 份 md 在內化期間以你為主。

**所以你不要自己改那些 md**——整理成 Notion 卡，決策者會轉給文件首腦派工。

### 🔴 第四棒改變的做法：不要補充式改稿（決策者 2026-09-21 要求）

決策者原話：「**要記得要 review 過整篇文章，直接調整成正確的內文，不要用 append 的方式，我都看過了，不要有雜訊，也都要白話文，不要太工程師——之前一堆文字看不懂。**」

**所以每張卡的施工要求都要寫這四條**：
1. **不要補充或加註**，直接把內文改成正確的——**不要留下「原本寫 X、現在改 Y」的痕跡**
2. **整頁從頭讀過再動手**
3. **全篇白話**，技術名詞換成它做的事
4. **不要有雜訊**——過程、沿革、「查證發現」這類敘述不進報告

### 派工卡必須交代的三件事
1. **施工清單列的是改動起點，不是全部**
2. **自我檢查那句要寫進卡**：「如果讀者只讀這一頁、從頭讀到尾，會不會讀到兩句互相打架的話？」
3. **刪除類改動要列出 grep 關鍵詞**

---

## 🔴 浮現中的問題分組（收尾要用）

| 組 | 成員 | 一句話 |
|---|---|---|
| **A. 只驗登入、不檢查歸屬** | M02、M06、M05（七條）、M10、M03、M19、M23 | **最大的一組** |
| **B. 鑰匙掛在牆上** | M02、M01、M22、M16、M09 | 拿到憑證就繞過所有檢查 |
| **C. 想到了，只做了一半** | M01、M02、M05、M22、M06 | **不是沒想到，是做了一部分就停了** |
| **D. 信任鏈的起點沒人守** | M08 | 驗證工具自己不在被驗證範圍內 |
| **E. 客戶層級的權限改到全系統共用那份** | M22、M09、**M16** | 判準見原則六 |
| **F. 進來照實記，交出去沒把關** | M09、M21 | 該編碼的沒編碼 |
| **G. 有正確版本但沒用** | M06、M08 | **東西寫對過，但被重做的時候沒跟上** |
| **🆕 H. 宣告了權限，只有畫面在認** | **M03（八支）、M19（七支）、M23（五顆）、M15（四支）** | **四處全部裁定「後端補檢查」，方向一致** |
| **🆕 I. 沒人用的入口也是入口** | **M06 兩條、M23 成員名冊、M04 開發工具** | **四處全部裁定「直接刪掉」** |
| **🆕 J. 憑證寫進版控** | **M23、M17、M16、M15** | **全部已裁定為已修正、殘留待清** |
| **🆕 K. 報告寫的是「當時」，事實後來變了** | **M04、M10、M15、M17、M16、M18** | 🔴 **這組是方法論層級的發現，收尾要單獨講** |

### 🔴 一條沒人串起來的線（收尾單獨講）
**「帳號可以沒有部門」這個模糊狀態，在兩個地方造成相反的結果**：

| 哪裡 | 沒部門的人會怎樣 |
|---|---|
| **公告** | **全部看得到**（過濾整個跳過） |
| **意見回饋** | **什麼都送不出去**（被資料庫規則擋住） |

**共同根因**：全系統沒有規定這種帳號該看到／做到什麼，**兩邊的作者做了相反的假設，各自寫在自己那一層，沒人對齊**。

**決策者已裁定兩邊分開看**（公告要選發送對象、意見回饋不需要部門），**但這個形狀值得在分析章節單獨提一段**。

---

## 🔴 零、下一步：修正派工首腦（卡 **CM-2019** https://app.notion.com/p/SUMMARY-145-worktree-3e2346da4cd0816a87fde3fc8a7eb10c ）

收尾棒 CM-2018 已交：`docs/security-report/SUMMARY.md`——145 件（194 條去重）、每件標所屬修正批、六批順序、十一組病因。**但總表按嚴重度排，不是派工單**；派工首腦要把它拆成「一個 worktree 一張卡」。決策者兩個補裁（2026-09-21）：①合規資源庫那條（M10 第 11 條）改**中**、後端補「改控制項清單前先確認範本是自己客戶的」（資料庫只擋主表、控制項那兩張表沒牆，子公司改母公司分享範本今天打得通）；②左側選單不對齊首頁表。

## 零之一、（已完成）總報告收尾（卡 **CM-2018** https://app.notion.com/p/3e2346da4cd0810b8546c082fae0159d ）

**內化階段已結束。** 第五棒與決策者定的收尾方式與修正順序如下，收尾棒與派工棒都照這個走。

### 兩份總表，以誰為準
| | 在哪 | 定位 |
|---|---|---|
| **內化報告（23 塊）** | `docs/security-report/` | **骨架**——有決策者裁定 |
| **掃描總表** | `docs/features/security-scan-consolidated/README.md` | 工具產出、**還在長**（FR-113 oscal 主專案側 9/21 才掃出第 118～122 項，例如第 120 項「改別家範本」就是 M10 第 7 條的完整現場）；§2 那 41 張舊修正卡與 CM-1983 分組草案**決策者裁定作廢，以最新裁定為準** |

收尾棒做法：**以 23 塊裁定為骨架，把掃描總表 §3 裡 23 塊沒涵蓋的新項對進去**（標明來源與所屬修正批）；之後掃完的再補進同一張總表。

### 收尾產出（四件，寫進 README.md 首頁）
1. **一頁摘要**（給只看一頁的人）
2. **問題總表**（去重、按嚴重度、**每條標所屬修正批**——這張表就是派工源）
3. **分析與結論**：上面十一組病因＋**K 組單獨講一段**（方法論層級）＋「帳號沒部門」那條線單獨一段
4. **修正建議**：只列順序不寫日期，照下面六批

🔴 **去重**：至少 M17 第 8 條＝M23 第 1 條；M10 **第 11 條**（改稿後條號；合規資源庫）＝掃描總表第 67／120 項；M13 第 10 條的主專案複製品 FR-085 C1 早撿到過。總表要合併計數。

### 🔴 修正順序（決策者 2026-09-21 裁定，六批）
判準：①先修「別人要靠它」的地基 ②同一套修法併一批、批與批互不相依才能分頭。

| 批 | 內容 | 為什麼 | repo | 平行？ |
|---|---|---|---|---|
| **1 權限地基** | M10 A 組（成員檢查／必填／驗物）＋原則十七角色規則（完成／退回／佐證／問卷審核）＋M06 第 7 條＋弱點掃描 8 支同道檢查 | 其他模組「補檢查」全是呼叫這一塊，它沒定好後面都在猜 | task-platform、flow-engine、survey、detection、BE | 🔴 **先做** |
| **2 只驗登入不檢查歸屬（A／H 組）** | M02、M03 八支、M05 七條、M19 七支、M23 五顆、M15 四支、M06 讀取、M10 第 2～4 條 | 修法＝補一行去問第 1 批，機械活 | 各套件＋BE | ✅ 第 1 批後**按模組平行**，一模組一 worktree |
| **3 刪除類（I 組）** | M06 兩條、M23 名冊、M04 開發工具、M10 三處寫入＋「專案任務設置」整頁、M13 快取複製品 | 零引用已查、互不相依 | BE、FE、套件 | ✅ **現在就能開始** |
| **4 憑證殘留（J 組）** | 版控字串清理、M23 第 6 條打包腳本 | 純機械 | BE、FE | ✅ 現在就能開始 |
| **5 設定與信任鏈（B／E／G／D 組）** | M01 代理程式、M08 防竄改、M22／M09／M16 客戶層級改全域、M13 第 17 條停權即時生效 | 各自獨立、各有設計判斷 | agent、BE、jedi-iam | ✅ 平行，每條要人看 |
| **6 資料庫牆** | M20 第 5 條 53 張（併 M11） | 決策者裁：程式面修完→測一版→再做 | BE migration | ⏸ 最後 |

**三個坑**：①第 1、2 批幾乎全在套件，worktree 要 BE＋套件各開、BE `pyproject.toml` 改 path dependency 指向套件 worktree（不 commit）；②每模組開卡把**每個入口 file:line 列成驗收項**（[[feedback_parallel_runners_two_entrypoints_one_fixed]]）；③舊的 41 張修正卡與 CM-1983 草案在總表標「作廢」，不然平行 session 會撿到過期的。

**決策者的打算**：修正 repo 開 worktree 分頭做，掃描還在跑的那條線繼續。第 3、4 批不依賴總表，可先動。

### 另兩項業界標準補強（不急）
報告封面基本資料、風險評級標準說明。

---

## 開場怎麼做

1. 讀完本文件（特別是第五節「已拍板原則」與第六節「已結清的事」）
2. **跑 pre-flight 唯讀盤點**（見下一節的現況表，確認與實際相符）
3. 用三五句話說你理解的「這份報告要解決什麼問題」
4. 問決策者任何不清楚的
5. **然後等他發令**，不要自己開始

**23 塊已全部過完，沒有下一塊。** 接手者的工作是收尾棒（CM-2018）或派工棒，不是繼續內化。開場照樣：讀完、盤點、等令。

---

## 現況盤點（2026-09-21 機器導出）

# 資安報告內化 arc 現況盤點（唯讀，第五棒交接用）

盤點時間：2026-09-21（依 git log 與 DB 現查）

## 一、23 塊報告的內化狀態

判準：檔案內出現「已裁定」「決策者裁定」等裁定字樣視為「已內化」；`M11`／`M12` 明確標註「這一塊到今天為止，一輪檢視都沒有做過」，故獨立標「未檢視」。

| 塊代號 | 中文名（含套件名） | 條數（問題編號行數） | 內化了沒 | 裁定字樣出現次數 | 最後 commit 日期 |
|---|---|---|---|---|---|
| M01 | 遠端代理程式（jedi-remote-agent） | 6 | 是 | 8 | 2026-09-20 |
| M02 | 檔案上傳下載（jedi-file-upload） | 10 | 是 | 3 | 2026-09-20 |
| M03 | 弱點檢測整合（jedi-detection） | 14 | 是 | 7 | 2026-09-21 |
| M04 | 共用基礎（jedi-common） | 14 | 是 | 1 | 2026-09-20 |
| M05 | 問卷（jedi-survey） | 13 | 是 | 3 | 2026-09-20 |
| M06 | 稽核流程（jedi-flow-engine） | 16 | 是 | 5 | 2026-09-20 |
| M07 | 證據自動分類（jedi-evidence-classification） | 12 | 是 | 7 | 2026-09-20 |
| M08 | 防竄改檢查（jedi-integrity） | 12 | 是 | 5 | 2026-09-20 |
| M09 | 系統日誌（jedi-log） | 5 | 是 | 6 | 2026-09-20 |
| M10 | 任務與成員管理（jedi-task-platform） | 20 | 否（無裁定字樣；問題表逐條複驗過但「怎麼修」欄無裁定內容） | 0 | 2026-09-20 |
| M11 | 合規文件核心（jedi-oscal-v2） | 0 | 未檢視（頁面明寫「這一塊到今天為止，一輪檢視都沒有做過」） | 0 | 2026-09-20 |
| M12 | 稽核輪次管理（jedi-compliance-audit） | 0 | 未檢視（同上，頁面明寫「一輪檢視都沒有做過」） | 0 | 2026-09-20 |
| M13 | 登入與權限（jedi-iam） | 16 | 是（狀態欄全部 ✅，含 1 筆「決策者裁定」） | 1 | 2026-09-20 |
| M14 | AI 聊天助手（jedi-ai-bot） | 1 | 是 | 3 | 2026-09-20 |
| M15 | AI 儀表板（jedi-ai-dashboard） | 6 | 是 | 7 | 2026-09-21 |
| M16 | 寄信與通知（jedi-notification） | 8 | 是（「裁定」字樣 1 次，非「已裁定／決策者裁定」固定句型，故上表判準未命中但實質已裁定） | 0（固定句型）／1（廣義「裁定」） | 2026-09-21 |
| M17 | 公告（jedi-bulletin） | 11 | 是 | 12 | 2026-09-21 |
| M18 | 授權管理（jedi-license-runtime ＋ 簽發站） | 9 | 是 | 5 | 2026-09-21 |
| M19 | 設備與資訊系統清冊（jedi-asset） | 3 | 是 | 9 | 2026-09-20 |
| M20 | 客戶資料隔離（跨模組專項檢查） | 5 | 是 | 1 | 2026-09-20 |
| M21 | 意見回饋重新檢視（跨模組專項） | 3 | 是 | 11 | 2026-09-21 |
| M22 | 系統設定（jedi-system-core） | 3 | 是 | 6 | 2026-09-20 |
| M23 | 意見回饋（jedi-issue） | 7 | 是 | 3 | 2026-09-21 |

**備註**：
- 條數＝檔案內 `^| \*\*[0-9]` 開頭的表格列數（即「問題一覽」表的編號列數），M11／M12 因無問題表故為 0。
- M16 的裁定字樣是「**裁定**：寄信設定由客戶最上游的帳號自行管控⋯」，語意上等同已裁定，只是未用「已裁定」或「決策者裁定」固定句型，判準抓取邏輯上會被算成「否」，實際內容應視為「是」——此處按盤判準字面結果與語意結果分列，交接時請下一棒自行核對。
- M10 的問題表 2026-09-20 有「逐條回程式碼複驗過」的 callout，12 條全部仍在、沒有任何一條被修掉，但「怎麼修」欄目前是純技術修法敘述，未見裁定內容。

## 二、Notion 卡清單（CM-1981 ～ CM-2014，含資安總報告相關卡）

來源：`python scripts/notion_case.py query --case <CM-xxxx>`（CM-1981 逐一查到 CM-2014）

| 卡號 | 標題 | 狀態 |
|---|---|---|
| CM-1981 | [資安總報告] M02 檔案上傳下載 — 內化修訂（3 條事實錯誤 + 7 項講者決策落地） | 修正待驗證 |
| CM-1982 | [資安總報告] M01 遠端代理程式 — 內化修訂（5 條描述更正 + 1 條新發現 + 6 項講者決策） | 修正待驗證 |
| CM-1983 | 資安掃描總表 117 條分類——按「修一套解一片」分組、每組出一張修正卡草案（分析棒，只寫文件不改程式、不開卡） | 修正待驗證 |
| CM-1984 | [資安總報告] M08 防竄改檢查 — 內化修訂 | 修正待驗證 |
| CM-1985 | [資安總報告] M22 系統設定 — 內化修訂 | 修正待驗證 |
| CM-1986 | 資安掃描總表數字對齊——照 CM-1983 更正表改六處、§0/§0.5 定稿數字（機械性） | 修正待驗證 |
| CM-1987 | [資安總報告] M09 系統日誌 — 內化修訂 | Not started |
| CM-1988 | [資安總報告] 全站三項裁定落地——出貨前定位／拿掉行號／M01 M02 回頭修 | 修正待驗證 |
| CM-1989 | [資安總報告] M06 稽核流程 — 內化修訂 | 修正待驗證 |
| CM-1990 | [資安總報告] M05 問卷 — 內化修訂 | 修正待驗證 |
| CM-1991 | [資安總報告] M07 證據自動分類 — 內化修訂 | 修正待驗證 |
| CM-1992 | [資安檢視-記錄] Google 雲端硬碟同步功能 — 三件待裁事項與未檢視盤點 | Not started |
| CM-1993 | [資安總報告] M03 弱點檢測整合 — 內化修訂 | 修正待驗證 |
| CM-1994 | [資安總報告] 全站裁定（二）— 本輪掃描止損定調 | 修正待驗證 |
| CM-1995 | [產品行為] 共用分頁查詢：多個文字條件是「或」不是「且」 | Not started |
| CM-1996 | [資安總報告] M19 設備與資訊系統清冊 — 內化修訂 | 修正待驗證 |
| CM-1997 | [資安總報告] M23 意見回饋 ＋ M21 重新檢視 — 內化修訂（兩頁合一） | 修正待驗證 |
| CM-1998 | FR-081.G 修 打包前端映像檔的腳本內嵌 Nexus 帳密且已入版控（跨 BE/FE 兩 repo 四檔） | Not started |
| CM-1999 | [資安總報告] M15 AI 儀表板 — 內化修訂 | 修正待驗證 |
| CM-2000 | FR-113 jedi-oscal-v2 主專案側接線 資安掃描（10 棒，只掃不修） | Not started |
| CM-2001 | FR-113.O1 掃 oscal 主專案側「控制項實作與權限判斷核心」 | 修正待驗證 |
| CM-2002 | FR-113.O2 掃 oscal 主專案側「資源庫、公版範本、匯出」 | Not started |
| CM-2003 | FR-113.O3a 掃 oscal 主專案側「Excel 上傳入口與確認流程」 | Not started |
| CM-2004 | FR-113.O4 掃 oscal 主專案側「Word 上傳與解析全鏈」 | Not started |
| CM-2005 | FR-113.O5 掃 oscal 主專案側「SSP 六種子物件的增刪改查」 | Not started |
| CM-2006 | FR-113.O6 掃 oscal 主專案側「程序書文件池與匯入比對引擎」 | Not started |
| CM-2007 | FR-113.O8a 掃 oscal 主專案側「合規框架 PDF 解析工作」 | Not started |
| CM-2008 | FR-113.O8b 掃 oscal 主專案側「合規框架與版本的增刪改查」 | Not started |
| CM-2009 | FR-113.O9 掃 oscal 主專案側「接線總裝、稽核階段掛鉤、人員對帳」（18 檔超標待切） | Not started |
| CM-2010 | FR-113.O3b 掃 oscal 主專案側「Excel 內容解析」 | Not started |
| CM-2011 | [資安總報告] M16 寄信與通知 — 內化修訂 | 修正待驗證 |
| CM-2012 | [資安總報告] M18 授權管理 — 內化修訂 | 修正待驗證 |
| CM-2013 | [資安總報告] M17 公告 — 內化修訂 | 修正待驗證 |
| CM-2014 | [資安總報告] M04 共用基礎 — 內化修訂 | Not started |

**備註**：CM-2000 ～ CM-2010 為 FR-113（jedi-oscal-v2 主專案側接線掃描）系列卡，與 M11/M12 未檢視狀態相關但不是同一 arc 的內化卡；列出供交接對照。CM-1987（M09）與 CM-2014（M04）Notion 狀態仍是「Not started」，與 §一盤點的「已內化（有裁定字樣）」結果不一致，需下一棒核對是否漏回寫 Notion 狀態。

## 三、git 現況

| 項目 | 內容 |
|---|---|
| 當前 branch | `feature/review` |
| `git status --short -- docs/security-report/` | 無輸出（乾淨，無未 commit 異動） |
| unpushed commits 數（`origin/feature/review..HEAD` 全 repo，非僅 security-report） | 14 |

**最近 15 筆動到 `docs/security-report/` 的 commit（oneline）：**

| # | commit | 說明 |
|---|---|---|
| 1 | bac27ddd | docs(security-report): CM-2013 M17 公告內化修訂——第 3、4 條合併成一套設計，六條憑證外流改標已修正 |
| 2 | d7fc878d | fix(security-report): CM-1993 M03 第 7 條的修法會把授權功能改壞——改成分兩組（照著報告做會出事） |
| 3 | 3a91a952 | docs(security-report): CM-2012 決策者裁定——M18 第 8 條提為高風險，並寫明與第 1 條的對照 |
| 4 | bab678d1 | docs(security-report): CM-2012 M18 授權管理內化修訂——新增三張表門禁規則方向寫反一整段 |
| 5 | c8ec7597 | docs(security-report): CM-2011 決策者兩項裁定——M16 第 1 條降為中，第 6 條拆成三分項 |
| 6 | 8a022e41 | docs(security-report): CM-2011 M16 寄信與通知內化修訂——第 1 條定性整條改寫，四條憑證外流改標已修正 |
| 7 | 67de39b8 | docs(security-report): CM-1999 統計表改用讀者看得懂的說法——決策者裁定拿掉「範圍內／外」 |
| 8 | 81387e5d | docs(security-report): CM-1999 M15 AI 儀表板內化修訂——整頁重寫為正確版本並全篇白話化 |
| 9 | 61f0586d | docs(security-report): CM-1997 決策者兩項裁定落地——M21 第 2 條降級、打包腳本帳密獨立成 M23 第 6 條（新開 CM-1998） |
| 10 | 83902ab8 | docs(security-report): CM-1997 M23 意見回饋 ＋ M21 重新檢視內化修訂（兩頁合一） |
| 11 | f80f708c | docs(security-report): 文件首腦交接（第二棒 → 第三棒）——九塊內化完成，新增三個坑 |
| 12 | 425ba57d | docs(security-report): CM-1996 M19 設備與資訊系統清冊內化修訂——裁定推翻舊決定，補上「會擋掉誰」 |
| 13 | ca130512 | docs(security-report): M14 AI 聊天助手第 1 條——裁定要修，與 AI 儀表板合併處理 |
| 14 | d9a3b89c | docs(security-report): CM-1994／CM-1993——本輪掃描止損定調，M03 十二項內化修訂 |
| 15 | 8aefea10 | docs(security-report): CM-1991 M07 證據自動分類內化修訂——舊線整組退役，五條隨之消失 |

## 四、查證產出的暫存檔

目錄：`/private/tmp/claude-501/-Users-chouraymond-Projects-Billows-Audit-Manager-compliance-manager-be/1b41850e-7f86-48c9-a75d-0cb62774d0d8/scratchpad/`

| 檔名 | 大小 | 最後修改時間 |
|---|---|---|
| DB_PASSWORD.txt | 24524 bytes | 09-20 23:35 |
| DRIVE_TOKEN_ENCRYPTION_KEY.txt | 1031 bytes | 09-20 23:35 |
| GOOGLE_DRIVE_OAUTH_CLIENT_SECRET.txt | 1241 bytes | 09-20 23:35 |
| REDIS_PASSWORD.txt | 24524 bytes | 09-20 23:35 |
| drive_card.py | 12397 bytes | 09-20 22:25 |
| drive_spec.json | 14516 bytes | 09-20 22:25 |
| global2.md | 1397 bytes | 09-21 16:48 |
| global_card.py | 6429 bytes | 09-20 23:14 |
| global_spec.json | 7427 bytes | 09-20 23:14 |
| m03_card.py | 24099 bytes | 09-20 23:14 |
| m03_spec.json | 28540 bytes | 09-20 23:14 |
| m04_card.py | 14876 bytes | 09-21 16:48 |
| m04_spec.json | 18402 bytes | 09-21 16:48 |
| m05_card.py | 17373 bytes | 09-20 21:24 |
| m05_spec.json | 20947 bytes | 09-20 21:24 |
| m07_card.py | 19801 bytes | 09-20 22:20 |
| m07_spec.json | 23456 bytes | 09-20 22:20 |
| m15_card.py | 14788 bytes | 09-21 13:10 |
| m15_fix.md | 1390 bytes | 09-21 13:12 |
| m15_spec.json | 18224 bytes | 09-21 13:10 |
| m16_card.py | 12514 bytes | 09-21 15:06 |
| m16_spec.json | 15206 bytes | 09-21 15:06 |
| m17_card.py | 10108 bytes | 09-21 15:49 |
| m17_spec.json | 12300 bytes | 09-21 15:49 |
| m18_card.py | 11527 bytes | 09-21 15:32 |
| m18_spec.json | 13997 bytes | 09-21 15:32 |
| m19_card.py | 11897 bytes | 09-20 23:41 |
| m19_spec.json | 14124 bytes | 09-20 23:41 |
| m23_append.md | 3441 bytes | 09-21 00:08 |
| m23_card.py | 18993 bytes | 09-21 00:07 |
| m23_final.md | 3153 bytes | 09-21 00:14 |
| m23_spec.json | 22692 bytes | 09-21 00:07 |
| pager_card.py | 4255 bytes | 09-20 23:15 |
| pager_spec.json | 5041 bytes | 09-20 23:15 |
| pg.env | 124 bytes | 09-20 21:52 |
| scan.py | 1349 bytes | 09-20 21:03 |
| scan2.py | 1418 bytes | 09-20 21:03 |

**注意**：目錄內含 4 個含真實憑證的檔案（`DB_PASSWORD.txt`／`DRIVE_TOKEN_ENCRYPTION_KEY.txt`／`GOOGLE_DRIVE_OAUTH_CLIENT_SECRET.txt`／`REDIS_PASSWORD.txt`），是 scratchpad 暫存區、非版控範圍，本盤點僅列檔名未開內容。

## 五、DEV 紀錄表現況（唯讀 SELECT，DEV：localhost:5432 / guidant_ai_dev，帳號 cmmgr）

| 資料表 | 筆數 |
|---|---|
| `public.api_logs` | 0 |
| `public.system_logs` | 0 |

**`log/` 目錄檔案清單與密碼明文掃描結果**（`grep -ac '"password":"'`）：

| 檔名 | 大小 | 含 `"password":"` 筆數 |
|---|---|---|
| log/app.log | 97925 bytes | 0 |
| log/app.log.2026-09-20 | 4431457 bytes | 0 |
| log/app_restart2.log | 24423 bytes | 0 |
| log/app_restart3.log | 17517 bytes | 0 |
| log/be_overnight.out | 40817 bytes | 0 |
| log/gunicorn-error.log | 1437 bytes | 0 |
| log/socketio_console.log | 43978 bytes | 0 |
| log/start.log | 1480 bytes | 0 |

共 8 個檔案，皆為 0 筆命中。
