---
title: FR-069 STATE — 現況盤點（living）
---

# FR-069 STATE（living，只描述此刻）

> 最後更新：2026-09-03（**第五任首腦交棒**——收整全收、v1.19.0 正式進版、剩出包部署與三件小事）。本檔就地 Edit，不留歷史；歷程看 `fr069-LOG.md`（最後一個 block 是第五任，教訓 23–32）；全案總帳看 `2026-09-01-FR069-SUMMARY.md`；本版 release note `docs/release_notes/v1.19.0.md`。

## 🔴 接手第一段：FR-069 已結案，此刻只剩四件

**全案狀態**：母卡 CM-1435 Done、收整十二棒＋五碎片卡全 Done、五 repo 全在 main 乾淨零未推、**v1.19.0 已在 main 進版**（BE `35e14ee6`／FE `31b658e`），spec 快照 `docs/spec-site/v1.19.0/`＋`current/legacy/v1.19.0/`。

| # | 事項 | 誰做 | 現況 |
|---|---|---|---|
| 1 | **推三個 tag** | **user 本人** | main 已推但 tag 沒跟著走（`git push` 預設不帶 tag）：BE `v1.19.0`、FE `v1.19.0`、evidence-agent `v1.0.0` 三個都在本地未上 remote。指令：各 repo `git push origin <tag>` |
| 2 | **CM-1543 出包＋STG→POC** | runner（Sonnet 5 級即可） | 卡已備、prompt 在本 STATE「派工 prompt」節；**前提是 #1 先推**（runner 開工驗 remote tag）。beta 六雷已入版，正式版 build 應一路綠；⓪ DB 斷言若紅停下回報 |
| 3 | FR-070／FR-071 排程 | user | Phase 0 草稿已落（AI/Drive 憑證 DB 化＋「密碼怎麼藏」合併談／診斷包），user 裁「先不做」 |
| 4 | 記帳項（不擋事） | — | bundle 公鑰死路徑（指 jedi-license-runtime，正式簽章前必修）／FE image tag 預發格式統一／jedi-survey 舊 48 紅／flow-engine 測試檔 27 遮蔽函式／Nexus 四支舊殼 user 裁不動 |

**接手必讀順序**：本檔本節 → `docs/release_notes/v1.19.0.md`（含 §7 部署順序）→ `fr069-LOG.md` 最後 block（第五任教訓）→ 需要全案脈絡再翻 SUMMARY。
**驗收基準**：`python -m pytest test/ -q`＝2155 passed（`pytest` 裸跑亦可，CM-1504 已根治）；守衛 80 綠；主專案 `poetry install` 即跑（零 editable）。

### 派工 prompt：CM-1543（貼新 session）
```
你是 runner，負責 Notion 卡 CM-1543（v1.19.0 正式版出包＋STG 升級＋POC 升級）。
卡片 URL：https://app.notion.com/p/v1-19-0-STG-POC-188-build-STG-install-sh-upgrade-POC-3d1346da4cd08105b9b1f73bfa72ca5d
先 `python scripts/notion_case.py get CM-1543` 讀卡——前提／三段工作／每段驗證項／邊界都在卡上；再讀 docs/release_notes/v1.19.0.md §7 與 scripts/build/README.md。
🔴 環境鐵律：190 不動；189 POC 只在 user 明示放行後才碰；⓪ DB 斷言紅了停下回報不自行套 migration。
runner 鐵律：①段做完回寫（包位置＋sha256＋開包驗證輸出）②段做完回寫並**停下等放行**；③段放行後做完回寫；狀態改「修正待驗證」。卡住：回寫卡在哪，沉默是最糟的狀態。
```

### 190 現況（2026-09-03）
主產品 1.19.0b1 stack（`--upgrade --force` 過，credentials 已移除版）＋Agent 1.0.0（FR-073 形態，`/srv/guidant-ai-agent`）＋POC 真資料庫 `guidant_ai_poc_test`。錄影機，FR-072/074 影片已錄完；`reset-190.sh` 可重置到檢查點。**不擋任何事，去留 user 裁。**

---

## 📜 以下為歷史狀態（收整期間的工作記錄，不再更新）

## 🔴 收整階段（FR-069.5，2026-09-01 user 拍板，進行中）

**「主專案內部重整＋技術債」不另開 FR，算在本 FR 收尾**（user 裁：這是本 FR 的大異動，收尾該做最後整理，債留給下個 FR 絕對忘光）。**兩 repo 皆已切 `feature/FR-069.5` branch 作業**（BE＋jedi monorepo，2026-09-01；原 `feature/FR-069` 為已審凍結狀態）；merge 回 main 順延到收整全收之後、母卡 CM-1435 屆時才收 Done。

**拆棒與卡（CM-1504～1510 連號新開＋沿用兩張既有）**：

| 棒 | 卡 | 內容 | 順序約束 | 狀態 |
|---|---|---|---|---|
| A | CM-1504 | 小債清掃（＋追加⑤退役 tests/ 套件、根治裸跑 pytest 假紅） | — | ✅ 驗收過（`da8c413e`＋`ecd315a3`），等 user 手測；**CM-1461 62 支全數處置完畢隨本棒收** |
| B | CM-1505 | 存量紅測試歸零——**94 紅 23 error → 0/0，全量 2149 綠**（產品碼零異動；最大宗根因是 DBLogHandler 併跑汙染非 import 漂移；CM-1510 的②順帶解掉） | — | ✅ 驗收過（`c7c1b222`＋`e3ef462a`，首腦親跑全量 2149 綠），等 user 複測 |
| C | CM-1506 | ~251 支 shim 清退（canonical 批次法） | B 已收 → **就緒可派** | 待派 |
| D | CM-1507 | readmodel 分子資料夾（照 README 既定規格搬檔） | 隨時可派 | ✅ 首腦驗收過（`d662e989`），等 user 手測收 Done |
| E | CM-1495（既有） | 孤兒清理 job（daily 03:10 UTC，delete 模式＋report 逃生門；DEV 實查現存孤兒 0） | — | ✅ 驗收過（BE `32c04478`＋mono `8bd80c6`），等 user 手測 |
| F | CM-1484（既有） | participant 六支 port 化完成（A/B 全量 13,247 列比對零差異；**主專案 10 支實查為宿主正當查詢不必改**；真同病 7 支在 compliance-audit/survey/task-platform 三套件，待開卡） | — | ✅ 驗收過（BE `20675f35`＋mono `af20824`），等 user 手測；**拉本 branch 需 `pip install -e` jedi-participant** |
| G | CM-1508 | 四類重佈局壓軸（佈局設計先給 user 過目才動手） | 只剩 C＋D 手測 → 近就緒 | 待派 |
| H | CM-1509 | 收口：總驗證＋mini arc-review＋收官章（母卡 Done 等 user 令） | 最後 | 待派 |
| — | CM-1510 | 追蹤卡：agent 身分漂移告警＋test_audit 併跑汙染（記帳不排程） | — | 記帳 |

**範圍裁定（2026-09-01 user）**：問卷審核開關端到端＝之後另開，不在本次；agent 漂移告警＋測試併跑汙染＝CM-1510 記帳；四類重佈局＝**全套**（前提：G 最後做／對外契約凍結 D5 複驗／canonical 批次法）。**Nexus 四支舊殼下架＝先不要**（維持現狀）；CM-1481/1489 端到端疑慮已消（user 確認 detection 測過）；jedi-issue GL/GH＝已裁留（產品承諾），結案。

## 前任交接殘留（第五任盤點後現況）

開發、review、修復、文件、發版全部完成。原「只剩四件」現況：

| # | 事項 | 現況 |
|---|---|---|
| 1 | FE `e5595f1` 未推 | ✅ **已消**——實查 origin HEAD 就是它（user 已自行推） |
| 2 | 最終收官章 | **併入收整 H 棒（CM-1509）**，收整全收後做，母卡屆時收 Done |
| 3 | merge 回 main | **順延**到收整全收之後（user 本人做；現作業 branch 為 `feature/FR-069.5`） |
| 4 | 190 dev server 去留 | 未裁，不擋事；H 棒的 dev server 直跑驗證會用到它 |

**接手必讀順序**：本檔（尤其上表與「190 現況」）→ `2026-09-01-FR069-SUMMARY.md`（全案總帳 275 行，含 26 支套件終態表與教訓精選）→ `docs/review/2026-09-01-fr069-review.md`（review findings 與 §⓪ Resolution 逐條處置）→ 需要脈絡再翻 `fr069-LOG.md`（歷程，按時序，最後一個 block 是第四任）。
**驗收基準**：主專案守衛 `python -m pytest test/test_module_boundaries.py test/test_error_code_uniqueness.py` = **80 綠**（必 `python -m`，直呼 pytest 假紅）；本機 8000/8002 跑 Nexus 正式版（無 path override，`poetry install` 即可）。

