FR-135 · 第二期討論稿 · 2026-10-11

讓 CRA 專案開得出工作、填得齊資料

平台層兩項先修(影響所有框架),CRA 層補表單設定、證據指到節、評估目標拆分、Annex II 欄位

第〇步拿自家材料在 DEV 走完 CRA 31 條,露出兩個所有框架都會踩到的底層缺口:規劃頁看不到條文與建議證據、沒有評估目標(AO)時準備期一個工作都開不出來。這兩件先拆小卡修。其餘是 CRA 本身要補的內容:資源庫第四件「表單設定」、證據指到檔內某一節、把一條包多件事的控制項拆成多個 AO、Annex II 的產品資訊存成結構化欄位,外加資訊系統版本、風險評估雛形、文件範本。本稿盤點現況、畫出資料落點、拆成四個階段,列出 14 項待裁。

已裁 5 項(本期前提) 待裁 14 項(D1~D14) 平台層 2 項先拆小卡 design.md 拆兩份:platform/cra 沒有「複製資源庫」功能

狀態:討論稿(待裁 14 項) | 日期:2026-10-11 | 輸入:step-zero-gap-list.md 第四節、cra-implementation-plan.md「第二期」

§1

分工概述(30 秒版)

整案一句話:先讓任何沒有評估目標的框架也能在規劃頁看到條文、開得出收證據的工作;再讓 CRA 專案有地方填產品版本、支援期、通報窗口這些法規要的資料,而 CMMC 專案的畫面一點都不變。

給非工程讀者的背景:每本框架(CMMC、CRA)在系統裡是一棵「控制項樹」;控制項底下可以再分「評估目標」(AO,一條控制項要查的幾件具體事情)。CMMC 每條都有 AO,CRA 第一期刻意不建,結果暴露出系統有兩處只在「有 AO」時才會動。

本期前提(決策者 2026-10-11 已裁,不再討論)

① 第二期範圍=規劃稿「第二期」四件 + gap list 第四節六項,合併做;平台層兩項先拆小卡獨立修。② design.md 拆兩份:design-platform.md(平台層,影響所有框架)與 design-cra.md(CRA 層)。③ 表單設定最小版:固定結構設定、四種欄位型別(文字/日期/下拉/布林)、CRA 公版由 seed(隨程式出貨的初始資料)建好、CMMC 畫面不變;畫面上的表單編輯器、條件顯示、驗證規則留 GRC。④ 瀏覽對話框第三態(CM-2687)與 DEV CMMC PDF 遺失不進本稿。⑤ 沿用既有裁示:通報與跨框架對應另開 FR;稽核階段當「檢查」用、系統不改;風險評估第一版手填登錄表。

項目 做什麼 產出 完成怎麼判定(決策者檢查法)
平台層 A 規劃頁顯示條文 控制項樹多帶「條文原文」與「建議證據」兩欄,規劃頁控制項面板顯示 後端樹多兩欄、前端面板兩塊 開 CRA 專案規劃頁點任一條,看得到「條文」「建議證據」且段落換行正常;開 CMMC 專案同一頁,AO 面板與現在一樣
平台層 B 無 AO 也開得出工作 系統內建一份「收證據」流程範本給所有租戶用;沒 AO 的控制項每條各開一筆工作 範本改系統層級、出貨基線帶上、開工邏輯修正 用 CRA 公版新建專案,準備期出現 31 筆工作;隨便改一條的流程,另一條不受影響;換一個新租戶建專案結果一樣
CRA 1 表單設定 資源庫第四件:決定這本框架的專案多顯示哪些欄位、要不要風險評估頁籤 設定欄位、CRA 公版設定內容、受評標的頁動態欄位 CRA 專案受評標的頁多一段 CRA 欄位、出現風險評估頁籤;CMMC 專案畫面與現在一模一樣
CRA 2 證據指到節 掛文件到控制項時可寫「§4.2;SR 1.1, 2.3」 對應表加一個文字欄、掛載對話框加輸入框 掛 FR-126 矩陣時填章節,規劃頁清單看得到;用此資源庫再建一個專案,章節還在
CRA 3 拆評估目標 7 條一條包多件事的控制項拆成 2~3 個 AO,隨框架出貨 套件 seed、重建 CRA 公版 新建 CRA 專案,那 7 條底下出現 AO,準備期按 AO 數開工作
CRA 4 Annex II 欄位 支援期結束日、通報窗口網址等 6 項存成結構化欄位,預設說明文字預填 受評標的擴充鍵、控制項預設值 受評標的填支援期結束日,存檔重整還在;新專案 A2.x 實作說明已預填文字
附:資訊系統版本 資訊系統盤點加「版本」子清單 新子表+畫面 系統盤點某一筆底下能新增 v1.0/v1.1,各有上市日與支援期結束日
附:風險評估雛形 專案多一個手填的風險登錄表 頁籤+存放處 CRA 專案新增兩筆風險、重整後還在;CMMC 專案看不到這個頁籤
附:文件範本 CVD 政策等 4~5 份 docx 範本放進 CRA 公版程序書池並預掛 13 條 純資料上傳 新建 CRA 專案,程序書池已有範本,13 條控制項都掛著

