🟢 START HERE — FR-038 Wave 2(BE 遷移)冷接交接

給下個 session 的 prompt 就一句:「讀 docs/features/FR-038-2606-oscal-redesign/handoff/2026-06-14-WAVE2-START-HERE-handoff.md,接手執行 Wave 2。」 本檔自包含 —— 看完 + 跑完 §6 pre-flight,就能正確開工,不需 user 再解釋。 所有狀態為 2026-06-14 verified(非假設)。

項目
緣由 FR-038 OSCAL 核心重設計;Wave 0(契約)+Wave 1(套件) 已完成,本期做 Wave 2 = 主專案 BE 遷移
branch(兩 repo 皆) feature/oscal-refactor已 push,main origin 5129f57f / 套件 origin 3096f1f
預估 62–81h(115 檔遷移,Type A/B/C)
接手前必讀(按序) 本檔 → §0

⛔ 本 session 範圍:只做 2A,到綠燈就停(別 marathon)

Wave 2 切成 3 棒,這個 session 只做 2A,達到綠燈就停下、寫下一棒 handoff、交給 user 換 session。不要一口氣做完整個 Wave 2(context 會爆、接手會錯 —— 這是 user 最痛的點)。

棒次 範圍 完工綠燈(達到才收,且是下一棒 pre-flight 要驗的)
2A(本 session) Phase 2.0:DI 全切 v2 + 全 Type A import + FK/view 重建 + 最小 Type B 讓 BE 起得來(未遷業務流程先 stub/disable) python main_socketio.py 能 boot + pytest test/ baseline 綠 + My Jobs view 出資料
2B(下個 session) B1 資源庫 + B2 專案成立 + B3 SSP+輪次狀態機 e2e:建專案→clone 三件組→編 SSP→啟動稽核 snapshot 凍結 綠
2C(再下個) B4 AP + B5 AR(AO矩陣)+風險+POA&M + 2.Z e2e:完整 CMMC 生命週期 綠 + baseline 零回歸

收這一棒時的 handoff 協定(防接手做錯,必照做)

  1. 完工斷言:把 2A 綠燈那幾條指令 + 預期輸出寫進新 handoff,下個 session 先跑、綠才信、紅就停。
  2. 起點斷言:pre-flight 數字現場跑命令驗,不抄 subagent 回報。
  3. 每句「X 完成」後面都要有能證明的指令(指令 > 敘述)。
  4. ship 前派 fresh agent 只讀新 handoff 模擬冷接,逼出瑕疵再修。
  5. 決策一律鎖在 requirement-analysis(D1-D7/Q1-Q4),不重新決定。

2A 是最該獨立的一棒:DI 是 all-or-nothing,切一半 BE 起不來=最容易交接出錯處。本 session 唯一目標=讓 BE 在 v2 上重新站起來並 pytest 綠

§0 接手讀序(按此順序,不要跳)

  1. 本檔(現況 + 陷阱 + 開工順位)
  2. wave2-migration-plan.md —— Wave 2 的 phase 拆解(2.0 前置 → B1-B5 → 2.Z)。⚠️ 同資料夾的 implementation-plan.md 是 Wave 1 的計畫(已執行完),不是 Wave 2 —— Wave 2 只看 wave2-migration-plan.md
  3. api-contract.md —— ~51 端點 req/resp 契約(標 [沿用]/[新]/[改])
  4. design.md §3(engagement 模型) §4.2(套件對外 service 簽章) §6(error code)
  5. requirement-analysis.md §3.3(輪次 7 態) §4.5-4.8(AP/AR/POA&M 流程) §5(SSP→OSCAL 落點)
  6. oscal-v2-deltas.sql —— 新增 6 delta 表的精確欄位/CHECK
  7. 2026-06-14-wave1-SUMMARY-and-wave2-handoff.md —— Wave 1 做了什麼的完整紀錄

