# FR-038 OSCAL GRC 核心架構重設計 — 詳細需求分析

> 狀態：需求分析（Phase 0/1）· 待 user review 後進入設計/計畫
> 來源：`draft-requirement.md` + PM 教材 `OSCAL_稽核生命週期_PM教材.html` + 現況盤點（jedi-oscal / BE / FE / v2 schema）
> 撰寫日：2026-06-14

---

## 0. 一句話總結

把現在「只套用 OSCAL **概念**、底層大量自定義欄位、用 AP 兼當稽核輪次」的實作，
重寫成「**正式 OSCAL v1.2.2 物件模型**落地、三層 clone/snapshot 邊界清楚、稽核輪次獨立成 `project_audit_rounds`」的專業 OSCAL GRC 系統。
範圍橫跨三個 repo：**jedi-oscal-v2（全新套件）+ 主專案 BE + 主專案 FE**。

---

## 1. 現況問題診斷（為什麼要打掉重練）

盤點現有 `jedi-oscal 0.0.22` + 主專案後，確認以下結構性問題（這些是「重練」而非「重構」的理由）：

| # | 問題 | 現況 | 影響 |
|---|------|------|------|
| P1 | **大量自定義欄位偏離 OSCAL** | SSP 有 `template_module_frame_id`/`is_template`/`group_id`/`version_no`；AP task 把 assessment-methods 壓成 JSON；ResponsibleParty 是無 uid 的 link record | 無法無損匯出標準 OSCAL、跟外部工具不互通、欄位語意混亂 |
| P2 | **用 AP 兼當「稽核輪次」** | 1 AP = 整個稽核 arc，多輪靠 `assessment_result_datas.run_no` 疊加 | 輪次語意藏在 AR 子表，狀態機綁在 AP 上，二次稽核/改善覆核難建模（user 明指「這設計是不對的」）|
| P3 | **catalog 階層與 AO 落地不標準** | 舊 `catalog_control_assessments` 用自定義 `assessment_method` 欄；AO 不是用 OSCAL `part` 表達 | 跟 NIST SP 800-53A 的 part/assessment-objective 結構對不上 |
| P4 | **Profile 只存 include 旗標、靠 runtime join 回母表** | `profile_controls.include` | PM 教材明列地雷：「不能只存 id 即時 join 回會變動的母表」→ 母版改動會抽換進行中的工作 |
| P5 | **三層 clone 邊界不乾淨** | MF defaults 與 template SSP 兩套並存（FR-036 才剛退役 *_defaults）；snapshot 概念散落 | 「單一真相來源」不成立，改一處對不齊其他 |
| P6 | **AR 缺總結層、AP 幾乎不存在** | AR 只有逐條 verdict；AP 前端只有列表沒有編輯畫面；無系統風險總結 | 稽核生命週期的 Phase 3（稽核員寫 AR/findings/risks）斷掉 |

> PM 教材 §市場定位：**Phase 3（外部稽核員寫 AR/findings）是市場空白區**，多數產品到此斷掉 —— 這正是本次重設計要補的核心價值。

---

## 2. 目標架構：OSCAL 三層 + clone/snapshot 邊界

依 PM 教材 §09「三層架構與 clone 邊界」，目標是把控制集分三層存放，**每層邊界都做一次「複製並固定」**，讓上游改動不波及下游進行中的工作：

```
第 1 層 · 合規框架（母版,很少改）
  catalog 母版 ── group→control→part(AO) 樹 · 永不硬刪 · 改版=新增 framework_version
  profile ── 從 catalog 挑控制 + 指向特定 framework_version
        │  解析 + clone（建立資源庫時）
        ▼
第 2 層 · 合規資源庫（公版範本,稽核顧問維護,共用）
  catalog 副本（已挑選、已固定）+ 公版 profile + 公版 SSP 範本
        │  專案成立 → clone（脫鉤公版）
        ▼
第 3 層 · 專案（這個專案自己的,可編輯）
  專案 catalog 副本 ★單一真相來源
  SSP / AP / AR / POA&M ── 全部 import 指向同一份控制副本,不互相複製
        │  啟動稽核 → snapshot（再凍結一份）
        ▼
  凍結的 SSP 快照 + 控制定義 ── 稽核判定的不變依據
```

