# FR-162 交接紀錄（LOG）

> **append-only**：每棒收工追加一個 block，既有 block 永不改。發現舊 block 有誤，在新 block「推翻了什麼」欄更正。現況看 `FR-162-STATE.md`。

## 第 1 棒 — 2026-10-24 — 首腦（分析、設計、開卡、雛形）

**做了什麼**
- 盤點：v2 無跨框架對照；v1 `oscal_control_mapping` 已退役且無業務呼叫點；`source_identifier` 是同框架跨版本代號；OSCAL 1.2.2 `mapping-collection` 的 `mapping-item.type` 可指 part，AO 層合規。
- 官方對照盤點（含網查、決策者下載 8 份檔）：CMMC↔800-171 恆等；800-171↔800-53 附錄 D；800-53↔ISO 2022 NIST OLIR（91 個 Annex A 全命中）；CRA 官方只對 Common Criteria（ENISA EUCC 附錄），對 800-53 有 OSA 社群 36 條；SEMI 官方無，SunSquare 第三方 12 條對 62443、METI 對 CSF。官方全不給關係型別。
- 文件：兩份 analysis、design.md（D1～D11）、README、三頁雛形、FR 登記；Notion 母卡 CM-3057 ＋ 九張子卡 CM-3058～3066（四欄齊）。
- 順手發現：`catalog_service.py:90` 預設 `oscal_version="1.1.2"`，DEV 53 筆錯標 → 開 CM-3059。

**commits（BE `feature/FR-139`，未 push）**：`c26eb5a6b` `4042d936c` `8ce3a4d5a` `939f329dd` `6c2793322` `435d1b9da` `86c6cb09a` `3e9152e16` `df4505b38` `c42d0f6a7` `d96ea1043` `c73bf133c` `d39d17774` `54c43b443` `a9d2f7eca` `5e438892a`

**關鍵決策**（決策者裁）：對照進套件；鍵用控制項代號；跨專案沿用不做一專案多框架；AI 兩模式（控制項層初配＋AO 配對）＋規則回填關係；專案層一鍵批次為主；定名「證據沿用／reuse」；工作台矩陣視圖、主軸凍結、參考框架隱藏；常駐入口按鈕；二級來源標 `curated`；「先出一版」。

**推翻了什麼**
- 第一版只做 AO 層 AI → 決策者指出 CRA／SEMI 控制項層空，加模式 B。
- 第一版任務層單筆勾選 → 改專案層批次為主。
- 第一版工作台一對一配對 → 改矩陣。
- 第一版「CRA、SEMI 真的沒對照」→ 重查後 CRA 有官方（對 CC）與社群（對 800-53），SEMI 有第三方（對 62443）。
- 第一版五批 → 2a／3a、2b／3b／3c 各改同一登記型檔，重排七批。

**教訓**
- **雛形要在 design 前**：我跳過雛形直接開卡，決策者看雛形後改了三處（矩陣、凍結欄、常駐按鈕），每處都要回頭改 design 與卡。照規範先雛形，這些在開卡前就會抓到。
- **分批要逐張問兩題**（用到誰的產出／改到同一檔），「不同模組」不等於「不同檔」——error code 表、migration manifest、FE api.js／locales 是登記型檔，任何兩張卡同時加列就撞。
- **「真的沒有官方對照」要查到檔為止**：第一輪網查結論太早下；決策者說「我記得有」就該再找一輪，結果 CRA 有、SEMI 半有。
- **提示類 UI 必配常駐入口**：橫幅／提示列可關閉或會消失，關掉就沒入口是設計洞。

**未驗證假設**（交給下一棒驗收時對照）：1a 是否做批次 `resolve_many`；OSA `iec-62443.json` 代號是否對得上 SunSquare；AI 配對準確率。

**派出／收回**：批 1（CM-3058、CM-3059）由決策者在工作坊派出；本棒無收回。


## 第 2 棒 — 2026-10-25 — 首腦（規格補路線圖與來源、第 9 輪開卡）

