# FR-134 交接現況（STATE）

> **這份是 living 檔**：每棒就地 Edit，只描述「此刻」。歷史脈絡看同資料夾的 `FR-134-LOG.md`。

| 項目 | 值 |
|------|-----|
| 最後更新 | 2026-10-11 傍晚（第 3 棒終局：G1／G2／G5／G6 收口，arc 休眠） |
| branch | BE／FE／jedi-python-package／license_center 皆 `feature/FR-134` |
| 母案卡 | CM-2625 https://app.notion.com/p/FR-134-SBOM-SBOM-30-3f5346da4cd08127b30ef574d14ced03 |
| 子卡 | CM-2626～CM-2674（原 30 張＋追加 V0／D4～D18／R1／G5／G6 共 49 張），索引 `../notion-cards.json`＋本檔 §1 |
| 角色 | 首腦（分析決策＋驗收），實作一律派 runner |
| **arc 狀態** | **🟢 功能完成、未進版、休眠中**（2026-10-11 決策者裁）。再次開工的觸發：決策者說「FR-134 要進版」或要開評級露出開關 |
| Notion 回寫規範 | `docs/claude/notion-issue-tracker.md`；開卡範本 `docs/claude/notion-card-templates.md` |

## 🧭 原始需求 / WHY

- **要解決的問題**（決策者原話整理，草稿 `../draft-requirement.md`）：顧問輔導客戶時，專案弱點本該由客戶工程師盤點，實務上常被「那個不嚴重」帶過；顧問沒技術背景無從判斷。要讓**不會技術的顧問自己就能知道專案用了哪些第三方元件、哪裡有已知弱點、多嚴重、修了沒**，拿有工具原始輸出背書的報表去對話。
- **做什麼**：上傳原始碼壓縮檔或 SBOM 檔 → 沙箱裡 Syft 產 SBOM（CycloneDX＋SPDX 多版本）→ Trivy＋Grype 雙掃 → 正規化 → 結果頁＋報表（PDF／HTML／Word）＋歷次比較。業界稱 **SCA（軟體組成分析）**——只看第三方套件，不檢查程式碼本身。
- **一個核心兩個入口**：側選單獨立模組；檢測工具清單裡的伺服器端工具（任務頁可選、不派 Agent、結果轉任務證據）。
- **需求演變**（細節見 LOG）：第一版只收上傳（Git 列第二版且畫面不出現）；不做 CLI；**D6「不做總評」已被推翻，改採 R1 整體風險評級**；顯示名改「第三方元件風險」；用語改專業表單用詞。

## §0 接手讀序

1. 本檔全部
2. `../design.md` §3 決策表、§5 詳細設計（注意 D6 已被推翻，見 §2）
3. 母卡 CM-2625 卡尾所有「追加」「決策變更」「上線前檢查」段（**Notion 上的才是最新**）
4. `FR-134-LOG.md` 最後一個 block
5. 自檢：①這功能給誰用、解決什麼？②兩個入口差在哪？③為什麼沙箱不出網？④整體風險評級的四條規則與依據？答不出回去讀 1–3。

## §1 當前狀態

**功能面全部完成並經決策者畫面複測。🔴 本 FR 這次不進版。** D12～D18 七張、G5 收尾紀錄、G6 出貨基線重產、G1 SPEC、G2 手冊全部首腦驗收通過（2652／2653／2673／2674 停「修正待驗證」等決策者複測收 Done）；只剩 G4 發版與上線前檢查，都等進版令。