§1 現況(2026-06-14 verified,不是假設)

  • Wave 1 套件 jedi-oscal-v2 完成~/Projects/Jedicogy/module/jedi-python-package/jedi-oscal-v2/,42 表 + 全邏輯 + snapshot/clone + CMMC 匯入 + OSCAL JSON 匯出,194 tests 全綠(最終 review Approved),57 commits 已 push
  • dev DB oscal schema 已 drop + 重建成新結構(48 表:base 42 + delta 6),compliance.project_audit_rounds 在、4 條 FK 在(ssp_id / assessment_plan_id / ar_result_id / parent_round_id)、7 態 CHECK 在。public.schema_migrations 已加 2 筆(FR-038 base + delta)。
  • 主專案 BE 目前是「新 schema + 舊 code」不一致態 → dev 的 OSCAL 功能現在是壞的。這是全重寫的預期中間態,不是要你去修的 bug。Wave 2 完成才會恢復。
  • 主專案 109 個 source 檔仍 import 舊 jedi_oscal(遷移 surface 一個都還沒動);0 檔用 jedi_oscal_v2
  • pyproject 兩套件並存(verified):line 80 jedi-oscal==0.0.22(舊) + line 81 jedi-oscal-v2(新);line 96/97 兩個 path-dep。jedi_oscal_v2 從主專案 env 可 import(已驗)。

§2 ⚠️ 會讓你做錯的 5 個陷阱(務必先看,這是 user 最在意的)

  1. 不要把 pyproject.toml 的 path-dep commit。它是 dev-only、目前 uncommitted(working tree M pyproject.toml)。BE 要靠它 import jedi_oscal_v2保持不 commit;等套件正式發 Nexus 時才改回 pin 版本一起 commit。若你不小心 commit 了 → reset。
  2. 不要以為 BE「壞了」要去修舊 code。OSCAL 功能壞是因為「新 schema + 舊套件 code」—— 正解是遷移到 jedi_oscal_v2(Wave 2 本體),不是去補舊 jedi_oscal。
  3. DI 切換要一次切乾淨 + 同批改所有 import(Phase 2.0a)。OscalContainer 改 v2 但 consumer 還 import 舊套件 → 整個 BE import 炸。Type A 批次改 import 要跟 DI 同一波完成,才能起 BE。
  4. 舊表沒了,不是改 import 就好。舊 assessment_result_datas / catalog_control_assessments / 舊 AP 子表(assessment_plan_controls/groups/tasks/task_workflow_execution_mapping)在新 schema 都不存在。引用它們的 consumer 要改對新結構(Type B/C),照 wave2-migration-plan.md 的分類做,不要硬改 import 然後撞 ImportError/AttributeError。
  5. 套件方法簽章以實際為準,不要憑本文件猜。開工前 pre-flight 實際讀 jedi_oscal_v2 對外 service(§6 有命令)。計畫寫到開工有時差,method 可能微調。

§3 Wave 2 執行順位(詳見 wave2-migration-plan.md,這裡是骨幹 + 不變的依賴)

2.0 前置(序列瓶頸,先做完才有 BE 可跑)
  2.0a DI 切 v2 + Type A 批次改 import(一起,否則 BE import 全炸)
  2.0b compliance FK:判定 assessment_plan_extensions 去留 → 重建 fk_ape 或 DROP
  2.0c 重寫 vw_user_job_queue(舊 join 的 4 張 AP 表沒了;對新 ap_tasks + Q1「job 綁 SSP 控制項」重寫)
       ▼
B1 框架+資源庫 API 對齊(可與 B2 並進)
B2 專案成立重寫(clone 三件組、AP/AR 延後、為 SSP 控制項建 job)  ← Type C
B3 SSP 維護 + 啟動稽核 snapshot + project_audit_rounds 7 態狀態機  ← Type C
B4 AP 後端(草稿生成 + reviewed-controls + 抽查名單 + tasks)
B5 AR(AO 全量矩陣 + 風險總結)+ POA&M(整改三層 + 結案/覆核)  ← Type C
       ▼