## 📍 本任（第四任）已完成事項

- **arc-review 全案**（5 agent 平行）：報告 `docs/review/2026-09-01-fr069-review.md`——1 Critical＋10 Important＋3 批 Minor；**零套件反向 import、D5 凍結面機器 diff 零漂移**；主題是「綠著的守衛不代表在守」（四條守衛掃舊名/掃描根縮水/假 docstring）。
- **CM-1501 修復棒**：13 條全處置（11 修/1 誤報/1 歸文件棒）；C-1 撞號（GRC_400105 一碼兩用）修成 `GRC_400121` 三 repo 同步；突變 15 發。**I-8 半條煞車**——問卷審核開關的平台側消費端根本未建，接線接了也沒人用，建議另開卡「問卷審核開關端到端接通」。
- **CM-1502 文件收官（第一段）**：CLAUDE.md＋docs/claude 死名同步／架構手冊終版（族譜 26 支終態＋四類清單＋readmodel 四規格落 `infra/readmodel/README.md`＋D6 六條）／**SUMMARY 275 行**／Postman 重產（637→609，減 28 支逐條核為刻意退役）／兩站重 build。
- **CM-1503 補發版**：四支 patch 上 Nexus——task-platform `0.1.1`／survey `0.1.2`／detection `0.0.2`／compliance-audit `0.0.2`；**可拉性三層驗證**（index／實抓 whl／解包 grep 確認 GRC_400121 真在產物內）；主專案 pin 跟上、守衛 80 綠、I-3 例外表已清空。
- **190 dev server 建置**（見下節）。

## 🖥 190 dev server 現況（`https://192.168.50.190/`）

**形態＝nginx 服務 build 產物（非 vite dev server）＋BE 直跑源碼（不編譯）**：
- **FE**：`/opt/guidant-ai-fe`（feature/FR-069）→ `npm run build:ONPREM` → 產物 rsync 到 `/var/www/html/audit-manager/`（既有站台已備份 `audit-manager.bak.20260901-205511`）。腳本在 190 的 `/tmp/build_fe.sh`＋`/tmp/deploy_fe.sh`（⚠️ **建議搬到 `/home/jedi/` 免得被清**）。
- **BE**：`/opt/guidant-ai-be`（feature/FR-069）＋`.venv`（symlink 到 `/home/jedi/dev-be/.venv`）；起法用 `/tmp/start_be.sh`（8000 api＋8002 socketio，用 setsid 脫離 ssh session——直接下 nohup 會連自己一起殺掉，踩過兩次）。
- **形態設定＝on-prem**：`DEPLOYMENT_MODE=host`＋`TURNSTILE_ENABLED=false`（BE/FE 一對，只關一邊會壞）；FE bundle 實查 turnstile 已編譯成常數 false。
- **nginx**：`/etc/nginx/sites-available/default`（已備份）——443 self-signed、root 指 audit-manager、`/api`→8000、**`/socket.io`→8002（本任修正，原設定錯指 8000，共編必不通）**。
- **DB**：e2e 容器組 `cm-e2e-postgres`（25432）/redis（26379）/minio（29000）/mailpit；run DB＝`guidant_ai_e2e`，**已補套 26 支 migration 全過**（8/4 水位→FR-069 最新，順帶完成「帶舊資料升級」實地驗證）。⚠️ **golden 庫未升級**——`clone-run-db.sh` 重來會回舊 schema，要重跑那 26 支（清單與腳本在 190 `/tmp/e2e-apply-list.txt`＋`/tmp/apply_migrations.sh`）。
- **AI 金鑰**已補（三家）；**MFA 關閉**。
- ⚠️ **git pull 拉不動**：token 已依 user 指示拔除、remote 還原 SSH 形式，但 190 沒配 GitLab SSH key。下次更新前要配 key 或臨時給 token。
- ⚠️ **踩過的坑（重做 190 或建新機時會再撞）**：①**FE 的 GitLab 專案名是 `audit-manager-system` 不是 compliance-manager-fe**（用後者 clone 會 404）；②190 原本沒有 Nexus 認證，憑證在 **188 的 `~/.config/pypoetry/auth.toml`**（poetry config http-basic.nexus）；③**Redis 埠在程式裡寫死 6379**（`config.py` REDIS_URL），主機映射 26379 連不上——解法是 `REDIS_HOST` 填**容器內網 IP**；④ssh 內下 `pkill python main.py` 會連自己的 session 一起殺（連線中斷兩次），用 `/tmp/start_be.sh` 的 setsid 形式；⑤e2e compose 的 BE 環境樣板**不含 AI 金鑰**（e2e 不打真 AI），要另外補三家 key。

## 一句話現況

FR-069 模組化抽取：**第一/二/2.5/第三階段＋發版（CM-1473）＋第四階段全收 ✅，user 手測全過、全卡 Done（2026-09-01）**。第四階段最終帳：核心抽取（participant／evidence-classification／detection／ai-dashboard 新抽＋flow_control 分家四步＋問卷合併）＋兩包定名（jedi-task-platform／jedi-compliance-audit）＋申報制＋D-10 償債＋掃卡補洞四棒（1493 償債：發版依賴環已解／1494 查證：殭屍定讞／1496 SMTP 修復／1483 儀表板）。**六項裁定全下（2026-09-01）**：三包名定案／task-platform 0.1.0／退役低風險＋套件內死碼放行併發版前置／S4 併收官 e2e／associations 殭屍開 CM-1498。發版棒 CM-1499 ✅＋CM-1500 問卷共編修復（jedi-survey 0.1.1）✅ 皆收 Done。**CM-1497 套件債清理＋CM-1498 associations 殭屍退役皆收 Done（2026-09-01 晚，user 手測 workflow-setup 存檔過）**——1497 帳：三筆測試債歸零（notification 226 綠/log 75 綠/flow-engine 116 綠）＋D6 契約七支統一補＋issue 死碼 367 行裁決材料（**A/B 留刪等 user 裁**）；1498 帳：活鏈端點退役＋兩套殭屍清光（BE `294fbec1`＋FE `8801f94`；`31f01cf2` 是出包空殼以 294 為準）。**收官串（user 2026-09-01 裁）**：e2e 暫不做改「dev server 直跑功能驗證」（190 已備妥待部署形狀裁定，最後做）→ arc-review → 文件收官。**已裁**：jedi-issue GL/GH 整合碼**留**（對外已宣稱有此整合，屬產品承諾）。**arc-review＋CM-1501 修復＋CM-1502 文件收官＋CM-1503 補發版四棒 2026-09-01 晚全收 Done**（詳見本檔頂端「本任已完成事項」）。守衛現 **80 綠**（`python -m pytest`）；主專案本輪淨刪 38,000+ 行；套件終態 26 支（現役 25＋退役 10 已刪）。

### 未結 follow-up（皆不擋 merge）
| 項目 | 卡 | 備註 |
|---|---|---|
| participant 六支 ORM 直連身分表改 port | CM-1484 | 同族：六支 serializer 曝光永遠空的 `*_name` |
| 任務綁定表孤兒定期清理 job | CM-1495 | D-10 償債配套 |
| 62 支死端點剩 9 支（bulletin/device/system-config） | CM-1461 | route 未上移故未處置 |
| **問卷審核開關端到端接通** | 未開卡 | CM-1501 I-8 查出：平台側消費端未建，屬功能建造非修復 |
| **S4 恆偽分支退役**（~26-66 行，live 路徑） | 未開卡 | 原併 e2e 站，e2e 取消後無落點；建議下次動 flow-engine 順手 |
| `test_audit_event_instrumentation` 併跑汙染 | 未開卡 | 1498 查明既有債 |
| agent 身分漂移無告警 | 未開卡 | 本任踩到（DB uid vs agent 持有 uid 不一致靜默到派工才炸）；同族 followup_agent_cert_expiry_no_renewal |
| `common/authz/__init__.py:54-55` 註解自相矛盾 | 未開卡 | 1502 順手發現，邊界外未動 |
| **主專案內部重整**（下個 FR 的材料） | 未開卡 | readmodel 分子資料夾（規格已寫未搬）／四類重新佈局／94 支存量紅測試（多為 import 舊路徑）／251 支 shim 多數已無 consumer。**建議另開 FR 不塞進本案**，且需 e2e/dev server 安全網（190 已備） |
| site-regression 接 190 跑最新版 | 未開卡 | 需改 BASE_URL＋重產 auth-state（origin-scoped）＋盤資料前提 |