| 群 | 卡 | 狀態 |
|---|---|---|
| A 沙箱 | CM-2626～2629 | Done |
| B 弱點資料 | B1 2630、B3 2632、B4 2633 | Done |
| | B2 2631 安裝包帶弱點資料 | Done（2026-10-11 驗收，zstd／volume 擁有者待 188 出包驗） |
| C 後端 | CM-2634～2639 | Done |
| D 畫面 | D1 2640、D2 2641、D3 2642、D4 2657、D6 2659 | Done |
| | D5 2658 改名＋專業用語＋CVE 連結＋報表「公告」改「來源頁」 | Done（2026-10-11 驗收；新增主線 migration 一支，出貨基線待重產） |
| | D7 2661 清單加「任務發起的掃描」頁籤 | Done（2026-10-11 驗收） |
| | D8 2662 結果頁三分頁、元件清單攤原檔、任務掃描頁籤整理 | Done（2026-10-11 決策者複測） |
| | D9 2663 報表只留完整版 | Done（2026-10-11 驗收） |
| | D11 2665 受評系統批次刪、失敗掃描可刪、列操作改純圖示 | Done（2026-10-11 決策者複測） |
| | D10 2664 伺服器端工具畫面殘留（抽屜 Agent 字樣／跑版、工具卡多餘按鈕） | Done（2026-10-11 決策者複測） |
| | D12 2666 加 OSV-Scanner 第三家（findings 加 osv 欄、更新包多包 OSV 十個生態系） | Done（新增主線 migration `2026-10-11-fr134-d12-findings-osv.sql`） |
| | D13 2667 產物檔名「名稱_種類_時間」；退回補修中文檔名炸標頭（下載無回應）、任務掃描檔名退路 | Done |
| | D14 2668 抽屜執行詳情時間格式、報告可預覽 | Done |
| | D15 2669 結果頁「顯示工具」勾選、沒掃的灰掉 | Done |
| | D16 2670 整體風險評級對外全藏、計算保留（開關 FE `RISK_RATING_VISIBLE`＝false、BE `SOURCE_SCAN_RISK_RATING_VISIBLE` 預設 false） | Done |
| | D17 2671 工具格子顯示各家自己的編號與分數差異 | Done |
| | D18 2672 畫面不出現「伺服器端」字樣、重新執行旁「沿用任務參數」提示 | Done |
| E 報表 | CM-2643～2645 | Done |
| F 歷次比較 | CM-2646 | Done |
| H 檢測工具入口 | CM-2647～2651 | Done |
| V0 DEV 掃描環境 | CM-2656 | Done |
| R1 整體風險評級 | CM-2660 | Done（2026-10-11 驗收） |
| G 收尾 | G3 2654 | Done（首腦直做 `ac56ce8ab`：規則 paths／能力索引四列／超標檔清單／FR 登記表） |
| | G5 2673 收尾紀錄（STATE／LOG／子卡收 Done／母卡五段） | 修正待驗證（首腦驗收通過 `a99e865b8`） |
| | G6 2674 出貨基線重產 10 支 | 修正待驗證（首腦驗收通過 `4a7554a3c`；188 基線庫 schema_migrations 245→255，STG／POC 未碰） |
| | G1 2652 SPEC、G2 2653 手冊與安裝文件 | 修正待驗證（首腦驗收通過 `80a5f8eb6`／`67afb114d`） |
| | G4 2655 套件發版 | Not started，**不進版就不發**，維持 path dependency |

**git**（皆未合併 main）：
- BE head 見 `git log -1`，已 push（2026-10-11）；工作樹只有 `pyproject.toml`／`poetry.lock`（開發期 path dependency，**不 commit**，發版後還原 pin）
- jedi-python-package head `a96ee821`，已 push
- FE head `5f5934a3`，已 push（遠端 branch 2026-10-11 首次建立）
- license_center head `14e798e`，已 push