依賴:平台層 A、B 互不相依,最先做。CRA 1 是 CRA 4 與風險評估頁籤的前提。CRA 3 與 CRA 4 的預設文字都要「重建 CRA 公版」才生效(D5),所以 CRA 層內容一次灌完再重建一次。決策者功課:請顧問確認 ① 7 條 AO 怎麼拆(D6)② 4~5 份文件範本內容(D10)③ Annex II 預設說明文字。


§2

第二期要解的六件事

來源是 step-zero-gap-list.md 第四節,括號內是第〇步實測時受影響的條數。第 8 項「定期執行的證明」(1 條,II.3)四份探脈都沒查,本期不處理,列入範圍外。

平台層(任何沒有 AO 的框架都會踩到)

① 規劃頁看不到條文原文與建議證據(31 條)

  • 白話問題:顧問在規劃頁只看得到「資料最小化」這種標題,法條原文與建議證據只在框架管理頁看得到。CMMC 有 AO 文字補上「要查什麼」,CRA 沒有就整個空掉。
  • 現況:後端其實已把每條控制項的全部段落撈出來(app/oscal/service/ssp_control_implementation_service.py:224-227),卻只留下 AO、把條文(statement)與建議證據(guidance)丟掉(:226)。回傳的控制項物件沒有這兩欄(:820-832);前端組樹時說明欄寫死空字串(FE ProjectPlanningView.vue:647)。沒 AO 時後端塞一個與控制項同名的假 AO(:792-803),畫面上是控制項底下一個同名節點、面板沒有任何「要查什麼」。

② 沒有 AO 時準備期一個工作都開不出來(31 條)

  • 白話問題:建專案回 job_count: 0,準備期空轉,沒有工作能派給客戶收證據。
  • 現況:程式其實已寫好「沒 AO 就在控制項層開一筆」(app/flow_control/service/prep_job_generation_service.py:165-166),但要找收證據的流程範本,來源只有兩個:AO 上掛的範本,或資源庫的 template_uid 退路(:168-169)。兩個都空時靜默略過(:170-172),只在 info log 記一筆 skipped(:220-225)。新建資源庫的寫入不寫 template_uid(app/oscal/service/resource_library_app_service.py:545-553),DEV 上 CRA 兩個資源庫 AO 數都是 0。

CRA 層(只影響 CRA)

③ 流程與文件類證據沒有材料(13 條):CVD 政策、通報窗口、安全通告、支援期聲明,產品本身沒有、系統也沒幫客戶產出的地方。現況:SSP 匯出用寫死的 CMMC 範本(app/oscal/service/ssp_docx_generator.py:1-29),程序書池只能上傳掛載、不能渲染,系統沒有通用的「範本→產出」機制。

④ 證據只能掛整份檔(11 條):FR-126 矩陣一份要掛 12 條,每條依據的 SR 只能寫在說明欄。現況:掛載對應表 oscal.ssp_reference_document_mappings 只有文件 id 與掛載對象,沒有章節欄(scripts/sql/2026-06-15-fr038-b3-ssp-reference-documents.sql:26-34);說明欄在池本體,整份共用。另有一套舊掛法並存(見 §4「CRA 2」)。

⑤ 一條包多件事要拆 AO(7 條):I.1、I.2.b、I.2.d、I.2.h、I.2.l、II.2、A2.8 的證據混在一起。現況:系統沒有手動新增 AO 的路徑——框架編輯端點只有改與刪(framework_version_edit_route.py:112-133),且只有草稿版可改,CRA 已發布。

⑥ Annex II 的「資訊本身」要結構化(6 條):支援期結束日、通報窗口網址現在只能截圖或寫說明。現況:受評標的表已有擴充屬性(props,OSCAL 標準的自訂鍵值欄)oscal.ssp_system_characteristics.props(jedi-oscal-v2 oscal_ssp_system_characteristics.py:104),已存 target-type/owner-uid 兩鍵(app/module_frame/service/module_frame_system_characteristic_service.py:34-36),加鍵即可。


§3

現況盤點:可複用 vs 要新做