> ⚠️ 本檔 2026-08-30 晚間曾被改回舊版（平行棒疑似還原），首腦已把累積現況補回——若與各卡回寫衝突，以 Notion 卡為準。

## 現況清單

- **九支套件全部正式版**：五支新套件 jedi-ai-bot / jedi-integrity / jedi-log-forwarding / jedi-remote-agent / jedi-license-runtime 皆 `==0.0.1`；jedi-common `0.0.33`（.11 JSONB 查詢＋身分脈絡包＋SessionMixin 正名）、jedi-auth `0.1.35`（P8 authz 主體域）、jedi-project `0.0.9`（.12 projects 四欄）。主專案 pin 至 commit `0f8c1b93`，零本地路徑依賴（1455 開發期 path override 除外，見下）。
- **jedi-department／jedi-resource-store 已標 deprecated**（monorepo `d765191`：README 警示＋pyproject `[DEPRECATED]`；目錄保留觀察期）。🔴 **重要交接事項**：主專案 pyproject/poetry.lock 的改動**持續留在 working tree 未 commit**，現已累積三批：①`.10` resource-store 拔 pin；②`.13`～`.15` 的 jedi-iam/auth/login/mfa/captcha dev path override（照規矩不入版控）；③**3.1（CM-1467）拔掉四支舊套件 pin 與四支 path override，只留 jedi-iam 一行**。三批同檔拆不開，**全部託付發版棒還原 pin 時一併入版**（.18 曾託付但發版擱置故未執行）。退役事實已由 docs commit `29e124bd` 與母卡記錄。
- **Postman 全站 API collection 已交付**（commit `38e8734a`）：637 支請求／21 資料夾，產生器 `scripts/gen_postman_collection.py` 是唯一真相（重跑 diff 空＝與路由表零落差）；掃出 **62 支裸路徑死端點**（雙路徑註冊缺 handler、FE 零裸打、線上零影響）→ 裁決開追蹤卡 **CM-1461**，隨 2.5/第三階段各棒動到該模組 route 時順手拔（拔前確認 e2e/agent 無呼叫）。
- **project_extensions 收斂（.12）**：四欄已收回主表、雙寫中、**舊表未 drop**（安全網，drop＋P-like 驗證等 user 令，往後排）。migration 只套 DEV（STG 實查未動）。
- 🔴 **jedi-iam 已是「完全體」插件**（3.1／CM-1467）：**route 也在套件內**——`register(mount_api=True)` 掛出 39 條身分 API，主專案 `api/auth/` 已刪除、`REGISTERED_APPS` 的 `"auth"` 已拔。身分 API 的存在與否由 `core/app_factory.py` 的 `register_identity(..., mount_api=True)` **一行**決定（拔掉測試實證：註解那行 → 16 支端點全 404、其餘模組無感）。
- 🔴 **主專案已零引用四支舊套件名**：`jedi_auth`／`jedi_login`／`jedi_mfa`／`jedi_captcha` 的 import 全改 `jedi_iam.*`（80 檔），pyproject 四支 pin 與四支 dev path override 已拔（**留 working tree 未 commit**，見下）。守衛測試 `test_no_import_of_retired_identity_package_names_in_main_project` 焊死舊名不得復活。轉發殼在 monorepo 仍在（過渡），3.6（CM-1472）退役執行。
- 後端：開發機 8000（api）與 8002（socketio）**皆已重啟且乾淨**（CM-1500 收口時實測，無 traceback）。DB 必須指 `guidant_ai_dev`（唯一套過最新 migration 的庫）。
- ✅ **path override 已全數清空、八支套件皆吃 Nexus 正式版**（CM-1499 發版棒還原 pin；CM-1500 再把 jedi-survey 推到 `0.1.1`）。實查確認：pyproject 無任何 active path 行、venv 內無 editable jedi 套件（無 `direct_url.json`）。**拉 `feature/FR-069` 分支不再需要 `pip install -e`**，`poetry install` 即可起 BE（先前的六支 editable 需求已失效）。

## 2.5 階段棒次與依賴（卡已全開）

| 棒 | 卡 | 狀態 |
|---|---|---|
| .13 地基棒（骨架＋遷入策略定案） | CM-1455 | ✅ **Done**（user 判定好的，2026-08-30 收） |
| .14 login 併入（21 處穿透重整＋登入編排收套件） | CM-1456 | ✅ **Done**（2026-08-30 驗收：66 檔遷入機械比對零行為差、殼 14＋identity 324 綠、守衛 49、行為親測 401/404/200/偽 token 401；已知 2 紅為既有 mock 問題非本棒；monorepo `6d4309b`＋主專案 `cb18b60c`，兩 repo 已 push。**遺留給 .18**：password_adapter infra→infra 是否改 domain service 由收口棒判斷；login_token_domain_service 2 紅待修） |
| .15 mfa＋captcha 併入（MFAFactory＋turnstile 降級＋死碼清） | CM-1457 | ✅ **Done**(2026-08-30 驗收:identity 324＋mfa 殼 11＋captcha 82＋守衛 49 親跑綠;首腦重啟 8000 主服務後親打 MFA 全鏈——resend 200/節流 429 `MFA_429001`/錯碼 401 `MFA_401001`/redis 真碼 200 發 token;mfa→notification 依賴邊已斷(僅剩 docstring 沿革註記);monorepo `52508b2`＋主專案 `b73acd9b`。**遺留給 .18**:發版時 jedi-mfa 必發 0.0.15 純殼(舊 0.0.14 自帶 totp_secrets 表宣告,與新家並存即炸)＋jedi-captcha 0.0.15;圖形驗證碼退役刪除) |
| .17 順手清理（root 判定收斂／依賴大掃除） | CM-1459 | ✅ **Done**（2026-08-30 驗收：收斂 40 鎖定測試綠＋守衛 49＋身分行為 401/403/200 親測；is_admin 實查非殭屍→裁 (A) 移出另開 **CM-1463**；monorepo `4fdbbe8`＋主專案 `45c6e832`） |
| .16 中介層上移（jwt_mw/socketio 驗簽/user_context_builder/安全政策 schema） | CM-1458 | ✅ **Done**（2026-08-30 驗收:守衛 57＋套件 347 親跑綠;X-Tenant-ID 新守門親打——tenant 0 提權向量/非隸屬皆 403 `GRC_403063`、自己租戶 200;RLS 抽查 roles 8 列與基準一致;FE i18n 兩語系已補。**本棒抓到並修掉真提權洞**:X-Tenant-ID:0 原可觸發 is_super_admin 繞過全 RLS;另 socket 整數 0 falsy 靜默丟棄的繞過也修了。三 repo commit:monorepo `e7e0258`＋BE `e86973c7`＋FE `e602f49`。**順帶發現另案**:main.py:173 integrity_scheduler 少傳 app、socketio 模式開機即 TypeError（既有問題,見卡片）） |
| **.H 補搬棒（D9 缺角三塊）** | **CM-1466** | ✅ **Done**（2026-08-30 驗收：守衛 60＋套件 350 親跑綠；範本下載 200 親打、測試資料清零實查；行為表全過——匯入中途失敗整批回滾零封信/成功兩封信 commit 後寄/root admin 停用 403。**裁決**：「消滅 raw SQL」照意圖不照字面——ORM 化但繞 RLS 保留（elevated_session.py 鎖唯讀+rollback），root admin 保護是承重牆不可拆。monorepo `af79a56`＋BE `8ae7c779`。順手收斂範本欄名雙份→套件單一持有） |
| .18 收口棒 | CM-1460 | ✅ **Done**（2026-08-30 23:00 驗收：拔掉測試 11 支 404/降級邊界正確；harness 空庫 16 表獨立活/353 綠；三路實測 12 列（LDAP 走 harness 模擬——DEV 無 LDAP 實況查證過）；login_token 2 紅修掉（測試陳舊非搬壞，突變驗證過）；圖形驗證碼全鏈刪除（重啟後 captcha 404 親驗）；pyproject 改 patch 備妥（`cm1460-post-release-pyproject.patch`，發版後套）。**裁決**：CM-1461 身分四模組煞車正確（裸路徑 POST 活著，正解回寫該卡）；password_adapter 不改歸第三階段；GoogleAuthAdapter stub bug 記第三階段隨手修。BE `a500a521`＋monorepo `fe77e59`。**🔴 發版清單備妥等 user 令**：jedi-iam 0.1.0 → auth 0.1.36/login 0.0.24/mfa 0.0.15（必發）/captcha 0.0.15，指令在卡片） |