**四個 clone/snapshot 邊界（每個都是「複製並固定」）：**
1. profile resolve → 資源庫 catalog 副本（建立資源庫時）
2. 資源庫三件組 → 專案三件組（專案成立時，脫鉤公版）
3. living SSP → 凍結 SSP 快照（每輪啟動稽核時）
4. （框架改版）= 新增 framework_version，不原地改舊版

**鐵則（PM 教材明列地雷）**：副本要存「內容」或指向「永不原地改的版本化控制」，**不能只存 id 即時 join 回會變動的母表**。這直接否定現有 P4 的 profile 做法。

---

## 3. 資料架構重設計

### 3.1 jedi-oscal-v2 全新套件

- **新開資料夾** `~/Projects/Jedicogy/module/jedi-python-package/jedi-oscal-v2/`，**不在舊 jedi-oscal 下改**，進入 v2.0。
- **沿用的優良設計**（從舊套件保留概念）：DDD 四層（domain/infra/app/ports）、parser adapter 工廠（CMMC/ISO/NIST 的 PDF/Excel 匯入）、mapper 雙向轉換、BaseRepositoryImpl 慣例。
- **重做的核心**：model 完全按 v2 schema（見 3.2）落地，欄位 1:1 對齊 OSCAL v1.2.2，移除所有 P1 自定義欄位（產品專屬欄位改用 props JSONB 或主專案 mapping 表承接，遵守記憶 `feedback_hybrid_soft_ref_asset_pattern` / `feedback_jedi_package_extraction_pattern`）。
- **對外介面定位**：user 要求「專業的第三方套件模式，因應各種情境讀寫資料給主專案」→ 套件提供 OSCAL 物件的 CRUD + 匯入匯出 + profile resolution + snapshot/clone primitive；主專案業務流程（輪次狀態機、權限、workflow）留在主專案。
- **開發期**：走 poetry path dependency（`feedback_jedi_package_dev_path_first`），feature 完成才正式 bump + 推 Nexus（`feedback_jedi_package_publish_flow`）。

### 3.2 v2 schema 涵蓋度 + 必補缺口

`docs/features/FR-037-2606-oscal-schema-gap-audit/oscal-catalog-and-roots-schema-v2.sql`（42 表、~650 欄、逐欄中文 COMMENT）已是 OSCAL v1.2.2 七大 model 的高保真關聯式落地，**AP/AR/POA&M 都已在內**。對齊度極高。**但落地前必須補三塊：**

| 缺口 | 說明 | 處置 |
|------|------|------|
| **G1 framework / framework_versions 完全沒有** | v2 SQL 不含這兩表（grep 零命中）；FR-038 §23-24 要 `oscal_frameworks→frameworks`、`oscal_framework_versions→framework_versions`；§26 要 `catalogs` 對應一個 `framework_versions` | 新增 `frameworks` / `framework_versions` 兩表 + `catalogs.framework_version_id` FK |
| **G2 schema name** | v2 SQL 直接 `CREATE SCHEMA oscal` | **已定（D1）：直接 drop 現有 `oscal` 重建，schema name 維持 `oscal`，不走 `oscalv2` 過渡**。dev DB 已備份；正式環境遷移走 D7 |
| **G3 缺 `project_audit_rounds`** | user 提出的新輪次表（取代「AP 當輪次」），v2 SQL 沒有（它只管純 OSCAL 物件） | 在主專案 `compliance` schema 新增（見 3.3）|

> v2 schema 已知刻意取捨（非缺陷）：mapping model 裁剪不實作；AP 的 terms-and-conditions/assessment-subjects/assessment-assets/local-definitions 暫 deferred；深層宣告式 leaf 留 JSONB。這些可在後續迭代補。

### 3.3 新增 `project_audit_rounds`（輪次主檔，取代「AP 當輪次」）

這是本次最大的流程架構變更。輪次從「藏在 AP/AR 子表的 run_no」升級成**獨立 first-class 物件**：

