{"abstract":"The second and later reformatted lines are credited to the reformatting commit, and duplicates inherit the wrong commit.","category":"Text diff and three-way merge","checks":8,"contract":"Given the old file's per-line commit annotations and an edit script, produce annotations for the new file: context lines keep their old annotation, added lines get the new commit. With ignore_ws, within a run of removed lines followed by added lines, the i-th added line keeps the i-th removed line's annotation when both are equal after deleting all whitespace.","evaluation_group":"w2-text-diff-merge-blame-propagation","failed_approach":"Searching the whole removed run for a whitespace-equal line lets one removed line lend its commit to several added lines.","family":"w2-text-diff-merge-blame-propagation-positional-pairing","id":"FA-75741","implementations":{"attempt":{"sha256":"e8e2591d0cf4fe79c7b34b5bf784eb667cdee8a1d27a6419889191f3ba6bff1a","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(ann, ops, commit, ignore_ws):\n    res = []\n    i = 0\n    k = 0\n    while k < len(ops):\n        tag = ops[k][0]\n        if tag == ' ':\n            res.append(ann[i])\n            i += 1\n            k += 1\n            continue\n        dels = []\n        while k < len(ops) and ops[k][0] == '-':\n            dels.append((ann[i], ops[k][1]))\n            i += 1\n            k += 1\n        adds = []\n        while k < len(ops) and ops[k][0] == '+':\n            adds.append(ops[k][1])\n            k += 1\n        for idx, text in enumerate(adds):\n            same = [d for d in dels if ''.join(d[1].split()) == ''.join(text.split())]\n            if ignore_ws and same:\n                res.append(same[0][0])\n            else:\n                res.append(commit)\n    return res\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncases = {\n    1: [('context keeps attribution', [['c1', 'c2', 'c3'], [[' ', 'a'], ['-', 'b'], [' ', 'c']], 'N', False], ['c1', 'c3']), ('insertion attributed to the new commit', [['c1', 'c2'], [[' ', 'a'], ['+', 'x'], [' ', 'b']], 'N', False], ['c1', 'N', 'c2']), ('removed lines advance the old cursor', [['c1', 'c2', 'c3', 'c4'], [['-', 'a'], ['-', 'b'], [' ', 'c'], [' ', 'd']], 'N', True], ['c3', 'c4']), ('whitespace-only change keeps blame when ignoring whitespace', [['c1', 'c2'], [['-', 'f(a,b)'], ['+', 'f(a, b)'], [' ', 'z']], 'N', True], ['c1', 'c2']), ('whitespace-only change is new without the flag', [['c1', 'c2'], [['-', 'f(a,b)'], ['+', 'f(a, b)'], [' ', 'z']], 'N', False], ['N', 'c2']), ('second pair compared positionally', [['c1', 'c2', 'c3'], [['-', 'x = 1'], ['-', 'y = 2'], ['+', 'x=1'], ['+', 'y =  2'], [' ', 'k']], 'N1', True], ['c1', 'c2', 'c3']), ('extra additions are new', [['c1', 'c2'], [['-', 'p'], ['+', 'p '], ['+', 'p'], [' ', 'q']], 'N', True], ['c1', 'N', 'c2']), ('real change within a whitespace block', [['c1', 'c2', 'c3'], [['-', 'u'], ['-', 'v'], ['+', 'u'], ['+', 'w'], [' ', 't']], 'N', True], ['c1', 'N', 'c3'])],\n    2: [('context keeps attribution', [['c1', 'c2', 'c3'], [[' ', 'a'], ['-', 'b'], [' ', 'c']], 'N', False], ['c1', 'c3']), ('insertion attributed to the new commit', [['c1', 'c2'], [[' ', 'a'], ['+', 'x'], [' ', 'b']], 'N', False], ['c1', 'N', 'c2']), ('removed lines advance the old cursor', [['c1', 'c2', 'c3', 'c4'], [['-', 'a'], ['-', 'b'], [' ', 'c'], [' ', 'd']], 'N', True], ['c3', 'c4']), ('whitespace-only change keeps blame when ignoring whitespace', [['c1', 'c2'], [['-', 'f(a,b)'], ['+', 'f(a, b)'], [' ', 'z']], 'N', True], ['c1', 'c2']), ('whitespace-only change is new without the flag', [['c1', 'c2'], [['-', 'f(a,b)'], ['+', 'f(a, b)'], [' ', 'z']], 'N', False], ['N', 'c2']), ('second pair compared positionally', [['c1', 'c2', 'c3'], [['-', 'x = 1'], ['-', 'y = 2'], ['+', 'x=1'], ['+', 'y =  2'], [' ', 'k']], 'N2', True], ['c1', 'c2', 'c3']), ('extra additions are new', [['c1', 'c2'], [['-', 'p'], ['+', 'p '], ['+', 'p'], [' ', 'q']], 'N', True], ['c1', 'N', 'c2']), ('real change within a whitespace block', [['c1', 'c2', 'c3'], [['-', 'u'], ['-', 'v'], ['+', 'u'], ['+', 'w'], [' ', 't']], 'N', True], ['c1', 'N', 'c3'])],\n    3: [('context keeps attribution', [['c1', 'c2', 'c3'], [[' ', 'a'], ['-', 'b'], [' ', 'c']], 'N', False], ['c1', 'c3']), ('insertion attributed to the new commit', [['c1', 'c2'], [[' ', 'a'], ['+', 'x'], [' ', 'b']], 'N', False], ['c1', 'N', 'c2']), ('removed lines advance the old cursor', [['c1', 'c2', 'c3', 'c4'], [['-', 'a'], ['-', 'b'], [' ', 'c'], [' ', 'd']], 'N', True], ['c3', 'c4']), ('whitespace-only change keeps blame when ignoring whitespace', [['c1', 'c2'], [['-', 'f(a,b)'], ['+', 'f(a, b)'], [' ', 'z']], 'N', True], ['c1', 'c2']), ('whitespace-only change is new without the flag', [['c1', 'c2'], [['-', 'f(a,b)'], ['+', 'f(a, b)'], [' ', 'z']], 'N', False], ['N', 'c2']), ('second pair compared positionally', [['c1', 'c2', 'c3'], [['-', 'x = 1'], ['-', 'y = 2'], ['+', 'x=1'], ['+', 'y =  2'], [' ', 'k']], 'N3', True], ['c1', 'c2', 'c3']), ('extra additions are new', [['c1', 'c2'], [['-', 'p'], ['+', 'p '], ['+', 'p'], [' ', 'q']], 'N', True], ['c1', 'N', 'c2']), ('real change within a whitespace block', [['c1', 'c2', 'c3'], [['-', 'u'], ['-', 'v'], ['+', 'u'], ['+', 'w'], [' ', 't']], 'N', True], ['c1', 'N', 'c3'])],\n    4: [('context keeps attribution', [['c1', 'c2', 'c3'], [[' ', 'a'], ['-', 'b'], [' ', 'c']], 'N', False], ['c1', 'c3']), ('insertion attributed to the new commit', [['c1', 'c2'], [[' ', 'a'], ['+', 'x'], [' ', 'b']], 'N', False], ['c1', 'N', 'c2']), ('removed lines advance the old cursor', [['c1', 'c2', 'c3', 'c4'], [['-', 'a'], ['-', 'b'], [' ', 'c'], [' ', 'd']], 'N', True], ['c3', 'c4']), ('whitespace-only change keeps blame when ignoring whitespace', [['c1', 'c2'], [['-', 'f(a,b)'], ['+', 'f(a, b)'], [' ', 'z']], 'N', True], ['c1', 'c2']), ('whitespace-only change is new without the flag', [['c1', 'c2'], [['-', 'f(a,b)'], ['+', 'f(a, b)'], [' ', 'z']], 'N', False], ['N', 'c2']), ('second pair compared positionally', [['c1', 'c2', 'c3'], [['-', 'x = 1'], ['-', 'y = 2'], ['+', 'x=1'], ['+', 'y =  2'], [' ', 'k']], 'N4', True], ['c1', 'c2', 'c3']), ('extra additions are new', [['c1', 'c2'], [['-', 'p'], ['+', 'p '], ['+', 'p'], [' ', 'q']], 'N', True], ['c1', 'N', 'c2']), ('real change within a whitespace block', [['c1', 'c2', 'c3'], [['-', 'u'], ['-', 'v'], ['+', 'u'], ['+', 'w'], [' ', 't']], 'N', True], ['c1', 'N', 'c3'])],\n    5: [('context keeps attribution', [['c1', 'c2', 'c3'], [[' ', 'a'], ['-', 'b'], [' ', 'c']], 'N', False], ['c1', 'c3']), ('insertion attributed to the new commit', [['c1', 'c2'], [[' ', 'a'], ['+', 'x'], [' ', 'b']], 'N', False], ['c1', 'N', 'c2']), ('removed lines advance the old cursor', [['c1', 'c2', 'c3', 'c4'], [['-', 'a'], ['-', 'b'], [' ', 'c'], [' ', 'd']], 'N', True], ['c3', 'c4']), ('whitespace-only change keeps blame when ignoring whitespace', [['c1', 'c2'], [['-', 'f(a,b)'], ['+', 'f(a, b)'], [' ', 'z']], 'N', True], ['c1', 'c2']), ('whitespace-only change is new without the flag', [['c1', 'c2'], [['-', 'f(a,b)'], ['+', 'f(a, b)'], [' ', 'z']], 'N', False], ['N', 'c2']), ('second pair compared positionally', [['c1', 'c2', 'c3'], [['-', 'x = 1'], ['-', 'y = 2'], ['+', 'x=1'], ['+', 'y =  2'], [' ', 'k']], 'N5', True], ['c1', 'c2', 'c3']), ('extra additions are new', [['c1', 'c2'], [['-', 'p'], ['+', 'p '], ['+', 'p'], [' ', 'q']], 'N', True], ['c1', 'N', 'c2']), ('real change within a whitespace block', [['c1', 'c2', 'c3'], [['-', 'u'], ['-', 'v'], ['+', 'u'], ['+', 'w'], [' ', 't']], 'N', True], ['c1', 'N', 'c3'])],\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":"5febb92a1949b4191bb13928f59240c37cd77f0891eeed54272a3c68fe579569","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(ann, ops, commit, ignore_ws):\n    res = []\n    i = 0\n    k = 0\n    while k < len(ops):\n        tag = ops[k][0]\n        if tag == ' ':\n            res.append(ann[i])\n            i += 1\n            k += 1\n            continue\n        dels = []\n        while k < len(ops) and ops[k][0] == '-':\n            dels.append((ann[i], ops[k][1]))\n            i += 1\n            k += 1\n        adds = []\n        while k < len(ops) and ops[k][0] == '+':\n            adds.append(ops[k][1])\n            k += 1\n        for idx, text in enumerate(adds):\n            if ignore_ws and idx < len(dels) and ''.join(dels[0][1].split()) == ''.join(text.split()):\n                res.append(dels[0][0])\n            else:\n                res.append(commit)\n    return res\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncases = {\n    1: [('context keeps attribution', [['c1', 'c2', 'c3'], [[' ', 'a'], ['-', 'b'], [' ', 'c']], 'N', False], ['c1', 'c3']), ('insertion attributed to the new commit', [['c1', 'c2'], [[' ', 'a'], ['+', 'x'], [' ', 'b']], 'N', False], ['c1', 'N', 'c2']), ('removed lines advance the old cursor', [['c1', 'c2', 'c3', 'c4'], [['-', 'a'], ['-', 'b'], [' ', 'c'], [' ', 'd']], 'N', True], ['c3', 'c4']), ('whitespace-only change keeps blame when ignoring whitespace', [['c1', 'c2'], [['-', 'f(a,b)'], ['+', 'f(a, b)'], [' ', 'z']], 'N', True], ['c1', 'c2']), ('whitespace-only change is new without the flag', [['c1', 'c2'], [['-', 'f(a,b)'], ['+', 'f(a, b)'], [' ', 'z']], 'N', False], ['N', 'c2']), ('second pair compared positionally', [['c1', 'c2', 'c3'], [['-', 'x = 1'], ['-', 'y = 2'], ['+', 'x=1'], ['+', 'y =  2'], [' ', 'k']], 'N1', True], ['c1', 'c2', 'c3']), ('extra additions are new', [['c1', 'c2'], [['-', 'p'], ['+', 'p '], ['+', 'p'], [' ', 'q']], 'N', True], ['c1', 'N', 'c2']), ('real change within a whitespace block', [['c1', 'c2', 'c3'], [['-', 'u'], ['-', 'v'], ['+', 'u'], ['+', 'w'], [' ', 't']], 'N', True], ['c1', 'N', 'c3'])],\n    2: [('context keeps attribution', [['c1', 'c2', 'c3'], [[' ', 'a'], ['-', 'b'], [' ', 'c']], 'N', False], ['c1', 'c3']), ('insertion attributed to the new commit', [['c1', 'c2'], [[' ', 'a'], ['+', 'x'], [' ', 'b']], 'N', False], ['c1', 'N', 'c2']), ('removed lines advance the old cursor', [['c1', 'c2', 'c3', 'c4'], [['-', 'a'], ['-', 'b'], [' ', 'c'], [' ', 'd']], 'N', True], ['c3', 'c4']), ('whitespace-only change keeps blame when ignoring whitespace', [['c1', 'c2'], [['-', 'f(a,b)'], ['+', 'f(a, b)'], [' ', 'z']], 'N', True], ['c1', 'c2']), ('whitespace-only change is new without the flag', [['c1', 'c2'], [['-', 'f(a,b)'], ['+', 'f(a, b)'], [' ', 'z']], 'N', False], ['N', 'c2']), ('second pair compared positionally', [['c1', 'c2', 'c3'], [['-', 'x = 1'], ['-', 'y = 2'], ['+', 'x=1'], ['+', 'y =  2'], [' ', 'k']], 'N2', True], ['c1', 'c2', 'c3']), ('extra additions are new', [['c1', 'c2'], [['-', 'p'], ['+', 'p '], ['+', 'p'], [' ', 'q']], 'N', True], ['c1', 'N', 'c2']), ('real change within a whitespace block', [['c1', 'c2', 'c3'], [['-', 'u'], ['-', 'v'], ['+', 'u'], ['+', 'w'], [' ', 't']], 'N', True], ['c1', 'N', 'c3'])],\n    3: [('context keeps attribution', [['c1', 'c2', 'c3'], [[' ', 'a'], ['-', 'b'], [' ', 'c']], 'N', False], ['c1', 'c3']), ('insertion attributed to the new commit', [['c1', 'c2'], [[' ', 'a'], ['+', 'x'], [' ', 'b']], 'N', False], ['c1', 'N', 'c2']), ('removed lines advance the old cursor', [['c1', 'c2', 'c3', 'c4'], [['-', 'a'], ['-', 'b'], [' ', 'c'], [' ', 'd']], 'N', True], ['c3', 'c4']), ('whitespace-only change keeps blame when ignoring whitespace', [['c1', 'c2'], [['-', 'f(a,b)'], ['+', 'f(a, b)'], [' ', 'z']], 'N', True], ['c1', 'c2']), ('whitespace-only change is new without the flag', [['c1', 'c2'], [['-', 'f(a,b)'], ['+', 'f(a, b)'], [' ', 'z']], 'N', False], ['N', 'c2']), ('second pair compared positionally', [['c1', 'c2', 'c3'], [['-', 'x = 1'], ['-', 'y = 2'], ['+', 'x=1'], ['+', 'y =  2'], [' ', 'k']], 'N3', True], ['c1', 'c2', 'c3']), ('extra additions are new', [['c1', 'c2'], [['-', 'p'], ['+', 'p '], ['+', 'p'], [' ', 'q']], 'N', True], ['c1', 'N', 'c2']), ('real change within a whitespace block', [['c1', 'c2', 'c3'], [['-', 'u'], ['-', 'v'], ['+', 'u'], ['+', 'w'], [' ', 't']], 'N', True], ['c1', 'N', 'c3'])],\n    4: [('context keeps attribution', [['c1', 'c2', 'c3'], [[' ', 'a'], ['-', 'b'], [' ', 'c']], 'N', False], ['c1', 'c3']), ('insertion attributed to the new commit', [['c1', 'c2'], [[' ', 'a'], ['+', 'x'], [' ', 'b']], 'N', False], ['c1', 'N', 'c2']), ('removed lines advance the old cursor', [['c1', 'c2', 'c3', 'c4'], [['-', 'a'], ['-', 'b'], [' ', 'c'], [' ', 'd']], 'N', True], ['c3', 'c4']), ('whitespace-only change keeps blame when ignoring whitespace', [['c1', 'c2'], [['-', 'f(a,b)'], ['+', 'f(a, b)'], [' ', 'z']], 'N', True], ['c1', 'c2']), ('whitespace-only change is new without the flag', [['c1', 'c2'], [['-', 'f(a,b)'], ['+', 'f(a, b)'], [' ', 'z']], 'N', False], ['N', 'c2']), ('second pair compared positionally', [['c1', 'c2', 'c3'], [['-', 'x = 1'], ['-', 'y = 2'], ['+', 'x=1'], ['+', 'y =  2'], [' ', 'k']], 'N4', True], ['c1', 'c2', 'c3']), ('extra additions are new', [['c1', 'c2'], [['-', 'p'], ['+', 'p '], ['+', 'p'], [' ', 'q']], 'N', True], ['c1', 'N', 'c2']), ('real change within a whitespace block', [['c1', 'c2', 'c3'], [['-', 'u'], ['-', 'v'], ['+', 'u'], ['+', 'w'], [' ', 't']], 'N', True], ['c1', 'N', 'c3'])],\n    5: [('context keeps attribution', [['c1', 'c2', 'c3'], [[' ', 'a'], ['-', 'b'], [' ', 'c']], 'N', False], ['c1', 'c3']), ('insertion attributed to the new commit', [['c1', 'c2'], [[' ', 'a'], ['+', 'x'], [' ', 'b']], 'N', False], ['c1', 'N', 'c2']), ('removed lines advance the old cursor', [['c1', 'c2', 'c3', 'c4'], [['-', 'a'], ['-', 'b'], [' ', 'c'], [' ', 'd']], 'N', True], ['c3', 'c4']), ('whitespace-only change keeps blame when ignoring whitespace', [['c1', 'c2'], [['-', 'f(a,b)'], ['+', 'f(a, b)'], [' ', 'z']], 'N', True], ['c1', 'c2']), ('whitespace-only change is new without the flag', [['c1', 'c2'], [['-', 'f(a,b)'], ['+', 'f(a, b)'], [' ', 'z']], 'N', False], ['N', 'c2']), ('second pair compared positionally', [['c1', 'c2', 'c3'], [['-', 'x = 1'], ['-', 'y = 2'], ['+', 'x=1'], ['+', 'y =  2'], [' ', 'k']], 'N5', True], ['c1', 'c2', 'c3']), ('extra additions are new', [['c1', 'c2'], [['-', 'p'], ['+', 'p '], ['+', 'p'], [' ', 'q']], 'N', True], ['c1', 'N', 'c2']), ('real change within a whitespace block', [['c1', 'c2', 'c3'], [['-', 'u'], ['-', 'v'], ['+', 'u'], ['+', 'w'], [' ', 't']], 'N', True], ['c1', 'N', 'c3'])],\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":"d4528568653c52e70162c7d70fe2e90bde1762740af533d308824a624b901b3f","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(ann, ops, commit, ignore_ws):\n    res = []\n    i = 0\n    k = 0\n    while k < len(ops):\n        tag = ops[k][0]\n        if tag == ' ':\n            res.append(ann[i])\n            i += 1\n            k += 1\n            continue\n        dels = []\n        while k < len(ops) and ops[k][0] == '-':\n            dels.append((ann[i], ops[k][1]))\n            i += 1\n            k += 1\n        adds = []\n        while k < len(ops) and ops[k][0] == '+':\n            adds.append(ops[k][1])\n            k += 1\n        for idx, text in enumerate(adds):\n            if ignore_ws and idx < len(dels) and ''.join(dels[idx][1].split()) == ''.join(text.split()):\n                res.append(dels[idx][0])\n            else:\n                res.append(commit)\n    return res\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncases = {\n    1: [('context keeps attribution', [['c1', 'c2', 'c3'], [[' ', 'a'], ['-', 'b'], [' ', 'c']], 'N', False], ['c1', 'c3']), ('insertion attributed to the new commit', [['c1', 'c2'], [[' ', 'a'], ['+', 'x'], [' ', 'b']], 'N', False], ['c1', 'N', 'c2']), ('removed lines advance the old cursor', [['c1', 'c2', 'c3', 'c4'], [['-', 'a'], ['-', 'b'], [' ', 'c'], [' ', 'd']], 'N', True], ['c3', 'c4']), ('whitespace-only change keeps blame when ignoring whitespace', [['c1', 'c2'], [['-', 'f(a,b)'], ['+', 'f(a, b)'], [' ', 'z']], 'N', True], ['c1', 'c2']), ('whitespace-only change is new without the flag', [['c1', 'c2'], [['-', 'f(a,b)'], ['+', 'f(a, b)'], [' ', 'z']], 'N', False], ['N', 'c2']), ('second pair compared positionally', [['c1', 'c2', 'c3'], [['-', 'x = 1'], ['-', 'y = 2'], ['+', 'x=1'], ['+', 'y =  2'], [' ', 'k']], 'N1', True], ['c1', 'c2', 'c3']), ('extra additions are new', [['c1', 'c2'], [['-', 'p'], ['+', 'p '], ['+', 'p'], [' ', 'q']], 'N', True], ['c1', 'N', 'c2']), ('real change within a whitespace block', [['c1', 'c2', 'c3'], [['-', 'u'], ['-', 'v'], ['+', 'u'], ['+', 'w'], [' ', 't']], 'N', True], ['c1', 'N', 'c3'])],\n    2: [('context keeps attribution', [['c1', 'c2', 'c3'], [[' ', 'a'], ['-', 'b'], [' ', 'c']], 'N', False], ['c1', 'c3']), ('insertion attributed to the new commit', [['c1', 'c2'], [[' ', 'a'], ['+', 'x'], [' ', 'b']], 'N', False], ['c1', 'N', 'c2']), ('removed lines advance the old cursor', [['c1', 'c2', 'c3', 'c4'], [['-', 'a'], ['-', 'b'], [' ', 'c'], [' ', 'd']], 'N', True], ['c3', 'c4']), ('whitespace-only change keeps blame when ignoring whitespace', [['c1', 'c2'], [['-', 'f(a,b)'], ['+', 'f(a, b)'], [' ', 'z']], 'N', True], ['c1', 'c2']), ('whitespace-only change is new without the flag', [['c1', 'c2'], [['-', 'f(a,b)'], ['+', 'f(a, b)'], [' ', 'z']], 'N', False], ['N', 'c2']), ('second pair compared positionally', [['c1', 'c2', 'c3'], [['-', 'x = 1'], ['-', 'y = 2'], ['+', 'x=1'], ['+', 'y =  2'], [' ', 'k']], 'N2', True], ['c1', 'c2', 'c3']), ('extra additions are new', [['c1', 'c2'], [['-', 'p'], ['+', 'p '], ['+', 'p'], [' ', 'q']], 'N', True], ['c1', 'N', 'c2']), ('real change within a whitespace block', [['c1', 'c2', 'c3'], [['-', 'u'], ['-', 'v'], ['+', 'u'], ['+', 'w'], [' ', 't']], 'N', True], ['c1', 'N', 'c3'])],\n    3: [('context keeps attribution', [['c1', 'c2', 'c3'], [[' ', 'a'], ['-', 'b'], [' ', 'c']], 'N', False], ['c1', 'c3']), ('insertion attributed to the new commit', [['c1', 'c2'], [[' ', 'a'], ['+', 'x'], [' ', 'b']], 'N', False], ['c1', 'N', 'c2']), ('removed lines advance the old cursor', [['c1', 'c2', 'c3', 'c4'], [['-', 'a'], ['-', 'b'], [' ', 'c'], [' ', 'd']], 'N', True], ['c3', 'c4']), ('whitespace-only change keeps blame when ignoring whitespace', [['c1', 'c2'], [['-', 'f(a,b)'], ['+', 'f(a, b)'], [' ', 'z']], 'N', True], ['c1', 'c2']), ('whitespace-only change is new without the flag', [['c1', 'c2'], [['-', 'f(a,b)'], ['+', 'f(a, b)'], [' ', 'z']], 'N', False], ['N', 'c2']), ('second pair compared positionally', [['c1', 'c2', 'c3'], [['-', 'x = 1'], ['-', 'y = 2'], ['+', 'x=1'], ['+', 'y =  2'], [' ', 'k']], 'N3', True], ['c1', 'c2', 'c3']), ('extra additions are new', [['c1', 'c2'], [['-', 'p'], ['+', 'p '], ['+', 'p'], [' ', 'q']], 'N', True], ['c1', 'N', 'c2']), ('real change within a whitespace block', [['c1', 'c2', 'c3'], [['-', 'u'], ['-', 'v'], ['+', 'u'], ['+', 'w'], [' ', 't']], 'N', True], ['c1', 'N', 'c3'])],\n    4: [('context keeps attribution', [['c1', 'c2', 'c3'], [[' ', 'a'], ['-', 'b'], [' ', 'c']], 'N', False], ['c1', 'c3']), ('insertion attributed to the new commit', [['c1', 'c2'], [[' ', 'a'], ['+', 'x'], [' ', 'b']], 'N', False], ['c1', 'N', 'c2']), ('removed lines advance the old cursor', [['c1', 'c2', 'c3', 'c4'], [['-', 'a'], ['-', 'b'], [' ', 'c'], [' ', 'd']], 'N', True], ['c3', 'c4']), ('whitespace-only change keeps blame when ignoring whitespace', [['c1', 'c2'], [['-', 'f(a,b)'], ['+', 'f(a, b)'], [' ', 'z']], 'N', True], ['c1', 'c2']), ('whitespace-only change is new without the flag', [['c1', 'c2'], [['-', 'f(a,b)'], ['+', 'f(a, b)'], [' ', 'z']], 'N', False], ['N', 'c2']), ('second pair compared positionally', [['c1', 'c2', 'c3'], [['-', 'x = 1'], ['-', 'y = 2'], ['+', 'x=1'], ['+', 'y =  2'], [' ', 'k']], 'N4', True], ['c1', 'c2', 'c3']), ('extra additions are new', [['c1', 'c2'], [['-', 'p'], ['+', 'p '], ['+', 'p'], [' ', 'q']], 'N', True], ['c1', 'N', 'c2']), ('real change within a whitespace block', [['c1', 'c2', 'c3'], [['-', 'u'], ['-', 'v'], ['+', 'u'], ['+', 'w'], [' ', 't']], 'N', True], ['c1', 'N', 'c3'])],\n    5: [('context keeps attribution', [['c1', 'c2', 'c3'], [[' ', 'a'], ['-', 'b'], [' ', 'c']], 'N', False], ['c1', 'c3']), ('insertion attributed to the new commit', [['c1', 'c2'], [[' ', 'a'], ['+', 'x'], [' ', 'b']], 'N', False], ['c1', 'N', 'c2']), ('removed lines advance the old cursor', [['c1', 'c2', 'c3', 'c4'], [['-', 'a'], ['-', 'b'], [' ', 'c'], [' ', 'd']], 'N', True], ['c3', 'c4']), ('whitespace-only change keeps blame when ignoring whitespace', [['c1', 'c2'], [['-', 'f(a,b)'], ['+', 'f(a, b)'], [' ', 'z']], 'N', True], ['c1', 'c2']), ('whitespace-only change is new without the flag', [['c1', 'c2'], [['-', 'f(a,b)'], ['+', 'f(a, b)'], [' ', 'z']], 'N', False], ['N', 'c2']), ('second pair compared positionally', [['c1', 'c2', 'c3'], [['-', 'x = 1'], ['-', 'y = 2'], ['+', 'x=1'], ['+', 'y =  2'], [' ', 'k']], 'N5', True], ['c1', 'c2', 'c3']), ('extra additions are new', [['c1', 'c2'], [['-', 'p'], ['+', 'p '], ['+', 'p'], [' ', 'q']], 'N', True], ['c1', 'N', 'c2']), ('real change within a whitespace block', [['c1', 'c2', 'c3'], [['-', 'u'], ['-', 'v'], ['+', 'u'], ['+', 'w'], [' ', 't']], 'N', True], ['c1', 'N', 'c3'])],\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 diff, patch or merge rule with stipulated conventions; it is not a production diff or version-control implementation and makes no claim of conformance to any specific tool. 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-text-diff-merge-blame-propagation-positional-pairing","generated_at":"2026-09-29T14:49:09.665317+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Blame and annotate views follow each line through history; whitespace-insensitive blame should not credit reformatting commits.","repair":"Pair the i-th added line with the i-th removed line.","root_cause":"Whitespace-insensitive pairing always consults the first removed line.","sha256":"c1f4a407c3b230378f59179900c2618a8239128e45407581ac3a9c32effa12d0","title":"Blame propagation: every added line is compared with the first removed line · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":41.852,"exit_code":1,"observations":[{"actual":["c1","c3"],"check":"context keeps attribution","expected":["c1","c3"],"passed":true},{"actual":["c1","N","c2"],"check":"insertion attributed to the new commit","expected":["c1","N","c2"],"passed":true},{"actual":["c3","c4"],"check":"removed lines advance the old cursor","expected":["c3","c4"],"passed":true},{"actual":["c1","c2"],"check":"whitespace-only change keeps blame when ignoring whitespace","expected":["c1","c2"],"passed":true},{"actual":["N","c2"],"check":"whitespace-only change is new without the flag","expected":["N","c2"],"passed":true},{"actual":["c1","c2","c3"],"check":"second pair compared positionally","expected":["c1","c2","c3"],"passed":true},{"actual":["c1","c1","c2"],"check":"extra additions are new","expected":["c1","N","c2"],"passed":false},{"actual":["c1","N","c3"],"check":"real change within a whitespace block","expected":["c1","N","c3"],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"context keeps attribution\", \"actual\": [\"c1\", \"c3\"], \"expected\": [\"c1\", \"c3\"], \"passed\": true}, {\"check\": \"insertion attributed to the new commit\", \"actual\": [\"c1\", \"N\", \"c2\"], \"expected\": [\"c1\", \"N\", \"c2\"], \"passed\": true}, {\"check\": \"removed lines advance the old cursor\", \"actual\": [\"c3\", \"c4\"], \"expected\": [\"c3\", \"c4\"], \"passed\": true}, {\"check\": \"whitespace-only change keeps blame when ignoring whitespace\", \"actual\": [\"c1\", \"c2\"], \"expected\": [\"c1\", \"c2\"], \"passed\": true}, {\"check\": \"whitespace-only change is new without the flag\", \"actual\": [\"N\", \"c2\"], \"expected\": [\"N\", \"c2\"], \"passed\": true}, {\"check\": \"second pair compared positionally\", \"actual\": [\"c1\", \"c2\", \"c3\"], \"expected\": [\"c1\", \"c2\", \"c3\"], \"passed\": true}, {\"check\": \"extra additions are new\", \"actual\": [\"c1\", \"c1\", \"c2\"], \"expected\": [\"c1\", \"N\", \"c2\"], \"passed\": false}, {\"check\": \"real change within a whitespace block\", \"actual\": [\"c1\", \"N\", \"c3\"], \"expected\": [\"c1\", \"N\", \"c3\"], \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":38.695,"exit_code":1,"observations":[{"actual":["c1","c3"],"check":"context keeps attribution","expected":["c1","c3"],"passed":true},{"actual":["c1","N","c2"],"check":"insertion attributed to the new commit","expected":["c1","N","c2"],"passed":true},{"actual":["c3","c4"],"check":"removed lines advance the old cursor","expected":["c3","c4"],"passed":true},{"actual":["c1","c2"],"check":"whitespace-only change keeps blame when ignoring whitespace","expected":["c1","c2"],"passed":true},{"actual":["N","c2"],"check":"whitespace-only change is new without the flag","expected":["N","c2"],"passed":true},{"actual":["c1","N1","c3"],"check":"second pair compared positionally","expected":["c1","c2","c3"],"passed":false},{"actual":["c1","N","c2"],"check":"extra additions are new","expected":["c1","N","c2"],"passed":true},{"actual":["c1","N","c3"],"check":"real change within a whitespace block","expected":["c1","N","c3"],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"context keeps attribution\", \"actual\": [\"c1\", \"c3\"], \"expected\": [\"c1\", \"c3\"], \"passed\": true}, {\"check\": \"insertion attributed to the new commit\", \"actual\": [\"c1\", \"N\", \"c2\"], \"expected\": [\"c1\", \"N\", \"c2\"], \"passed\": true}, {\"check\": \"removed lines advance the old cursor\", \"actual\": [\"c3\", \"c4\"], \"expected\": [\"c3\", \"c4\"], \"passed\": true}, {\"check\": \"whitespace-only change keeps blame when ignoring whitespace\", \"actual\": [\"c1\", \"c2\"], \"expected\": [\"c1\", \"c2\"], \"passed\": true}, {\"check\": \"whitespace-only change is new without the flag\", \"actual\": [\"N\", \"c2\"], \"expected\": [\"N\", \"c2\"], \"passed\": true}, {\"check\": \"second pair compared positionally\", \"actual\": [\"c1\", \"N1\", \"c3\"], \"expected\": [\"c1\", \"c2\", \"c3\"], \"passed\": false}, {\"check\": \"extra additions are new\", \"actual\": [\"c1\", \"N\", \"c2\"], \"expected\": [\"c1\", \"N\", \"c2\"], \"passed\": true}, {\"check\": \"real change within a whitespace block\", \"actual\": [\"c1\", \"N\", \"c3\"], \"expected\": [\"c1\", \"N\", \"c3\"], \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":40.586,"exit_code":0,"observations":[{"actual":["c1","c3"],"check":"context keeps attribution","expected":["c1","c3"],"passed":true},{"actual":["c1","N","c2"],"check":"insertion attributed to the new commit","expected":["c1","N","c2"],"passed":true},{"actual":["c3","c4"],"check":"removed lines advance the old cursor","expected":["c3","c4"],"passed":true},{"actual":["c1","c2"],"check":"whitespace-only change keeps blame when ignoring whitespace","expected":["c1","c2"],"passed":true},{"actual":["N","c2"],"check":"whitespace-only change is new without the flag","expected":["N","c2"],"passed":true},{"actual":["c1","c2","c3"],"check":"second pair compared positionally","expected":["c1","c2","c3"],"passed":true},{"actual":["c1","N","c2"],"check":"extra additions are new","expected":["c1","N","c2"],"passed":true},{"actual":["c1","N","c3"],"check":"real change within a whitespace block","expected":["c1","N","c3"],"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"context keeps attribution\", \"actual\": [\"c1\", \"c3\"], \"expected\": [\"c1\", \"c3\"], \"passed\": true}, {\"check\": \"insertion attributed to the new commit\", \"actual\": [\"c1\", \"N\", \"c2\"], \"expected\": [\"c1\", \"N\", \"c2\"], \"passed\": true}, {\"check\": \"removed lines advance the old cursor\", \"actual\": [\"c3\", \"c4\"], \"expected\": [\"c3\", \"c4\"], \"passed\": true}, {\"check\": \"whitespace-only change keeps blame when ignoring whitespace\", \"actual\": [\"c1\", \"c2\"], \"expected\": [\"c1\", \"c2\"], \"passed\": true}, {\"check\": \"whitespace-only change is new without the flag\", \"actual\": [\"N\", \"c2\"], \"expected\": [\"N\", \"c2\"], \"passed\": true}, {\"check\": \"second pair compared positionally\", \"actual\": [\"c1\", \"c2\", \"c3\"], \"expected\": [\"c1\", \"c2\", \"c3\"], \"passed\": true}, {\"check\": \"extra additions are new\", \"actual\": [\"c1\", \"N\", \"c2\"], \"expected\": [\"c1\", \"N\", \"c2\"], \"passed\": true}, {\"check\": \"real change within a whitespace block\", \"actual\": [\"c1\", \"N\", \"c3\"], \"expected\": [\"c1\", \"N\", \"c3\"], \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}