項目 可複用(已存在) 要新做
規劃頁條文 後端已撈全部段落(ssp_control_implementation_service.py:224-227);條文/建議證據挑法 framework_version_edit_service.py:266,272;同頁換行樣式先例 FE ProjectPlanningView.vue:2226 _resolve_inscope_catalog(:165)多帶兩欄;_build_control(:820)加兩欄;FE 面板兩塊;無 AO 退回分支(:792)改顯示控制項建議證據
無 AO 開工 控制項層退回邏輯(prep_job_generation_service.py:165-166);下游工作紀錄、指派、覆核沿用、證據範圍、稽核判定全部對得上(探脈逐一查過,見 §4「平台層 B」) 系統層級「收證據」範本;資源庫範本來源補值或讀時退回;每條各 clone 一份;規劃頁控制項層那筆補範本 uid
表單設定 受評標的 props 非破壞合併工具(module_frame_system_characteristic_service.py:94-115,163-182);建專案深拷貝帶 props(ssp_clone_service.py:147-153);動態頁籤 v-if 先例(雲端頁籤 FE ProjectPlanningView.vue:416-429);公版 seed 入口 public_library_seed_cli.py:_seed_one 設定落點+migration+ORM+DTO;專案端拿設定的管道;動態欄位渲染元件(四型別);CRA 公版設定內容
複製資源庫 不存在。唯一 clone module_frame_service.py:130-222 只複製 BPMN 範本與資源庫列,FE 無呼叫端(api.js:152) 若要「隨資源庫複製」得新做(D1)
證據指到節 新套掛法:池(ssp_document_pool_service.py:63-78)+多對多對應(:148-201);建專案複製(project_start_app_service.py:255-295) 對應表加 locator 文字欄;新增/列出 API、FE 掛載對話框、建專案複製(:270,292)、快照還原(ssp_document_pool_service.py:216,249)
AO 拆分 AO 存法(catalog_control_parts name=assessment-objective,key {control_id}_obj.N);003 seed 的冪等寫法 套件 004 seed;重建 CRA 公版
Annex II 受評標的 props;控制項預設值(module_frame_control_default_service.py:36-41,187-201)建專案隨範本 SSP 複製 6 個鍵+FE 表單;A2.x 預設說明文字
資訊系統版本 compliance.information_systems 表與端點(jedi-asset routing.py:48-51);SSP 軟關聯(module_frame_inventory_service.py:43-46) jedi-asset 新子表 information_system_versions+CRUD+畫面
風險評估 AR/POA&M 層有風險表與畫面(oscal.assessment_risks、FE RiskBadge.vue)可參考欄位 SSP 層完全沒有風險表與頁籤(D9)
文件範本 資源庫層程序書池(api/module_frame/__init__.py:167-177),建專案整池複製 4~5 份 docx 內容(顧問功課)+上傳預掛
自家 SBOM build 產 CycloneDX(scripts/build/sbom.sh:60,70);源碼掃描可匯入(api/source_scan/routes/target_route.py:130-145) 掃描結果→控制項證據的連結(D14)

§4

方案與資料落點

整體架構

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#E2F0F1','primaryTextColor':'#14201F','primaryBorderColor':'#0E7C86','secondaryColor':'#EEF2F3','secondaryTextColor':'#14201F','tertiaryColor':'#FBFCFC','tertiaryTextColor':'#14201F','lineColor':'#4A5A5C','textColor':'#14201F','mainBkg':'#E2F0F1','nodeBorder':'#0E7C86','nodeTextColor':'#14201F','edgeLabelBackground':'#FBFCFC','titleColor':'#14201F','clusterBkg':'#FBFCFC','clusterBorder':'#E4EAEB','actorBkg':'#E2F0F1','actorTextColor':'#14201F','actorBorder':'#0E7C86','actorLineColor':'#C7D1D2','signalColor':'#4A5A5C','signalTextColor':'#14201F','labelBoxBkgColor':'#EEF2F3','labelBoxBorderColor':'#C7D1D2','labelTextColor':'#14201F','loopTextColor':'#14201F','noteBkgColor':'#F6EBD5','noteTextColor':'#14201F','noteBorderColor':'#9C6B12','activationBkgColor':'#EEF2F3','activationBorderColor':'#C7D1D2','sequenceNumberColor':'#FFFFFF'}}}%%
flowchart LR
  subgraph RL["資源庫(module_frames)"]
    P["① 控制項選集<br/>oscal_profile_uid"]
    S["② SSP 範本<br/>template_ssp_id"]
    F["③ 稽核流程範本<br/>audit_flow_template_uid"]
    T["收證據退路<br/>template_uid"]
    FS["④ 表單設定<br/>(新)"]
  end
  SYS["系統「收證據」範本<br/>(改 SYSTEM 層級)"]
  subgraph PJ["專案"]
    SSP["專案 SSP<br/>受評標的 props"]
    TREE["控制項樹<br/>+條文/建議證據"]
    JOB["準備期工作"]
  end
  P -->|建專案複製| TREE
  S -->|深拷貝帶 props| SSP
  F -->|建首輪預設| JOB
  FS -.->|決定顯示哪些欄位| SSP
  SYS -.->|補值或讀時退回| T
  T -->|無 AO 時| JOB
  TREE -->|每 AO 或每控制項| JOB
圖 1 — 資源庫四件如何流到專案與準備期工作(虛線=本期要新增或補值)

