FAILURE MAP
← Case archive

FA-76261 / Chat ordering and read receipts / Open access

Assign idempotent per-conversation sequence numbers: idempotency scope · case 01

A second sender, or the same sender in another conversation, who happens to reuse a nonce gets the other message's seq.

Verified by executionVariant 1 · 6 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The idempotency scope decision evaluates `key = nonce` where the contract requires `key = (conv, sender, nonce)`.

VERIFIED REPAIR

Use `key = (conv, sender, nonce)` for the idempotency scope decision and keep every other rule of the model unchanged.

Unsuccessful approach: Scoping by sender still merges the same client nonce across conversations. The attempted `key = (sender, nonce)` still disagrees with a fixture.

Case contract

requests are [conv, sender, nonce] in arrival order; members maps conv -> member list. A sender who is not a member gets "forbidden" and consumes nothing. Each conversation numbers accepted messages 1, 2, 3... A retry with the same (conv, sender, nonce) returns the originally assigned seq without consuming a new one.

Why this case matters

Server sequencing is the backbone of chat ordering; idempotency errors create duplicates or gaps.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(requests, members):
    counters = {}
    known = {}
    out = []
    for conv, sender, nonce in requests:
        if sender not in members.get(conv, []):
            out.append('forbidden')
            continue
        key = nonce
        if key in known:
            out.append(known[key])
            continue
        counters[conv] = counters.get(conv, 0) + 1
        known[key] = counters[conv]
        out.append(counters[conv])
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('nonce reused by another sender', ([['c', 'al', 'n1'], ['c', 'bo', 'n1']], {'c': ['al', 'bo']}), [1, 2]), ('nonce reused in another conversation', ([['d', 'al', 'z'], ['c', 'al', 'n1'], ['d', 'al', 'n1']], {'c': ['al'], 'd': ['al']}), [1, 1, 2]), ('two conversations interleaved', ([['c', 'al', 'a'], ['d', 'al', 'b'], ['c', 'al', 'c']], {'c': ['al'], 'd': ['al']}), [1, 1, 2]), ('retry returns original', ([['c', 'al', 'x'], ['c', 'al', 'y'], ['c', 'al', 'x']], {'c': ['al']}), [1, 2, 1]), ('forbidden sender', ([['c', 'eve', 'z'], ['c', 'al', 'q']], {'c': ['al']}), ['forbidden', 1]), ('burst', ([['c', 'al', 'm0'], ['c', 'al', 'm1']], {'c': ['al']}), [1, 2])], 2: [('nonce reused by another sender', ([['c', 'al', 'n1'], ['c', 'bo', 'n1']], {'c': ['al', 'bo']}), [1, 2]), ('nonce reused in another conversation', ([['d', 'al', 'z'], ['c', 'al', 'n2'], ['d', 'al', 'n2']], {'c': ['al'], 'd': ['al']}), [1, 1, 2]), ('two conversations interleaved', ([['c', 'al', 'a'], ['d', 'al', 'b'], ['c', 'al', 'c']], {'c': ['al'], 'd': ['al']}), [1, 1, 2]), ('retry returns original', ([['c', 'al', 'x'], ['c', 'al', 'y'], ['c', 'al', 'x']], {'c': ['al']}), [1, 2, 1]), ('forbidden sender', ([['c', 'eve', 'z'], ['c', 'al', 'q']], {'c': ['al']}), ['forbidden', 1]), ('burst', ([['c', 'al', 'm0'], ['c', 'al', 'm1'], ['c', 'al', 'm2']], {'c': ['al']}), [1, 2, 3])], 3: [('nonce reused by another sender', ([['c', 'al', 'n1'], ['c', 'bo', 'n1']], {'c': ['al', 'bo']}), [1, 2]), ('nonce reused in another conversation', ([['d', 'al', 'z'], ['c', 'al', 'n3'], ['d', 'al', 'n3']], {'c': ['al'], 'd': ['al']}), [1, 1, 2]), ('two conversations interleaved', ([['c', 'al', 'a'], ['d', 'al', 'b'], ['c', 'al', 'c']], {'c': ['al'], 'd': ['al']}), [1, 1, 2]), ('retry returns original', ([['c', 'al', 'x'], ['c', 'al', 'y'], ['c', 'al', 'x']], {'c': ['al']}), [1, 2, 1]), ('forbidden sender', ([['c', 'eve', 'z'], ['c', 'al', 'q']], {'c': ['al']}), ['forbidden', 1]), ('burst', ([['c', 'al', 'm0'], ['c', 'al', 'm1'], ['c', 'al', 'm2'], ['c', 'al', 'm3']], {'c': ['al']}), [1, 2, 3, 4])], 4: [('nonce reused by another sender', ([['c', 'al', 'n1'], ['c', 'bo', 'n1']], {'c': ['al', 'bo']}), [1, 2]), ('nonce reused in another conversation', ([['d', 'al', 'z'], ['c', 'al', 'n4'], ['d', 'al', 'n4']], {'c': ['al'], 'd': ['al']}), [1, 1, 2]), ('two conversations interleaved', ([['c', 'al', 'a'], ['d', 'al', 'b'], ['c', 'al', 'c']], {'c': ['al'], 'd': ['al']}), [1, 1, 2]), ('retry returns original', ([['c', 'al', 'x'], ['c', 'al', 'y'], ['c', 'al', 'x']], {'c': ['al']}), [1, 2, 1]), ('forbidden sender', ([['c', 'eve', 'z'], ['c', 'al', 'q']], {'c': ['al']}), ['forbidden', 1]), ('burst', ([['c', 'al', 'm0'], ['c', 'al', 'm1'], ['c', 'al', 'm2'], ['c', 'al', 'm3'], ['c', 'al', 'm4']], {'c': ['al']}), [1, 2, 3, 4, 5])], 5: [('nonce reused by another sender', ([['c', 'al', 'n1'], ['c', 'bo', 'n1']], {'c': ['al', 'bo']}), [1, 2]), ('nonce reused in another conversation', ([['d', 'al', 'z'], ['c', 'al', 'n5'], ['d', 'al', 'n5']], {'c': ['al'], 'd': ['al']}), [1, 1, 2]), ('two conversations interleaved', ([['c', 'al', 'a'], ['d', 'al', 'b'], ['c', 'al', 'c']], {'c': ['al'], 'd': ['al']}), [1, 1, 2]), ('retry returns original', ([['c', 'al', 'x'], ['c', 'al', 'y'], ['c', 'al', 'x']], {'c': ['al']}), [1, 2, 1]), ('forbidden sender', ([['c', 'eve', 'z'], ['c', 'al', 'q']], {'c': ['al']}), ['forbidden', 1]), ('burst', ([['c', 'al', 'm0'], ['c', 'al', 'm1'], ['c', 'al', 'm2'], ['c', 'al', 'm3'], ['c', 'al', 'm4'], ['c', 'al', 'm5']], {'c': ['al']}), [1, 2, 3, 4, 5, 6])]}
for _label, _args, _expected in _CASES[N]:
    check(_label, solve(*_args), _expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
nonce reused by another sender[1, 1][1, 2]Failed
nonce reused in another conversation[1, 1, 1][1, 1, 2]Failed
two conversations interleaved[1, 1, 2][1, 1, 2]Passed
retry returns original[1, 2, 1][1, 2, 1]Passed
forbidden sender['forbidden', 1]['forbidden', 1]Passed
burst[1, 2][1, 2]Passed

SHA-256 / 8c14cff8f3c3b055955b4b098848299fe302212cb75b1f11c7999f2a779eadf5

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(requests, members):
    counters = {}
    known = {}
    out = []
    for conv, sender, nonce in requests:
        if sender not in members.get(conv, []):
            out.append('forbidden')
            continue
        key = (sender, nonce)
        if key in known:
            out.append(known[key])
            continue
        counters[conv] = counters.get(conv, 0) + 1
        known[key] = counters[conv]
        out.append(counters[conv])
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('nonce reused by another sender', ([['c', 'al', 'n1'], ['c', 'bo', 'n1']], {'c': ['al', 'bo']}), [1, 2]), ('nonce reused in another conversation', ([['d', 'al', 'z'], ['c', 'al', 'n1'], ['d', 'al', 'n1']], {'c': ['al'], 'd': ['al']}), [1, 1, 2]), ('two conversations interleaved', ([['c', 'al', 'a'], ['d', 'al', 'b'], ['c', 'al', 'c']], {'c': ['al'], 'd': ['al']}), [1, 1, 2]), ('retry returns original', ([['c', 'al', 'x'], ['c', 'al', 'y'], ['c', 'al', 'x']], {'c': ['al']}), [1, 2, 1]), ('forbidden sender', ([['c', 'eve', 'z'], ['c', 'al', 'q']], {'c': ['al']}), ['forbidden', 1]), ('burst', ([['c', 'al', 'm0'], ['c', 'al', 'm1']], {'c': ['al']}), [1, 2])], 2: [('nonce reused by another sender', ([['c', 'al', 'n1'], ['c', 'bo', 'n1']], {'c': ['al', 'bo']}), [1, 2]), ('nonce reused in another conversation', ([['d', 'al', 'z'], ['c', 'al', 'n2'], ['d', 'al', 'n2']], {'c': ['al'], 'd': ['al']}), [1, 1, 2]), ('two conversations interleaved', ([['c', 'al', 'a'], ['d', 'al', 'b'], ['c', 'al', 'c']], {'c': ['al'], 'd': ['al']}), [1, 1, 2]), ('retry returns original', ([['c', 'al', 'x'], ['c', 'al', 'y'], ['c', 'al', 'x']], {'c': ['al']}), [1, 2, 1]), ('forbidden sender', ([['c', 'eve', 'z'], ['c', 'al', 'q']], {'c': ['al']}), ['forbidden', 1]), ('burst', ([['c', 'al', 'm0'], ['c', 'al', 'm1'], ['c', 'al', 'm2']], {'c': ['al']}), [1, 2, 3])], 3: [('nonce reused by another sender', ([['c', 'al', 'n1'], ['c', 'bo', 'n1']], {'c': ['al', 'bo']}), [1, 2]), ('nonce reused in another conversation', ([['d', 'al', 'z'], ['c', 'al', 'n3'], ['d', 'al', 'n3']], {'c': ['al'], 'd': ['al']}), [1, 1, 2]), ('two conversations interleaved', ([['c', 'al', 'a'], ['d', 'al', 'b'], ['c', 'al', 'c']], {'c': ['al'], 'd': ['al']}), [1, 1, 2]), ('retry returns original', ([['c', 'al', 'x'], ['c', 'al', 'y'], ['c', 'al', 'x']], {'c': ['al']}), [1, 2, 1]), ('forbidden sender', ([['c', 'eve', 'z'], ['c', 'al', 'q']], {'c': ['al']}), ['forbidden', 1]), ('burst', ([['c', 'al', 'm0'], ['c', 'al', 'm1'], ['c', 'al', 'm2'], ['c', 'al', 'm3']], {'c': ['al']}), [1, 2, 3, 4])], 4: [('nonce reused by another sender', ([['c', 'al', 'n1'], ['c', 'bo', 'n1']], {'c': ['al', 'bo']}), [1, 2]), ('nonce reused in another conversation', ([['d', 'al', 'z'], ['c', 'al', 'n4'], ['d', 'al', 'n4']], {'c': ['al'], 'd': ['al']}), [1, 1, 2]), ('two conversations interleaved', ([['c', 'al', 'a'], ['d', 'al', 'b'], ['c', 'al', 'c']], {'c': ['al'], 'd': ['al']}), [1, 1, 2]), ('retry returns original', ([['c', 'al', 'x'], ['c', 'al', 'y'], ['c', 'al', 'x']], {'c': ['al']}), [1, 2, 1]), ('forbidden sender', ([['c', 'eve', 'z'], ['c', 'al', 'q']], {'c': ['al']}), ['forbidden', 1]), ('burst', ([['c', 'al', 'm0'], ['c', 'al', 'm1'], ['c', 'al', 'm2'], ['c', 'al', 'm3'], ['c', 'al', 'm4']], {'c': ['al']}), [1, 2, 3, 4, 5])], 5: [('nonce reused by another sender', ([['c', 'al', 'n1'], ['c', 'bo', 'n1']], {'c': ['al', 'bo']}), [1, 2]), ('nonce reused in another conversation', ([['d', 'al', 'z'], ['c', 'al', 'n5'], ['d', 'al', 'n5']], {'c': ['al'], 'd': ['al']}), [1, 1, 2]), ('two conversations interleaved', ([['c', 'al', 'a'], ['d', 'al', 'b'], ['c', 'al', 'c']], {'c': ['al'], 'd': ['al']}), [1, 1, 2]), ('retry returns original', ([['c', 'al', 'x'], ['c', 'al', 'y'], ['c', 'al', 'x']], {'c': ['al']}), [1, 2, 1]), ('forbidden sender', ([['c', 'eve', 'z'], ['c', 'al', 'q']], {'c': ['al']}), ['forbidden', 1]), ('burst', ([['c', 'al', 'm0'], ['c', 'al', 'm1'], ['c', 'al', 'm2'], ['c', 'al', 'm3'], ['c', 'al', 'm4'], ['c', 'al', 'm5']], {'c': ['al']}), [1, 2, 3, 4, 5, 6])]}
for _label, _args, _expected in _CASES[N]:
    check(_label, solve(*_args), _expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
nonce reused by another sender[1, 2][1, 2]Passed
nonce reused in another conversation[1, 1, 1][1, 1, 2]Failed
two conversations interleaved[1, 1, 2][1, 1, 2]Passed
retry returns original[1, 2, 1][1, 2, 1]Passed
forbidden sender['forbidden', 1]['forbidden', 1]Passed
burst[1, 2][1, 2]Passed

SHA-256 / d857a9ff448b928b0345d5449d7cebffe3d87afed07fd705bed9443388b0df2c

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(requests, members):
    counters = {}
    known = {}
    out = []
    for conv, sender, nonce in requests:
        if sender not in members.get(conv, []):
            out.append('forbidden')
            continue
        key = (conv, sender, nonce)
        if key in known:
            out.append(known[key])
            continue
        counters[conv] = counters.get(conv, 0) + 1
        known[key] = counters[conv]
        out.append(counters[conv])
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('nonce reused by another sender', ([['c', 'al', 'n1'], ['c', 'bo', 'n1']], {'c': ['al', 'bo']}), [1, 2]), ('nonce reused in another conversation', ([['d', 'al', 'z'], ['c', 'al', 'n1'], ['d', 'al', 'n1']], {'c': ['al'], 'd': ['al']}), [1, 1, 2]), ('two conversations interleaved', ([['c', 'al', 'a'], ['d', 'al', 'b'], ['c', 'al', 'c']], {'c': ['al'], 'd': ['al']}), [1, 1, 2]), ('retry returns original', ([['c', 'al', 'x'], ['c', 'al', 'y'], ['c', 'al', 'x']], {'c': ['al']}), [1, 2, 1]), ('forbidden sender', ([['c', 'eve', 'z'], ['c', 'al', 'q']], {'c': ['al']}), ['forbidden', 1]), ('burst', ([['c', 'al', 'm0'], ['c', 'al', 'm1']], {'c': ['al']}), [1, 2])], 2: [('nonce reused by another sender', ([['c', 'al', 'n1'], ['c', 'bo', 'n1']], {'c': ['al', 'bo']}), [1, 2]), ('nonce reused in another conversation', ([['d', 'al', 'z'], ['c', 'al', 'n2'], ['d', 'al', 'n2']], {'c': ['al'], 'd': ['al']}), [1, 1, 2]), ('two conversations interleaved', ([['c', 'al', 'a'], ['d', 'al', 'b'], ['c', 'al', 'c']], {'c': ['al'], 'd': ['al']}), [1, 1, 2]), ('retry returns original', ([['c', 'al', 'x'], ['c', 'al', 'y'], ['c', 'al', 'x']], {'c': ['al']}), [1, 2, 1]), ('forbidden sender', ([['c', 'eve', 'z'], ['c', 'al', 'q']], {'c': ['al']}), ['forbidden', 1]), ('burst', ([['c', 'al', 'm0'], ['c', 'al', 'm1'], ['c', 'al', 'm2']], {'c': ['al']}), [1, 2, 3])], 3: [('nonce reused by another sender', ([['c', 'al', 'n1'], ['c', 'bo', 'n1']], {'c': ['al', 'bo']}), [1, 2]), ('nonce reused in another conversation', ([['d', 'al', 'z'], ['c', 'al', 'n3'], ['d', 'al', 'n3']], {'c': ['al'], 'd': ['al']}), [1, 1, 2]), ('two conversations interleaved', ([['c', 'al', 'a'], ['d', 'al', 'b'], ['c', 'al', 'c']], {'c': ['al'], 'd': ['al']}), [1, 1, 2]), ('retry returns original', ([['c', 'al', 'x'], ['c', 'al', 'y'], ['c', 'al', 'x']], {'c': ['al']}), [1, 2, 1]), ('forbidden sender', ([['c', 'eve', 'z'], ['c', 'al', 'q']], {'c': ['al']}), ['forbidden', 1]), ('burst', ([['c', 'al', 'm0'], ['c', 'al', 'm1'], ['c', 'al', 'm2'], ['c', 'al', 'm3']], {'c': ['al']}), [1, 2, 3, 4])], 4: [('nonce reused by another sender', ([['c', 'al', 'n1'], ['c', 'bo', 'n1']], {'c': ['al', 'bo']}), [1, 2]), ('nonce reused in another conversation', ([['d', 'al', 'z'], ['c', 'al', 'n4'], ['d', 'al', 'n4']], {'c': ['al'], 'd': ['al']}), [1, 1, 2]), ('two conversations interleaved', ([['c', 'al', 'a'], ['d', 'al', 'b'], ['c', 'al', 'c']], {'c': ['al'], 'd': ['al']}), [1, 1, 2]), ('retry returns original', ([['c', 'al', 'x'], ['c', 'al', 'y'], ['c', 'al', 'x']], {'c': ['al']}), [1, 2, 1]), ('forbidden sender', ([['c', 'eve', 'z'], ['c', 'al', 'q']], {'c': ['al']}), ['forbidden', 1]), ('burst', ([['c', 'al', 'm0'], ['c', 'al', 'm1'], ['c', 'al', 'm2'], ['c', 'al', 'm3'], ['c', 'al', 'm4']], {'c': ['al']}), [1, 2, 3, 4, 5])], 5: [('nonce reused by another sender', ([['c', 'al', 'n1'], ['c', 'bo', 'n1']], {'c': ['al', 'bo']}), [1, 2]), ('nonce reused in another conversation', ([['d', 'al', 'z'], ['c', 'al', 'n5'], ['d', 'al', 'n5']], {'c': ['al'], 'd': ['al']}), [1, 1, 2]), ('two conversations interleaved', ([['c', 'al', 'a'], ['d', 'al', 'b'], ['c', 'al', 'c']], {'c': ['al'], 'd': ['al']}), [1, 1, 2]), ('retry returns original', ([['c', 'al', 'x'], ['c', 'al', 'y'], ['c', 'al', 'x']], {'c': ['al']}), [1, 2, 1]), ('forbidden sender', ([['c', 'eve', 'z'], ['c', 'al', 'q']], {'c': ['al']}), ['forbidden', 1]), ('burst', ([['c', 'al', 'm0'], ['c', 'al', 'm1'], ['c', 'al', 'm2'], ['c', 'al', 'm3'], ['c', 'al', 'm4'], ['c', 'al', 'm5']], {'c': ['al']}), [1, 2, 3, 4, 5, 6])]}
for _label, _args, _expected in _CASES[N]:
    check(_label, solve(*_args), _expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
nonce reused by another sender[1, 2][1, 2]Passed
nonce reused in another conversation[1, 1, 2][1, 1, 2]Passed
two conversations interleaved[1, 1, 2][1, 1, 2]Passed
retry returns original[1, 2, 1][1, 2, 1]Passed
forbidden sender['forbidden', 1]['forbidden', 1]Passed
burst[1, 2][1, 2]Passed

SHA-256 / 18a59b9a57f8b8a0ae5fc5af3c9fa4f75873d0ea5bdde29102533309423fcc1c

Verification & scope

Stipulated offline chat model; not a complete messaging protocol, client or server implementation. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.

Observations recorded using Python 3.12.14 at 2026-09-29T14:49:14.712955+00:00.

Case digest / 9e99a2bdc1ae6e5ed196cf110e0f8bc1b0367967e1b8c3b94c3a00db1f87ad8c