FAILURE MAP
← Case archive

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

Batch outgoing read receipts per conversation: missing marker default · case 01

A conversation that never sent a receipt suppresses the receipt for its seq-zero message.

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

ROOT CAUSE

The missing marker default decision evaluates `sent_markers.get(c, 0)]` where the contract requires `sent_markers.get(c, -1)]`.

THE FAILURE

The missing marker default decision evaluates `sent_markers.get(c, 0)]` where the contract requires `sent_markers.get(c, -1)]`.

Unsuccessful approach: Falling back to zero via "or" has the same effect on the first message. The attempted `(sent_markers.get(c) or 0)]` still disagrees with a fixture.

Case contract

pending_reads are [conv, seq] events produced while scrolling, in any order. Per conversation only the highest seq is sent, and only if it is above the marker already sent (missing marker means nothing sent, -1). In the background nothing is sent: the eligible conversations are deferred. Result {send: [[conv, seq]...] sorted by conv, defer: [conv...]}.

Why this case matters

Receipt batching limits traffic; batching errors send stale receipts or none at all.

1 / The failure

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

N = 1
observations = []
def solve(pending_reads, sent_markers, foreground):
    best = {}
    for conv, seq in pending_reads:
        if seq > best.get(conv, -1):
            best[conv] = seq
    rows = [[c, s] for c, s in sorted(best.items()) if s > sent_markers.get(c, 0)]
    if not foreground:
        return {'send': [], 'defer': [c for c, _ in rows]}
    return {'send': rows, 'defer': []}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('scroll events out of order', ([['a', 10], ['a', 4], ['b', 2]], {}, True), {'defer': [], 'send': [['a', 10], ['b', 2]]}), ('first message has seq zero', ([['n', 0]], {}, True), {'defer': [], 'send': [['n', 0]]}), ('not advancing', ([['a', 5], ['b', 8]], {'a': 5, 'b': 3}, True), {'defer': [], 'send': [['b', 8]]}), ('lower than sent', ([['a', 2]], {'a': 7}, True), {'defer': [], 'send': []}), ('background defers', ([['a', 3], ['b', 2]], {'b': 2}, False), {'defer': ['a'], 'send': []}), ('empty', ([], {'a': 1}, True), {'defer': [], 'send': []})], 2: [('scroll events out of order', ([['a', 11], ['a', 4], ['b', 2]], {}, True), {'defer': [], 'send': [['a', 11], ['b', 2]]}), ('first message has seq zero', ([['n', 0]], {}, True), {'defer': [], 'send': [['n', 0]]}), ('not advancing', ([['a', 5], ['b', 9]], {'a': 5, 'b': 3}, True), {'defer': [], 'send': [['b', 9]]}), ('lower than sent', ([['a', 2]], {'a': 8}, True), {'defer': [], 'send': []}), ('background defers', ([['a', 3], ['b', 3]], {'b': 3}, False), {'defer': ['a'], 'send': []}), ('empty', ([], {'a': 1}, True), {'defer': [], 'send': []})], 3: [('scroll events out of order', ([['a', 12], ['a', 4], ['b', 2]], {}, True), {'defer': [], 'send': [['a', 12], ['b', 2]]}), ('first message has seq zero', ([['n', 0]], {}, True), {'defer': [], 'send': [['n', 0]]}), ('not advancing', ([['a', 5], ['b', 10]], {'a': 5, 'b': 3}, True), {'defer': [], 'send': [['b', 10]]}), ('lower than sent', ([['a', 2]], {'a': 9}, True), {'defer': [], 'send': []}), ('background defers', ([['a', 3], ['b', 4]], {'b': 4}, False), {'defer': ['a'], 'send': []}), ('empty', ([], {'a': 1}, True), {'defer': [], 'send': []})], 4: [('scroll events out of order', ([['a', 13], ['a', 4], ['b', 2]], {}, True), {'defer': [], 'send': [['a', 13], ['b', 2]]}), ('first message has seq zero', ([['n', 0]], {}, True), {'defer': [], 'send': [['n', 0]]}), ('not advancing', ([['a', 5], ['b', 11]], {'a': 5, 'b': 3}, True), {'defer': [], 'send': [['b', 11]]}), ('lower than sent', ([['a', 2]], {'a': 10}, True), {'defer': [], 'send': []}), ('background defers', ([['a', 3], ['b', 5]], {'b': 5}, False), {'defer': ['a'], 'send': []}), ('empty', ([], {'a': 1}, True), {'defer': [], 'send': []})], 5: [('scroll events out of order', ([['a', 14], ['a', 4], ['b', 2]], {}, True), {'defer': [], 'send': [['a', 14], ['b', 2]]}), ('first message has seq zero', ([['n', 0]], {}, True), {'defer': [], 'send': [['n', 0]]}), ('not advancing', ([['a', 5], ['b', 12]], {'a': 5, 'b': 3}, True), {'defer': [], 'send': [['b', 12]]}), ('lower than sent', ([['a', 2]], {'a': 11}, True), {'defer': [], 'send': []}), ('background defers', ([['a', 3], ['b', 6]], {'b': 6}, False), {'defer': ['a'], 'send': []}), ('empty', ([], {'a': 1}, True), {'defer': [], 'send': []})]}
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
scroll events out of order{'defer': [], 'send': [['a', 10], ['b', 2]]}{'defer': [], 'send': [['a', 10], ['b', 2]]}Passed
first message has seq zero{'defer': [], 'send': []}{'defer': [], 'send': [['n', 0]]}Failed
not advancing{'defer': [], 'send': [['b', 8]]}{'defer': [], 'send': [['b', 8]]}Passed
lower than sent{'defer': [], 'send': []}{'defer': [], 'send': []}Passed
background defers{'defer': ['a'], 'send': []}{'defer': ['a'], 'send': []}Passed
empty{'defer': [], 'send': []}{'defer': [], 'send': []}Passed