**做了什麼**
- 接手時盤點：STATE 寫批 1 剛派，實查批 1～11 已由工作坊首腦驗收完畢（CM-3058～3071 皆 `驗收通過待確認`），CM-3072／3073 暫緩；本棒「驗收批 1」任務已過時，改做規格補強與新一輪開卡。
- design.md 新增「各框架怎麼轉到 ISO 27001：轉乘路線」節：圖 3（實線官方、虛線第三方）、路線表、與第 1 棒同日補的每跳來源公信力表合併；再補 DEV 實灌九冊表（含 AI 直達冊 267／268）、OSA 官網與 GitHub 檔案路徑、SunSquare 文章完整網址；origin 由三值對齊成四值（third-party，套件 024）。
- 第 9 輪開卡（決策者工作台實測五個問題）：CM-3074 9a／3075 9b（BE，批 14）、3076 9c（FE，批 15）、3077 9d（FE，批 16），四欄齊、已接母卡、母卡尾段 append 批次清單。開卡腳本 `gen_notion_cards_r9.py`／`patch_workshop_fields_r9.py`。

**commits（BE `feature/FR-139`）**：`78187f451`（圖 3）、`5ab551010`（DEV 實灌表、網址、origin 四值）、本次開卡 commit。

**關鍵發現（已核對）**
- 問題 1 根因：五框架間無直接對照、全經 800-53 中轉，ISO×CRA 每格皆兩跳；FE `ControlMappingSidePanel.vue` 對 `hops>1` 一律唯讀，BE `override`／`disable` 只作用最後一跳邊。解法不是改中繼邊，是在主軸↔目標建 curated 直連（解析規則 6「hops 最少優先」會蓋過多跳；`not-related-to` 當刪除）。
- 問題 3 根因：`catalog_controls.sort_order` 是群組內序號（ISO 93 條只 37 個相異值），套件 `get_by_catalog` 全表 `ORDER BY sort_order` 讓群組首條交錯；`get_by_catalog` 有 7 個呼叫者，改在主專案 `mapping_common._load_catalog` 讀取端排序，不動套件。
- 問題 4／5：`AXIS_REM=24`／`COL_REM=18` 寫死＋`fit-content`；全螢幕先例 `FilePreviewDialog.vue` 的 `maximizable`。

**推翻了什麼**
- 第 1 棒 2667e52a9 的來源表把二級來源標 `curated`，與套件 024 之後的實作（`third-party`）不符，本棒對齊；design.md D5、DDL、不做段同步。
- STATE 寫「未 push 18 個」，實查 origin 已與 HEAD 一致。

**教訓**
- **接手前先 fetch 卡狀態再信 STATE**：STATE 是交棒當下的快照，工作坊多個 session 平行推進時幾小時就過期；本棒開場盤點與一小時後重查，DEV 從「無表」變成「九冊」。
- **分批時兩張 FE 卡改同一個 i18n 檔就不能同批**：9c／9d 都改 `control-mapping.json` 與 `ControlMappingMatrixTable.vue`，拆成批 15／16。

**未驗證假設**：9a 用直連 curated 列蓋多跳的做法，解析器規則 6 在「同目標、直連 1 跳 vs 多跳」的確取直連（讀碼推斷，runner 寫測試驗）；9d 全螢幕 Dialog 疊 Sidebar 的 z-index 要實測。

**第 10 輪（同日續）**：決策者審側面板退回。討論：容器三案（對話框／下方詳情區／寬抽屜）→ 決策者裁對話框，首腦原推下方詳情區的「不用一直開關」理由被駁（常駐面板一樣要開關）；狀態文案三輪（部分重疊→符合／部分符合→通用／部分可用），決策者定「通用／部分可用」，「不可用」不是顯示狀態；內容七塊。開 CM-3078（10a BE）／3079（10b FE），9c append 縮範圍。commits `bafc108b9`、`f8f786aca`。

**教訓（第 10 輪）**
- **文案要從「使用者在這格要做什麼決定」出發，不是列同義詞**：第一批（可參考／部分符合／需補強）被決策者點名「幾乎都沒認真想過」；改從「舊證據拿來能不能過」出發才收斂。
- **「資料庫有什麼就顯示什麼」不是設計**：側面板倒出五個欄位，真正有價值的（兩邊條文、誰說的、怎麼轉）一樣沒放；設計面板先問「點開的人要回答什麼問題」。
- **替代方案要先驗它跟被退方案的本質差別**：下方詳情區／寬抽屜與抽屜同是常駐面板，決策者一問「乙跟抽屜有什麼差別」就倒。

