---
title: FR-080 定版交付 — jedi-* 套件整併後的最終長相
brand: Guidant AI · **FR-080** 定版交付
eyebrow: 定版參考文件 · 只寫現況 · 已出貨
h1: 整併後的最終長相：21 支套件、五層、誰依賴誰
lede: 這頁是 FR-080 的**定版交付規格**——只回答「現在長什麼樣」。要看「當初為什麼這樣決定」去 design.md，要看「哪一棒做了什麼」去 handoff/LOG。**本頁不記沿革、不 append 進度**，內容變了就整段改寫。
chips: [{text: 21 支套件, kind: ok}, {text: 五層依賴只准往下, kind: ok}, {text: 六支已 archive, kind: plain}, {text: 定版參考, kind: accent}]
footer: 本頁只描述現況。決策理由見 design.md，逐棒紀錄見 handoff/fr080-LOG.md 與 git log。套件形狀規格（plugin/ 五檔、api/ 拆 guards 與 routing）屬 FR-089／FR-091，見該站的 plugin-anatomy。
---

## 一句話 {#tldr nav="一句話"}

**25 支套件合併成 21 支，分五層，上層可以用下層、下層不准反過來認識上層。** 被合併掉的六支搬進 `archive/` 封存，不刪也不再發版。

主專案要接一支套件，就在 `core/plugins/` 下開一個同名檔案接它——**裝上、接好線、API 就自己長出來**，主專案不用重寫一次業務邏輯。

---

## 21 支套件現況表 {#packages nav="21 支套件"}

版號為 Nexus 上的現役版本。「自帶 SQL」是套件 `migrations/` 目錄下的腳本支數——有值代表該套件自己帶資料表，客戶端升級鏈由 FR-093 負責。

| 套件 | 做什麼（一句白話） | 層 | 版本 | 自帶 SQL |
|---|---|---|---|---|
| jedi-common | 地基：資料庫連線、交易、錯誤格式、共用工具。所有套件都踩在它上面 | ① 基座 | 1.0.1 | — |
| jedi-iam | 登入、帳號、角色、租戶、權限。管「你是誰、能不能進來、能做什麼」 | ② 中介 | 1.0.1 | — |
| **jedi-log** | 日誌管線：API 存取紀錄 ＋ 轉發到客戶 SIEM（syslog／GELF，選配、可失敗） | ② 中介 | 1.0.1 | — |
| jedi-integrity | 防篡改：開機前逐檔比對簽章，程式被改過就拒絕啟動 | ② 中介 | 1.0.1 | 1 |
| jedi-license-runtime | 授權驗證：讀客戶的授權檔、驗簽、到期狀態機、開通與展延 | ② 中介 | 1.0.1 | 3 |
| jedi-notification | 寄通知：Email、Discord、Telegram 三個出站管道 | ③ 平台服務 | 1.0.1 | — |
| jedi-file-upload | 檔案上傳下載、轉 PDF 預覽，支援本機與 S3 類儲存 | ③ 平台服務 | 1.0.1 | 2 |
| **jedi-system-core** | 系統開機字典：系統設定表（SMTP、LDAP、儲存設定）＋ 前端下拉選單字典 | ③ 平台服務 | 1.0.1 | 2 |
| **jedi-asset** | 資產清冊：設備（主機、IP、OS）＋ 資訊系統（FIPS-199 等級、系統狀態、負責人） | ③ 平台服務 | 1.0.1 | 2 |
| jedi-bulletin | 系統公告：發布、到期、發給哪些部門 | ③ 平台服務 | 1.0.1 | 2 |
| jedi-issue | 工單與意見回饋：本地工單，可同步到 GitLab／GitHub | ③ 平台服務 | 1.0.1 | — |
| jedi-remote-agent | 客戶端 agent 的註冊、心跳、派工、mTLS 身分。是通道，不含業務 | ③ 平台服務 | 1.0.1 | 3 |
| jedi-ai-bot | 系統內建 AI 聊天視窗 | ③ 平台服務 | 1.0.1 | — |
| jedi-ai-dashboard | 一句話生成儀表板：AI 挑資料源、查資料、設計版面 | ③ 平台服務 | 1.0.1 | — |
| **jedi-task-platform** | 專案與任務骨架：專案主檔、任務留言、任務綁設備／組織／問卷、匯入匯出，**加上**誰被指派到哪一層與角色繼承 | ③.5 骨架 | 1.0.1 | 2 |
| jedi-flow-engine | BPMN 流程引擎：解析流程圖、推進節點、記錄執行 | ③.5 骨架 | 1.0.1 | — |
| jedi-oscal-v2 | OSCAL 合規標準資料模型：控制項目錄、基準線、SSP、評估計畫與結果、改善計畫，共 45 張表 | ④ 業務 | 2.3.1 | — |
| jedi-compliance-audit | 稽核業務本身：稽核輪次七態狀態機、評估計畫與結果匯入、缺失追蹤、審閱標記 | ④ 業務 | 1.0.1 | — |
| jedi-survey | 問卷：設計問卷、發給人填、記錄作答與修改歷史、多人即時共編 | ④ 業務 | 1.0.1 | — |
| jedi-detection | 檢測：檢測工具目錄、租戶憑證、檢測基準庫、派工到 agent、收回掃描報告 | ④ 業務 | 1.0.1 | 2 |
| jedi-evidence-classification | AI 證據分類：把 Google Drive 上的證據檔用 AI 對應到評估項目 | ④ 業務 | 1.0.1 | 2 |