SHA-256 / e234537197ed03feb7a2e419a93e3bc08db0128f61d4e34dced167e4725095a8

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(pending_reads, sent_markers, foreground):
    best = {}
    for conv, seq in pending_reads:
        if seq > best.get(conv, -1):
            best[conv] = seq
    rows = [[c, s] for c, s in sorted(best.items()) if s > (sent_markers.get(c) or 0)]
    if not foreground:
        return {'send': [], 'defer': [c for c, _ in rows]}
    return {'send': rows, 'defer': []}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('scroll events out of order', ([['a', 10], ['a', 4], ['b', 2]], {}, True), {'defer': [], 'send': [['a', 10], ['b', 2]]}), ('first message has seq zero', ([['n', 0]], {}, True), {'defer': [], 'send': [['n', 0]]}), ('not advancing', ([['a', 5], ['b', 8]], {'a': 5, 'b': 3}, True), {'defer': [], 'send': [['b', 8]]}), ('lower than sent', ([['a', 2]], {'a': 7}, True), {'defer': [], 'send': []}), ('background defers', ([['a', 3], ['b', 2]], {'b': 2}, False), {'defer': ['a'], 'send': []}), ('empty', ([], {'a': 1}, True), {'defer': [], 'send': []})], 2: [('scroll events out of order', ([['a', 11], ['a', 4], ['b', 2]], {}, True), {'defer': [], 'send': [['a', 11], ['b', 2]]}), ('first message has seq zero', ([['n', 0]], {}, True), {'defer': [], 'send': [['n', 0]]}), ('not advancing', ([['a', 5], ['b', 9]], {'a': 5, 'b': 3}, True), {'defer': [], 'send': [['b', 9]]}), ('lower than sent', ([['a', 2]], {'a': 8}, True), {'defer': [], 'send': []}), ('background defers', ([['a', 3], ['b', 3]], {'b': 3}, False), {'defer': ['a'], 'send': []}), ('empty', ([], {'a': 1}, True), {'defer': [], 'send': []})], 3: [('scroll events out of order', ([['a', 12], ['a', 4], ['b', 2]], {}, True), {'defer': [], 'send': [['a', 12], ['b', 2]]}), ('first message has seq zero', ([['n', 0]], {}, True), {'defer': [], 'send': [['n', 0]]}), ('not advancing', ([['a', 5], ['b', 10]], {'a': 5, 'b': 3}, True), {'defer': [], 'send': [['b', 10]]}), ('lower than sent', ([['a', 2]], {'a': 9}, True), {'defer': [], 'send': []}), ('background defers', ([['a', 3], ['b', 4]], {'b': 4}, False), {'defer': ['a'], 'send': []}), ('empty', ([], {'a': 1}, True), {'defer': [], 'send': []})], 4: [('scroll events out of order', ([['a', 13], ['a', 4], ['b', 2]], {}, True), {'defer': [], 'send': [['a', 13], ['b', 2]]}), ('first message has seq zero', ([['n', 0]], {}, True), {'defer': [], 'send': [['n', 0]]}), ('not advancing', ([['a', 5], ['b', 11]], {'a': 5, 'b': 3}, True), {'defer': [], 'send': [['b', 11]]}), ('lower than sent', ([['a', 2]], {'a': 10}, True), {'defer': [], 'send': []}), ('background defers', ([['a', 3], ['b', 5]], {'b': 5}, False), {'defer': ['a'], 'send': []}), ('empty', ([], {'a': 1}, True), {'defer': [], 'send': []})], 5: [('scroll events out of order', ([['a', 14], ['a', 4], ['b', 2]], {}, True), {'defer': [], 'send': [['a', 14], ['b', 2]]}), ('first message has seq zero', ([['n', 0]], {}, True), {'defer': [], 'send': [['n', 0]]}), ('not advancing', ([['a', 5], ['b', 12]], {'a': 5, 'b': 3}, True), {'defer': [], 'send': [['b', 12]]}), ('lower than sent', ([['a', 2]], {'a': 11}, True), {'defer': [], 'send': []}), ('background defers', ([['a', 3], ['b', 6]], {'b': 6}, False), {'defer': ['a'], 'send': []}), ('empty', ([], {'a': 1}, True), {'defer': [], 'send': []})]}
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
scroll events out of order{'defer': [], 'send': [['a', 10], ['b', 2]]}{'defer': [], 'send': [['a', 10], ['b', 2]]}Passed
first message has seq zero{'defer': [], 'send': []}{'defer': [], 'send': [['n', 0]]}Failed
not advancing{'defer': [], 'send': [['b', 8]]}{'defer': [], 'send': [['b', 8]]}Passed
lower than sent{'defer': [], 'send': []}{'defer': [], 'send': []}Passed
background defers{'defer': ['a'], 'send': []}{'defer': ['a'], 'send': []}Passed
empty{'defer': [], 'send': []}{'defer': [], 'send': []}Passed

SHA-256 / 8f8f27547c9ceeb41a02a6e9d50eb146f60ce2e6d8792fcc3e288451326862a1

HELD IN THE MEMBER ARCHIVE

The verified repair and its recorded checks are member-only.

This mechanism has 6 recorded checks per implementation. The open-access tier publishes the failure and the unsuccessful fix; the repaired source that passes every check, and the observations that prove it, are available to members.

Every case sharing this mechanism uses the same contract and the same repair, so this one record is held back for all of them.

Member access is invitation-based. Sign in with your invited account to inspect the repair.

Sign in to the archive ↗

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.181465+00:00.

Case digest / 4b96cefacc36dc9e399d8ca7f97fdeff1321229d1d54cdf1caaf4bf1e1b9580a