**第 11 輪（同日續）**：決策者實測規劃頁沿用對話框退回四點。首腦探脈抓到真 bug：來源範圍「同租戶」把另一組織單位的鼎盛專案列進來（使用者列表看不到卻能拉它的證據），屬跨組織單位資料外洩，也解釋 CM-3072 那次 3,599 筆爆量；封存專案也沒排除。定案（design D9／D10／D11 改判）：入口「證據作業」下拉；比照自動分類做獨立三頁；一來源一份設定不做批次、每次調整留唯讀紀錄；可見性照 `_visible_project_ids`。開 CM-3080（11a BE，資安優先）／3081（11b FE 入口）／3082（11c FE 三頁）。CM-3072／3073 決策者在工作坊跳過。commits `e5ae16fe2`、本次。

**教訓（第 11 輪）**
- **「同租戶」不等於「使用者看得到」**：RLS 只擋租戶，組織單位與參與者可見性在應用層；任何「列其他專案給使用者選」的功能都要走專案列表那套可見性，不能自訂範圍。D11 當初寫「第一版＝同租戶」就是沒查可見性模型。
- **「3 個選項只有 2 個專案」要查到人**：先假設是封存沒排除，實查 DB 才發現是別的組織單位的專案；資料面查到底才知道是資安問題不是 UI 小 bug。
- **開卡後決策者一問「有正確分批嗎」才實查：11b／11c 撞 api.js／router／menu.json 三個登記型檔**，原排同批是錯的，改 11c 先、11b 後。分批要用腳本掃卡內文列到的檔名求交集，不憑「不同模組」判斷——這是 LOG 第 1 棒就寫過的教訓，第 2 棒又犯一次。
- **決策者連續簡化三次**（批次→一份設定→只要紀錄→紀錄放彈窗）：先問「user 反悔時要做什麼」再設計資料模型，批次 id 整套是為沒人要的「復原某一次」做的。

**第 12 輪（同日續）**：決策者問重複證據。查明三種情境（同任務同檔已有唯一索引擋；同檔多 AO 是關聯模型本身，254 檔最多掛 56 任務；同內容不同檔要靠 sha256 但 96% 空、全專案無上傳路徑在算，MinIO adapter 只算 md5）。定案不硬擋、看得見＋地基補 hash；決策者同意動套件 jedi-file-upload。開 CM-3097（12a 套件＋BE 回填，批 22）／3098（12b BE 加欄＋FE Tag 與上傳提示，批 23）。

**推翻了什麼（第 12 輪）**
- 我的 STATE／任務總表停在「批 14 待驗收」，決策者一問才 fetch 實況：批 14～21 全部已驗收通過待確認、11c 已合回。開新卡前**必須先 fetch 母卡全部子卡的 Stage 與狀態**，不能用自己手上的快照排批次（又一次「STATE 是快照、工作坊平行推進幾小時就過期」）。

**第二道檢查（第 9～11 輪，決策者定雙重驗證）**：九張卡的「首腦復核」段都在且有打折處；六支新路由實打 401（存在）；四支新測試檔 43 條綠；origin 四值分佈正常；事件碼已登記；FE 側面板與規劃頁沿用元件已刪、無「間接」、無粗左框、沿用頁無 SSP。**抓到三件工作坊首腦沒標的**：①守衛 `test_module_boundaries` 1 支紅是 FR-162 自己的（套件 resolution service domain→infra import，CM-3058 起就在，歷棒都寫「開工前就紅」）；②ISO 專案 3,741 筆有效 REUSED 列（19:54 blsadmin 寫），比 3072 清掉的還多，來源未查；③共用 8000 跑 18:18 舊程式，工作坊首腦是另起 8034 驗的——決策者要邊測，本棒已重啟 8000。

**頁面改名**：決策者「框架對照這個名稱好爛」→ 候選後定「控制項關聯管理」（「管理」把可編輯講出來）。FE i18n 13 處＋BE seed migration 改 `ui_routes`／能力點描述，已套 DEV。commits FE `431b1ffc`、BE `3ada4f2ed`。

**本棒 commits（BE `feature/FR-139`，未 push）**：`78187f451` `5ab551010` `49e2cebc9` `bafc108b9` `f8f786aca` `7a862cdea` `e5ae16fe2` `d7b4b4948` `be3aecf35` `98dd936ea` `86c733d6f` `3ada4f2ed`；FE `431b1ffc`。

