FAILURE MAP
← Case archive

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

Place the "new messages" divider in a loaded window: older unread boundary · case 01

The "older unread messages" banner appears when the window begins right after the marker, or misses a single unloaded unread.

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

ROOT CAUSE

The older unread boundary decision evaluates `eff < window_start` where the contract requires `eff < window_start - 1`.

VERIFIED REPAIR

Use `eff < window_start - 1` for the older unread boundary decision and keep every other rule of the model unchanged.

Unsuccessful approach: Shifting the comparison the other way misses exactly one unloaded unread message. The attempted `eff + 1 < window_start - 1` still disagrees with a fixture.

Case contract

messages are ascending [seq, author] pairs of the loaded window that starts at window_start. Sending a message implies having read everything before it, so the effective marker is the larger of marker and the highest seq authored by me. The divider goes before the first loaded message after the effective marker not written by me (index, or None). older_unread is true when some unread seq lies before the loaded window (effective marker < window_start - 1).

Why this case matters

The divider tells users where to resume reading; misplacing it hides or repeats unread history.

1 / The failure

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

N = 1
observations = []
def solve(messages, me, marker, window_start):
    eff = marker
    for seq, author in messages:
        if author == me and seq > eff:
            eff = seq
    index = None
    for i, (seq, author) in enumerate(messages):
        if seq > eff and author != me:
            index = i
            break
    return {'index': index, 'older_unread': eff < window_start}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('interleaved own replies', ([[11, 'bo'], [12, 'me'], [13, 'bo'], [14, 'me'], [15, 'cy']], 'me', 10, 11), {'index': 4, 'older_unread': False}), ('window starts right after marker', ([[20, 'bo'], [21, 'bo']], 'me', 19, 20), {'index': 0, 'older_unread': False}), ('one unloaded unread', ([[20, 'bo'], [22, 'bo']], 'me', 18, 20), {'index': 0, 'older_unread': True}), ('all read', ([[5, 'bo'], [6, 'cy']], 'me', 7, 5), {'index': None, 'older_unread': False}), ('only own messages after marker', ([[1, 'bo'], [2, 'me']], 'me', 1, 1), {'index': None, 'older_unread': False}), ('first unread foreign', ([[3, 'bo'], [4, 'cy'], [5, 'dd']], 'me', 3, 3), {'index': 1, 'older_unread': False})], 2: [('interleaved own replies', ([[12, 'bo'], [13, 'me'], [14, 'bo'], [15, 'me'], [16, 'cy']], 'me', 11, 12), {'index': 4, 'older_unread': False}), ('window starts right after marker', ([[20, 'bo'], [21, 'bo']], 'me', 19, 20), {'index': 0, 'older_unread': False}), ('one unloaded unread', ([[20, 'bo'], [23, 'bo']], 'me', 18, 20), {'index': 0, 'older_unread': True}), ('all read', ([[5, 'bo'], [6, 'cy']], 'me', 8, 5), {'index': None, 'older_unread': False}), ('only own messages after marker', ([[1, 'bo'], [2, 'me']], 'me', 1, 1), {'index': None, 'older_unread': False}), ('first unread foreign', ([[3, 'bo'], [4, 'cy'], [5, 'dd']], 'me', 3, 3), {'index': 1, 'older_unread': False})], 3: [('interleaved own replies', ([[13, 'bo'], [14, 'me'], [15, 'bo'], [16, 'me'], [17, 'cy']], 'me', 12, 13), {'index': 4, 'older_unread': False}), ('window starts right after marker', ([[20, 'bo'], [21, 'bo']], 'me', 19, 20), {'index': 0, 'older_unread': False}), ('one unloaded unread', ([[20, 'bo'], [24, 'bo']], 'me', 18, 20), {'index': 0, 'older_unread': True}), ('all read', ([[5, 'bo'], [6, 'cy']], 'me', 9, 5), {'index': None, 'older_unread': False}), ('only own messages after marker', ([[1, 'bo'], [2, 'me']], 'me', 1, 1), {'index': None, 'older_unread': False}), ('first unread foreign', ([[3, 'bo'], [4, 'cy'], [5, 'dd']], 'me', 3, 3), {'index': 1, 'older_unread': False})], 4: [('interleaved own replies', ([[14, 'bo'], [15, 'me'], [16, 'bo'], [17, 'me'], [18, 'cy']], 'me', 13, 14), {'index': 4, 'older_unread': False}), ('window starts right after marker', ([[20, 'bo'], [21, 'bo']], 'me', 19, 20), {'index': 0, 'older_unread': False}), ('one unloaded unread', ([[20, 'bo'], [25, 'bo']], 'me', 18, 20), {'index': 0, 'older_unread': True}), ('all read', ([[5, 'bo'], [6, 'cy']], 'me', 10, 5), {'index': None, 'older_unread': False}), ('only own messages after marker', ([[1, 'bo'], [2, 'me']], 'me', 1, 1), {'index': None, 'older_unread': False}), ('first unread foreign', ([[3, 'bo'], [4, 'cy'], [5, 'dd']], 'me', 3, 3), {'index': 1, 'older_unread': False})], 5: [('interleaved own replies', ([[15, 'bo'], [16, 'me'], [17, 'bo'], [18, 'me'], [19, 'cy']], 'me', 14, 15), {'index': 4, 'older_unread': False}), ('window starts right after marker', ([[20, 'bo'], [21, 'bo']], 'me', 19, 20), {'index': 0, 'older_unread': False}), ('one unloaded unread', ([[20, 'bo'], [26, 'bo']], 'me', 18, 20), {'index': 0, 'older_unread': True}), ('all read', ([[5, 'bo'], [6, 'cy']], 'me', 11, 5), {'index': None, 'older_unread': False}), ('only own messages after marker', ([[1, 'bo'], [2, 'me']], 'me', 1, 1), {'index': None, 'older_unread': False}), ('first unread foreign', ([[3, 'bo'], [4, 'cy'], [5, 'dd']], 'me', 3, 3), {'index': 1, 'older_unread': False})]}
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
interleaved own replies{'index': 4, 'older_unread': False}{'index': 4, 'older_unread': False}Passed
window starts right after marker{'index': 0, 'older_unread': True}{'index': 0, 'older_unread': False}Failed
one unloaded unread{'index': 0, 'older_unread': True}{'index': 0, 'older_unread': True}Passed
all read{'index': None, 'older_unread': False}{'index': None, 'older_unread': False}Passed
only own messages after marker{'index': None, 'older_unread': False}{'index': None, 'older_unread': False}Passed
first unread foreign{'index': 1, 'older_unread': False}{'index': 1, 'older_unread': False}Passed

