Skip to content
Sequence & interaction templates

Teaching Case — A Reply That Went to the Wrong Participant

The same interaction with one word changed: the card vault answers the order service instead of the saga that called it. Fourteen arrows, fourteen rows, the same labels — one arrowhead lands one column further along. The saga is left blocked forever on an answer that went elsewhere, and the order service receives an answer to a call it never made. No runtime could produce this interaction, and no tool that draws what it is handed can tell you so.

Template previewSequence & interaction
Checkout — card authorisation14 messages · deepest 4 openaltauth.code · 00"51","91"parpostnotifyplace orderPOST /ordersbegin(orderId)authorize(token, 4200)approved(authId)debit(4200)postedreceipt.readycaptured(authId)authorize(token, 4200)declined(code)failed(code)201 CreatedconfirmationShopperStorefrontOrder serviceLedgerconcurrentCard vaultPayment saga1 statement in this interaction contradicts another — over 6 lifelines and 14 messages. 3 of the 17 checks could not run.ERROR`Cards` replies to `Orders`, and the open call to `Cards` was made by `Saga` on line 16. `Saga` is left blocked on an answer that went elsewhere, and `Orders` receives an answer to a call itnever made. The arrowhead lands one column away from the correct one; nothing else about the figure changes.INFO6 lifelines, 14 messages, 2 fragments. 6 synchronous calls, 6 answered; the deepest point of the interaction has 4 calls open at once. The call stack could not be simulated to the end, so thereply findings above cover only the part that could be.OK13 of the 17 checks ran over every instance of their subject and found nothing: orphan-reply, after-destroy, before-create, double-create, double-destroy, par-interference, guard-overlap,guard-incomplete, activation-claim, unused-participant, undeclared-lifeline, duplicate-id, fragment-unclosed.

Make it your own.

sequence "Checkout — card authorisation"

actor       Shopper
participant Web     "Storefront"
participant Orders  "Order service"
participant Ledger  "Ledger"        concurrent
database    Cards   "Card vault"

Shopper -> Web              : place order
Web     -> Orders           : POST /orders
Orders  create Saga         "Payment saga"
Orders  -> Saga             : begin(orderId)

alt on auth.code : "00","51","91"
  when "00"
    Saga  -> Cards          : authorize(token, 4200)
    Cards reply Orders      : approved(authId)
    par
      branch "post"
        Saga   -> Ledger    : debit(4200)
        Ledger reply Saga   : posted
      branch "notify"
        Saga  async Web     : receipt.ready
    end
    Saga reply Orders       : captured(authId)
  when "51","91"
    Saga  -> Cards          : authorize(token, 4200)
    Cards reply Saga        : declined(code)
    Saga  reply Orders      : failed(code)
end

Orders destroy Saga
Orders reply Web            : 201 Created
Web    reply Shopper        : confirmation