| 項目 | 內容 |
|---|---|
| Phase | Phase 1 + Phase 2 COMPLETE |
| 日期區間 | 2026-05-24(Phase 1 全日 + Phase 2 開工) ~ 2026-05-25(Phase 2 完工 + 收尾) |
| Branch(兩 repo 一致) | feature/ssp-oscal-alignment |
| Phase 1 完成 Tasks | 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 14(11 / 14)— 跳 Task 10 E2E / Task 13 套件進版 |
| Phase 2 完成 Tasks | 1, 2, 3, 4, 5A, 5B, 5C, 6, 7, 8, 9, 11A, 11B(13 / 12 — Task 11 拆兩段執行) |
| 主專案 local commits | 30(Phase 1: 14 + Phase 2: 14 + 收尾 hotfix: 2;全 local,未 push) |
| jedi-oscal local commits | 18(Phase 1 全;Phase 2 + 收尾 hotfix 全在主專案) |
| 主專案 working tree | M pyproject.toml(Phase 1 Task 1 dev-only path dep,永遠不 stage;Task 12 Part 2 套件進版時才還原) |
| jedi-oscal working tree | clean |
| Dev DB | 4 新 OSCAL 表 + RLS (delimiter 修好) + 12 LA + 341 components + 0 inv_items;Docx import path 通;Excel import 走 legacy 412(見 §6.2) |
| 下一步 | Phase 3 / Phase 4(user 拍板「衝一下 3, 4」)— 詳見 2026-05-25-phase3-4-handoff.md;Task 12 Part 2 (jedi-oscal bump + push) 仍待 user 拍板 |
✅ Phase 1(Foundation) — OLD 單一 SspSystemImplementationItemEntity 拆成 OSCAL-correct 3 entity(LeveragedAuthorization / Component / InventoryItem + M2M join),落地到 DB + jedi-oscal 套件 + 主專案 BE 全層。12 LA + 341 components migrate verified。18 主專案 callers refactor 完成,舊表 + 舊 M2M 全 DROP。
✅ Phase 2(Import Pipeline 對接) — Import pipeline 拆出獨立 module domain/oscal/import_pipeline/(warnings collector / normalizer / bundle_restore / confirm_service 四檔);3 個 v3 write strategy(LeveragedWriteStrategy / ComponentWriteStrategy / InventoryItemWriteStrategy)落地;orchestrator 採 Minimal scope(只保留 leveraged reconcile);Docx adapter 加 adapt_to_bundle() 輸出 v3;Docx app service 走新 pipeline 全通;Task 11 cleanup 刪 5 src + 4 test 共 1057 LOC dead code。
⚠️ Excel parser gap(§6.2 / design.md §11.13) — Excel app service dispatch 落地但 parser 還沒輸出 v2-bundle dict shape,目前 Excel import 走 legacy path → 412。Phase 3 §3.X 接手。
✅ Subagent-driven mode 跑通(13 個 Phase 2 task),review-after-implementer pattern 多次截到 spec drift(如 Task 11B reviewer 加 SourceTable enum)。
| # | Task | Status |
|---|---|---|
| 1 | 主專案 pyproject.toml path dep | ✅ 落地(dev-only, M pyproject.toml) |
| 2-4 | jedi-oscal PR-1/2/3(LA / Component / Inventory) | ✅ SHIPPED |
| 5 | ParsedExcelEntityBundle restructure | ✅ SHIPPED |
| 6 | DI container wire 3 services | ✅ SHIPPED |
| 7-9 | DB Step 1-3(建表 / migrate / verify) | ✅ SHIPPED |
| 10 | E2E 測試 | ⏭ SKIPPED(Phase 2 重設計,throwaway) |
| 11A/B | jedi-oscal cleanup + 主專案 refactor | ✅ SHIPPED |
| 12 | DROP 舊表 + 舊 M2M | ✅ SHIPPED |
| 13 | jedi-oscal bump + 推 Nexus + 主專案 pin 還原 | ⏭ DEFERRED to Task 12 Part 2 |
| 14 | Mini-handoff | ✅ SHIPPED (2026-05-24-phase1-COMPLETE-SUMMARY.md) |
| # | Task | Status | Commit |
|---|---|---|---|
| 1 | Pre-flight — parsed_result shape reference | ✅ SHIPPED | 6b577a55 |
| 2 | ImportWarnings collector module |
✅ SHIPPED | aee0e991 |
| 3 | ParsedBundleNormalizer + warnings emission |
✅ SHIPPED | ec9d3b20 |
| 4 | SspImportConfirmService + bundle_restore |
✅ SHIPPED | f6069f83 + 901d3460 |
| 5A | LeveragedWriteStrategy v3 |
✅ SHIPPED | dfdc6d98 |
| 5B | ComponentWriteStrategy v3 |
✅ SHIPPED | d8c9a19d |
| 5C | InventoryItemWriteStrategy v3(含 M2M) |
✅ SHIPPED | d547f314 |
| 6 | Orchestrator + leveraged_reconciler v3(Minimal scope) | ✅ SHIPPED | 56f35d83 |
| 7 | Excel app service wire ConfirmService | ✅ SHIPPED(dispatch 落地 / parser gap 見 §6.2) | f4cb9b10 |
| 8 | CmmcSspAdapter.adapt_to_bundle 輸出 v3 |
✅ SHIPPED | e6bc9ede |
| 9 | Docx app service wire ConfirmService | ✅ SHIPPED | c681e3a8 |
| 11A | 刪 v2 strategies + dataclasses + helpers + reconcilers | ✅ SHIPPED | 9165b866 |
| 11B | Reviewer minor follow-ups(SourceTable enum / _strip_nulls DRY 等 7 點) | ✅ SHIPPED | 1e3abaee |
| 12 Part 1 | Changelog + Final SUMMARY + design §11 update + conversation extract | ✅ SHIPPED(本文件) | |
| 12 Part 2 | jedi-oscal 進版 + Nexus push + 主專案 pin 還原 | ⏸ PENDING user 拍板 |
Note:Plan 寫 Task 10 是 E2E pre-flight smoke,Phase 2 期間 user 拍板「重設計後寫」延到 Phase 3+ 一起做。Plan 也沒列 Task 11B(reviewer follow-up),實際是 Phase 2 review checkpoint 後自然產出的 minor cleanup。
6f04da7;Phase 1 期間 ship,Phase 2 全 0 commit)| Commit | 摘要 |
|---|---|
ebadfe8 |
refactor(oscal): remove deprecated SspSystemImplementationItem (Task 11A) |
ac1d860 |
fix(oscal): harden InventoryItem M2M contract (PR-3 follow-up) |
2162af2 |
feat(oscal): add InventoryItemDomainService (PR-3 part 6) |
646cc38 |
feat(oscal): add InventoryItem repo + M2M write path (PR-3 part 5) |
1b22843 |
feat(oscal): add InventoryItemMapper + tests (PR-3 part 4) |
c358d8e |
feat(oscal): add OscalInventoryImplementedComponent M2M ORM (PR-3 part 3) |
9d0db75 |
feat(oscal): add OscalInventoryItem ORM (PR-3 part 2) |
1281121 |
feat(oscal): add InventoryItemEntity + QueryEntity (PR-3 part 1) |
29b3bf0 |
feat(oscal): add ComponentDomainService (PR-2 part 5) |
f498af1 |
feat(oscal): add Component repo + impl (PR-2 part 4) |
697a460 |
feat(oscal): add ComponentMapper + tests (PR-2 part 3) |
fdfd317 |
feat(oscal): add OscalComponent ORM with partial index (PR-2 part 2) |
157d2bc |
feat(oscal): add ComponentEntity + QueryEntity + enums (PR-2 part 1) |
a748205 |
feat(oscal): add LeveragedAuthorizationDomainService (PR-1 part 5) |
fed9970 |
feat(oscal): add LeveragedAuthorization repo + impl (PR-1 part 4) |
773c5eb |
feat(oscal): add LeveragedAuthorizationMapper (PR-1 part 3) |
bf12dc9 |
feat(oscal): add OscalLeveragedAuthorization ORM (PR-1 part 2) |
ab66af0 |
feat(oscal): add LeveragedAuthorizationEntity + QueryEntity (PR-1 part 1) |
d6fab20)Phase 1(14 commits)
| Commit | 摘要 |
|---|---|
dfefab08 |
docs(ssp-oscal-alignment): Phase 1 COMPLETE mini-handoff |
af3b0952 |
SQL migration step 4 — DROP 舊表 + 舊 M2M(Task 12) |
f9e6de75 |
chore — update stale comment after Task 11A provider removal |
2776d151 |
Task 11A — remove deprecated system_implementation_item DI providers |
94891eb3 |
Task 11B-3 — remove 3 backward-compat shims + migrate 11 tests |
176c977b |
Task 11B-2 follow-up — migrate 3 context services props JSONB |
7d1d0a76 |
Task 11B-2 — migrate app services + project layer |
5eaee305 |
Task 11B-1 review — tighten LeveragedWriteStrategy except scope |
8a81c221 |
Task 11B-1 — migrate write strategies from SspSystemImplementationItem |
af0ea339 |
docs — Phase 1 Tasks 2-9 SHIPPED handoff |
1f944e2a |
docs — design.md v1.1 → v1.2 §11 reconciliation |
c5b43fbd |
Task 9 — SQL verification |
567efe73 |
Task 8 — SQL migrate data |
a9712a12 |
Task 7 — SQL create tables + RLS |
2e6849fb |
Task 6 — DI wire 3 services |
95e9efd2 |
Task 5 — ParsedExcelEntityBundle restructure |
Phase 2(14 commits)
| Commit | 摘要 |
|---|---|
1e3abaee |
Task 11B — Phase 2.A/B reviewer minor follow-ups(7 點 cleanup) |
9165b866 |
Task 11A — remove v2 strategies + dataclasses + helpers + reconcilers |
c681e3a8 |
Task 9 — wire Docx app service through SspImportConfirmService |
e6bc9ede |
Task 8 — CmmcSspAdapter.adapt_to_bundle outputs v3 bundle |
f4cb9b10 |
Task 7 — wire Excel app service through SspImportConfirmService |
56f35d83 |
Task 6 — orchestrator + leveraged_reconciler v3(Minimal scope) |
d547f314 |
Task 5C — InventoryItemWriteStrategy v3(M2M write) |
d8c9a19d |
Task 5B — ComponentWriteStrategy v3(consume ParsedComponent, resolve LA ref) |
dfdc6d98 |
Task 5A — LeveragedWriteStrategy v3 |
901d3460 |
Phase 2.A review — bundle_restore preserves reconciler fields + log orchestrator failures |
f6069f83 |
Task 4 — SspImportConfirmService + bundle_restore |
6b577a55 |
Task 1 — parsed_result shape reference |
ec9d3b20 |
Task 3 — ParsedBundleNormalizer + warnings emission |
aee0e991 |
Task 2 — ImportWarnings collector module |
.env)oscal.ssp_leveraged_authorizations rowsecurity=t 12 rows
oscal.ssp_components rowsecurity=t 341 rows (164 hw + 165 system + 12 service)
oscal.ssp_inventory_items rowsecurity=t 0 rows (Phase 3 Excel parser fix 後 Phase 2 confirm 流程才會寫入)
oscal.ssp_inventory_implemented_components rowsecurity=t 0 rows (M2M join)
舊表狀態(Phase 1 Task 12 DROP):
oscal.ssp_system_implementation_items → DROPPEDoscal.ssp_inventory_item_components (OLD M2M) → DROPPEDFK linkage:12/12 service components 全綁回 leveraged_authorizations.uid(Phase 1 migration 期)。
Note:Phase 2 完工但 ssp_inventory_items 仍 0 rows 是因 Phase 2 期間沒新 import;新 import 經 Docx flow 應能寫入,Excel flow 待 Phase 3 §3.X parser 對齊。
POST /api/1.0/ssp-docx-imports/parse + POST /api/1.0/ssp-docx-imports/<uid>/confirm:
ParsedSsp overlay(Stage 1 docx-import-parity caller 仍依賴)+ v2-bundle ParsedExcelEntityBundle(merged into parsed_result with schema_version="v2-bundle")。SspImportConfirmService.confirm()(bundle_restore → normalize → orchestrator → 3 write strategies)。POST /api/1.0/ssp-excel-imports/.../confirm:
schema_version="v2-bundle"。parsed_result.get("schema_version", "v1-ssp") == "v1-ssp" → 直接 raise PreconditionFailedError(GRC_DOCX_PARSE_JOB_LEGACY_SHAPE, 412)。Phase 2 Task 11A 刪:
device_write_strategy.py / information_system_write_strategy.py / base.py AbstractSspComponentWriteStrategy / device_reconciler.py / information_system_reconciler.py)test_a4_write_all_data_pipeline.py / test_a4_reconciliation_device.py / test_a4_reconciliation_information_system.py / test_a4_boundary_cases.py)ParsedDevice / ParsedInformationSystem / ParsedLeveraged)未來 caller 若 import 上述 symbol 會 ImportError — Phase 3+ 引用者請 migrate 到 v3 dataclass + ConfirmService。
| 項目 | 路徑 | 狀態 |
|---|---|---|
| design.md v1.2 + §11 reconciliation(11 + 4 條 = 15 條 deviations) | docs/features/FR-028-2605-ssp-oscal-alignment/design.md |
✅ Phase 2 加 §11.12~§11.15 |
| implementation-plan-phase1.md + SHIPPED markers | docs/features/FR-028-2605-ssp-oscal-alignment/implementation-plan-phase1.md |
✅ |
| implementation-plan-phase2.md | docs/features/FR-028-2605-ssp-oscal-alignment/implementation-plan-phase2.md |
✅(SHIPPED markers 略) |
| Phase 1 mini-handoff | docs/features/FR-028-2605-ssp-oscal-alignment/handoff/2026-05-24-phase1-COMPLETE-SUMMARY.md |
✅ |
| Phase 1+2 Final SUMMARY(本文件) | docs/features/FR-028-2605-ssp-oscal-alignment/handoff/2026-05-25-phase1-phase2-FINAL-SUMMARY.md |
✅ |
| Changelog (batch Phase 1+2) | docs/changelog/2026-05-25-feat-ssp-oscal-alignment-phase1-phase2.md |
✅ |
| Conversation history JSONL extract | docs/conversation-history/2026-05-24/ssp-oscal-alignment-phase2/ |
✅(7 個 .md) |
| Analysis 文件 | design.md §11 涵蓋(不另寫) | ✅ |
⚠️ 3 個 Phase 2 收尾留下的 leftover 抽到 §8(L1 / L2 / L3)獨立列,下方是更早期的 follow-up 清單。
domain/oscal/parser/excel/cmmc_excel_parser.py 需輸出 parsed_result["schema_version"] = "v2-bundle" + components / leveraged_authorizations / inventory_items 三 list(mirror Docx Task 8 adapt_to_bundle)。改完 Excel import 從 412 變 200 + 寫入新表。_parsed_ssp_to_dict_overlay 仍存在於 Docx app service(Stage 1 docx-import-parity 留下的 ParsedSsp overlay logic)— Phase 4 FE preview UI 重設計後可考慮整段刪掉,直接吃 v2-bundle。ImportWarning chip(normalizer.py 已 emit warnings)+ LA / Component / InventoryItem 三 sub-panel;template-edit 5-tab 第四 tab 必須改讀新表 — 這是 user-facing demo readiness 的關鍵 phase(見 §9 demo gap)。2026-05-24-phase1-COMPLETE-SUMMARY.md 延續)implementation_type vs component_type:SspImportTemplateAppService._build_info_systems dict key 改了,Phase 3 e2e 要驗 Excel template 下游沒人依賴舊 key。project_device_route 410-Gone 未實作:tests/test_c3_scope_migration.py::test_gone_response_uses_grc_error_code 用 @pytest.mark.skip,獨立任務。leveraged_authorization_uid 指向已刪 LA.uid)— Phase 4 FE 重設計時處理。AbstractSspComponentWriteStrategy.write() sys_impl_main_id dead param — Phase 2 Task 11A 刪 base.py 後此 follow-up 自動結案 ✅。兩 repo 都還 local,未 push。Push 需 user 明確指示(per CLAUDE.md「push 永遠要 user 明確指示」)。
執行步驟(user 拍板後):
# 1. jedi-oscal bump version
cd ~/Projects/Jedicogy/module/jedi-python-package/jedi-oscal
# 編輯 pyproject.toml: version = "0.0.18" → "0.1.0"
git add pyproject.toml
git commit -m "chore(jedi-oscal): bump 0.0.18 → 0.1.0 (OSCAL Component/LA/Inventory split)"
# push 到 Nexus(依套件 publish flow)
# 2. 主專案 pin 還原
cd ~/Projects/Billows/Audit-Manager/compliance-manager-be
# 編輯 pyproject.toml:
# - line ~80 jedi-oscal pin: "^0.0.18" → "^0.1.0"
# - line ~91 path dep 改回註解(dev-only)
poetry update jedi-oscal
# smoke:python main_app.py 8000 listening + DI 122 modules wired
git add pyproject.toml poetry.lock
git commit -m "chore(ssp-oscal-alignment): bump jedi-oscal 0.0.18 → 0.1.0 + restore pin"
# 3. 兩 repo push(user 明確指示後)
git push origin feature/ssp-oscal-alignment
cd ~/Projects/Jedicogy/module/jedi-python-package/jedi-oscal
git push origin feature/ssp-oscal-alignmentscripts/sql/2026-05-24-ssp-oscal-alignment-*.sql 4 個檔)Phase 4 FE preview UI 是 Phase 1+2 ship 後的後續 task — FE repo 路徑 ~/Projects/Billows/Audit-Manager/compliance-manager-fe,建議切到 FE repo 開新 session 由 FE Claude 主導。Phase 1+2 本身沒動 FE,但 Excel import 412 行為差異會被 FE 既有 error toast 抓到。
Phase 2 Task 12 Part 1 commit (2bd8e7b3) 之後,user 拉 docx import 跑端到端驗證,連續觸發兩個 latent bug:
ba0cdd7a)| 項目 | 內容 |
|---|---|
| 症狀 | docx import 成功,但 template-edit「外部利用服務」tab 仍空白 |
| Root cause | _run_v2_bundle_confirm 只 handle source_type='project_ssp';module_frame branch ssp_id 留 None → SspImportConfirmService 拿不到 ssp_id 直接 skip LA/Component/Inventory writes |
| Fix | 抽出 domain/oscal/service/ssp_shell_service.py(DDD domain-service 層,無 infra import;含 can_build / create_shell / resolve_existing_shell / ensure_shell);docx app service 新增 kwarg ssp_shell_service,module_frame branch 呼叫 ensure_shell() 取得 ssp_id 後才 delegate confirm_service |
| 範圍 | 新檔 domain/oscal/service/ssp_shell_service.py;修 app/oscal/service/ssp_docx_import_app_service.py(__init__ + _run_v2_bundle_confirm + 新 helper _derive_shell_description);Excel inline logic 不動(32 既有 tests 保留) |
| 教訓 | v3 wire-up 必須同時支援 superset / update / module_frame 三種 source_type;v2 → v3 過渡期 Excel/docx 流程 source_type 處理不對稱 → 留後門 latent bug |
d12bd705)| 項目 | 內容 |
|---|---|
| 症狀 | Bug A 修完,docx confirm 第一次從 cm_app 真寫 4 張新表 → DataError: invalid input syntax for type integer: '/1/102/' |
| Root cause | Phase 1 §1.2 spec RLS policy 寫 split by ,;實際 session_scope 設 app.allowed_tenant_paths='/1/102/'(slash-delimited path) |
| Why latent | Phase 1 Task 9 verify 用 cmmgr (superuser bypasses RLS) → false-positive ship;Bug A 沒 fix 時 confirm path 從沒實際 evaluate RLS |
| Fix | DROP + recreate 4 policies (ssp_components_rls / ssp_leveraged_authorizations_rls / ssp_inventory_items_rls / ssp_inventory_implemented_components_rls) 改用 string_to_array(trim(both '/' from ...), '/')::integer[] |
| Migration | scripts/sql/2026-05-24-ssp-oscal-alignment-fix-rls-delimiter.sql |
| 教訓 | 未來新增 RLS policy 一律 cm_app verify(cmmgr superuser 等於沒測);session 變數格式跨套件假設要在 spec 明寫 |
完整 root-cause 寫在 design.md §11.16(RLS)+ 待補 §11.17(Bug A — 本文件下方第 12 段補入)。
⚠️ 3 個未收尾項目,Phase 3/4 接手者開工前先掃過:
| 項目 | 內容 |
|---|---|
| 範圍 | jedi-oscal 套件 pyproject.toml bump、Nexus push、主專案 pyproject.toml path-dep 還原為 pin ^0.1.0、poetry update jedi-oscal、兩 repo git push |
| 阻擋 | user 拍板才執行 — 違反 CLAUDE.md「絕對禁止:自動執行套件發版」+「push 永遠要 user 明確指示」 |
| 時機 | 建議 Phase 3+4 全 ship 後一次性處理;中間 phase 還會改 jedi-oscal(特別 Phase 5 export)就再 bump 一次成本高 |
| 步驟 | 見 §7.1 |
decision=skip → 0 parties 寫入| 項目 | 內容 |
|---|---|
| 症狀 | user 用 docx import flow,diff stepper 顯示 5 parties,user 點確認後 0 parties 落到 DB → template-edit「責任單位 / 責任人員」tab 空白 |
| 推測 root cause | FE diff stepper 預設 decision=skip 而不是 decision=accept;user 沒手動切換就直接送 confirm → BE 全 skip 是正確行為 |
| 待釐清 | (a) FE 給的預設 decision 是哪個?(b) user 在 UI 上看到的有沒有預先 highlight?(c) BE response 顯示的 decision distribution 跟 user 看到的差異 |
| 行動 | Phase 4 FE 重設計時 BE/FE 共查;BE 端不主動改行為(accept-by-default 風險:user 沒看 diff 就誤寫資料) |
content_overrides| 項目 | 內容 |
|---|---|
| 症狀 | user 在 docx preview UI 改 component 類型 / LA 欄位 → submit 後 DB 仍是 parse 時原值 |
| Root cause | ssp_docx_import_app_service._run_v2_bundle_confirm 入口直接 dict_to_bundle(parsed_result["bundle"]);沒套 content_overrides。對比 Excel side ssp_excel_import_app_service._apply_content_overrides 有完整 metadata / system_characteristic / sheet rows / controls overrides handling |
| 範圍(fix outline) | 在 _run_v2_bundle_confirm 入口加 _apply_content_overrides_to_bundle() helper:拆 overrides 對 bundle.components / bundle.leveraged_authorizations / bundle.inventory_items 三 list 做 row-level update(mirror Excel _apply_content_overrides 的 sheet-row loop logic) |
| 注意 | Excel side override 是針對 parsed_result dict path(row_overrides[sheet_key][row_idx]);v2-bundle 已是 dataclass list → 設 idx-based mapping 或 uid-based mapping,需先決定 |
| 時機 | Phase 4 開工時順手做(FE 改 preview 行為 → BE override path 一起對齊) |
這段是 Phase 3/4 接手者必讀 — 解釋為何 Phase 1+2 完成 ≠ user 看得到 import 結果。
| Phase | 完成後 user 能做什麼 | 完成後 user 不能做什麼 |
|---|---|---|
| Phase 1(DDD/DB foundation) | 後台資料模型正確;無 user-facing 行為 | 看不到 component / LA / inventory tab 內容 |
| Phase 2(Import pipeline 對接) | docx import 把 LA + Component + InventoryItem 寫進新表;Excel import 412 提示重傳 | template-edit 5-tab 還是舊架構,看不到新表內容 |
| Phase 3(Excel/Docx 樣板重設計) | Excel import 從 412 變 200 + 寫入新表 | template-edit FE 還是舊架構,仍看不到 |
| Phase 4(FE preview UI 重設計) | template-edit 改讀新 ssp_components / ssp_leveraged_authorizations / ssp_inventory_items 表,user 看到 import 結果 | OSCAL JSON export 還沒 |
| — |
驗證 case:MF 62c31d47-a90e-40e0-98ae-cb0c164a8acc(SSP id=260)
| 後端 DB 真實狀態 | FE template-edit 顯示 |
|---|---|
| 1 LA + 4 Components 寫入新表 | 「外部利用服務 (1)」(只看到 LA) |
| 「設備 (0)」(讀舊 jedi_device 概念表) | |
| 「資訊系統 (0)」(讀舊 jedi_information_system 概念表) |
Root cause:template-edit 5-tab 仍是 Phase 0 設計(OLD 三族 entity device / information_system / leveraged);新表 ssp_components 沒有對應的 tab → 4 個 components 在 FE「不存在」。
驗證 query(密碼請查 .env):
-- 連 cmmgr@192.168.50.188:25432/guidant_ai_dev
SET app.is_super_admin='t';
-- LA 由 SSP id 查
SELECT id, uid, title FROM oscal.ssp_leveraged_authorizations WHERE ssp_id=260;
-- Components 同上
SELECT id, uid, title, component_type FROM oscal.ssp_components WHERE ssp_id=260;
-- 對比 FE 截圖 → 確認 BE 有資料,差距在 FE 沒讀| 層 | 條件 | 由哪個 phase 收 |
|---|---|---|
| (a) BE 寫對 | DB 4 新表有正確資料 + RLS 通過 | Phase 1+2 ✅(已驗) |
| (b) UI 可看到 | template-edit 改讀新 ssp_components / ssp_leveraged_authorizations / ssp_inventory_items;新 tab「元件 + 授權 + 資產」 |
Phase 4(最關鍵 demo gap) |
| (c) 完整 demo 流程 | Excel import 也通(不只 docx)+ OSCAL JSON export | Phase 3(Excel)+ Phase 5(export) |
結論:要做 user-facing demo readiness,先做 Phase 4 收 demo gap;Phase 3 解 Excel import path 但不阻擋 docx demo;Phase 5 是 round-trip 收尾。
本 task arc 全程採 superpowers:subagent-driven-development mode:
| 觀察 | 說明 |
|---|---|
| Reviewer-after-implementer | Task 4 / 11B 兩次抓到 spec drift(bundle_restore 漏 reconciler field / SourceTable enum 該加)— review 投資值得 |
| Token budget | Phase 2 13 task 全 subagent,主 thread token 用量明顯低於同等 monolithic session |
| Wall clock | Task 5A/B/C 三 task 平行 dispatch(共用 v3 dataclass dep)— 比 sequential 快 |
| Trap | Task 6 plan 寫「filter components by type 再 dispatch reconciler」,第一次 dispatch implementer 照寫;review checkpoint 才提「reconciler 已 dead code,跳過更乾淨」→ 採 Minimal scope(§11.12) |
Pattern baked into 後續 phase prompt:DB-touching / 大規模 refactor task 開工前,controller 親查 schema + sample data + 看既有 caller 慣例(trust-but-verify pre-flight),再寫 implementer prompt。
詳細版本(含 Phase 4 優先建議 + Bug B/C 開工前必處理)見 docs/features/FR-028-2605-ssp-oscal-alignment/handoff/2026-05-25-phase3-4-handoff.md。下方為精簡版:
你接手 SSP OSCAL Alignment Phase 3 — Excel/Docx 樣板重設計。Phase 1+2 完整 SHIPPED(28 主專案 commits + 18 jedi-oscal commits,全 local)。請按以下順序讀文件:
1. docs/features/FR-028-2605-ssp-oscal-alignment/handoff/2026-05-25-phase1-phase2-FINAL-SUMMARY.md(本文件 — 5 分鐘)
2. docs/features/FR-028-2605-ssp-oscal-alignment/design.md §11.12~§11.15(Phase 2 reconciliation)— 重點 §11.13 Excel parser gap
3. docs/features/FR-028-2605-ssp-oscal-alignment/design.md §3 Phase 3 段(Excel/Docx 樣板重設計 4d)
4. domain/oscal/import_pipeline/normalizer.py(理解 v2-bundle dict shape)
5. domain/oscal/adapter/cmmc_ssp_adapter.py:adapt_to_bundle()(Docx 端 v3 輸出 reference)
開工前 pre-flight:
1. 兩 repo branch:
git branch --show-current # 預期 feature/ssp-oscal-alignment
git -C ~/Projects/Jedicogy/module/jedi-python-package/jedi-oscal branch --show-current
2. Dev DB 確認 Phase 2 final state(密碼請查 .env):
psql -h 192.168.50.188 -p 25432 -U cmmgr -d guidant_ai_dev -c "
SET app.is_super_admin='t';
SELECT
(SELECT count(*) FROM oscal.ssp_leveraged_authorizations) AS la,
(SELECT count(*) FROM oscal.ssp_components) AS comp,
(SELECT count(*) FROM oscal.ssp_inventory_items) AS inv;"
預期: la=12, comp=341, inv=0
3. Smoke:tail -50 log/app.log,預期無 Traceback;pytest tests/test_ssp_docx_import_app_service.py 應綠
Phase 3 §3.X 首要任務:改 Excel parser 輸出 v2-bundle dict shape,恢復 Excel import 從 412 變 200。
| 用途 | 路徑 |
|---|---|
| Spec v1.2 + §11 reconciliation 15 條 | docs/features/FR-028-2605-ssp-oscal-alignment/design.md |
| Phase 1 plan | docs/features/FR-028-2605-ssp-oscal-alignment/implementation-plan-phase1.md |
| Phase 2 plan | docs/features/FR-028-2605-ssp-oscal-alignment/implementation-plan-phase2.md |
| Phase 1 mini-handoff | docs/features/FR-028-2605-ssp-oscal-alignment/handoff/2026-05-24-phase1-COMPLETE-SUMMARY.md |
| Phase 1+2 Final SUMMARY(本文件) | docs/features/FR-028-2605-ssp-oscal-alignment/handoff/2026-05-25-phase1-phase2-FINAL-SUMMARY.md |
| Phase 1+2 changelog | docs/changelog/2026-05-25-feat-ssp-oscal-alignment-phase1-phase2.md |
| Conversation history | docs/conversation-history/2026-05-24/ssp-oscal-alignment-phase2/ |
| Import pipeline 新 module | domain/oscal/import_pipeline/ |
| 新 entities(jedi-oscal) | ~/Projects/Jedicogy/module/jedi-python-package/jedi-oscal/jedi_oscal/domain/entity/base/oscal_{leveraged_authorization,component,inventory_item}_entity.py |
| SQL migration 4 檔 | scripts/sql/2026-05-24-ssp-oscal-alignment-*.sql |