{"abstract":"Appending a character after the last visible character is refused.","category":"CRDT convergence","checks":9,"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.","evaluation_group":"w2-crdt-convergence-visible-index-translation","failed_approach":"Special-casing the empty document still refuses appends to non-empty text.","family":"w2-crdt-convergence-visible-index-translation-insert-upper-bound","id":"FA-75166","implementations":{"attempt":{"sha256":"105dd6023f999719c4d161be34040149cb02755f26770169b5f0ce6821761f21","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(elements, edits):\n    seq = [list(e) for e in elements]\n    out = []\n    k = 0\n    for ed in edits:\n        vis = [i for i, e in enumerate(seq) if not e[2]]\n        idx = ed[1]\n        if ed[0] == 'insert':\n            if idx < 0 or (idx >= len(vis) and idx != 0):\n                out.append(['reject', idx])\n                continue\n            if idx == 0:\n                after, pos = None, 0\n            else:\n                p = vis[idx - 1]\n                after, pos = seq[p][0], p + 1\n            k += 1\n            nid = 'L%d' % k\n            seq.insert(pos, [nid, ed[2], False])\n            out.append(['ins', nid, after])\n        else:\n            if idx < 0 or idx >= len(vis):\n                out.append(['reject', idx])\n                continue\n            p = vis[idx]\n            seq[p][2] = True\n            out.append(['del', seq[p][0]])\n    return {'ops': out, 'text': ''.join(e[1] for e in seq if not e[2])}\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncases = {\n    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?'})],\n    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?'})],\n    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?'})],\n    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?'})],\n    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}[N]\nfor label, args, expected in cases:\n    check(label, solve(*args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"},"broken":{"sha256":"8ead4d446f964b3a93bf3ffefbcb4fc2d196c2b4f0ce4c98c9d8abe6ef41b4ce","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(elements, edits):\n    seq = [list(e) for e in elements]\n    out = []\n    k = 0\n    for ed in edits:\n        vis = [i for i, e in enumerate(seq) if not e[2]]\n        idx = ed[1]\n        if ed[0] == 'insert':\n            if idx < 0 or idx >= len(vis):\n                out.append(['reject', idx])\n                continue\n            if idx == 0:\n                after, pos = None, 0\n            else:\n                p = vis[idx - 1]\n                after, pos = seq[p][0], p + 1\n            k += 1\n            nid = 'L%d' % k\n            seq.insert(pos, [nid, ed[2], False])\n            out.append(['ins', nid, after])\n        else:\n            if idx < 0 or idx >= len(vis):\n                out.append(['reject', idx])\n                continue\n            p = vis[idx]\n            seq[p][2] = True\n            out.append(['del', seq[p][0]])\n    return {'ops': out, 'text': ''.join(e[1] for e in seq if not e[2])}\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncases = {\n    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?'})],\n    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?'})],\n    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?'})],\n    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?'})],\n    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}[N]\nfor label, args, expected in cases:\n    check(label, solve(*args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"},"fixed":{"sha256":"f442879e70a927fc6310e255f5ae0a30a1772555903470c8f30318698b00183e","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(elements, edits):\n    seq = [list(e) for e in elements]\n    out = []\n    k = 0\n    for ed in edits:\n        vis = [i for i, e in enumerate(seq) if not e[2]]\n        idx = ed[1]\n        if ed[0] == 'insert':\n            if idx < 0 or idx > len(vis):\n                out.append(['reject', idx])\n                continue\n            if idx == 0:\n                after, pos = None, 0\n            else:\n                p = vis[idx - 1]\n                after, pos = seq[p][0], p + 1\n            k += 1\n            nid = 'L%d' % k\n            seq.insert(pos, [nid, ed[2], False])\n            out.append(['ins', nid, after])\n        else:\n            if idx < 0 or idx >= len(vis):\n                out.append(['reject', idx])\n                continue\n            p = vis[idx]\n            seq[p][2] = True\n            out.append(['del', seq[p][0]])\n    return {'ops': out, 'text': ''.join(e[1] for e in seq if not e[2])}\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncases = {\n    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?'})],\n    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?'})],\n    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?'})],\n    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?'})],\n    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}[N]\nfor label, args, expected in cases:\n    check(label, solve(*args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"}},"limitations":"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.","method":"Deterministic executable model with adversarial boundary fixtures.","provenance":{"created_by":"Failure Map","dependencies":"Python standard library","family":"w2-crdt-convergence-visible-index-translation-insert-upper-bound","generated_at":"2026-09-29T14:49:03.690024+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Editors translate cursor positions into identifier-based CRDT operations; tombstones make that translation error-prone.","repair":"Inserts accept every index from zero through the visible length inclusive.","root_cause":"The insert bound uses the delete rule, excluding the position equal to the visible length.","sha256":"f684b9864a2e953837e3a0b0b1fd16852563a37694efc4b77c7228b60b30940e","title":"Visible index translation: typing at the end of the document is rejected · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":42.759,"exit_code":1,"observations":[{"actual":{"ops":[["ins","L1","e3"]],"text":"adXe"},"check":"insert after tombstones uses the visible neighbour","expected":{"ops":[["ins","L1","e3"]],"text":"adXe"},"passed":true},{"actual":{"ops":[["reject",2],["reject",3]],"text":"ab"},"check":"insert at the visible end","expected":{"ops":[["ins","L1","e1"],["ins","L2","L1"]],"text":"abZW"},"passed":false},{"actual":{"ops":[["ins","L1",null]],"text":"Sbc"},"check":"insert at the start","expected":{"ops":[["ins","L1",null]],"text":"Sbc"},"passed":true},{"actual":{"ops":[["del","e1"],["del","e5"]],"text":"ce"},"check":"delete by visible index","expected":{"ops":[["del","e1"],["del","e5"]],"text":"ce"},"passed":true},{"actual":{"ops":[["del","e2"]],"text":"ab"},"check":"delete last visible character","expected":{"ops":[["del","e2"]],"text":"ab"},"passed":true},{"actual":{"ops":[["reject",4],["reject",2],["reject",-1],["reject",-1],["ins","L1","e0"]],"text":"akb"},"check":"out-of-range edits are rejected","expected":{"ops":[["reject",4],["reject",2],["reject",-1],["reject",-1],["ins","L1","e0"]],"text":"akb"},"passed":true},{"actual":{"ops":[["reject",5],["ins","L1","e0"],["ins","L2",null]],"text":"nxmy"},"check":"ids stay dense after a rejection","expected":{"ops":[["reject",5],["ins","L1","e0"],["ins","L2",null]],"text":"nxmy"},"passed":true},{"actual":{"ops":[["ins","L1",null],["reject",1],["reject",2]],"text":"h"},"check":"typing into an empty document","expected":{"ops":[["ins","L1",null],["ins","L2","L1"],["ins","L3","L2"]],"text":"hi!"},"passed":false},{"actual":{"ops":[["del","e2"],["ins","L1","e0"],["reject",4]],"text":"hElo"},"check":"mixed edits","expected":{"ops":[["del","e2"],["ins","L1","e0"],["ins","L2","e4"]],"text":"hElo?"},"passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"insert after tombstones uses the visible neighbour\", \"actual\": {\"ops\": [[\"ins\", \"L1\", \"e3\"]], \"text\": \"adXe\"}, \"expected\": {\"ops\": [[\"ins\", \"L1\", \"e3\"]], \"text\": \"adXe\"}, \"passed\": true}, {\"check\": \"insert at the visible end\", \"actual\": {\"ops\": [[\"reject\", 2], [\"reject\", 3]], \"text\": \"ab\"}, \"expected\": {\"ops\": [[\"ins\", \"L1\", \"e1\"], [\"ins\", \"L2\", \"L1\"]], \"text\": \"abZW\"}, \"passed\": false}, {\"check\": \"insert at the start\", \"actual\": {\"ops\": [[\"ins\", \"L1\", null]], \"text\": \"Sbc\"}, \"expected\": {\"ops\": [[\"ins\", \"L1\", null]], \"text\": \"Sbc\"}, \"passed\": true}, {\"check\": \"delete by visible index\", \"actual\": {\"ops\": [[\"del\", \"e1\"], [\"del\", \"e5\"]], \"text\": \"ce\"}, \"expected\": {\"ops\": [[\"del\", \"e1\"], [\"del\", \"e5\"]], \"text\": \"ce\"}, \"passed\": true}, {\"check\": \"delete last visible character\", \"actual\": {\"ops\": [[\"del\", \"e2\"]], \"text\": \"ab\"}, \"expected\": {\"ops\": [[\"del\", \"e2\"]], \"text\": \"ab\"}, \"passed\": true}, {\"check\": \"out-of-range edits are rejected\", \"actual\": {\"ops\": [[\"reject\", 4], [\"reject\", 2], [\"reject\", -1], [\"reject\", -1], [\"ins\", \"L1\", \"e0\"]], \"text\": \"akb\"}, \"expected\": {\"ops\": [[\"reject\", 4], [\"reject\", 2], [\"reject\", -1], [\"reject\", -1], [\"ins\", \"L1\", \"e0\"]], \"text\": \"akb\"}, \"passed\": true}, {\"check\": \"ids stay dense after a rejection\", \"actual\": {\"ops\": [[\"reject\", 5], [\"ins\", \"L1\", \"e0\"], [\"ins\", \"L2\", null]], \"text\": \"nxmy\"}, \"expected\": {\"ops\": [[\"reject\", 5], [\"ins\", \"L1\", \"e0\"], [\"ins\", \"L2\", null]], \"text\": \"nxmy\"}, \"passed\": true}, {\"check\": \"typing into an empty document\", \"actual\": {\"ops\": [[\"ins\", \"L1\", null], [\"reject\", 1], [\"reject\", 2]], \"text\": \"h\"}, \"expected\": {\"ops\": [[\"ins\", \"L1\", null], [\"ins\", \"L2\", \"L1\"], [\"ins\", \"L3\", \"L2\"]], \"text\": \"hi!\"}, \"passed\": false}, {\"check\": \"mixed edits\", \"actual\": {\"ops\": [[\"del\", \"e2\"], [\"ins\", \"L1\", \"e0\"], [\"reject\", 4]], \"text\": \"hElo\"}, \"expected\": {\"ops\": [[\"del\", \"e2\"], [\"ins\", \"L1\", \"e0\"], [\"ins\", \"L2\", \"e4\"]], \"text\": \"hElo?\"}, \"passed\": false}], \"passed\": false}\n"},"broken":{"elapsed_ms":46.71,"exit_code":1,"observations":[{"actual":{"ops":[["ins","L1","e3"]],"text":"adXe"},"check":"insert after tombstones uses the visible neighbour","expected":{"ops":[["ins","L1","e3"]],"text":"adXe"},"passed":true},{"actual":{"ops":[["reject",2],["reject",3]],"text":"ab"},"check":"insert at the visible end","expected":{"ops":[["ins","L1","e1"],["ins","L2","L1"]],"text":"abZW"},"passed":false},{"actual":{"ops":[["ins","L1",null]],"text":"Sbc"},"check":"insert at the start","expected":{"ops":[["ins","L1",null]],"text":"Sbc"},"passed":true},{"actual":{"ops":[["del","e1"],["del","e5"]],"text":"ce"},"check":"delete by visible index","expected":{"ops":[["del","e1"],["del","e5"]],"text":"ce"},"passed":true},{"actual":{"ops":[["del","e2"]],"text":"ab"},"check":"delete last visible character","expected":{"ops":[["del","e2"]],"text":"ab"},"passed":true},{"actual":{"ops":[["reject",4],["reject",2],["reject",-1],["reject",-1],["ins","L1","e0"]],"text":"akb"},"check":"out-of-range edits are rejected","expected":{"ops":[["reject",4],["reject",2],["reject",-1],["reject",-1],["ins","L1","e0"]],"text":"akb"},"passed":true},{"actual":{"ops":[["reject",5],["ins","L1","e0"],["ins","L2",null]],"text":"nxmy"},"check":"ids stay dense after a rejection","expected":{"ops":[["reject",5],["ins","L1","e0"],["ins","L2",null]],"text":"nxmy"},"passed":true},{"actual":{"ops":[["reject",0],["reject",1],["reject",2]],"text":""},"check":"typing into an empty document","expected":{"ops":[["ins","L1",null],["ins","L2","L1"],["ins","L3","L2"]],"text":"hi!"},"passed":false},{"actual":{"ops":[["del","e2"],["ins","L1","e0"],["reject",4]],"text":"hElo"},"check":"mixed edits","expected":{"ops":[["del","e2"],["ins","L1","e0"],["ins","L2","e4"]],"text":"hElo?"},"passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"insert after tombstones uses the visible neighbour\", \"actual\": {\"ops\": [[\"ins\", \"L1\", \"e3\"]], \"text\": \"adXe\"}, \"expected\": {\"ops\": [[\"ins\", \"L1\", \"e3\"]], \"text\": \"adXe\"}, \"passed\": true}, {\"check\": \"insert at the visible end\", \"actual\": {\"ops\": [[\"reject\", 2], [\"reject\", 3]], \"text\": \"ab\"}, \"expected\": {\"ops\": [[\"ins\", \"L1\", \"e1\"], [\"ins\", \"L2\", \"L1\"]], \"text\": \"abZW\"}, \"passed\": false}, {\"check\": \"insert at the start\", \"actual\": {\"ops\": [[\"ins\", \"L1\", null]], \"text\": \"Sbc\"}, \"expected\": {\"ops\": [[\"ins\", \"L1\", null]], \"text\": \"Sbc\"}, \"passed\": true}, {\"check\": \"delete by visible index\", \"actual\": {\"ops\": [[\"del\", \"e1\"], [\"del\", \"e5\"]], \"text\": \"ce\"}, \"expected\": {\"ops\": [[\"del\", \"e1\"], [\"del\", \"e5\"]], \"text\": \"ce\"}, \"passed\": true}, {\"check\": \"delete last visible character\", \"actual\": {\"ops\": [[\"del\", \"e2\"]], \"text\": \"ab\"}, \"expected\": {\"ops\": [[\"del\", \"e2\"]], \"text\": \"ab\"}, \"passed\": true}, {\"check\": \"out-of-range edits are rejected\", \"actual\": {\"ops\": [[\"reject\", 4], [\"reject\", 2], [\"reject\", -1], [\"reject\", -1], [\"ins\", \"L1\", \"e0\"]], \"text\": \"akb\"}, \"expected\": {\"ops\": [[\"reject\", 4], [\"reject\", 2], [\"reject\", -1], [\"reject\", -1], [\"ins\", \"L1\", \"e0\"]], \"text\": \"akb\"}, \"passed\": true}, {\"check\": \"ids stay dense after a rejection\", \"actual\": {\"ops\": [[\"reject\", 5], [\"ins\", \"L1\", \"e0\"], [\"ins\", \"L2\", null]], \"text\": \"nxmy\"}, \"expected\": {\"ops\": [[\"reject\", 5], [\"ins\", \"L1\", \"e0\"], [\"ins\", \"L2\", null]], \"text\": \"nxmy\"}, \"passed\": true}, {\"check\": \"typing into an empty document\", \"actual\": {\"ops\": [[\"reject\", 0], [\"reject\", 1], [\"reject\", 2]], \"text\": \"\"}, \"expected\": {\"ops\": [[\"ins\", \"L1\", null], [\"ins\", \"L2\", \"L1\"], [\"ins\", \"L3\", \"L2\"]], \"text\": \"hi!\"}, \"passed\": false}, {\"check\": \"mixed edits\", \"actual\": {\"ops\": [[\"del\", \"e2\"], [\"ins\", \"L1\", \"e0\"], [\"reject\", 4]], \"text\": \"hElo\"}, \"expected\": {\"ops\": [[\"del\", \"e2\"], [\"ins\", \"L1\", \"e0\"], [\"ins\", \"L2\", \"e4\"]], \"text\": \"hElo?\"}, \"passed\": false}], \"passed\": false}\n"},"fixed":{"elapsed_ms":42.522,"exit_code":0,"observations":[{"actual":{"ops":[["ins","L1","e3"]],"text":"adXe"},"check":"insert after tombstones uses the visible neighbour","expected":{"ops":[["ins","L1","e3"]],"text":"adXe"},"passed":true},{"actual":{"ops":[["ins","L1","e1"],["ins","L2","L1"]],"text":"abZW"},"check":"insert at the visible end","expected":{"ops":[["ins","L1","e1"],["ins","L2","L1"]],"text":"abZW"},"passed":true},{"actual":{"ops":[["ins","L1",null]],"text":"Sbc"},"check":"insert at the start","expected":{"ops":[["ins","L1",null]],"text":"Sbc"},"passed":true},{"actual":{"ops":[["del","e1"],["del","e5"]],"text":"ce"},"check":"delete by visible index","expected":{"ops":[["del","e1"],["del","e5"]],"text":"ce"},"passed":true},{"actual":{"ops":[["del","e2"]],"text":"ab"},"check":"delete last visible character","expected":{"ops":[["del","e2"]],"text":"ab"},"passed":true},{"actual":{"ops":[["reject",4],["reject",2],["reject",-1],["reject",-1],["ins","L1","e0"]],"text":"akb"},"check":"out-of-range edits are rejected","expected":{"ops":[["reject",4],["reject",2],["reject",-1],["reject",-1],["ins","L1","e0"]],"text":"akb"},"passed":true},{"actual":{"ops":[["reject",5],["ins","L1","e0"],["ins","L2",null]],"text":"nxmy"},"check":"ids stay dense after a rejection","expected":{"ops":[["reject",5],["ins","L1","e0"],["ins","L2",null]],"text":"nxmy"},"passed":true},{"actual":{"ops":[["ins","L1",null],["ins","L2","L1"],["ins","L3","L2"]],"text":"hi!"},"check":"typing into an empty document","expected":{"ops":[["ins","L1",null],["ins","L2","L1"],["ins","L3","L2"]],"text":"hi!"},"passed":true},{"actual":{"ops":[["del","e2"],["ins","L1","e0"],["ins","L2","e4"]],"text":"hElo?"},"check":"mixed edits","expected":{"ops":[["del","e2"],["ins","L1","e0"],["ins","L2","e4"]],"text":"hElo?"},"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"insert after tombstones uses the visible neighbour\", \"actual\": {\"ops\": [[\"ins\", \"L1\", \"e3\"]], \"text\": \"adXe\"}, \"expected\": {\"ops\": [[\"ins\", \"L1\", \"e3\"]], \"text\": \"adXe\"}, \"passed\": true}, {\"check\": \"insert at the visible end\", \"actual\": {\"ops\": [[\"ins\", \"L1\", \"e1\"], [\"ins\", \"L2\", \"L1\"]], \"text\": \"abZW\"}, \"expected\": {\"ops\": [[\"ins\", \"L1\", \"e1\"], [\"ins\", \"L2\", \"L1\"]], \"text\": \"abZW\"}, \"passed\": true}, {\"check\": \"insert at the start\", \"actual\": {\"ops\": [[\"ins\", \"L1\", null]], \"text\": \"Sbc\"}, \"expected\": {\"ops\": [[\"ins\", \"L1\", null]], \"text\": \"Sbc\"}, \"passed\": true}, {\"check\": \"delete by visible index\", \"actual\": {\"ops\": [[\"del\", \"e1\"], [\"del\", \"e5\"]], \"text\": \"ce\"}, \"expected\": {\"ops\": [[\"del\", \"e1\"], [\"del\", \"e5\"]], \"text\": \"ce\"}, \"passed\": true}, {\"check\": \"delete last visible character\", \"actual\": {\"ops\": [[\"del\", \"e2\"]], \"text\": \"ab\"}, \"expected\": {\"ops\": [[\"del\", \"e2\"]], \"text\": \"ab\"}, \"passed\": true}, {\"check\": \"out-of-range edits are rejected\", \"actual\": {\"ops\": [[\"reject\", 4], [\"reject\", 2], [\"reject\", -1], [\"reject\", -1], [\"ins\", \"L1\", \"e0\"]], \"text\": \"akb\"}, \"expected\": {\"ops\": [[\"reject\", 4], [\"reject\", 2], [\"reject\", -1], [\"reject\", -1], [\"ins\", \"L1\", \"e0\"]], \"text\": \"akb\"}, \"passed\": true}, {\"check\": \"ids stay dense after a rejection\", \"actual\": {\"ops\": [[\"reject\", 5], [\"ins\", \"L1\", \"e0\"], [\"ins\", \"L2\", null]], \"text\": \"nxmy\"}, \"expected\": {\"ops\": [[\"reject\", 5], [\"ins\", \"L1\", \"e0\"], [\"ins\", \"L2\", null]], \"text\": \"nxmy\"}, \"passed\": true}, {\"check\": \"typing into an empty document\", \"actual\": {\"ops\": [[\"ins\", \"L1\", null], [\"ins\", \"L2\", \"L1\"], [\"ins\", \"L3\", \"L2\"]], \"text\": \"hi!\"}, \"expected\": {\"ops\": [[\"ins\", \"L1\", null], [\"ins\", \"L2\", \"L1\"], [\"ins\", \"L3\", \"L2\"]], \"text\": \"hi!\"}, \"passed\": true}, {\"check\": \"mixed edits\", \"actual\": {\"ops\": [[\"del\", \"e2\"], [\"ins\", \"L1\", \"e0\"], [\"ins\", \"L2\", \"e4\"]], \"text\": \"hElo?\"}, \"expected\": {\"ops\": [[\"del\", \"e2\"], [\"ins\", \"L1\", \"e0\"], [\"ins\", \"L2\", \"e4\"]], \"text\": \"hElo?\"}, \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}