**DEV 實況**：
- 已是**真實掃描環境**（V0）：`.env` 設 remote 沙箱；`guidant-sandbox`（image `evidence-classifier:fr134-dev`，internal 網段）＋`guidant-sandbox-relay`（只綁 127.0.0.1:18080）；起停見 `docker/dev/README-source-scan.md`
- 弱點資料 `/opt/vulndb -> ~/.guidant-dev/vulndb`，`current -> 20261018`（**手動解包、未經產品驗章、無更新紀錄**——出貨公鑰表只認 189 正式鑰，本機開發鑰簽的包會被拒收）。下次測上傳要用日期 > 20261018、189 簽的包
- 189 LC 跑 `main`，尚無 `vulndb_manifest` 簽章型（`14e798e` 只在 feature/FR-134）→ 正式鑰弱點包要先合 main、部署 189 才簽得出來
- BE api＋worker 跑在本機（log：`log/dev-api.out`、`log/dev-worker.out`）；FE dev server 5180
- 主線 migration **10 支已套 DEV 與 188 基線庫**（G6 `4a7554a3c` 重產 02-schema／04-seed-core／99-stamp；**STG／POC 未套，進版時走 init image migrate 模式**）：`scripts/sql/2026-10-10-fr134-*.sql` 8 支（tables／capabilities／grant-admin-roles／h1-sbom-scan-tool／result-route／diff-route／vulndb-updates／vulndb-settings-page）＋`2026-10-11-fr134-d5-rename-third-party-component-risk.sql`＋`2026-10-11-fr134-d12-findings-osv.sql`
- DEV 的 7 筆 SBOM 孤兒 detection_executions 與群組已刪、對應證據軟刪
- **DEV 掃描資料已於 2026-10-11 清空**（決策者令）；要驗再用決策者桌面 `guidant-be-sca-test.zip`／`guidant-fe-sca-test.zip` 掃
- 決策者桌面有兩包測試 zip：`guidant-be-sca-test.zip`、`guidant-fe-sca-test.zip`（只含依賴宣告與鎖定檔）

**守衛基準**（`pytest test/security/ test/test_module_boundaries.py test/test_fr132_split_capability_grants.py test/test_migration_stamp_policy.py -q`）：**預期 7 紅**（首腦 2026-10-11 傍晚乾淨 worktree 實跑 `7 failed, 524 passed, 16 skipped`）——
FR-134 之前即存在的 2 紅：`test_permission_matrix_three_way::test_feature_capability_matches_backend_guard`（JobExecutionDrawer job-evidence 項）、`test_route_guard_inventory::test_every_unguarded_route_is_exempt_or_pending`（survey 路由）。`test_host_capabilities_are_seeded` 已隨 G6 基線重產轉綠。
另 5 紅非 FR-134 造成（commit `6df463c1d` 時就是紅）：`test_security_behavior_notify_escaping` 四個參數化案例、`test_package_ui_routes_have_route_capabilities` 的 license-status 項。**多於 7 個就是新卡造成。** runner 常回報「2 紅」，那是跑的範圍較窄，紅數一律以全套實跑為準。
套件基準：jedi-source-scan **155**、jedi-detection 174、jedi-ai-gateway 169。

## §2 已定裁示（不要重新討論）

