FAILURE MAP
← Case archive

FA-75181 / CRDT convergence / Open access

Visible index translation: negative delete indices wrap to the end · case 01

A delete at index minus one silently removes the last visible character.

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

ROOT CAUSE

The delete bound checks only the upper end, so Python negative indexing selects elements from the end.

THE FAILURE

The delete bound checks only the upper end, so Python negative indexing selects elements from the end.

Unsuccessful approach: Allowing indices down to minus the length accepts every Pythonic negative index instead of rejecting it.

Case contract

A sequence CRDT holds [id, char, deleted]. Local edits use visible indices: ["insert", i, ch] (0 <= i <= visible length) references the visible element at i-1 (None at 0), is placed immediately after it, and gets id "L<k>" from a counter advanced only by accepted inserts; ["delete", i] (0 <= i < visible length) tombstones the visible element at i. Out-of-range edits yield ["reject", i]. Return the emitted ops and visible text.

Why this case matters

Editors translate cursor positions into identifier-based CRDT operations; tombstones make that translation error-prone.

1 / The failure

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

N = 1
observations = []
def solve(elements, edits):
    seq = [list(e) for e in elements]
    out = []
    k = 0
    for ed in edits:
        vis = [i for i, e in enumerate(seq) if not e[2]]
        idx = ed[1]
        if ed[0] == 'insert':
            if idx < 0 or idx > len(vis):
                out.append(['reject', idx])
                continue
            if idx == 0:
                after, pos = None, 0
            else:
                p = vis[idx - 1]
                after, pos = seq[p][0], p + 1
            k += 1
            nid = 'L%d' % k
            seq.insert(pos, [nid, ed[2], False])
            out.append(['ins', nid, after])
        else:
            if idx >= len(vis):
                out.append(['reject', idx])
                continue
            p = vis[idx]
            seq[p][2] = True
            out.append(['del', seq[p][0]])
    return {'ops': out, 'text': ''.join(e[1] for e in seq if not e[2])}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = {
    1: [('insert after tombstones uses the visible neighbour', [[['e0', 'a', False], ['e1', 'b', True], ['e2', 'c', True], ['e3', 'd', False], ['e4', 'e', False]], [['insert', 2, 'X']]], {'ops': [['ins', 'L1', 'e3']], 'text': 'adXe'}), ('insert at the visible end', [[['e0', 'a', False], ['e1', 'b', False], ['e2', 'c', True]], [['insert', 2, 'Z'], ['insert', 3, 'W']]], {'ops': [['ins', 'L1', 'e1'], ['ins', 'L2', 'L1']], 'text': 'abZW'}), ('insert at the start', [[['e0', 'a', True], ['e1', 'b', False], ['e2', 'c', False]], [['insert', 0, 'S']]], {'ops': [['ins', 'L1', None]], 'text': 'Sbc'}), ('delete by visible index', [[['e0', 'a', True], ['e1', 'b', False], ['e2', 'c', False], ['e3', 'd', True], ['e4', 'e', False], ['e5', 'f', False]], [['delete', 0], ['delete', 2]]], {'ops': [['del', 'e1'], ['del', 'e5']], 'text': 'ce'}), ('delete last visible character', [[['e0', 'a', False], ['e1', 'b', False], ['e2', 'c', False], ['e3', 'd', True]], [['delete', 2]]], {'ops': [['del', 'e2']], 'text': 'ab'}), ('out-of-range edits are rejected', [[['e0', 'a', False], ['e1', 'b', False]], [['insert', 4, 'q'], ['delete', 2], ['delete', -1], ['insert', -1, 'r'], ['insert', 1, 'k']]], {'ops': [['reject', 4], ['reject', 2], ['reject', -1], ['reject', -1], ['ins', 'L1', 'e0']], 'text': 'akb'}), ('ids stay dense after a rejection', [[['e0', 'x', False], ['e1', 'y', False]], [['insert', 5, 'p'], ['insert', 1, 'm'], ['insert', 0, 'n']]], {'ops': [['reject', 5], ['ins', 'L1', 'e0'], ['ins', 'L2', None]], 'text': 'nxmy'}), ('typing into an empty document', [[], [['insert', 0, 'h'], ['insert', 1, 'i'], ['insert', 2, '!']]], {'ops': [['ins', 'L1', None], ['ins', 'L2', 'L1'], ['ins', 'L3', 'L2']], 'text': 'hi!'}), ('mixed edits', [[['e0', 'h', False], ['e1', 'e', True], ['e2', 'l', False], ['e3', 'l', False], ['e4', 'o', False]], [['delete', 1], ['insert', 1, 'E'], ['insert', 4, '?']]], {'ops': [['del', 'e2'], ['ins', 'L1', 'e0'], ['ins', 'L2', 'e4']], 'text': 'hElo?'})],
    2: [('insert after tombstones uses the visible neighbour', [[['e0', 'a', False], ['e1', 'b', True], ['e2', 'c', True], ['e3', 'd', False], ['e4', 'e', False]], [['insert', 2, 'X']]], {'ops': [['ins', 'L1', 'e3']], 'text': 'adXe'}), ('insert at the visible end', [[['e0', 'a', False], ['e1', 'b', False], ['e2', 'c', True]], [['insert', 2, 'Z'], ['insert', 3, 'W']]], {'ops': [['ins', 'L1', 'e1'], ['ins', 'L2', 'L1']], 'text': 'abZW'}), ('insert at the start', [[['e0', 'a', True], ['e1', 'b', False], ['e2', 'c', False]], [['insert', 0, 'S']]], {'ops': [['ins', 'L1', None]], 'text': 'Sbc'}), ('delete by visible index', [[['e0', 'a', True], ['e1', 'b', False], ['e2', 'c', False], ['e3', 'd', True], ['e4', 'e', False], ['e5', 'f', False]], [['delete', 0], ['delete', 2]]], {'ops': [['del', 'e1'], ['del', 'e5']], 'text': 'ce'}), ('delete last visible character', [[['e0', 'a', False], ['e1', 'b', False], ['e2', 'c', False], ['e3', 'd', True]], [['delete', 2]]], {'ops': [['del', 'e2']], 'text': 'ab'}), ('out-of-range edits are rejected', [[['e0', 'a', False], ['e1', 'b', False]], [['insert', 5, 'q'], ['delete', 2], ['delete', -1], ['insert', -1, 'r'], ['insert', 1, 'k']]], {'ops': [['reject', 5], ['reject', 2], ['reject', -1], ['reject', -1], ['ins', 'L1', 'e0']], 'text': 'akb'}), ('ids stay dense after a rejection', [[['e0', 'x', False], ['e1', 'y', False]], [['insert', 5, 'p'], ['insert', 1, 'm'], ['insert', 0, 'n']]], {'ops': [['reject', 5], ['ins', 'L1', 'e0'], ['ins', 'L2', None]], 'text': 'nxmy'}), ('typing into an empty document', [[], [['insert', 0, 'h'], ['insert', 1, 'i'], ['insert', 2, '!'], ['insert', 3, '!']]], {'ops': [['ins', 'L1', None], ['ins', 'L2', 'L1'], ['ins', 'L3', 'L2'], ['ins', 'L4', 'L3']], 'text': 'hi!!'}), ('mixed edits', [[['e0', 'h', False], ['e1', 'e', True], ['e2', 'l', False], ['e3', 'l', False], ['e4', 'o', False]], [['delete', 1], ['insert', 1, 'E'], ['insert', 4, '?']]], {'ops': [['del', 'e2'], ['ins', 'L1', 'e0'], ['ins', 'L2', 'e4']], 'text': 'hElo?'})],
    3: [('insert after tombstones uses the visible neighbour', [[['e0', 'a', False], ['e1', 'b', True], ['e2', 'c', True], ['e3', 'd', False], ['e4', 'e', False]], [['insert', 2, 'X']]], {'ops': [['ins', 'L1', 'e3']], 'text': 'adXe'}), ('insert at the visible end', [[['e0', 'a', False], ['e1', 'b', False], ['e2', 'c', True]], [['insert', 2, 'Z'], ['insert', 3, 'W']]], {'ops': [['ins', 'L1', 'e1'], ['ins', 'L2', 'L1']], 'text': 'abZW'}), ('insert at the start', [[['e0', 'a', True], ['e1', 'b', False], ['e2', 'c', False]], [['insert', 0, 'S']]], {'ops': [['ins', 'L1', None]], 'text': 'Sbc'}), ('delete by visible index', [[['e0', 'a', True], ['e1', 'b', False], ['e2', 'c', False], ['e3', 'd', True], ['e4', 'e', False], ['e5', 'f', False]], [['delete', 0], ['delete', 2]]], {'ops': [['del', 'e1'], ['del', 'e5']], 'text': 'ce'}), ('delete last visible character', [[['e0', 'a', False], ['e1', 'b', False], ['e2', 'c', False], ['e3', 'd', True]], [['delete', 2]]], {'ops': [['del', 'e2']], 'text': 'ab'}), ('out-of-range edits are rejected', [[['e0', 'a', False], ['e1', 'b', False]], [['insert', 6, 'q'], ['delete', 2], ['delete', -1], ['insert', -1, 'r'], ['insert', 1, 'k']]], {'ops': [['reject', 6], ['reject', 2], ['reject', -1], ['reject', -1], ['ins', 'L1', 'e0']], 'text': 'akb'}), ('ids stay dense after a rejection', [[['e0', 'x', False], ['e1', 'y', False]], [['insert', 5, 'p'], ['insert', 1, 'm'], ['insert', 0, 'n']]], {'ops': [['reject', 5], ['ins', 'L1', 'e0'], ['ins', 'L2', None]], 'text': 'nxmy'}), ('typing into an empty document', [[], [['insert', 0, 'h'], ['insert', 1, 'i'], ['insert', 2, '!'], ['insert', 3, '!'], ['insert', 4, '!']]], {'ops': [['ins', 'L1', None], ['ins', 'L2', 'L1'], ['ins', 'L3', 'L2'], ['ins', 'L4', 'L3'], ['ins', 'L5', 'L4']], 'text': 'hi!!!'}), ('mixed edits', [[['e0', 'h', False], ['e1', 'e', True], ['e2', 'l', False], ['e3', 'l', False], ['e4', 'o', False]], [['delete', 1], ['insert', 1, 'E'], ['insert', 4, '?']]], {'ops': [['del', 'e2'], ['ins', 'L1', 'e0'], ['ins', 'L2', 'e4']], 'text': 'hElo?'})],
    4: [('insert after tombstones uses the visible neighbour', [[['e0', 'a', False], ['e1', 'b', True], ['e2', 'c', True], ['e3', 'd', False], ['e4', 'e', False]], [['insert', 2, 'X']]], {'ops': [['ins', 'L1', 'e3']], 'text': 'adXe'}), ('insert at the visible end', [[['e0', 'a', False], ['e1', 'b', False], ['e2', 'c', True]], [['insert', 2, 'Z'], ['insert', 3, 'W']]], {'ops': [['ins', 'L1', 'e1'], ['ins', 'L2', 'L1']], 'text': 'abZW'}), ('insert at the start', [[['e0', 'a', True], ['e1', 'b', False], ['e2', 'c', False]], [['insert', 0, 'S']]], {'ops': [['ins', 'L1', None]], 'text': 'Sbc'}), ('delete by visible index', [[['e0', 'a', True], ['e1', 'b', False], ['e2', 'c', False], ['e3', 'd', True], ['e4', 'e', False], ['e5', 'f', False]], [['delete', 0], ['delete', 2]]], {'ops': [['del', 'e1'], ['del', 'e5']], 'text': 'ce'}), ('delete last visible character', [[['e0', 'a', False], ['e1', 'b', False], ['e2', 'c', False], ['e3', 'd', True]], [['delete', 2]]], {'ops': [['del', 'e2']], 'text': 'ab'}), ('out-of-range edits are rejected', [[['e0', 'a', False], ['e1', 'b', False]], [['insert', 7, 'q'], ['delete', 2], ['delete', -1], ['insert', -1, 'r'], ['insert', 1, 'k']]], {'ops': [['reject', 7], ['reject', 2], ['reject', -1], ['reject', -1], ['ins', 'L1', 'e0']], 'text': 'akb'}), ('ids stay dense after a rejection', [[['e0', 'x', False], ['e1', 'y', False]], [['insert', 5, 'p'], ['insert', 1, 'm'], ['insert', 0, 'n']]], {'ops': [['reject', 5], ['ins', 'L1', 'e0'], ['ins', 'L2', None]], 'text': 'nxmy'}), ('typing into an empty document', [[], [['insert', 0, 'h'], ['insert', 1, 'i'], ['insert', 2, '!'], ['insert', 3, '!'], ['insert', 4, '!'], ['insert', 5, '!']]], {'ops': [['ins', 'L1', None], ['ins', 'L2', 'L1'], ['ins', 'L3', 'L2'], ['ins', 'L4', 'L3'], ['ins', 'L5', 'L4'], ['ins', 'L6', 'L5']], 'text': 'hi!!!!'}), ('mixed edits', [[['e0', 'h', False], ['e1', 'e', True], ['e2', 'l', False], ['e3', 'l', False], ['e4', 'o', False]], [['delete', 1], ['insert', 1, 'E'], ['insert', 4, '?']]], {'ops': [['del', 'e2'], ['ins', 'L1', 'e0'], ['ins', 'L2', 'e4']], 'text': 'hElo?'})],
    5: [('insert after tombstones uses the visible neighbour', [[['e0', 'a', False], ['e1', 'b', True], ['e2', 'c', True], ['e3', 'd', False], ['e4', 'e', False]], [['insert', 2, 'X']]], {'ops': [['ins', 'L1', 'e3']], 'text': 'adXe'}), ('insert at the visible end', [[['e0', 'a', False], ['e1', 'b', False], ['e2', 'c', True]], [['insert', 2, 'Z'], ['insert', 3, 'W']]], {'ops': [['ins', 'L1', 'e1'], ['ins', 'L2', 'L1']], 'text': 'abZW'}), ('insert at the start', [[['e0', 'a', True], ['e1', 'b', False], ['e2', 'c', False]], [['insert', 0, 'S']]], {'ops': [['ins', 'L1', None]], 'text': 'Sbc'}), ('delete by visible index', [[['e0', 'a', True], ['e1', 'b', False], ['e2', 'c', False], ['e3', 'd', True], ['e4', 'e', False], ['e5', 'f', False]], [['delete', 0], ['delete', 2]]], {'ops': [['del', 'e1'], ['del', 'e5']], 'text': 'ce'}), ('delete last visible character', [[['e0', 'a', False], ['e1', 'b', False], ['e2', 'c', False], ['e3', 'd', True]], [['delete', 2]]], {'ops': [['del', 'e2']], 'text': 'ab'}), ('out-of-range edits are rejected', [[['e0', 'a', False], ['e1', 'b', False]], [['insert', 8, 'q'], ['delete', 2], ['delete', -1], ['insert', -1, 'r'], ['insert', 1, 'k']]], {'ops': [['reject', 8], ['reject', 2], ['reject', -1], ['reject', -1], ['ins', 'L1', 'e0']], 'text': 'akb'}), ('ids stay dense after a rejection', [[['e0', 'x', False], ['e1', 'y', False]], [['insert', 5, 'p'], ['insert', 1, 'm'], ['insert', 0, 'n']]], {'ops': [['reject', 5], ['ins', 'L1', 'e0'], ['ins', 'L2', None]], 'text': 'nxmy'}), ('typing into an empty document', [[], [['insert', 0, 'h'], ['insert', 1, 'i'], ['insert', 2, '!'], ['insert', 3, '!'], ['insert', 4, '!'], ['insert', 5, '!'], ['insert', 6, '!']]], {'ops': [['ins', 'L1', None], ['ins', 'L2', 'L1'], ['ins', 'L3', 'L2'], ['ins', 'L4', 'L3'], ['ins', 'L5', 'L4'], ['ins', 'L6', 'L5'], ['ins', 'L7', 'L6']], 'text': 'hi!!!!!'}), ('mixed edits', [[['e0', 'h', False], ['e1', 'e', True], ['e2', 'l', False], ['e3', 'l', False], ['e4', 'o', False]], [['delete', 1], ['insert', 1, 'E'], ['insert', 4, '?']]], {'ops': [['del', 'e2'], ['ins', 'L1', 'e0'], ['ins', 'L2', 'e4']], 'text': 'hElo?'})],
}[N]
for label, args, expected in cases:
    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
