使用方式:把下方「交接 prompt 本體」整段貼到新 session 即可接手。 前置狀態:A4 Session D BE shipped;working tree 乾淨(除 pre-existing pyproject.toml dev-path + 2 zip)。
我要進 SSP 匯入匯出 Phase 2 / A4 Session E — T6 + T7 + T8(WriteStrategy + SSP shell + _write_all_data 8-step pipeline)。
執行策略(user 拍板:順序做 + base class 抽共用 pattern,不用 subagent)
=====================================================================
進度有點落後,但**不要拆 subagent 平行做** — 原因:
1. T6 → T8 → T7 強耦合鏈(T8 _write_all_data Step 2 call T6 _create_ssp_shell;Step 6 call T7 5 WriteStrategy;T7 ControlWriteStrategy 回 ctrl_impl_id_map 給 AoWriteStrategy)— 平行做反覆 mock 對方比順做還慢
2. DI Container 是 single point(5 strategy + 3 domain service + 11 dep 全寫 oscal_containers.py)— subagent 平行改這檔 100% merge conflict
3. T0 偏差 context cost 高(T0.1/T0.2/T0.5/T0.6/T0.7 + ssp_domain.add 簽章)— 每個 subagent prompt 都要貼 design §11.1,寫 prompt 時間 ≈ 自己順做時間
4. TDD 流程在 subagent 內難 control — 容易踩 Session D 那種「app service logger patch」debug 陷阱,subagent 報「做完」但實際 RED
**加速關鍵:T7 抽 base class 共用 80% pattern**
5 個 WriteStrategy 中:
- Control / AO:跨兩個 table(control_implementations + control_impl_objectives),各自獨立寫
- Device / InfoSystem / Leveraged:都寫**同一張表** `ssp_system_implementation_items`,差別只在 `kind` 欄位 + parsed entity 不同
→ 抽 `AbstractSspImplementationItemWriteStrategy` base class:
```python
class AbstractSspImplementationItemWriteStrategy(ABC):
def write(self, parsed_list, ssp_id, sys_impl_main_id, user_context) -> int:
"""共用 80% loop / session / mapper / count return."""
# ... 統一 transaction-friendly loop + count
@property
@abstractmethod
def kind(self) -> str: ...
@abstractmethod
def _parsed_to_item_payload(self, parsed) -> dict: ...
subclass 各只 ~10 行:
DeviceWriteStrategy.kind = "device" + _parsed_to_item_payload(ParsedDevice)InformationSystemWriteStrategy.kind = "information_system" + _parsed_to_item_payload(ParsedInformationSystem)LeveragedWriteStrategy.kind = "leveraged" + _parsed_to_item_payload(ParsedLeveraged) + party_uuid效益:T7 5 strategy 順做 ~60 min → base class + 5 subclass 順做 ~30-40 min,0 整合風險。
順序: T6 ship → T7 (base + 5 strategy + DI Factory) → T8 (5 dict_to* + 8-step pipeline + DI 11 dep)
調整後預估 ~1.5-2d(原 plan ~2.25d);T6/T7/T8 各自 commit。
Branch: feature/ssp-import-export-phase2(BE,45 commits 未 push)
Session D 結束 design §11.1.3 已補正 T0.4 偏差最終決議(Option C — entity.name 直接 query); 以下 Session C T0 偏差會直接影響 Session E:
⚠️ T0.1 偏差 — 影響 T6.2 _create_ssp_shell SspEntity 構造
description: str = ""(非 title)profile_id: Optional[int](非 profile_uid 字串)description=metadata.get("target_mf_name") or f"SSP for MF {mf_uid[:8]}"、 profile_id=mf.oscal_profile_id(MF 載入時取 int)⚠️ T0.2 偏差 — 影響 T6.2 SystemCharacteristic class name
SspSystemCharacteristicEntitySystemCharacteristicEntity(無 Ssp 前綴)domain/entity/ssp/ssp_system_characteristic_entity.py⚠️ T0.5 偏差 — 影響 T7.2 ControlImplementation class name
SspControlImplementation / SspControlImplementationEntityControlImplementationEntity(無 Ssp 前綴)domain/entity/ssp/ssp_control_implementation_entity.py⚠️ T0.6 偏差 — 影響 T7.3 AoWriteStrategy upsert key
(ssp_control_implementation_id, catalog_control_assessment_id)statement_identifier(字串對應 statement_id)catalog_control_assessment_id FK(control_implementation_id, statement_identifier)⚠️ T0.7 偏差 — ⭐ critical,影響 T6.3 _resolve_existing_ssp_shell
self._ssp_domain.get_one_by_profile_uid(mf.oscal_profile_uid)profile_id 欄位 ✅ssp = self._ssp_domain.get_one(SystemSecurityPlanQueryEntity(profile_id=mf.oscal_profile_id))⚠️ ssp_domain_service.add() 簽章偏差 — 影響 T6.2
self._ssp_domain.add(SystemSecurityPlanEntity(...), curr_user=user)add(_entity: SystemSecurityPlanEntity) 只接 1 個 entity 參數created_user=user 帶入;不傳 kwargT6 — SSP shell + 新 error code(implementation-plan-A4.md §Task 6)
Commit:feat(oscal): A4 T6 SSP shell + GRC_EXCEL_UPDATE_FLOW_NO_SSP
T7 — 5 WriteStrategy(implementation-plan-A4.md §Task 7)
新建 domain/oscal/service/write_strategy/ 子目錄。先抽 base class 再寫 subclass:
write(parsed_list, ssp_id, sys_impl_main_id, user_context) -> int 樣板:loop / count / mapperkind property + _parsed_to_item_payload(parsed) -> dict methodControlImplementationEntity(無 Ssp 前綴)(control_implementation_id, statement_identifier),非 assessment_id(T0.6)kind = "device";payload from ParsedDevicekind = "information_system";payload from ParsedInformationSystemkind = "leveraged";payload 含 party_uuid from ParsedLeveragedCommit:feat(oscal): A4 T7 5 WriteStrategy
T8 — _write_all_data 8-step pipeline + DI 注入(implementation-plan-A4.md §Task 8)
Commit:feat(oscal): A4 T8 _write_all_data 8-step pipeline + DI
第一步:必讀文件(順序)
jedi_oscal/domain/entity/ssp/ssp_entity.py (SystemSecurityPlanEntity)jedi_oscal/domain/entity/ssp/ssp_system_characteristic_entity.py (SystemCharacteristicEntity)jedi_oscal/domain/entity/ssp/ssp_system_implementation_entity.py (SspSystemImplementationEntity)jedi_oscal/domain/entity/ssp/ssp_control_implementation_entity.py (ControlImplementationEntity)jedi_oscal/domain/entity/ssp/ssp_control_impl_objective_entity.py (ControlImplementationObjectiveEntity)jedi_oscal/domain/entity/ssp/system_security_plan_query_entity.py (SystemSecurityPlanQueryEntity)~/Projects/Jedicogy/module/jedi-python-package/jedi-oscal/jedi_oscal/domain/services/ssp/system_security_plan_domain_service.py~/Projects/Jedicogy/module/jedi-python-package/jedi-oscal/jedi_oscal/domain/services/ssp/system_characteristic_domain_service.py~/Projects/Jedicogy/module/jedi-python-package/jedi-oscal/jedi_oscal/domain/services/ssp/system_implementation_domain_service.py讀完後給「我看完了,準備 T6 開工」確認。
第二步:T6 開工
feat(oscal): A4 T6 SSP shell + GRC_EXCEL_UPDATE_FLOW_NO_SSP第三步:T7 開工(依賴 T6 ship)
domain/oscal/service/write_strategy/ 子目錄AbstractSspImplementationItemWriteStrategy + base unit test(mock subclass 驗 loop / count / payload 注入)feat(oscal): A4 T7 5 WriteStrategy + base class第四步:T8 開工
feat(oscal): A4 T8 _write_all_data 8-step pipeline + DI第五步:Session E 收尾
依 plan §「換 Session 收尾規範」E → F:
poetry run python3 -c "from core.app_factory import create_app; app = create_app()" → DI wiring 不能炸app.oscal.service.ssp_excel_import_app_service.logger總計:~1.5-2d / 3 commit(原 plan ~2.25d,base class pattern 加速 ~0.25-0.75d);T7 / T8 串聯依賴(T7 ship 後 T8 才能跑完整 pipeline)。
不要 subagent 平行 — 強耦合鏈 + DI single point + TDD 流程難 control 三點不適合(詳見頂部「執行策略」段)。
謝謝。
---
## 收口清單(A4 D → E 端)
本 handoff prompt commit 後,新 session 接手即可:
1. 讀 6 個必讀文件(plan-A4 §Task 6-8 / design-A4 §6/§11 / jedi-oscal entity / domain service / app service / DI container)
2. T6 SSP shell + GRC_EXCEL_UPDATE_FLOW_NO_SSP(受 T0.1/T0.2/T0.7 + ssp_domain.add() 簽章偏差影響)
3. T7 5 WriteStrategy(受 T0.5/T0.6 偏差影響)
4. T8 _write_all_data 8-step pipeline + DI 11 個依賴注入
5. Session E → F 收尾(產下個 handoff,準備 T9/T10/T11 test 補齊 + cucumber + 收尾)
## A4 完成度 reference(Session E 直接擴)
Session E 直接擴的 A3 + A4 Session A/B/C/D 產物:
design-A4.md(§11.1 含 T0.4 偏差最終決議;plan / spec review 都 approved) implementation-plan-A4.md(3466 行 / 11 task / 4 session)
domain/oscal/service/reconciliation/ # ✅ Session C/D 完整 ├── base.py # stage 0 dispatch ✅ ├── match_method.py # USER_SELECTED ✅ ├── _normalizers.py # 4 helper ✅ ├── person_reconciler.py # A4 T4 加 stage 0 ✅ ├── organization_reconciler.py # A4 T4 加 stage 0 ✅ ├── device_reconciler.py # A4 T3 完整演算法 ✅ ├── information_system_reconciler.py # A4 T3 完整 + system_owner ✅ ├── leveraged_reconciler.py # A4 T3 完整 + FUZZY_NAME_PREFIX ✅ ├── catalog_control_reconciler.py # A4 T3 二階段 ✅ ├── assessment_objective_reconciler.py # A4 T3 + T0.4 偏差後 entity.name query ✅ └── ssp_entity_orchestrator.py # facade ✅
domain/oscal/parser/ssp_intermediate.py # 5 dataclass + Bundle + Context + ParsedParty label ✅
di_containers/oscal/oscal_containers.py # 6 reconciler Factory + orchestrator + catalog_control_reconciler 注入 ssp_excel_import_app_service ✅ di_containers/containers.py # device_container 注入 oscal_container ✅
app/oscal/service/ssp_excel_import_app_service.py
tests/ ├── test_a4_reconciliation_helpers.py # T1 ✅ ├── test_a4_parsed_entity_fixtures.py # T1 ✅ ├── test_a4_reconciliation_device.py # T3 完整 14 test ✅ ├── test_a4_reconciliation_information_system.py # T3 完整 16 test ✅ ├── test_a4_reconciliation_leveraged.py # T3 完整 16 test ✅ ├── test_a4_reconciliation_catalog_control.py # T3 完整 11 test ✅ ├── test_a4_reconciliation_assessment_objective.py # T3 完整 13 test ✅ ├── test_a4_reconciliation_orchestrator.py # T2 ✅ ├── test_a4_a3_retroactive.py # T4 12 test ✅ └── test_a4_a2_integration.py # T5 5 test ✅
## A4 Session D 規範遵守
- [x] 顯式 `git add <file>` 顯式檔名(T3 11 檔 + T4 4 檔 + T5 3 檔,禁 -A)
- [x] Commit 含 `Co-Authored-By: Claude Opus 4.7 (1M context)` footer
- [x] jedi-oscal 沒動(path-dep 維持)
- [x] `pyproject.toml` dev-path 不 commit
- [x] DDD 規範貫徹(reconciler 純 domain,無 session / @transaction;app service @transaction)
- [x] T0.4 偏差最終決議補進 design §11.1.3(Option C — entity.name 直接 query)
- [x] handoff 文件統一放 `docs/features/<feature>/handoff/`
- [x] Session D 預估 ~1.25d 實際在 1 session 內完成
- [x] 183 a3+a4 test 全綠(0 regression)