# Handoff Prompt — A4 Brainstorm Kickoff（devices / info_systems / leveraged / 控制項 / AO 鉤稽）

> **使用方式**：把下方「交接 prompt 本體」整段貼到新 session 即可接手。
> **前置狀態**：A3 BE 完整 shipped（6 commits + 67 個 A3 新 test 全綠 + cucumber regression partial ship）；working tree 乾淨（除 pre-existing pyproject.toml + zip）；A4 是 Phase 2 第 5 個 task arc、**重型 phase**，要走完整 `superpowers:brainstorming` SOP。

---

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

```
我要進 SSP 匯入匯出 Phase 2 / A4 phase brainstorm。

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

Branch: feature/ssp-import-export-phase2（BE，38 commits 未 push）
- A0 / A0.1 / A1 / A2 / A3 都 BE shipped；A4 是 Phase 2 第 5 個 task arc
- A3 ship 完整 commit chain：b011f2f + 82f0dc8 + 854b238 + 773e108 + 761fd7c + 481b2d6
- test repo branch feature/a3-ssp-party-match-regression (27e52fe) 待 env 配齊 merge
- 工具狀態：jedi-oscal 仍 path-dep；pyproject.toml dev-path 改動仍未 commit
- Test 基準：694 passed / 40 pre-existing fail（0 A3 regression）
- A3 ship 後 A4 可直接擴 BaseReconciliationService[TParsed, TEntity]

A4 是重型 phase（README.md tracker 標 重 / requirement-understanding §6.1 預判 4 個重型）
→ 走完整 brainstorm SOP：
  brainstorm 收斂 → design-A4.md → implementation-plan-A4.md → 開工

開工 SOP
========

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

1. docs/features/FR-011.2-2605-ssp-import-export-phase2/handoff/2026-05-20-a3-SUMMARY.md
   ← A3 整段收口（含 8 段 SUMMARY + follow-up 清單）— A4 直接接續

2. docs/features/FR-011.2-2605-ssp-import-export-phase2/design-A3.md
   ← 重點 §3.2 BaseReconciliationService 抽象基類（A4 5 reconciler 都建在此上）
   ← §5.1/5.2 Person/Organization 三階段 fallback 樣板
   ← §11 reconciliation 9 條偏差條目（plan vs reality 寫法樣板）

3. docs/features/FR-011.2-2605-ssp-import-export-phase2/design-A2.md
   ← 重點 §15.3「Superset flow include_controls 待 A4」(line 724) — A4 必補 control_id → catalog_control_uid 反查
   ← §15.1-15.3 reconciliation 樣板（A4 §11 對照）

4. app/oscal/service/excel_parser/types.py
   ← ParsedExcel dataclass — devices / info_systems / leveraged / controls_with_aos
     全是 list[dict]，A4 brainstorm 必確認：保留 dict 還是改 typed dataclass

5. domain/oscal/parser/ssp_intermediate.py
   ← 既有 typed dataclass：ParsedParty / ParsedLeveragedService / ParsedInformationType
   ← 既有 ParsedLeveragedService 沒 matched_* 欄位 — A4 需補

6. domain/oscal/service/reconciliation/base.py + match_method.py
   ← A4 直接擴的抽象基類；5 hook + 三階段 fallback + candidate cache pattern

7. domain/oscal/service/reconciliation/person_reconciler.py + organization_reconciler.py
   ← Reference 實作 — A4 5 個新 reconciler 直接抄樣板

8. app/oscal/service/ssp_excel_import_app_service.py
   ← _write_all_data 串接點（A3 已串 party 進來；A4 5 個新的也要決定串哪）

9. docs/features/FR-011.2-2605-ssp-import-export-phase2/README.md
   ← tracker A4 row pending；F3 follow-up 標「直接擴 BaseReconciliationService」

10. docs/changelog/2026-05-20-feat-party-matcher-shared.md
    ← A3 ship 後規範 — A4 changelog 直接對照（type=feat / modules=oscal）

讀完後給「我看完了，建議下一步 X」的簡短確認。

第二步：Brainstorm 收斂（superpowers:brainstorming）

A4 重點 question 清單（brainstorm 時務必確認）：

【A. 範圍 / Entity 對應】

1. 5 個 entity 各對到哪張 DB table / ORM model？
   - Device → ?（oscal.inventory_items? component_definitions? 是否要查現有 schema）
   - Info System → ?（oscal.information_systems? public.information_systems?）
   - Leveraged → oscal.leveraged_authorizations
   - 控制項 → oscal.catalog_controls（A1 framework PDF import 已建）
   - AO → oscal.assessment_objectives / oscal.catalog_assessment_objectives
   先查 schema，再決定鉤稽 target

2. Excel parser 跟 docx parser 是否需對齊產出 schema？
   - Excel: ParsedExcel.devices / info_systems / leveraged / controls_with_aos 全 list[dict]
   - Docx: ParsedSsp.leveraged_services (typed ParsedLeveragedService) 只 cover 1 個 entity
   - A4 要不要逼 docx parser 也產出 device / info_system / AO 結構？還是接受 docx-only 場景跳過鉤稽？

3. 鉤稽資料來源跨多 caller 一致性問題：
   - A3 範圍 docx + Excel 兩條 caller 都要串 party reconcile
   - A4 5 個新 entity 也要兩條 caller 都串嗎？或只 Excel？
   - docx parser 不產出某些 entity 時，跳過 vs 報錯？

【B. Match 策略 per entity】

4. 各 entity 三階段 fallback 是否都需要？
   - Device：exact (hostname?) + normalized (lowercase?) + fuzzy (IP / asset_tag 反查?)
   - Info System：exact (system_name?) + normalized (全形半形?) + fuzzy 需要嗎？
   - Leveraged：exact (provider name + auth_id?) + normalized + fuzzy?
   - 控制項：exact (control_id 「AC-1」+ catalog_uid context) — 是嚴格識別符，**可能不需 fuzzy**
   - AO：exact (objective_id 「AC-1.a」+ control_uid context) — 同上，可能不需 fuzzy
   建議方向：嚴格識別符類（control / AO）只做 exact + normalized；自由文字類（device / info_system / leveraged）做完整三階段

5. 控制項鉤稽的特殊性 — A2 §15.3 待補：
   - parsed 內 control_id「AC-1」字串 → 對到該 catalog 內 catalog_control_uid (UUID)
   - 需要 catalog_uid context 限制範圍（不能跨 catalog 命中）
   - A2 skeleton include_controls=[]（全納入）— A4 補完後 superset flow 才能做真正 subset profile
   - 串接點：app/oscal/service/ssp_excel_import_app_service.py _confirm_superset_flow 內呼叫 ProfileService.add_profile 前

6. AO 鉤稽：
   - AO 是 control 子層 — 鉤稽要在 control 鉤稽**之後**做（依賴 catalog_control_uid context）
   - parser 內 controls_with_aos: list[dict] 已 nest 結構 — 鉤稽演算法用兩層 loop？還是 flatten?
   - 一個 ParsedControl 可能對到「該 catalog 內多個 AO」— 怎麼 batch reconcile？

【C. DI / 架構安排】

7. 5 個 reconciler 都建在 domain/oscal/service/reconciliation/ 下嗎？
   - 既有 sub-folder 加 device_reconciler.py / info_system_reconciler.py / leveraged_reconciler.py / catalog_control_reconciler.py / assessment_objective_reconciler.py
   - __init__.py 是否 export 5 新類別？（A3 因 circular import 縮減為只 export Base + MatchMethod — A4 沿用此 pattern）

8. 共用 facade dispatch 還是各自獨立？
   - A3 party_reconciliation_service 是 facade，dispatch by party_type
   - A4 5 個 entity 彼此無 type dispatch 關係 — 是否各自獨立 service？
   - 或建一個「SspEntityReconciliationOrchestrator」統一 batch reconcile？

9. DI Factory wiring：
   - 5 個新 Factory 加在 di_containers/oscal/oscal_containers.py
   - 依賴 jedi-* 哪些 domain service？（device → ? / info_system → ? / leveraged → ?）

【D. 串接點 + 流程順序】

10. Excel _write_all_data 串接點：
    - A3 reconcile parties 已串
    - A4 5 個怎麼串？逐 entity reconcile call 5 次？還是 orchestrator 1 次？
    - 順序：control → AO（依賴 control_uid）→ device / info_system / leveraged？

11. Docx flow（ssp_docx_import_app_service）也串嗎？
    - A3 docx 既有 PartyReconciliationService.reconcile 兩處
    - A4 docx parser 不產出 device / info_system / AO 時跳過？或同樣 5 reconciler 都 wire 進 docx?
    - Cucumber regression 範圍要不要擴？

12. 跟 A2 §15.3 (Superset flow include_controls) 整併：
    - A4 完工後 superset flow 真正生效 — 從 control_id 反查 catalog_control_uid
    - 是 A4 task 內子項，還是獨立 follow-up commit？

【E. Fuzzy 演算法細節】

13. Device fuzzy：
    - hostname normalize (case + trim)？
    - IP 對 IP？asset_tag？
    - 多欄位匹配時 score 怎麼算？

14. Info System fuzzy：
    - 名稱類似度（A3 OrganizationReconciler 樣板可借用）？
    - 還是需要新 normalize 規則？

15. Leveraged fuzzy：
    - provider name 對到 system 內 vendor 表？
    - fedramp_package_id 唯一識別優先？

【F. Test + Cucumber 範圍】

16. 預估 unit test 數量：
    - 每個 reconciler ~10-15 case（A3 person 16 / org 16 為樣板）
    - 5 個 = 50-75 case + base 既有不變 + integration test (Excel + 可能 docx)
    - + ParsedXxx fixture test（5 entity 加 matched_* 欄位 + asdict serialize）

17. Cucumber regression：
    - 06-ssp-excel-import-entity-match.feature 含 5 scenarios（each entity 1）？
    - 沿用 A3 partial-ship pattern（env 配齊後跑通即 ship）？

【G. Out of Scope（必先列）】

18. 預覽 UI 在 A5 — A4 期間 fuzzy 自動寫入（同 A3 pattern）
19. jedi-* 不動 — 維持 path-dep / pin Nexus
20. A4 範圍不整併修補 B / C / D / F1 / F6（A3 同樣排除）

【H. 套件預期異動】

21. jedi-auth Query Entity 是否要加 _in_email_domain / _in_name_prefix (A3 F4 follow-up)？
22. jedi-oscal 是否要加新 domain service / Entity / Mapper？
    - Device / Info System / Leveraged Auth / Catalog Control / AO 各自的 domain service 是否已在 jedi-oscal 內？
    - 若需要新加 → 套件異動需 user 拍板（CLAUDE.md 規範）

第三步：產出 design-A4.md

Brainstorm 收斂後產 design-A4.md（13 章樣板：
範圍 / Architecture / Data Structures / Match 演算法 / Caller 切換 / Pre-flight Verification / Acceptance Criteria / 風險 / 跨 repo / §11 reconciliation / 執行階段切分 / 設計決策溯源）。

第四步：產出 implementation-plan-A4.md（Phase 3 SOP）

照 A3 plan 樣板（~2,000 行 / T0 verify + T1-T7 task / 鐵律清單）。

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

1. 顯式 git add <file>，禁 -am / -A — commit 前 git status --short 確認
2. jedi-oscal 維持 path-dep，不 bump 版本不推 Nexus（Phase 2 整體完工才 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 / matcher 不接 DB
7. 不寫 docstring / 註解除非真有 non-obvious 的 why
   - A4 例外（沿用 A3）：BaseReconciliationService 抽象基類已寫；新 reconciler 5 hook
     僅當 fuzzy 演算法有 non-obvious why 才寫
8. Test 用 mock 包 logger 避開 jedi DBLogHandler 撞 SessionLocal=None；@transaction 用 patch_session_scope
9. plan 階段假設不準確時主動修 design.md (§11 reconciliation 收口時一次補)
10. 跨 repo 切換時提醒 user：cucumber 在 compliance-manager-test repo，commit / branch 分開
11. 改 docx parser 既有行為 → cucumber regression 必跑（A4 視範圍決定 partial ship）
12. 重大決策 → docs/analysis/YYYY-MM-DD-<topic>.md
13. 重型 bug / 跨域問題 → docs/issues/pending/YYYY-MM-DD-<title>.md
14. Handoff 文件統一放 docs/features/<feature>/handoff/（CLAUDE.md 2026-05-20 新規）
15. brainstorm dump 留每 session 收口才一次 dump
16. 階段性 commit 不用問
17. Subagent dispatch prompt 必加「git add 顯式檔名，禁用 -am」
18. 套件異動需 user 拍板（jedi-auth / jedi-oscal 加欄位 / 改 service 簽章前必先提）

A4 phase 預估規模（粗估）
========================

| Session | 範圍 | Task | 預估 |
|---------|------|------|------|
| A | brainstorm 收斂 → design-A4.md | brainstorm + spec review loop | 0.5d |
| B | writing-plans → implementation-plan-A4.md | plan review + user review | 0.25d |
| C~? | 5 reconciler 各自實作（每個 ~10-15 case test）| T1~Tn | ~2~3d |
| 最後 | cucumber + 收尾 SUMMARY | partial ship 模式 | ~0.5d |

總計：~3~4d（含 design / plan / 5 reconciler 開工 / 收尾）— 跟 A3 差不多但範圍大 5x，
靠 BaseReconciliationService 抽象基類 + 樣板 reconciler 大幅壓縮邊際成本。

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

- 直接照 A3 樣板：每個 reconciler 跑 TDD（write failing test → run FAIL → implement → run PASS → commit）
- 5 個 reconciler 各自 commit；不要堆一個大 commit
- Catalog control 鉤稽涉及 A2 §15.3 follow-up 一併處理 — 子 task 範圍明確
- 不需 dispatch subagent — 整段在主 session 推得動（個別 reconciler 工作量跟 A3 person/org 相當）

謝謝。
```

