語意變更不能 additive-first,一律當 breaking
契約要改時的通則是 additive-first(先加後刪 + 過渡期),避免多條平行線同時炸。但這招只救得了結構變更;語意變更加欄位是沒有用的。
欄位形狀沒動、意思換了——例如 status = DONE 原本代表「已出貨」改成代表「已付款」——消費端讀得到、parse 得過、測試全綠,然後行為悄悄錯掉。
三個對應手段
- 把語意寫進契約本身:欄位 description、單位、時區、狀態機合法轉移表、錯誤碼語意表。契約裡沒有這些,語意就無處可 diff。
- semantic diff:對 description/enum/狀態轉移表做 diff,任何非新增的變更一律標為 BREAKING 並列出所有消費端。BREAKING 與否是 diff 判定的,不是人工宣稱的。
- 語意變更走改名或新版本,不是加欄位。
- 真正的證偽機制是 consumer-driven contract test 取代 E2E 驗串接:消費端把自己理解的語意寫成測試,上游一改就紅。
停線判定
規格變更 SOP 裡兩者的處置不同:
- 契約為 additive → 不停線,加過渡期
- 語意/狀態機變更 → 受影響的線立即停在當前 commit,不繼續往前做;更新 spec → 場景表 → AC → skeleton → 契約重新凍結 pin 新 SHA → 各線以新 SHA 重啟,consumer contract test 為復工驗收條件