- **D1** 掃描工具併進既有沙箱，容器數不變；沙箱不出網
- **D3** 只做純靜態解析（讀鎖定檔），缺鎖定檔明確標示
- **D4** 弱點資料獨立更新包；**不做 CLI**；進入途徑：裝機自動、設定頁上傳、連網自動下載
- **D5** CycloneDX＋SPDX 都支援
- **D6 已推翻（2026-10-10）→ R1**：整體風險評級，材料引公開來源、每個結論附判定依據；建議性結論句仍禁。**公式是自家組合、非業界標準，故對外全藏（見 D16）**
- **D16 整體風險評級對外全藏、計算保留（2026-10-11）**：開關 FE `RISK_RATING_VISIBLE`＝false、BE `SOURCE_SCAN_RISK_RATING_VISIBLE` 預設 false，PM 要開再開開關；結果頁、清單、歷次比較、報表、AI 提示都跟著開關
- **D18 畫面不出現「伺服器端」字樣（2026-10-11）**；錯誤碼 `DETECTION_TOOLS_412003` 訊息保留
- **Agent 與 Server**：此工具維持 Server 端執行（隔離、工具形式、弱點庫更新模型三點），不放 Agent
- **任務重掃沿用建任務時的工具快照**（`config.job_execution_detection_tools.tool_params`），D12 之前建的任務重掃沒有 OSV 是設計；畫面已加提示
- **D8** 授權歸既有「檢測工具包」
- **D9** 一個核心兩個入口，同版交付
- **第一版只收上傳**，Git 第二版且**畫面不出現 Git 字樣**
- **UI 自行設計不仿競品**；未實作功能不預告、不留灰入口
- **報表只留完整技術版**（2026-10-11）：顧問會自行消化再交付，不隱藏內部備註，不留樣式選擇；任務回填也用完整版
- **可刪除**（2026-10-11）：受評系統批次刪（連歷次掃描）；掃描紀錄只刪失敗的；任務發起的不從模組刪。**不再做無謂的突變測試**（決策者指示）
- **結果頁三個分頁**（2026-10-11）：風險總覽／弱點明細／元件清單；「SBOM 元件」加工清單拿掉，元件清單＝原始 SBOM 檔攤表（可切格式、搜尋、帶弱點數），原始檔案下載併入；報表「公告」連結改「來源頁」
- **嚴重度上色**（推翻 D2 原設計；顏色是工具分級非系統總評）
- **顯示名改「第三方元件風險」**，內部代號 `source-scan` 不動
- **用語改專業表單用詞**（對照表在 CM-2658 卡尾）
- **新功能能力點走 FR-132 N 類**（由自己的 migration 發給既有 is_admin 角色，逐顆列名）
- **弱點資料庫權限**：`system.vulndb.*` 非平台專屬、列基礎設施；**SaaS 寫入要求平台管理員**
- **188／189 動作、出貨基線重產、正式鑰驗章** → 全部列母卡「上線前檢查」，出貨前一次做
- **決策者要測完整功能**，不要半成品

## §3 未完成清單（決策者 2026-10-11 要求明列；再開工時逐項對）

**arc 休眠。下列每一項都要決策者當次下令才動。**

| # | 項目 | 誰裁／前置 | 備註 |
|---|---|---|---|
| 1 | ~~G3 驗收（CM-2654）~~ | 已 Done | |
| 2 | **整體風險評級（R1）對外開關** | 已裁：全藏、計算保留 | 要露出時開兩個開關（FE `RISK_RATING_VISIBLE`、BE `SOURCE_SCAN_RISK_RATING_VISIBLE`），不需改碼 |
| 3 | ~~G1 SPEC（CM-2652）~~ | 已做，待決策者複測收 Done | `80a5f8eb6`：source-scan 五頁＋system-admin/vulndb.md；流程圖 .dot 圖源照慣例放舊站 `docs/specs/current/` |
| 4 | ~~G2 手冊＋安裝文件（CM-2653）~~ | 已做，待決策者複測收 Done | `67afb114d`：`third-party-component-risk-guide.md`＋onprem 六章＋deployment-env；磁碟數字用實測 4.7GB／更新時 9.5GB／包 480MB |
| 5 | **G4 套件發版**（CM-2655） | 進版前、決策者明示 | jedi-source-scan 首版；jedi-detection／evidence-classification／ai-gateway 進版；主專案還原 pin |
| 6 | ~~出貨基線重產（G6 CM-2674）~~ | 已做，待決策者複測收 Done | `4a7554a3c`；備份 `~/backup/guidant_ai_baseline_20261011_1519_before_CM-2674.dump`；出貨 stamp gate (c) jedi_detection 7 支差異仍要在 188 build 機驗 |
| 7 | **上線前檢查**（母卡卡尾清單） | 進版前 | 189 LC 合 main＋部署（`14e798e`，含 vulndb_manifest 型）→ 正式鑰弱點包（本機 `.build/vulndb/` 留有 20261018 包，清單可重用、只需換 189 簽的 `manifest.sig` 重打包；資料太舊就重跑 `build_vulndb_bundle.sh`）、188 弱點閘放行新沙箱 image、容器內 zstd／volume 擁有者／worker 寫入實測、PDF 字型 NotoSansCJK、安裝包內 vulndb 一份 |
| 8 | **跑版未重現** | 決策者提供條件 | 結果頁右緣被切（決策者截圖）。D8 runner 700～2200px 各條件都重現不出來；若再發生要瀏覽器／縮放／哪筆／側欄狀態 |
| 9 | **外呼守衛盲區** | 待評估 | `test_security_shape_external_calls.py` 看不到 `httpx.stream`，vulndb 下載那支未被涵蓋 |
| 10 | **更新站未定** | 決策者 | `VULNDB_UPDATE_URL` 預設空；`latest.json` 與更新包由誰放哪發布 |
| 11 | **既存紅：任務抽屜 job-evidence 掛點** | 非 FR-134 | `test_feature_capability_matches_backend_guard` 唯一剩餘項，`JobExecutionDrawer.vue` 新增連結掛 read 但打 create／update |
| 12 | **Git 來源第二版** | 未排程 | 畫面不出現 Git 字樣（§8） |
| 13 | **非本 FR 的 5 紅待別的 arc 處理** | 別的 arc | `test_security_behavior_notify_escaping` 四案例、`test_package_ui_routes_have_route_capabilities` license-status 項（見 §1 守衛基準） |
| 14 | **掃描結果加「處理狀態／揭露狀態」欄** | 待決策者裁 | CRA.II.1_obj.4 要求每筆弱點有狀態；鍵用 `fingerprint` 不用 `match_key`（含版本，升版會變新筆）；設計草案見 FR-135 CM-2710 討論稿 `e3ed5ce76` W1 節與衝突① |