```
id              BIGSERIAL PK
project_id      int NN  FK→compliance.projects
name            varchar(255) NN          -- 輪次名稱
round_no        int NN                    -- 輪次編號（1,2,3…）
round_type      enum NN                   -- initial / close-out(覆核) / surveillance(年度抽樣)  ← PM 教材 §08 round_type 分流
status          enum NN                   -- 7 態（見下方狀態機）
parent_round_id int NULL  FK→project_audit_rounds.id   -- 複驗的母輪；NOT NULL ⟺ round_type=close-out（initial/surveillance 為 NULL）
ssp_id          int NULL  FK→oscal.system_security_plans  -- 凍結快照,啟動稽核 SSP 鎖定時才填
ar_result_id    int NULL  FK→oscal.ar_results            -- 該輪對應的 AR result（D2：1 round ↔ 1 ar_results）
start_at / end_at        datetime
created_at / updated_at / created_user / updated_user
```

**狀態機（Q4 定案 = 7 態 + 覆核開新 round）：**
```
尚未開始
  ─[PM 建立輪次]──────────────▶ 專案規劃中    （受評方持續編 living SSP）
  ─[PM 啟動稽核, snapshot SSP]─▶ 稽核規劃中    （稽核員補 AP 草稿：subjects/行程/方法）
  ─[稽核員 開始稽核]──────────▶ 稽核進行中    （稽核員填 AO 全量判定 + finding + risk）
  ─[稽核員 AR 定版]──┬─ 無 not_met ─────────▶ 結案（直接過，無需整改）
                     └─ 有 not_met ─────────▶ 改善計劃中（系統自動生 POA&M）
  改善計劃中 ─[執行人員整改完 + 更新 living SSP]─▶ 待複驗
  待複驗 ─[稽核員 發起覆核]──▶ 自動開新 close-out round（稽核規劃中, parent_round_id=本輪）
```
- 「待複驗」獨立一態 encode PM 教材鐵則「受評方不能自宣告通過，要稽核員複驗」。
- **跨 round 結案連動**：母輪停在「待複驗」；close-out round 定版確認那幾條 AO 過了 → 沿 `parent_round_id` 回頭關閉母輪 POA&M → 母輪轉「結案」。
- 角色：PM(manager) 管輪次/SSP/POA&M 規劃；執行人員做準備 job + 整改；稽核員(auditor) 寫 AP/填 AR/定版/發起覆核。

**輪次 ↔ OSCAL 物件關係（決策 D2 已定 = OSCAL 官方做法）：**
- 1 project → 1 **living SSP**（受評公司持續維護）
- 1 project → N **audit_rounds**（血緣用 `parent_round_id` 串：initial → close-out → close-out…；surveillance 另起）
- 每個 round 啟動稽核時 → snapshot living SSP 成凍結副本（填 `ssp_id`）
- **1 engagement → 1 AP + 1 AR**（engagement = 一個 initial/surveillance 輪 + 其下所有 close-out 覆核輪）；reviewed-controls=完整適用集
  - initial / surveillance 起新 AP+AR；close-out 覆核沿用母輪 AP+AR（細節見 design.md §3 engagement 模型，已取代「1 project 1 AP」的早期表述）
- **每輪 = 一筆 `ar_results`**，往後追加、舊的不改（PM 教材「在原 AR 後追加、第一次不改」）
- **覆核輪縮小範圍** = 該輪 `ar_results` 自帶 narrowed `reviewed-controls`（OSCAL-faithful，範圍從 `parent_round_id` 母輪的 not_met findings 推導），UI 呈現成「該輪的計畫」
- POA&M 用 FK 指回 AR 記錄，不複製（PM 教材「不要真的複製一份」）

---

## 4. 業務流程重設計（新舊對照）

### 4.1 合規框架（FE 不大改 / BE schema rename）

| 面向 | 舊 | 新 |
|------|----|----|
| 主檔 | `oscal.oscal_frameworks` | `oscal.frameworks`（新 schema 重建）|
| 版本 | `oscal.oscal_framework_versions` | `oscal.framework_versions`（新 schema 重建）|
| catalog 關聯 | catalog 自由存在 | `catalogs.framework_version_id` 綁定（一版本一 catalog）|
| 匯入 | PDF/Excel → 自定義 catalog 結構 | PDF/Excel → 標準 catalog/group/control/part(AO) 結構 |