SHA-256 / e019666bafc1463f4e4c304255397ef6f2f645bae8a7e63411802d71d4a717f5

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(messages, me, marker, window_start):
    eff = marker
    for seq, author in messages:
        if author == me and seq > eff:
            eff = seq
    index = None
    for i, (seq, author) in enumerate(messages):
        if seq > eff and author != me:
            index = i
            break
    return {'index': index, 'older_unread': eff + 1 < window_start - 1}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('interleaved own replies', ([[11, 'bo'], [12, 'me'], [13, 'bo'], [14, 'me'], [15, 'cy']], 'me', 10, 11), {'index': 4, 'older_unread': False}), ('window starts right after marker', ([[20, 'bo'], [21, 'bo']], 'me', 19, 20), {'index': 0, 'older_unread': False}), ('one unloaded unread', ([[20, 'bo'], [22, 'bo']], 'me', 18, 20), {'index': 0, 'older_unread': True}), ('all read', ([[5, 'bo'], [6, 'cy']], 'me', 7, 5), {'index': None, 'older_unread': False}), ('only own messages after marker', ([[1, 'bo'], [2, 'me']], 'me', 1, 1), {'index': None, 'older_unread': False}), ('first unread foreign', ([[3, 'bo'], [4, 'cy'], [5, 'dd']], 'me', 3, 3), {'index': 1, 'older_unread': False})], 2: [('interleaved own replies', ([[12, 'bo'], [13, 'me'], [14, 'bo'], [15, 'me'], [16, 'cy']], 'me', 11, 12), {'index': 4, 'older_unread': False}), ('window starts right after marker', ([[20, 'bo'], [21, 'bo']], 'me', 19, 20), {'index': 0, 'older_unread': False}), ('one unloaded unread', ([[20, 'bo'], [23, 'bo']], 'me', 18, 20), {'index': 0, 'older_unread': True}), ('all read', ([[5, 'bo'], [6, 'cy']], 'me', 8, 5), {'index': None, 'older_unread': False}), ('only own messages after marker', ([[1, 'bo'], [2, 'me']], 'me', 1, 1), {'index': None, 'older_unread': False}), ('first unread foreign', ([[3, 'bo'], [4, 'cy'], [5, 'dd']], 'me', 3, 3), {'index': 1, 'older_unread': False})], 3: [('interleaved own replies', ([[13, 'bo'], [14, 'me'], [15, 'bo'], [16, 'me'], [17, 'cy']], 'me', 12, 13), {'index': 4, 'older_unread': False}), ('window starts right after marker', ([[20, 'bo'], [21, 'bo']], 'me', 19, 20), {'index': 0, 'older_unread': False}), ('one unloaded unread', ([[20, 'bo'], [24, 'bo']], 'me', 18, 20), {'index': 0, 'older_unread': True}), ('all read', ([[5, 'bo'], [6, 'cy']], 'me', 9, 5), {'index': None, 'older_unread': False}), ('only own messages after marker', ([[1, 'bo'], [2, 'me']], 'me', 1, 1), {'index': None, 'older_unread': False}), ('first unread foreign', ([[3, 'bo'], [4, 'cy'], [5, 'dd']], 'me', 3, 3), {'index': 1, 'older_unread': False})], 4: [('interleaved own replies', ([[14, 'bo'], [15, 'me'], [16, 'bo'], [17, 'me'], [18, 'cy']], 'me', 13, 14), {'index': 4, 'older_unread': False}), ('window starts right after marker', ([[20, 'bo'], [21, 'bo']], 'me', 19, 20), {'index': 0, 'older_unread': False}), ('one unloaded unread', ([[20, 'bo'], [25, 'bo']], 'me', 18, 20), {'index': 0, 'older_unread': True}), ('all read', ([[5, 'bo'], [6, 'cy']], 'me', 10, 5), {'index': None, 'older_unread': False}), ('only own messages after marker', ([[1, 'bo'], [2, 'me']], 'me', 1, 1), {'index': None, 'older_unread': False}), ('first unread foreign', ([[3, 'bo'], [4, 'cy'], [5, 'dd']], 'me', 3, 3), {'index': 1, 'older_unread': False})], 5: [('interleaved own replies', ([[15, 'bo'], [16, 'me'], [17, 'bo'], [18, 'me'], [19, 'cy']], 'me', 14, 15), {'index': 4, 'older_unread': False}), ('window starts right after marker', ([[20, 'bo'], [21, 'bo']], 'me', 19, 20), {'index': 0, 'older_unread': False}), ('one unloaded unread', ([[20, 'bo'], [26, 'bo']], 'me', 18, 20), {'index': 0, 'older_unread': True}), ('all read', ([[5, 'bo'], [6, 'cy']], 'me', 11, 5), {'index': None, 'older_unread': False}), ('only own messages after marker', ([[1, 'bo'], [2, 'me']], 'me', 1, 1), {'index': None, 'older_unread': False}), ('first unread foreign', ([[3, 'bo'], [4, 'cy'], [5, 'dd']], 'me', 3, 3), {'index': 1, 'older_unread': False})]}
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
interleaved own replies{'index': 4, 'older_unread': False}{'index': 4, 'older_unread': False}Passed
window starts right after marker{'index': 0, 'older_unread': False}{'index': 0, 'older_unread': False}Passed
one unloaded unread{'index': 0, 'older_unread': False}{'index': 0, 'older_unread': True}Failed
all read{'index': None, 'older_unread': False}{'index': None, 'older_unread': False}Passed
only own messages after marker{'index': None, 'older_unread': False}{'index': None, 'older_unread': False}Passed
first unread foreign{'index': 1, 'older_unread': False}{'index': 1, 'older_unread': False}Passed