**教訓（收尾補）**
- **第二道檢查要看「歷棒都說與本卡無關」的紅**：每棒各自對比自己的 diff 說守衛紅不是我造成的，沒人回頭問「那是誰造成的」——跨棒累積的紅只有首腦看得到全貌。
- **共用 8000 不等於決策者看到的版本**：runner 與工作坊首腦都另起埠驗，8000 可能停在幾小時前；決策者說要邊測，先比對進程啟動時間與最後合回時間。

**派出／收回**：第 9～11 輪九張由決策者在工作坊派，全部驗收通過待確認（工作坊首腦驗、本棒二檢）；第 12 輪 CM-3097 `In progress`（runner 在套件主線直接改）、CM-3098 待派；本棒無收回。

## 第 3 棒 — 2026-10-25 21:30 ～ 10-26 11:30 — 首腦（決策者令「直接改」，主線直改 FE／BE／套件）

**做了什麼**
- 接手盤點：CM-3097 已轉修正待驗證但 BE 段在 worktree 未合回；3,741 筆 REUSED 查出 3,740 筆是 10-25 00:13 CM-3072 爆量殘留。
- 決策者在 5180 實測後逐項口頭裁示、令首腦直接改（未開卡、未經工作坊），約 30 個 commit：
  - 控制項關聯管理矩陣：膠囊帶名稱、有對應的格也能＋／×、群組帶編號、拖曳直接生效且只能同層搬、每格清空、評估目標列直接列出控制項層帶出的全部評估目標（只顯示不寫資料，刪／搬／新增前才 expand）、左欄編號名稱兩行、欄分隔線、欄頭拖曳排序、欄寬自動符合／平均分配、工具列兩列、批次作業／維護兩個選單、還原出廠設定（停用不刪、清覆寫指向）、AI 建議與 OSCAL 隱藏、新增對應改多選挑選器。
  - 共用挑選器 `AOPickerDialog` 改左右兩欄（雛形四方案中決策者選 D），三處共用。
  - 證據沿用：右欄依控制項分組、中欄檔案可預覽、挑選器顯示正在歸檔的檔名、沿用提示移到流程列下方、控制項層對應與評估目標層一視同仁、按鈕改「一鍵勾選通用對應（N）」。
  - 關聯表 Excel 重做版面（機器鍵藏第 5 列，匯出再匯入零變動），匯出主軸對全部框架。
  - 套件 jedi-oscal-v2 026：CRA.A2.8 的 17 條評估目標→控制項跨層列改成 12 條控制項層（已套 DEV）。
  - 抽 `SegmentButtons`（照待辦任務頁、small），修好 FE `v-can-guards` 守衛紅（CM-3076 起就紅）。

**commits**：BE `6aa56172b` `42265a3cf` `108d27e87` `c3be5af8f` `333ba9da0` `ff82e549b` `053ff6884`；套件 `1ef1403b`；FE `f68c143a` 起至 `5a9499a3`（約 27 個，`git log --grep=FR-162` 可列）。都未 push。

**關鍵決策（決策者裁）**：只能同層對；控制項層有、評估目標層沒細分＝全部評估目標適用，顯示不寫資料；人工新增一律通用、信心 1；重建＝還原出廠設定；分段按鈕統一。全部已寫進 STATE §2。

**推翻了什麼**
- 第 2 棒「AI 建議原廠限定」靠能力點 is_platform——super_admin 帳號 break-glass 仍看得到；決策者改裁「先對所有人隱藏」。
- 我自己：承繼對應先做成「點了展開就寫資料」→ 決策者指出證據沿用本來就全部給、展開不必寫 → 改成只顯示；再被裁「不要分群不要收合，全部列出」。
- 我自己：控制項層刪除排除會連帶評估目標，原以為「逐顆標評估目標」就能清空，DEV 試跑發現藏在後面的多跳控制項層對應會重新冒出來，改寫控制項層不可用——結果在評估目標列寫出跨層列（**本棒留下的阻斷 bug，STATE §3 第 1 項**）。

