# FR-162 交接現況（STATE）

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

| 項目 | 值 |
|------|-----|
| 最後更新 | 2026-10-26 15:30（第 4 棒收尾：決策者手測通過，規格／手冊／analysis／SUMMARY 已寫，見 `2026-10-26-FR-162-SUMMARY.md`） |
| branch | BE、FE、jedi-python-package 皆 `feature/FR-139`（三 repo 同名 branch，不切） |
| 母案卡 | CM-3057 https://app.notion.com/p/FR-162-403346da4cd0810e9b5ff4fd980ff091 |
| 子卡 | 母卡關聯 26 張：23 張 `驗收通過待確認`、CM-3072／3073 `Done`（決策者跳過）、CM-3100 `修正待驗證`（第 4 棒跨層清空）。證據刪除行為（FR-162.14）首腦直改、**沒開卡**，紀錄在 commit 與 LOG。CM-3097／3098 不在母卡關聯裡，也不在預設任務清單查得到 |
| 本棒角色 | 首腦。決策者第 3、4 棒都明令直接改，首腦在 `feature/FR-139` 改 FE／BE／套件。下一棒：等決策者手測 CM-3100 與刪除行為，回饋照改 |
| Notion 回寫規範 | `docs/claude/notion-issue-tracker.md`；首腦驗收段格式見 `closing-and-handoff` skill「首腦驗收側紀律」 |
| 接手前必讀 | §0 讀序 |

## 🧭 原始需求 / WHY

> 這節寫一次，之後各棒不動。

- **決策者原話（2026-10-24）**：「我們再來新的需求是需要降低 user 重工，像是 NIST 我記得就有發佈他跟 iso27001 的控制項是怎麼關聯的。我們可能要把這種機制建立起來，讓 user 在引入不同框架的時候，就不要一直重複上傳證據，可以用關聯的方式完成多項框架規範。我們系統應該是要到 AO。」
- **演變**：① 原本只做 AO 層 AI 配對 → 決策者指出 CRA、SEMI 控制項層是空的沒起點，加「控制項層初配」模式；② 原本證據「一筆一筆勾」→ 決策者「很蠢」，改專案層一鍵批次為主、任務層單筆為輔、三個提醒點；③ 動作定名「證據沿用」（程式 `reuse`／`REUSED`），與覆核輪「承襲」區分；④ 工作台原為一對一配對 → 決策者指出 5 框架 10 對、10 框架 45 對會爆，改矩陣視圖（主軸 × 並排欄、主軸欄凍結、右側橫向捲）；⑤ 橫幅／提示列關掉後無入口 → 規劃頁與任務 drawer 都加常駐按鈕。
- **目標模型**：對照存 `jedi-oscal-v2` 兩表（對齊 OSCAL 1.2.2 `mapping-collection`，不塞 catalog），鍵用控制項代號與 AO `part_id`，雙粒度，官方層／覆寫層分開（`origin` official／curated／ai-suggested）。證據沿用＝新開一筆 `job_evidences` 同 `file_id`（關聯不複製）。第一版「其他專案」範圍＝同租戶。
- **資料現況**：CMMC↔800-171 恆等（規則生成）、800-171↔800-53（附錄 D）、800-53↔ISO 2022（NIST OLIR，91 個 Annex A 全命中我們 catalog）為官方鏈；CRA 靠 OSA `cra.json`（→800-53）、SEMI 靠 SunSquare 表 2（→62443）二級來源，灌入標 `curated`；官方全不給關係型別。

## §0 接手讀序

### 0.1 🔒 先懂需求 gate
1. 本檔 🧭 WHY
2. `../design.md` **全讀**（D1～D11、矩陣工作台段、證據沿用段、拆分表）；雛形 `../prototype/index.html` 三頁點一遍
3. `docs/analysis/2026-10-24-cross-framework-control-mapping.md` §一～§四、`docs/analysis/2026-10-24-mapping-sources-for-frameworks-without-official-crosswalk.md`（來源三級分級）
4. Notion 母卡 CM-3057 尾段「子卡清單與工作坊批次」與「批次重排」兩段

