# Handoff Prompt — A4 Session B → C（plan ship → T0+T1+T2 開工）

> **使用方式**：把下方「交接 prompt 本體」整段貼到新 session 即可接手。
> **前置狀態**：A4 Session A（design）+ Session B（plan）都 BE shipped；working tree 乾淨（除 pre-existing pyproject.toml dev-path + zip）。

---

## 交接 prompt 本體（從此貼到新 session）

```
我要進 SSP 匯入匯出 Phase 2 / A4 Session C — T0 + T1 + T2。

前置狀態
========

Branch: feature/ssp-import-export-phase2（BE，40 commits 未 push）
- A4 Session A (design-A4.md) shipped：commit 1de5f51（spec review approved）
- A4 Session B (implementation-plan-A4.md) shipped：commit 57bcb2e（plan review approved）
- jedi-oscal 仍 path-dep；pyproject.toml dev-path 改動仍未 commit
- A3 ship 後 65+ test baseline 全綠（694 passed / 40 pre-existing fail）

A4 是重型 phase（5 reconciler + 5 WriteStrategy + SSP shell + retroactive 同 PR）
→ 11 task 跨 4 implementation session：
  Session C (T0+T1+T2) / D (T3+T4+T5) / E (T6+T7+T8) / F (T9+T10+T11)

Session C 範圍
===============

T0 — Implementer Pre-flight Verification（implementation-plan-A4.md §Task 0）

8 項 verify（**front-load critical**：T0.5 + T0.7 優先驗）：
- T0.1: jedi-oscal SspEntity 欄位
- T0.2: SspSystemCharacteristicEntity 欄位
- T0.3: SspSystemImplementationEntity main + A0.1 scope 欄位
- T0.4: CatalogControlAssessmentQueryEntity 是否有 objective_id 欄位
- T0.5: ⭐ system_security_plan_control_implementations ORM model + Mapper
- T0.6: ssp_control_impl_objective ORM model 欄位
- T0.7: ⭐ ssp_domain_service.get_one_by_profile_uid 是否存在
- T0.8: DeviceQueryEntity 雙欄 (name, ip) 同時 query 支援度

任一不符 → 主動修 design-A4 §11 補偏差條目（不照舊硬幹）。

T1 — base.py stage 0 + MatchMethod USER_SELECTED + 4 helper + 5 dataclass + ParsedExcelEntityBundle + SspEntityReconciliationContext + ParsedParty 加 label 欄位

- 1.1: MatchMethod 加 USER_SELECTED
- 1.2: _normalizers 補 4 helper（parse_user/device/info_system_lookup_label + _normalize_control_id）+ 17 test
- 1.3: base.py 加 stage 0 dispatch + _try_user_selected_match default no-op + 2 test
- 1.4: ssp_intermediate 加 5 dataclass + Bundle + Context + ParsedParty 加 2 label 欄位 + 10 test

Commit：`feat(oscal): A4 T1 stage 0 hook + dataclass + helpers`

T2 — 5 reconciler skeleton + orchestrator + DI Factory

- 2.1: DeviceReconciler skeleton + 2 test
- 2.2: InformationSystemReconciler skeleton（接 2 個 domain service）+ 2 test
- 2.3: LeveragedReconciler skeleton + 2 test
- 2.4: CatalogControlReconciler skeleton + 2 test
- 2.5: AssessmentObjectiveReconciler skeleton（加 reconcile_with_control_map）+ 2 test
- 2.6: SspEntityReconciliationOrchestrator + 2 dispatch test
- 2.7: DI Container 加 6 Factory

Commit：`feat(oscal): A4 T2 reconciler + orchestrator skeleton + DI`

開工 SOP
========

第一步：必讀文件（順序）

1. docs/features/FR-011.2-2605-ssp-import-export-phase2/implementation-plan-A4.md
   ← A4 完整 plan（3466 行 / 11 task / 4 session）— Session C 對應 T0+T1+T2 段
   重點段：File Structure / Task 切分概覽 / Task 0 / Task 1 / Task 2 / 規範遵守清單

2. docs/features/FR-011.2-2605-ssp-import-export-phase2/design-A4.md
   ← A4 spec（13 章）— §3 Architecture / §4 Data Structures / §5 Reconciler 演算法 / §7.2 T0 verify list

3. docs/features/FR-011.2-2605-ssp-import-export-phase2/design-A3.md
   ← §3.2 BaseReconciliationService 抽象基類（A4 直接擴）+ §5.1/5.2 三階段樣板

4. domain/oscal/service/reconciliation/{base,match_method,_normalizers,person_reconciler,organization_reconciler}.py
   ← A3 既有 6 個檔（A4 不動 base/match_method/normalizers 的既有部分，加 stage 0 / USER_SELECTED / 4 helper）

5. domain/oscal/parser/ssp_intermediate.py
   ← A3 既有 ParsedParty（A4 加 2 label 欄位）

讀完後給「我看完了，準備 T0 開工」的簡短確認。

第二步：T0 Pre-flight 8 項並行 verify

照 plan §Task 0 步驟（8 個 grep / read 指令）並行跑；驗證結果整理 → 對齊 design §7.2 假設。
任一不符就主動修 design-A4 §11（不照舊硬幹）。

第三步：T1 開工

照 plan §Task 1 完整步驟，逐 step TDD：
1.1 加 USER_SELECTED → 1.2 寫 17 helper test → 1.3 改 base.py + 2 test → 1.4 加 5 dataclass + 10 test → Commit T1。

第四步：T2 開工

照 plan §Task 2 完整步驟，5 reconciler skeleton + orchestrator + DI Factory 全部建好 → Commit T2。

第五步：Session C 收尾

依 plan §「換 Session 收尾規範」C → D：
- 跑 pytest tests/test_a3_*.py tests/test_a4_*.py -v 確認 0 regression
- git status --short 確認 working tree 乾淨（除 pre-existing pyproject.toml + zip）
- 產 handoff prompt → docs/features/FR-011.2-2605-ssp-import-export-phase2/handoff/2026-05-XX-a4-c-to-d.md
  含已 ship commits + T3/T4/T5 開工指引 + 鐵律提醒

鐵律（沿用 A0.1 + A1 + A2 + A3 全部）
======================================

1. 顯式 git add <file>，禁 -am / -A — commit 前 git status --short 確認
2. jedi-oscal 維持 path-dep，不 bump 版本不推 Nexus（feature 整體完工才 bump）
3. pyproject.toml dev-path 改動不該 commit
4. BE 重啟必 lsof -ti:8000 | xargs kill -9
5. 改 BE service code 後必提醒 user 重啟 — BE 沒 hot reload
6. DDD 嚴格分層 — Route 不碰 DB，App Service @transaction，純函式 helper / reconciler / WriteStrategy 不接 session
7. 不寫 docstring / 註解除非真有 non-obvious 的 why
   - A4 例外：SspEntityReconciliationOrchestrator facade docstring + AssessmentObjectiveReconciler.reconcile_with_control_map instance attr thread-safety note 屬「non-obvious why」
8. Test 用 mock 包 logger 避開 jedi DBLogHandler 撞 SessionLocal=None；@transaction 用 patch_session_scope
9. T0 verify 不符 design 假設 → 主動修 design-A4 §11 reconciliation
10. 跨 repo 切換時提醒 user：cucumber 在 compliance-manager-test repo，commit / branch 分開
11. 重大決策 → docs/analysis/YYYY-MM-DD-<topic>.md
12. 重型 bug / 跨域問題 → docs/issues/pending/YYYY-MM-DD-<title>.md
13. Handoff 文件統一放 docs/features/<feature>/handoff/（CLAUDE.md 2026-05-20 新規）
14. 階段性 commit 不用問
15. Subagent dispatch prompt 必加「git add 顯式檔名，禁用 -am」
16. 套件異動需 user 拍板（jedi-* 加欄位 / 改 service 簽章前必先提）

Session C 預估規模
==================

- T0: 0.25d（8 項並行 verify）
- T1: 0.5d（17 helper + 10 dataclass + 2 base stage 0 = 29 test）
- T2: 0.75d（5 reconciler × 2 test + 2 orchestrator dispatch test = 12 test + DI Factory）

總計：~1.5d / 2 commit（T1 + T2）；T0 可併入 T1 commit。

不在 Session C 範圍
====================

- 5 reconciler 完整演算法（T3 — Session D）
- A3 retroactive PersonReconciler / OrganizationReconciler 加 stage 0（T4 — Session D）
- A2 §15.3 整併（T5 — Session D）
- SSP shell + WriteStrategy + 8-step pipeline（T6/T7/T8 — Session E）
- Test 補齊 + Cucumber + 收尾（T9/T10/T11 — Session F）

工具預期
========

- 直接照 plan A4 樣板：每個 task 跑 TDD（write failing test → run FAIL → implement → run PASS → commit）
- 5 個 reconciler skeleton 各自 commit；不要堆一個大 commit
  → T2 整段一個 commit 即可（5 個 skeleton 性質一致）
- 不需 dispatch subagent — Session C 工作量在主 session 推得動

謝謝。
```