insert after tombstones uses the visible neighbour{'ops': [['ins', 'L1', 'e3']], 'text': 'adXe'}{'ops': [['ins', 'L1', 'e3']], 'text': 'adXe'}Passed
insert at the visible end{'ops': [['ins', 'L1', 'e1'], ['ins', 'L2', 'L1']], 'text': 'abZW'}{'ops': [['ins', 'L1', 'e1'], ['ins', 'L2', 'L1']], 'text': 'abZW'}Passed
insert at the start{'ops': [['ins', 'L1', None]], 'text': 'Sbc'}{'ops': [['ins', 'L1', None]], 'text': 'Sbc'}Passed
delete by visible index{'ops': [['del', 'e1'], ['del', 'e5']], 'text': 'ce'}{'ops': [['del', 'e1'], ['del', 'e5']], 'text': 'ce'}Passed
delete last visible character{'ops': [['del', 'e2']], 'text': 'ab'}{'ops': [['del', 'e2']], 'text': 'ab'}Passed
out-of-range edits are rejected{'ops': [['reject', 4], ['reject', 2], ['del', 'e1'], ['reject', -1], ['ins', 'L1', 'e0']], 'text': 'ak'}{'ops': [['reject', 4], ['reject', 2], ['reject', -1], ['reject', -1], ['ins', 'L1', 'e0']], 'text': 'akb'}Failed
ids stay dense after a rejection{'ops': [['reject', 5], ['ins', 'L1', 'e0'], ['ins', 'L2', None]], 'text': 'nxmy'}{'ops': [['reject', 5], ['ins', 'L1', 'e0'], ['ins', 'L2', None]], 'text': 'nxmy'}Passed
typing into an empty document{'ops': [['ins', 'L1', None], ['ins', 'L2', 'L1'], ['ins', 'L3', 'L2']], 'text': 'hi!'}{'ops': [['ins', 'L1', None], ['ins', 'L2', 'L1'], ['ins', 'L3', 'L2']], 'text': 'hi!'}Passed
mixed edits{'ops': [['del', 'e2'], ['ins', 'L1', 'e0'], ['ins', 'L2', 'e4']], 'text': 'hElo?'}{'ops': [['del', 'e2'], ['ins', 'L1', 'e0'], ['ins', 'L2', 'e4']], 'text': 'hElo?'}Passed