**粗體四支是合併產物**，其餘 17 支維持原樣。

### 四組合併：誰併成誰

| 合併後 | 由誰組成 | 合併的判準 |
|---|---|---|
| **jedi-asset** | jedi-device ＋ jedi-information-system | 同一件事的兩種型別（資產清冊表本來就用 `asset_type ∈ {hardware, information_system}` 區分） |
| **jedi-task-platform** | jedi-task-platform ＋ jedi-participant | 資料同生共死（任務指派 12,479 筆全部對得上專案表），且是整個套件庫唯一的雙向循環 |
| **jedi-system-core** | jedi-system-config ＋ jedi-system-menu | 同層、同性質（字典型增刪改查）、近三個月三次同批異動 |
| **jedi-log** | jedi-log ＋ jedi-log-forwarding | 同屬中介層，「記錄」與「轉發」是同一條日誌管線的上下游 |

被合併的六支（device、information-system、participant、system-config、system-menu、log-forwarding）已搬到 `jedi-python-package/archive/`——**不刪、不發版、不再維護**。

### 三組「像但不併」

這三組看起來該合，刻意保留分開。列在這裡是為了不要每次有人看到就再問一次。

| 這兩支 | 為什麼不併 |
|---|---|
| oscal-v2 與 compliance-audit | oscal-v2 是國際合規標準的資料模型，任何合規產品都可能用；compliance-audit 是本產品獨有的七態流程。合了等於把通用標準庫綁死在 Guidant 的狀態機上 |
| integrity 與 license-runtime | 資料完全不共用、啟動時機不同（一個在服務起來之前跑、一個在之後）。共用的只有簽章驗證引擎 |
| detection 與 remote-agent | 一個是業務層、一個是平台服務層。remote-agent 是通道，通道不能併進業務 |

---

## 五層：依賴只准往下 {#layers nav="五層"}

```
① 基座        jedi-common
                  ↑
② 中介層      jedi-iam ／ jedi-log ／ jedi-integrity ／ jedi-license-runtime
                  ↑
③ 平台服務    notification ／ file-upload ／ system-core ／ asset ／ bulletin
              issue ／ remote-agent ／ ai-bot ／ ai-dashboard
                  ↑
③.5 骨架      jedi-task-platform ／ jedi-flow-engine
                  ↑
④ 業務        oscal-v2 ／ compliance-audit ／ survey ／ detection
              evidence-classification
```

**規則三句**：上層可以用下層；下層不准反過來認識上層；**同一層之間也不准直接互相抓**，要合作就經過主專案轉一手。

這三條不是靠自律——守衛測試 `test/test_module_boundaries.py` 會擋，寫錯就測試紅字。

判某支該歸哪層用兩個問題：**壞了會怎樣**（基座壞了全倒、業務壞了只倒一塊）、**換一個產品還要不要**（要 → 越下層）。長期規範版見 [架構手冊的套件分層頁](../architecture-handbook/package-layers.md)。