平台層 A:控制項樹加條文與建議證據兩欄

  • 做法:_resolve_inscope_catalog(ssp_control_implementation_service.py:165)本來就對每條控制項撈全部段落(:224-227),改成順手留下 statement 與 guidance;_build_control(:820)加 statement、guidance 兩欄。挑段落的邏輯沿用 framework_version_edit_service.py:266(_statement_prose)與 :272(_guidance_prose)。
  • 不增 SQL:段落原本就全撈。CMMC L2 110 條合計約 50KB、CRA 31 條約 25KB,直接併進樹,不做延遲載入。每控制項各查一次的既有問題不是本案造成,不在本期處理。
  • 順手收掉的重複查詢:分類器用的 build_classifier_catalog_by_ssp_id(:266-272)為了拿 statement 重打一次,改形狀後兩邊共用。
  • 前端:ProjectPlanningView.vue:647 改接新欄位;控制項面板加「條文」「建議證據」兩塊,換行樣式照同頁 :2226;沒 AO 的退回分支(後端 :792)顯示控制項的建議證據。
  • 命名:新欄位直接叫 statement/guidance,不沿用 description——框架管理頁的 description 是條文、規劃頁的 description 是空佔位,同字兩義。
  • 影響面:control-tree 另有 6 頁在用(RoundAuditReview、RoundApAuthoring、ProjectAuditorOverview、EvidenceClassificationReview、AutoClassifyBatch 等),只加欄位不動既有欄位就不會壞。稽核執行頁 AuditControlRef.vue:65-66 已有欄位但 RoundAuditReviewView.vue:337-338 寫死空字串,要不要一併接起來在 design-platform.md 定。

平台層 B:沒有 AO 也開得出準備期工作

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#E2F0F1','primaryTextColor':'#14201F','primaryBorderColor':'#0E7C86','secondaryColor':'#EEF2F3','secondaryTextColor':'#14201F','tertiaryColor':'#FBFCFC','tertiaryTextColor':'#14201F','lineColor':'#4A5A5C','textColor':'#14201F','mainBkg':'#E2F0F1','nodeBorder':'#0E7C86','nodeTextColor':'#14201F','edgeLabelBackground':'#FBFCFC','titleColor':'#14201F','clusterBkg':'#FBFCFC','clusterBorder':'#E4EAEB','actorBkg':'#E2F0F1','actorTextColor':'#14201F','actorBorder':'#0E7C86','actorLineColor':'#C7D1D2','signalColor':'#4A5A5C','signalTextColor':'#14201F','labelBoxBkgColor':'#EEF2F3','labelBoxBorderColor':'#C7D1D2','labelTextColor':'#14201F','loopTextColor':'#14201F','noteBkgColor':'#F6EBD5','noteTextColor':'#14201F','noteBorderColor':'#9C6B12','activationBkgColor':'#EEF2F3','activationBorderColor':'#C7D1D2','sequenceNumberColor':'#FFFFFF'}}}%%
sequenceDiagram
  participant API as 建專案 API
  participant ST as 啟動服務
  participant GEN as 準備期產生器
  participant WT as 流程範本表
  API->>ST: start_project
  ST->>ST: 讀資源庫 template_uid(可能是空)
  ST->>GEN: generate(fallback_template_uid)
  loop 每條在範圍內的控制項
    alt 控制項有 AO
      GEN->>GEN: 每個 AO 取 props 上的範本 uid
    else 沒有 AO
      GEN->>GEN: 控制項層一筆,取 fallback
    end
    alt 範本 uid 是空
      Note over GEN: 靜默略過 skipped+1(:170-172)
    else 有 uid
      GEN->>WT: 依 uid 取範本
      alt 本租戶讀不到(TENANT 範本跨租戶)
        Note over GEN: 一樣靜默略過(:173-175)
      else 讀得到
        GEN->>WT: clone 專案副本(同來源只 clone 一次)
        GEN->>GEN: 寫一筆準備期工作
      end
    end
  end
圖 2 — 建專案時開準備期工作的判斷順序(紅字=現在會靜默略過的地方)

四處要改,缺一個都還是 0 工作或工作打架:

  1. 系統「收證據」範本改成所有租戶讀得到:系統只有一份 compliance.workflow_templates uid f4038001-…0001「收證據」,DEV 上是租戶 102 的 TENANT 層級,其他租戶因 RLS(資料庫依租戶隔離)讀不到,get_workflow_template_by_uid 回空照樣略過。要改 SYSTEM 層級,並帶進出貨基線——但基線 scripts/init/04-seed-core.sql:824,868 目前強制 workflow_templates 必須為空(D4)。
  2. 範本來源補上:兩條路擇一或併用(D12)——建資源庫的 INSERT 帶上系統範本 uid(resource_library_app_service.py:545-553),或啟動時讀到空值退回系統預設(project_start_app_service.py:146)。前者要回頭補 DEV 既有資源庫;後者既有資源庫自動生效。
  3. 每條控制項各 clone 一份:現在 _clone_for 快取同來源只 clone 一次(prep_job_generation_service.py:142-156),31 筆工作共用一份副本,inject_job_execution_uid 覆蓋寫入只留最後一筆,流程編輯器存檔還會重複建工作(:139-141,194-203)。控制項層退回時改成每條各 clone。
  4. 規劃頁控制項層那筆補範本 uid:ssp_control_implementation_service.py:796-803 有輪次時帶得到工作,但沒帶 workflow_template_uid/workflow_execution_uid,FE ProjectPlanningView.vue:1407 會提示「沒有流程」;無輪次的舊路徑(:488-494)依 AO props 找工作,控制項層工作看不到。

