# FR-107 交接現況（living，就地更新）

> **這個檔只描述「此刻」。** 每棒只 Edit 變動的節，決策脈絡與教訓寫進
> [`fr107-LOG.md`](fr107-LOG.md)（append-only）。
>
> 最後更新：2026-09-17 首腦（第五棒，開發收口：30／33 Done、三 repo 已 push、出貨三卡暫停等發版）

---

## §0 接手讀序

1. 本檔 §1 WHY ← 先讀，不懂為什麼要拆這樣容易把「照卡做完」當目標
2. 本檔 §2～§8（環境座標／已定裁示／表 A 卡片狀態／表 B commits／待決策者／follow-up／下一棒）
3. [`fr107-LOG.md`](fr107-LOG.md) 全部 Block（尤其 Block 3「推翻了什麼」、Block 4）
4. 母卡 [CM-1843](https://app.notion.com/p/FR-107-2-0-22-3dd346da4cd08161b91ef582075062d0)、design.md（規格來源）
5. 三張跑中卡（T-3.4／CM-1860、T-4.1／CM-1861、T-5.3b／CM-1877）的卡面「首腦補充」段
6. 要動哪一棒才讀那張子卡

**冷接自檢**（答不出來回頭讀）：
- 為什麼新功能全部進套件 `jedi-evidence-classification`、不開新套件？（D11）
- state 的鍵為何從 `[a]` 換成 `part_id`？對位到 design.md 哪張表／哪個風險？（風險 6、§6.1.4）
- 金鑰三層解析順序是什麼？第一版誰能改金鑰設定頁？（D13）
- 套件 migration 落在哪個目錄、登不登 `schema_migrations`？跟主線 `scripts/sql/` 有什麼不同？
- 為什麼三支套件現在是 path dependency 且主專案 `pyproject.toml` 未 commit？下次發版前要做什麼？（答案見 §6／§8）

---

## §1 WHY

決策者 2026-09-16 母卡 CM-1843 首段：**把「證據自動分類」從 Google Drive 搬回系統自己
的儲存後端，分完的檔直接搬進任務變成正式證據，而且不管哪個合規框架都能用**——落地版
客戶沒有 Drive，舊分類線等於不存在；新功能長在套件裡，主專案只接線與前端。

---

## §2 環境座標

| 什麼 | 在哪 |
|---|---|
| BE 主專案 | `~/Projects/Billows/Audit-Manager/compliance-manager-be/`，branch `feature/review` |
| FE | `~/Projects/Billows/Audit-Manager/compliance-manager-fe/`，同 branch |
| 套件 monorepo | `~/Projects/Jedicogy/module/jedi-python-package/`，同 branch；動 `jedi-evidence-classification`／`jedi-file-upload` |
| E2E | `~/Projects/Billows/Audit-Manager/compliance-manager-test/`（本案 e2e 排在 T-6.3，未到） |
| DEV DB | `localhost:5432 / cmmgr / guidant_ai_dev`（2026-09-13 起在本機，不是 188:25432） |
| BE 服務 | `python main.py`，port 8000，log `log/app.log`；起 BE 的 shell 要帶 `ANTHROPIC_API_KEY`／`AI_PROVIDER_ENCRYPTION_KEY`（`.env` 都有，`load_dotenv` 不覆蓋既有變數，別讓舊 shell 變數蓋掉） |
| DEV 登入 | ROOT 平台管理員 `admin`；tenant 102 租戶管理員 `blsadmin`；一般成員 `blsit`（密碼查 memory `reference_dev_login.md`） |
| 套件 path dependency | `pyproject.toml:126`（jedi-evidence-classification）、`:132-133`（jedi-ai-bot、jedi-ai-dashboard）三行 path 開著，對應 pin `:75`／`:81-82` 註解。**不還原不 commit，等決策者下次發版時併 T-6.4 一次做** |
| 分類容器 image | 本機已 `docker/rebuild.sh` build 出 `evidence-classifier:dev`（已含思考深度參數，重 build 過）；別台機要跑要自己重 build |

---

## §3 已定裁示（D1–D13＋補裁）

一句話版，理由與被排除方案見 design.md「決策定案表」與「寫作時發現的事」兩節：

- **D1** 批次檔存新表 `evidence_batch_files`，`upload_files` 只補租戶／擁有者三欄
- **D2** 容器改甲案：宿主先把整批檔拉到 job 工作目錄，容器零網路零憑證
- **D3** 舊 Drive 分類線並存一版、前端入口隱藏、下一版才刪
- **D4** job 狀態 DB 化併入 .3 做最小版（心跳＋逾時標 failed），不開通用 job 表
- **D5** 分類結果沿用 `evidence_classification_runs` 加欄改掛批次
- **D6** 未設 STORAGE_CONFIG 只在批次上傳路徑擋（412 防呆），落地版安裝即設定不會走到
- **D7** 清批次剩餘檔實刪實體＋留 `removed` 紀錄列
- **D8** 批次權限：manager 建／傳／分類／歸檔／清；auditor 唯讀
- **D9** 不做跨來源（Drive／批次）去重，只提示 hash 相同
- **D10** `upload_files` 孤兒回填歸 ROOT（tenant_id=1），migration 輸出回報筆數
- **D11** 新功能全進既有套件 `jedi-evidence-classification`，不開新套件；落點表見 design.md
- **D12** 支援多供應商 AI：金鑰進 `system_configs` 新 group `AI_PROVIDER_CONFIG`，容器抽 `LlmClient`，型號碼表獨立套件檔 `llm_models.py`
- **D13**（2026-09-17）原廠 AI 金鑰：AI 小幫手／AI Dashboard／證據分類三功能統一金鑰解析
  順序**租戶設定 → ROOT 原廠鑰 → 環境變數**；`AI_PROVIDER_CONFIG` 值走 Fernet 加密落 DB
  （獨立加密鑰，不與 `DRIVE_TOKEN_ENCRYPTION_KEY` 共用）；`install.sh` 裝機把原廠鑰寫進
  ROOT，`--upgrade` 不覆寫既有值；**第一版不開放租戶自填**，金鑰設定頁鎖 ROOT 平台管理員。
  排除項：明文存 DB、加密鑰與密文同機（防護等於沒加）、「原廠代理」完全藏鑰（列為獨立 FR
  候選，未裁，見 §6）

補裁（design.md「寫作時發現的事」，含 2026-09-17 一項修正）：
① 分類容器 image 進出貨包，新增 T-6.4；
② port 切法照 design（`IEvidenceStorage` 只管檔案實體、`ITaskEvidenceSink` 管找任務掛證據）；
③ `classification_profiles` 不建 FK，一律軟參照；
④ **profile CRUD 守門 2026-09-17 修正為「放寬到租戶管理員」**（原裁「只給平台管理員」——
實查發現解析鏈裡租戶那兩層本來就只有租戶管理員建得出來，鎖平台管理員會讓那兩層永遠沒人
用；**金鑰設定頁仍鎖 ROOT 平台管理員，這是 D13 的另一軸，不要混為一談**）；
⑤ `job_evidences` 既存重複列先查不自動合併；
⑥ 舊 route／FE 常數並存期可接受，.6 刪舊線一起清。

---

## §4 表 A：卡片狀態（33 張，2026-09-17 晚間逐張核對 Notion）

**31 張 ✅ Done：**

| 卡 | 是什麼 | commit |
|---|---|---|
| CM-1850 T-1.1 | `upload_files` 補租戶／擁有者／RLS（套件 jedi-file-upload） | 套件 `651e33c`／BE `a48b41cc` |
| CM-1851 T-1.2 | `evidence_batches`／`evidence_batch_files` 兩張表＋狀態機 | 套件 `a6475b4`／BE `c98c119d`／FE `f2f0339` |
| CM-1852 T-1.3 | 批次五條 API＋`IEvidenceStorage` port＋宿主 adapter | 套件 `7e066d6`／BE `276e1369`／FE `6d0ccf6` |
| CM-1853 T-1.4 | 前端「上傳到批次」頁（依 T-1.4m mockup 重刻） | FE `3dc7e93` 起 |
| CM-1878 T-1.4m | 自動分類證據兩頁 HTML mockup | BE `b86fd129`／`393582ec` |
| CM-1854 T-2.1 | 三支 port 定義＋舊 Drive port 標 deprecated | 套件 `8261475` |
| CM-1855 T-2.2 | 宿主三支 adapter＋DI wiring | BE（套件 `8261475` 同批接線） |
| CM-1856 T-2.3 | 容器 image 搬套件 repo＋改讀目錄＋改名 | 套件 `6119da5` |
| CM-1857 T-3.1 | runs 表改掛批次（D5） | 套件 `710e146` |
| CM-1858 T-3.2 | 批次版觸發＋狀態機＋心跳＋啟動掃逾時 | 套件 `8d34642`／BE `9da5f3f6` |
| CM-1859 T-3.3 | run 新定址 route＋批次詳情帶 run | 套件 `839786c`／BE `a9a319c9` |
| CM-1860 T-3.4 | FE 審閱頁換 `run_uid`＋`part_id`＋批次列表／流程頁②③步 | FE `5489e93` |
| CM-1884 | 批次詳情補 `current_run_uid`／心跳／失敗原因，state 帶目標集快照（T-3.4 補洞） | 套件 `35c2fd7` |
| CM-1861 T-4.1 | `job_evidences` 加 `AI_CLASSIFIED`＋`classification_run_id`＋partial UNIQUE＋`attach`／`find_same_content` | BE `0cccfe5b` |
| CM-1862 T-4.2 | 歸檔＋清理兩支 API（`archived→archived` 放行） | 套件 `4fa846b` |
| CM-1863 T-4.3 | FE 歸檔按鈕、摘要、清理詢問、「AI 分類」標籤（`SourceBadge`）；收掉 T-3.4 兩個繞道 | FE `409b10a` |
| CM-1864 T-5.1 | `classification_profiles`＋CRUD＋解析鏈＋`AI_PROVIDER_CONFIG` | 套件 `4d5b431`／BE `d914b7eb` |
| CM-1865 T-5.2 | catalog 補 `part_id`／`group`＋報表改讀快照＋靜態 JSON 退場 | BE `c68afa2a`／套件 `795306b`／FE `bc11786` |
| CM-1866 T-5.3a | prompt 三段組裝 | 套件 `90f0ce3`／BE `46e8ef0f` |
| CM-1877 T-5.3b | 容器多供應商 `LlmClient`（Anthropic＋OpenAI），宿主只注入該家一把鑰 | 套件 `82d78bc`／BE `5e0bad60` |
| CM-1867 T-5.4 | 框架版本管理頁「AI 分類設定」分頁；金鑰頁鎖 ROOT | FE `c230a4d`／`b28f651`／`4488670`；套件 `1f1c73b`；BE `851e2d92`／`09f3a1d0`／`1b96ac93` |
| CM-1879 T-5.5 | 三個 AI 功能統一金鑰來源＋install.sh 寫入原廠鑰（D13） | BE `f87468ff` |
| CM-1883 | 升級路徑也補寫原廠 AI 金鑰（缺補、有不動；順手補「沿用設定」路徑加密鑰不落檔的洞） | BE `267ca531` |
| CM-1885 | 模型碼表換代（Sonnet 5／Opus 5、GPT-5.6 Terra／Luna）＋「思考深度」三檔預設 medium 穿五層；套件 migration 006 | 套件 `d687592`／FE `26972fc` |
| CM-1887 | AI 小幫手 Haiku 4.5、Dashboard 三檔 Sonnet 5、OpenAI 5.6、Gemini 3.5；Anthropic 呼叫 thinking 相容 | 套件 `b26b647` |
| CM-1868 T-6.1 | 拿掉舊 Drive 版前端入口；套件觸發端點標 legacy；follow-up memory | FE `6302535`／套件 `3835bdb`／BE `fcb8b0a6` |
| CM-1869 T-6.2 | jedi-file-upload 1.2.0、jedi-evidence-classification 1.2.0 發 Nexus；pin 還原（後續卡又切回 path） | 套件 `7548c44`／BE `42b29618` |
| CM-1870 T-6.3 | 五頁 SPEC＋FINAL-SPEC（e2e 拆至 CM-1886） | BE `a7036e28`／`1308e0f3` |
| CM-1888 | 決策者手測第一批：篩選下拉、模型下拉不分組、審閱配對改表格、拿掉歸檔方式、classify 送 provider／反查、控制樹補 FILE／LINK 證據、「AI 把握度」、刪整批；追加收件匣文案、SPEC 對齊、選單 icon／分組、歸檔後顯示模型 | FE `1cf8788`／`a6c1284`／`1b4c67c`／`3fa7fce`；套件 `f8fcde4`／`a0a5d6e`；BE `29b99302`／`5840db67`／`1603dab7`／`c235cdfe`／`c3db0b27` |
| CM-1889 | 出貨基線重產：五支主線 migration 進 188 基線庫，02／04／99 重產（04 順帶結清 CM-1833 未重產的退役五路由） | BE `8f92b6c1` |

**2 張暫停（出貨動作，等決策者發版時機）：**

| 卡 | 是什麼 | 狀態 |
|---|---|---|
| CM-1871 T-6.4 | 三支套件發版（jedi-evidence-classification 1.2.1、jedi-ai-bot 1.1.1、jedi-ai-dashboard 1.1.1）＋還原 pin＋分類 image 進出貨包 | 決策者 2026-09-17 裁「先不發版，後續幾個 FR 一起發」。卡末首腦補充已寫好六步與兩個結構缺口（§6） |
| CM-1886 T-6.3b | e2e 補跑（stub 分類容器） | 吃 T-6.4 的 image 進 190，跟著暫停 |

母卡 CM-1843 與子需求卡 CM-1844～1849 維持 Not started，全案收口時收。

---

## §5 表 B：commits

三 repo 已於 2026-09-17 push 到 `origin/feature/review`（BE 至 `3b0a35dd`，之後 `8f92b6c1` 與本檔 commit 未 push；套件至 `a0a5d6e`；FE 至 `3fa7fce`）。逐卡 hash 見 §4；要精確核對開對應 Notion 卡。

---

## §6 待決策者

- **發版時機**：三支套件 1.2.1／1.1.1／1.1.1 與主專案 pin 還原，併下次多 FR 一起發；T-6.4／CM-1886 隨之解凍。發版前 `pyproject.toml:75`／`:81-82` pin 註解、`:126`／`:132-133` path 開著且未 commit，別人 clone BE 會裝到沒新功能的 1.2.0／1.1.0。
- **T-6.4 查到兩個出貨結構缺口，發版前要一起解**：① `docker/production/docker-compose.yml` BE service 沒掛 `/var/run/docker.sock`，落地版 BE 在容器內起不了分類容器（image 帶了也沒用）；② 分類容器 Dockerfile 在 monorepo `jedi-evidence-classification/docker/`，188 build 機沒有 monorepo clone（兩案：188 clone monorepo，或 `docker/` 納 wheel；首腦傾向前者）。
- **188 build 機 `/opt/guidant-ai-be` 在 branch `jedi-iso-llm`**（HEAD `084daecb`），出 FR-107 包前要決定切不切 `feature/review`。
- **模型清單改設定驅動**（存 `AI_PROVIDER_CONFIG` 旁、AI 服務設定頁維護，三份碼表退成出廠預設）：決策者裁「先不用」，記為後續候選。
- 三份模型碼表（證據分類 `domain/llm_models.py`、Dashboard 三個 client `MODEL_MAP`、小幫手常數）合一：CM-1887 列 follow-up，未裁。
- Google `gemini-3.5-flash` 型號 id 未經真鑰驗證（DEV 那把無效）。
- 「證據蒐集 N%」進度條算的是任務完成率非證據數，要不要改標籤或加一格，未裁。
- 原廠代理（D13 排除項）要不要立獨立 FR，未裁。
- Google Drive 當儲存後端：決策者 2026-09-17 問過，首腦粗估 adapter 兩三棒＋授權模型設計一棒，建議維持「同步來源」角色不當主儲存；未立案。

---

## §7 follow-up（不進本案 scope，記錄在案）

- `doc-site-build` skill 寫「`docs/spec-site/site/` 不入版控」與現況不符（`.gitignore:175` CM-1184 起入版控、已追蹤 4172 檔），改一行。
- jedi-ai-bot `tests/test_plugin_contract.py` 收集報錯（`from tests.…` 但沒 `tests/__init__.py`），既有問題非本案引入。
- 套件 `jedi-evidence-classification/docker/` 測試要在容器 venv 跑（主專案 venv 缺 `pptx`）。
- design.md 狀態機表與實作偏離七點（`archived→archived` 放行、歸檔取審閱後 state 排除 `is_na`／`is_deleted`、已歸檔批次鈕降級「重新歸檔」、列表清理鈕不判剩餘檔數、`purge` 回 `{purged_files}`、LlmClient 實作在 `docker/llm_clients.py`、profile 守門租戶管理員）已寫進 SPEC 與 FINAL-SPEC，design.md 本體收口時改。
- stamp gate (c) 目前紅：path dependency 下 site-packages 無實體 `migrations/`，pin 還原後自消。
- 套件 `.venv` 過舊要用主專案 `.venv` 跑測試；FE `zh-cn` 缺 `EC_*` 碼；FE `npm run lint` 指向不存在路徑；`upload_files` 37 筆舊檔 owner 空白已裁不補；DEV Drive 授權失效（`GRC_DRIVE_TOKEN_REVOKED`）；T-1.1 誤刪一筆 PDF 預覽快取（id=3784，可重生）；`EC_403001` 文案借用記 T-3.2。

---

## §8 下一棒要做

1. **決策者宣布發版** → 派 T-6.4（CM-1871，卡末首腦補充已備：發版六步、pin 還原＋symlink 驗、docker.sock、image 來源兩案、188 branch）→ 回 Harbor tag → 派 CM-1886。
2. 全部 Done 後：`arc-review`、design.md 偏離七點回寫、母卡與六張子需求卡收 Done、SUMMARY（材料在 LOG Block 1～5）。
3. 驗收紀律不變：不信 runner 自報——數字重跑、端點實打、突變自己做；派 subagent 帶 `model`＋effort；給過 prompt ≠ 已派。
4. 派工卡上明寫「鑰在 DB、取鑰走 `resolve_api_key`」（Block 5 教訓 2）。

**接手側紀律**：讀完 §0～§8 即停，等決策者下令。