---

## 收口清單（A3 → A4 端）

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

1. 讀 10 個必讀文件（A3 SUMMARY / design-A3 / design-A2 §15.3 / Excel parser types / ssp_intermediate / base + match_method / 2 樣板 reconciler / excel_import_app_service / tracker README / changelog）
2. 走 superpowers:brainstorming SOP — 答完 22 個 question
3. 產出 design-A4.md → implementation-plan-A4.md → 開工

## A3 完成度 reference（A4 直接擴）

A4 直接擴的 A3 產物：

```
domain/oscal/service/reconciliation/
├── base.py                      # ← A4 5 個新 reconciler 繼承 BaseReconciliationService[TParsed, TEntity]
├── match_method.py              # ← A4 可加新 MatchMethod 值（FUZZY_IP / FUZZY_HOSTNAME / ...）
├── _normalizers.py              # ← A4 可加 _normalize_hostname / _normalize_ip / _normalize_control_id
├── person_reconciler.py         # ← reference 樣板
├── organization_reconciler.py   # ← reference 樣板
└── (A4 新增) {device,info_system,leveraged,catalog_control,assessment_objective}_reconciler.py
```

## A4 完工後可進的 phase

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

## A3 partial follow-up（A4 期間不阻擋，留 idle 處理）

- Manual smoke：BE 重啟驗 A2 reconcile 串接（user 動作）
- Cucumber T6 partial ship：env 配齊後跑通 5 scenarios
- 對話歷史 dump：A3 task arc 原始對話原樣寫入 `docs/conversation-history/2026-05-20/ssp-import-export-phase2-A3/`
- Push 38 commits 到 origin（review 用）
- F-T1-pre 兩個 pre-existing docx fail（與 A3 無關）

## A3 Session E 規範遵守

- [x] 顯式 `git add <file>` 顯式檔名（3 個 commit 都用 explicit list，禁 -A）
- [x] Commit 含 `Co-Authored-By: Claude Opus 4.7 (1M context)` footer
- [x] jedi-oscal 沒動
- [x] `pyproject.toml` dev-path 不 commit
- [x] DDD 規範貫徹
- [x] T5 跑全套 pytest 確認 0 A3 regression（694 passed / 40 pre-existing fail）
- [x] T6 跨 repo 切換 + 獨立 branch（feature/a3-ssp-party-match-regression）
- [x] T7 design §11 不空段（9 條偏差 + 已對齊條目）
- [x] handoff 文件統一放 `docs/features/<feature>/handoff/`