下游不用改(探脈逐一查過):工作紀錄寫 (control_id=cid, ao_part_id=cid)(prep_job_generation_service.py:214-216);指派綁工作 id(flow_control_job_repo_impl.py:548-552);覆核輪沿用指派用 ao_part_id IS NOT DISTINCT FROM 配得上(reverify_clone_query.py:48);稽核判定 ao_derivation.py:38-41 無 AO 同樣退回 (cid,cid)。

唯一例外在套件:覆核輪 jedi-compliance-audit audit_round_app_service.py:774-779 傳 fallback=None,控制項層一定略過(D8)。

CRA 1:資源庫第四件「表單設定」

  • 落點取捨(D2):
資源庫表加 JSONB 欄 module_frames.form_settings 新表 module_frame_form_settings
改動量 一個 INSERT+mapper,seed/DTO 帶得順 多 repo、mapper、RLS 政策,複製多一段,載入多一次查詢
約束 資料庫不擋結構錯誤,靠程式驗 每欄一列,可加約束與排序
未來 GRC 表單編輯器 結構變大後較難維護 擴充好接
先例 detection_tools.config_field_schema(scripts/sql/2026-07-31-fr058-9-...sql:22-36) —
  • 值存哪:使用者填的值存專案 SSP 受評標的 props,鍵加 ext: 前綴(例 ext:cra-support-end-date),避免撞到既有 target-type/owner-uid。寫入用既有非破壞合併工具(module_frame_system_characteristic_service.py:94-115),建專案深拷貝自然帶過去(ssp_clone_service.py:147-153)。
  • 專案怎麼拿到設定(D3):專案已記得資源庫(projects.module_frame_id,建專案寫於 project_start_app_service.py:374),但規劃頁拿的 GET /grc/project/<uid> 回應裡資源庫只有 id/name/group/version/frequency(jedi-compliance-audit api/serializers/project.py:203-212、project_dto.py:72-76)。兩條路:改套件 DTO 加欄,或主專案另開端點。
  • 畫面:受評標的固定 8 欄(SspTabPanel.vue:339-342 → SspBasicSection.vue,useSspSystemCharacteristic.js:34),設定有值時在下方多渲染一段動態欄位;風險評估頁籤照雲端頁籤 v-if 先例(ProjectPlanningView.vue:416-429)。
  • CMMC 不受影響的條件:設定為空就照現在固定頁籤與 8 欄;CMMC 公版不寫設定。
  • CRA 公版怎麼帶設定:public_library_seed_cli.py 的 PublicLibrary dataclass(:18-23)加 form_settings,在 _seed_one 建庫之後(:79)、改名升 SYSTEM 之前(:80-83)同一個交易寫入。
  • 建議結構(草案,design-cra.md 定稿):{ "sections": {"risk_assessment": true}, "fields": [{"key": "ext:cra-support-end-date", "label": "...", "type": "date", "required": true, "options": null}] },type 限 text/date/select/boolean。

CRA 2:證據指到檔內某一節(locator)

  • 對應表 oscal.ssp_reference_document_mappings 加一個文字欄 locator,內容自由寫(「§4.2;SR 1.1, 2.3」),不做結構化——各家文件的章節格式不一。
  • 連動五處:新增對應的請求、列出對應的回傳(jedi_compliance_audit SspDocumentPoolQuery)、FE 掛載對話框(ProjectPlanningView.vue:2509 DocumentLinkDialog)加輸入框、建專案複製(project_start_app_service.py:270,292)、快照還原(ssp_document_pool_service.py:216,249)。
  • 舊套掛法:context_type=control_implementation|objective 直接寫在 ssp_reference_documents(寫 ssp_control_implementation_service.py:887,974-992、讀 :1010-1012),FE 上傳函式 handleUploadRefDoc(ProjectPlanningView.vue:1511-1533)沒有模板呼叫=沒有入口,這就是「控制項詳情回空陣列」的原因;建專案也只複製新套。只在新套加 locator,舊套 API 繼續回空(D7)。

CRA 3:拆評估目標(AO seed 004)與重建公版

  • 仿套件 003 的冪等寫法(以 part_id 判斷不存在才寫),新增 jedi_oscal_v2/migrations/004,7 條各寫 2~3 個 AO,key 用 {control_id}_obj.N。CMMC 的 AO 來自 PDF 解析器(cmmc2_lv2_parser_adapter.py:610-620),CRA 002 明寫不建 AO(:9),所以只能走 seed。
  • 只對之後新建的資源庫與專案有效:建資源庫時整份複製 catalog(resource_library_app_service.py:500-501),AO 的流程範本也只在那時建(_init_ao_workflows,:236-278)。既有 CRA 公版與第〇步測資吃不到(D5);本期稍早灌的 guidance 同理。
  • 生效後:拆了 AO 的 7 條準備期自動變每 AO 一筆(prep_job_generation_service.py:160-172),稽核計畫的查核項(assessment_plan_app_service.py:401)跟著 AO 走。其餘 24 條仍靠平台層 B 的退路開工——拆 AO 不能取代平台層 B。

