FA-75871 / Chat ordering and read receipts / Open access
Advance a stored read marker from a device report: monotonic advance · case 01
A delayed report from a slower device drags the read marker backwards and resurrects already-read messages.
ROOT CAUSE
The monotonic advance decision evaluates `new = target` where the contract requires `new = max(marker, target)`.
VERIFIED REPAIR
Use `new = max(marker, target)` for the monotonic advance decision and keep every other rule of the model unchanged.
Unsuccessful approach: Guarding only against a zero report still lets any lower late report regress the marker. The attempted `new = target if target else marker` still disagrees with a fixture.
Case contract
A report from a device session whose epoch differs from the current epoch (for example a session that predates a "mark unread") is ignored. Otherwise the report is clamped to latest_seq and the marker only moves forward. Result: {marker, broadcast (true only when the marker changed), unread = max(0, latest_seq - marker)}.
Why this case matters
Read markers drive unread badges on every device; regressions or stale sessions resurrect or hide unread messages.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(marker, report, latest_seq, session_epoch, current_epoch):
if session_epoch != current_epoch:
return {'marker': marker, 'broadcast': False, 'unread': max(0, latest_seq - marker)}
target = min(report, latest_seq)
new = target
return {'marker': new, 'broadcast': new != marker, 'unread': max(0, latest_seq - new)}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('stale session after mark-unread', (10, 15, 18, 3, 4), {'broadcast': False, 'marker': 10, 'unread': 8}), ('session two epochs behind', (10, 17, 19, 1, 3), {'broadcast': False, 'marker': 10, 'unread': 9}), ('report beyond latest', (1, 21, 5, 2, 2), {'broadcast': True, 'marker': 5, 'unread': 0}), ('older report arrives late', (51, 41, 61, 1, 1), {'broadcast': False, 'marker': 51, 'unread': 10}), ('equal report no broadcast', (30, 30, 41, 5, 5), {'broadcast': False, 'marker': 30, 'unread': 11}), ('history trimmed below marker', (21, 5, 18, 1, 1), {'broadcast': False, 'marker': 21, 'unread': 0}), ('normal advance', (1, 4, 11, 7, 7), {'broadcast': True, 'marker': 4, 'unread': 7}), ('lower report with zero', (3, 0, 7, 2, 2), {'broadcast': False, 'marker': 3, 'unread': 4})], 2: [('stale session after mark-unread', (20, 25, 28, 3, 4), {'broadcast': False, 'marker': 20, 'unread': 8}), ('session two epochs behind', (20, 27, 29, 1, 3), {'broadcast': False, 'marker': 20, 'unread': 9}), ('report beyond latest', (2, 22, 6, 2, 2), {'broadcast': True, 'marker': 6, 'unread': 0}), ('older report arrives late', (52, 42, 62, 1, 1), {'broadcast': False, 'marker': 52, 'unread': 10}), ('equal report no broadcast', (30, 30, 42, 5, 5), {'broadcast': False, 'marker': 30, 'unread': 12}), ('history trimmed below marker', (22, 5, 18, 1, 1), {'broadcast': False, 'marker': 22, 'unread': 0}), ('normal advance', (2, 5, 12, 7, 7), {'broadcast': True, 'marker': 5, 'unread': 7}), ('lower report with zero', (4, 0, 8, 2, 2), {'broadcast': False, 'marker': 4, 'unread': 4})], 3: [('stale session after mark-unread', (30, 35, 38, 3, 4), {'broadcast': False, 'marker': 30, 'unread': 8}), ('session two epochs behind', (30, 37, 39, 1, 3), {'broadcast': False, 'marker': 30, 'unread': 9}), ('report beyond latest', (3, 23, 7, 2, 2), {'broadcast': True, 'marker': 7, 'unread': 0}), ('older report arrives late', (53, 43, 63, 1, 1), {'broadcast': False, 'marker': 53, 'unread': 10}), ('equal report no broadcast', (30, 30, 43, 5, 5), {'broadcast': False, 'marker': 30, 'unread': 13}), ('history trimmed below marker', (23, 5, 18, 1, 1), {'broadcast': False, 'marker': 23, 'unread': 0}), ('normal advance', (3, 6, 13, 7, 7), {'broadcast': True, 'marker': 6, 'unread': 7}), ('lower report with zero', (5, 0, 9, 2, 2), {'broadcast': False, 'marker': 5, 'unread': 4})], 4: [('stale session after mark-unread', (40, 45, 48, 3, 4), {'broadcast': False, 'marker': 40, 'unread': 8}), ('session two epochs behind', (40, 47, 49, 1, 3), {'broadcast': False, 'marker': 40, 'unread': 9}), ('report beyond latest', (4, 24, 8, 2, 2), {'broadcast': True, 'marker': 8, 'unread': 0}), ('older report arrives late', (54, 44, 64, 1, 1), {'broadcast': False, 'marker': 54, 'unread': 10}), ('equal report no broadcast', (30, 30, 44, 5, 5), {'broadcast': False, 'marker': 30, 'unread': 14}), ('history trimmed below marker', (24, 5, 18, 1, 1), {'broadcast': False, 'marker': 24, 'unread': 0}), ('normal advance', (4, 7, 14, 7, 7), {'broadcast': True, 'marker': 7, 'unread': 7}), ('lower report with zero', (6, 0, 10, 2, 2), {'broadcast': False, 'marker': 6, 'unread': 4})], 5: [('stale session after mark-unread', (50, 55, 58, 3, 4), {'broadcast': False, 'marker': 50, 'unread': 8}), ('session two epochs behind', (50, 57, 59, 1, 3), {'broadcast': False, 'marker': 50, 'unread': 9}), ('report beyond latest', (5, 25, 9, 2, 2), {'broadcast': True, 'marker': 9, 'unread': 0}), ('older report arrives late', (55, 45, 65, 1, 1), {'broadcast': False, 'marker': 55, 'unread': 10}), ('equal report no broadcast', (30, 30, 45, 5, 5), {'broadcast': False, 'marker': 30, 'unread': 15}), ('history trimmed below marker', (25, 5, 18, 1, 1), {'broadcast': False, 'marker': 25, 'unread': 0}), ('normal advance', (5, 8, 15, 7, 7), {'broadcast': True, 'marker': 8, 'unread': 7}), ('lower report with zero', (7, 0, 11, 2, 2), {'broadcast': False, 'marker': 7, 'unread': 4})]}
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| stale session after mark-unread | {'broadcast': False, 'marker': 10, 'unread': 8} | {'broadcast': False, 'marker': 10, 'unread': 8} | Passed |
| session two epochs behind | {'broadcast': False, 'marker': 10, 'unread': 9} | {'broadcast': False, 'marker': 10, 'unread': 9} | Passed |
| report beyond latest | {'broadcast': True, 'marker': 5, 'unread': 0} | {'broadcast': True, 'marker': 5, 'unread': 0} | Passed |
| older report arrives late | {'broadcast': True, 'marker': 41, 'unread': 20} | {'broadcast': False, 'marker': 51, 'unread': 10} | Failed |
| equal report no broadcast | {'broadcast': False, 'marker': 30, 'unread': 11} | {'broadcast': False, 'marker': 30, 'unread': 11} | Passed |
| history trimmed below marker | {'broadcast': True, 'marker': 5, 'unread': 13} | {'broadcast': False, 'marker': 21, 'unread': 0} | Failed |
| normal advance | {'broadcast': True, 'marker': 4, 'unread': 7} | {'broadcast': True, 'marker': 4, 'unread': 7} | Passed |
| lower report with zero | {'broadcast': True, 'marker': 0, 'unread': 7} | {'broadcast': False, 'marker': 3, 'unread': 4} | Failed |
SHA-256 / b54bcd7ec8dc3fad52418320bb0c54c879b662dfae55a1d702b7780ae1252e5f
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(marker, report, latest_seq, session_epoch, current_epoch):
if session_epoch != current_epoch:
return {'marker': marker, 'broadcast': False, 'unread': max(0, latest_seq - marker)}
target = min(report, latest_seq)
new = target if target else marker
return {'marker': new, 'broadcast': new != marker, 'unread': max(0, latest_seq - new)}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('stale session after mark-unread', (10, 15, 18, 3, 4), {'broadcast': False, 'marker': 10, 'unread': 8}), ('session two epochs behind', (10, 17, 19, 1, 3), {'broadcast': False, 'marker': 10, 'unread': 9}), ('report beyond latest', (1, 21, 5, 2, 2), {'broadcast': True, 'marker': 5, 'unread': 0}), ('older report arrives late', (51, 41, 61, 1, 1), {'broadcast': False, 'marker': 51, 'unread': 10}), ('equal report no broadcast', (30, 30, 41, 5, 5), {'broadcast': False, 'marker': 30, 'unread': 11}), ('history trimmed below marker', (21, 5, 18, 1, 1), {'broadcast': False, 'marker': 21, 'unread': 0}), ('normal advance', (1, 4, 11, 7, 7), {'broadcast': True, 'marker': 4, 'unread': 7}), ('lower report with zero', (3, 0, 7, 2, 2), {'broadcast': False, 'marker': 3, 'unread': 4})], 2: [('stale session after mark-unread', (20, 25, 28, 3, 4), {'broadcast': False, 'marker': 20, 'unread': 8}), ('session two epochs behind', (20, 27, 29, 1, 3), {'broadcast': False, 'marker': 20, 'unread': 9}), ('report beyond latest', (2, 22, 6, 2, 2), {'broadcast': True, 'marker': 6, 'unread': 0}), ('older report arrives late', (52, 42, 62, 1, 1), {'broadcast': False, 'marker': 52, 'unread': 10}), ('equal report no broadcast', (30, 30, 42, 5, 5), {'broadcast': False, 'marker': 30, 'unread': 12}), ('history trimmed below marker', (22, 5, 18, 1, 1), {'broadcast': False, 'marker': 22, 'unread': 0}), ('normal advance', (2, 5, 12, 7, 7), {'broadcast': True, 'marker': 5, 'unread': 7}), ('lower report with zero', (4, 0, 8, 2, 2), {'broadcast': False, 'marker': 4, 'unread': 4})], 3: [('stale session after mark-unread', (30, 35, 38, 3, 4), {'broadcast': False, 'marker': 30, 'unread': 8}), ('session two epochs behind', (30, 37, 39, 1, 3), {'broadcast': False, 'marker': 30, 'unread': 9}), ('report beyond latest', (3, 23, 7, 2, 2), {'broadcast': True, 'marker': 7, 'unread': 0}), ('older report arrives late', (53, 43, 63, 1, 1), {'broadcast': False, 'marker': 53, 'unread': 10}), ('equal report no broadcast', (30, 30, 43, 5, 5), {'broadcast': False, 'marker': 30, 'unread': 13}), ('history trimmed below marker', (23, 5, 18, 1, 1), {'broadcast': False, 'marker': 23, 'unread': 0}), ('normal advance', (3, 6, 13, 7, 7), {'broadcast': True, 'marker': 6, 'unread': 7}), ('lower report with zero', (5, 0, 9, 2, 2), {'broadcast': False, 'marker': 5, 'unread': 4})], 4: [('stale session after mark-unread', (40, 45, 48, 3, 4), {'broadcast': False, 'marker': 40, 'unread': 8}), ('session two epochs behind', (40, 47, 49, 1, 3), {'broadcast': False, 'marker': 40, 'unread': 9}), ('report beyond latest', (4, 24, 8, 2, 2), {'broadcast': True, 'marker': 8, 'unread': 0}), ('older report arrives late', (54, 44, 64, 1, 1), {'broadcast': False, 'marker': 54, 'unread': 10}), ('equal report no broadcast', (30, 30, 44, 5, 5), {'broadcast': False, 'marker': 30, 'unread': 14}), ('history trimmed below marker', (24, 5, 18, 1, 1), {'broadcast': False, 'marker': 24, 'unread': 0}), ('normal advance', (4, 7, 14, 7, 7), {'broadcast': True, 'marker': 7, 'unread': 7}), ('lower report with zero', (6, 0, 10, 2, 2), {'broadcast': False, 'marker': 6, 'unread': 4})], 5: [('stale session after mark-unread', (50, 55, 58, 3, 4), {'broadcast': False, 'marker': 50, 'unread': 8}), ('session two epochs behind', (50, 57, 59, 1, 3), {'broadcast': False, 'marker': 50, 'unread': 9}), ('report beyond latest', (5, 25, 9, 2, 2), {'broadcast': True, 'marker': 9, 'unread': 0}), ('older report arrives late', (55, 45, 65, 1, 1), {'broadcast': False, 'marker': 55, 'unread': 10}), ('equal report no broadcast', (30, 30, 45, 5, 5), {'broadcast': False, 'marker': 30, 'unread': 15}), ('history trimmed below marker', (25, 5, 18, 1, 1), {'broadcast': False, 'marker': 25, 'unread': 0}), ('normal advance', (5, 8, 15, 7, 7), {'broadcast': True, 'marker': 8, 'unread': 7}), ('lower report with zero', (7, 0, 11, 2, 2), {'broadcast': False, 'marker': 7, 'unread': 4})]}
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| stale session after mark-unread | {'broadcast': False, 'marker': 10, 'unread': 8} | {'broadcast': False, 'marker': 10, 'unread': 8} | Passed |
| session two epochs behind | {'broadcast': False, 'marker': 10, 'unread': 9} | {'broadcast': False, 'marker': 10, 'unread': 9} | Passed |
| report beyond latest | {'broadcast': True, 'marker': 5, 'unread': 0} | {'broadcast': True, 'marker': 5, 'unread': 0} | Passed |
| older report arrives late | {'broadcast': True, 'marker': 41, 'unread': 20} | {'broadcast': False, 'marker': 51, 'unread': 10} | Failed |
| equal report no broadcast | {'broadcast': False, 'marker': 30, 'unread': 11} | {'broadcast': False, 'marker': 30, 'unread': 11} | Passed |
| history trimmed below marker | {'broadcast': True, 'marker': 5, 'unread': 13} | {'broadcast': False, 'marker': 21, 'unread': 0} | Failed |
| normal advance | {'broadcast': True, 'marker': 4, 'unread': 7} | {'broadcast': True, 'marker': 4, 'unread': 7} | Passed |
| lower report with zero | {'broadcast': False, 'marker': 3, 'unread': 4} | {'broadcast': False, 'marker': 3, 'unread': 4} | Passed |
SHA-256 / 5af655299bb5f22f47b40147e87ab6c7c328164448acde111a1d789eba4f1c35
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(marker, report, latest_seq, session_epoch, current_epoch):
if session_epoch != current_epoch:
return {'marker': marker, 'broadcast': False, 'unread': max(0, latest_seq - marker)}
target = min(report, latest_seq)
new = max(marker, target)
return {'marker': new, 'broadcast': new != marker, 'unread': max(0, latest_seq - new)}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('stale session after mark-unread', (10, 15, 18, 3, 4), {'broadcast': False, 'marker': 10, 'unread': 8}), ('session two epochs behind', (10, 17, 19, 1, 3), {'broadcast': False, 'marker': 10, 'unread': 9}), ('report beyond latest', (1, 21, 5, 2, 2), {'broadcast': True, 'marker': 5, 'unread': 0}), ('older report arrives late', (51, 41, 61, 1, 1), {'broadcast': False, 'marker': 51, 'unread': 10}), ('equal report no broadcast', (30, 30, 41, 5, 5), {'broadcast': False, 'marker': 30, 'unread': 11}), ('history trimmed below marker', (21, 5, 18, 1, 1), {'broadcast': False, 'marker': 21, 'unread': 0}), ('normal advance', (1, 4, 11, 7, 7), {'broadcast': True, 'marker': 4, 'unread': 7}), ('lower report with zero', (3, 0, 7, 2, 2), {'broadcast': False, 'marker': 3, 'unread': 4})], 2: [('stale session after mark-unread', (20, 25, 28, 3, 4), {'broadcast': False, 'marker': 20, 'unread': 8}), ('session two epochs behind', (20, 27, 29, 1, 3), {'broadcast': False, 'marker': 20, 'unread': 9}), ('report beyond latest', (2, 22, 6, 2, 2), {'broadcast': True, 'marker': 6, 'unread': 0}), ('older report arrives late', (52, 42, 62, 1, 1), {'broadcast': False, 'marker': 52, 'unread': 10}), ('equal report no broadcast', (30, 30, 42, 5, 5), {'broadcast': False, 'marker': 30, 'unread': 12}), ('history trimmed below marker', (22, 5, 18, 1, 1), {'broadcast': False, 'marker': 22, 'unread': 0}), ('normal advance', (2, 5, 12, 7, 7), {'broadcast': True, 'marker': 5, 'unread': 7}), ('lower report with zero', (4, 0, 8, 2, 2), {'broadcast': False, 'marker': 4, 'unread': 4})], 3: [('stale session after mark-unread', (30, 35, 38, 3, 4), {'broadcast': False, 'marker': 30, 'unread': 8}), ('session two epochs behind', (30, 37, 39, 1, 3), {'broadcast': False, 'marker': 30, 'unread': 9}), ('report beyond latest', (3, 23, 7, 2, 2), {'broadcast': True, 'marker': 7, 'unread': 0}), ('older report arrives late', (53, 43, 63, 1, 1), {'broadcast': False, 'marker': 53, 'unread': 10}), ('equal report no broadcast', (30, 30, 43, 5, 5), {'broadcast': False, 'marker': 30, 'unread': 13}), ('history trimmed below marker', (23, 5, 18, 1, 1), {'broadcast': False, 'marker': 23, 'unread': 0}), ('normal advance', (3, 6, 13, 7, 7), {'broadcast': True, 'marker': 6, 'unread': 7}), ('lower report with zero', (5, 0, 9, 2, 2), {'broadcast': False, 'marker': 5, 'unread': 4})], 4: [('stale session after mark-unread', (40, 45, 48, 3, 4), {'broadcast': False, 'marker': 40, 'unread': 8}), ('session two epochs behind', (40, 47, 49, 1, 3), {'broadcast': False, 'marker': 40, 'unread': 9}), ('report beyond latest', (4, 24, 8, 2, 2), {'broadcast': True, 'marker': 8, 'unread': 0}), ('older report arrives late', (54, 44, 64, 1, 1), {'broadcast': False, 'marker': 54, 'unread': 10}), ('equal report no broadcast', (30, 30, 44, 5, 5), {'broadcast': False, 'marker': 30, 'unread': 14}), ('history trimmed below marker', (24, 5, 18, 1, 1), {'broadcast': False, 'marker': 24, 'unread': 0}), ('normal advance', (4, 7, 14, 7, 7), {'broadcast': True, 'marker': 7, 'unread': 7}), ('lower report with zero', (6, 0, 10, 2, 2), {'broadcast': False, 'marker': 6, 'unread': 4})], 5: [('stale session after mark-unread', (50, 55, 58, 3, 4), {'broadcast': False, 'marker': 50, 'unread': 8}), ('session two epochs behind', (50, 57, 59, 1, 3), {'broadcast': False, 'marker': 50, 'unread': 9}), ('report beyond latest', (5, 25, 9, 2, 2), {'broadcast': True, 'marker': 9, 'unread': 0}), ('older report arrives late', (55, 45, 65, 1, 1), {'broadcast': False, 'marker': 55, 'unread': 10}), ('equal report no broadcast', (30, 30, 45, 5, 5), {'broadcast': False, 'marker': 30, 'unread': 15}), ('history trimmed below marker', (25, 5, 18, 1, 1), {'broadcast': False, 'marker': 25, 'unread': 0}), ('normal advance', (5, 8, 15, 7, 7), {'broadcast': True, 'marker': 8, 'unread': 7}), ('lower report with zero', (7, 0, 11, 2, 2), {'broadcast': False, 'marker': 7, 'unread': 4})]}
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| stale session after mark-unread | {'broadcast': False, 'marker': 10, 'unread': 8} | {'broadcast': False, 'marker': 10, 'unread': 8} | Passed |
| session two epochs behind | {'broadcast': False, 'marker': 10, 'unread': 9} | {'broadcast': False, 'marker': 10, 'unread': 9} | Passed |
| report beyond latest | {'broadcast': True, 'marker': 5, 'unread': 0} | {'broadcast': True, 'marker': 5, 'unread': 0} | Passed |
| older report arrives late | {'broadcast': False, 'marker': 51, 'unread': 10} | {'broadcast': False, 'marker': 51, 'unread': 10} | Passed |
| equal report no broadcast | {'broadcast': False, 'marker': 30, 'unread': 11} | {'broadcast': False, 'marker': 30, 'unread': 11} | Passed |
| history trimmed below marker | {'broadcast': False, 'marker': 21, 'unread': 0} | {'broadcast': False, 'marker': 21, 'unread': 0} | Passed |
| normal advance | {'broadcast': True, 'marker': 4, 'unread': 7} | {'broadcast': True, 'marker': 4, 'unread': 7} | Passed |
| lower report with zero | {'broadcast': False, 'marker': 3, 'unread': 4} | {'broadcast': False, 'marker': 3, 'unread': 4} | Passed |
SHA-256 / dd2d1a000597884213acafaeb41562829e91b9cbf08e39227985d1c7d03a7829
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:10.892994+00:00.
Case digest / 17ccd5a31541564d6baf0ca9cf9e23c4129613a38625699296d67250672e15e4