## 第三階段 3.1 首棒（CM-1467）——已收，範本已立

**狀態**：✅ Done（2026-08-31，Notion 已回寫「修正待驗證」等 user 驗）。
commit：monorepo `e614c34`＋`d6b0dfa`／主專案 `e483ba17`＋`d1a141c2`，兩 repo 已 push `feature/FR-069`。

**六件工作全數勾銷**：①route 上移（39 條進套件，`api/auth/` 刪除，URL 機械比對集合相等）；
②內部結構重整（頂層兩套 common 合一、mfa/common 併回頂層、`entity`→`entities`）；
③四殼退役（80 檔改名＋拔 pin＋死名守衛）；④D16 port 化（10 處自建 RepoImpl 收進
`AuthRepositories`）；⑤GoogleAuthAdapter stub TypeError 修掉（已復現舊行為確認）；
⑥README 架構節＋README.html。**隨棒**：CM-1461 身分 13 支死路徑照 .18 正解拆
Create Route 類（500→405，POST 仍活），已回該卡勾銷；依賴衛生順掃。

**追加改名**（user 2026-08-31 指示「以前叫 identity 的換成 iam」）：blueprint 名
`identity`→`iam`（`.13` 建骨架時的殘留，`.G` 漏改；**對外 URL 零影響**，三 repo 對
`identity.*` endpoint 引用皆為 0）；`common/identity.py`→`common/iam_ports.py`、
`core/identity_wiring.py`→`core/iam_wiring.py`、對應測試檔。**刻意不改**：
`JWT_IDENTITY_CLAIM`／`user_identity` 欄位／`get_jwt_identity()`／`resolve_identity()`
／`Accept-Encoding: identity`／`Identity*` 四個公開型別——那些是領域概念或對外契約，
不是舊套件名。

### 📌 照抄要點（3.2–3.6 十一支的範本，**派工 prompt 請帶這段**）

1. **route 取 service 用 `ctx().service("name")`，不要 `@inject`**——`Provide[Containers.x.y]`
   要在 import 期寫死具體 container 路徑＝套件反依賴主專案。改由 `register()` 把
   **provider 名冊**放進 `app.extensions`，route 在 request 期取。
   🔴 **存 provider 不存實例**——主專案 service 多為每 request 建新的（內含 session-bound
   repo），存實例會讓第一個 request 建的物件用到天荒地老，平常看不出、併發才爆。
2. **認證與能力點一律 port 化，且刻意不給預設值**；缺接線要**拒絕掛載**不是跳過——
   跳過的後果是端點全變公開，而服務照常起得來、健康檢查照樣綠燈。
3. **什麼留套件、什麼回宿主：問「換一個產品，這段還會一樣嗎」**。一樣→留（流程順序、
   資料模型組樹、欄位正規化）；不一樣→走 hook 回宿主（商務授權旗標、選單過濾、政策值
   從哪讀、審計欄位 nickname、原廠帳號保護）。
4. **register 掛 route 的形狀**：`create_blueprint()` 內 `_assert_api_wiring(adapters)`
   → 建 context → `record_once` 寫 `app.extensions` → `mount_routes(bp)`。
   **URL 對照表就是 `api/__init__.py::mount_routes()`**，它是唯一真相。
5. **對外契約凍結，用機械比對證明**：URL／error code 字串／能力點名一字不動，用
   **集合比對**（不是比數量——數量對但拼錯一條的症狀是該 API 憑空消失 404，route 表看不出）。
6. **死路徑順手拔（CM-1461 型）**：先實打確認裸路徑 POST 是否活著。活的就**拆獨立
   Create Route 類**（不是整條拔），死 verb 自然 405，呼叫端零改動。
7. **harness 要真的能打**：補殼後不能只證明「register() 掛得上」，要實打一支端點走通。
   3.1 踩出**四道宿主前提**，有 route＋有 DB 表的套件大概率同樣要踩：
   `init_db(DB_URL)`／`PROPAGATE_EXCEPTIONS=True`（否則 flask-restful 吃掉所有例外，
   error handler 註冊成功卻不生效）／`JWT_IDENTITY_CLAIM`／`column_property` 用的 DB 函式。
8. **blueprint 名別再叫舊套件名**——改名時記得掃「寫死 endpoint 前綴」的地方（3.1 有
   兩處），那種寫死壞掉的方式是**靜默匹配到 0 條**而不是報錯。

### 待 user 裁的一件

**`authz/` 是否改名**（②的未竟項）：實查後**建議維持不改**，理由（docs 內 2824 處提及、
改名解不掉真正的門檻是六個軸的分界、`common/authz/` 是 FR-048 收斂後的唯一 import 面
改名期間必然出現新舊並存空窗）與候選比較（`access/` 與 IAM 的 Access 撞名反而更糟）
已完整回寫 CM-1467。本棒已做零風險償還：在 `authz/__init__.py` 與 README 補上
「authz = authorization，與 authn 相對」。若仍要改，建議 `authorization/`、整批原子改、
**另開卡單獨做**（混進大搬遷會讓機械比對失去意義）。

## 已定調待執行

- **✅ 套件改名 jedi-identity → jedi-iam 已執行完畢（CM-1464，2026-08-30）**：全名 Identity and Access Management（PM 定調，推翻 D9 原命名段）。monorepo 目錄／package／pyproject dist 名、三支轉發殼的轉發目標、主專案 96 處 import、pyproject path override、守衛測試、design.md §3 D9・§7 2.5 節・§8 狀態表、boundary-map／roadmap／phase2 全部改完（monorepo `e3d3aec`）。**`jedi_identity` 不留轉發殼**——未上 Nexus、無外部消費者，守衛測試已焊死舊名不得復活；被合併的四支舊名（auth／login／mfa／captcha）維持轉發殼到第三階段。**.18 的發版清單以 `jedi-iam` 為準**；新開的棒一律直接寫 `jedi_iam`。

## 已立案待啟動／等 user