### 0.2 現況與待辦
5. 本檔 §1、§3
6. `FR-162-LOG.md` 最後 1 個 block

### 0.3 需要細節才開
- 各子卡內文（含卡尾「首腦追加」段，**以卡尾為準**，蓋過內文舊寫法）
- 官方對照檔：決策者桌面 `00_Compliance Manager/07_稽核法規文件/Mapping/`

### 0.4 ✅ 冷接自檢
1. 為什麼對照不塞進 catalog、要獨立兩表？（答：OSCAL Control Layer 三 model 平行；對照會變、catalog 不一定變；多對多帶關係型別與信心度）
2. 證據沿用是複製還是關聯？為什麼不共用同一筆 `job_evidences`？
3. 為什麼工作台是矩陣不是一對一？參考框架為什麼預設隱藏？
4. 批 3／批 4 為什麼拆成單張一批？（答：登記型共用檔）

## §1 當前狀態（2026-10-26 13:40 實查）

**git（三 repo 皆 `feature/FR-139`）**：**全部已 push**（BE 最後 `9a996fd1d`、FE `92b005b5`、套件 `7e475c86`）。BE working tree 別人的改動照舊不碰（一支 memory、`docs/spec-site/site/search/search_index.json`、FR-155／156／163 的 html、`docs/website/support/`）。

**服務**：BE 8000 是 10-26 13:25 重啟的，晚於本棒最後一個 BE commit，已載入新的解析規則與刪除端點。FE 5180 Vite 熱更新。
**套件已發版**（2026-10-26）：jedi-oscal-v2 2.9.0、jedi-file-upload 1.3.8、jedi-compliance-audit 1.4.1、jedi-task-platform 1.4.1 都在 Nexus；BE pin 已對齊、path 已還原，venv 四支都是正式版（無 editable）。BE 8000 用正式版重啟過。

**Notion**：母卡 CM-3057 與 28 張子卡（CM-3058～3082、3097、3098、3100）全部 `Done`（決策者 2026-10-26 令）。誤建在工作坊任務清單的 #65 已移到垃圾桶。

**DEV**：
- 對照有效列：official 1,143／third-party 282／ai-suggested 905／curated 2。**有效跨層列 0**（原 12 筆已停用，remarks 註明；備份在本棒 scratchpad）。
- 套件 migration 到 026；主線新增 `2026-10-26-fr162-job-evidences-not-applicable.sql`（已套 DEV 並登記）。
- 有效 `REUSED` 列 7；軟刪 REUSED 3,745 筆全是 `USER_DELETED`（歷史清理），`NOT_APPLICABLE` 0 筆。
- `upload_files` sha256 空 2,619／4,888（照舊）。

**守衛**：BE `test/test_module_boundaries.py` 3 紅照舊。FE vitest 157 綠 1 紅照舊（`zh-tw-no-bare-oscal-abbr`，5 筆都在其他檔）。

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