SHA-256 / d91c86ce31b5e627d5839fb33ff073eb183524d7c26162aac568ff0e6b1ce6bf

3 / The verified repair

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

N = 1
observations = []
def solve(messages, me, marker, window_start):
    eff = marker
    for seq, author in messages:
        if author == me and seq > eff:
            eff = seq
    index = None
    for i, (seq, author) in enumerate(messages):
        if seq > eff and author != me:
            index = i
            break
    return {'index': index, 'older_unread': eff < window_start - 1}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('interleaved own replies', ([[11, 'bo'], [12, 'me'], [13, 'bo'], [14, 'me'], [15, 'cy']], 'me', 10, 11), {'index': 4, 'older_unread': False}), ('window starts right after marker', ([[20, 'bo'], [21, 'bo']], 'me', 19, 20), {'index': 0, 'older_unread': False}), ('one unloaded unread', ([[20, 'bo'], [22, 'bo']], 'me', 18, 20), {'index': 0, 'older_unread': True}), ('all read', ([[5, 'bo'], [6, 'cy']], 'me', 7, 5), {'index': None, 'older_unread': False}), ('only own messages after marker', ([[1, 'bo'], [2, 'me']], 'me', 1, 1), {'index': None, 'older_unread': False}), ('first unread foreign', ([[3, 'bo'], [4, 'cy'], [5, 'dd']], 'me', 3, 3), {'index': 1, 'older_unread': False})], 2: [('interleaved own replies', ([[12, 'bo'], [13, 'me'], [14, 'bo'], [15, 'me'], [16, 'cy']], 'me', 11, 12), {'index': 4, 'older_unread': False}), ('window starts right after marker', ([[20, 'bo'], [21, 'bo']], 'me', 19, 20), {'index': 0, 'older_unread': False}), ('one unloaded unread', ([[20, 'bo'], [23, 'bo']], 'me', 18, 20), {'index': 0, 'older_unread': True}), ('all read', ([[5, 'bo'], [6, 'cy']], 'me', 8, 5), {'index': None, 'older_unread': False}), ('only own messages after marker', ([[1, 'bo'], [2, 'me']], 'me', 1, 1), {'index': None, 'older_unread': False}), ('first unread foreign', ([[3, 'bo'], [4, 'cy'], [5, 'dd']], 'me', 3, 3), {'index': 1, 'older_unread': False})], 3: [('interleaved own replies', ([[13, 'bo'], [14, 'me'], [15, 'bo'], [16, 'me'], [17, 'cy']], 'me', 12, 13), {'index': 4, 'older_unread': False}), ('window starts right after marker', ([[20, 'bo'], [21, 'bo']], 'me', 19, 20), {'index': 0, 'older_unread': False}), ('one unloaded unread', ([[20, 'bo'], [24, 'bo']], 'me', 18, 20), {'index': 0, 'older_unread': True}), ('all read', ([[5, 'bo'], [6, 'cy']], 'me', 9, 5), {'index': None, 'older_unread': False}), ('only own messages after marker', ([[1, 'bo'], [2, 'me']], 'me', 1, 1), {'index': None, 'older_unread': False}), ('first unread foreign', ([[3, 'bo'], [4, 'cy'], [5, 'dd']], 'me', 3, 3), {'index': 1, 'older_unread': False})], 4: [('interleaved own replies', ([[14, 'bo'], [15, 'me'], [16, 'bo'], [17, 'me'], [18, 'cy']], 'me', 13, 14), {'index': 4, 'older_unread': False}), ('window starts right after marker', ([[20, 'bo'], [21, 'bo']], 'me', 19, 20), {'index': 0, 'older_unread': False}), ('one unloaded unread', ([[20, 'bo'], [25, 'bo']], 'me', 18, 20), {'index': 0, 'older_unread': True}), ('all read', ([[5, 'bo'], [6, 'cy']], 'me', 10, 5), {'index': None, 'older_unread': False}), ('only own messages after marker', ([[1, 'bo'], [2, 'me']], 'me', 1, 1), {'index': None, 'older_unread': False}), ('first unread foreign', ([[3, 'bo'], [4, 'cy'], [5, 'dd']], 'me', 3, 3), {'index': 1, 'older_unread': False})], 5: [('interleaved own replies', ([[15, 'bo'], [16, 'me'], [17, 'bo'], [18, 'me'], [19, 'cy']], 'me', 14, 15), {'index': 4, 'older_unread': False}), ('window starts right after marker', ([[20, 'bo'], [21, 'bo']], 'me', 19, 20), {'index': 0, 'older_unread': False}), ('one unloaded unread', ([[20, 'bo'], [26, 'bo']], 'me', 18, 20), {'index': 0, 'older_unread': True}), ('all read', ([[5, 'bo'], [6, 'cy']], 'me', 11, 5), {'index': None, 'older_unread': False}), ('only own messages after marker', ([[1, 'bo'], [2, 'me']], 'me', 1, 1), {'index': None, 'older_unread': False}), ('first unread foreign', ([[3, 'bo'], [4, 'cy'], [5, 'dd']], 'me', 3, 3), {'index': 1, 'older_unread': False})]}
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
interleaved own replies{'index': 4, 'older_unread': False}{'index': 4, 'older_unread': False}Passed
window starts right after marker{'index': 0, 'older_unread': False}{'index': 0, 'older_unread': False}Passed
one unloaded unread{'index': 0, 'older_unread': True}{'index': 0, 'older_unread': True}Passed
all read{'index': None, 'older_unread': False}{'index': None, 'older_unread': False}Passed
only own messages after marker{'index': None, 'older_unread': False}{'index': None, 'older_unread': False}Passed
first unread foreign{'index': 1, 'older_unread': False}{'index': 1, 'older_unread': False}Passed

SHA-256 / b96673fbbd3711b5170fb321e0f037bff2e88667ddcad455b30f91e43de39784

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

Case digest / deb294dd4720339793848c2f6d876ba597b9ad592a15723742793768ec99ec74