Stable business identity makes repeated delivery convergent and reconcilable.
Kafka External-Effect Identity
Kafka delivery identity must become stable business-operation identity before an external effect.
const key = `order:${event.orderId}:capture:v1`
const fingerprint = sha256(canonicalJson(event.payment))
const known = await operations.get(key)
if (known && known.fingerprint !== fingerprint) throw new KeyReuseConflict()
const result = await payments.capture({
idempotencyKey: key,
amount: event.payment.amount,
})
await operations.record(key, fingerprint, result.providerId)
// Commit the offset after durable evidence. On ambiguity, query by key.Invariant: One logical Kafka record produces at most one externally committed business effect.
Use when: A consumer calls a provider and may crash before committing progress.
Why this boundary matters
A consumer can crash after a provider commits but before Kafka records progress. Reusing one key makes retry converge instead of repeat the effect.
Failure policy
| Boundary | Action |
|---|---|
| First delivery | Create the stable business operation key |
| Provider accepts | Persist provider identity before committing progress |
| Delivery repeats | Reuse the same key and payload fingerprint |
| Payload differs | Reject key reuse |
| Outcome ambiguous | Query status; never mint a new key |
Trade-offs
Idempotency keys require durable retention and provider support. They contain duplicates but do not create atomicity across Kafka and the provider; reconciliation remains necessary.
Decision rule: Use one key derived from immutable business identity whenever external success can precede durable consumer progress.