**教訓**
- **動 UI 前先查現成的，記憶裡就有**：分段按鈕（`feedback_list_page_filter_baseline_my_tasks`）、導航樹（`feedback_fe_nav_tree_rewritten_per_page_reuse_first`）兩條記憶都早寫了，我還是自刻 `.cm-seg`／`.ao-seg` 與第 8 棵樹，被決策者連續點名「到底為什麼」「這頁到底自己刻了多少東西」。
- **只靠 build 就回報＝把驗證丟給決策者**：欄寬兩模式看不出差別、按鈕太大、間距擠、主軸被撐寬，都是決策者看了才發現。靜態頁截圖幾秒鐘就能看出來。
- **寫死色碼與自訂字型在淺色主題下會脫節**：決策者用淺色主題（奶油底），token 會跟著切、寫死的不會。
- **雛形與實作要一致**：雛形是「群組 → 控制項」兩層、群組顯示 A.5，實作卻顯示 `ISO27001-A5`，決策者「那做雛形幹嘛」。
- **「_obj.N」不是字母序**：ISO A.5.1 [a]＝`_obj.3`，拿數字當字母會標錯；字母只能從文字取。
- **解析器的「有評估目標層就不退回控制項層」是所有寫入入口的共同陷阱**：×、拖曳、新增、清空都踩過一次。
- **群組不能拿顯示代號當鍵**：ISO 群組顯示代號被藏起來後是空字串，四個群組同一個鍵、點一個全選。
- **工作坊合回會讓 BE 起不來**：CM-3097 合回 import 了未發版套件函式，venv 還是舊版；先查 venv 再重啟。

**未驗證假設**：所有 FE 改動沒有實際登入看過（本機無可用 auth-state）；「專案規劃進不去」原因未明，可能來自同日 FR-164 對總覽頁的大改。

**派出／收回**：本棒無派工、無開卡；CM-3097／3098 已由工作坊首腦驗收通過待確認並合回，本棒未做第二道檢查（決策者改要直接改頁面）。

## 第 4 棒 — 2026-10-26 11:40 ～ 13:40 — 首腦（決策者令「直接修」：跨層清空＋證據刪除行為）

**做了什麼**
- 接手盤點：「專案規劃進不去」決策者回報已好，結案。
- **跨層清空（CM-3100，`修正待驗證`）**：根因在套件解析器——排除判定只比同一節點或控制項層排除，評估目標層的不可用擋不住多跳的控制項層退路，前一棒只好寫跨層排除列。套件 `_is_excluded` 加一條（排除了某控制項任一評估目標，該控制項的控制項層命中就不成立）；BE `add_entry` 一處把關：評估目標→控制項的直連展開成逐條評估目標，其他跨層 400 `GRC_400189`；FE `clearCell` 評估目標列改送同層。DEV 那 12 筆跨層列停用。這一修同時蓋掉詳情對話框確認／改狀態／標不可用的同一個洞。
- **證據刪除行為（FR-162.14，無卡）**：決策者裁「只刪當下、不連帶其他專案、同專案多處讓使用者選」。BE 新增刪除前影響範圍端點、刪除帶 `scope=this|project`、沿用刪了寫 `NOT_APPLICABLE`（新 migration）、沿用候選排除、調整頁標 `dismissed`、下游標「來源已移除」。FE 新 `JobEvidenceDeleteDialog.vue`，抽屜原確認段移進去；五處沿用標籤帶 removed。

**commits**：套件 `c792aa47`；BE `25ba155c3`（已被決策者 push）`97cc679c1`；FE `cdbcb1d0` `92b005b5`。後三支未 push。

**關鍵決策（決策者裁）**：照同層逐條寫、不開例外；刪除只動本專案；沿用刪了＝本專案不適用、調整頁可加回；沿用是關聯不複製，來源刪除下游照常；`job_evidences` 不開 RLS。全部已寫進 STATE §2 與 design.md。

**推翻了什麼**
- 第 3 棒以為「逐條標評估目標不可用清不乾淨是筆數問題」，實際是解析器判定沒拿評估目標層排除去比控制項層節點；修一處判斷，同層寫法就清得乾淨。
- 我自己：先打算拿既有 `USER_DELETED` 當「不適用」不動 schema，DEV 實查當前輪有 3,738 筆歷史清理也是 USER_DELETED，會讓整輪沿用建議消失，改成新原因值 `NOT_APPLICABLE`。
- 我自己：一度建議 `job_evidences` 開 RLS 補強，決策者提醒影響面；查到背景／系統脈絡路徑十幾處，收回。
- design.md 原寫「`upload_files` 引用計數既有機制確保來源刪檔不影響」，實際沒有引用計數，是外鍵＋軟刪；已改寫。