CRA 4:Annex II 結構化欄位與預設文字

  • 結構化值:受評標的 props 加 6 個鍵(例 ext:cra-support-end-date、ext:cra-vuln-contact-url),由 CRA 1 的表單設定宣告、受評標的頁渲染。不開新表、不加新欄。
  • 預設說明文字:放「適用控制項預設值」——資源庫範本 SSP 的實作需求 props(implementation-description 等,module_frame_control_default_service.py:1-16,36-41,187-201),建專案隨範本 SSP 複製。A2.x 的預設說明文字是純資料,寫進 CRA 公版 seed。
  • 與規劃稿的落點差異:規劃稿把「漏洞揭露政策、通報窗口、通報人員」放組織層資訊系統盤點,探脈建議放受評標的 props(D13)。

資訊系統版本子表

  • compliance.information_systems(scripts/sql/packages/jedi_asset/001-asset-tables.sql:97-118)沒有版本欄。建議 jedi-asset 新子表 information_system_versions(資訊系統 FK、版號、上市日、支援期結束日、理由)+CRUD 端點+FE InformationSystemManage.vue 子清單。
  • SSP 端軟關聯不動:受評標的 inventory_items.props 存 ref-type=information_system+ref-id(module_frame_inventory_service.py:43-46)。專案要不要「選到某個版本」(規劃稿樹狀圖寫「專案(選系統與版本)」)探脈未查、待驗,design-cra.md 定。

風險評估頁籤(最小雛形)

  • 現況:專案頂層頁籤固定六個(ProjectPlanningView.vue:405-413),SSP 子頁籤固定四個(SspTabPanel.vue:336-386),SSP 層完全沒有風險表;風險只存在稽核結果層 oscal.assessment_risks(oscal_ar_risk.py:25,characterizations JSONB :59)與 POA&M 畫面(RoundPoamView.vue:533-633)。
  • 已裁第一版是手填登錄表,預留「威脅來源」「元件連結」兩欄。存放處 D9。頁籤顯示由表單設定的 sections.risk_assessment 控制。
  • 規劃稿寫「風險資料掛在系統主檔、由專案頁籤寫入」,若照此做就要掛到資訊系統而非 SSP;D9 一併裁。

文件範本進程序書池

  • 系統沒有通用的範本產出機制(SSP 匯出寫死 CMMC docx,摘要報告是 Jinja HTML→PDF,common/util/html_pdf.py:26)。
  • 最小做法:CVD 政策、通報窗口、安全通告、支援期聲明等 4~5 份 docx 放 CRA 公版的資源庫程序書池(/module-frame/<uid>/reference-documents),預掛到 13 條控制項;建專案整池複製(project_start_app_service.py:229-297)。客戶下載填寫、再上傳成證據。屬純資料(S),範本內容是顧問功課(D10)。
  • 「填欄位自動產出」(docxtpl+Annex II props)是 M~L,屬第三期「三份文件範本」範圍,本期不做。

自家 SBOM:可匯,但不會變成證據

  • build 產 CycloneDX JSON(scripts/build/sbom.sh:60,70),安裝包收進 sbom/(build_bundle.sh:30,359-361);源碼掃描對象端點收 CycloneDX 1.2–1.6、SPDX 2.1–2.3(target_route.py:130-145)——現在就能匯。
  • 但掃描模組與控制項證據沒有連結,要當 I.2.a/II.1 證據只能下載報告再手動上傳(D14)。

§5

階段拆分(草案)

階段 卡(粗切) 規模 依賴
P2-A 平台層先行 A1 控制項樹加 statement/guidance+規劃頁兩塊(BE+FE 同卡) S 無
B1 「收證據」範本 SYSTEM 化+出貨基線放行+範本來源補值或退回 M D4、D12
B2 控制項層每條各 clone+規劃頁控制項層那筆補 uid M B1
B3 覆核輪改從上一輪取範本(改 jedi-compliance-audit,發版) S D8,B1
P2-B 表單設定與受評標的擴充 F1 表單設定落點+migration+ORM+mapper S~M D2
F2 專案取得設定(套件 DTO 或新端點) S~M D3、F1
F3 FE 動態欄位元件(四型別)+受評標的頁接上+頁籤開關 M F2
F4 CRA 公版設定內容+Annex II 六鍵+A2.x 預設文字(seed) S F1、顧問確認預設文字
P2-C 產品版本與風險 V1 jedi-asset 版本子表+CRUD+FE 子清單 M 無(可與 P2-B 平行)
R1 風險評估頁籤雛形(存放處+頁籤+表格) M D9、F3
P2-D CRA 內容補強 C1 套件 AO seed 004(7 條) S D6、顧問確認
C2 證據 locator(對應表欄+API+FE+複製+快照;視 D7 收舊套) M D7
C3 文件範本 4~5 份上傳 CRA 公版程序書池並預掛 13 條 S D10
C4 重建 CRA 公版與測資(或回灌補丁) S D5,C1、F4、C3 全部完成
  • P2-A 四張卡互不碰 CRA 內容,可立刻派;A1 與 B1 平行。
  • P2-D 的 C4 是收口卡:所有要進 catalog 或公版的資料灌完後只重建一次。
  • 合計約 14 張卡;design-platform.md 管 P2-A,design-cra.md 管 P2-B~D。

§6

待決策

