Handoff Prompt — A5 smoke → bugfix(Session C ship → manual smoke + 修 bug)

使用方式:跑完 smoke checklist 撞到 bug → /clear 後把下方「交接 prompt 本體」貼到新 session 接手。 前置狀態:A5 Session A docs + B BE + C FE 三 session 全 shipped;BE 273 pytest 0 regression;FE build:DEV 過;manual smoke 待 user 跑。 典型 bug 範圍:BE A5 confirm flow / FE preview UX / decision 跟 write-time 一致性 / inline create rollback / i18n 漏 key / localStorage 邊界。


§1

交接 prompt 本體(從此貼到新 session)

我在 SSP 匯入匯出 Phase 2 / A5 的 manual smoke 跑出 bug,需要修。

A5 task arc 已 ship(BE + FE)— 本 session 工作集中在 bug 修復、不再有
新 feature 開工。可能修到 BE confirm flow / FE preview UX / decision 跟
write-time 一致性 / inline create rollback / i18n / localStorage 邊界。

範圍與工作 SOP
==============

1. 修 bug 走 docs/issues/ 流程:
   - 第一次踩到的 bug 寫 docs/issues/pending/YYYY-MM-DD-<title>.md
   - 修完 → 寫 changelog → resolved/ 加 Resolution 段(commit / 修復日期 /
     follow-up)+ git mv pending → resolved
2. 走 TDD:先寫 failing test 確認 RED → 實作 → 確認 GREEN
3. 修 root cause 不繞 workaround;BE side issue 一律在 BE 修(不要在 FE
   蓋資料)
4. 跨 BE/FE 修同個 bug → 各 repo 各一 commit + 各一 changelog(兩 repo
   issue 文件互相 cross-link)
5. 完成不自動 commit;階段性 milestone commit 不用問
6. 顯式 git add <file>,禁 -am / -A
7. 改 BE service 層 code 後必提醒 user kill BE process 重啟

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

BE branch: feature/ssp-import-export-phase2 (compliance-manager-be)
- A5 Session B + C 都 ship 完。最新 BE commit:
  · b942f85 docs A5 task arc 收口 SUMMARY + design §10.3 + tracker
  · c61ef02 docs A5 T14 manual smoke checklist
  · c091824 docs A5 Session B 收尾 handoff B→C
- BE 273 ssp_excel pytest 全綠 0 regression

FE branch: feature/ssp-import-export-phase2 (compliance-manager-fe)
- A5 Session C 5 commits + changelog commit:
  · cf88198 docs A5 Session C FE changelog
  · 332b393 feat T13 confirm Dialog + decision summary
  · 0cf3058 feat T12 RowActionMenu + InlineCreateDialog + EntityPickerDialog
  · 2412e74 feat T11 5 sheet preview + MatchStatusCell
  · 24622ee feat T10 ImportExcelPage + ImportExcelPreviewPage shell
  · c95d02a feat T9 SspExcelImportService + Pinia store + 3 routes

jedi-* 不動(path-dep 維持,Phase 2 整體完工才 bump)。
pyproject.toml dev-path 改動不 commit(沿 A4 慣例)。

5 條已知 caveat(user smoke 時的觀察點)
========================================

1. F-A5-decision-write-propagation (medium-high) ⚠ 最可能踩
   - 描述:A5 _apply_decisions 蓋 parsed_result 的 matched_*_id,但
     _write_all_data Step 7 by-key 對齊時被 orchestrator 結果覆寫
   - 觀察:user 選 device A,BE 最後 FK 可能仍是 B
   - 修法:跨 A4/A5 邊界,需在 A4 base.py reconciler 加
     _already_resolved_by_decision() hook + _dict_to_parsed_* helper 把
     A5 decision lock 寫到 ParsedDevice 等 typed entity
   - 影響檔:app/oscal/service/ssp_excel_import_app_service.py +
     domain/oscal/service/reconciliation/base.py + 5 個 reconciler
   - design §10.2.1 已記錄為 known limitation

2. F-A5-leveraged-action (medium) — leveraged sheet 操作欄空(無 party
   menu API + BE InlineCreateSchema OneOf 不含 leveraged)
   - 修法:補 party menu API (BE) + leveraged 加入 InlineCreateSchema
     OneOf(或拍板繼續維持「leveraged 只能 use_existing 不能新建」)

3. F-A5-content-overrides-ui (medium) — 01_基本資料 / 08_程序書 沒對
   應 sheet preview tab;user 無法在預覽頁編輯 metadata + 程序書連結
   - 修法:新加 SheetPreviewBasic + SheetPreviewRefDocs;接 store
     setMetadataOverride / setControlOverride