| 案 | 卡 | 狀態 |
|---|---|---|
| drop project_extensions 舊表＋P-like 乾淨庫雙路徑驗證 | 未開卡 | user 拍板往後排，drop 前必先 P-like 驗證 |
| **第三階段（3.1 已收，其餘待發）** | **CM-1467（3.1 jedi-iam 完全體）✅ Done** → **CM-1469（notification）✅ Done**（2026-08-31 驗收:178 綠親跑/mail-test 401 親打/「拔掉≠寄信消失」雙用法誠實揭露/README 原是 issue 照抄件已重寫/挖出 factory 反向 import 4 紅既有債另議;monorepo `11d0767`＋BE `db0899f7`，未 push 等令）；**CM-1468（file-upload）✅ Done**（2026-08-31 兩輪：API 面全過＋補修 97 綠親跑；16 ERROR 經 runner 三證歸因為**既有存量債非本棒連帶**（首腦初判有誤，接受更正）——fixture 未跟 d5e9dc2 的參數＋4 支測不存在方法，已修 fixture＋過時測試搬 adapter 層補真覆蓋含突變；monorepo `9c294ef`+`af3e2e4`＋BE `6ec924e9`）；**CM-1470（flow-engine）✅ Done**（2026-08-31 兩輪：煞車正確（route 的 service 在主專案）→裁 (a)+(c) 降級輕量收——register 插槽/harness(逼出 models __init__ 只 export 1/9 的真缺陷已修)/README 含誠實聲明表（無 api 層/無拔掉測試+原因）/D16 實查本就乾淨/依賴衛生四類修；job-evidence 死路徑拆 Create Route（GET/PUT/DELETE 500→405 親打）；守衛 56+基準 API 3 條 200 親打；既有債 workflow_execution 測試 8F9E 本棒零觸及不算帳。monorepo `738f13d`＋BE `a1332c8d`，未 push 等令）→ **CM-1471（輕量批七支）✅ Done**（2026-08-31 首腦驗收：守衛 64 親跑綠（⚠️ 須 `python -m pytest`，直呼 `pytest` 會 ModuleNotFoundError 'common' 假紅）；API 抽打 10 條全符合（三支上移 route 401 活著/死 verb 405/裸路徑 POST 依 FE 實查保留）；bulletin 4F11E＋system-menu 32F 三證歸因存量債（失敗檔不在本棒 diff/錯誤型態=Mock 測不存在方法同 3.2 型/新契約測試 72 綠）——卡片「拔掉測試七支」被實查推翻只三支做得到（route 的 service 在哪），後四支誠實聲明不搬理由成立；四真缺陷已修（models __init__ 空×5/notification common floor 0.0.30→33/守衛字串比對盲點/infra/log 被 .gitignore 吃）；monorepo f996740+104df8c+f59be9c+a1a0225＋BE 2a6888e4+5bbc5506，兩 repo 已 push）→ **CM-1472（退役執行）✅ Done**（2026-08-31 首腦驗收：四目錄刪除實查（oscal v1/resource-store/department/jedi_system_log 半邊）＋v2 與 api_log 未誤傷（import smoke 親跑）；守衛 64 親跑綠（換軌——刪除套件移出 EXTRACTED_PACKAGES 防永久 skip 假綠，新增 deleted-retired 守衛 top-level 全等比對防誤殺 v2，突變雙向驗過）；API 抽打 log/api-logs 與 system/menus 皆 401 活；CM-1451 勾銷（實查推翻卡片斷言——jedi-issue 根本沒宣告 jedi-common 靠傳遞相依撐著，真補 >=0.0.30 非確認）；CM-1143 resource-store 項勾銷；venv 陳舊 jedi_oscal 0.0.23 順手清。monorepo `e98c17b`＋BE `a780871c`，兩 repo 已 push）。**第三階段六棒全收 ✅** | 3.2/3.3/3.4 prompt 待 user 發；隨棒必做（D16 port 化/CM-1461 正解/依賴衛生）已寫進各卡 |
| **第四階段（已拆卡 2026-08-31，CM-1475–1483 九張連號）** | 4.A=CM-1475（地基：D17/D18 通則入 design.md＋套件分類地圖 package-taxonomy.md＋8 支聚合 query 搬 infra/readmodel/）→4.B=CM-1476（AI registry 自註冊，可與 P12 平行）→4.1=CM-1477（P12 jedi-participant，核心抽取首棒；TaskAssigneeService 已裁：CRUD 隨套件/list_my_grc_jobs 留 readmodel）→4.2=CM-1478（flow_control 拆出＋流程疆界三方設計，先設計後動工）→4.3=CM-1479（P13 中間路線，user 已裁採納）→4.4=CM-1480（P9 detection，開工先過服務化評估）→4.5=CM-1481（P10 evidence-classification，可與 4.4 平行）→4.6=CM-1482（P11 問卷合併）→4.7=CM-1483（P6 儀表板框架，收尾棒） | **4.A=CM-1475 ✅**（③搬遷因前提被推翻裁併入 P12 步驟 0——readmodel 採「純讀聚合」為準）；**清債 CM-1474 ✅**（兩表 DROP＋P-like 雙路徑過＋抓到 .12 漏網 view 活依賴等價改寫）；**4.B=CM-1476 ✅**（registry 申報制、壞條目 2→4 修 3 刪 1、順修 Singleton 永久快取地雷）；**4.1=CM-1477 ✅**（jedi-participant 抽出：readmodel 三支同 view 查詢一起搬 40 組參數 md5 一致／URL 全站 425 條零差異／A/B 對打抓到 Containers 類別層取用真回歸／identity JOIN 待償項開 **CM-1484** 追蹤）。**平台化方向拍板**（2026-08-31）：project＝插座（詳 architecture-handbook/project-platform-decision.md）；flow_control 分家＝骨架半供複用＋稽核半自成插件。**4.2 設計稿已出**（CM-1478 修正待驗證，BE `ebe36214`——切線盤點骨架 12/稽核 22/灰區 12＋D-1～D-9 待決＋實查新發現：jedi-project dto 反向 import 宿主 3 支/4 支讀寫混合 query/兩支純讀 4.A 漏收/stage route 4 條同結實體；順手清 jedi-project 虛掛依賴 16→2 monorepo `a5d5d35`）。**兩支平行棒跑著**：白話改寫棒（設計稿黑話全面白話化，結論零變動，決策者抓的——黑話標準比照 project-platform-decision.md）＋**CM-1485 flow-engine 用量盤點**（camunda 死活/BPMN 實際用量/可退役三類清單；決策者印象「只剩 BPMN 解析在用」待驗）。**兩平行棒已收（2026-08-31 晚）**：白話改寫棒 ✅（`39bbf7d5`，黑話零殘留、數字/檔名/圖邊機械比對零漂移）；**CM-1485 盤點 ✅ Done**（`3d0c5aff`＋analysis 275 行）——兩條上游線索各推翻一半：camunda 程式側死透（AST 零 importer/log 零請求/設定鏈懸空）**但 189 有孤兒 camunda 容器**（4 個月、8888 埠、內容全是原廠範例與 Modeler 手動上傳，與產品零關聯，是否關掉待裁）；「只剩 BPMN 解析」**推翻**——執行面完全活著且是唯一引擎（COMPLETED 3,146 首腦 DB 親查、最新寫入 2026-08-24）。三類清單：確定死 11 條 ~3,357 行（含 camunda_service 2,852 行——設計稿原判「引擎」要改死碼）/疑似死 4/活 11；6 條停用 route 可正式刪；**三護欄**（wf_exec_control_mapping 表活著僅 API 層死/update_element_variable 死活共用/死活 enum 同檔）。退役後 app/flow_engine 9,183→6,117 行、「引擎」歸屬腰斬 3,022 行；**D-10 判準改「執行面與平台任務層的耦合程度」非行數**。**2026-08-31 晚拍板**：退役清單放行→**退役棒 CM-1486 已開**（確定死 11 條 ~3,357 行＋三護欄；追加 D-8① dark stub 3 支退役＋D-5 兩支純讀補 readmodel）；189 孤兒 camunda 容器 user 裁不動；**D-1～D-9 全數照建議採納**（user 委任首腦複審後拍板，裁決紀錄在 CM-1478 已收 Done；D-7 補閥「port 超過一張即退回稽核半」；D-8② oscal_audit_service 殭屍查證另立）；D-10（flow-engine 與 task 平台層是否合體）判準改「執行面耦合度」，**留待第 2 步分家後裁**。**CM-1486 退役棒 ✅ Done**（2026-08-31 驗收：淨刪 4,351 行 33 檔三 commit `561922d4`/`4be998f9`/`10b1417a`；三護欄各一發突變實證守住——wf_exec_control_mapping 表 804 筆＋繼承 SQL 解出 526 組配對/update_element_variable 套件零異動/EvidencesType 保留；停用 route 404、camunda 檔消失、readmodel +2 支首腦親驗；守衛 64 綠；⚠️ 驗收打折已聲明：DEV 帳號全 MFA 拿不到 token，驗的是 route 狀態碼＋SQL 可執行性非端到端，user 手測清單 7 條在卡上）。app/flow_engine 9,183→~6,100 行。**CM-1487 第 1 步搬遷 ✅ Done**（2026-08-31 深夜驗收：**runner 煞車推翻「226 檔比照 P12 機械搬」**——16 檔依賴未套件化模組硬搬＝套件反向 import；首腦裁 A 拆兩棒。實收：清 20 處死 import `1e4cb41d`→jedi-flow-control 抽出 190 檔 15,183 行 monorepo `f6f7743`→主專案改接線 171 支 shim `761eea3b`。驗證六項全額：URL 424 條逐字同/守衛 65 綠（+本棒列，突變驗過）/套件獨立 venv 11 綠/拔掉測試/A-B 對打 42/42 同/baseline 回歸 diff 零新增；⚠️ 打折已聲明：token 註冊屬寫 DEV 不做，A/B 走到認證層，端到端留 user 手測（卡上 8 條）。**留主專案 24 支**（16 卡住+D-4 四支+2 連帶），**16 支逐支清單在卡上＝第 2 步開工名單**，歸納：先解 detection_tools/associations/task_survey/module_frame/cloud_integration/flow_engine 三支未上移件的套件化。⚠️ 其他 session 拉 branch 需 `pip install -e` 該套件路徑否則 BE 起不來（path override 未 commit 慣例）。大架構圖＋相依關係圖已交付 `26968933`。**CM-1488 分家棒 ✅ Done**（2026-08-31 深夜：通用平台層下沉 32 支（機械判準過——平台層零稽核詞雙向驗）＋兩處設計稿判反照紀律改判（project_extension 六支/task_setup 退回稽核半）＋16 支留守解鎖 1 支（task_execution_service 走 ITaskExecutionQuery port，D-7 閥計量 1 張通過）＋**D-10 材料備妥**（`docs/analysis/2026-08-31-d10-flow-engine-task-platform-coupling.md`：import 平台→引擎僅 2 條，但 **DB 四條 CASCADE FK 平台綁定表→job_executions**——D17 律①鐵證；裁決取決於「任務可綁東西」債償不償：償→維持兩包/不償→合體才誠實，**等 user 裁**）。守衛 69 綠/URL 424 同/A-B 對打失敗清單零新增。⚠️ **平行棒共用 index 事故**：`b74bd564` 誤收 CM-1481 的 35 檔（顯式 add 不足以防「別人 staged 的混進來」，教訓＝commit 前必 `git diff --cached --stat`；歸屬已補 `7b160e5e`，零工作遺失）。**CM-1481 P10 ✅ Done**（jedi-evidence-classification 抽出：五張 port（含 IProjectRoleGuard 窄 port 不依賴 jedi_participant）/兩表刻意不加 RLS（DEV 實查本就無，加了=行為變更，測試焊死）/打包腳本補 PKG_DATA_DIRS 防基準資料靜默缺失/突變 9 發含抓到自家守衛盲點一發；⚠️ 端到端打折（觸發分類要花 AI 錢，手測 9 條在卡上）。**CM-1480 前半評估 ✅ 已裁「插件化」**（user 2026-08-31）。**D-10 已裁（2026-08-31）：先償債、維持兩包**——四條 CASCADE FK 改軟參照（D17 律②），償債併入第 3 步；反悔條件＝償債時發現真共生。**兩棒齊發**：CM-1489（detection 插件動工——綁定表歸 flow_control 已裁/四張 port/切 DI 雙向迴圈/profiles 5.4MB 隨包）＋CM-1490（4.2 第 3 步——D-10 償債 migration 只套 DEV/FlowControlJobType 申報制/D-1 job_service 三分/問卷審核第一案例「設定關掉審核消失」）。⚠️ 平行紀律升級：commit 前必 `git diff --cached --stat`（index 共用事故教訓）。**CM-1489 中途裁 B**（綁定表留檢測側——runner 實查推翻首腦裁決：用量反向 12:10 含 2 寫入/FK 指向 config.detection_tools 而非 job_executions/撞 port 閥門；教訓＝首腦裁決含事實斷言也要附實查；排序約定＝1489 的 job_service 段等 1490 收口）。**CM-1490 ✅ Done**（2026-08-31 深夜驗收：D-10 償債四條 CASCADE FK 拆除——首腦 pg_constraint 親查指向 job_executions 剩 3 條（餘屬 job_evidences/device_mapping 不在範圍）、migration 入帳只套 DEV、反悔條件逐條驗過未觸發（唯留言表補程式側刪除）、懸空 id 降級實測；申報制上線——型別表=插件申報、假型別掛拔實證、拔問卷申報選單同步消失；問卷審核開關 ON/OFF 實測「設定不是客製」兌現；D-1 job_service 1144→427＋兩 handler mixin 只搬不改（detection handler 歸宿留 1489）；D-3 一行未改吃到申報制。守衛 69 綠/URL 424 同/8 紅既有（stash 比對證明）。**未做誠實**：孤兒定期清理 job 未建置（防線=顯式刪+降級）。BE `0b695740`+`93eebedd`/monorepo `eaaa651`+`99536a6`。**CM-1489 detection ✅ Done**（2026-09-01 驗收：147 支 11.6k 行進 jedi-detection、主專案淨刪 13,138 行；裁 B 兌現（綁定表留檢測、理由入 plugin.py）；DI 迴圈前提修正屬實（套件層本無迴圈，只補 IAgentDirectory 反向半邊）；migration 隨包取自 pg_dump 實況、11 表 7 掛 RLS 四張全域字典刻意不掛（測試焊死）；profiles 5.4MB 隨包實查；守衛 70 綠親跑/端點 401/零未推；shim 兩坑記錄（walk_packages 遞迴掛＋1490 handler 靠 shim 化解零觸檔）。⚠️ 打折：無 token 端到端留手測（卡上 10 條，派工鏈第 6 條最重要）；無 harness（跨四套件相依，README 誠實聲明待型別層償還後補）。**漏項裁明**：裁示④ detection_profile_usage_query 未進 readmodel（runner 自首非刻意）→ 開小卡 **CM-1491** 補正（純搬檔+DI 改 port 注入，比照 DetectionJobNotifyQuery）。CM-1480 隨動工完成收 Done。**三包定名拍板（2026-09-01，user 註「可能再調」——發版前是改名零成本窗口）**：jedi-flow-engine 不動（實查證實名至實歸——執行引擎活著在套件內，先前「只剩 BPMN 工具箱」說法有誤已更正；BPMN generator/validator 2,758 行實住主專案，裁歸引擎套件隨 4 步搬）／平台包=**jedi-task-platform**／稽核插件=**jedi-compliance-audit**（不佔 audit 泛稱防撞名）。**申報書選配化定調**（survey 先例制度化：task type declaration 必須選配、核心能力不得依賴它——audit 型積木必依平台、survey 型核心可獨立）。**第 4 步打包棒 CM-1492 已開**（兩包改名/D6D7 補齊/BPMN 工具歸引擎/CM-1491 併入/兩包間 2 條 import 收 port/申報書選配入指南；不 publish——發版仍歸統一發版棒）。⚠️ 拉 branch 需 pip install -e jedi-flow-control/jedi-project/jedi-evidence-classification 三支。identity JOIN 償還=CM-1484（排 4.2 後）；view 歸屬與 D17 view 條款已補 |
| **跨疆界聚合 API 盤點（✅ 2026-08-31 完成，第四階段前置）** | 待落檔 | **核心發現:最重的聚合不在 service 注入面、在 infra 層跨 schema raw SQL**——8 支聚合 query（約 1,500–2,000 行,冠軍 ssp_control_implementation_query 一句 SQL JOIN 19 表 4 schema 七疆界）＋DB view vw_user_job_queue（六疆界）。真聚合端點約 25–30 條/真聚合 service 8 支;假聚合清單已辨（task_survey 12 條/participant 10 條等合併後即單疆界;project_summary_report 洗清嫌疑=純 CRUD）。**三條關鍵建議待 user 裁**:①8 支聚合 query 正名搬 infra/readmodel/（防抽套件時被誤搬——第四階段最可能出事處）②AI Dashboard registry 改套件自註冊（否則每抽一支要回改 525 行硬編碼+14 container resolver;順修 2 個指向不存在 provider 的壞條目）③P12 前先裁 TaskAssigneeService 切法（純 CRUD 隨套件/list_my_grc_jobs 留聚合層——「我的任務」主動線,P12 頭號障礙）。全文待落 docs/analysis/ |
| **資料關聯解耦三律（2026-08-31 與 user 討論定調，第四階段入 design.md 通則）** | 未開卡 | 套件間資料表關聯的判斷樹：①**想建 FK＝該合併疆界**（FK 是「同一生活圈被切錯」的訊號——D10 問卷合併的鐵證邏輯，通則化）；②**真跨疆界＝軟參照**（存 id 不建 FK 約束、讀取走名冊/port、查不到必降級不炸——D8 身分脈絡標準件與 log-forwarding 先例的通則化，含「禁 JOIN 宿主身分表」既有禁令）；③**流程耦合＝事件/port，連 id 不存**。第四階段 P12（participant hub）/問卷合併/flow_control 拆出全依此判 |
| **設定 schema 申報制（user 2026-08-31 定調，第四階段議程）** | 未開卡 | **「設定的 schema 進套件、值與存放留宿主、模組開關表永遠留宿主」**——把 D6 config 插槽升級為正式規格：套件 register() 時申報設定 schema（鍵/型別/預設/驗證），宿主照舊集中存 system_configs 並拿 schema 驗寫入；加分項＝設定頁由申報 schema 自動生成。業界同構（GitLab/Odoo/WordPress register_setting/K8s CRD——插件宣告形狀、平台管存放）。first case＝.16 的 security_policy.py（七鍵 schema 進套件、值留 system_configs），第四階段制度化並回頭套用到既有套件。**2026-08-31 討論補充**：①schema 申報須含**作用域**（系統級/租戶級/租戶可覆寫）——system_configs 已有 tenant_id＋(tenant_id,group,key) 唯一鍵，儲存機制現成；②初始化採「預設活在 code、DB 只存差異」優先（讀無列回 schema 預設，免 seed 時序問題），若 seed 則只補缺鍵絕不覆蓋（冪等鐵則）；③SMTP by domain 型＝租戶可覆寫系統級：fallback 鏈（租戶→系統→fail loudly）是套件申報的行為，客戶只控自己作用域內的值、寫入過 schema 驗證、跨層有授權守門 |
| **flow_control 拆出（user 2026-08-30 指示）＋流程疆界三方設計（2026-08-31 併入）** | 未開卡 | **第四階段議程**——flow_control 拆法「先單純拆出、切分後議」；**3.4 實查證實 flow-engine 的 route/app 層歸屬也懸在同一條線上**（19 條 route 17 條吃稽核業務、6,375 行 app/flow_engine 疆界未定，CM-1470 裁 (a)+(c)：本棒降級輕量、route 歸屬併此案），屆時 flow-engine/flow_control/project 三方同席，與 P12/P13 同場設計 |
| 查證卡 | **CM-1450 ✅ 已結**（2026-09-01 第四任首腦查實：DROP＋FlowTemplateEnricher 連帶清理**已由 CM-1474 清債棒全數執行**——表已 drop、程式已清、只套 DEV；此項不再等令）。**CM-1462**：D12 歸因＝97% 服務層缺能力、僅 2 條便宜行事；P13 中間路線已由 CM-1479 採納；boundary-map §3④ 兩處待修 | CM-1450 結案；1462 餘文件債 |
| 追蹤帳（隨棒勾銷，不單獨派） | CM-1461（62 支死路徑）／CM-1451（**2026-08-30 裁併入第三階段**：system_log 會炸碼＝退役級優先項、issue 依賴宣告＝補殼必辦；卡上已註記） | 隨 2.5/三階段消化 |
| 真 backlog（等 user 哪天清債再排） | CM-1445（RLS 三表）／CM-1452（出貨品質——排下次出包前）／CM-1453（projects RLS 查證）／CM-1463（is_admin 權限遷移，1459 衍生，2.5 收口後才可動）／**license-runtime view 穿越債**（tenant_admin_notify_query raw SQL 直打 v_user_capabilities＝套件查身分疆界 view，改走宿主 port，隨下次動該套件順手償還；2026-08-31 view 盤點發現） | 未排 |
| 不開卡（階段內建） | pyproject 依賴衛生（pycryptodome 虛掛＋15 支測試依賴錯放）——**第三階段補殼棒 prompt 帶「順手掃依賴」即可**（D16 過 pyproject 時自然做） | — |
| jedi-bulletin | — | D14 定維持獨立套件，第三階段補殼＋依賴 port 化 |