### 4.2 合規資源庫（核心語意調整：catalog + profile + ssp 三件組）

**新定位**：公版稽核範本，由稽核顧問針對各框架設計維護；客戶有需求時拿來成立專案。
由三個 OSCAL 物件組成：**catalog（控制集副本）+ profile（baseline 定義）+ ssp（公用範本）**。

新建資源庫流程：
1. 選一個 `framework_versions` → 把對應 catalog **snapshot 一份**給該資源庫（邊界①）
2. 依 profile 設定，決定哪些 control / AO 納入這份資源庫（profile resolve）
3. 提供匯入 SSP（docx/excel）功能 —— **沿用現有匯入 UI/流程，只把落地資料改用 v2 schema**
4. （取代舊 MF defaults / template SSP 並存）→ 資源庫三件組就是專案的起點母版

### 4.3 專案成立（clone 資源庫三件組）

| 面向 | 舊 | 新 |
|------|----|----|
| 起點 | MF defaults + template SSP（兩套並存）| 最新發布的資源庫三件組，**clone 一份脫鉤**（邊界②）|
| 寫入 | `POST /oscal/projects/start` 單一 @transaction 寫 21 表，AP/AR 當場建好 | 專案成立只 clone catalog/profile/ssp + 建 project 主檔；**AP/AR 延到輪次啟動才建** |
| 控制集 | AP controls snapshot | 專案 catalog 副本 = ★單一真相來源，SSP/AP/AR/POA&M 全 import 指它 |

#### 4.3b 任務執行 / workflow 引擎綁定（Q1 定案）

**「任務執行 / My Jobs」= 受評公司「準備 SSP / 收證據」的工作（Phase 1-2，稽核前）。**
- job 綁在 **專案 SSP 的控制項**上，**專案成立時就建**（clone 資源庫 workflow 設定），**與 AP / 稽核輪次無關**。
- 符合 PM 教材「合規工作八成在準備期、證據在 SSP 階段就備好；AP 裡一份證據都沒有」。
- workflow/job 引擎（jedi-flow-engine）保留，綁定點從「AP task」改為「專案 SSP 控制項」。
- 稽核員執行稽核（Phase 3）走 AR 判定流程，**不**走 job 引擎。
- 影響舊流程 P2：舊 `project-start` 為每個 AP task 建 workflow 的邏輯要改成「為 SSP 控制項建 workflow」，且移到專案成立階段。

### 4.4 SSP 維護 + 啟動稽核 snapshot（FE 不大改 / 語意收緊）

- 啟動稽核前：對專案 living SSP 持續編輯（受評公司）。
- PM 按「啟動稽核」→ 系統 **snapshot 當前 SSP 定版**（邊界③），填入該 `project_audit_rounds.ssp_id`，此後該快照不可改；living SSP 仍可繼續往前改（PM 教材「考試交卷」比喻）。
- **UI 資料 → OSCAL 物件對應**（user 明列，見 §5）。

### 4.5 AP 稽核計畫（**全新，FE + BE 都要做**）

現況：FE 只有 AP 列表、無編輯畫面；概念幾乎不存在。需全新設計。

依 PM 教材 §04，AP 回答四件事（只有①必填，②③④是稽核員臨場專業判斷可省略）：

| # | 內容 | OSCAL | 必填 | 系統可自動帶 |
|---|------|-------|------|------|
| 1 | 查哪些控制 | `reviewed-controls` | ✅ | 由 SSP 快照的適用性(SoA)表自動生草稿 |
| 2 | 會碰哪些東西（人/設備/服務/地點抽查）| `assessment-subjects` | ✗ | 從 SSP 快照資產清單勾選 |
| 3 | 什麼時候查 | `tasks.timing` | ✗ | 稽核員補行程 |
| 4 | 怎麼查（看文件/訪談/實測 + 步驟）| assessment-methods | ✗ | 稽核員補 |

**關鍵設計**：按「開始稽核」系統自動產一份 AP 草稿（標題+對著哪份 SSP 快照+查哪些控制都有現成資料），稽核員再補日期與抽查名單。PM 不用從白紙開始。
> **D3 已定**：本期補 `assessment-subjects`（抽查名單，AP 核心 UX）相關表；assets（工具/團隊）後續。v2 schema 的 `ap_reviewed_controls` / `ap_local_objectives` / `ap_assessment_activities` / `ap_tasks` 已備，subjects 需補表。