---

## 收口清單（A4 B → C 端）

本 handoff prompt commit 後，新 session 接手即可：

1. 讀 5 個必讀文件（plan-A4 / design-A4 / design-A3 §3.2 / 5 reconciliation/.py / ssp_intermediate.py）
2. T0 pre-flight 8 項 verify
3. T1 stage 0 + dataclass + helpers
4. T2 5 reconciler skeleton + orchestrator + DI
5. Session C → D 收尾（產下個 handoff）

## A4 完成度 reference（Session C 直接擴）

A4 Session C 直接擴的 A3 + A4 Session A/B 產物：

```
design-A4.md（1077 行 / 13 章 / spec review approved）
implementation-plan-A4.md（3466 行 / 11 task / 4 session / plan review approved）

domain/oscal/service/reconciliation/
├── base.py              # A4 T1 加 stage 0 dispatch + default no-op hook
├── match_method.py      # A4 T1 加 USER_SELECTED
├── _normalizers.py      # A4 T1 補 4 helper
├── person_reconciler.py # A4 T4 加 stage 0 override (Session D)
├── organization_reconciler.py # A4 T4 加 stage 0 override (Session D)
└── (Session C T2 新增) device / information_system / leveraged / catalog_control / assessment_objective / ssp_entity_orchestrator
```

## A4 完工後可進的 phase

- **A5**：預覽 UI + Confirm 寫入（A4 fuzzy 結果都自動寫入，A5 才補預覽拍板）
- **A2 FE**：上傳 UI（A2 BE 已 ship，FE 待開）— A4 完工後配對 A4 鉤稽結果可整段測 FE 上傳 template

## A4 Session A/B 規範遵守

- [x] 顯式 `git add <file>` 顯式檔名（design + plan 兩 commit 都用 explicit list，禁 -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 規範貫徹
- [x] spec review subagent approved（design-A4）
- [x] plan review subagent approved（plan-A4）
- [x] design §11 reconciliation 段預留（Session F 收口補實作偏差）
- [x] handoff 文件統一放 `docs/features/<feature>/handoff/`