## P3＋P4 全卡掃描盤點結果（2026-09-01 第四任首腦，user 指示逐卡重讀後）

**背景**：user 質疑「收 Done 的卡裡有沒有沒人接的遺留」，首腦把 P4（CM-1474–1492）＋P3（CM-1467–1473）共 24 張卡全文重讀盤點。結論：多數遺留有被接住（如 1475③→P12 步驟 0、1489 漏項→1491），但抓到懸案，已開五張新卡：

| 新卡 | 接住什麼 | 排程 |
|---|---|---|
| **CM-1493 償債棒** | ①task-platform 反向依賴 survey/device 斷開（pyproject 自註「方向是反的」，**發版依賴環的根源**）②detection handler 640 行歸位（1489↔1490 互踢無人認領）③1482 shim 清理＋1487 16 支留守實搬 | 🔴 **發版前置** |
| **CM-1494 查證棒** | ①oscal_audit_service 殭屍查證（D-8② 裁「另立」從未立）②flow-engine 疑似死 4 條補證據（1485 遺留） | 收官串內 |
| **CM-1495 追蹤** | 任務綁定表孤兒定期清理 job（1490 償債配套，明文「尚未建置」） | 發版後可 |
| **CM-1496 SMTP 修復** | 測試信按鈕壞掉的既有 bug（1469 發現「另開卡」未開；根因修法在卡上；user 裁不搬套件、修主專案 TestMailService） | 隨時可派 |
| **CM-1497 套件債清理棒** | notification 架構 4 紅＋jedi-log 11 紅＋flow-engine 26 紅 9 err 三筆存量債修除＋jedi-issue 58% 死碼裁決材料 | 發版後、arc-review 前 |