### 4.6 AR 稽核結果（**中改：控制項導覽 + AO 層全量判定矩陣 + 風險總結**）

現況：逐「控制項」填 verdict。需補 PM 教材 §05 的三層鏈 + 總結，**並把判定粒度下沉到 AO 層**（Q3 定案 = OSCAL 官方做法）：

```
observation（看到什麼,好壞都記）→ finding（每個 in-scope AO 一筆 met/not_met/pending）→ risk（稽核員手動組,沒過的進整改）
```

| 調整項 | 說明 | 對應 |
|--------|------|------|
| **A1 AO 層全量判定矩陣**（Q3 定案）| 判定下沉到 AO/objective 層：**每個 in-scope AO 一筆 finding**（met/not_met/pending），不是只記沒過的，也不是只到控制項層。OSCAL `finding.target.type="objective-id"`、NIST 800-53A determination statements。UI 以控制項為導覽單位、展開填各 AO（控制項摺疊緩解資料量）| PM 教材 §08 全量判定矩陣；finding 掛 `catalog_control_parts`(AO) |
| **A2 系統風險總結**（Q2 定案 / 新）| 稽核員**手動建 risk**，勾選**哪幾條 finding 組成這個風險（多對多）**，風險等級（low/medium/high/critical）在 **risk 層**由稽核員判定 | v2 `assessment_risks` + `assessment_findings` + finding↔risk 多對多關聯表；**目前完全沒有，需新畫面 + 後端** |
| **A3 observation 引用證據不複製** | `ar_evidences → job_evidence_id` 引用 | PM 教材標「教科書級」，沿用 |
| **A4 AR 定版** | 稽核員寫完即定版，不再改，每輪往後追加一筆 `ar_results` | 狀態機 |

### 4.7 POA&M 改善計劃（**小改**）

現況已完整（列表/詳情/狀態轉換/remediation）。依 PM 教材調整：

| 調整項 | 說明 |
|--------|------|
| **PM1 FK 指回不複製** | poam-item 是「封面」（哪個缺失/為何改），執行細節在連著的 risk；DB 用 FK 指回 AR，只在匯出 OSCAL 時才填實內容 |
| **PM2 整改計畫 + milestone + assignee** | OSCAL `risk → remediations[](response) → tasks[]` 三層忠實落地（B 方案）：`assessment_remediations`（整改計畫）+ `poam_milestones`（里程碑，每個各別負責人，跨部門 M1 歸 IT、M2 歸採購可拆）。milestone 掛在 response 下而非直接掛 risk，匯出 OSCAL 1:1 免合成 wrapper |
| **PM3 deviation / risk_accepted** | ISO 風險接受（Clause 6.1.3）需 `risk_accepted` 分支 → **D5 已定屬 ISO，本期 follow-up，先做穩 CMMC 五態** |
| **PM4 180 天期限** | CMMC 限 180 天，UI 提醒 |

### 4.8 結案 / 二次稽核（覆核）

依 PM 教材 §07 完整流程：
1. 稽核員寫完第一次 AR（定版）→ 換手受評方
2. 系統自動把沒過的 finding 整理成 POA&M 空白卡（搬風險+佐證，FK 不複製）
3. PM 排整改計畫（拆步驟+日期+指派，180 天）
4. 執行人員整改（上傳證據+更新 living SSP）→ 狀態「待複驗」（不能自宣告通過）
5. **發起新 round**（`round_type=close-out`）：**重新 snapshot 當下 SSP**（PM 教材標：沿用舊快照是 bug）→ 範圍縮小只查那幾條 → 在原 AR 後追加第二次 results
6. 全關閉 → 發證；CMMC 180 天逼近告警

**結案判斷**：所有該輪 POA&M closed → round 可結案。年度查核 = 再走一輪（`round_type=surveillance`）。

---

## 5. SSP UI 資料 → OSCAL 物件對應（user 明列）