| 裁示 | 何時 |
|---|---|
| D1 對照表進 `jedi-oscal-v2`（「這應該是套件功能」） | 2026-10-24 |
| D2 鍵用控制項代號（`control_id`）＋ AO `part_id`，不綁數字 id | 2026-10-24 |
| D4 證據重用走跨專案沿用，不做一專案多框架 | 2026-10-24 |
| D8 AO 層要由系統分析（AI 兩模式：控制項層初配＋AO 配對）；CRA／SEMI 先灌二級來源再 AI 補洞 | 2026-10-24 |
| D9 專案層一鍵批次為主、單筆為輔（「一筆一筆勾很蠢」）；定名「證據沿用」 | 2026-10-24 |
| D10 三個提醒點＋**常駐入口按鈕**（規劃頁、任務 drawer），橫幅／提示列只是提醒 | 2026-10-24 |
| 工作台＝矩陣視圖，主軸欄凍結、右側橫向捲，參考框架預設隱藏 | 2026-10-24 |
| 點膠囊開**置中對話框**（捨棄抽屜；下方詳情區／寬抽屜同屬常駐面板一樣要開關，理由不成立）| 2026-10-25 |
| 畫面狀態只顯示「**通用／部分可用**」兩種，「不可用」只當動作名；術語留 DB／匯出 | 2026-10-25 |
| 膠囊不標「間接」，轉乘路徑只在對話框「路徑」段 | 2026-10-25 |
| 信心分數：第三方／AI／顧問顯示，官方不顯示（不顯示「未給」） | 2026-10-25 |
| 沿用入口＝專案總覽「證據作業」下拉（AI 自動分類／雲端資料夾／沿用其他專案）；規劃頁按鈕與橫幅移除 | 2026-10-25 |
| 沿用＝一個來源專案一份設定，隨時調整、可全部取消、每次留唯讀紀錄；**不做批次、不做復原某一次**（CM-3072／3073 跳過） | 2026-10-25 |
| 來源範圍＝**使用者可見的專案**（owner／參與者／admin），排除封存；「同租戶」改判（跨組織單位外洩） | 2026-10-25 |
| 選來源要看得到授權邊界，畫面不標「SSP」；按鈕文案「選擇來源專案」 | 2026-10-25 |
| 調整頁三欄可拖；左欄照規劃頁三層導航（搜尋、全部展開／收合）、預設篩選「有對應的」、排序照目錄 | 2026-10-25 |
| 重複證據不硬擋：同檔多 AO 畫面標「也掛在 N 處」、上傳同內容提示；地基是上傳統一算 sha256（套件 jedi-file-upload 可動）＋回填 | 2026-10-25 |
| 二級來源（OSA、SunSquare）灌入標 `curated` 不標 `official`，報告如實標來源 | 2026-10-24 |
| 「先出一版來看看」，雛形審過 | 2026-10-24 |
| 頁面改名「控制項關聯管理」 | 2026-10-25 |
| **對照只能同層**：控制項對控制項、評估目標對評估目標；拖曳只能同層、放下就是「搬」（無複製） | 2026-10-25 |
| 控制項層有對應、評估目標層沒細分＝**目標控制項全部評估目標都適用**（與證據沿用同規則）；評估目標列直接把它們全部列出（虛線膠囊），**只顯示不寫資料**；使用者刪或搬其中一顆時才把整組寫成逐條 curated | 2026-10-25 |
| 已細分到某目標控制項部分評估目標的列，該控制項的控制項層命中不再算「全部適用」（矩陣與沿用同規則，共用 `refined_targets`） | 2026-10-26 |
| 人工新增一律「通用」、信心 1，不讓使用者填 | 2026-10-25 |
| 「重建」改「還原出廠設定」＝主軸 × 一欄只留官方與第三方，顧問與 AI 列停用不刪（清掉覆寫指向讓官方列回來）；「以檔案取代」拿掉（就是匯入） | 2026-10-25 |
| 「產生 AI 建議」對所有人隱藏（含超級管理員）；OSCAL 匯入匯出隱藏；都是 `controlMappingUtil.js` 的開關 | 2026-10-25 |
| 每格可「清空」；膠囊可 ×；格尾＋與清空靠右 | 2026-10-25 |
| 關聯表 Excel：匯出主軸對全部框架（選單文字「下載當前主軸框架設定」）、給人看的版面、匯出再匯入零變動 | 2026-10-26 |
| 工具列兩列（上：搜尋／篩選／排序；下：展開／欄寬／全螢幕 ｜ 批次作業／維護）；欄寬「自動符合／平均分配」 | 2026-10-26 |
| 新增對應／加入評估項目共用同一個挑選器 `AOPickerDialog`，**左右兩欄（方案 D）**：左群組→控制項、右勾選、底列已勾 | 2026-10-26 |
| 分段按鈕一律 `SegmentButtons`（照待辦任務頁、size small），不自刻、不用 SelectButton | 2026-10-26 |
| 沿用提示從按鈕列移到總覽流程列下方（`EvidenceReuseHint`） | 2026-10-26 |
| 「清空這格」在評估目標列照同層逐條寫，不開「評估目標→控制項」例外；套件解析器改判（評估目標層排除也擋控制項層退路）放行 | 2026-10-26 |
| 證據刪除只動當下，不連帶其他專案；同專案多處掛同一份檔讓使用者選「只這一處／本專案全部」 | 2026-10-26 |
| 沿用來的證據刪了＝本專案此處不適用，沿用建議不再帶回；調整頁看得到、勾得回 | 2026-10-26 |
| 沿用是關聯不是複製；來源被刪下游照常可用，只標「來源已移除」 | 2026-10-26 |
| `job_evidences` 不開 RLS（背景與系統脈絡路徑太多，收益小） | 2026-10-26 |
| 沿用頁：控制項層對應與評估目標層一視同仁，「通用」就預設勾；按鈕改「一鍵勾選通用對應（N）」，N＝0 停用 | 2026-10-26 |