**教訓**
- **開卡要用本 repo 的 `scripts/notion_create_case.py`**：agent-workshop 那支預設寫進工作坊自己的任務清單（Case No #65、專案 Agent Workshop），母卡關聯也掛不上；而且預設 `Not started` 會被工作坊派走。本 repo 那支能在建立時帶 `status`，首腦直修的卡直接建成 `修正待驗證`。
- **i18n JSON 用 `json.dump` 會把整檔重排**（2 格縮排變 4 格，578 行 diff）；要用文字插入保留原格式。
- **FE 匯入寫法照既有檔抄**：`BaseService` 是具名匯出、`API` 是預設匯出，寫反 build 直接紅。
- **「刪除語意」先查歷史資料分布**：同一個原因值被多種動作共用時，拿它當新語意的判準會把歷史全部算進去。

**未驗證假設**：所有畫面沒有實際登入看過；刪除與沿用排除只用行程內 dry-run（整段回滾）驗過資料層行為，HTTP 只驗到路由註冊（未登入回 401）。

**派出／收回**：本棒無派工；開 CM-3100 一張（首腦直修，直接建成 `修正待驗證`）。

**追加（13:55，決策者令直接修）**：誤建的 #65 卡移到 Notion 垃圾桶。修資安小縫 `e55dd46b3`：檔案下載的證據認領改成只認未刪的證據列（原本用通用查詢、已刪列也放行），補測試並做突變驗證（退回舊寫法 5 紅）；DEV 108 份只剩已刪證據的檔從此下載不到，查過沒有畫面或判定引用依賴它們。

**追加（14:30，決策者令 push＋全部發版）**：BE／FE 在我 push 前已由決策者推過，本棒 commit 全在遠端。套件四支 bump（oscal-v2 2.9.0、file-upload 1.3.8、compliance-audit 1.4.1、task-platform 1.4.1）commit `7e475c86` 並 push；先試發 file-upload 驗認證，再發其餘三支，每支只推當版號的兩個檔（`dist/` 有舊版殘留，用 `--dist-dir` 隔離，避免重推舊版被 Nexus 拒絕）；開包核對 oscal-v2 含 021～026 與解析器修正、compliance-audit 含 005。BE `9a996fd1d` 還原 path、pin 對齊、`poetry update` 只點名四支；venv 四支無 editable，BE 用正式版重啟無錯。compliance-audit 1.4.1（FR-161.3）與 task-platform 1.4.1（FR-155）不是本 arc 的改動，因宿主早已依賴、且決策者令全部發，一併發。

**追加（15:30，決策者令收尾：「測過了，四項文件全部寫掉」）**：規格三頁（控制項關聯管理、證據沿用 hub、沿用調整頁）`b186d3618`，順手重產 `db_schema.json`（原檔停在 07-04、沒有 FR-162 的表）；使用手冊「跨框架對照與證據沿用使用指南」並掛技術支援站 `04073fd75`；決策分析 `2026-10-26-fr162-same-level-mapping-and-evidence-delete-semantics.md`；SUMMARY `2026-10-26-FR-162-SUMMARY.md`。教訓：SVG wireframe 裡的錨點不會被 `fix_anchor_ids.py` 補 id，要從 build 出的 HTML 反查實際 id；`json.dump` 改 i18n 會整檔重排（本棒前段已記）。

**追加（16:10，決策者令 Notion 全部 Done）**：母卡 CM-3057 與 28 張子卡改 `Done`，以 GuidantAI 任務清單「母卡＝CM-3057」查詢複核 28/28。陷阱：母卡頁面的「子卡」反向欄位只列 25 張，漏了 CM-3097／3098／3100（後建、或建好後才 PATCH 母卡的），一定要用子卡的「母卡」欄位反查；agent-workshop 的 `notion_case.py` 的 `DATASOURCE_ID` 是工作坊清單，用它查 GuidantAI 卡會回 0。出貨基線決策者定發版前做。