| UI 資料 | OSCAL 落點 |
|---------|-----------|
| 受評標的 | `system-characteristics` |
| 人員 / 單位 | `parties` + `roles` |
| 證據 | `by-component.links` → `back-matter` |
| 實施計劃 | `props`（planned 日期）|
| 實作狀態 | `props`（implementation-status）|
| 控制實作描述, SoA | `implemented-requirement`（一條控制一筆）：<br>├ props.applicability ← SoA 適用性<br>├ props.inclusion-justification ← SoA 理由<br>├ props.implementation-status ← 實作狀態<br>└ statements[].by-components[]：description ← 實作描述 / links ← 證據綁定 |

> **SoA 釐清（PM 教材 §02）**：SoA 不是 SSP 之前的獨立步驟，而是 SSP 的一部分（每條控制旁標「適不適用+理由」）。要分清兩件事：**「適不適用」**（標不適用→不準備證據、跳過查驗、但不跳過審查理由、永遠不會變缺失）vs **「做了沒」**（已完成/部分/規劃中/還沒做→標還沒做=缺口=會開不符合）。

---

## 6. 前端影響分析

| 區塊 | 現況完整度 | 本期變動 |
|------|-----------|---------|
| 合規框架 | ✅ 100% | 不大改（底層 schema rename，API 對齊）|
| 合規資源庫 | ✅ 100% | 不大改（語意調整成三件組，匯入落地改 v2 schema）|
| 專案列表/建立 | ✅ 100% | 不大改 |
| 專案總覽 | ✅ 100% | 不大改 |
| 專案規劃(SSP) | ✅ 100%（7 tabs）| 不大改（OSCAL 落點對齊；新增「啟動稽核→snapshot」動作）|
| 任務執行 | ✅ 100% | 不大改（綁定點後端從 AP task 改為 SSP 控制項，FE 畫面不動，Q1）|
| **AP 稽核計畫** | ⚠️ 20%（只列表）| **全新畫面**：AP 草稿生成 + reviewed-controls + 抽查名單(subjects) + 行程 + 方法 |
| **AR 稽核結果** | ⚠️ 50%（只逐控制項 verdict）| **中改**：控制項導覽 + **AO 層全量判定矩陣** + **系統風險總結**（稽核員手動組 risk、多對多關聯 finding、等級在 risk 層）|
| **POA&M** | ✅ 100% | **小改**：milestone+assignee、180 天告警、從這裡發起覆核 round（deviation/risk_accepted 屬 ISO，本期 follow-up）|
| 輪次切換 | 現用 run_no | 改對應 `project_audit_rounds`（1 round ↔ 1 ar_results）|

> 與 user 判斷大致一致：合規框架→任務執行不大改；AP 全新、POA&M 小改。**唯一修正：AR 從「小改」上修為「中改」**——因 Q3 定案判定下沉到 AO 層（OSCAL 官方全量矩陣），畫面要從控制項展開到 AO。

---

## 7. 待討論決策清單（重點 — user 明指 ap/as/poam 需討論）

| ID | 決策 | 結論 / 選項 | 備註 |
|----|------|------|---------|
| **D1** ✅ | schema 過渡策略 | **已定：直接 drop `oscal` 重建**（dev DB 會備份）| v2 schema 直接用 `oscal`（不必過渡 `oscalv2`）；不可回頭，正式環境遷移走 D7 |
| **D2** ✅ | 輪次 ↔ AP/AR 基數 | **已定：採 OSCAL 官方做法 = 每 round 1 筆 `ar_results` + 全專案 1 AP + 1 AR** | OSCAL 硬規則：AR.import-ap 單一、results[] 是官方多輪機制、每筆 result 可自帶 narrowed reviewed-controls。`project_audit_rounds` 一列 ↔ `ar_results` 一筆(1:1)。覆核輪「縮小計畫」折進 result 的 narrowed scope（資料 OSCAL-faithful），UI 呈現成「該輪計畫」|
| **D3** ✅ | AP assessment-subjects/assets | **已定：本期做 assessment-subjects（抽查名單），assets 後續** | 需在 v2 schema 補 assessment-subjects 相關表（目前 deferred）|
| **D4** | 系統風險總結資料模型 | 用 v2 既有 `assessment_risks`/`assessment_findings`/`assessment_observations`，補 finding↔risk 關聯表 | 待 design 階段定 schema 細節 |
| **D5** ✅ | 框架範圍 | **已定：本期先做穩 CMMC 流程** | ISO 專屬（risk_accepted deviation、L1⊂L2、SoA 自選排除）標 follow-up |
| **D6** | source_identifier / L1⊂L2 | catalog_controls 加 `source_identifier` 支撐跨框架 crosswalk | CMMC 本期可先加欄位佔位；L1/L2 合併屬 ISO 整合，follow-up |
| **D7** | 舊資料遷移 | dev 直接重建（D1）；**正式環境（stg/poc/prod）遷移策略需另議** | 重大，上正式前必須有遷移計畫 |