## §3 下一步

**1. 已收尾**（2026-10-26）：決策者手測通過；規格三頁、使用手冊、決策分析、SUMMARY 已寫並 commit。剩下的是下方待裁與 Notion 卡片收 Done（決策者的事）。

**待決策者裁**（問之前先查卡與 LOG）：
1. 挑選器左樹是第 8 份手刻導航樹；抽共用樹元件要另開 FR（決策者 10-25 裁「之後再做」）。
2. 全站另有 13 檔手刻分段按鈕，要不要收斂到 `SegmentButtons`（另案）。
3. 後端舊 `POST /oscal/control-mappings/rebuild` 端點還在（畫面已無入口），要不要刪。
4. 守衛紅：套件 `control_mapping_resolution_service.py` domain→infra import 要不要開小卡修。
5. 三冊 provenance 無網址（128、127、131）補 url；NIST SP 800-82 r3 換一級來源。
6. **出貨基線**：主線 `phase=active` migration（CM-3061、CM-3062、AI 能力點、本棒 not-applicable）＋套件 026 要進下一包基線——決策者 2026-10-26 定**發版前做**。

> ⚠️ 這節是建議清單，不是執行授權。接手方讀完盤點完即停，等決策者發令。

## §4 待辦與風險

- **1a 解析服務是否含批次版**：卡上寫的是單筆 `resolve`；矩陣端點（2a）需要 `resolve_many`。推測 1a 不會自己加，驗收時確認。
- **OLIR 的 Clause 條文列**（204 列對到 ISO Clauses 4～10）：我們 ISO catalog 只有 Annex A，1b 要標 `remarks='clause'` 存著。Clauses 建模屬 ISO 導入設計待拍板。
- **62443→800-53 沒有官方直接對照**（決策者 2026-10-24 追問後確認）：優先 NIST SP 800-82 r3 附錄（**待決策者下載**到 `Mapping/`，連結在 analysis §四）＞ ISAGCA↔CSF 再接 NIST CSF↔800-53 xlsx ＞ OSA 社群。CM-3060 卡尾已寫優先序；1b 回寫會說實際用哪個。
- **AI 配對準確率未實測**：批 7 跑完抽查三條。
- **「同租戶」範圍**：多資訊系統客戶可能看到不相干專案，由選來源專案那步排除；資訊系統過濾等 ISO 資產設計。
- **AO 的 `_obj.N` 是我們依匯入順序編的**：框架重匯順序變會對錯，mapping 綁框架版本可隔離，但同版本重匯要留意。
- **SMCC WG4 官方比較分析**出來後要換掉 SunSquare 二級來源。
- **CRA 群組順序**：Annex VII 在 Art.13 前面是框架資料 `sort_order` 的事，不是程式錯（11a 復核已標）；真要調改 CRA 框架資料（`cra-framework` skill 範圍）。
- **11c「全部取消」只用模擬回應測**，DEV 沒真刪；可在 DEV 實測一次。
- **展開／刪除／搬移／新增四個動作都依賴同一個陷阱**：評估目標列一有任何評估目標層列，解析器就不再退回控制項層，帶出的那組會消失。所以 FE 在 ×、拖曳、挑選器新增前都先呼叫 `POST /oscal/control-mappings/entries/expand` 把整組寫成逐條。新增任何會寫評估目標層的入口都要照做。標不可用、清空不用：評估目標層的排除本身就擋得住控制項層退路，後端也會把評估目標→控制項的直連展開。
- **「不適用」只認 `NOT_APPLICABLE`**：調整頁拿掉、全部取消、歷史清理都寫 `USER_DELETED`，別拿它判不適用，否則整輪沿用建議會一起消失。新增任何「從任務移除沿用證據」的入口，原因值要寫 `NOT_APPLICABLE`。
- **評估目標字母不是 `_obj.N`**：ISO A.5.1 的 [a] 是 `_obj.3`；字母只能從評估目標文字開頭的 `[x]` 取。
- **證據沿用頁 ISO × SEMI 全是第三方「部分可用」**（56 條），「一鍵勾選通用對應」會是 0、按鈕停用——不是壞掉。
- **挑選器 `AOPickerDialog` 三處共用**（控制項關聯管理、證據沿用、AI 自動分類），改它要三處一起看；`ControlMappingEntryDialog` 只是轉資料格式的包裝。
- **AI 建議與 OSCAL 只是畫面隱藏**，後端端點與能力點守門照舊。