SHA-256 / ed8c085f2dbbf3e910a52502095a24e61043005ca4a13225c4eba26fdaa2d8e2

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(elements, edits):
    seq = [list(e) for e in elements]
    out = []
    k = 0
    for ed in edits:
        vis = [i for i, e in enumerate(seq) if not e[2]]
        idx = ed[1]
        if ed[0] == 'insert':
            if idx < 0 or idx > len(vis):
                out.append(['reject', idx])
                continue
            if idx == 0:
                after, pos = None, 0
            else:
                p = vis[idx - 1]
                after, pos = seq[p][0], p + 1
            k += 1
            nid = 'L%d' % k
            seq.insert(pos, [nid, ed[2], False])
            out.append(['ins', nid, after])
        else:
            if idx < -len(vis) or idx >= len(vis):
                out.append(['reject', idx])
                continue
            p = vis[idx]
            seq[p][2] = True
            out.append(['del', seq[p][0]])
    return {'ops': out, 'text': ''.join(e[1] for e in seq if not e[2])}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = {
    1: [('insert after tombstones uses the visible neighbour', [[['e0', 'a', False], ['e1', 'b', True], ['e2', 'c', True], ['e3', 'd', False], ['e4', 'e', False]], [['insert', 2, 'X']]], {'ops': [['ins', 'L1', 'e3']], 'text': 'adXe'}), ('insert at the visible end', [[['e0', 'a', False], ['e1', 'b', False], ['e2', 'c', True]], [['insert', 2, 'Z'], ['insert', 3, 'W']]], {'ops': [['ins', 'L1', 'e1'], ['ins', 'L2', 'L1']], 'text': 'abZW'}), ('insert at the start', [[['e0', 'a', True], ['e1', 'b', False], ['e2', 'c', False]], [['insert', 0, 'S']]], {'ops': [['ins', 'L1', None]], 'text': 'Sbc'}), ('delete by visible index', [[['e0', 'a', True], ['e1', 'b', False], ['e2', 'c', False], ['e3', 'd', True], ['e4', 'e', False], ['e5', 'f', False]], [['delete', 0], ['delete', 2]]], {'ops': [['del', 'e1'], ['del', 'e5']], 'text': 'ce'}), ('delete last visible character', [[['e0', 'a', False], ['e1', 'b', False], ['e2', 'c', False], ['e3', 'd', True]], [['delete', 2]]], {'ops': [['del', 'e2']], 'text': 'ab'}), ('out-of-range edits are rejected', [[['e0', 'a', False], ['e1', 'b', False]], [['insert', 4, 'q'], ['delete', 2], ['delete', -1], ['insert', -1, 'r'], ['insert', 1, 'k']]], {'ops': [['reject', 4], ['reject', 2], ['reject', -1], ['reject', -1], ['ins', 'L1', 'e0']], 'text': 'akb'}), ('ids stay dense after a rejection', [[['e0', 'x', False], ['e1', 'y', False]], [['insert', 5, 'p'], ['insert', 1, 'm'], ['insert', 0, 'n']]], {'ops': [['reject', 5], ['ins', 'L1', 'e0'], ['ins', 'L2', None]], 'text': 'nxmy'}), ('typing into an empty document', [[], [['insert', 0, 'h'], ['insert', 1, 'i'], ['insert', 2, '!']]], {'ops': [['ins', 'L1', None], ['ins', 'L2', 'L1'], ['ins', 'L3', 'L2']], 'text': 'hi!'}), ('mixed edits', [[['e0', 'h', False], ['e1', 'e', True], ['e2', 'l', False], ['e3', 'l', False], ['e4', 'o', False]], [['delete', 1], ['insert', 1, 'E'], ['insert', 4, '?']]], {'ops': [['del', 'e2'], ['ins', 'L1', 'e0'], ['ins', 'L2', 'e4']], 'text': 'hElo?'})],
    2: [('insert after tombstones uses the visible neighbour', [[['e0', 'a', False], ['e1', 'b', True], ['e2', 'c', True], ['e3', 'd', False], ['e4', 'e', False]], [['insert', 2, 'X']]], {'ops': [['ins', 'L1', 'e3']], 'text': 'adXe'}), ('insert at the visible end', [[['e0', 'a', False], ['e1', 'b', False], ['e2', 'c', True]], [['insert', 2, 'Z'], ['insert', 3, 'W']]], {'ops': [['ins', 'L1', 'e1'], ['ins', 'L2', 'L1']], 'text': 'abZW'}), ('insert at the start', [[['e0', 'a', True], ['e1', 'b', False], ['e2', 'c', False]], [['insert', 0, 'S']]], {'ops': [['ins', 'L1', None]], 'text': 'Sbc'}), ('delete by visible index', [[['e0', 'a', True], ['e1', 'b', False], ['e2', 'c', False], ['e3', 'd', True], ['e4', 'e', False], ['e5', 'f', False]], [['delete', 0], ['delete', 2]]], {'ops': [['del', 'e1'], ['del', 'e5']], 'text': 'ce'}), ('delete last visible character', [[['e0', 'a', False], ['e1', 'b', False], ['e2', 'c', False], ['e3', 'd', True]], [['delete', 2]]], {'ops': [['del', 'e2']], 'text': 'ab'}), ('out-of-range edits are rejected', [[['e0', 'a', False], ['e1', 'b', False]], [['insert', 5, 'q'], ['delete', 2], ['delete', -1], ['insert', -1, 'r'], ['insert', 1, 'k']]], {'ops': [['reject', 5], ['reject', 2], ['reject', -1], ['reject', -1], ['ins', 'L1', 'e0']], 'text': 'akb'}), ('ids stay dense after a rejection', [[['e0', 'x', False], ['e1', 'y', False]], [['insert', 5, 'p'], ['insert', 1, 'm'], ['insert', 0, 'n']]], {'ops': [['reject', 5], ['ins', 'L1', 'e0'], ['ins', 'L2', None]], 'text': 'nxmy'}), ('typing into an empty document', [[], [['insert', 0, 'h'], ['insert', 1, 'i'], ['insert', 2, '!'], ['insert', 3, '!']]], {'ops': [['ins', 'L1', None], ['ins', 'L2', 'L1'], ['ins', 'L3', 'L2'], ['ins', 'L4', 'L3']], 'text': 'hi!!'}), ('mixed edits', [[['e0', 'h', False], ['e1', 'e', True], ['e2', 'l', False], ['e3', 'l', False], ['e4', 'o', False]], [['delete', 1], ['insert', 1, 'E'], ['insert', 4, '?']]], {'ops': [['del', 'e2'], ['ins', 'L1', 'e0'], ['ins', 'L2', 'e4']], 'text': 'hElo?'})],
    3: [('insert after tombstones uses the visible neighbour', [[['e0', 'a', False], ['e1', 'b', True], ['e2', 'c', True], ['e3', 'd', False], ['e4', 'e', False]], [['insert', 2, 'X']]], {'ops': [['ins', 'L1', 'e3']], 'text': 'adXe'}), ('insert at the visible end', [[['e0', 'a', False], ['e1', 'b', False], ['e2', 'c', True]], [['insert', 2, 'Z'], ['insert', 3, 'W']]], {'ops': [['ins', 'L1', 'e1'], ['ins', 'L2', 'L1']], 'text': 'abZW'}), ('insert at the start', [[['e0', 'a', True], ['e1', 'b', False], ['e2', 'c', False]], [['insert', 0, 'S']]], {'ops': [['ins', 'L1', None]], 'text': 'Sbc'}), ('delete by visible index', [[['e0', 'a', True], ['e1', 'b', False], ['e2', 'c', False], ['e3', 'd', True], ['e4', 'e', False], ['e5', 'f', False]], [['delete', 0], ['delete', 2]]], {'ops': [['del', 'e1'], ['del', 'e5']], 'text': 'ce'}), ('delete last visible character', [[['e0', 'a', False], ['e1', 'b', False], ['e2', 'c', False], ['e3', 'd', True]], [['delete', 2]]], {'ops': [['del', 'e2']], 'text': 'ab'}), ('out-of-range edits are rejected', [[['e0', 'a', False], ['e1', 'b', False]], [['insert', 6, 'q'], ['delete', 2], ['delete', -1], ['insert', -1, 'r'], ['insert', 1, 'k']]], {'ops': [['reject', 6], ['reject', 2], ['reject', -1], ['reject', -1], ['ins', 'L1', 'e0']], 'text': 'akb'}), ('ids stay dense after a rejection', [[['e0', 'x', False], ['e1', 'y', False]], [['insert', 5, 'p'], ['insert', 1, 'm'], ['insert', 0, 'n']]], {'ops': [['reject', 5], ['ins', 'L1', 'e0'], ['ins', 'L2', None]], 'text': 'nxmy'}), ('typing into an empty document', [[], [['insert', 0, 'h'], ['insert', 1, 'i'], ['insert', 2, '!'], ['insert', 3, '!'], ['insert', 4, '!']]], {'ops': [['ins', 'L1', None], ['ins', 'L2', 'L1'], ['ins', 'L3', 'L2'], ['ins', 'L4', 'L3'], ['ins', 'L5', 'L4']], 'text': 'hi!!!'}), ('mixed edits', [[['e0', 'h', False], ['e1', 'e', True], ['e2', 'l', False], ['e3', 'l', False], ['e4', 'o', False]], [['delete', 1], ['insert', 1, 'E'], ['insert', 4, '?']]], {'ops': [['del', 'e2'], ['ins', 'L1', 'e0'], ['ins', 'L2', 'e4']], 'text': 'hElo?'})],
    4: [('insert after tombstones uses the visible neighbour', [[['e0', 'a', False], ['e1', 'b', True], ['e2', 'c', True], ['e3', 'd', False], ['e4', 'e', False]], [['insert', 2, 'X']]], {'ops': [['ins', 'L1', 'e3']], 'text': 'adXe'}), ('insert at the visible end', [[['e0', 'a', False], ['e1', 'b', False], ['e2', 'c', True]], [['insert', 2, 'Z'], ['insert', 3, 'W']]], {'ops': [['ins', 'L1', 'e1'], ['ins', 'L2', 'L1']], 'text': 'abZW'}), ('insert at the start', [[['e0', 'a', True], ['e1', 'b', False], ['e2', 'c', False]], [['insert', 0, 'S']]], {'ops': [['ins', 'L1', None]], 'text': 'Sbc'}), ('delete by visible index', [[['e0', 'a', True], ['e1', 'b', False], ['e2', 'c', False], ['e3', 'd', True], ['e4', 'e', False], ['e5', 'f', False]], [['delete', 0], ['delete', 2]]], {'ops': [['del', 'e1'], ['del', 'e5']], 'text': 'ce'}), ('delete last visible character', [[['e0', 'a', False], ['e1', 'b', False], ['e2', 'c', False], ['e3', 'd', True]], [['delete', 2]]], {'ops': [['del', 'e2']], 'text': 'ab'}), ('out-of-range edits are rejected', [[['e0', 'a', False], ['e1', 'b', False]], [['insert', 7, 'q'], ['delete', 2], ['delete', -1], ['insert', -1, 'r'], ['insert', 1, 'k']]], {'ops': [['reject', 7], ['reject', 2], ['reject', -1], ['reject', -1], ['ins', 'L1', 'e0']], 'text': 'akb'}), ('ids stay dense after a rejection', [[['e0', 'x', False], ['e1', 'y', False]], [['insert', 5, 'p'], ['insert', 1, 'm'], ['insert', 0, 'n']]], {'ops': [['reject', 5], ['ins', 'L1', 'e0'], ['ins', 'L2', None]], 'text': 'nxmy'}), ('typing into an empty document', [[], [['insert', 0, 'h'], ['insert', 1, 'i'], ['insert', 2, '!'], ['insert', 3, '!'], ['insert', 4, '!'], ['insert', 5, '!']]], {'ops': [['ins', 'L1', None], ['ins', 'L2', 'L1'], ['ins', 'L3', 'L2'], ['ins', 'L4', 'L3'], ['ins', 'L5', 'L4'], ['ins', 'L6', 'L5']], 'text': 'hi!!!!'}), ('mixed edits', [[['e0', 'h', False], ['e1', 'e', True], ['e2', 'l', False], ['e3', 'l', False], ['e4', 'o', False]], [['delete', 1], ['insert', 1, 'E'], ['insert', 4, '?']]], {'ops': [['del', 'e2'], ['ins', 'L1', 'e0'], ['ins', 'L2', 'e4']], 'text': 'hElo?'})],
    5: [('insert after tombstones uses the visible neighbour', [[['e0', 'a', False], ['e1', 'b', True], ['e2', 'c', True], ['e3', 'd', False], ['e4', 'e', False]], [['insert', 2, 'X']]], {'ops': [['ins', 'L1', 'e3']], 'text': 'adXe'}), ('insert at the visible end', [[['e0', 'a', False], ['e1', 'b', False], ['e2', 'c', True]], [['insert', 2, 'Z'], ['insert', 3, 'W']]], {'ops': [['ins', 'L1', 'e1'], ['ins', 'L2', 'L1']], 'text': 'abZW'}), ('insert at the start', [[['e0', 'a', True], ['e1', 'b', False], ['e2', 'c', False]], [['insert', 0, 'S']]], {'ops': [['ins', 'L1', None]], 'text': 'Sbc'}), ('delete by visible index', [[['e0', 'a', True], ['e1', 'b', False], ['e2', 'c', False], ['e3', 'd', True], ['e4', 'e', False], ['e5', 'f', False]], [['delete', 0], ['delete', 2]]], {'ops': [['del', 'e1'], ['del', 'e5']], 'text': 'ce'}), ('delete last visible character', [[['e0', 'a', False], ['e1', 'b', False], ['e2', 'c', False], ['e3', 'd', True]], [['delete', 2]]], {'ops': [['del', 'e2']], 'text': 'ab'}), ('out-of-range edits are rejected', [[['e0', 'a', False], ['e1', 'b', False]], [['insert', 8, 'q'], ['delete', 2], ['delete', -1], ['insert', -1, 'r'], ['insert', 1, 'k']]], {'ops': [['reject', 8], ['reject', 2], ['reject', -1], ['reject', -1], ['ins', 'L1', 'e0']], 'text': 'akb'}), ('ids stay dense after a rejection', [[['e0', 'x', False], ['e1', 'y', False]], [['insert', 5, 'p'], ['insert', 1, 'm'], ['insert', 0, 'n']]], {'ops': [['reject', 5], ['ins', 'L1', 'e0'], ['ins', 'L2', None]], 'text': 'nxmy'}), ('typing into an empty document', [[], [['insert', 0, 'h'], ['insert', 1, 'i'], ['insert', 2, '!'], ['insert', 3, '!'], ['insert', 4, '!'], ['insert', 5, '!'], ['insert', 6, '!']]], {'ops': [['ins', 'L1', None], ['ins', 'L2', 'L1'], ['ins', 'L3', 'L2'], ['ins', 'L4', 'L3'], ['ins', 'L5', 'L4'], ['ins', 'L6', 'L5'], ['ins', 'L7', 'L6']], 'text': 'hi!!!!!'}), ('mixed edits', [[['e0', 'h', False], ['e1', 'e', True], ['e2', 'l', False], ['e3', 'l', False], ['e4', 'o', False]], [['delete', 1], ['insert', 1, 'E'], ['insert', 4, '?']]], {'ops': [['del', 'e2'], ['ins', 'L1', 'e0'], ['ins', 'L2', 'e4']], 'text': 'hElo?'})],
}[N]
for label, args, expected in cases:
    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