---

## 新產品起手式 {#starter nav="起手式"}

要開一個新產品，**裝這五支就有登入、存取紀錄、設定、選單、寄信**：

```
jedi-common ＋ jedi-iam ＋ jedi-log ＋ jedi-system-core ＋ jedi-notification
```

其餘依產品需要選裝。

🔴 **一個陷阱**：system-core 的**表結構**屬於套件沒問題，但它裡面那 74 筆下拉選單資料含有稽核專用的項目（像「稽核方法」「SSP 角色」）。**表跟著套件走，資料留在主專案**——不然新產品裝上去會冒出一堆稽核才有的選項。

---

## 主專案怎麼接 {#host nav="主專案接法"}

**一支套件一個檔**：`core/plugins/<pkg>.py`。檔案裡固定三段——① 回答套件開出來的問題（它問「誰是這個使用者」，主專案答）、② 填一張表把答案交給它、③ 把 API 掛上去。接手的人一個檔看完，不用翻五個地方。

**接一支新套件只要三步**：

1. `pyproject.toml` 加一行相依
2. 新建 `core/plugins/<pkg>.py`，照抄任一支現成的
3. `core/plugins/__init__.py` 的 `PLUGINS` 清單加一列

第四步只有在「主專案別的地方要直接用這支套件的服務」時才做（`di_containers/` 加一顆）。純掛 API 不需要。

🔴 **`PLUGINS` 的順序就是掛載順序，沒理由不要重排**。兩處有實質依賴：`identity` 必須早於 `file_upload`；`api_log` 必須晚於 `configure_logging()`。

詳細機制（袋子比喻、guards.py、port 與 adapter、一個 request 的旅程）見 [FR-089 插件解剖](../FR-089-2609-package-shape-unification/plugin-anatomy.md)；不需要技術背景的版本見 [給 PM 的說明](../FR-089-2609-package-shape-unification/for-pm.md)。

---

## 四個驗收指標 {#metrics nav="指標"}

指令：`python scripts/deliverables/plugin_metrics.py`（BE repo 根目錄跑）。

| 量什麼 | 白話 | 開工前 | 現在 |
|---|---|---|---|
| 套件之間直接抓對方程式的地方 | 越少越好。這種線換到別的產品就會斷 | 120 處 | **93 處** |
| 開了接口但沒人用 | 宣告了「我需要你給我這個」卻沒人接，是白宣告 | 16 個 | **4 個** |
| 主專案接線的程式行數 | 接線是主專案回答套件「你要的東西我給你」的那份程式 | 7,457 行 | **9,762 行** |
| 裝上就能用、不用改主專案的套件 | 越多越好，這是「隨插即用」的直接量測 | 17 支 | **17 支** |

**兩個數字要解釋一下**，不然會看成變糟：

- **93 處裡有 68 處是稽核套件去用 OSCAL 套件**，那是**刻意留的**（見上面「像但不併」）。真正該清的其他 25 處。
- **接線行數上升是預期內**：套件把「我需要什麼」講清楚，另一半（「我給你什麼」）就落到主專案。主專案 DI 瘦身做完會往下降。
- **裝上就能用維持 17 支不是沒進步**：套件總數從 25 降到 21，同樣 17 支代表比例從 68% 升到 81%。

⚠️ 指標工具目前回報 `infra/detection_tools/adapters.py` 找不到（檔案已搬走），**接線行數會少算**，待修清單。

---

## 這一輪沒做完的 {#remaining nav="沒做完的"}

寫在這裡是為了不要被當成已完成。每一項都有人接，接的是哪個案子見下一節。