## §5 Pre-flight（必跑）

```bash
cd ~/Projects/Billows/Audit-Manager/compliance-manager-be
git branch --show-current && git log --oneline -3 && git status --short | grep -v '^??'   # 別人的改動在，不碰
git -C ~/Projects/Billows/Audit-Manager/compliance-manager-fe log --oneline -2
git -C ~/Projects/Jedicogy/module/jedi-python-package status --short
# Notion 實況（不要信本檔快照）——撈母卡全部子卡 Stage／狀態
python3 - <<'PY'
import sys; sys.path.insert(0,"/Users/chouraymond/Projects/Jedicogy/agent-workshop/scripts"); import notion_case as nc
pg=nc.notion_request("GET","/pages/403346da-4cd0-810e-9b5f-f4fd980ff091")
for r in pg["properties"]["子卡"]["relation"]:
    k=nc.notion_request("GET",f"/pages/{r['id']}")["properties"]; print(k["Stage"]["number"], "CM-%s"%k["Case No"]["unique_id"]["number"], (k["狀態"]["status"] or {}).get("name"))
PY
# DEV（密碼在 .env DB_PASSWORD）
psql -h localhost -p 5432 -U cmmgr -d guidant_ai_dev -c "select count(*) from oscal.control_mapping_entries where status='active' and source_level<>target_level;" -c "select origin, count(*) from oscal.control_mapping_entries where status='active' group by 1;"
# BE venv 的 jedi-file-upload 應是 editable（套件原始碼）；不是的話 BE 會起不來
.venv/bin/pip show jedi-file-upload | grep -i editable
# 8000 跑的是不是最新：比對進程啟動時間與最後合回 commit 時間
ps -o lstart= -p $(lsof -nP -iTCP:8000 -sTCP:LISTEN -t | head -1); git log -1 --format=%ci
```

## §6 環境座標

