A3 Session C — SUMMARY(implementation T0+T1+T2 收口)

Session 範圍:A3 phase Session C — T0 implementer pre-flight verify + T1 BaseReconciliationService / reconcilers skeleton / ParsedParty 加欄位 + T2 PartyReconciliationService 改門面 + DI wiring 預估 vs 實際:預估 ~1d / 實際 ~0.5d(plan 內 bite-sized step 落地順暢 + 兩個 plan 假設不符 inline 修正) 狀態:✅ T1 + T2 shipped;42 A3 + reconciliation test passed;廣域 regression 40 pre-existing fail 與 A3 無關


1. Session C Commits(feature/ssp-import-export-phase2)

commit 訊息
b011f2f feat(oscal): A3 T1 base + reconcilers skeleton
82f0dc8 feat(oscal): A3 T2 facade + DI wiring
(待 commit) handoff 2026-05-20-a3-session-C-to-D-implementation.md + 本 SUMMARY

working tree 狀態:除 pre-existing pyproject.toml dev-path 改動 + 既有 conversation-history zip 異動 + 一個 untracked docs/features/ssp-import-export-phase2.zip(user 自行匯出),本 session 改動全 commit。

2. 改動範圍

新建檔案

檔案 行數
domain/oscal/service/reconciliation/__init__.py 17
domain/oscal/service/reconciliation/base.py 95
domain/oscal/service/reconciliation/match_method.py 10
domain/oscal/service/reconciliation/_normalizers.py 39
domain/oscal/service/reconciliation/person_reconciler.py 41
domain/oscal/service/reconciliation/organization_reconciler.py 43
tests/test_a3_reconciliation_normalizers.py 62
tests/test_a3_reconciliation_base.py 96
tests/test_a3_reconciliation_person.py 54
tests/test_a3_reconciliation_organization.py 62
tests/test_a3_reconciliation_facade.py 55

改動既有檔案

檔案 動作
domain/oscal/parser/ssp_intermediate.py ParsedParty 加 match_method + match_confidence optional 欄位(含 docstring 解釋 EXACT/NORMALIZED 都 confidence=1.0 但 method 區分為 A5 UI 提示)
domain/oscal/service/party_reconciliation_service.py 97 行 → 30 行門面 dispatch by party_type
di_containers/oscal/oscal_containers.py 加 import + 加 person_reconciler / organization_reconciler Factory + 改 party_reconciliation_service 注入兩 reconciler
tests/test_party_reconciliation_service.py fixture _make_facade() 改 inject PersonReconciler / OrganizationReconcilerassertion 0 行改動

3. 行為差異

A3 前後對照