| 沒做完的事 | 白話說明 | 誰接 |
|---|---|---|
| 🔴 **切子租戶功能暫不可對外** | 有 13 張表沒把「每個客戶只看自己資料」這道鎖打開，切到子租戶會看到別人的東西 | FR-094 |
| flow-engine 沒補實 | 流程引擎的核心程式被複製到主專案改過，現在套件裡那份 549 行沒人用、主專案那份 1,559 行才是真的在跑。兩份已經長歪，方法簽名都對不上 | CM-1478 流程疆界設計（未開工） |
| 主專案 DI 瘦身 | 主專案有 48 處直接去綁套件內部的元件，應該改成跟套件要（`host_services()`） | 已完成（FR-090 第 6 棒） |
| 套件自帶的資料表建不起來 | 套件會帶自己的建表腳本，但出貨的安裝程式只讀主專案那份，客戶升級時套件的表永遠不會出現 | FR-093 |
| 主體還沒進版 1.20.0 | 21 支套件都出版了，主專案本身還沒 | FR-089（等令） |
| 指標工具有一條失效路徑 | `plugin_metrics.py` 指著一個已經搬走的檔，導致接線行數少算。工具自己會印 FAIL | 已修（2026-09-16） |

---

## 延伸出去的 FR：這條線後來長成什麼樣 {#downstream nav="延伸 FR"}

FR-080 只做「合併成 21 支」。做完之後陸續長出六個案子，都是這一輪的直接後果。**要判斷「套件這條線現在到哪」，看這張表。**

| FR | 在做什麼（白話） | 為什麼會長出來 | 狀態 |
|---|---|---|---|
| [FR-089](../FR-089-2609-package-shape-unification/) | **21 支套件長相統一** — 每支的檔案怎麼擺、API 怎麼拆、logger 怎麼掛，全部照同一套 | 合併完發現 21 支各長各的，接手的人每支都要重學一次 | 🟢 全案 Done，套件 1.0.1 已出版；剩主體進版 |
| [FR-090](../FR-090-2609-host-side-residue-cleanup/) | **主專案側殘留清理** — 功能搬進套件後，主專案留下的空殼、轉接層收乾淨 | 功能上移了，舊的那份沒人刪 | 🟢 七棒 Done，含 DI 瘦身三卡（CM-1749～1751） |
| [FR-091](../FR-091-2609-package-shape-rollout/) | **把 FR-089 定的形狀真的套到 21 支** | FR-089 定規格，FR-091 是施工 | 🟢 28 卡全 Done |
| [FR-092](../FR-092-2609-dead-code-cleanup/) | **廢碼清理** — 搬完之後沒人引用的檔案、沒人打的 API 端點刪掉 | 三輪搬移累積下來的殘骸 | ✅ 全案收口 |
| [FR-093](../FR-093-2609-package-migrations-and-capability-seeding/) | **出貨升級鏈補齊** — 讓套件自帶的資料表、權限、選單在客戶升級時自動到位 | 查出出貨安裝程式只讀主專案的建表腳本，套件那份客戶端永遠套不到 | 🟡 進行中（母卡 CM-1752，十棒） |
| [FR-094](../FR-094-2609-tenant-isolation-fix/) | **租戶隔離修正** — 13 張表＋4 支 view 真的把「每個客戶只看自己資料」關上 | 資產套件補鎖時連帶盤出一整批沒關的 | 🟡 已開卡待派（母卡 CM-1766，八棒） |

另有一條**盤點性質**的：[FR-087 租戶隔離破洞盤點](../FR-087-2609-tenant-isolation-audit/)（✅ 已盤完）——它只查不修，查出來的東西交給 FR-094 動手。

**這條線的閱讀順序**：先看本頁知道合併結果 → FR-089 知道套件長什麼樣 → FR-093／094 知道還有什麼沒好。

---

## 這份文件的定位 {#scope nav="本頁定位"}

| 你想知道 | 看哪份 |
|---|---|
| **現在長什麼樣**（21 支、五層、誰依賴誰、怎麼接） | **本頁** |
| 當初為什麼這樣決定、被推翻過什麼 | [design.md](design.md) |
| 哪一棒做了什麼、驗收結果 | [handoff/fr080-LOG.md](handoff/fr080-LOG.md) |
| 原始盤點證據（25 支逐支 8 題、宿主接線、空殼細查） | [inventory/](inventory/) |
| **套件這條線現在整體到哪**（六個後續案子的狀態） | [本頁的延伸 FR 段](#downstream) |
| 一支套件內部長什麼樣（檔案怎麼擺、守門怎麼寫） | [FR-089 插件解剖](../FR-089-2609-package-shape-unification/plugin-anatomy.md) |
| 長期的分層判準（以後照這個判） | [架構手冊 · 套件分層](../architecture-handbook/package-layers.md) |
