Phase 2 A0.1 執行收尾 — 完整 ship 報告

日期:2026-05-19 本檔角色:A0.1 task arc 收尾總結(執行 session 完成) 前置文件00-plan-handoff.md 是設計階段的 handoff,本檔是執行階段的收尾 狀態A0.1 shipped


§1

一句話總結

A0.1 結構重整補丁(rename items + 新建 main / join + column rename + caller 改寫)按 plan 全跑完,8 個 commits 跨 2 repos + 1 個 device_id e2e 補丁 commit,所有 unit test 全綠,DB schema / DI / yaml 序列化全驗證,主 BE smoke 因環境問題改 partial smoke 也通。


§2

本 session 完成的事

1. 執行 SQL Migration

scripts/sql/2026-05-19-ssp-system-implementation-restructure.sql 已在 dev DB 跑通:

  • 既有表 rename system_security_plan_system_implementationsssp_system_implementation_items
  • Column rename information_system_idsystem_characteristic_id
  • 新建 main ssp_system_implementations(129 個 distinct scope → 129 rows backfill)
  • 新建 join ssp_inventory_item_components
  • Items 加 system_implementation_id NOT NULL FK + 140 筆全部補齊

2. 10 個 Task 全部 ship

Task Commit 範圍 模型
0 Pre-flight verification
1 jedi-oscal 762d8fc items stack 8 檔 rename Ssp*Item* + 5 父層引用 + 3 __init__ + test 改名 haiku impl + sonnet 雙 reviewer
2 jedi-oscal cc65e3b main stack 8 新檔(含 upsert_by_scope)+ 25 個 unit test haiku
3 jedi-oscal c0fcae9 column information_system_idsystem_characteristic_id 跨 7 檔 haiku
4 jedi-oscal d2178c1 items 加 NOT NULL FK + relationship + 7 個新 test haiku
5 jedi-oscal 8e3e58b join stack 8 新檔(含 add_link type 語意驗證)+ 11 個新 test haiku
6 jedi-oscal 4666091 yaml_mapper 加 main block-level + implemented-components + 4 個新 test sonnet impl + sonnet 雙 reviewer
7 主 BE eb9fa7e 2 個 caller + DI + 既有/新 regression test sonnet impl + sonnet 雙 reviewer
8 BE smoke partial(DI / service / DB 4 項都通;完整 boot 撞 gitlab/github env 問題與 A0.1 無關)
9 主 BE 87126ab changelog + tracker + design §11 reconciliation (inline)
10 通知 user + 收口

3. A0.1 e2e 驗證 + 1 個 follow-up fix

驗證(user 提供 SSP id=244, AP cd128dce-...):

  • AP → SSP 串接 / project 229 / 4 人 / 3 設備 / 3 系統都對齊 UI
  • A0.1 三表 main(136) / items(168-170) / FK 全部正確寫入
  • 發現:items 的 device_id 全 NULL(A0 既有 caller 忘了填)

follow-up fix(同日 ship):

  • 主 BE 6deacefproject_device_mapping_service.add()device_id=device_entity.id
  • scripts/sql/2026-05-19-backfill-ssp-system-implementation-items-device-id.sql 已執行 → UPDATE 135 筆 + 10 筆 unmatchable 保留 NULL

4. 文件交付

文件 路徑
A0.1 主 changelog docs/changelog/2026-05-19-tweak-ssp-system-impl-restructure.md
device_id fix changelog docs/changelog/2026-05-19-fix-ssp-impl-item-device-id.md
tracker README docs/features/FR-011.2-2605-ssp-import-export-phase2/README.md(A0.1 row → shipped + 7 commits)
design + reconciliation docs/features/FR-011.2-2605-ssp-import-export-phase2/design-A0.1.md §11(5 條偏離紀錄)
analysis docs/analysis/2026-05-19-ssp-system-impl-restructure-rationale.md
plan handoff docs/conversation-history/2026-05-19/ssp-import-export-phase2-A0.1/00-plan-handoff.md
執行收尾(本檔) docs/conversation-history/2026-05-19/ssp-import-export-phase2-A0.1/SUMMARY.md

§3

完整 commit 鏈

jedi-oscal(6 commits, 全 path-dep 未推 Nexus)

4666091 refactor(ssp-system-impl): yaml_mapper 加 main block-level + implemented-components
8e3e58b feat(ssp-system-impl): 新增 inventory_item_components M:N join 表完整 stack
d2178c1 feat(ssp-system-impl): items 表加 system_implementation_id NOT NULL FK + relationship to main
c0fcae9 refactor(ssp-system-impl): items column rename information_system_id → system_characteristic_id
cc65e3b feat(ssp-system-impl): 新增 main 表 OscalSspSystemImplementation 完整 stack
762d8fc refactor(ssp-system-impl): rename items stack to Ssp* + _items suffix

主 BE(3 commits)

6deacef fix(associations): ProjectDeviceMappingService 寫 SSP item 補填 device_id soft FK
87126ab docs(ssp-import-export-phase2): A0.1 shipped — changelog + tracker + design §11
eb9fa7e fix(ssp-system-impl): 主 BE caller 改寫支援 main 表 + 對齊新 class 命名

累計 9 commits(不含 Task 9 之前的 design / plan / SQL handoff commits)。