2.Z 全 e2e(精誠機械 CMMC 劇本)+ baseline 零回歸

能平行:Type A 批次分檔;B1 與 B2。必序列:2.0a、B2→B3→B5 業務鏈、Type C 重寫。 3 個 Type C 重寫點app/project/service/oscal_project_service.py(start 拆 start_project+launch_new_round)、infra/grc/repository/grc_audit_repo_impl.py(AR→AO 矩陣)、di_containers/oscal/oscal_containers.py實際 1074 行,verified —— Phase 2.0a 最大工作量,勿照 150 估)。


§4 開工順位(步驟)

  1. 跑 §6 pre-flight,確認現況與本檔一致(branch / 兩 repo pushed / 套件可 import / 109 檔待遷移 / DB schema)。
  2. 讀 §0 讀序的 2-6。
  3. 用 superpowers:subagent-driven-development 跑 wave2-migration-plan.md,從 Phase 2.0a 開始。
  4. 每個 Type C 完成各自全 e2e;每 phase 末跑 BE smoke + baseline diff。
  5. fix/phase 完 停下給 user status,不自動收尾、不自動 push(§8)。

§5 套件對外 service(Wave 2 呼叫點 — 實際 dotted path,verified 2026-06-14

⚠️ service 不在 app.service 底下直接放(app/service/__init__.py 是空的);每個在 app.service.<domain>.<file>。照下面的精確路徑 import,別寫 from jedi_oscal_v2.app.service import X(會 ImportError)。簽章仍 pre-flight 驗。

Service / 方法 import path
FrameworkService jedi_oscal_v2.app.service.framework.framework_service
CatalogService jedi_oscal_v2.app.service.catalog.catalog_service
ProfileService(resolve_profile jedi_oscal_v2.app.service.profile.profile_service
SspService(deep_clone_ssp)/ SspCloneService jedi_oscal_v2.app.service.ssp.ssp_service / ...ssp.ssp_clone_service
AssessmentPlanService(generate_draft jedi_oscal_v2.app.service.ap.assessment_plan_service
AssessmentResultService jedi_oscal_v2.app.service.ar.assessment_result_service
AssessmentRiskService(link_findings jedi_oscal_v2.app.service.ar.assessment_risk_service
PoamService(generate_from_findings)/ RemediationService jedi_oscal_v2.app.service.poam.poam_service / ...poam.remediation_service
OscalSnapshotService(snapshot_ssp/clone_resource_library)+ metadata/clone helper jedi_oscal_v2.app.service.snapshot.oscal_snapshot_service(+ metadata_clone_service / oscal_clone_service
OscalIoService(export_oscal jedi_oscal_v2.app.service.io.oscal_io_service
AO 全量矩陣(init_finding_matrix/upsert_finding/list_findings domain:jedi_oscal_v2.domain.service.ar.ar_finding_matrix_service(AssessmentResultService 也代理)
profile resolution / AP draft domain:jedi_oscal_v2.domain.service.profile.profile_resolution_service / ...ap.ap_draft_service
parser factory get_oscal_parser_adapter jedi_oscal_v2.ports.oscal_parser_factory

已 defer(套件沒有,Wave 2 若需要要先補套件或暫接舊路徑):ISO/NIST parser、docx/excel SSP 匯入、深層 SSP 匯出(statements/by-components 等)。


§6 Pre-flight Command(必跑,確認現況)

cd /Users/chouraymond/Projects/Billows/Audit-Manager/compliance-manager-be
# 1. branch + 兩 repo pushed
git branch --show-current                 # 期望 feature/oscal-refactor
git status -sb | head -1                   # 可能 ahead by N(本 handoff 等收尾 commit,user push 後歸零)—— 不是問題
git status --short                          # 期望只有 ' M pyproject.toml'(dev path-dep,勿 commit);其餘應為 user 已 push
( cd ~/Projects/Jedicogy/module/jedi-python-package && git status -sb | head -1 )
# 2. 套件可 import + 測試綠
poetry run python -c "import jedi_oscal_v2; print('OK', jedi_oscal_v2.__file__)"
poetry run pytest ~/Projects/Jedicogy/module/jedi-python-package/jedi-oscal-v2/tests -q | tail -2   # 期望 194 passed
# 3. 遷移 surface(期望 ~109 舊 / 0 新)
grep -rl "from jedi_oscal\b\|import jedi_oscal\b" --include="*.py" api/ app/ domain/ infra/ di_containers/ config/ common/ core/ | wc -l
grep -rl "jedi_oscal_v2" --include="*.py" api/ app/ domain/ infra/ di_containers/ config/ common/ core/ | wc -l
# 4. dev DB schema(密碼從 .env DB_SECRET.rds_master_password,勿落檔)
#   PGPASSWORD=... psql -h 192.168.50.188 -p 25432 -U cmmgr -d guidant_ai_dev -c "\dt oscal.*" | wc -l   # 期望 48 表 + 標題
#   ...-c "\d compliance.project_audit_rounds"   # 期望 7態 CHECK 在

§7 行為規範重要提醒(適用 Wave 2)

  • 不切 branch(兩 repo 都在 feature/oscal-refactor 工作;branch 不對停下問 user)。
  • push 永遠等 user 明示收尾類動作(changelog/SUMMARY/發版/Notion)等 user 下令
  • 可自行階段性 commit(顯式 git add 檔名、-am;各 repo 分開 commit)。
  • 改 BE service 後提醒 user 重啟 BE(無 hot reload);服務 user 自己起。
  • 改套件走 path-dep dev(已設好);發 Nexus 等 feature 完成 + user 明示
  • 跨 schema FK 字串帶 schema 前綴(記憶 feedback_cross_schema_fk_must_qualify)。
  • SQL migration:cmmgr + --single-transaction -v ON_ERROR_STOP=1,新表 GRANT cm_app,收尾 INSERT schema_migrations;正式環境不能 drop schema(D7 待策略)。
  • plan 假設先 verify(套件 method 簽章 / 欄位)才開工。
  • 不晶晶體。

§8 不在 Wave 2 scope(不要順手做)

  • ISO/NIST 框架支援(D5 follow-up)、SSP docx/excel 匯入、深層 SSP 匯出
  • 套件發 Nexus(feature 全完成 + user 明示才做)
  • FE(Wave 3,另起;用 api-contract.md,BE 端點好一個跟一個垂直管線)
  • 正式環境 schema 遷移(D7,需可移植 migration,非 drop&rebuild)
  • Notion 任務(user 說最後再做)

§9 前期 commits(origin 已同步)

  • 主專案(feature/oscal-refactor,origin head 5129f57f):dad80aef(契約) 471862d8(plan 修正) 0af2d862(Wave1 收尾) 5129f57f(Wave2 計畫+API契約) + changelog 2026-06-14-feat-fr038-wave1-*
  • 套件(origin head 3096f1f):57 commits(Phase0 aaec083 → A5c2 3096f1f
  • 未 commit:主專案 pyproject.toml(dev path-dep,刻意保留勿 commit

§10 給 fresh session 的超短 prompt(user 複製貼)

讀 docs/features/FR-038-2606-oscal-redesign/handoff/2026-06-14-WAVE2-START-HERE-handoff.md,
跑完 §6 pre-flight 確認現況。本 session 只做 2A(讓 BE 在 jedi_oscal_v2 上重新 boot + pytest test/ 綠),
到綠燈就停、寫下一棒(2B) handoff、交回給我換 session。不要一口氣做完整個 Wave 2。
push / 收尾 / Notion 都等我明示。

冷接可行性自檢 ✅

下個 session 只看本檔 + §0 讀序 + 跑 §6 → 能確認現況一致、知道陷阱、知道從 Phase 2.0a 開工、知道套件呼叫點與 defer 項、知道規範界線。不需 user 額外解釋即可正確開工。