**完整手測清單（進版前決策者要跑一遍）**：各卡回寫的手測段彙總——清單頁（勾選批次刪、失敗紀錄清理、列操作圖示）、精靈三步、結果頁三分頁（元件清單切格式／搜尋／弱點數跳轉／原始檔下載）、歷次比較與回訪報告、匯出 HTML／PDF／Word 單一版、任務頁發起掃描（抽屜不顯示 Agent、回填 PDF 有全部弱點列表章）、檢測工具卡只剩徽章、系統設定弱點資料庫（分塊上傳、檢查更新、排程、紀錄）、授權徽章 Copyleft／寬鬆在真資料上尚未看過。

> ⚠️ 本節是待辦清單，不是執行授權。接手讀完盤點完即停，等決策者下令。

## §4 待辦與風險

- **已裁（2026-10-11）：整體風險評級對外全藏、計算保留**（D16）。要露出只開開關。

- **已裁（2026-10-11）：任務發起的掃描在清單看不到 → 採 B 案，開 D7（CM-2661），Done**。反查專案走 canonical `JobProjectOwnershipQuery`；**決策者看畫面後再裁：所屬任務已刪除的掃描不列**（推翻 D7 的「任務已移除」列），併入 D8。權限沿用能力點、不加專案守門（要加須連結果頁一起，另案）。

- ~~route_guards.json 過期~~ **已重產（2026-10-11）**，`test_feature_capability_matches_backend_guard` 只剩既存 JobExecutionDrawer job-evidence 項。重產時抓到三顆寫入鈕漏 v-can，首腦已補（FE `5f5934a3`）。
- **外呼守衛盲區**（B4 回報）：`test_security_shape_external_calls.py` 只看 httpx 呼叫第一個參數，`httpx.stream("GET", url)` 掃不到；下載更新包那支未被守衛涵蓋。待評估是否補守衛。
- **更新站未定**：`VULNDB_UPDATE_URL` 預設空＝不連網；`latest.json` 與更新包由誰、放哪發布未決。
- **授權徽章 Copyleft／寬鬆顏色**未在真資料上看過（DEV 元件授權全為未標示）。
- **完整手測**：各卡打折處（瀏覽器實點、OpenSCAP 列不出連結、閘道關閉時 AI 按鈕不出現）全部併入最後的完整手測清單。
- 上線前檢查清單在母卡卡尾（189 LC 部署、188 弱點包含正式簽章、沙箱 image 重 build 過弱點閘、容器實測、PDF 字型、磁碟 4.7／9.5GB 已寫進安裝文件）。

## §5 Pre-flight（必跑）