insert after tombstones uses the visible neighbour{'ops': [['ins', 'L1', 'e3']], 'text': 'adXe'}{'ops': [['ins', 'L1', 'e3']], 'text': 'adXe'}Passed
insert at the visible end{'ops': [['ins', 'L1', 'e1'], ['ins', 'L2', 'L1']], 'text': 'abZW'}{'ops': [['ins', 'L1', 'e1'], ['ins', 'L2', 'L1']], 'text': 'abZW'}Passed
insert at the start{'ops': [['ins', 'L1', None]], 'text': 'Sbc'}{'ops': [['ins', 'L1', None]], 'text': 'Sbc'}Passed
delete by visible index{'ops': [['del', 'e1'], ['del', 'e5']], 'text': 'ce'}{'ops': [['del', 'e1'], ['del', 'e5']], 'text': 'ce'}Passed
delete last visible character{'ops': [['del', 'e2']], 'text': 'ab'}{'ops': [['del', 'e2']], 'text': 'ab'}Passed
out-of-range edits are rejected{'ops': [['reject', 4], ['reject', 2], ['del', 'e1'], ['reject', -1], ['ins', 'L1', 'e0']], 'text': 'ak'}{'ops': [['reject', 4], ['reject', 2], ['reject', -1], ['reject', -1], ['ins', 'L1', 'e0']], 'text': 'akb'}Failed
ids stay dense after a rejection{'ops': [['reject', 5], ['ins', 'L1', 'e0'], ['ins', 'L2', None]], 'text': 'nxmy'}{'ops': [['reject', 5], ['ins', 'L1', 'e0'], ['ins', 'L2', None]], 'text': 'nxmy'}Passed
typing into an empty document{'ops': [['ins', 'L1', None], ['ins', 'L2', 'L1'], ['ins', 'L3', 'L2']], 'text': 'hi!'}{'ops': [['ins', 'L1', None], ['ins', 'L2', 'L1'], ['ins', 'L3', 'L2']], 'text': 'hi!'}Passed
mixed edits{'ops': [['del', 'e2'], ['ins', 'L1', 'e0'], ['ins', 'L2', 'e4']], 'text': 'hElo?'}{'ops': [['del', 'e2'], ['ins', 'L1', 'e0'], ['ins', 'L2', 'e4']], 'text': 'hElo?'}Passed

SHA-256 / 8ee92c17829b654d0db2c172b40d7beb8ee0cf6a4e24c39a88b2063027a79ff3

HELD IN THE MEMBER ARCHIVE

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

This mechanism has 9 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

A deterministic, bounded teaching model of one replicated data type with stipulated operation and merge rules; it is not a production CRDT library and makes no claim of conformance to any specific published design. 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:03.705105+00:00.

Case digest / 59583ebf3f67a4e93b940ad3cdd879e68f9028813e04df77071189a821764200