CM-1484 排序更新：改排 1493 之後（同型手術照抄先例）。原卡（1482/1489/1490/1484/1469/1470/1471）已 append 指向。
**P3 掃卡另兩項裁定**：`authz/` 命名 **user 拍板不改**（維持 `authz`，CM-1467 待裁項結案）；SMTP 測試功能**不搬套件**（TestMailService 屬產品設定知識，CM-1496 卡上有裁定全文）。
**P3 記帳（不開卡）**：Nexus 四支舊殼（auth/login/mfa/captcha 舊版）下架/yank 等 user 令；CM-1461 剩 bulletin/device/system-config 9 支未拔（route 未上移），收官前盤總帳。

**綠色記帳（時機未到不開卡）**：四張 `hi_*` 歷史表 0 筆留另議（1486）／`flow_template` API 欄位併 FE 拿掉（1474）／兩套件 harness 待型別償還後補（1489/1492 誠實聲明）／存量紅燈一批（8 紅 guard 未接線＋AI dashboard 舊測試 metadata_builder 不存在）——收官 e2e 會撞到，先記。

**⚠️ 待 user 確認**：CM-1481（AI 分類）與 CM-1489（detection）收 Done 在本任接手前，兩卡手測清單都聲明「端到端未跑」（分類要 AI 錢／檢測要 agent 實掃）——user 是否實際手測過待確認，未測過則實質是「修正待驗證」。

## 收官棒待辦累積（隨討論記帳，收官時一次做）

0. **Postman collection 重產**（2026-09-01 發現）：`docs/reference/postman/` 是第四階段搬遷前產的已過期（分類/auth 標記與現況差 7,800 行）——收官時重跑 `gen_postman_collection.py` 入版。

1. **readmodel 整理**（user 2026-09-01 記帳）：①按功能語境分子資料夾（tasks/audit/oscal/detection）＋每支檔頭標「拼了哪些疆界」；②**四條規格入資料夾 README**（只讀鐵則/層次紀律 route→app query service→infra readmodel/出口必 DTO 不泄 ORM row/port 化注入）——聚合查詢仍屬 DDD＋六邊形（CQRS 讀側），不是豁免區；③逐支核 DTO 出口。等在途檔落定（CM-1491/D-2 聚合半）再動。
2. **套件族譜對照表終版**：路線圖「套件族譜」節（`a71ab166` 已有活版本）在 CM-1492/1482 收口後把進行中段搬進已完成，定名後為終態。
3. **「主專案剩什麼」四類清單落架構手冊**（櫃檯/接線盤/組裝/業務加工——口頭版已給 user，2026-09-01）。
4. **可選**：跨 schema SQL 提示型守衛（掃 infra/ 各模組目錄 SQL 字串含跨 schema 表名——已知盲區的不完美緩解）。
5. **終局備忘（不排程）**：主專案 DDD 四層縮成產品定義層後，目錄語意重新表述。

## 委任狀態

- **分支 push 已委任**（memory `feedback_fr069_push_delegated_branch_only`）：僅限 BE 與 jedi monorepo 兩 repo 的 `feature/FR-069`，收口後順手推不必請示；**合併回 main 仍 user 本人**；arc 收口後委任失效。

## 關鍵檔案座標

| 東西 | 位置 |
|---|---|
| 決策與路線圖 | `docs/features/FR-069-2608-jedi-module-extraction/design.md`（**D1–D16** 決策表＋四階段＋2.5 階段＋§8 套件階層依賴圖 living＋CM-1461 隨棒必做；HTML 站同資料夾） |
| 疆界地圖 | 同資料夾 `boundary-map.md`（D10–D14 的證據基礎；第三/四階段名單依它） |
| ext 盤點 | 同資料夾 `phase2-ext-table-inventory.md`（.12 的依據；190 張表四偵測面可重跑） |
| 抽取 SOP | 同資料夾 `extraction-sop.md`（七階段；§4.2 migration 隨包五規則） |
| Postman | `docs/reference/postman/`（產生器＋collection＋environment＋端點對照） |
| **jedi-iam 套件** | `~/Projects/Jedicogy/module/jedi-python-package/jedi-iam/`——**route 在 `jedi_iam/api/`**（URL 表在其 `__init__.py::mount_routes()`）；插件契約在 `plugin.py`；架構說明見 `README.md` §3.5／`README.html` |
| **宿主接線** | `common/iam_ports.py`（三張疆界外 port）＋`core/iam_wiring.py`（route 層 service 名冊／認證／hook）；守衛 `test/test_iam_wiring.py` |
| Notion | 母卡 CM-1435（**不收 Done**——後續階段仍掛其下）；P0–P8＝CM-1436～1443 全 Done；.9～.12＝CM-1446～1449 全 Done；CM-1454 Done；2.5＝CM-1455～1460 全 Done；**第三階段＝CM-1467（Done）～1472**；技術債 CM-1445/1450–1453/1461/1463 |
| 交接 | 本檔＋`fr069-LOG.md` |
| **發版清單草稿** | 同資料夾 `release-plan-p4.md`（七支順序表＋三個發版前必解的結：依賴環查證／三包名最後確認／task-platform 版號起點） |
| **第四階段決策推理** | `docs/analysis/2026-09-01-p4-key-decisions-rationale.md`（D-10 兩包攻防／detection 綁定表裁決反轉／三包命名死路——**重議命名時必讀**） |