Caller A3 前 A3 後
PartyReconciliationService.reconcile(parties, tenant_id) 公開 method exact match only 公開 API 簽章不變;底層改 facade dispatch(A3 T2);normalized + fuzzy stage 仍是 stub return None(T4 落地後三階段降級才完整啟用
ParsedParty dataclass 11 欄位 13 欄位(加 match_method default UNMATCHED + match_confidence default 0.0)— 既有 caller / fixture 不破壞
DI container 1 個 party_reconciliation_service Factory + 2 個新 Factory (person_reconciler / organization_reconciler);門面改注入兩 reconciler instance

Session C 期間 Reconciliation 實際行為

T1 + T2 落地後,行為仍等同 A3 前的 exact match — 因為 PersonReconciler / OrganizationReconciler_try_normalized_match_try_fuzzy_match 都還是 return None stub。Fuzzy 真正啟用要等 Session D T4。但既有 docx / Excel caller 已經透過門面接到新架構,A3 後續 T4 / T5 改動對 caller 完全透明。

4. 規範文件齊全度

文件類型 路徑 狀態
Implementation commits b011f2f + 82f0dc8 ✅ shipped
Handoff prompt(Session C→D) docs/features/FR-011.2-2605-ssp-import-export-phase2/handoff/2026-05-20-a3-session-C-to-D-implementation.md ✅ written
Session SUMMARY docs/features/FR-011.2-2605-ssp-import-export-phase2/handoff/2026-05-20-a3-session-C-SUMMARY.md ✅ written(本檔)
Changelog ⏳ Session E T7 一次寫 2026-05-XX-feat-party-matcher-shared.md(A3 整段 feat)
Analysis ❌ 不適用(無重大決策 trade-off — design 階段已落地)
Issue ❌ 不適用
Tracker README 更新 docs/features/FR-011.2-2605-ssp-import-export-phase2/README.md ⏳ A3 row 等 Session E 收口時一次更新
Conversation history dump ⏳ 留 Session E 收口時 task arc 全 dump

5. Plan vs Reality 偏差(留 Session E T7.3 design §11 reconciliation 補)

# Plan 假設 Reality 處理
1 T1.7 __init__.py export 4 個(base / enum / 兩 reconciler) 只能 export 2 個(base + enum);reconciler 會 trigger ssp_intermediate → match_method circular import __init__.py 加 docstring 解釋;caller 從 person_reconciler / organization_reconciler module 直接 import
2 T2.1 「既有 8 party test 0 行測試 code 改動全綠」 facade __init__ signature 從 (user_svc, org_svc)(person_reconciler, organization_reconciler) → 既有 8 test 直接構建會 fail _make_facade(user_svc, org_svc) helper 包 inject — assertion 行 0 行改動,只改構造方式
3 T1.5 / T1.6 code snippet 寫 jedi_auth.domain.entity.user_query_entity 既有 party_reconciliation_service.py:69 / 88jedi_auth.domain.entities.user_query_entityentities 複數 實作對齊既有 import path
4 T2.2 Step 1b verify ^from.*auth import 應存在 OscalContainer 用 auth_container = providers.DependenciesContainer()(line 111)sub-container reference pattern,不是普通 import wiring pattern 正確;plan grep 條件需放寬到 DependenciesContainer
5 T2.2 Step 3 BE full boot smoke .env line 3 JWT_SECRET={...} 沒 quote → set -a; source .env 撞 bash parser syntax error 改用 OscalContainer module import + provider 宣告檢查(partial smoke pass);plan T2.2 acceptance「BE 起動成功(或 partial smoke pass — wire 無 error)」涵蓋此 fallback ✅

5 條偏差留 Session E T7.3 一次補進 design-A3.md §11。

6. 已知 Follow-up

# 項目 狀態
F1 ~ F7 沿用 plan 預列 7 條 follow-up(docx role normalize / A5 fuzzy 拍板 / A4 5 reconciler / jedi-auth fuzzy filter / OSCAL party 雙寫 / DB 髒資料 audit / docx fuzzy UI) 沿用
T8 Cucumber regression 5 scenarios 跑(user 端 GitLab env 未配齊) Session E 才有
F-env(新) .env line 3 JWT_SECRET={...} 沒 quote → BE 用 set -a; source .env 撞 bash parser;Workaround:手動 export 變數 / 用 python-dotenv 開發環境問題,跟 A3 無關但 surfaced 出來;標 follow-up 給後續 dev 處理
F-T1-pre(新) 2 個 pre-existing 既有 docx test fail(與 A3 無關,stash verify 過):test_create_mode_get_parse_result_all_controls_added / test_get_parse_result_party_added_when_ssp_has_no_parties,兩者皆 default_action == 'use_docx' 拿到 None 開 issue 給 docx default_action 邏輯 owner
F-regression-env(新) 廣域 regression 40 fail(A3 commit HEAD 上 verify 跟 A3 無關)— 多數是 _no_jwt / _hidden_secret / PART_* / PROJ_* 等 conftest fixture / env 相關 pre-existing 問題 環境問題,A3 ship 不擋;列 follow-up 給後續 test infra 處理

7. 部署 Handover

  • 無部署需求 — Session C 純 BE domain layer + DI wiring 改動,無 DB migration / 無 jedi-* 套件 bump
  • 改了 BE service code(T1 ParsedParty + T2 facade + DI)— 下次 manual 測 reconcile 行為前必重啟 BE
    lsof -ti:8000 | xargs kill -9
  • jedi-oscal 維持 path-dep,dev path 設定不變
  • pyproject.toml dev-path 改動仍未 commit(按鐵律不該 commit)
  • .env 環境 issue:使用者後續若要 manual smoke E2E,要先處理 JWT_SECRET JSON quote 問題(標 follow-up F-env)

8. 下一步(Session D 接手)

按 handoff prompt 2026-05-20-a3-session-C-to-D-implementation.md 執行:

  1. 讀 5 個必讀文件(plan-A3 T3+T4 段 / design-A3 §5+§6 / ssp_excel_import_app_service.py / person_reconciler.py / organization_reconciler.py + 對應 test 檔)
  2. T3 — A2 _confirm_*_flow 補 reconcile() 串接(~0.25d,4 個 integration test)
  3. T4 — Fuzzy 演算法完整落地(~0.5d,PersonReconciler normalized + fuzzy 8 case + OrganizationReconciler normalized + fuzzy 5 case)
  4. T3 + T4 結束提醒 user 重啟 BE
  5. 產 Session D → E handoff + Session D SUMMARY

預估:Session D 整段 ~0.75d


A3 phase 整體進度

Session 範圍 狀態 Commits
A brainstorm + design 落地 ✅ shipped 8e61def, 6e0f103
B writing-plans ✅ shipped 479bc28
C Implementation T0+T1+T2 ✅ shipped(本 session) b011f2f, 82f0dc8
D Implementation T3+T4 ⏳ pending
E Test + cucumber + 收尾 ⏳ pending

A3 phase 累計:5 commits(design ×2 + plan ×1 + implementation ×2)+ 4 handoff + 2 SUMMARY;剩餘 ~2d 進入後續 implementation + 收尾。


Session C 收口完成。