⏸ D1 — 沒有「複製資源庫」功能:第二期做,還是明列範圍外

已裁「表單設定隨資源庫複製」,但系統沒有複製資源庫的功能:唯一的 clone(module_frame_service.py:130-222)只複製 BPMN 範本與資源庫列,FE 沒有呼叫端。真正「資源庫→副本」只發生在建專案(oscal_snapshot_service.py:105 複製 catalog/profile/SSP,project_start_app_service.py:390 複製程序書池)。表單設定若放資源庫 JSONB,專案可以直接讀資源庫的設定,不必複製。

建議:明列範圍外,專案直接讀資源庫設定。理由:「之後 SEMI E187 複製 CRA 資源庫微調」是 GRC 期才出現的需求,現在做複製服務要連 profile、SSP 範本、流程範本、程序書池一起處理,是 L 級工程;建專案時已會帶走 SC.props 與程序書池,CRA 第二期用不到複製。風險:資源庫設定事後被改,舊專案畫面會跟著變——表單設定最小版只有 seed 建、沒有畫面編輯器,這個風險現在不存在。

⏸ D2 — 表單設定落點:資源庫 JSONB 欄 vs 新表

利弊見 §4「CRA 1:資源庫第四件」的對照表。

建議:JSONB(module_frames.form_settings)。最小版只有 seed 寫入、沒有畫面編輯器,用不到每欄一列的約束;只動一個 INSERT 與 mapper。結構驗證放程式(讀取時檢查四種型別)。GRC 做表單編輯器時再評估拆表。

⏸ D3 — 專案怎麼拿到表單設定:改套件 DTO 加欄 vs 主專案新端點

規劃頁現在讀 GET /grc/project/<uid>,資源庫資訊只有五欄(jedi-compliance-audit project_dto.py:72-76)。

建議:主專案新端點(例 GET /module-frame/<uid>/form-settings,用專案已有的 module_frame_id 查)。理由:不用為一個欄位發 jedi-compliance-audit 版本、不碰其他 consumer;表單設定是 CRA 期才有的概念,放主專案。代價是規劃頁多一次請求,可接受。

⏸ D4 — 「收證據」範本改 SYSTEM 層級,要動出貨基線的「必須為空」檢查

出貨基線 scripts/init/04-seed-core.sql:824,868 強制 workflow_templates 為空,新裝客戶目前沒有這份範本。要讓所有租戶讀得到,得把這一份放進基線並把檢查改成「只允許這一份 SYSTEM 範本」。重產基線屬決策者裁示。

建議:同意。只放一份、uid 固定、檢查改成白名單。不放的話平台層 B 對新客戶等於沒修。

⏸ D5 — 既有 CRA 公版(SYSTEM 451)與第〇步測資:重建 vs 回灌補丁

catalog 是建資源庫當下整份複製,之後灌的 AO、guidance、Annex II 預設文字都吃不到。

現況(DEV,2026-10-11 查):compliance.module_frames 451=SYSTEM 公版(tenant 1),掛專案 1398「CM-2682 公版建專案測試(驗完刪)」;449=租戶版第〇步測資(tenant 102),掛專案 1397「CRA 第〇步測試(Guidant AI 自評)」。STG/POC 兩台都沒有任何 CRA 資源庫與 CRA 專案(唯讀查證)。

建議:公版重建(seed 遇同名 SYSTEM 庫會跳過,public_library_seed_cli.py:62-66,所以要先刪再重跑 RUN_MODE=seed-public-libraries),重建 451 時專案 1398 一起刪;449 與專案 1397 保留當第〇步測資,另建一個新測試專案驗收。理由:公版是程式建的、本來就可重跑;回灌補丁要同時處理 catalog、AO 流程範本、控制項預設值三處,等於重寫一次建庫邏輯。STG/POC 都沒有 CRA 資源庫與專案,直接重建沒有外部影響。

⏸ D6 — 7 條 AO 各拆幾個、怎麼拆,由誰定

建議:runner 以第一期 ENISA 對照底稿(enisa-mapping-worksheet.md)的子要求為依據直接擬稿,顧問審稿後才灌。理由:底稿已逐條對到 ENISA 拆出的子要求,起稿成本低;AO 會影響稽核判定單位,不比建議證據可以先上再修,所以要審。

⏸ D7 — 兩套程序書掛法並存,加 locator 時順手收掉舊套嗎

建議:收。舊套沒有 FE 入口、建專案不複製,只剩控制項詳情 API 回空陣列造成誤導。同卡把詳情 API 改讀新套的對應,舊套寫入路徑標棄用;DEV 查證 oscal.ssp_reference_documents 5,222 筆全是 context_type='ssp'(池本體),舊套 control_implementation/objective 零筆,ssp_reference_document_mappings 45 筆——收舊套不需要搬資料。

⏸ D8 — 覆核輪對控制項層工作傳 None,本期修嗎(改 jedi-compliance-audit)

audit_round_app_service.py:774-779 傳 fallback=None,沒 AO 的控制項在覆核輪一定開不出工作。