- DEV DB：本機 `localhost:5432` `guidant_ai_dev`，帳號 `cmmgr`，密碼查 `.env` 的 `DB_PASSWORD`。只動 DEV。
- 套件：`~/Projects/Jedicogy/module/jedi-python-package/jedi-oscal-v2/`（2.8.0，未發版）；BE 走 path dependency 時 `pyproject.toml` 第 139 行取消註解、第 85 行 pin 註解，**不 commit 那段**。
- 套件 migration 套 DEV：`psql --single-transaction -v ON_ERROR_STOP=1 -f <檔>` 後手動 `INSERT public.schema_migrations(filename, note)` 登記 `packages/jedi_oscal_v2/<檔名>`。
- 官方對照檔：決策者桌面 `00_Compliance Manager/07_稽核法規文件/Mapping/`（OLIR xlsx、CSF xlsx、ENISA pdf、OSA json、EUCC 附錄、SMCC 白皮書、METI 指引、SunSquare 三圖）；800-171↔800-53 表格版在 BE `common/util/input/NIST_800-53_to_800-171.xlsx`。
- 雛形：`docs/features/FR-162-2610-cross-framework-control-mapping/prototype/index.html`（雙擊可開；定案版是 `mapping-side-panel.html`、`project-reuse-page.html`、`picker-and-toolbar.html`——最後這頁是第 3 棒的挑選器四方案比較＋工具列＋欄寬，決策者選 D 與二、三節）。私人 artifact：https://claude.ai/artifact/YZpZhazEKKs8s7F6zTBDWX
- FE 關鍵檔：`src/views/control-mapping/`（矩陣頁）、`src/views/evidence-classification/components/AOPickerDialog.vue`（共用挑選器）、`src/components/common/SegmentButtons.vue`、`src/views/evidence-reuse/`、`src/views/project/EvidenceReuseHint.vue`、`src/components/grc/job-drawer/JobEvidenceDeleteDialog.vue`（刪除說明框）。
- 需求站：`python scripts/deliverables/render_index.py docs/features/FR-162-2610-cross-framework-control-mapping/`。

## §7 行為規範提醒

- 首腦不開 subagent、不自己做卡；派工由決策者在工作坊按。
- **雙重驗證**（決策者 2026-10-25）：工作坊首腦先驗、改 `驗收通過待確認`；本線首腦做第二道檢查，不重做手測、只核對（卡上復核段與打折、該卡測試、守衛、DEV 數字、FE grep、8000 版本）。驗完回報固定附任務總表。
- 開新卡前**先 fetch 母卡全部子卡實況**排批次，不用本檔快照；排完用腳本掃卡內文檔名求同批交集（登記型檔撞到就分批）。
- push 等決策者；三 repo 不切 branch；working tree 別人的改動不碰。
- 套件不 bump 版本、不發版、不推 Nexus。
- 主線 `phase=active` migration（CM-3061 能力點、CM-3062 job_evidences）回寫要講「出貨基線待重產」。
- UI 禁左側粗色邊框；超標檔（`JobExecutionDrawer.vue`、`ProjectPlanningView.vue`、`ProjectAuditorOverview.vue`）只准新開子元件。
- **🔴 動 UI 前先查全站現成的**（第 3 棒被點名三次）：分段按鈕用 `SegmentButtons`、代號用 `tag-code`、字級只用 0.75／0.875／1rem、不自訂 `font-family`、顏色只用 token（決策者用淺色主題，寫死色碼會跟主題脫節）、導航樹先看 `ApObjectiveTree`／規劃頁樹。權限判斷只用 `v-can`／`$can`（`v-can-guards` 守衛會擋 `hasCap(`）。
- **雛形做了就要照它實作**：第 3 棒雛形與實作長不一樣被決策者點名「那做雛形幹嘛」。
- **交出前自己先看畫面**：靜態頁截圖（`node <scratchpad>/mock.cjs <html> <png>`，Playwright 在 test repo）至少能驗版面；本棒多次只靠 build 就回報，被抓到看不出差別、按鈕太大、間距擠。

## §8 不在本期 scope

- 一專案多框架；ISO Clauses 4～10 建模；資訊系統過濾；自動從 NIST／ENISA 抓更新；CRA／SEMI 的「官方」等級對照（沒有）。

## §9 給 fresh session 的短 prompt

```
你是 FR-162 跨框架控制項對應的首腦（分析決策／協調），接手第 5 棒。上一棒修了跨層清空（CM-3100）並直改證據刪除行為，兩件都等決策者手測。
先讀 docs/features/FR-162-2610-cross-framework-control-mapping/handoff/FR-162-STATE.md（含 §0 讀序與自檢、§7 行為規範），
再讀 FR-162-LOG.md 最後一個 block（第 4 棒）。讀取與盤點完成後不做任何事——不派工、不跑測試、不改檔，
回報①自檢答案②現況盤點（與 STATE 不符處）③「待辦已就緒等發令」，等我下指令才開始作業。
```