## 決策速覽（一行一條，全文見 design.md §3）

- **D5** grc→`flow_control`（error code 字串值與 API path 不動）。
- **D6** 插件契約：自帶 api／container／migration 隨包／`register(app, adapters, config, schema_extensions, mount_api)`；拔掉測試。
- **D7** harness＋接入 README 標配；形態分流準則。
- **D8** 全路線解凍、四階段結構；身分脈絡名冊標準件。
- **D9** 身分族合併 **jedi-iam**（auth＋login＋mfa＋captcha 降級＋主專案身分中介層）；notification 獨立、agent 機器身分不併；順手清四髒。前置已確認：jedi-* 僅 Guidant AI 消費。
- **D10** 問卷疆界合併成立（跨邊界 FK 鐵證）；**D11** device 不併檢測；**D12** OSCAL 三角改寫（開工前查證依賴方向）；**D13** 三支退役＋user 追加 department/resource-store 即刻標記；**D14** bulletin 維持獨立套件；**D15** ext 裁決三件（.12 改打 project_extensions／孤兒表另案 CM-1450／JSONB 定位改預防性建設）；**D16** 基礎依賴 port 化通則（四張標準 port；唯一例外 jedi-common）。

## 文件債（下次順手修）

- CLAUDE.md「Response Format」段寫信封鍵是 `code`，實際是 `status`（P7 驗收確認文件從頭錯）。

## 🔴 驗證瘦身規則（2026-08-30 user 拍板，CM-1464 起生效；派工 prompt 必帶）

> 背景：實測驗證吃掉每棒 6 成以上時間，多為重複與儀式。判準沿用既有原則——**「壞了會不會靜默」**：會靜默的驗證是保命錢不砍，會大聲叫的靠測試扛、不手驗。

1. **突變驗證只做「安靜壞」的**（安全降級/漏接 port/授權放行類）；結構守衛類（殼檔數/警告訊息等,壞了測試本來就紅）不做突變。
2. **行為驗證表只驗本棒動到的路徑**，上游棒驗過且本棒未碰的不重驗（regression 由守衛測試扛）；**上限 8 列**，超過要在回寫說明理由。
3. **不跑全量 pytest**——只跑動到模組的既有 test 檔＋守衛測試（本來就是 CLAUDE.md 測試政策）。
4. **同型棒信任遞減**：同型第二支起驗證項對半（例：第三階段補殼首棒全額，之後每支輕驗）。**地板不再往下**：守衛全綠＋拔掉測試＋該模組 2–3 條 API 實打，每棒必做。
5. **首腦驗收改抽查**：runner 已貼實際回應碼的，首腦抽 2–3 條關鍵路徑核對，不重打全鏈。
6. **不砍的保命錢**：守衛 grep、機械 diff 比對、「該擋的擋」核心 2–3 條（401/403）、RLS 抽查——全屬無聲失敗類或成本極低。
7. runner 側落地方式＝派工 prompt 固定尾註（runner 不讀本檔）；本段為 canonical，prompt 與此不一致以本段為準。

## 每棒驗收 SOP（首腦側固定檢查，P1–P8＋.10–.12 實跑過）

1. 套件結構五層齊備（api/app/domain/infra/plugin＋harness/＋tests/＋README）。
2. 守衛：套件源碼 grep 主專案 import＝0（`^\s*(from|import)\s+(app|domain|infra|api|common|config|di_containers|core)\.`）。
3. 套件測試離開主專案獨立跑全綠。
4. `register()` 四插槽簽名與 P1 範本一致。
5. 拔掉測試證據（卡片回寫要有：註解註冊行→BE 起得來→該模組路由 404→其餘無感→還原恢復）。
6. 接入 README 含 quickstart；migration 隨包照 SOP §4.2。
7. 主專案 `pytest test/test_module_boundaries.py` 全綠（現 49）；卡片白話回寫＋commit hash。
8. **身分類棒次加驗**：權限行為實測（該擋的 403/401、該過的 200）貼實際回應碼；驗證/密碼/token 邏輯零行為改動。

發版流程（user 明令後）：套件 `poetry publish --build -r nexus` → 主專案 pin `==版號`＋path 行註解回去 → `poetry update`（禁 poetry lock）→ symlink 驗證 → 煙測（守衛＋重啟後端＋實打一支 API＋log 無 ERROR）→ commit（只收 pyproject.toml＋poetry.lock）→ Notion 補發版紀錄。後端切正式版**必重啟**。semver：加新無破壞＝patch/minor；jedi-auth 依賴 jedi-common，發版順序 common 先。

## 踩雷提醒（接手必讀）

- 平行棒同時改 `config/app_modules.py`／`pyproject.toml`：commit 前 `git status`，只顯式 add 自己的檔，禁 `-am`／`git add -A`；絕不跑整樹還原。**同檔混有平行棒不可入版的改動時：docs 先行記錄事實、檔案改動託付後棒入版**（退役棒先例）。
- 驗收「文件 vs 實況不符」先比對變更前後原始碼再下結論；「看似重複的殘留」先查繼承鏈（見 LOG 教訓）。
- 改主體域守門行為改 **`jedi_iam.authz`** 套件（3.1 起主專案已零引用 `jedi_auth`，守衛測試焊死），不在 `common/authz/` shim 補邏輯（守衛測試會擋）。
- 🔴 **身分 route 已不在主專案**——要改帳號／角色／租戶／部門／登入／MFA 的端點行為，改 `jedi-iam/jedi_iam/api/routes/`，不是 `api/auth/`（該目錄已刪）。URL 對照表在 `jedi_iam/api/__init__.py::mount_routes()`。
- 🔴 **宿主接線檔命名**：`common/iam_ports.py`（套件要的疆界外服務：通知／設定／OTP 文案）vs `core/iam_wiring.py`（route 層的 service 名冊、認證 decorator、產品 hook）。**要加新的 service／hook 改後者**，且它放 `core/` 是刻意的——它 import `app/` 與 `infra/`，放 `common/` 會被反向 import 守衛擋下。
- 看 log 分辨平行棒：錯誤請求的 `Host:` 埠——8000 是主開發服務，其他埠（如 8010）是平行棒臨時服務，錯誤不要誤判為主線 bug。
- BE 連的庫必須是套過最新 migration 的（目前僅 `guidant_ai_dev`）；基線庫補套走 P-like 驗證那條路，不手動補。

## 新首腦接手指引

讀本檔＋`design.md` §3 決策表（D1–D16）＋§8 依賴圖即可接手。驗收照上方 SOP；發版照上方流程；派工 prompt 慣例見 LOG 各棒記錄（薄 prompt＋卡號＋該卡會踩的鐵則＋runner 鐵律尾註）。

**此刻的下一步**（2026-09-01，CM-1499 發版棒 ＋ CM-1500 共編修復皆已收 Done）：
1. **收官串**：CM-1497 套件債清理（**新增待辦：D6 契約 library 模式不寫 runtime context，七支同款缺口統一補齊**——見下）＋CM-1498（associations 殭屍）→ e2e 回歸（含 S4 恆偽分支退役）→ arc-review → 文件收官（「收官棒待辦累積」節）。
2. user 手上的待裁：三包名字最後確認（發版前是免費改名窗口）。CM-1450 已查實由 CM-1474 執行完畢，不再等令。

**CM-1497 新增待辦（CM-1500 帶出，2026-09-01）**：插件 `register(..., mount_api=False)`
（D6「當 library 用」逃生門）**只做 configure、不寫 `app.extensions`**，而寫入綁在
`create_blueprint(s)()` 的 `record_once` 上、只有 blueprint 真被掛上才觸發 →
**「不掛路由」與「拿得到 `ctx()`」成了綁死的二選一**，宿主端補不出來。
jedi-survey 已於 `0.1.1` 單獨修好（user 裁 A 案）；**其餘七支仍有同款缺口**
（iam／file-upload／detection／notification／system-menu／issue／log），現無 socket
模式使用場景故不發作，裁定併 CM-1497 當 D6 契約統一補齊。修法照抄 monorepo `28e8be3`
（約 4 行＋兩條契約測試），語意須與 `record_once` 一致＝**無條件覆寫、最後一次贏**。
