Catch a double credit before writing code
\* The bank can deliver one webhook twice Deliver(id) == \* no idempotency check /\ balance' = [balance EXCEPT !.alice = @ - 500, !.bob = @ + 500] /\ applied' = applied \union {id} NoDoubleCredit == balance.bob <= 500
Error: Invariant NoDoubleCredit is violated. State 1: <Initial predicate> bob = 0 State 2: <Deliver("t81")> bob = 500 State 3: <Deliver("t81")> bob = 1000
TLC tries every order of events, so the duplicate webhook is found before any code exists.