4. F-A5-cucumber (low) — env 配齊那天一次性補 A1-A5 共 5 phase

5. F-A5-user-invite-on-inline-create (low) — UserDomainService.add_user
   無 send_invite 機制;user 帳號 admin 後續手動處理

開工 SOP
========

第一步:必讀文件(順序)

1. 本 handoff prompt(你正在看)
2. docs/features/FR-011.2-2605-ssp-import-export-phase2/handoff/2026-05-21-a5-SUMMARY.md
   - 整段 A5 task arc 概覽 + 12 條偏差 + 5 條 follow-up
3. docs/features/FR-011.2-2605-ssp-import-export-phase2/design-A5.md
   - §10.1-10.4 12 條偏差全紀錄(修 bug 前對齊原設計)
4. docs/features/FR-011.2-2605-ssp-import-export-phase2/handoff/2026-05-21-a5-smoke-checklist.md
   - 8 段 smoke checklist 是 reference;user 踩到的 bug 對應哪段
5. docs/changelog/2026-05-21-feat-ssp-excel-import-phase2-a5-be.md
6. compliance-manager-fe/docs/changelog/2026-05-21-feat-ssp-excel-import-phase2-a5-fe.md
7. docs/issues/README.md + TEMPLATE.md(修 bug 寫 issue 規範)

讀完後給「我看完了,準備聽 bug 描述」確認。

第二步:根因追蹤

User 描述 bug 後:

1. 先 verify 行為(不要靠直覺猜):
   - 看 BE log/app.log + tail
   - 看 BE 實際寫進 DB 的資料(psql 連 192.168.50.188:25432/guidant_ai_dev
     用 cmmgr 帳號)
   - 看 FE browser console + Network panel
   - 確認 reproduce path

2. 比對 design + plan 預期行為
3. 寫 docs/issues/pending/YYYY-MM-DD-<title>.md
4. TDD:寫 RED test → fix → GREEN

第三步:修 bug

按 root cause 修,遵守:
- BE side issue 在 BE 修(不 FE 蓋資料)
- 跨層修改 → docs/analysis/YYYY-MM-DD-<topic>.md 記決策軌跡
- 改 BE service 層 → 提醒 user 重啟 BE
- 改 FE → 通常 Vite HMR 自動

第四步:規範文件齊全

每修一個 bug:
- changelog (type=fix) → docs/changelog/YYYY-MM-DD-fix-<title>.md
- frontmatter 寫 issue: docs/issues/resolved/<file>.md
- issue resolved/ 加 Resolution 段

第五步:跑回歸

- BE pytest 全套 + 新加的 fix test 必綠
- FE build:DEV 通

鐵律(沿 A0.1 + A1-A4 + A5 全部)
==================================

1. 顯式 git add <file>,禁 -am / -A
2. 不寫 docstring / 註解除非有 non-obvious why
3. DDD 嚴格分層;Route 不查 DB
4. App service @transaction;不要在 helper 外開 session_scope
5. Test 必 patch logger 避開 jedi DBLogHandler 撞 SessionLocal=None
6. 寫 SQL 不用 DTO 名當 column;必 grep ORM Mapped[]
7. SQLAlchemy text() 用 cast(:p AS type) 不用 :param::type
8. 修 bug 先驗證 DB / response 真實狀態,不靠直覺
9. 階段性 commit 不用問
10. 重大決策 → docs/analysis/
11. 重型 bug 跨層 → docs/issues/pending/
12. jedi-* 不動(A5 已 ship;Phase 2 完工才 bump)

不在本 session 範圍
====================

- A5 新 feature 擴張(5 條 follow-up 視優先序評估)
- Track B 開工
- jedi-* 套件改動
- A4 ship 的 reconciler / WriteStrategy / pipeline 行為改動(除非修
  F-A5-decision-write-propagation 而必須動 base.py — 此時擴 issue 文件
  詳述跨層影響)

謝謝。

§2

收口清單(A5 ship → bugfix 端)

本 handoff 寫完後可直接 /clear 換 session:

  1. 新 session 貼上方 prompt 接手 manual smoke 後的 bug 修復工作
  2. 預期主要 bug 範圍:F-A5-decision-write-propagation(最高優先觀察點)/ leveraged action UI / 其他 smoke 踩到的小 bug
  3. 修完 → 各 bug 都有對應 issue + changelog + 必要時 analysis

換 session 後 user 可選:

  • 跑完整 smoke → 一次性把所有 bug 列給新 session
  • 或單個 bug 撞到就回報 → 一個一個修

兩種模式都 OK,前者較有效率(避免 context-switch 成本)。