---

## 8. 平行開發任務規劃（user 要求 multi-agent 平行加速）

依賴關係決定哪些能平行。**第一波必須先收斂「契約」（schema + 套件介面 + API spec），契約定了之後三 repo 才能真正平行。**

### Wave 0（序列 · 契約收斂，~1-2 天）
- **T0.1 schema 定稿**：補 G1（framework 表）+ G3（audit_rounds）+ D1 schema name 決策 → 產出可執行 migration（dev 先套）
- **T0.2 jedi-oscal-v2 套件骨架 + port 介面定稿**：DDD 四層目錄、對外 service 簽章、snapshot/clone/resolve primitive 介面
- **T0.3 API spec 定稿**：AP / AR 總結 / POA&M / audit_rounds 的 api-spec.md（SA）

> Wave 0 三項彼此相依（schema→套件→API），建議我**序列做但快速**，或 schema 先行、套件骨架與 API spec 平行。

### Wave 1（高度平行 · 套件實作）
契約定稿後，jedi-oscal-v2 各 model 模組可**完全平行**（彼此無共享狀態）：
- **A1** catalog/group/control/part(AO) + framework/version + profile resolution
- **A2** SSP + 12 子表 + UI→OSCAL 落點 mapper
- **A3** AP（reviewed-controls / subjects / tasks / methods）
- **A4** AR（observation/finding 全量矩陣/risk）+ POA&M（item/milestone/deviation）
- **A5** parser adapter 搬移 + 對齊新 catalog 結構（CMMC/ISO/NIST）

### Wave 2（平行 · 主專案 BE）
套件 path-dep 可用後：
- **B1** 合規框架 + 資源庫 API 對齊新 schema（含 profile resolve、資源庫三件組 snapshot）
- **B2** 專案成立流程重寫（clone 三件組、AP/AR 延後建）
- **B3** SSP 維護 + 啟動稽核 snapshot + audit_rounds 狀態機
- **B4** AP 後端（草稿生成 + CRUD）
- **B5** AR 後端（全量判定矩陣 + 風險總結）+ POA&M 小改 + 結案/覆核 round

### Wave 3（平行 · 主專案 FE，可與 Wave 2 部分交疊）
- **C1** AP 全新畫面
- **C2** AR 總結層（判定矩陣 + 風險總結）
- **C3** POA&M 小改（milestone/assignee/deviation/180 天/發起覆核）
- **C4** 輪次切換改接 audit_rounds
- （合規框架/資源庫/專案/規劃/任務 不大改，只 API 對齊驗證）

### Wave 4（序列 · 整合驗證）
- 端到端走一次完整生命週期（精誠機械 CMMC L2 劇本）→ 套件正式發版 → 主專案 pin → schema rename（若 D1 選 a）

> **平行策略總結**：Wave 0 是序列瓶頸（契約），務必先做完；Wave 1 套件模組可開 ~5 個 agent 平行；Wave 2/3 BE/FE 可交疊。我會用 subagent dispatch（顯式 git add、各 repo 分開 commit、不切 branch）。

---

## 9. 下一步

這份是**需求分析**。請 user 針對 §7 決策清單（尤其 **D1 schema 策略 / D2 輪次基數 / D3 AP 範圍 / D5 是否本期含 ISO**）拍板後，我再進 Phase 1 brainstorm → Phase 3 寫 `design.md` + `implementation-plan.md`（含詳細 schema、API spec、平行任務拆解到可執行顆粒）。