建議:本期修。平台層 B 修好後首輪會有工作、覆核輪卻沒有,使用者會以為是新 bug;改法小(從上一輪對應紀錄取範本 uid),跟 B 系列卡一起發套件版本。

⏸ D9 — 風險評估雛形存哪:新表 vs 先用受評標的 props 存 JSON 陣列

SSP 層沒有風險表;規劃稿又寫「資料掛在系統主檔」。

建議:新表,掛專案 SSP(不掛資訊系統主檔)。理由:風險會一筆一筆增刪改,塞 props 的 JSON 陣列會有並發覆寫問題,也難接下一階段的「依元件類型建議威脅」;掛 SSP 符合「專案的風險評估」語意,組織層風險登錄等 GRC 再從各專案彙整。欄位參考 oscal.assessment_risks。

⏸ D10 — 4~5 份文件範本 docx 由誰寫

建議:顧問主筆、runner 只做格式與上傳預掛。理由:CVD 政策、支援期聲明是對外法律文件,AI 起稿可以,但出貨前要有人負責內容;這是決策者功課,不卡 P2-A~C。

⏸ D11 — 舊 clone_module_frame 端點保留還是刪

FE 無呼叫(api.js:152),template_uid 為空時推斷會在 .xml 步驟壞(未實跑);平台層 B 補值後它會深複製子流程,語意與新模型可能不一致。

建議:刪(含 FE 常數)。沒人用、補值後行為不可預期,留著反而讓人以為已有「複製資源庫」。D1 若裁要做複製,也是新寫,不在這支上改。

⏸ D12 — 收證據範本來源:建資源庫時寫入 vs 啟動時讀到空值退回系統預設

建議:啟動時退回系統預設(project_start_app_service.py:146)。理由:既有資源庫不必回頭補值,所有租戶自動生效;資源庫有填 template_uid 的照舊優先。建資源庫的 INSERT 不必改。

⏸ D13 — 漏洞揭露政策、通報窗口放哪:資訊系統主檔 vs 受評標的 props

規劃稿放組織層資訊系統盤點;探脈建議受評標的 props。

建議:值存受評標的 props(跟著專案與表單設定走,CMMC 不受影響),資訊系統主檔本期只加版本子表。理由:放主檔要改 jedi-asset 主表與畫面且所有框架都看得到;第三期通報模組需要時再把窗口提升到主檔。

⏸ D14 — 自家 SBOM「掃描結果→控制項證據」連結、定期執行證明,本期做嗎

建議:範圍外。只影響 3 條(I.2.a、II.1、II.3),現有做法(下載報告再上傳)可用;連結是 M 級且屬掃描模組與證據模組的整合,放 FR-134 後續或 GRC。


§7

風險與陷阱

🔴 catalog 是建庫當下整份複製,seed 對既有資源庫與專案無效

AO、guidance、Annex II 預設文字灌進套件後,既有 CRA 公版與專案都吃不到,必須重建或回灌(D5)。驗收一律用新建的資源庫與專案,不要拿第〇步測資驗。

🔴 拆 AO 不能取代平台層 B

AO seed 只解 7 條,另 24 條仍靠 template_uid 退路開工,而 DEV 全部是空的。P2-D 不能早於 P2-A 的 B 系列宣告「CRA 準備期能開工」。

🔴 範本跨租戶讀不到也是靜默略過

「收證據」範本現在是租戶 102 的 TENANT 層級,其他租戶 get_workflow_template_by_uid 回空,結果一樣是 0 工作且只有 info log。驗收必須換一個非 102 的租戶建專案。

🔴 同來源範本只 clone 一次,31 筆工作會共用一份副本

_clone_for 快取讓控制項層退回時全部工作共用一份流程副本,inject_job_execution_uid 只留最後一筆、編輯器存檔會重複建工作(prep_job_generation_service.py:139-141,194-203)。只補範本 uid 不改 clone 粒度,會從「0 工作」變成「31 筆工作互相覆蓋」。

🔴 _resolve_inscope_catalog 有兩個使用者,control-tree 有 7 頁在用

控制項樹與分類器(ssp_control_implementation_service.py:242)共用,改回傳形狀兩邊一起改;control-tree 只加欄位、不改 description 語意,否則其他 6 頁會壞。

🔴 兩套程序書掛法,只改一套會繼續誤導

locator 只加在新套對應表,舊套的控制項詳情 API 仍回空陣列;建專案、快照還原各有一份複製邏輯,漏一處 locator 就在新專案消失(D7)。

🔴 擴充屬性鍵要加前綴

受評標的 props 已存 target-type/owner-uid,新鍵不加 ext: 前綴可能撞名;寫入必須走既有非破壞合併,整包覆寫會把這兩鍵清掉。

🔴 資源庫「第三件」稽核流程範本的欄位也沒人寫

module_frames.audit_flow_template_uid 只有 migration 加欄,app 與 api 全無寫入者,只在建首輪時當預設值讀(audit_round_app_service.py:302)。規劃稿說「四件並列」,實際上第三件與收證據退路(template_uid)兩欄建庫時都是空的。設計表單設定時別假設前三件都已完整落地。


沿革見 handoff/FR-135-LOG.md 與 git log。