{"abstract":"The table ack server revision result violates the stipulated asynchronous table cell save acknowledgement contract.","category":"Table interactions","checks":7,"contract":"A save acknowledgement belongs to an exact pending request and row, clears only that pending cell, preserves errors and newer edits, rejects older server revisions, installs canonical server values/revisions, and clears a draft only when the original edit ID still owns it.","evaluation_group":"s3-table-interactions-async-cell-save","failed_approach":"The attempted repair \"out['revision']=row['revision']\" still loses a required part of the table contract.","family":"s3-table-interactions-async-cell-save-ack-server-revision","id":"FA-38171","implementations":{"attempt":{"sha256":"2ffba32e839f0ed176b0591c55efc26455b25537e5e930c03f137946c2f44ee3","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(row, pending, response, draft):\n    key=(response['row'],response['column'])\n    request=pending.get(key)\n    if request is None or request['id']!=response['request']: return {'row':row,'pending':sorted(pending.items()),'draft':sorted(draft.items()),'error':None}\n    if row['id']!=response['row']: return {'row':row,'pending':sorted(pending.items()),'draft':sorted(draft.items()),'error':None}\n    next_pending=dict(pending); next_pending.pop(key)\n    if response.get('error') is not None: return {'row':row,'pending':sorted(next_pending.items()),'draft':sorted(draft.items()),'error':response['error']}\n    out=dict(row)\n    if response['revision']<row['revision']: return {'row':out,'pending':sorted(next_pending.items()),'draft':sorted(draft.items()),'error':'stale'}\n    out[response['column']]=response['value']; out['revision']=row['revision']\n    next_draft=dict(draft)\n    if key in next_draft and next_draft[key]['edit_id']==request['edit_id']: next_draft.pop(key)\n    return {'row':out,'pending':sorted(next_pending.items()),'draft':sorted(next_draft.items()),'error':None}\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nif N == 1:\n    check('canonical server response', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':' raw '},('r','b'):{'id':3,'edit_id':10,'value':'B'}}, {'row':'r','column':'a','request':2,'revision':8,'value':'raw'+str(1),'warning':'informational'}, {('r','a'):{'edit_id':9,'value':' raw '},('r','b'):{'edit_id':10,'value':'B'}}), {'row': {'id': 'r', 'a': 'raw1', 'revision': 8}, 'pending': [(('r', 'b'), {'id': 3, 'edit_id': 10, 'value': 'B'})], 'draft': [(('r', 'b'), {'edit_id': 10, 'value': 'B'})], 'error': None})\n    check('late old request', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':1,'revision':4,'value':'old ack'}, {}), {'row': {'id': 'r', 'a': 'old', 'revision': 3}, 'pending': [(('r', 'a'), {'id': 2, 'edit_id': 9, 'value': 'v'})], 'draft': [], 'error': None})\n    check('different row', solve({'id':'other','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack'}, {}), {'row': {'id': 'other', 'a': 'old', 'revision': 3}, 'pending': [(('r', 'a'), {'id': 2, 'edit_id': 9, 'value': 'v'})], 'draft': [], 'error': None})\n    check('empty error message', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack','error':''}, {('r','a'):{'edit_id':9,'value':'v'}}), {'row': {'id': 'r', 'a': 'old', 'revision': 3}, 'pending': [], 'draft': [(('r', 'a'), {'edit_id': 9, 'value': 'v'})], 'error': ''})\n    check('stale revision', solve({'id':'r','a':'new','revision':7}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':6,'value':'ack'}, {}), {'row': {'id': 'r', 'a': 'new', 'revision': 7}, 'pending': [], 'draft': [], 'error': 'stale'})\n    check('equal revision allowed', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':3,'value':'ack'}, {}), {'row': {'id': 'r', 'a': 'ack', 'revision': 3}, 'pending': [], 'draft': [], 'error': None})\n    check('new edit same value', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack'}, {('r','a'):{'edit_id':10,'value':'v'}}), {'row': {'id': 'r', 'a': 'ack', 'revision': 4}, 'pending': [], 'draft': [(('r', 'a'), {'edit_id': 10, 'value': 'v'})], 'error': None})\n\nif N == 2:\n    check('canonical server response', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':' raw '},('r','b'):{'id':3,'edit_id':10,'value':'B'}}, {'row':'r','column':'a','request':2,'revision':8,'value':'raw'+str(2),'warning':'informational'}, {('r','a'):{'edit_id':9,'value':' raw '},('r','b'):{'edit_id':10,'value':'B'}}), {'row': {'id': 'r', 'a': 'raw2', 'revision': 8}, 'pending': [(('r', 'b'), {'id': 3, 'edit_id': 10, 'value': 'B'})], 'draft': [(('r', 'b'), {'edit_id': 10, 'value': 'B'})], 'error': None})\n    check('late old request', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':1,'revision':4,'value':'old ack'}, {}), {'row': {'id': 'r', 'a': 'old', 'revision': 3}, 'pending': [(('r', 'a'), {'id': 2, 'edit_id': 9, 'value': 'v'})], 'draft': [], 'error': None})\n    check('different row', solve({'id':'other','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack'}, {}), {'row': {'id': 'other', 'a': 'old', 'revision': 3}, 'pending': [(('r', 'a'), {'id': 2, 'edit_id': 9, 'value': 'v'})], 'draft': [], 'error': None})\n    check('empty error message', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack','error':''}, {('r','a'):{'edit_id':9,'value':'v'}}), {'row': {'id': 'r', 'a': 'old', 'revision': 3}, 'pending': [], 'draft': [(('r', 'a'), {'edit_id': 9, 'value': 'v'})], 'error': ''})\n    check('stale revision', solve({'id':'r','a':'new','revision':7}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':6,'value':'ack'}, {}), {'row': {'id': 'r', 'a': 'new', 'revision': 7}, 'pending': [], 'draft': [], 'error': 'stale'})\n    check('equal revision allowed', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':3,'value':'ack'}, {}), {'row': {'id': 'r', 'a': 'ack', 'revision': 3}, 'pending': [], 'draft': [], 'error': None})\n    check('new edit same value', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack'}, {('r','a'):{'edit_id':10,'value':'v'}}), {'row': {'id': 'r', 'a': 'ack', 'revision': 4}, 'pending': [], 'draft': [(('r', 'a'), {'edit_id': 10, 'value': 'v'})], 'error': None})\n\nif N == 3:\n    check('canonical server response', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':' raw '},('r','b'):{'id':3,'edit_id':10,'value':'B'}}, {'row':'r','column':'a','request':2,'revision':8,'value':'raw'+str(3),'warning':'informational'}, {('r','a'):{'edit_id':9,'value':' raw '},('r','b'):{'edit_id':10,'value':'B'}}), {'row': {'id': 'r', 'a': 'raw3', 'revision': 8}, 'pending': [(('r', 'b'), {'id': 3, 'edit_id': 10, 'value': 'B'})], 'draft': [(('r', 'b'), {'edit_id': 10, 'value': 'B'})], 'error': None})\n    check('late old request', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':1,'revision':4,'value':'old ack'}, {}), {'row': {'id': 'r', 'a': 'old', 'revision': 3}, 'pending': [(('r', 'a'), {'id': 2, 'edit_id': 9, 'value': 'v'})], 'draft': [], 'error': None})\n    check('different row', solve({'id':'other','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack'}, {}), {'row': {'id': 'other', 'a': 'old', 'revision': 3}, 'pending': [(('r', 'a'), {'id': 2, 'edit_id': 9, 'value': 'v'})], 'draft': [], 'error': None})\n    check('empty error message', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack','error':''}, {('r','a'):{'edit_id':9,'value':'v'}}), {'row': {'id': 'r', 'a': 'old', 'revision': 3}, 'pending': [], 'draft': [(('r', 'a'), {'edit_id': 9, 'value': 'v'})], 'error': ''})\n    check('stale revision', solve({'id':'r','a':'new','revision':7}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':6,'value':'ack'}, {}), {'row': {'id': 'r', 'a': 'new', 'revision': 7}, 'pending': [], 'draft': [], 'error': 'stale'})\n    check('equal revision allowed', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':3,'value':'ack'}, {}), {'row': {'id': 'r', 'a': 'ack', 'revision': 3}, 'pending': [], 'draft': [], 'error': None})\n    check('new edit same value', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack'}, {('r','a'):{'edit_id':10,'value':'v'}}), {'row': {'id': 'r', 'a': 'ack', 'revision': 4}, 'pending': [], 'draft': [(('r', 'a'), {'edit_id': 10, 'value': 'v'})], 'error': None})\n\nif N == 4:\n    check('canonical server response', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':' raw '},('r','b'):{'id':3,'edit_id':10,'value':'B'}}, {'row':'r','column':'a','request':2,'revision':8,'value':'raw'+str(4),'warning':'informational'}, {('r','a'):{'edit_id':9,'value':' raw '},('r','b'):{'edit_id':10,'value':'B'}}), {'row': {'id': 'r', 'a': 'raw4', 'revision': 8}, 'pending': [(('r', 'b'), {'id': 3, 'edit_id': 10, 'value': 'B'})], 'draft': [(('r', 'b'), {'edit_id': 10, 'value': 'B'})], 'error': None})\n    check('late old request', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':1,'revision':4,'value':'old ack'}, {}), {'row': {'id': 'r', 'a': 'old', 'revision': 3}, 'pending': [(('r', 'a'), {'id': 2, 'edit_id': 9, 'value': 'v'})], 'draft': [], 'error': None})\n    check('different row', solve({'id':'other','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack'}, {}), {'row': {'id': 'other', 'a': 'old', 'revision': 3}, 'pending': [(('r', 'a'), {'id': 2, 'edit_id': 9, 'value': 'v'})], 'draft': [], 'error': None})\n    check('empty error message', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack','error':''}, {('r','a'):{'edit_id':9,'value':'v'}}), {'row': {'id': 'r', 'a': 'old', 'revision': 3}, 'pending': [], 'draft': [(('r', 'a'), {'edit_id': 9, 'value': 'v'})], 'error': ''})\n    check('stale revision', solve({'id':'r','a':'new','revision':7}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':6,'value':'ack'}, {}), {'row': {'id': 'r', 'a': 'new', 'revision': 7}, 'pending': [], 'draft': [], 'error': 'stale'})\n    check('equal revision allowed', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':3,'value':'ack'}, {}), {'row': {'id': 'r', 'a': 'ack', 'revision': 3}, 'pending': [], 'draft': [], 'error': None})\n    check('new edit same value', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack'}, {('r','a'):{'edit_id':10,'value':'v'}}), {'row': {'id': 'r', 'a': 'ack', 'revision': 4}, 'pending': [], 'draft': [(('r', 'a'), {'edit_id': 10, 'value': 'v'})], 'error': None})\n\nif N == 5:\n    check('canonical server response', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':' raw '},('r','b'):{'id':3,'edit_id':10,'value':'B'}}, {'row':'r','column':'a','request':2,'revision':8,'value':'raw'+str(5),'warning':'informational'}, {('r','a'):{'edit_id':9,'value':' raw '},('r','b'):{'edit_id':10,'value':'B'}}), {'row': {'id': 'r', 'a': 'raw5', 'revision': 8}, 'pending': [(('r', 'b'), {'id': 3, 'edit_id': 10, 'value': 'B'})], 'draft': [(('r', 'b'), {'edit_id': 10, 'value': 'B'})], 'error': None})\n    check('late old request', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':1,'revision':4,'value':'old ack'}, {}), {'row': {'id': 'r', 'a': 'old', 'revision': 3}, 'pending': [(('r', 'a'), {'id': 2, 'edit_id': 9, 'value': 'v'})], 'draft': [], 'error': None})\n    check('different row', solve({'id':'other','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack'}, {}), {'row': {'id': 'other', 'a': 'old', 'revision': 3}, 'pending': [(('r', 'a'), {'id': 2, 'edit_id': 9, 'value': 'v'})], 'draft': [], 'error': None})\n    check('empty error message', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack','error':''}, {('r','a'):{'edit_id':9,'value':'v'}}), {'row': {'id': 'r', 'a': 'old', 'revision': 3}, 'pending': [], 'draft': [(('r', 'a'), {'edit_id': 9, 'value': 'v'})], 'error': ''})\n    check('stale revision', solve({'id':'r','a':'new','revision':7}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':6,'value':'ack'}, {}), {'row': {'id': 'r', 'a': 'new', 'revision': 7}, 'pending': [], 'draft': [], 'error': 'stale'})\n    check('equal revision allowed', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':3,'value':'ack'}, {}), {'row': {'id': 'r', 'a': 'ack', 'revision': 3}, 'pending': [], 'draft': [], 'error': None})\n    check('new edit same value', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack'}, {('r','a'):{'edit_id':10,'value':'v'}}), {'row': {'id': 'r', 'a': 'ack', 'revision': 4}, 'pending': [], 'draft': [(('r', 'a'), {'edit_id': 10, 'value': 'v'})], 'error': None})\n\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":"67a0bded60d6648a9cf49169315d10e3fd42d604b30a08527ae874c7e75a79c0","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(row, pending, response, draft):\n    key=(response['row'],response['column'])\n    request=pending.get(key)\n    if request is None or request['id']!=response['request']: return {'row':row,'pending':sorted(pending.items()),'draft':sorted(draft.items()),'error':None}\n    if row['id']!=response['row']: return {'row':row,'pending':sorted(pending.items()),'draft':sorted(draft.items()),'error':None}\n    next_pending=dict(pending); next_pending.pop(key)\n    if response.get('error') is not None: return {'row':row,'pending':sorted(next_pending.items()),'draft':sorted(draft.items()),'error':response['error']}\n    out=dict(row)\n    if response['revision']<row['revision']: return {'row':out,'pending':sorted(next_pending.items()),'draft':sorted(draft.items()),'error':'stale'}\n    out[response['column']]=response['value']; out['revision']=row['revision']+1\n    next_draft=dict(draft)\n    if key in next_draft and next_draft[key]['edit_id']==request['edit_id']: next_draft.pop(key)\n    return {'row':out,'pending':sorted(next_pending.items()),'draft':sorted(next_draft.items()),'error':None}\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nif N == 1:\n    check('canonical server response', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':' raw '},('r','b'):{'id':3,'edit_id':10,'value':'B'}}, {'row':'r','column':'a','request':2,'revision':8,'value':'raw'+str(1),'warning':'informational'}, {('r','a'):{'edit_id':9,'value':' raw '},('r','b'):{'edit_id':10,'value':'B'}}), {'row': {'id': 'r', 'a': 'raw1', 'revision': 8}, 'pending': [(('r', 'b'), {'id': 3, 'edit_id': 10, 'value': 'B'})], 'draft': [(('r', 'b'), {'edit_id': 10, 'value': 'B'})], 'error': None})\n    check('late old request', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':1,'revision':4,'value':'old ack'}, {}), {'row': {'id': 'r', 'a': 'old', 'revision': 3}, 'pending': [(('r', 'a'), {'id': 2, 'edit_id': 9, 'value': 'v'})], 'draft': [], 'error': None})\n    check('different row', solve({'id':'other','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack'}, {}), {'row': {'id': 'other', 'a': 'old', 'revision': 3}, 'pending': [(('r', 'a'), {'id': 2, 'edit_id': 9, 'value': 'v'})], 'draft': [], 'error': None})\n    check('empty error message', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack','error':''}, {('r','a'):{'edit_id':9,'value':'v'}}), {'row': {'id': 'r', 'a': 'old', 'revision': 3}, 'pending': [], 'draft': [(('r', 'a'), {'edit_id': 9, 'value': 'v'})], 'error': ''})\n    check('stale revision', solve({'id':'r','a':'new','revision':7}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':6,'value':'ack'}, {}), {'row': {'id': 'r', 'a': 'new', 'revision': 7}, 'pending': [], 'draft': [], 'error': 'stale'})\n    check('equal revision allowed', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':3,'value':'ack'}, {}), {'row': {'id': 'r', 'a': 'ack', 'revision': 3}, 'pending': [], 'draft': [], 'error': None})\n    check('new edit same value', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack'}, {('r','a'):{'edit_id':10,'value':'v'}}), {'row': {'id': 'r', 'a': 'ack', 'revision': 4}, 'pending': [], 'draft': [(('r', 'a'), {'edit_id': 10, 'value': 'v'})], 'error': None})\n\nif N == 2:\n    check('canonical server response', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':' raw '},('r','b'):{'id':3,'edit_id':10,'value':'B'}}, {'row':'r','column':'a','request':2,'revision':8,'value':'raw'+str(2),'warning':'informational'}, {('r','a'):{'edit_id':9,'value':' raw '},('r','b'):{'edit_id':10,'value':'B'}}), {'row': {'id': 'r', 'a': 'raw2', 'revision': 8}, 'pending': [(('r', 'b'), {'id': 3, 'edit_id': 10, 'value': 'B'})], 'draft': [(('r', 'b'), {'edit_id': 10, 'value': 'B'})], 'error': None})\n    check('late old request', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':1,'revision':4,'value':'old ack'}, {}), {'row': {'id': 'r', 'a': 'old', 'revision': 3}, 'pending': [(('r', 'a'), {'id': 2, 'edit_id': 9, 'value': 'v'})], 'draft': [], 'error': None})\n    check('different row', solve({'id':'other','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack'}, {}), {'row': {'id': 'other', 'a': 'old', 'revision': 3}, 'pending': [(('r', 'a'), {'id': 2, 'edit_id': 9, 'value': 'v'})], 'draft': [], 'error': None})\n    check('empty error message', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack','error':''}, {('r','a'):{'edit_id':9,'value':'v'}}), {'row': {'id': 'r', 'a': 'old', 'revision': 3}, 'pending': [], 'draft': [(('r', 'a'), {'edit_id': 9, 'value': 'v'})], 'error': ''})\n    check('stale revision', solve({'id':'r','a':'new','revision':7}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':6,'value':'ack'}, {}), {'row': {'id': 'r', 'a': 'new', 'revision': 7}, 'pending': [], 'draft': [], 'error': 'stale'})\n    check('equal revision allowed', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':3,'value':'ack'}, {}), {'row': {'id': 'r', 'a': 'ack', 'revision': 3}, 'pending': [], 'draft': [], 'error': None})\n    check('new edit same value', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack'}, {('r','a'):{'edit_id':10,'value':'v'}}), {'row': {'id': 'r', 'a': 'ack', 'revision': 4}, 'pending': [], 'draft': [(('r', 'a'), {'edit_id': 10, 'value': 'v'})], 'error': None})\n\nif N == 3:\n    check('canonical server response', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':' raw '},('r','b'):{'id':3,'edit_id':10,'value':'B'}}, {'row':'r','column':'a','request':2,'revision':8,'value':'raw'+str(3),'warning':'informational'}, {('r','a'):{'edit_id':9,'value':' raw '},('r','b'):{'edit_id':10,'value':'B'}}), {'row': {'id': 'r', 'a': 'raw3', 'revision': 8}, 'pending': [(('r', 'b'), {'id': 3, 'edit_id': 10, 'value': 'B'})], 'draft': [(('r', 'b'), {'edit_id': 10, 'value': 'B'})], 'error': None})\n    check('late old request', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':1,'revision':4,'value':'old ack'}, {}), {'row': {'id': 'r', 'a': 'old', 'revision': 3}, 'pending': [(('r', 'a'), {'id': 2, 'edit_id': 9, 'value': 'v'})], 'draft': [], 'error': None})\n    check('different row', solve({'id':'other','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack'}, {}), {'row': {'id': 'other', 'a': 'old', 'revision': 3}, 'pending': [(('r', 'a'), {'id': 2, 'edit_id': 9, 'value': 'v'})], 'draft': [], 'error': None})\n    check('empty error message', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack','error':''}, {('r','a'):{'edit_id':9,'value':'v'}}), {'row': {'id': 'r', 'a': 'old', 'revision': 3}, 'pending': [], 'draft': [(('r', 'a'), {'edit_id': 9, 'value': 'v'})], 'error': ''})\n    check('stale revision', solve({'id':'r','a':'new','revision':7}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':6,'value':'ack'}, {}), {'row': {'id': 'r', 'a': 'new', 'revision': 7}, 'pending': [], 'draft': [], 'error': 'stale'})\n    check('equal revision allowed', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':3,'value':'ack'}, {}), {'row': {'id': 'r', 'a': 'ack', 'revision': 3}, 'pending': [], 'draft': [], 'error': None})\n    check('new edit same value', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack'}, {('r','a'):{'edit_id':10,'value':'v'}}), {'row': {'id': 'r', 'a': 'ack', 'revision': 4}, 'pending': [], 'draft': [(('r', 'a'), {'edit_id': 10, 'value': 'v'})], 'error': None})\n\nif N == 4:\n    check('canonical server response', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':' raw '},('r','b'):{'id':3,'edit_id':10,'value':'B'}}, {'row':'r','column':'a','request':2,'revision':8,'value':'raw'+str(4),'warning':'informational'}, {('r','a'):{'edit_id':9,'value':' raw '},('r','b'):{'edit_id':10,'value':'B'}}), {'row': {'id': 'r', 'a': 'raw4', 'revision': 8}, 'pending': [(('r', 'b'), {'id': 3, 'edit_id': 10, 'value': 'B'})], 'draft': [(('r', 'b'), {'edit_id': 10, 'value': 'B'})], 'error': None})\n    check('late old request', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':1,'revision':4,'value':'old ack'}, {}), {'row': {'id': 'r', 'a': 'old', 'revision': 3}, 'pending': [(('r', 'a'), {'id': 2, 'edit_id': 9, 'value': 'v'})], 'draft': [], 'error': None})\n    check('different row', solve({'id':'other','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack'}, {}), {'row': {'id': 'other', 'a': 'old', 'revision': 3}, 'pending': [(('r', 'a'), {'id': 2, 'edit_id': 9, 'value': 'v'})], 'draft': [], 'error': None})\n    check('empty error message', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack','error':''}, {('r','a'):{'edit_id':9,'value':'v'}}), {'row': {'id': 'r', 'a': 'old', 'revision': 3}, 'pending': [], 'draft': [(('r', 'a'), {'edit_id': 9, 'value': 'v'})], 'error': ''})\n    check('stale revision', solve({'id':'r','a':'new','revision':7}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':6,'value':'ack'}, {}), {'row': {'id': 'r', 'a': 'new', 'revision': 7}, 'pending': [], 'draft': [], 'error': 'stale'})\n    check('equal revision allowed', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':3,'value':'ack'}, {}), {'row': {'id': 'r', 'a': 'ack', 'revision': 3}, 'pending': [], 'draft': [], 'error': None})\n    check('new edit same value', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack'}, {('r','a'):{'edit_id':10,'value':'v'}}), {'row': {'id': 'r', 'a': 'ack', 'revision': 4}, 'pending': [], 'draft': [(('r', 'a'), {'edit_id': 10, 'value': 'v'})], 'error': None})\n\nif N == 5:\n    check('canonical server response', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':' raw '},('r','b'):{'id':3,'edit_id':10,'value':'B'}}, {'row':'r','column':'a','request':2,'revision':8,'value':'raw'+str(5),'warning':'informational'}, {('r','a'):{'edit_id':9,'value':' raw '},('r','b'):{'edit_id':10,'value':'B'}}), {'row': {'id': 'r', 'a': 'raw5', 'revision': 8}, 'pending': [(('r', 'b'), {'id': 3, 'edit_id': 10, 'value': 'B'})], 'draft': [(('r', 'b'), {'edit_id': 10, 'value': 'B'})], 'error': None})\n    check('late old request', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':1,'revision':4,'value':'old ack'}, {}), {'row': {'id': 'r', 'a': 'old', 'revision': 3}, 'pending': [(('r', 'a'), {'id': 2, 'edit_id': 9, 'value': 'v'})], 'draft': [], 'error': None})\n    check('different row', solve({'id':'other','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack'}, {}), {'row': {'id': 'other', 'a': 'old', 'revision': 3}, 'pending': [(('r', 'a'), {'id': 2, 'edit_id': 9, 'value': 'v'})], 'draft': [], 'error': None})\n    check('empty error message', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack','error':''}, {('r','a'):{'edit_id':9,'value':'v'}}), {'row': {'id': 'r', 'a': 'old', 'revision': 3}, 'pending': [], 'draft': [(('r', 'a'), {'edit_id': 9, 'value': 'v'})], 'error': ''})\n    check('stale revision', solve({'id':'r','a':'new','revision':7}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':6,'value':'ack'}, {}), {'row': {'id': 'r', 'a': 'new', 'revision': 7}, 'pending': [], 'draft': [], 'error': 'stale'})\n    check('equal revision allowed', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':3,'value':'ack'}, {}), {'row': {'id': 'r', 'a': 'ack', 'revision': 3}, 'pending': [], 'draft': [], 'error': None})\n    check('new edit same value', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack'}, {('r','a'):{'edit_id':10,'value':'v'}}), {'row': {'id': 'r', 'a': 'ack', 'revision': 4}, 'pending': [], 'draft': [(('r', 'a'), {'edit_id': 10, 'value': 'v'})], 'error': None})\n\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":"6abca38b7fcc658eece313d36360a0600cc1cbebc7f0467ae4a496fc7b71096b","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(row, pending, response, draft):\n    key=(response['row'],response['column'])\n    request=pending.get(key)\n    if request is None or request['id']!=response['request']: return {'row':row,'pending':sorted(pending.items()),'draft':sorted(draft.items()),'error':None}\n    if row['id']!=response['row']: return {'row':row,'pending':sorted(pending.items()),'draft':sorted(draft.items()),'error':None}\n    next_pending=dict(pending); next_pending.pop(key)\n    if response.get('error') is not None: return {'row':row,'pending':sorted(next_pending.items()),'draft':sorted(draft.items()),'error':response['error']}\n    out=dict(row)\n    if response['revision']<row['revision']: return {'row':out,'pending':sorted(next_pending.items()),'draft':sorted(draft.items()),'error':'stale'}\n    out[response['column']]=response['value']; out['revision']=response['revision']\n    next_draft=dict(draft)\n    if key in next_draft and next_draft[key]['edit_id']==request['edit_id']: next_draft.pop(key)\n    return {'row':out,'pending':sorted(next_pending.items()),'draft':sorted(next_draft.items()),'error':None}\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nif N == 1:\n    check('canonical server response', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':' raw '},('r','b'):{'id':3,'edit_id':10,'value':'B'}}, {'row':'r','column':'a','request':2,'revision':8,'value':'raw'+str(1),'warning':'informational'}, {('r','a'):{'edit_id':9,'value':' raw '},('r','b'):{'edit_id':10,'value':'B'}}), {'row': {'id': 'r', 'a': 'raw1', 'revision': 8}, 'pending': [(('r', 'b'), {'id': 3, 'edit_id': 10, 'value': 'B'})], 'draft': [(('r', 'b'), {'edit_id': 10, 'value': 'B'})], 'error': None})\n    check('late old request', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':1,'revision':4,'value':'old ack'}, {}), {'row': {'id': 'r', 'a': 'old', 'revision': 3}, 'pending': [(('r', 'a'), {'id': 2, 'edit_id': 9, 'value': 'v'})], 'draft': [], 'error': None})\n    check('different row', solve({'id':'other','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack'}, {}), {'row': {'id': 'other', 'a': 'old', 'revision': 3}, 'pending': [(('r', 'a'), {'id': 2, 'edit_id': 9, 'value': 'v'})], 'draft': [], 'error': None})\n    check('empty error message', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack','error':''}, {('r','a'):{'edit_id':9,'value':'v'}}), {'row': {'id': 'r', 'a': 'old', 'revision': 3}, 'pending': [], 'draft': [(('r', 'a'), {'edit_id': 9, 'value': 'v'})], 'error': ''})\n    check('stale revision', solve({'id':'r','a':'new','revision':7}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':6,'value':'ack'}, {}), {'row': {'id': 'r', 'a': 'new', 'revision': 7}, 'pending': [], 'draft': [], 'error': 'stale'})\n    check('equal revision allowed', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':3,'value':'ack'}, {}), {'row': {'id': 'r', 'a': 'ack', 'revision': 3}, 'pending': [], 'draft': [], 'error': None})\n    check('new edit same value', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack'}, {('r','a'):{'edit_id':10,'value':'v'}}), {'row': {'id': 'r', 'a': 'ack', 'revision': 4}, 'pending': [], 'draft': [(('r', 'a'), {'edit_id': 10, 'value': 'v'})], 'error': None})\n\nif N == 2:\n    check('canonical server response', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':' raw '},('r','b'):{'id':3,'edit_id':10,'value':'B'}}, {'row':'r','column':'a','request':2,'revision':8,'value':'raw'+str(2),'warning':'informational'}, {('r','a'):{'edit_id':9,'value':' raw '},('r','b'):{'edit_id':10,'value':'B'}}), {'row': {'id': 'r', 'a': 'raw2', 'revision': 8}, 'pending': [(('r', 'b'), {'id': 3, 'edit_id': 10, 'value': 'B'})], 'draft': [(('r', 'b'), {'edit_id': 10, 'value': 'B'})], 'error': None})\n    check('late old request', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':1,'revision':4,'value':'old ack'}, {}), {'row': {'id': 'r', 'a': 'old', 'revision': 3}, 'pending': [(('r', 'a'), {'id': 2, 'edit_id': 9, 'value': 'v'})], 'draft': [], 'error': None})\n    check('different row', solve({'id':'other','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack'}, {}), {'row': {'id': 'other', 'a': 'old', 'revision': 3}, 'pending': [(('r', 'a'), {'id': 2, 'edit_id': 9, 'value': 'v'})], 'draft': [], 'error': None})\n    check('empty error message', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack','error':''}, {('r','a'):{'edit_id':9,'value':'v'}}), {'row': {'id': 'r', 'a': 'old', 'revision': 3}, 'pending': [], 'draft': [(('r', 'a'), {'edit_id': 9, 'value': 'v'})], 'error': ''})\n    check('stale revision', solve({'id':'r','a':'new','revision':7}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':6,'value':'ack'}, {}), {'row': {'id': 'r', 'a': 'new', 'revision': 7}, 'pending': [], 'draft': [], 'error': 'stale'})\n    check('equal revision allowed', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':3,'value':'ack'}, {}), {'row': {'id': 'r', 'a': 'ack', 'revision': 3}, 'pending': [], 'draft': [], 'error': None})\n    check('new edit same value', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack'}, {('r','a'):{'edit_id':10,'value':'v'}}), {'row': {'id': 'r', 'a': 'ack', 'revision': 4}, 'pending': [], 'draft': [(('r', 'a'), {'edit_id': 10, 'value': 'v'})], 'error': None})\n\nif N == 3:\n    check('canonical server response', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':' raw '},('r','b'):{'id':3,'edit_id':10,'value':'B'}}, {'row':'r','column':'a','request':2,'revision':8,'value':'raw'+str(3),'warning':'informational'}, {('r','a'):{'edit_id':9,'value':' raw '},('r','b'):{'edit_id':10,'value':'B'}}), {'row': {'id': 'r', 'a': 'raw3', 'revision': 8}, 'pending': [(('r', 'b'), {'id': 3, 'edit_id': 10, 'value': 'B'})], 'draft': [(('r', 'b'), {'edit_id': 10, 'value': 'B'})], 'error': None})\n    check('late old request', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':1,'revision':4,'value':'old ack'}, {}), {'row': {'id': 'r', 'a': 'old', 'revision': 3}, 'pending': [(('r', 'a'), {'id': 2, 'edit_id': 9, 'value': 'v'})], 'draft': [], 'error': None})\n    check('different row', solve({'id':'other','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack'}, {}), {'row': {'id': 'other', 'a': 'old', 'revision': 3}, 'pending': [(('r', 'a'), {'id': 2, 'edit_id': 9, 'value': 'v'})], 'draft': [], 'error': None})\n    check('empty error message', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack','error':''}, {('r','a'):{'edit_id':9,'value':'v'}}), {'row': {'id': 'r', 'a': 'old', 'revision': 3}, 'pending': [], 'draft': [(('r', 'a'), {'edit_id': 9, 'value': 'v'})], 'error': ''})\n    check('stale revision', solve({'id':'r','a':'new','revision':7}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':6,'value':'ack'}, {}), {'row': {'id': 'r', 'a': 'new', 'revision': 7}, 'pending': [], 'draft': [], 'error': 'stale'})\n    check('equal revision allowed', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':3,'value':'ack'}, {}), {'row': {'id': 'r', 'a': 'ack', 'revision': 3}, 'pending': [], 'draft': [], 'error': None})\n    check('new edit same value', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack'}, {('r','a'):{'edit_id':10,'value':'v'}}), {'row': {'id': 'r', 'a': 'ack', 'revision': 4}, 'pending': [], 'draft': [(('r', 'a'), {'edit_id': 10, 'value': 'v'})], 'error': None})\n\nif N == 4:\n    check('canonical server response', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':' raw '},('r','b'):{'id':3,'edit_id':10,'value':'B'}}, {'row':'r','column':'a','request':2,'revision':8,'value':'raw'+str(4),'warning':'informational'}, {('r','a'):{'edit_id':9,'value':' raw '},('r','b'):{'edit_id':10,'value':'B'}}), {'row': {'id': 'r', 'a': 'raw4', 'revision': 8}, 'pending': [(('r', 'b'), {'id': 3, 'edit_id': 10, 'value': 'B'})], 'draft': [(('r', 'b'), {'edit_id': 10, 'value': 'B'})], 'error': None})\n    check('late old request', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':1,'revision':4,'value':'old ack'}, {}), {'row': {'id': 'r', 'a': 'old', 'revision': 3}, 'pending': [(('r', 'a'), {'id': 2, 'edit_id': 9, 'value': 'v'})], 'draft': [], 'error': None})\n    check('different row', solve({'id':'other','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack'}, {}), {'row': {'id': 'other', 'a': 'old', 'revision': 3}, 'pending': [(('r', 'a'), {'id': 2, 'edit_id': 9, 'value': 'v'})], 'draft': [], 'error': None})\n    check('empty error message', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack','error':''}, {('r','a'):{'edit_id':9,'value':'v'}}), {'row': {'id': 'r', 'a': 'old', 'revision': 3}, 'pending': [], 'draft': [(('r', 'a'), {'edit_id': 9, 'value': 'v'})], 'error': ''})\n    check('stale revision', solve({'id':'r','a':'new','revision':7}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':6,'value':'ack'}, {}), {'row': {'id': 'r', 'a': 'new', 'revision': 7}, 'pending': [], 'draft': [], 'error': 'stale'})\n    check('equal revision allowed', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':3,'value':'ack'}, {}), {'row': {'id': 'r', 'a': 'ack', 'revision': 3}, 'pending': [], 'draft': [], 'error': None})\n    check('new edit same value', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack'}, {('r','a'):{'edit_id':10,'value':'v'}}), {'row': {'id': 'r', 'a': 'ack', 'revision': 4}, 'pending': [], 'draft': [(('r', 'a'), {'edit_id': 10, 'value': 'v'})], 'error': None})\n\nif N == 5:\n    check('canonical server response', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':' raw '},('r','b'):{'id':3,'edit_id':10,'value':'B'}}, {'row':'r','column':'a','request':2,'revision':8,'value':'raw'+str(5),'warning':'informational'}, {('r','a'):{'edit_id':9,'value':' raw '},('r','b'):{'edit_id':10,'value':'B'}}), {'row': {'id': 'r', 'a': 'raw5', 'revision': 8}, 'pending': [(('r', 'b'), {'id': 3, 'edit_id': 10, 'value': 'B'})], 'draft': [(('r', 'b'), {'edit_id': 10, 'value': 'B'})], 'error': None})\n    check('late old request', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':1,'revision':4,'value':'old ack'}, {}), {'row': {'id': 'r', 'a': 'old', 'revision': 3}, 'pending': [(('r', 'a'), {'id': 2, 'edit_id': 9, 'value': 'v'})], 'draft': [], 'error': None})\n    check('different row', solve({'id':'other','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack'}, {}), {'row': {'id': 'other', 'a': 'old', 'revision': 3}, 'pending': [(('r', 'a'), {'id': 2, 'edit_id': 9, 'value': 'v'})], 'draft': [], 'error': None})\n    check('empty error message', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack','error':''}, {('r','a'):{'edit_id':9,'value':'v'}}), {'row': {'id': 'r', 'a': 'old', 'revision': 3}, 'pending': [], 'draft': [(('r', 'a'), {'edit_id': 9, 'value': 'v'})], 'error': ''})\n    check('stale revision', solve({'id':'r','a':'new','revision':7}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':6,'value':'ack'}, {}), {'row': {'id': 'r', 'a': 'new', 'revision': 7}, 'pending': [], 'draft': [], 'error': 'stale'})\n    check('equal revision allowed', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':3,'value':'ack'}, {}), {'row': {'id': 'r', 'a': 'ack', 'revision': 3}, 'pending': [], 'draft': [], 'error': None})\n    check('new edit same value', solve({'id':'r','a':'old','revision':3}, {('r','a'):{'id':2,'edit_id':9,'value':'v'}}, {'row':'r','column':'a','request':2,'revision':4,'value':'ack'}, {('r','a'):{'edit_id':10,'value':'v'}}), {'row': {'id': 'r', 'a': 'ack', 'revision': 4}, 'pending': [], 'draft': [(('r', 'a'), {'edit_id': 10, 'value': 'v'})], 'error': None})\n\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":"Pending entries and matching drafts are well-formed; revisions are integers. Pair-keyed maps serialize as sorted pairs. Deterministic offline table UI model; no browser, DOM, framework, or standards conformance is claimed. 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":"s3-table-interactions-async-cell-save-ack-server-revision","generated_at":"2026-09-29T14:43:08.519503+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"An offline table UI model isolates asynchronous table cell save acknowledgement, including adversarial row/column relationships.","repair":"Apply the complete ack server revision rule: out['revision']=response['revision'].","root_cause":"The ack server revision decision uses \"out['revision']=row['revision']+1\" instead of \"out['revision']=response['revision']\".","sha256":"102a9583c143a8fb298b9140affbed13c7edad02ca9c7a397dfb1225f9f9d188","title":"Asynchronous table cell save acknowledgement: ack server revision · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":44.805,"exit_code":1,"observations":[{"actual":{"draft":[[["r","b"],{"edit_id":10,"value":"B"}]],"error":null,"pending":[[["r","b"],{"edit_id":10,"id":3,"value":"B"}]],"row":{"a":"raw1","id":"r","revision":3}},"check":"canonical server response","expected":{"draft":[[["r","b"],{"edit_id":10,"value":"B"}]],"error":null,"pending":[[["r","b"],{"edit_id":10,"id":3,"value":"B"}]],"row":{"a":"raw1","id":"r","revision":8}},"passed":false},{"actual":{"draft":[],"error":null,"pending":[[["r","a"],{"edit_id":9,"id":2,"value":"v"}]],"row":{"a":"old","id":"r","revision":3}},"check":"late old request","expected":{"draft":[],"error":null,"pending":[[["r","a"],{"edit_id":9,"id":2,"value":"v"}]],"row":{"a":"old","id":"r","revision":3}},"passed":true},{"actual":{"draft":[],"error":null,"pending":[[["r","a"],{"edit_id":9,"id":2,"value":"v"}]],"row":{"a":"old","id":"other","revision":3}},"check":"different row","expected":{"draft":[],"error":null,"pending":[[["r","a"],{"edit_id":9,"id":2,"value":"v"}]],"row":{"a":"old","id":"other","revision":3}},"passed":true},{"actual":{"draft":[[["r","a"],{"edit_id":9,"value":"v"}]],"error":"","pending":[],"row":{"a":"old","id":"r","revision":3}},"check":"empty error message","expected":{"draft":[[["r","a"],{"edit_id":9,"value":"v"}]],"error":"","pending":[],"row":{"a":"old","id":"r","revision":3}},"passed":true},{"actual":{"draft":[],"error":"stale","pending":[],"row":{"a":"new","id":"r","revision":7}},"check":"stale revision","expected":{"draft":[],"error":"stale","pending":[],"row":{"a":"new","id":"r","revision":7}},"passed":true},{"actual":{"draft":[],"error":null,"pending":[],"row":{"a":"ack","id":"r","revision":3}},"check":"equal revision allowed","expected":{"draft":[],"error":null,"pending":[],"row":{"a":"ack","id":"r","revision":3}},"passed":true},{"actual":{"draft":[[["r","a"],{"edit_id":10,"value":"v"}]],"error":null,"pending":[],"row":{"a":"ack","id":"r","revision":3}},"check":"new edit same value","expected":{"draft":[[["r","a"],{"edit_id":10,"value":"v"}]],"error":null,"pending":[],"row":{"a":"ack","id":"r","revision":4}},"passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"canonical server response\", \"actual\": {\"row\": {\"id\": \"r\", \"a\": \"raw1\", \"revision\": 3}, \"pending\": [[[\"r\", \"b\"], {\"id\": 3, \"edit_id\": 10, \"value\": \"B\"}]], \"draft\": [[[\"r\", \"b\"], {\"edit_id\": 10, \"value\": \"B\"}]], \"error\": null}, \"expected\": {\"row\": {\"id\": \"r\", \"a\": \"raw1\", \"revision\": 8}, \"pending\": [[[\"r\", \"b\"], {\"id\": 3, \"edit_id\": 10, \"value\": \"B\"}]], \"draft\": [[[\"r\", \"b\"], {\"edit_id\": 10, \"value\": \"B\"}]], \"error\": null}, \"passed\": false}, {\"check\": \"late old request\", \"actual\": {\"row\": {\"id\": \"r\", \"a\": \"old\", \"revision\": 3}, \"pending\": [[[\"r\", \"a\"], {\"id\": 2, \"edit_id\": 9, \"value\": \"v\"}]], \"draft\": [], \"error\": null}, \"expected\": {\"row\": {\"id\": \"r\", \"a\": \"old\", \"revision\": 3}, \"pending\": [[[\"r\", \"a\"], {\"id\": 2, \"edit_id\": 9, \"value\": \"v\"}]], \"draft\": [], \"error\": null}, \"passed\": true}, {\"check\": \"different row\", \"actual\": {\"row\": {\"id\": \"other\", \"a\": \"old\", \"revision\": 3}, \"pending\": [[[\"r\", \"a\"], {\"id\": 2, \"edit_id\": 9, \"value\": \"v\"}]], \"draft\": [], \"error\": null}, \"expected\": {\"row\": {\"id\": \"other\", \"a\": \"old\", \"revision\": 3}, \"pending\": [[[\"r\", \"a\"], {\"id\": 2, \"edit_id\": 9, \"value\": \"v\"}]], \"draft\": [], \"error\": null}, \"passed\": true}, {\"check\": \"empty error message\", \"actual\": {\"row\": {\"id\": \"r\", \"a\": \"old\", \"revision\": 3}, \"pending\": [], \"draft\": [[[\"r\", \"a\"], {\"edit_id\": 9, \"value\": \"v\"}]], \"error\": \"\"}, \"expected\": {\"row\": {\"id\": \"r\", \"a\": \"old\", \"revision\": 3}, \"pending\": [], \"draft\": [[[\"r\", \"a\"], {\"edit_id\": 9, \"value\": \"v\"}]], \"error\": \"\"}, \"passed\": true}, {\"check\": \"stale revision\", \"actual\": {\"row\": {\"id\": \"r\", \"a\": \"new\", \"revision\": 7}, \"pending\": [], \"draft\": [], \"error\": \"stale\"}, \"expected\": {\"row\": {\"id\": \"r\", \"a\": \"new\", \"revision\": 7}, \"pending\": [], \"draft\": [], \"error\": \"stale\"}, \"passed\": true}, {\"check\": \"equal revision allowed\", \"actual\": {\"row\": {\"id\": \"r\", \"a\": \"ack\", \"revision\": 3}, \"pending\": [], \"draft\": [], \"error\": null}, \"expected\": {\"row\": {\"id\": \"r\", \"a\": \"ack\", \"revision\": 3}, \"pending\": [], \"draft\": [], \"error\": null}, \"passed\": true}, {\"check\": \"new edit same value\", \"actual\": {\"row\": {\"id\": \"r\", \"a\": \"ack\", \"revision\": 3}, \"pending\": [], \"draft\": [[[\"r\", \"a\"], {\"edit_id\": 10, \"value\": \"v\"}]], \"error\": null}, \"expected\": {\"row\": {\"id\": \"r\", \"a\": \"ack\", \"revision\": 4}, \"pending\": [], \"draft\": [[[\"r\", \"a\"], {\"edit_id\": 10, \"value\": \"v\"}]], \"error\": null}, \"passed\": false}], \"passed\": false}\n"},"broken":{"elapsed_ms":43.277,"exit_code":1,"observations":[{"actual":{"draft":[[["r","b"],{"edit_id":10,"value":"B"}]],"error":null,"pending":[[["r","b"],{"edit_id":10,"id":3,"value":"B"}]],"row":{"a":"raw1","id":"r","revision":4}},"check":"canonical server response","expected":{"draft":[[["r","b"],{"edit_id":10,"value":"B"}]],"error":null,"pending":[[["r","b"],{"edit_id":10,"id":3,"value":"B"}]],"row":{"a":"raw1","id":"r","revision":8}},"passed":false},{"actual":{"draft":[],"error":null,"pending":[[["r","a"],{"edit_id":9,"id":2,"value":"v"}]],"row":{"a":"old","id":"r","revision":3}},"check":"late old request","expected":{"draft":[],"error":null,"pending":[[["r","a"],{"edit_id":9,"id":2,"value":"v"}]],"row":{"a":"old","id":"r","revision":3}},"passed":true},{"actual":{"draft":[],"error":null,"pending":[[["r","a"],{"edit_id":9,"id":2,"value":"v"}]],"row":{"a":"old","id":"other","revision":3}},"check":"different row","expected":{"draft":[],"error":null,"pending":[[["r","a"],{"edit_id":9,"id":2,"value":"v"}]],"row":{"a":"old","id":"other","revision":3}},"passed":true},{"actual":{"draft":[[["r","a"],{"edit_id":9,"value":"v"}]],"error":"","pending":[],"row":{"a":"old","id":"r","revision":3}},"check":"empty error message","expected":{"draft":[[["r","a"],{"edit_id":9,"value":"v"}]],"error":"","pending":[],"row":{"a":"old","id":"r","revision":3}},"passed":true},{"actual":{"draft":[],"error":"stale","pending":[],"row":{"a":"new","id":"r","revision":7}},"check":"stale revision","expected":{"draft":[],"error":"stale","pending":[],"row":{"a":"new","id":"r","revision":7}},"passed":true},{"actual":{"draft":[],"error":null,"pending":[],"row":{"a":"ack","id":"r","revision":4}},"check":"equal revision allowed","expected":{"draft":[],"error":null,"pending":[],"row":{"a":"ack","id":"r","revision":3}},"passed":false},{"actual":{"draft":[[["r","a"],{"edit_id":10,"value":"v"}]],"error":null,"pending":[],"row":{"a":"ack","id":"r","revision":4}},"check":"new edit same value","expected":{"draft":[[["r","a"],{"edit_id":10,"value":"v"}]],"error":null,"pending":[],"row":{"a":"ack","id":"r","revision":4}},"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"canonical server response\", \"actual\": {\"row\": {\"id\": \"r\", \"a\": \"raw1\", \"revision\": 4}, \"pending\": [[[\"r\", \"b\"], {\"id\": 3, \"edit_id\": 10, \"value\": \"B\"}]], \"draft\": [[[\"r\", \"b\"], {\"edit_id\": 10, \"value\": \"B\"}]], \"error\": null}, \"expected\": {\"row\": {\"id\": \"r\", \"a\": \"raw1\", \"revision\": 8}, \"pending\": [[[\"r\", \"b\"], {\"id\": 3, \"edit_id\": 10, \"value\": \"B\"}]], \"draft\": [[[\"r\", \"b\"], {\"edit_id\": 10, \"value\": \"B\"}]], \"error\": null}, \"passed\": false}, {\"check\": \"late old request\", \"actual\": {\"row\": {\"id\": \"r\", \"a\": \"old\", \"revision\": 3}, \"pending\": [[[\"r\", \"a\"], {\"id\": 2, \"edit_id\": 9, \"value\": \"v\"}]], \"draft\": [], \"error\": null}, \"expected\": {\"row\": {\"id\": \"r\", \"a\": \"old\", \"revision\": 3}, \"pending\": [[[\"r\", \"a\"], {\"id\": 2, \"edit_id\": 9, \"value\": \"v\"}]], \"draft\": [], \"error\": null}, \"passed\": true}, {\"check\": \"different row\", \"actual\": {\"row\": {\"id\": \"other\", \"a\": \"old\", \"revision\": 3}, \"pending\": [[[\"r\", \"a\"], {\"id\": 2, \"edit_id\": 9, \"value\": \"v\"}]], \"draft\": [], \"error\": null}, \"expected\": {\"row\": {\"id\": \"other\", \"a\": \"old\", \"revision\": 3}, \"pending\": [[[\"r\", \"a\"], {\"id\": 2, \"edit_id\": 9, \"value\": \"v\"}]], \"draft\": [], \"error\": null}, \"passed\": true}, {\"check\": \"empty error message\", \"actual\": {\"row\": {\"id\": \"r\", \"a\": \"old\", \"revision\": 3}, \"pending\": [], \"draft\": [[[\"r\", \"a\"], {\"edit_id\": 9, \"value\": \"v\"}]], \"error\": \"\"}, \"expected\": {\"row\": {\"id\": \"r\", \"a\": \"old\", \"revision\": 3}, \"pending\": [], \"draft\": [[[\"r\", \"a\"], {\"edit_id\": 9, \"value\": \"v\"}]], \"error\": \"\"}, \"passed\": true}, {\"check\": \"stale revision\", \"actual\": {\"row\": {\"id\": \"r\", \"a\": \"new\", \"revision\": 7}, \"pending\": [], \"draft\": [], \"error\": \"stale\"}, \"expected\": {\"row\": {\"id\": \"r\", \"a\": \"new\", \"revision\": 7}, \"pending\": [], \"draft\": [], \"error\": \"stale\"}, \"passed\": true}, {\"check\": \"equal revision allowed\", \"actual\": {\"row\": {\"id\": \"r\", \"a\": \"ack\", \"revision\": 4}, \"pending\": [], \"draft\": [], \"error\": null}, \"expected\": {\"row\": {\"id\": \"r\", \"a\": \"ack\", \"revision\": 3}, \"pending\": [], \"draft\": [], \"error\": null}, \"passed\": false}, {\"check\": \"new edit same value\", \"actual\": {\"row\": {\"id\": \"r\", \"a\": \"ack\", \"revision\": 4}, \"pending\": [], \"draft\": [[[\"r\", \"a\"], {\"edit_id\": 10, \"value\": \"v\"}]], \"error\": null}, \"expected\": {\"row\": {\"id\": \"r\", \"a\": \"ack\", \"revision\": 4}, \"pending\": [], \"draft\": [[[\"r\", \"a\"], {\"edit_id\": 10, \"value\": \"v\"}]], \"error\": null}, \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":44.119,"exit_code":0,"observations":[{"actual":{"draft":[[["r","b"],{"edit_id":10,"value":"B"}]],"error":null,"pending":[[["r","b"],{"edit_id":10,"id":3,"value":"B"}]],"row":{"a":"raw1","id":"r","revision":8}},"check":"canonical server response","expected":{"draft":[[["r","b"],{"edit_id":10,"value":"B"}]],"error":null,"pending":[[["r","b"],{"edit_id":10,"id":3,"value":"B"}]],"row":{"a":"raw1","id":"r","revision":8}},"passed":true},{"actual":{"draft":[],"error":null,"pending":[[["r","a"],{"edit_id":9,"id":2,"value":"v"}]],"row":{"a":"old","id":"r","revision":3}},"check":"late old request","expected":{"draft":[],"error":null,"pending":[[["r","a"],{"edit_id":9,"id":2,"value":"v"}]],"row":{"a":"old","id":"r","revision":3}},"passed":true},{"actual":{"draft":[],"error":null,"pending":[[["r","a"],{"edit_id":9,"id":2,"value":"v"}]],"row":{"a":"old","id":"other","revision":3}},"check":"different row","expected":{"draft":[],"error":null,"pending":[[["r","a"],{"edit_id":9,"id":2,"value":"v"}]],"row":{"a":"old","id":"other","revision":3}},"passed":true},{"actual":{"draft":[[["r","a"],{"edit_id":9,"value":"v"}]],"error":"","pending":[],"row":{"a":"old","id":"r","revision":3}},"check":"empty error message","expected":{"draft":[[["r","a"],{"edit_id":9,"value":"v"}]],"error":"","pending":[],"row":{"a":"old","id":"r","revision":3}},"passed":true},{"actual":{"draft":[],"error":"stale","pending":[],"row":{"a":"new","id":"r","revision":7}},"check":"stale revision","expected":{"draft":[],"error":"stale","pending":[],"row":{"a":"new","id":"r","revision":7}},"passed":true},{"actual":{"draft":[],"error":null,"pending":[],"row":{"a":"ack","id":"r","revision":3}},"check":"equal revision allowed","expected":{"draft":[],"error":null,"pending":[],"row":{"a":"ack","id":"r","revision":3}},"passed":true},{"actual":{"draft":[[["r","a"],{"edit_id":10,"value":"v"}]],"error":null,"pending":[],"row":{"a":"ack","id":"r","revision":4}},"check":"new edit same value","expected":{"draft":[[["r","a"],{"edit_id":10,"value":"v"}]],"error":null,"pending":[],"row":{"a":"ack","id":"r","revision":4}},"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"canonical server response\", \"actual\": {\"row\": {\"id\": \"r\", \"a\": \"raw1\", \"revision\": 8}, \"pending\": [[[\"r\", \"b\"], {\"id\": 3, \"edit_id\": 10, \"value\": \"B\"}]], \"draft\": [[[\"r\", \"b\"], {\"edit_id\": 10, \"value\": \"B\"}]], \"error\": null}, \"expected\": {\"row\": {\"id\": \"r\", \"a\": \"raw1\", \"revision\": 8}, \"pending\": [[[\"r\", \"b\"], {\"id\": 3, \"edit_id\": 10, \"value\": \"B\"}]], \"draft\": [[[\"r\", \"b\"], {\"edit_id\": 10, \"value\": \"B\"}]], \"error\": null}, \"passed\": true}, {\"check\": \"late old request\", \"actual\": {\"row\": {\"id\": \"r\", \"a\": \"old\", \"revision\": 3}, \"pending\": [[[\"r\", \"a\"], {\"id\": 2, \"edit_id\": 9, \"value\": \"v\"}]], \"draft\": [], \"error\": null}, \"expected\": {\"row\": {\"id\": \"r\", \"a\": \"old\", \"revision\": 3}, \"pending\": [[[\"r\", \"a\"], {\"id\": 2, \"edit_id\": 9, \"value\": \"v\"}]], \"draft\": [], \"error\": null}, \"passed\": true}, {\"check\": \"different row\", \"actual\": {\"row\": {\"id\": \"other\", \"a\": \"old\", \"revision\": 3}, \"pending\": [[[\"r\", \"a\"], {\"id\": 2, \"edit_id\": 9, \"value\": \"v\"}]], \"draft\": [], \"error\": null}, \"expected\": {\"row\": {\"id\": \"other\", \"a\": \"old\", \"revision\": 3}, \"pending\": [[[\"r\", \"a\"], {\"id\": 2, \"edit_id\": 9, \"value\": \"v\"}]], \"draft\": [], \"error\": null}, \"passed\": true}, {\"check\": \"empty error message\", \"actual\": {\"row\": {\"id\": \"r\", \"a\": \"old\", \"revision\": 3}, \"pending\": [], \"draft\": [[[\"r\", \"a\"], {\"edit_id\": 9, \"value\": \"v\"}]], \"error\": \"\"}, \"expected\": {\"row\": {\"id\": \"r\", \"a\": \"old\", \"revision\": 3}, \"pending\": [], \"draft\": [[[\"r\", \"a\"], {\"edit_id\": 9, \"value\": \"v\"}]], \"error\": \"\"}, \"passed\": true}, {\"check\": \"stale revision\", \"actual\": {\"row\": {\"id\": \"r\", \"a\": \"new\", \"revision\": 7}, \"pending\": [], \"draft\": [], \"error\": \"stale\"}, \"expected\": {\"row\": {\"id\": \"r\", \"a\": \"new\", \"revision\": 7}, \"pending\": [], \"draft\": [], \"error\": \"stale\"}, \"passed\": true}, {\"check\": \"equal revision allowed\", \"actual\": {\"row\": {\"id\": \"r\", \"a\": \"ack\", \"revision\": 3}, \"pending\": [], \"draft\": [], \"error\": null}, \"expected\": {\"row\": {\"id\": \"r\", \"a\": \"ack\", \"revision\": 3}, \"pending\": [], \"draft\": [], \"error\": null}, \"passed\": true}, {\"check\": \"new edit same value\", \"actual\": {\"row\": {\"id\": \"r\", \"a\": \"ack\", \"revision\": 4}, \"pending\": [], \"draft\": [[[\"r\", \"a\"], {\"edit_id\": 10, \"value\": \"v\"}]], \"error\": null}, \"expected\": {\"row\": {\"id\": \"r\", \"a\": \"ack\", \"revision\": 4}, \"pending\": [], \"draft\": [[[\"r\", \"a\"], {\"edit_id\": 10, \"value\": \"v\"}]], \"error\": null}, \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}