§4

測試結果

範圍 passed
jedi-oscal 全套 regression 93
主 BE A0.1-related (regression + main_regression + versioning) 33
累計 126 個 unit test 全綠

§5

DB Schema 最終狀態(dev DB)

oscal.ssp_system_implementations         129 rows (1:1 per SSP scope)
oscal.ssp_system_implementation_items    140 rows (全部 system_implementation_id 補齊)
oscal.ssp_inventory_item_components        0 rows (預期 — 等 caller / UI 觸發)

Hardware items device_id backfill 後:
  hw_total=145, hw_has_device=135, hw_null_device=10 (unmatchable)

§6

關鍵設計決策(design-A0.1.md §11 reconciliation 條目)

  1. yaml_mapper 簽章 backward-compat — items_list 維持第一 positional,避免破壞既有 7 個 yaml_mapper test
  2. _clone_system_implementations 用 SSP relationship — 直接 old_ssp.system_implementations,不另建 old_main → items 反向 relationship
  3. 9 個 OSCAL extension 欄位 clone — 7 個 getattr 安全取,2 個 scope_type/scope_id hardcode
  4. BE smoke partial — 完整 boot 撞 gitlab/github env 環境問題(非 A0.1),改 DI / service / DB sanity 4 項驗證
  5. 3 個 minor robustness follow-up — main audit created_user=None、orphan main、yaml implemented-components 排序

§7

已知 follow-up(不阻 A0.1)

# 項目 嚴重度 建議
1 jedi-oscal Nexus 發版 例行 Phase 2 整體完工再一次性 bump
2 pyproject.toml path-dep 還原 pin Nexus 版本 例行 整 Phase 2 收口時做
3 created_user=None 在 main upsert minor caller 從 auth context 取
4 刪 item 後 main 變孤兒 minor (deliberate) 評估是否要 cleanup
5 yaml implemented-components 多 component 排序 minor sort 一行修正
6 10 筆 hardware items device_id 無法 backfill 業務判斷 確認對應 device 是否該刪
7 主 BE jedi-issue/github boot env 環境 GITHUB_PRIVATE_TOKEN / GITLAB_* 到 .env
8 delete*() by-name 查找改 by-device-id 中型 refactor 另開 task
9 items.system_characteristic_id 沒 caller 填 預期 預留欄位,未來 caller 鉤稽 information_system 時用
10 Join 表 (ssp_inventory_item_components) 沒 caller 自動填 預期 等 SSP 編輯頁「設定 component 屬於哪 inventory-item」feature

§8

部署 handover

對 dev DB 已執行

  • scripts/sql/2026-05-19-ssp-system-implementation-restructure.sql
  • scripts/sql/2026-05-19-backfill-ssp-system-implementation-items-device-id.sql

對 staging / production

  • ⏸ 上述 2 個 SQL migration 需要 user 在對應環境執行
  • ⏸ jedi-oscal 仍在 path-dep 模式,要正式 deploy 前需:
    1. jedi-oscal pyproject.toml bump version
    2. 推 Nexus
    3. 主 BE pyproject.toml 改回 pin Nexus 版本
    4. poetry update jedi-oscal

BE 重啟(user 在配齊 GITLAB_*/GITHUB_PRIVATE_TOKEN env 環境)

lsof -ti:8000 | xargs kill -9
cd ~/Projects/Billows/Audit-Manager/compliance-manager-be
set -a; source .env; set +a
nohup poetry run python main_app.py > /dev/null 2>&1 &

§9

下一階段 — Phase 2 A0.1 之後可推進

兩條 parallel paths

A1:Excel 樣板設計 + 下載

  • 中型 phase(design 段落 + plan,不獨立 brainstorm)
  • 依賴 A0.1(已 ship ✓)
  • 範圍:產出 9 大資料領域(metadata / 單位 / 人員 / 設備 / 資訊系統 / leveraged / 控制項 / AO / 程序書)的 Excel 樣板 + 下載 API

B1:Docx 樣板 + generator 骨架

  • 中型 phase
  • 依賴 A0.1(已 ship ✓)
  • 範圍:SSP docx 匯出格式樣板 + python-docx generator 基礎

兩條可平行起手,依 user 優先級決定。

建議

  • 接手前讀本 SUMMARY.md(執行階段全脈絡)+ 00-plan-handoff.md(設計階段脈絡)
  • A1 or B1 開工前先 brainstorm scope(中型不必但建議先列範圍)
  • 建議先看 docs/features/FR-011.2-2605-ssp-import-export-phase2/requirement-understanding.md §3、§4 確認最新 scope

§10

session 規範遵守清單


§11

結語

A0.1 是 A0 ship 後 e2e 校正的補丁 — 從「items 表名稱誤導 / 缺 main / 缺 join / 鉤稽路徑重疊 / 命名不一致」5 個結構問題收口到「items + main + join 三層完整 OSCAL block 鏡像」。execution 階段照 plan 跑完 10 個 task 沒大偏差,最大的驚喜是 e2e 驗證階段意外發現了 A0 既有 device_id caller 沒填的 bug 並順手修正。

A0.1 task arc 完整收尾。Phase 2 的基礎建設層完成,後續可開始 Track A(Excel 匯入)或 Track B(SSP 匯出)的具體 phase。