FR-135 · 第二期 design-cra · 2026-10-12(D1~D17 已裁)

CRA 專案填得齊產品資料、風險評估與證據來源

P2-B 表單設定、P2-C 產品版本與風險評估、P2-D CRA 內容(建庫帶預設、評估目標調整、證據來源、文件範本)

第〇步拿自家材料走完 CRA 31 條,露出 CRA 本身要補的內容:受評標的沒地方填用途、分級、支援期;沒有製造商與通報聯絡人;沒有風險評估;7 條一條包多件事;有些證據客戶在系統別頁填完就有、卻要他再上傳。本文件把已裁的 D 項展開到「照做就能交」:資源庫第四件「表單設定」決定 CRA 專案多出哪些欄位與頁籤、製造商與通報聯絡人用 OSCAL 的 Party 與角色、風險評估開新表並對齊 OSCAL 風險物件、顧問從畫面新增 CRA 資源庫時由建庫程式依框架帶入預設內容、評估目標(AO)全面調整為 4 群 34 條 49 個、AO 帶「證據來源」屬性直接連到系統內的頁面。CMMC 專案畫面一點都不變。

D1~D17 已裁(本文件管 14 項) 13 張卡:F1~F4 V1 R1-a R1-b C1 C1b C2 C2b C3 E1 跨 3 repo:BE/FE/jedi-python-package 表單設定為空=CMMC 畫面不變 陷阱:預設內容只在建庫當下寫入,舊資源庫不補 陷阱:規劃頁 2,600 行級,新邏輯一律新開元件

狀態:設計定案(D1~D17 已裁,本文件展開 D1 D2 D3 D5 D6 D7 D9 D10 D11 D13 D14 D15 D16 D17)|日期:2026-10-12|平台層(規劃頁條文、無 AO 開工、覆核輪、收證據範本)見 design-platform.md

🔴 這份是設計決策,不是現況。 內文行號是 2026-10-12 的位置,會隨程式漂移;上線後的現況看 SPEC 頁。

§1

變更紀錄

日期 變更 對應
2026-10-11 v1:P2-B/C/D 設計定案 母卡 CM-2675
2026-10-12 v2:對齊已落地的實作與決策者裁示——建庫帶預設內容機制、程序書與證據分兩套、風險評估「依據標準」、AO 全面調整、AO 證據來源機制;十三張卡附實際 Case No CM-2705

§2

需求背景與端到端流程

CRA(歐盟網路韌性法,Regulation (EU) 2024/2847)要求製造商回答「你為什麼這樣做、依據是什麼」,不只是逐條打勾。一個 CRA 專案要能留下:圈範圍(用途、誤用、環境、角色、八題適用判定、產品分級)、Annex II 使用者資訊(製造商、漏洞通報窗口、揭露政策網址、產品識別、支援期結束日)、風險評估(威脅、依據標準、資產、衝擊、可能性、既有控制、措施、對應控制項)、產品版本與支援期、評估目標拆分(一條控制項底下要查的幾件具體事情)、證據來源(系統內已有的資料直接當證據,客戶自有的檔才上傳)。

端到端:資源庫四件 → 建專案 → 專案 SSP → 規劃頁

顧問視角:從畫面新增資源庫、框架選 CRA,建庫程式依框架代號 CRA_2024 自動帶入表單設定、Annex II 預設說明、製造商與通報聯絡人兩個空殼、五份文件範本。用這個資源庫建專案,規劃頁就多出 CRA 專用欄位與「風險評估」頁籤,參與單位頁已有兩個空位,程序書池已有範本並掛好控制項。CMMC 資源庫沒有這些預設內容,專案完全不受影響。

