語意變更不能 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 為復工驗收條件