```bash
cd ~/Projects/Billows/Audit-Manager/compliance-manager-be
for r in compliance-manager-be compliance-manager-fe; do git -C ~/Projects/Billows/Audit-Manager/$r branch --show-current; done
git -C ~/Projects/Jedicogy/module/jedi-python-package branch --show-current
git status --short                      # 預期只有 pyproject.toml／poetry.lock
ls -la /opt/vulndb/                     # current 要指向有效目錄
docker ps --format '{{.Names}} {{.Status}}' | grep sandbox
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:8000/api/1.0/version
python -m pytest test/security/ test/test_module_boundaries.py test/test_fr132_split_capability_grants.py test/test_migration_stamp_policy.py -q 2>&1 | grep -E '^FAILED|passed'
```
DB 連線與密碼請查 `.env`（`DB_HOST`／`DB_PORT`／`DB_NAME`／`DB_PASSWORD`）。測試帳號密碼在 `compliance-manager-test/.env.e2e`，**不要印出**。

## §6 環境座標

| 東西 | 位置 |
|---|---|
| DEV DB | 本機 `localhost:5432` `guidant_ai_dev`，帳號 cmmgr（見 `.env`） |
| BE | 本機 8000（api）＋ worker；重啟前先查 `public.background_jobs` 沒有 queued／running |
| FE | 本機 5180（`npm run dev`），`.env.development.local` 指向 localhost:8000 |
| 沙箱 | `guidant-sandbox`＋`guidant-sandbox-relay`（127.0.0.1:18080），`docker/dev/source-scan-sandbox.sh` |
| 弱點資料 | `~/.guidant-dev/vulndb`（`/opt/vulndb` 連結） |
| 新套件 | `~/Projects/Jedicogy/module/jedi-python-package/jedi-source-scan/`（path dependency） |
| 設計文件 | `docs/features/FR-134-2610-source-code-sbom-scan/` |

## §7 行為規範提醒

- **只動 DEV**；188／189 一律不碰（上線前檢查另行裁示）
- **不切 branch、不 push**（push 要決策者明示）
- 首腦驗收**只用唯讀 git**；要比對舊版用 `git worktree add` 另開目錄，**不在共用工作樹 stash／checkout**
- 驗收**每張都跑全套守衛＋動到的套件全套測試**，逐條歸因；runner 自報「其餘紅不是我」要查錯誤訊息點名的檔是否在該卡 diff 內
- 驗收**用真資料**（DEV 已可掃出真弱點）；畫面類卡要有瀏覽器實點或併入完整手測
- 開卡前**先 grep 現有程式＋查 `docs/claude/domain-capabilities.md`**再下指令（B4、B2、匯出按鈕、D7 反查路徑四次因沒先查而卡錯；D7 那次索引明禁 `task_assignees` 推專案，runner 自己查到才避開）
- **不可改動產品公鑰表檔**（`jedi_license_runtime/common/public_keys.py`）；手測開發鑰只能在記憶體
- 派工 prompt 第一行寫 model／effort；**可以派的卡一次全部給**，不要一張一張問
- 長工作收工發 `terminal-notifier`

## §8 不在本期 scope

Git 來源（含私有倉庫憑證）、建置型依賴解析（cdxgen）、容器 image 掃描、定期重掃告警、授權合規法律意見、伺服器端自動化任務通用機制（大整理時做）。

## §9 給 fresh session 的短 prompt

```
接手 FR-134（原始碼弱點掃描／第三方元件風險）首腦角色。
先完整讀 docs/features/FR-134-2610-source-code-sbom-scan/handoff/FR-134-STATE.md，
再讀 FR-134-LOG.md 最後一個 block，再 fetch 母卡 CM-2625 卡尾所有追加段。
回答 STATE §0 的五題自檢，跑 §5 pre-flight。
目前現況：功能、SPEC、手冊、出貨基線全部完成且首腦驗收通過，arc 休眠；未進版，G4 發版與上線前檢查等決策者進版令（§3）。
讀取與盤點完成後不做任何事——不派工、不跑測試、不改檔，回報現況後等我下指令才開始作業。
```