%%{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["新增 CRA 資源庫(module_frames)"]
    P["① 控制項選集<br/>catalog+profile<br/>(4 群 34 條 49 AO)"]
    S["② SSP 範本<br/>Party 空殼/A2.x 預設說明"]
    F["③ 稽核流程範本"]
    FS["④ 表單設定<br/>form_settings"]
    POOL["程序書池<br/>文件範本 5 份"]
  end
  DEF["framework_library_defaults/<br/>cra_2024.py(建庫時依框架 code 查表)"]
  subgraph PJ["CRA 專案"]
    SC["受評標的<br/>SC.props ext:cra-*"]
    PARTY["參與單位<br/>製造商/通報聯絡人"]
    RISK["風險評估表<br/>ssp_risks"]
    PLAN["規劃頁<br/>依 sections 開頁籤"]
    AOP["AO 面板<br/>證據來源或上傳"]
  end
  IS["資訊系統盤點<br/>+版本子表"]
  DEF -.-> S
  DEF -.-> FS
  DEF -.-> POOL
  P -->|建專案複製| PLAN
  S -->|深拷貝| SC
  S -->|深拷貝 metadata| PARTY
  POOL -->|整池複製+對應| PLAN
  F --> PLAN
  FS -->|專案讀資源庫設定| PLAN
  FS -->|宣告欄位| SC
  PLAN -->|頁籤開關| RISK
  IS -->|版本與支援期| SC
  P -->|AO 屬性 evidence-source| AOP
  RISK --> AOP
  SC --> AOP
  PARTY --> AOP
  IS --> AOP
圖 1 — 資源庫如何流到 CRA 專案(虛線=建庫時依框架帶入)

本文件只管 CRA 層;平台層兩項(規劃頁看條文、無 AO 開工)見 design-platform.md,兩份可平行施工。


§3

分工概述(30 秒版)

整案一句話:CRA 專案多出一套 CRA 專用的欄位、角色與風險評估頁,AO 調整為 49 個並可直接連到系統內的證據來源;CMMC 專案一個像素都不變。

卡 Case No 做什麼 規模 決策者檢查法
F1 表單設定落點 CM-2690 module_frames 加 form_settings 欄、程式驗結構 S DEV 查 CRA 資源庫 form_settings 有值、CMMC 資源庫是 NULL
F2 專案取設定端點 CM-2693 兩支 GET 端點:資源庫取、專案 SSP 取 S Swagger 打 GET /ssp/<CRA 專案 SSP uid>/form-settings 回欄位清單;打 CMMC 專案回 null
F3 前端動態欄位與頁籤開關 CM-2699 受評標的頁依設定渲染擴充欄位;BE 收送 ext_fields/ext_links M CRA 專案受評標的頁多四段、填完重整還在;CMMC 專案畫面不變
F4 建庫帶 CRA 預設 CM-2700 create_resource_library 依框架 code 帶表單設定 22 欄、A2.1~A2.9 預設說明、兩個 Party 空殼 S~M 畫面新增 CRA 資源庫:表單設定、預設說明、兩個空角色都在;新增 CMMC 資源庫什麼都沒多
V1 資訊系統版本子表 CM-2694 jedi-asset 新子表+CRUD+盤點頁子表格 M 盤點任一筆底下新增 v1.0/v1.1,各有上市日與支援期結束日
R1-a 風險評估本體 CM-2701 新表 oscal.ssp_risks、DDD 四層、端點、手填表格 M CRA 專案新增兩筆風險、勾對應控制項、重整還在
R1-b 頁籤開關與依據標準 CM-2702 頁籤依表單設定顯示;「依據標準」下拉讀 system_menus S CMMC 專案看不到頁籤;風險編輯的依據標準有 10 項下拉
C1 AO 拆分範本 CM-2691 首版 AO 拆分文件與套件 seed 004 S 打開 md 看拆點與依據
C1b AO 全面調整 CM-2696 新群組、拆條、改句、建議證據三段式掛各 AO、套件 seed 005 M~L 框架 4 群 34 條 49 AO;每個 AO 有自己的建議證據
C2 收舊套掛檔+刪舊 clone CM-2695 控制項層舊上傳路徑刪除、詳情改讀程序書池;刪舊 clone 端點 M POST /module-frame/clone 回 404;控制項詳情 reference_documents 回池資料
C2b 撤回程序書 locator CM-2697 拔掉加錯層的 locator 欄與前後端帶欄 S~M oscal.ssp_reference_document_mappings 無 locator 欄
C3 文件範本骨架 CM-2703 五份 docx 骨架,建庫時上傳進程序書池並預掛 S 新 CRA 資源庫程序書頁有五份、15 條控制項共 16 筆掛載
E1 AO 證據來源機制 CM-2704 AO 屬性 evidence-source、解析端點、規劃頁與判定頁依屬性切顯示 M 風險評估那條 AO 面板顯示「證據來源:風險評估頁,已登錄 N 筆」並可跳轉,不顯示上傳區

依賴:F1 → F2 → F3 → R1-b;R1-a 與 F3 合流後 R1-b;F4 依賴 F1,畫面等 F3;C3 依賴 F4(共用建庫機制);C1 → C1b → E1;C2 → C2b;V1 隨時可派。

§4

決策定案

決策者已裁

項 裁示 被排除的方案與原因
D1 複製資源庫 本期範圍外;專案直接讀資源庫的表單設定 新做複製服務:要連 catalog、profile、SSP 範本、流程範本、程序書池一起處理,L 級工程,第二期用不到
D2 表單設定落點 compliance.module_frames 加 JSONB 欄 form_settings,結構檢查在應用層 新表 module_frame_form_settings:多 repo、mapper、RLS 政策,最小版用不到每欄一列的約束
D3 專案取設定 主專案新端點,不改 jedi-compliance-audit DTO 改套件 DTO 加欄:要為一個欄位發套件版本、碰其他 consumer
D5 公版資源庫 公版機制裁撤:不隨安裝出貨 CRA 資源庫、不用 seed CLI;驗收由決策者從畫面新建 CRA 資源庫與專案 出貨公版並提供 --rebuild:資源庫是顧問的事,出貨公版要連帶處理既有專案引用
D6 AO 拆分 不等顧問;依 ENISA 底稿、第〇步拆點、法條原文自產,標「AI 拆分待顧問確認」,經套件 seed 進框架;範圍由矛盾掃描報告與決策者裁示擴大為全面調整(§6.7) 等顧問先拆:卡住第二期驗收
D7 兩套程序書掛法 收掉控制項層舊上傳路徑,詳情 API 改讀程序書池;程序書不加 locator(程序書是公司 SOP,掛控制項證明有規定,不指章節) 在程序書對應加 locator:加錯層,「證據指到檔內某節」屬證據那條
D9 風險評估存哪 新表,掛專案 SSP,欄位對齊 OSCAL 風險物件;與改善計畫(POA&M)分開 借 AR 殼(主體錯、要先造評估計畫);借 POA&M(與「改善計畫=結案才有」的心智模型衝突);SC.props JSON 陣列(多人覆寫、無外鍵、統計要拆 JSON)
D10 文件範本 顧問主筆;runner 只做格式,本期放骨架佔位;骨架放 repo,建庫時走 F4 機制上傳並預掛 AI 起稿直接出貨:對外法律文件需有人負責內容
D11 舊 clone 端點 刪,FE 常數一起刪 保留:無人呼叫,讓人誤以為已有「複製資源庫」
D13 製造商與通報窗口 製造商與漏洞通報聯絡人是 SSP metadata 的 Party,以角色掛上;揭露政策網址、安全通告頁、聲明取得位置是 SSP link;支援期結束日、產品識別等單值走 SC.props ext: 前綴 全放 SC.props:通報模組要讀「人」與聯絡方式,props 存不了結構;放資訊系統主檔:改 jedi-asset 主表且所有框架都看得到
D14 自家 SBOM 成證據 本期範圍外 —
D15 證據來源機制 AO 多「證據來源」屬性,指向系統內已有的資料;規劃頁與判定頁依屬性切顯示(§6.11) 全部要客戶匯出再上傳:同一件事兩份真相;為每個來源各做獨立頁:重複造輪子
D16 下拉選項進字典表 畫面下拉、單選、分類標籤的選項一律存 public.system_menus,由主線 phase=seed migration 寫入,FE 走既有選單讀取 選項寫進 FE 元件或框架預設內容:管理員想加一項要改程式
D17 風險評估不做威脅清單與精靈 系統不出威脅清單、不自動帶入;顧問填威脅時選「依據標準」(下拉)並自填條號 內建威脅庫:系統不是有公信力的單位;全自由文字:沒有人會填

實作層決定(本文件定案)

編號 決定 理由
C-P1 form_settings JSON 結構固定三鍵:version(整數,現為 1)、sections(物件,布林開關)、groups(陣列,每組 key/title/fields[]);欄位物件 key/label/type/required/options/help/reason。type 限 text/textarea/url/date/select/boolean textarea、url 是 text 的顯示變體,型別檢查仍歸四型;reason: true 讓布林題自帶「理由」文字欄,八題適用判定不必拆 16 個欄位
C-P2 欄位值存受評標的 SC.props,鍵一律 ext:cra-*;理由欄鍵為 <key>-reason 避開既有 target-type/owner-uid;ext: 前綴讓 OSCAL 匯出時一眼看出是產品擴充
C-P3 新端點只讀:GET /module-frame/<uid>/form-settings、GET /ssp/<uid>/form-settings;SSP 版只服務專案 SSP(經 ctx.project.module_frame_id 取資源庫),資源庫範本編輯頁用資源庫 uid 那支 規劃頁手上只有專案 SSP uid;資源庫範本編輯頁手上只有資源庫 uid
C-P4 Party 角色 id:manufacturer、vulnerability-contact,登記進 system_menus 群組 ssp_party_role;現行 DEV 沒有 oscal.oscal_roles 表,不寫該表 沿用既有 9 個角色的 kebab-case 命名;FE 下拉自動多兩項
C-P5 角色掛法沿用產品既有做法:party 本體的 props.responsible-role,不寫 metadata.responsible_parties 建專案時 party uuid 會重產(jedi-oscal-v2 metadata_clone_service.py),metadata.responsible_parties 照原樣複製會指到舊 uuid
C-P6 link 存受評標的 SC.links(OSCAL [{href, rel, text}]),rel 用 ext:cra-disclosure-policy/ext:cra-advisories/ext:cra-doc-location SC.links 已有欄且建專案深拷貝自然帶過;oscal.metadata.links DEV 0 筆使用、無服務寫入入口
C-P7 風險表名 oscal.ssp_risks;租戶隔離比照 compliance.source_scans(tenant_id+org_unit_id+RLS FOR ALL,ENABLE+FORCE) oscal.* 既有表沒有租戶欄、RLS 擋不到;新表一開始就補上
C-P9 AO 的 part_id 為 <control_id>_obj.<N>,N 從 3 起算(1=_smt、2=_gdn 已佔);sort_order 與 N 相同;props 不帶 workflow-template-uid 對齊 CMMC 的 _obj.N 與 sort_order 一致慣例;流程範本 uid 由建庫時 _init_ao_workflows 補,seed 寫死會指到不存在的範本
C-P10 建庫預設內容放 app/oscal/service/framework_library_defaults/<框架 code>.py(純資料),由 __init__.py 的 REGISTRY 以框架 code 查表;查無=什麼都不寫 一框架一檔,新增框架只加一檔一列;CMMC 沒有檔,行為不變
C-P11 AO 證據來源存 AO part 的 props,名 evidence-source;狀態不隨控制項樹回傳,另打端點取 控制項樹已很重;先例是 workflow-template-uid 同樣存 AO props

§5

接入點

項目 落點 做法
資源庫表 compliance.module_frames;ORM infra/module_frame/models/module_frame.py、mapper module_frame_mapper.py、entity module_frame_entity.py form_settings JSONB 欄,三處帶欄
建庫入口 app/oscal/service/resource_library_app_service.py 的 create_resource_library 建庫尾端兩行呼叫 apply_framework_defaults,同一交易
建庫預設內容 app/oscal/service/framework_library_defaults/(__init__.py 查表套用、cra_2024.py 純資料) 表單設定、A2.x 預設說明、Party 空殼、文件範本清單
受評標的 props module_frame_system_characteristic_service.py(資源庫端)、ssp_system_characteristic_app_service.py(專案端,讀 require_participant、寫 require_manager) 擴充鍵走同一合併工具,收送 ext_fields/ext_links
Party 資源庫 module_frame_party_service.py、專案 ssp_party_app_service.py;角色存 props.responsible-role;FE ModuleFramePartiesPanel.vue 讀 system_menus ssp_party_role 兩個角色進字典表;建庫預建兩筆空殼
風險 新表 oscal.ssp_risks;稽核結果層 oscal.assessment_risks 不動 四層+頁籤
下拉字典 public.system_menus(group/key/value/sort/enable/public) 角色、風險依據標準都在這
資訊系統 compliance.information_systems(jedi-asset,有 tenant_id/org_unit_id、RLS 已開) 版本子表+套件 migration 006+子表格元件
程序書池 oscal.ssp_reference_document_mappings 與資源庫程序書池服務 module_frame_reference_document_service.py 建庫時上傳範本並預掛;詳情 API 讀池資料
AO oscal.catalog_control_parts name=assessment-objective,底下的 guidance 子段落放該 AO 的建議證據;建庫補流程範本 _init_ao_workflows 套件 seed 005;讀法 app/oscal/service/control_part_prose.py 的 ao_guidance_map

體積:ProjectPlanningView.vue、ssp_control_implementation_service.py、RoundAuditReviewView.vue 已超標,本期在這幾檔只准刪與少數幾行(一行 v-if、字典補欄),新邏輯一律新開檔;InformationSystemManage.vue 797 行貼線,子表格必須新開元件。

§6

詳細設計

6.1 表單設定

資料庫:migration scripts/sql/2026-10-11-fr135-module-frame-form-settings.sql

ALTER TABLE compliance.module_frames ADD COLUMN IF NOT EXISTS form_settings JSONB;
COMMENT ON COLUMN compliance.module_frames.form_settings IS '表單設定:專案受評標的多顯示哪些欄位、哪些 SSP 子頁籤;結構由應用層驗';

NULL=照固定畫面(CMMC 不受影響)。不新建表,既有 GRANT 與 RLS 照舊。manifest.tsv 登記 active *,出貨基線待重產。

三層帶欄:ORM form_settings: Mapped[Optional[dict]] = mapped_column(JSONB, nullable=True);mapper 兩向帶;entity 建構子加參數。

結構驗證:app/module_frame/service/form_settings_schema.py 的 validate_form_settings(dict) -> dict,檢查三鍵、type 白名單、key 必為 ext: 開頭且不重複、select 必有 options。不合格拋 BadRequestError(ModuleFrameErrorCode.MODULE_FRAME_FORM_SETTINGS_INVALID)(MODULE_FRAME_400013)。唯一寫入者是建庫預設(§6.9),寫入前驗一次;讀取端不再驗。

組的兩個選填鍵:collapsed(布林,前端預設折疊該組)與 gate({when_any_true, when_any_false, message_key},兩個陣列只能列本組的布林欄位;任一題命中即判「不在範圍」,前端收起其餘組並顯示 message_key 的提示,使用者仍可手動展開)。CRA 的「適用判定」排第一組並帶 gate,其餘四組 collapsed: true;沒有這兩鍵的設定照舊全部展開。sections.nist_fields: false(CRA 預設)讓共用基本欄位藏起 FIPS 199 與授權邊界兩欄與頂部 NIST 導向說明;有表單設定時共用欄位也包成同樣的可折疊組「系統基本資料(各框架共用)」,預設展開。

端點(api/module_frame/routes/form_settings_route.py,app service app/module_frame/service/form_settings_app_service.py):

端點 守門 回傳
GET /module-frame/<uid>/form-settings verify_module_frame_exists_by_uid(uid)(讀) {"data": <form_settings 或 null>}
GET /ssp/<ssp_uid>/form-settings SspPermissionChecker.require_read_access(ssp_uid) 專案 SSP:ctx.project.module_frame_id → 資源庫設定

兩支都只讀。

前端(FE repo):

  • src/composables/useFormSettings.js:依 apiBase 打兩支端點之一、快取。
  • src/components/grc/ssp/SspExtFieldsSection.vue:吃 groups,各型別對應 PrimeVue 元件(InputText/Textarea/Calendar/Dropdown/InputSwitch),reason: true 的欄位下方多一個理由框;送出走既有 system-characteristic PUT,多帶 ext_fields: {<key>: <value>}。
  • SspBasicSection.vue 底部一行掛 <SspExtFieldsSection v-if="settings?.groups?.length">。
  • SspTabPanel.vue:「風險評估」子頁籤 v-if="settings?.sections?.risk_assessment",其他子頁籤不動。
  • BE 受評標的服務 _apply_payload 多收 ext_fields:只接受 ext: 開頭的鍵,逐鍵 _set_prop;_to_dict 回傳 ext_fields(把 props 中 ext: 開頭者攤平)。資源庫與專案共用此對應,兩頁同時生效。

CMMC 不變的條件:form_settings 為 NULL 時,端點回 null、前端兩個 v-if 都不成立,DOM 與 CMMC 現況相同。

CRA 資源庫的表單設定內容(cra_2024.py 的 FORM_SETTINGS;label 為繁中、help 簡述法源;5 群 22 欄):

{
  "version": 1,
  "sections": {"risk_assessment": true},
  "groups": [
    { "key": "scope", "title": "產品用途與環境", "fields": [
      {"key": "ext:cra-intended-purpose", "label": "預期用途", "type": "textarea", "required": true, "help": "Art. 3(12);技術文件第 1 項"},
      {"key": "ext:cra-foreseeable-misuse", "label": "可合理預見的誤用", "type": "textarea", "required": true, "help": "Art. 13(3) 風險評估要涵蓋"},
      {"key": "ext:cra-operational-environment", "label": "預期使用環境", "type": "textarea", "required": true, "help": "Annex II 第 4 項"},
      {"key": "ext:cra-operator-role", "label": "客戶在 CRA 的角色", "type": "select", "required": true, "options": ["manufacturer", "importer", "distributor", "authorised-representative", "open-source-steward"], "help": "Art. 3(13)~(18)"}
    ]},
    { "key": "applicability", "title": "適用判定", "fields": [
      {"key": "ext:cra-q-eu-market", "label": "會在歐盟市場上市或提供", "type": "boolean", "reason": true, "help": "Art. 2(1)"},
      {"key": "ext:cra-q-digital-elements", "label": "產品含數位元素(軟體或含軟體的硬體)", "type": "boolean", "reason": true, "help": "Art. 3(1)"},
      {"key": "ext:cra-q-data-connection", "label": "預期用途包含與裝置或網路的資料連線", "type": "boolean", "reason": true, "help": "Art. 2(1)"},
      {"key": "ext:cra-q-pure-saas", "label": "是純 SaaS(無製造商設計的遠端處理以外的產品部分)", "type": "boolean", "reason": true, "help": "前言 (12);純 SaaS 不在範圍"},
      {"key": "ext:cra-q-spare-part", "label": "是同規格替換用的備品", "type": "boolean", "reason": true, "help": "Art. 2(6)"},
      {"key": "ext:cra-q-open-source-non-commercial", "label": "是非商業活動提供的開源軟體", "type": "boolean", "reason": true, "help": "前言 (18)~(19)、Art. 24"},
      {"key": "ext:cra-q-sector-exempt", "label": "已受專法規範(醫療器材、汽車、民航、船舶等)", "type": "boolean", "reason": true, "help": "Art. 2(2)~(4)"},
      {"key": "ext:cra-q-defence-security", "label": "專為國安或國防目的開發", "type": "boolean", "reason": true, "help": "Art. 2(7)~(8)"}
    ]},
    { "key": "classification", "title": "產品分級與支援期", "fields": [
      {"key": "ext:cra-product-class", "label": "產品分級", "type": "select", "required": true, "options": ["default", "important-class-i", "important-class-ii", "critical"], "help": "Art. 7~8、Annex III/IV;細節見 (EU) 2025/2392"},
      {"key": "ext:cra-product-class-reason", "label": "分級理由(對到 Annex III/IV 哪一類)", "type": "textarea"},
      {"key": "ext:cra-support-end-date", "label": "支援期結束日", "type": "date", "required": true, "help": "Art. 13(8)、Annex II 第 7 項"},
      {"key": "ext:cra-support-end-reason", "label": "支援期長度的理由", "type": "textarea", "required": true, "help": "Art. 13(8):至少 5 年,短於預期使用期需說明"}
    ]},
    { "key": "annex2", "title": "Annex II 產品識別", "fields": [
      {"key": "ext:cra-product-name", "label": "產品名稱與型號", "type": "text", "required": true, "help": "Annex II 第 3 項"},
      {"key": "ext:cra-product-identifier", "label": "產品識別(類型、批號、序號或版本)", "type": "text", "required": true, "help": "Annex II 第 3 項"},
      {"key": "ext:cra-sbom-access", "label": "SBOM 取得方式(若對使用者提供)", "type": "textarea", "help": "Annex II 第 9 項(選擇性)"}
    ]},
    { "key": "links", "title": "公開資訊網址", "fields": [
      {"key": "ext:cra-disclosure-policy", "label": "漏洞揭露政策網址", "type": "url", "help": "Annex II 第 2 項"},
      {"key": "ext:cra-advisories", "label": "安全通告頁網址", "type": "url", "help": "CRA.II.4/II.8 引用"},
      {"key": "ext:cra-doc-location", "label": "EU 符合性聲明取得位置", "type": "url", "help": "Annex II 第 6 項"}
    ]}
  ]
}

欄位數:scope 4、applicability 8、classification 4、annex2 3、links 3,共 22 個;8 題適用判定各帶理由欄,3 個網址欄存 links、其餘 19 欄加 8 個理由欄,props 最多 27 鍵。八題的「理由」對應 Art. 2 範圍判斷,是技術文件要寫的「為什麼適用/不適用」。欄位 key 是 SC.props 的鍵,有專案填過值就是資料契約,不可改名。

6.2 Annex II 單值與預設說明文字

Annex II 九項按 D13 分三類:

Annex II 項 控制項 落點 鍵或角色
1 製造商名稱、地址、聯絡方式 CRA.A2.1 Party(§6.3) 角色 manufacturer
2 漏洞通報單一聯絡點、揭露政策位置 CRA.A2.2 Party+link 角色 vulnerability-contact;rel=ext:cra-disclosure-policy
3 產品名稱、類型、識別 CRA.A2.3 SC.props ext:cra-product-name、ext:cra-product-identifier
4 預期用途、安全環境、功能 CRA.A2.4 SC.props ext:cra-intended-purpose、ext:cra-operational-environment
5 已知或可預見的風險情境 CRA.A2.5 風險評估表(§6.4) —
6 EU 符合性聲明取得位置 CRA.A2.6 link rel=ext:cra-doc-location
7 技術支援方式、支援期結束日 CRA.A2.7 SC.props ext:cra-support-end-date、ext:cra-support-end-reason
8 安全安裝、更新、停用等說明 (a)~(f) CRA.A2.8 拆 AO(§6.7)+證據 —
9 SBOM 取得方式 CRA.A2.9 SC.props ext:cra-sbom-access

安全通告頁網址另以 rel=ext:cra-advisories 存,供 CRA.II.4/II.8 引用。

link 怎麼編輯:受評標的服務 _apply_payload 多收 ext_links: [{rel, href, text}],只接受 ext:cra- 開頭的 rel,同 rel 覆寫、其他 link 保留;_to_dict 回傳 ext_links。表單設定的 links 群組宣告三種 rel 的標籤,SspExtFieldsSection 以文字框渲染網址,型別 url。欄位 key 要 ext:cra- 開頭才存得進 links。

預設說明文字:A2.1~A2.9 九條的 implementation-description 寫進資源庫範本 SSP 的實作需求 props(module_frame_control_default_service.py 的 _P_DESC),建專案隨範本 SSP 複製。文字放 cra_2024.py 的 A2_DEFAULT_DESCRIPTIONS,英文、每條 2~4 句,說明「這段資訊放在使用者資訊的哪一章、對應受評標的哪個欄位」,標 [AI draft – consultant to confirm]。只寫入該資源庫 profile 內的控制項。

6.3 製造商與通報聯絡人

角色登記(migration scripts/sql/2026-10-12-fr135-cra-party-roles.sql,manifest.tsv 登記 seed *):

INSERT INTO system_menus ("group", key, value, sort, enable, public) VALUES
('ssp_party_role', 'manufacturer',          'manufacturer',          100, 1, 1),
('ssp_party_role', 'vulnerability-contact', 'vulnerability-contact', 110, 1, 1)
ON CONFLICT DO NOTHING;

只寫 system_menus;DEV 沒有 oscal.oscal_roles 表。冪等,資料類不進出貨基線。FE ModuleFramePartiesPanel.vue 從 system_menus 讀,下拉自動多兩項,所有框架都看得到這兩個選項——這是可接受的副作用(選項存在不影響 CMMC 既有資料)。i18n 標籤走 lang.oscal_role.ssp_party_role.<key>.label,roleLabel() 查不到時退回顯示 key,不會壞。

角色怎麼掛:沿用產品既有做法(C-P5)——party 本體 props.responsible-role。同一角色允許多人(例如通報聯絡人有主要與備援),由現有參與單位頁增刪。

CRA 資源庫預建空殼:建庫預設(§6.9)呼叫既有 ModuleFramePartyService.add_party 兩次:

party_type name role 說明
organization Manufacturer (to be filled) manufacturer 客戶在專案參與單位頁改名、填地址、email
organization Vulnerability contact (to be filled) vulnerability-contact 填通報信箱或網頁表單網址

名稱帶 (to be filled) 讓顧問一眼看出還沒填。建專案時 clone_metadata_with_party_map 整批複製 party,專案端由 ssp_party_app_service.py 讀寫,FE 參與單位頁不用改。

第三期接點:通報模組讀專案 SSP metadata 下 props.responsible-role in ('manufacturer','vulnerability-contact') 的 party,取 name/email_addresses/props.address。

6.4 風險評估新表

表:oscal.ssp_risks(migration scripts/sql/2026-10-12-fr135-ssp-risks.sql)

欄 型別 對齊 assessment_risks 說明
id BIGSERIAL PK 同
uid UUID NOT NULL UNIQUE — 對外識別
tenant_id BIGINT NOT NULL — RLS 依此隔離(C-P7)
org_unit_id BIGINT — 租戶表必含
ssp_id BIGINT NOT NULL FK → oscal.system_security_plans.id ON DELETE CASCADE 取代 ar_result_id/poam_id 專案 SSP
sort_order INT NOT NULL DEFAULT 0 同
uuid UUID NOT NULL 同 OSCAL risk uuid,匯出用
title TEXT NOT NULL 同 威脅(一句話)
description TEXT 同(原為必填) 威脅情境說明
statement TEXT 同(原為必填) 受影響資產
status VARCHAR(40) NOT NULL DEFAULT 'open' 同 open/investigating/remediating/deviation-approved/closed(OSCAL risk-status,有 CHECK)
threat_ids JSONB 同 依據標準:[{key, system, id, href}],畫面開放讀寫(見下)
characterizations JSONB 同 衝擊與可能性:[{facets:[{name:"impact",value:"high"},{name:"likelihood",value:"moderate"}]}]
mitigating_factors JSONB 同 既有控制:[{description}]
remediations JSONB 同 處理措施:[{lifecycle:"planned", title, description}]
related_control_ids JSONB 新 對應控制項 ["CRA.I.2.d", …]
component_uuids JSONB 新 元件連結預留:SSP 元件 uuid 陣列;畫面不出現
props/links JSONB 同 OSCAL 擴充
remarks TEXT — 備註
created_user/updated_user VARCHAR(255) 同 審計
created_at/updated_at TIMESTAMPTZ NOT NULL DEFAULT now() 同

不帶 origins/deadline/risk_log/related_observations(屬稽核發現,風險評估期沒有)。description/statement 可空,讓顧問先記一句威脅再補。衝擊與可能性用 OSCAL characterizations.facets 存,值域 low/moderate/high,風險等級在畫面算(衝擊與可能性取較高者),不存欄。

migration 登記 active *(出貨基線待重產):ENABLE+FORCE ROW LEVEL SECURITY、POLICY ... FOR ALL(超管放行或 app_tenant_allowed_for_session(tenant_id))、GRANT ... TO cm_app 含 sequence、索引 (ssp_id)、(tenant_id)。

依據標準:風險編輯對話框的「依據標準(選填)」每列三格:標準名(下拉)、條號(自由文字)、網址(選填)。

  • 標準名選項讀 public.system_menus 群組 risk_reference_standard(D16;migration scripts/sql/2026-10-12-fr135-risk-reference-standards.sql,seed *,十列:etsi-en-303-645、iec-62443-4-2、iec-62443-4-1、en-18031、iso-iec-27005、capec、attack、owasp-iot-top10、enisa-threat-landscape、other)。管理員可在系統選單維護頁增刪;顯示名優先走 i18n lang.risk_reference_standard.<key>。
  • 存進 threat_ids 的 key 是 system_menus.key(程式用)、system 是顯示名;選 other 時標準名變文字框自填。
  • 條號 placeholder 與網址樣板(CAPEC、ATT&CK 填條號後自動帶網址)是只含附加屬性、不含選項本身的 FE 小對照;其餘用 value 當提示。
  • 後端 app service 去前後空白、丟掉「標準名和條號都空」的列、網址沒填就不存 href 鍵;網址只有 http://、https:// 開頭才渲染成連結。
  • 第一版不做威脅清單與精靈,依據由顧問自標(D17)。

DDD 四層(主專案,不進套件——SSP 層風險是產品概念):

層 檔
domain domain/oscal/entity/ssp_risk_entity.py、domain/oscal/repository/i_ssp_risk_repo.py(介面)、domain/oscal/service/ssp_risk_domain_service.py
infra infra/oscal/model/ssp_risk.py、infra/oscal/mapper/ssp_risk_mapper.py、infra/oscal/repository/ssp_risk_repo_impl.py(繼承 BaseRepositoryImpl)
app app/oscal/service/ssp_risk_app_service.py:讀 require_participant、寫 require_manager;tenant_id/org_unit_id 取自專案;審計欄暱稱以 enrich_audit_nickname_objs 補 *_user_name
api api/oscal/routes/ssp/ssp_risk_route.py、api/oscal/serializers/ssp/ssp_risk.py;DI 進 di_containers/oscal/

端點:GET/POST /ssp/<ssp_uid>/risks、PUT/DELETE /ssp/<ssp_uid>/risk/<risk_uid>。related_control_ids 寫入時驗證每個 id 在該專案的控制項範圍內(查法與控制項導航樹同一個 profile 解析),不在拋 GRC_400140;刪改時同時比對風險屬於該 SSP,找不到拋 GRC_404051(common/code/flow_control_error_code.py),同步 FE i18n。

前端:src/components/grc/ssp/SspRiskAssessmentSection.vue(DataTable+編輯對話框;衝擊、可能性兩個下拉,風險等級顯示徽章、依據標準多列、對應控制項多選),掛在 SspTabPanel.vue 子頁籤,v-if="settings?.sections?.risk_assessment"。

與 POA&M 不互動:不讀、不寫 assessment_risks;稽核結果頁不顯示。GRC 期再決定是否合併(§後續)。

6.5 資訊系統版本子表

套件 migration jedi-asset/jedi_asset/migrations/006-information-system-versions.sql:

欄 型別 說明
id SERIAL PK
uid VARCHAR(50) NOT NULL UNIQUE 比照母表
information_system_id INTEGER NOT NULL FK → compliance.information_systems.id ON DELETE CASCADE
version VARCHAR(100) NOT NULL 版號,同母表唯一 (information_system_id, version)
release_date DATE 上市日
support_end_date DATE 支援期結束日
support_end_reason TEXT 支援期長度理由
remarks TEXT
tenant_id INTEGER NOT NULL 比照母表
org_unit_id INTEGER
created_user/updated_user VARCHAR(50)
created_at/updated_at TIMESTAMPTZ NOT NULL DEFAULT now()

RLS 四支政策照母表寫法(select/insert/update/delete 各一)、GRANT cm_app 含 sequence。build 期自動同步到主專案 scripts/sql/packages/jedi_asset/ 與 packages/manifest.tsv。

套件四層:infra/models/information_system_version.py、mapper、repo;domain/entity+domain/repository;app/service/information_system_version_service.py(新檔,不塞進母服務);api/routes/information_system_version_route.py:

端點 守門
GET/POST /information-system/<uid>/versions 讀/寫各套母表的 information_system_read_capability/information_system_update_capability
PUT/DELETE /information-system/<uid>/version/<version_uid> update_capability

FROZEN_URLS(routing.py)同步加兩條;能力點沿用母表,不新增。jedi-asset 版號 1.2.4,發版等決策者明示。

前端:src/views/information-system/InformationSystemVersionTable.vue,InformationSystemManage.vue 的編輯對話框底部一行掛上(該檔 797 行,只准加一行)。

SSP 端不動:受評標的以 inventory_items.props 的 ref-type/ref-id 軟連到資訊系統。「專案選定某個版本」本期不做;受評標的的 ext:cra-product-identifier 由顧問手填版本字串。

6.6 程序書與證據是兩套

🔴 概念鐵則:程序書 ≠ 證據,兩套路、兩種畫面,不可混

程序書=公司的 SOP/流程文件(CMMC、ISO 都有),掛在控制項上,證明「公司有這個規定」,不指檔內章節。證據=證明達到控制項要求的附件,掛在準備期工作(job evidence)底下。

程序書的對應表 oscal.ssp_reference_document_mappings 只有「哪份檔掛哪個控制項/AO」,沒有出處欄。第〇步缺口「證據指不到檔內某一節」屬證據那條,是否在證據上加出處另案討論,不在本文件範圍。

舊路已收掉:控制項層舊上傳與刪除(add_reference_documents、delete_reference_document)、AO 層舊讀寫與其 route 已刪,FE 對應呼叫一併刪除;控制項詳情 API 的 reference_documents 讀程序書池對應。ssp_control_implementation_service.py 超標,這塊只刪不加。

6.7 AO 全面調整

結果:CRA 框架為 4 群組、34 條控制項、49 個 AO,每個 AO 可獨立判定「有/沒有」,句型比照 CMMC(句首 [a]、[b] 字母配合分類器解析)。依據是 cra-ao-contradiction-scan-2026-10-12.md 的矛盾掃描與決策者裁示。

動作 內容
新群組 Articles 13 and 14 三條:CRA.ART.13.RA 風險評估(3 AO)、CRA.ART.13.SP 支援期(3 AO)、CRA.ART.14.RP 通報(3 AO)。三件製造商義務的法源在 Article 13/14,不在 Annex I
搬移 CRA.I.1 底下三個屬 Article 13 的 AO 搬到 CRA.ART.13.RA;搬移是改掛(保留原列 id、換控制項與 part_id),不是刪掉重建
拆 6 條 CRA.I.2.c、CRA.I.2.f、CRA.I.2.m、CRA.II.1、CRA.II.4、CRA.II.8;CRA.II.6 不拆
改句 既有 AO 依矛盾掃描改寫,消除互相重疊與一句多件事
建議證據 每個 AO 底下掛一個 guidance 子段落,內容為三段式:Deliverable(交什麼檔或紀錄)、Must show(審閱者要在裡面看到什麼)、Evidence(upload|system — <頁面>|template — <範本>);不帶 [obj.N] 與 [beyond ENISA] 之類內部標記

內容單一來源:scripts/cra_ao_content.py,產生器 scripts/gen_cra_ao_restructure.py 一次產出 cra-assessment-objectives.md、cra-suggested-evidence.md 的建議證據段與套件 seed 005。AO 句與證據依 docs/reference/CRA/ 法條原文自寫,不抄 ENISA 或 EN 40000 條文;Basis(依據)欄只進 md,不進 seed。md 頁首標「AI 依 ENISA 子要求拆分,待顧問確認」。

套件 seed 005 jedi-oscal-v2/jedi_oscal_v2/migrations/005-cra-2024-ao-restructure.sql(套件版號 2.5.4,發版推 Nexus 等決策者明示):

  • 冪等:每列 INSERT ... WHERE NOT EXISTS (part_id),重跑計數不變;catalog_id 以 CRA catalog 固定 uuid 定位。
  • name='assessment-objective'、parent_id=NULL(CMMC 也是平鋪)、part_id='<control_id>_obj.<N>'、N 從 3 起(C-P9)。
  • AO 的 guidance 子段落 parent_id 指向該 AO。

讀法陷阱:AO 底下的 guidance sort_order=1 會排在控制項層 _gdn 前面。控制項層的 statement/guidance 只取 parent_id 為空的列,AO 層建議證據走 control_part_prose.py 的 ao_guidance_map;framework_version_edit_service 的 _guidance_prose/_upsert_part 同樣加此過濾,否則瀏覽對話框與編輯會被子段落干擾。

生效範圍:只對之後新建的資源庫與專案(建庫整份複製 catalog)。

6.8 文件範本

本期只做骨架佔位(D10):五份 docx,每份有封面、法源、版本紀錄表、目錄,每節一句「此節要寫什麼、依據哪條」與紅字 [Consultant to complete] 佔位,內容由顧問日後替換。

檔 掛的控制項
CRA-CVD-Policy-Template.docx(協調漏洞揭露政策) II.5、II.6、A2.2
CRA-Security-Advisory-Template.docx(安全通告) II.4、II.8
CRA-Support-Period-Statement-Template.docx(支援期聲明) A2.7、I.2.c
CRA-User-Information-Template.docx(Annex II 使用者資訊) A2.1、A2.3、A2.4、A2.5、A2.8
CRA-Update-and-Decommission-Procedure-Template.docx(更新與停用程序) I.2.m、II.2、II.7、A2.8

合計 15 條控制項、16 筆掛載(A2.8 同時掛兩份)。

  • 產生腳本 scripts/generate_cra_doc_templates.py(python-docx 手寫,可重跑覆蓋),產物放 app/oscal/templates/cra/——打包腳本只帶清單內的資料夾,此路徑已在清單內。
  • 建庫預設(§6.9)把檔上傳到系統儲存(與框架 PDF 同一條路),再掛到資源庫程序書池的對應控制項;同一份範本隨建專案被各租戶共用,放建庫者租戶其他租戶會下載不到。不在資源庫 profile 內的控制項不掛。
  • 建專案時程序書池與掛載整批複製(project_start_app_service.py 的 _clone_reference_documents)。

三份法定文件匯出:與上面五份骨架是兩回事——骨架是空白章節給顧問主筆,匯出是從專案已填資料直接組出內容的 docx(D4 只出 docx),顧問下載後可再改字。

匯出 format 值 範本
Annex VII 技術文件 cra-annex7 CRA-Annex-VII-Technical-Documentation-Export.docx
Annex II 使用者資訊 cra-annex2 CRA-Annex-II-User-Information-Export.docx
EU 符合性聲明(Annex V) cra-doc CRA-EU-Declaration-of-Conformity-Export.docx
  • 端點沿用 GET /ssp/<uid>/export?format=…,同一顆 oscal.ssp.export 能力點、同樣只限專案參與者;非 CRA 專案(表單設定沒開風險評估段)回 412 GRC_412059。
  • 產生在 app/oscal/service/export/cra_legal_docs_export_service.py,每份一支 context 組裝;內容來源:受評標的 ext:cra-* 欄與連結、風險評估(含依據標準,歸併成「採用標準」表)、資訊系統版本(支援期以最新版本為準,沒建版本才讀 ext:cra-support-end-date)、參與單位 manufacturer/vulnerability-contact(名字仍是建庫佔位的不算填了)、控制項實作說明(Annex VII 列全部控制項)。
  • 沒填的欄位印 (not provided);符合性聲明的簽署人、地點日期與簽名留底線空白給製造商親簽。
  • 範本由同一支 scripts/generate_cra_doc_templates.py 產(docxtpl {{ }} 佔位,變數名與 service context 鍵對應);重跑會順手重寫五份骨架的檔案時間戳,只改匯出範本時記得還原那五份。
  • 規劃頁「匯出」選單:CRA 專案多這三項,CMMC 等其他框架看不到。

6.9 建資源庫時帶框架預設內容

顧問從畫面新增資源庫、框架選 CRA 時,create_resource_library(app/oscal/service/resource_library_app_service.py)在建庫尾端兩行呼叫 FrameworkLibraryDefaultsService.apply_framework_defaults(rl_uid, framework_id, user),與建庫同一交易,任一步失敗整個建庫回滾。

流程:由 framework_id 反查 oscal.frameworks.code(CRA 是 CRA_2024)→ 以 REGISTRY 查 framework_library_defaults/<code>.py → 依序寫入:

  1. 表單設定(先 validate_form_settings,再設到 module_frames.form_settings)
  2. A2.1~A2.9 預設說明(只寫 profile 內的控制項)
  3. 兩個 Party 空殼
  4. 五份文件範本上傳並預掛

查無該框架 code=什麼都不寫,CMMC 行為不變。預設內容寫在資源庫層即可:建專案時 party、SC props、範本 SSP 的控制項預設值、程序書池都會整批複製。

陷阱:

  • DI 迴圈:既有控制項預設值 service 依賴資源庫 service,資源庫 service 再依賴它會成環。預設內容 service 另組一支不帶資源庫 service 的控制項預設值 service,少掉的「控制項必須在 profile 內」守門由預設內容 service 先用 resolve_profile 過濾。
  • module_frame repo 的 update 會把 entity 所有非空欄位寫回,entity 的 enable 預設 0。自己 new 一個 entity 去 update 會把新庫打回草稿;要讀回完整 entity 再改 form_settings。
  • 只對新建的資源庫生效:舊資源庫不補預設內容;驗收一律用新建的庫與專案。

6.10 刪舊 clone 端點

clone_module_frame service、route(註冊於 api/module_frame/__init__.py)、schema、FE src/config/api/api.js 的 MODULE_FRAME_CLONE 已刪(D11)。刪前 grep BE/FE/test 三處確認無呼叫端;刪後端點少一條,route guard inventory 守衛清單同步。

6.11 AO 證據來源機制

問題:CRA 有一批證據是客戶在系統其他頁填完就有的——風險評估頁籤、每條控制項的適用/不適用與理由、受評標的的支援期結束日與產品識別、參與單位的製造商與通報聯絡人、資訊系統版本、FR-134 的 SBOM 與弱點掃描。只有「上傳檔案」一種掛法,客戶得把系統裡的東西匯出再傳回來,同一件事兩份真相。矛盾掃描報告標出 116 點建議證據中 15 點主要來源是系統內、另 10 點混合。

做法:AO part 的 props 多一個 evidence-source:

{"name": "evidence-source", "value": "<type>", "ns": "guidant"}

值由 §6.7 三段式第三段 Evidence: system — <頁面> 轉出,由框架 seed 以冪等 UPDATE 寫入。六種 type:

type 讀哪裡 狀態句例
risk-assessment oscal.ssp_risks 筆數與最後更新 已登錄 6 筆,最後更新 10/12
applicability 該專案控制項的適用/不適用判定數 已判定 28/34
system-characteristic:<ext-key> 受評標的 props 該鍵的值 已填:2031-12
party:<role> 有無該角色 party 且名稱不是 (to be filled) 尚未填寫
information-system-version 受評標的所連資訊系統的版本數 已登錄 2 個版本
source-scan 該專案最近一次原始碼掃描 最近掃描 10/10

BE:

  • app/oscal/service/ao_evidence_source.py:一支 resolve(ssp_id, source),六個 type 各一小函式,回統一形狀 {type, label_key, status: 'filled'|'empty'|'partial', count, summary, link: {route, params}};各物件的讀取走既有 service,不另寫查詢,不新增表。
  • AO dict 帶 evidence_source: {type, ref}(只帶 type 與 ref;ssp_control_implementation_service.py 超標,只加幾行,解析放新檔)。
  • 端點 GET /ssp/<ssp_uid>/ao/<part_id>/evidence-source(參與者可讀)取狀態,lazy 打,避免控制項樹變重。

FE:

  • 新元件 src/components/grc/planning/AoEvidenceSourcePanel.vue:顯示「證據來源:<白話名稱>」、狀態一行、「前往」按鈕(router 到對應頁籤)。
  • 規劃頁 AO 面板(ProjectPlanningView.vue):evidence_source 有值 → 掛 AoEvidenceSourcePanel、隱藏關聯程序書與上傳區;無值 → 照舊。一行 v-if。
  • 稽核判定頁(RoundAuditReviewView.vue、AuditControlRef.vue):有值顯示來源狀態與「前往」,稽核員看那頁判定。
  • i18n 兩語系:六種 type 的白話名稱與狀態句。

稽核判定邏輯不改:稽核員仍手動判定,本機制只改「看證據的入口」。

收證據任務:evidence-source-only 為 true 的 AO(沒 AO 的控制項看 catalog_controls.props)啟動稽核與覆核輪都不產收證據任務,統計卡也就不算它;混合型(有 evidence-source 但 only 不是 true)照常產。判斷在 prep_job_generation_service.py,與規劃頁藏上傳區同一旗標。

CMMC 不變:CMMC 所有 AO 無此屬性,畫面與現況完全相同。

§7

拆分

共通鐵則(每張卡都適用,開卡照抄):只動 DEV;不切 branch、不 push;顯式 git add;動到已超標檔只准刪或一行呼叫;migration 照 sql-migration skill(日期註解、GRANT、schema_migrations、manifest.tsv,active * 要回報出貨基線待重產);套件走 path dependency、發版等令;commit 前跑 test/test_module_boundaries.py 與 RLS 形狀守衛;做完 commit+Notion 回寫+子卡改「修正待驗證」。

卡 Case No 依賴 規模 重點
F1 表單設定落點 CM-2690 無 S §6.1 資料庫、三層帶欄、validate_form_settings;本卡需單元測試(結構守門屬共用邏輯)
F2 專案取設定端點 CM-2693 F1 S §6.1 兩支 GET;SSP 版只服務專案 SSP
F3 前端動態欄位與頁籤開關 CM-2699 F2 M BE ext_fields/ext_links 收送;FE useFormSettings.js、SspExtFieldsSection.vue;驗收專查 target-type/owner-uid 未被清掉
F4 建庫帶 CRA 預設 CM-2700 F1 S~M §6.9 機制+cra_2024.py 內容+角色 migration;FE i18n 兩個角色標籤;畫面等 F3
V1 資訊系統版本子表 CM-2694 無 M §6.5;套件異動,發版等令
R1-a 風險評估本體 CM-2701 無 M §6.4 新表+四層+端點+FE 表格;新租戶表,RLS 形狀守衛要綠,本卡含 repo 層 RLS 測試
R1-b 頁籤開關與依據標準 CM-2702 F3、R1-a S 頁籤 v-if+依據標準下拉(讀 system_menus,seed migration 一支)
C1 AO 拆分範本 CM-2691 無 S 首版 AO 拆分文件與 seed 004
C1b AO 全面調整 CM-2696 C1 M~L §6.7;套件 seed 005、BE/FE 讀 AO 自己的建議證據
C2 收舊套掛檔+刪舊 clone CM-2695 無 M §6.6 收舊路、§6.10 刪 clone;套件異動等令
C2b 撤回程序書 locator CM-2697 C2 S~M 拔掉 locator 欄與前後端帶欄;保留 C2 收舊路
C3 文件範本骨架 CM-2703 F4 S §6.8;產生腳本+五份 docx+建庫預掛
E1 AO 證據來源機制 CM-2704 C1b M §6.11;resolve 六個 type 各一 case 的測試,突變拿掉任一分支要紅;FE 新 v-can 掛點要重跑權限矩陣
%%{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
  F1 --> F2 --> F3 --> R1b["R1-b"]
  R1a["R1-a"] --> R1b
  F1 --> F4
  F3 -.畫面.-> F4
  F4 --> C3
  C1 --> C1b --> E1
  C2 --> C2b
  V1
圖 2 — 卡依賴(虛線=跨 design-platform.md)
§8

端到端驗收

用非 102 租戶的帳號,從畫面新增一個 CRA 資源庫、再用它建驗收專案,逐項做(批次跑完再一次回報):

  1. 受評標的頁出現四段 CRA 欄位+三個網址欄;填滿、存檔、重整都在;DB SC.props 只多 ext:cra-*,target-type/owner-uid 仍在。
  2. A2.1~A2.9 控制項實作說明已預填英文草稿。
  3. 參與單位頁有「製造商」「漏洞通報聯絡人」兩筆空殼,改名填 email 後重整還在。
  4. 「風險評估」子頁籤出現;新增兩筆、勾對應控制項、依據標準下拉有 10 項;CMMC 專案同一頁沒有此頁籤。
  5. 框架為 4 群 34 條 49 AO;準備期工作按 AO 數產生(平台層 B)。
  6. 規劃頁看得到每條控制項的 guidance(平台層 A)與每個 AO 自己的三段式建議證據,沒有 [obj.N] 標記。
  7. 程序書頁有五份範本,15 條控制項共 16 筆掛載;自行再掛一份成功。
  8. 資訊系統盤點頁新增兩個版本。
  9. 風險評估那條 AO 的面板顯示證據來源與狀態並可跳轉,不顯示上傳區(E1)。
  10. 開一個 CMMC 專案,規劃頁、受評標的、參與單位下拉以外的畫面與改版前截圖一致(下拉多兩個角色屬預期)。

§9

風險與陷阱

🔴 預設內容只在建庫當下寫入,任何 seed 或預設內容對既有資源庫無效

AO、guidance、表單設定、預設說明、party 空殼、文件範本全部只對建庫之後的新資源庫生效。驗收一律用新建的資源庫與專案,不拿第〇步測資驗。

陷阱 後果 對策
建專案時 party uuid 重產 用 uuid 指 party 的寫法(metadata.responsible_parties)在專案端斷鏈 只用 party 本體 props.responsible-role;第三期通報模組照此讀
受評標的整包覆寫 清掉固定 8 欄或 target-type/owner-uid ext_fields 逐鍵 _set_prop;F3 驗收專查
照抄 oscal.assessment_risks 欄位 該表 RLS 未開,新表沒隔離 ssp_risks 必含 tenant_id+org_unit_id+RLS FOR ALL
兩個新角色進全域下拉 CMMC 專案參與單位也看得到「製造商」 無害、不過濾;要只在 CRA 出現需新機制,本期外
docx 範本是資料檔 Nuitka 不自動帶,客戶端建庫時上傳失敗 範本放 app/oscal/templates/cra/(打包清單內);出包後確認 image 內有五份
建庫預設的 repo update 寫回 entity 全部非空欄位 新庫被打回草稿(enable 預設 0) 讀回完整 entity 再改欄位
AO 底下的 guidance 排在控制項層 _gdn 前面 控制項層取到 AO 的證據 控制項層只取 parent_id 為空的列
ProjectPlanningView.vue、ssp_control_implementation_service.py、RoundAuditReviewView.vue 超標 往裡加會被 reviewer 判阻斷 只准刪與少數幾行,邏輯進新檔

§10

已知未做與後續

項目 去向
複製資源庫(連表單設定一起帶) D1,GRC 期
自家 SBOM 掃描結果轉控制項證據、定期執行證明 D14,FR-134 後續或 GRC
證據(job evidence)指到檔內某一節的出處欄 另案討論
專案選定資訊系統的某個版本 第三期三份文件需要時再做;本期以 ext:cra-product-identifier 手填
畫面上的表單設定編輯器、條件顯示、驗證規則 GRC 期
風險評估與改善計畫(POA&M)合併、組織層風險登錄、依元件建議威脅 GRC 期;component_uuids 已預留
框架版本瀏覽對話框列出 AO 層建議證據 小卡,未開
文件範本正式內容、Annex II 預設說明、AO 拆法 顧問確認後以框架新版本或補灌修正
「填欄位自動產出」三份法定文件 第三期

§11

與其他需求關係

  • design-platform.md(P2-A):平台層 A(規劃頁條文與建議證據)、B1~B3(無 AO 開工、覆核輪)。驗收第 5、6 項依賴它;兩份文件改不同檔,平行施工不衝突。
  • 第三期通報模組:讀 §6.3 的 party 與 §6.2 的 ext:cra-*、link;版本子表供支援期到期排程。
  • 第三期三份文件匯出:欄位來源是 SC.props、party、風險表、版本子表。
  • FR-134 原始碼掃描:source-scan 證據來源讀其掃描紀錄;SBOM 轉證據本期不接(D14)。
  • CM-2687 框架版本預覽第三態:獨立卡,不在本文件範圍。