{"abstract":"Making a script executable produces no change entry.","category":"Text diff and three-way merge","checks":9,"contract":"Compare two tree listings of [name, mode, hash]. Entries are ordered by name, with directories (mode 040000) compared as name + \"/\". Walk both in that order: entries only in the old tree are \"D\", only in the new tree \"A\". Entries matched by sort key report \"T\" when the mode type (first two digits) differs, else \"M\" when the hash or mode differs. Return [status, name] rows.","evaluation_group":"w2-text-diff-merge-tree-listing-diff","failed_approach":"Comparing abbreviated hashes misses content changes whose hashes share a prefix.","family":"w2-text-diff-merge-tree-listing-diff-modification-test","id":"FA-75776","implementations":{"attempt":{"sha256":"c758b6f32cb4172770cb3acef9e969ee3e82bd74bb7c35f82ba61ce4ead18862","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(old, new):\n    def key(x):\n        return x[0] + '/' if x[1] == '040000' else x[0]\n    A = sorted(old, key=key)\n    B = sorted(new, key=key)\n    i = j = 0\n    out = []\n    while i < len(A) or j < len(B):\n        if j >= len(B) or (i < len(A) and key(A[i]) < key(B[j])):\n            out.append(['D', A[i][0]])\n            i += 1\n        elif i >= len(A) or key(B[j]) < key(A[i]):\n            out.append(['A', B[j][0]])\n            j += 1\n        else:\n            a, b = A[i], B[j]\n            if a[1][:2] != b[1][:2]:\n                out.append(['T', a[0]])\n            elif a[2][:7] != b[2][:7] or a[1] != b[1]:\n                out.append(['M', a[0]])\n            i += 1\n            j += 1\n    return out\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncases = {\n    1: [('modified blob', [[['a.txt', '100644', 'h1']], [['a.txt', '100644', 'h2']]], [['M', 'a.txt']]), ('exec bit change is a modification', [[['run.sh', '100644', 'h']], [['run.sh', '100755', 'h']]], [['M', 'run.sh']]), ('file becomes a symlink', [[['lnk', '100644', 'h']], [['lnk', '120000', 'h']]], [['T', 'lnk']]), ('file replaced by a directory of the same name', [[['x', '100644', 'h']], [['x', '040000', 't']]], [['D', 'x'], ['A', 'x']]), ('directory sorts as name plus slash', [[['a.b', '100644', 'h'], ['a', '040000', 't1']], [['a.b', '100644', 'h'], ['a', '040000', 't2'], ['a-c', '100644', 'q']]], [['A', 'a-c'], ['M', 'a']]), ('trailing additions and deletions', [[['b', '100644', '1']], [['b', '100644', '1'], ['z0', '100644', 'n']]], [['A', 'z0']]), ('only deletions at the end', [[['m', '100644', '1'], ['y', '100644', '2']], [['m', '100644', '1']]], [['D', 'y']]), ('hashes sharing a long prefix', [[['k', '100644', 'abcdef0123']], [['k', '100644', 'abcdef0999']]], [['M', 'k']]), ('added then removed around a common entry', [[['a', '100644', '1'], ['c', '100644', '3']], [['b', '100644', '2'], ['c', '100644', '3']]], [['D', 'a'], ['A', 'b']])],\n    2: [('modified blob', [[['a.txt', '100644', 'h1']], [['a.txt', '100644', 'h2']]], [['M', 'a.txt']]), ('exec bit change is a modification', [[['run.sh', '100644', 'h']], [['run.sh', '100755', 'h']]], [['M', 'run.sh']]), ('file becomes a symlink', [[['lnk', '100644', 'h']], [['lnk', '120000', 'h']]], [['T', 'lnk']]), ('file replaced by a directory of the same name', [[['x', '100644', 'h']], [['x', '040000', 't']]], [['D', 'x'], ['A', 'x']]), ('directory sorts as name plus slash', [[['a.b', '100644', 'h'], ['a', '040000', 't1']], [['a.b', '100644', 'h'], ['a', '040000', 't2'], ['a-c', '100644', 'q']]], [['A', 'a-c'], ['M', 'a']]), ('trailing additions and deletions', [[['b', '100644', '1']], [['b', '100644', '1'], ['z0', '100644', 'n'], ['z1', '100644', 'n']]], [['A', 'z0'], ['A', 'z1']]), ('only deletions at the end', [[['m', '100644', '1'], ['y', '100644', '2']], [['m', '100644', '1']]], [['D', 'y']]), ('hashes sharing a long prefix', [[['k', '100644', 'abcdef0123']], [['k', '100644', 'abcdef0999']]], [['M', 'k']]), ('added then removed around a common entry', [[['a', '100644', '1'], ['c', '100644', '3']], [['b', '100644', '2'], ['c', '100644', '3']]], [['D', 'a'], ['A', 'b']])],\n    3: [('modified blob', [[['a.txt', '100644', 'h1']], [['a.txt', '100644', 'h2']]], [['M', 'a.txt']]), ('exec bit change is a modification', [[['run.sh', '100644', 'h']], [['run.sh', '100755', 'h']]], [['M', 'run.sh']]), ('file becomes a symlink', [[['lnk', '100644', 'h']], [['lnk', '120000', 'h']]], [['T', 'lnk']]), ('file replaced by a directory of the same name', [[['x', '100644', 'h']], [['x', '040000', 't']]], [['D', 'x'], ['A', 'x']]), ('directory sorts as name plus slash', [[['a.b', '100644', 'h'], ['a', '040000', 't1']], [['a.b', '100644', 'h'], ['a', '040000', 't2'], ['a-c', '100644', 'q']]], [['A', 'a-c'], ['M', 'a']]), ('trailing additions and deletions', [[['b', '100644', '1']], [['b', '100644', '1'], ['z0', '100644', 'n'], ['z1', '100644', 'n'], ['z2', '100644', 'n']]], [['A', 'z0'], ['A', 'z1'], ['A', 'z2']]), ('only deletions at the end', [[['m', '100644', '1'], ['y', '100644', '2']], [['m', '100644', '1']]], [['D', 'y']]), ('hashes sharing a long prefix', [[['k', '100644', 'abcdef0123']], [['k', '100644', 'abcdef0999']]], [['M', 'k']]), ('added then removed around a common entry', [[['a', '100644', '1'], ['c', '100644', '3']], [['b', '100644', '2'], ['c', '100644', '3']]], [['D', 'a'], ['A', 'b']])],\n    4: [('modified blob', [[['a.txt', '100644', 'h1']], [['a.txt', '100644', 'h2']]], [['M', 'a.txt']]), ('exec bit change is a modification', [[['run.sh', '100644', 'h']], [['run.sh', '100755', 'h']]], [['M', 'run.sh']]), ('file becomes a symlink', [[['lnk', '100644', 'h']], [['lnk', '120000', 'h']]], [['T', 'lnk']]), ('file replaced by a directory of the same name', [[['x', '100644', 'h']], [['x', '040000', 't']]], [['D', 'x'], ['A', 'x']]), ('directory sorts as name plus slash', [[['a.b', '100644', 'h'], ['a', '040000', 't1']], [['a.b', '100644', 'h'], ['a', '040000', 't2'], ['a-c', '100644', 'q']]], [['A', 'a-c'], ['M', 'a']]), ('trailing additions and deletions', [[['b', '100644', '1']], [['b', '100644', '1'], ['z0', '100644', 'n'], ['z1', '100644', 'n'], ['z2', '100644', 'n'], ['z3', '100644', 'n']]], [['A', 'z0'], ['A', 'z1'], ['A', 'z2'], ['A', 'z3']]), ('only deletions at the end', [[['m', '100644', '1'], ['y', '100644', '2']], [['m', '100644', '1']]], [['D', 'y']]), ('hashes sharing a long prefix', [[['k', '100644', 'abcdef0123']], [['k', '100644', 'abcdef0999']]], [['M', 'k']]), ('added then removed around a common entry', [[['a', '100644', '1'], ['c', '100644', '3']], [['b', '100644', '2'], ['c', '100644', '3']]], [['D', 'a'], ['A', 'b']])],\n    5: [('modified blob', [[['a.txt', '100644', 'h1']], [['a.txt', '100644', 'h2']]], [['M', 'a.txt']]), ('exec bit change is a modification', [[['run.sh', '100644', 'h']], [['run.sh', '100755', 'h']]], [['M', 'run.sh']]), ('file becomes a symlink', [[['lnk', '100644', 'h']], [['lnk', '120000', 'h']]], [['T', 'lnk']]), ('file replaced by a directory of the same name', [[['x', '100644', 'h']], [['x', '040000', 't']]], [['D', 'x'], ['A', 'x']]), ('directory sorts as name plus slash', [[['a.b', '100644', 'h'], ['a', '040000', 't1']], [['a.b', '100644', 'h'], ['a', '040000', 't2'], ['a-c', '100644', 'q']]], [['A', 'a-c'], ['M', 'a']]), ('trailing additions and deletions', [[['b', '100644', '1']], [['b', '100644', '1'], ['z0', '100644', 'n'], ['z1', '100644', 'n'], ['z2', '100644', 'n'], ['z3', '100644', 'n'], ['z4', '100644', 'n']]], [['A', 'z0'], ['A', 'z1'], ['A', 'z2'], ['A', 'z3'], ['A', 'z4']]), ('only deletions at the end', [[['m', '100644', '1'], ['y', '100644', '2']], [['m', '100644', '1']]], [['D', 'y']]), ('hashes sharing a long prefix', [[['k', '100644', 'abcdef0123']], [['k', '100644', 'abcdef0999']]], [['M', 'k']]), ('added then removed around a common entry', [[['a', '100644', '1'], ['c', '100644', '3']], [['b', '100644', '2'], ['c', '100644', '3']]], [['D', 'a'], ['A', 'b']])],\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":"ee8d9fc0df2ffeef517ce03a86afd4bc32a350a2a6fbc3a620c0552ec59f5fed","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(old, new):\n    def key(x):\n        return x[0] + '/' if x[1] == '040000' else x[0]\n    A = sorted(old, key=key)\n    B = sorted(new, key=key)\n    i = j = 0\n    out = []\n    while i < len(A) or j < len(B):\n        if j >= len(B) or (i < len(A) and key(A[i]) < key(B[j])):\n            out.append(['D', A[i][0]])\n            i += 1\n        elif i >= len(A) or key(B[j]) < key(A[i]):\n            out.append(['A', B[j][0]])\n            j += 1\n        else:\n            a, b = A[i], B[j]\n            if a[1][:2] != b[1][:2]:\n                out.append(['T', a[0]])\n            elif a[2] != b[2]:\n                out.append(['M', a[0]])\n            i += 1\n            j += 1\n    return out\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncases = {\n    1: [('modified blob', [[['a.txt', '100644', 'h1']], [['a.txt', '100644', 'h2']]], [['M', 'a.txt']]), ('exec bit change is a modification', [[['run.sh', '100644', 'h']], [['run.sh', '100755', 'h']]], [['M', 'run.sh']]), ('file becomes a symlink', [[['lnk', '100644', 'h']], [['lnk', '120000', 'h']]], [['T', 'lnk']]), ('file replaced by a directory of the same name', [[['x', '100644', 'h']], [['x', '040000', 't']]], [['D', 'x'], ['A', 'x']]), ('directory sorts as name plus slash', [[['a.b', '100644', 'h'], ['a', '040000', 't1']], [['a.b', '100644', 'h'], ['a', '040000', 't2'], ['a-c', '100644', 'q']]], [['A', 'a-c'], ['M', 'a']]), ('trailing additions and deletions', [[['b', '100644', '1']], [['b', '100644', '1'], ['z0', '100644', 'n']]], [['A', 'z0']]), ('only deletions at the end', [[['m', '100644', '1'], ['y', '100644', '2']], [['m', '100644', '1']]], [['D', 'y']]), ('hashes sharing a long prefix', [[['k', '100644', 'abcdef0123']], [['k', '100644', 'abcdef0999']]], [['M', 'k']]), ('added then removed around a common entry', [[['a', '100644', '1'], ['c', '100644', '3']], [['b', '100644', '2'], ['c', '100644', '3']]], [['D', 'a'], ['A', 'b']])],\n    2: [('modified blob', [[['a.txt', '100644', 'h1']], [['a.txt', '100644', 'h2']]], [['M', 'a.txt']]), ('exec bit change is a modification', [[['run.sh', '100644', 'h']], [['run.sh', '100755', 'h']]], [['M', 'run.sh']]), ('file becomes a symlink', [[['lnk', '100644', 'h']], [['lnk', '120000', 'h']]], [['T', 'lnk']]), ('file replaced by a directory of the same name', [[['x', '100644', 'h']], [['x', '040000', 't']]], [['D', 'x'], ['A', 'x']]), ('directory sorts as name plus slash', [[['a.b', '100644', 'h'], ['a', '040000', 't1']], [['a.b', '100644', 'h'], ['a', '040000', 't2'], ['a-c', '100644', 'q']]], [['A', 'a-c'], ['M', 'a']]), ('trailing additions and deletions', [[['b', '100644', '1']], [['b', '100644', '1'], ['z0', '100644', 'n'], ['z1', '100644', 'n']]], [['A', 'z0'], ['A', 'z1']]), ('only deletions at the end', [[['m', '100644', '1'], ['y', '100644', '2']], [['m', '100644', '1']]], [['D', 'y']]), ('hashes sharing a long prefix', [[['k', '100644', 'abcdef0123']], [['k', '100644', 'abcdef0999']]], [['M', 'k']]), ('added then removed around a common entry', [[['a', '100644', '1'], ['c', '100644', '3']], [['b', '100644', '2'], ['c', '100644', '3']]], [['D', 'a'], ['A', 'b']])],\n    3: [('modified blob', [[['a.txt', '100644', 'h1']], [['a.txt', '100644', 'h2']]], [['M', 'a.txt']]), ('exec bit change is a modification', [[['run.sh', '100644', 'h']], [['run.sh', '100755', 'h']]], [['M', 'run.sh']]), ('file becomes a symlink', [[['lnk', '100644', 'h']], [['lnk', '120000', 'h']]], [['T', 'lnk']]), ('file replaced by a directory of the same name', [[['x', '100644', 'h']], [['x', '040000', 't']]], [['D', 'x'], ['A', 'x']]), ('directory sorts as name plus slash', [[['a.b', '100644', 'h'], ['a', '040000', 't1']], [['a.b', '100644', 'h'], ['a', '040000', 't2'], ['a-c', '100644', 'q']]], [['A', 'a-c'], ['M', 'a']]), ('trailing additions and deletions', [[['b', '100644', '1']], [['b', '100644', '1'], ['z0', '100644', 'n'], ['z1', '100644', 'n'], ['z2', '100644', 'n']]], [['A', 'z0'], ['A', 'z1'], ['A', 'z2']]), ('only deletions at the end', [[['m', '100644', '1'], ['y', '100644', '2']], [['m', '100644', '1']]], [['D', 'y']]), ('hashes sharing a long prefix', [[['k', '100644', 'abcdef0123']], [['k', '100644', 'abcdef0999']]], [['M', 'k']]), ('added then removed around a common entry', [[['a', '100644', '1'], ['c', '100644', '3']], [['b', '100644', '2'], ['c', '100644', '3']]], [['D', 'a'], ['A', 'b']])],\n    4: [('modified blob', [[['a.txt', '100644', 'h1']], [['a.txt', '100644', 'h2']]], [['M', 'a.txt']]), ('exec bit change is a modification', [[['run.sh', '100644', 'h']], [['run.sh', '100755', 'h']]], [['M', 'run.sh']]), ('file becomes a symlink', [[['lnk', '100644', 'h']], [['lnk', '120000', 'h']]], [['T', 'lnk']]), ('file replaced by a directory of the same name', [[['x', '100644', 'h']], [['x', '040000', 't']]], [['D', 'x'], ['A', 'x']]), ('directory sorts as name plus slash', [[['a.b', '100644', 'h'], ['a', '040000', 't1']], [['a.b', '100644', 'h'], ['a', '040000', 't2'], ['a-c', '100644', 'q']]], [['A', 'a-c'], ['M', 'a']]), ('trailing additions and deletions', [[['b', '100644', '1']], [['b', '100644', '1'], ['z0', '100644', 'n'], ['z1', '100644', 'n'], ['z2', '100644', 'n'], ['z3', '100644', 'n']]], [['A', 'z0'], ['A', 'z1'], ['A', 'z2'], ['A', 'z3']]), ('only deletions at the end', [[['m', '100644', '1'], ['y', '100644', '2']], [['m', '100644', '1']]], [['D', 'y']]), ('hashes sharing a long prefix', [[['k', '100644', 'abcdef0123']], [['k', '100644', 'abcdef0999']]], [['M', 'k']]), ('added then removed around a common entry', [[['a', '100644', '1'], ['c', '100644', '3']], [['b', '100644', '2'], ['c', '100644', '3']]], [['D', 'a'], ['A', 'b']])],\n    5: [('modified blob', [[['a.txt', '100644', 'h1']], [['a.txt', '100644', 'h2']]], [['M', 'a.txt']]), ('exec bit change is a modification', [[['run.sh', '100644', 'h']], [['run.sh', '100755', 'h']]], [['M', 'run.sh']]), ('file becomes a symlink', [[['lnk', '100644', 'h']], [['lnk', '120000', 'h']]], [['T', 'lnk']]), ('file replaced by a directory of the same name', [[['x', '100644', 'h']], [['x', '040000', 't']]], [['D', 'x'], ['A', 'x']]), ('directory sorts as name plus slash', [[['a.b', '100644', 'h'], ['a', '040000', 't1']], [['a.b', '100644', 'h'], ['a', '040000', 't2'], ['a-c', '100644', 'q']]], [['A', 'a-c'], ['M', 'a']]), ('trailing additions and deletions', [[['b', '100644', '1']], [['b', '100644', '1'], ['z0', '100644', 'n'], ['z1', '100644', 'n'], ['z2', '100644', 'n'], ['z3', '100644', 'n'], ['z4', '100644', 'n']]], [['A', 'z0'], ['A', 'z1'], ['A', 'z2'], ['A', 'z3'], ['A', 'z4']]), ('only deletions at the end', [[['m', '100644', '1'], ['y', '100644', '2']], [['m', '100644', '1']]], [['D', 'y']]), ('hashes sharing a long prefix', [[['k', '100644', 'abcdef0123']], [['k', '100644', 'abcdef0999']]], [['M', 'k']]), ('added then removed around a common entry', [[['a', '100644', '1'], ['c', '100644', '3']], [['b', '100644', '2'], ['c', '100644', '3']]], [['D', 'a'], ['A', 'b']])],\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":"65a54a854bdf51e007e9d36898821d1d01b1febc67a2764e097b92defbe15097","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(old, new):\n    def key(x):\n        return x[0] + '/' if x[1] == '040000' else x[0]\n    A = sorted(old, key=key)\n    B = sorted(new, key=key)\n    i = j = 0\n    out = []\n    while i < len(A) or j < len(B):\n        if j >= len(B) or (i < len(A) and key(A[i]) < key(B[j])):\n            out.append(['D', A[i][0]])\n            i += 1\n        elif i >= len(A) or key(B[j]) < key(A[i]):\n            out.append(['A', B[j][0]])\n            j += 1\n        else:\n            a, b = A[i], B[j]\n            if a[1][:2] != b[1][:2]:\n                out.append(['T', a[0]])\n            elif a[2] != b[2] or a[1] != b[1]:\n                out.append(['M', a[0]])\n            i += 1\n            j += 1\n    return out\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncases = {\n    1: [('modified blob', [[['a.txt', '100644', 'h1']], [['a.txt', '100644', 'h2']]], [['M', 'a.txt']]), ('exec bit change is a modification', [[['run.sh', '100644', 'h']], [['run.sh', '100755', 'h']]], [['M', 'run.sh']]), ('file becomes a symlink', [[['lnk', '100644', 'h']], [['lnk', '120000', 'h']]], [['T', 'lnk']]), ('file replaced by a directory of the same name', [[['x', '100644', 'h']], [['x', '040000', 't']]], [['D', 'x'], ['A', 'x']]), ('directory sorts as name plus slash', [[['a.b', '100644', 'h'], ['a', '040000', 't1']], [['a.b', '100644', 'h'], ['a', '040000', 't2'], ['a-c', '100644', 'q']]], [['A', 'a-c'], ['M', 'a']]), ('trailing additions and deletions', [[['b', '100644', '1']], [['b', '100644', '1'], ['z0', '100644', 'n']]], [['A', 'z0']]), ('only deletions at the end', [[['m', '100644', '1'], ['y', '100644', '2']], [['m', '100644', '1']]], [['D', 'y']]), ('hashes sharing a long prefix', [[['k', '100644', 'abcdef0123']], [['k', '100644', 'abcdef0999']]], [['M', 'k']]), ('added then removed around a common entry', [[['a', '100644', '1'], ['c', '100644', '3']], [['b', '100644', '2'], ['c', '100644', '3']]], [['D', 'a'], ['A', 'b']])],\n    2: [('modified blob', [[['a.txt', '100644', 'h1']], [['a.txt', '100644', 'h2']]], [['M', 'a.txt']]), ('exec bit change is a modification', [[['run.sh', '100644', 'h']], [['run.sh', '100755', 'h']]], [['M', 'run.sh']]), ('file becomes a symlink', [[['lnk', '100644', 'h']], [['lnk', '120000', 'h']]], [['T', 'lnk']]), ('file replaced by a directory of the same name', [[['x', '100644', 'h']], [['x', '040000', 't']]], [['D', 'x'], ['A', 'x']]), ('directory sorts as name plus slash', [[['a.b', '100644', 'h'], ['a', '040000', 't1']], [['a.b', '100644', 'h'], ['a', '040000', 't2'], ['a-c', '100644', 'q']]], [['A', 'a-c'], ['M', 'a']]), ('trailing additions and deletions', [[['b', '100644', '1']], [['b', '100644', '1'], ['z0', '100644', 'n'], ['z1', '100644', 'n']]], [['A', 'z0'], ['A', 'z1']]), ('only deletions at the end', [[['m', '100644', '1'], ['y', '100644', '2']], [['m', '100644', '1']]], [['D', 'y']]), ('hashes sharing a long prefix', [[['k', '100644', 'abcdef0123']], [['k', '100644', 'abcdef0999']]], [['M', 'k']]), ('added then removed around a common entry', [[['a', '100644', '1'], ['c', '100644', '3']], [['b', '100644', '2'], ['c', '100644', '3']]], [['D', 'a'], ['A', 'b']])],\n    3: [('modified blob', [[['a.txt', '100644', 'h1']], [['a.txt', '100644', 'h2']]], [['M', 'a.txt']]), ('exec bit change is a modification', [[['run.sh', '100644', 'h']], [['run.sh', '100755', 'h']]], [['M', 'run.sh']]), ('file becomes a symlink', [[['lnk', '100644', 'h']], [['lnk', '120000', 'h']]], [['T', 'lnk']]), ('file replaced by a directory of the same name', [[['x', '100644', 'h']], [['x', '040000', 't']]], [['D', 'x'], ['A', 'x']]), ('directory sorts as name plus slash', [[['a.b', '100644', 'h'], ['a', '040000', 't1']], [['a.b', '100644', 'h'], ['a', '040000', 't2'], ['a-c', '100644', 'q']]], [['A', 'a-c'], ['M', 'a']]), ('trailing additions and deletions', [[['b', '100644', '1']], [['b', '100644', '1'], ['z0', '100644', 'n'], ['z1', '100644', 'n'], ['z2', '100644', 'n']]], [['A', 'z0'], ['A', 'z1'], ['A', 'z2']]), ('only deletions at the end', [[['m', '100644', '1'], ['y', '100644', '2']], [['m', '100644', '1']]], [['D', 'y']]), ('hashes sharing a long prefix', [[['k', '100644', 'abcdef0123']], [['k', '100644', 'abcdef0999']]], [['M', 'k']]), ('added then removed around a common entry', [[['a', '100644', '1'], ['c', '100644', '3']], [['b', '100644', '2'], ['c', '100644', '3']]], [['D', 'a'], ['A', 'b']])],\n    4: [('modified blob', [[['a.txt', '100644', 'h1']], [['a.txt', '100644', 'h2']]], [['M', 'a.txt']]), ('exec bit change is a modification', [[['run.sh', '100644', 'h']], [['run.sh', '100755', 'h']]], [['M', 'run.sh']]), ('file becomes a symlink', [[['lnk', '100644', 'h']], [['lnk', '120000', 'h']]], [['T', 'lnk']]), ('file replaced by a directory of the same name', [[['x', '100644', 'h']], [['x', '040000', 't']]], [['D', 'x'], ['A', 'x']]), ('directory sorts as name plus slash', [[['a.b', '100644', 'h'], ['a', '040000', 't1']], [['a.b', '100644', 'h'], ['a', '040000', 't2'], ['a-c', '100644', 'q']]], [['A', 'a-c'], ['M', 'a']]), ('trailing additions and deletions', [[['b', '100644', '1']], [['b', '100644', '1'], ['z0', '100644', 'n'], ['z1', '100644', 'n'], ['z2', '100644', 'n'], ['z3', '100644', 'n']]], [['A', 'z0'], ['A', 'z1'], ['A', 'z2'], ['A', 'z3']]), ('only deletions at the end', [[['m', '100644', '1'], ['y', '100644', '2']], [['m', '100644', '1']]], [['D', 'y']]), ('hashes sharing a long prefix', [[['k', '100644', 'abcdef0123']], [['k', '100644', 'abcdef0999']]], [['M', 'k']]), ('added then removed around a common entry', [[['a', '100644', '1'], ['c', '100644', '3']], [['b', '100644', '2'], ['c', '100644', '3']]], [['D', 'a'], ['A', 'b']])],\n    5: [('modified blob', [[['a.txt', '100644', 'h1']], [['a.txt', '100644', 'h2']]], [['M', 'a.txt']]), ('exec bit change is a modification', [[['run.sh', '100644', 'h']], [['run.sh', '100755', 'h']]], [['M', 'run.sh']]), ('file becomes a symlink', [[['lnk', '100644', 'h']], [['lnk', '120000', 'h']]], [['T', 'lnk']]), ('file replaced by a directory of the same name', [[['x', '100644', 'h']], [['x', '040000', 't']]], [['D', 'x'], ['A', 'x']]), ('directory sorts as name plus slash', [[['a.b', '100644', 'h'], ['a', '040000', 't1']], [['a.b', '100644', 'h'], ['a', '040000', 't2'], ['a-c', '100644', 'q']]], [['A', 'a-c'], ['M', 'a']]), ('trailing additions and deletions', [[['b', '100644', '1']], [['b', '100644', '1'], ['z0', '100644', 'n'], ['z1', '100644', 'n'], ['z2', '100644', 'n'], ['z3', '100644', 'n'], ['z4', '100644', 'n']]], [['A', 'z0'], ['A', 'z1'], ['A', 'z2'], ['A', 'z3'], ['A', 'z4']]), ('only deletions at the end', [[['m', '100644', '1'], ['y', '100644', '2']], [['m', '100644', '1']]], [['D', 'y']]), ('hashes sharing a long prefix', [[['k', '100644', 'abcdef0123']], [['k', '100644', 'abcdef0999']]], [['M', 'k']]), ('added then removed around a common entry', [[['a', '100644', '1'], ['c', '100644', '3']], [['b', '100644', '2'], ['c', '100644', '3']]], [['D', 'a'], ['A', 'b']])],\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-tree-listing-diff-modification-test","generated_at":"2026-09-29T14:49:10.111566+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Tree diffs drive status, rename detection and checkout; their ordering and type-change rules follow the object-store conventions.","repair":"Report \"M\" when either the hash or the mode differs.","root_cause":"Modification is detected from the hash alone.","sha256":"6411bd3af22e0494ac1faba045d909eaebe39a26803e2ba602d6260f9e4184b1","title":"Tree listing diff: mode-only changes are not reported · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":38.686,"exit_code":1,"observations":[{"actual":[["M","a.txt"]],"check":"modified blob","expected":[["M","a.txt"]],"passed":true},{"actual":[["M","run.sh"]],"check":"exec bit change is a modification","expected":[["M","run.sh"]],"passed":true},{"actual":[["T","lnk"]],"check":"file becomes a symlink","expected":[["T","lnk"]],"passed":true},{"actual":[["D","x"],["A","x"]],"check":"file replaced by a directory of the same name","expected":[["D","x"],["A","x"]],"passed":true},{"actual":[["A","a-c"],["M","a"]],"check":"directory sorts as name plus slash","expected":[["A","a-c"],["M","a"]],"passed":true},{"actual":[["A","z0"]],"check":"trailing additions and deletions","expected":[["A","z0"]],"passed":true},{"actual":[["D","y"]],"check":"only deletions at the end","expected":[["D","y"]],"passed":true},{"actual":[],"check":"hashes sharing a long prefix","expected":[["M","k"]],"passed":false},{"actual":[["D","a"],["A","b"]],"check":"added then removed around a common entry","expected":[["D","a"],["A","b"]],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"modified blob\", \"actual\": [[\"M\", \"a.txt\"]], \"expected\": [[\"M\", \"a.txt\"]], \"passed\": true}, {\"check\": \"exec bit change is a modification\", \"actual\": [[\"M\", \"run.sh\"]], \"expected\": [[\"M\", \"run.sh\"]], \"passed\": true}, {\"check\": \"file becomes a symlink\", \"actual\": [[\"T\", \"lnk\"]], \"expected\": [[\"T\", \"lnk\"]], \"passed\": true}, {\"check\": \"file replaced by a directory of the same name\", \"actual\": [[\"D\", \"x\"], [\"A\", \"x\"]], \"expected\": [[\"D\", \"x\"], [\"A\", \"x\"]], \"passed\": true}, {\"check\": \"directory sorts as name plus slash\", \"actual\": [[\"A\", \"a-c\"], [\"M\", \"a\"]], \"expected\": [[\"A\", \"a-c\"], [\"M\", \"a\"]], \"passed\": true}, {\"check\": \"trailing additions and deletions\", \"actual\": [[\"A\", \"z0\"]], \"expected\": [[\"A\", \"z0\"]], \"passed\": true}, {\"check\": \"only deletions at the end\", \"actual\": [[\"D\", \"y\"]], \"expected\": [[\"D\", \"y\"]], \"passed\": true}, {\"check\": \"hashes sharing a long prefix\", \"actual\": [], \"expected\": [[\"M\", \"k\"]], \"passed\": false}, {\"check\": \"added then removed around a common entry\", \"actual\": [[\"D\", \"a\"], [\"A\", \"b\"]], \"expected\": [[\"D\", \"a\"], [\"A\", \"b\"]], \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":40.534,"exit_code":1,"observations":[{"actual":[["M","a.txt"]],"check":"modified blob","expected":[["M","a.txt"]],"passed":true},{"actual":[],"check":"exec bit change is a modification","expected":[["M","run.sh"]],"passed":false},{"actual":[["T","lnk"]],"check":"file becomes a symlink","expected":[["T","lnk"]],"passed":true},{"actual":[["D","x"],["A","x"]],"check":"file replaced by a directory of the same name","expected":[["D","x"],["A","x"]],"passed":true},{"actual":[["A","a-c"],["M","a"]],"check":"directory sorts as name plus slash","expected":[["A","a-c"],["M","a"]],"passed":true},{"actual":[["A","z0"]],"check":"trailing additions and deletions","expected":[["A","z0"]],"passed":true},{"actual":[["D","y"]],"check":"only deletions at the end","expected":[["D","y"]],"passed":true},{"actual":[["M","k"]],"check":"hashes sharing a long prefix","expected":[["M","k"]],"passed":true},{"actual":[["D","a"],["A","b"]],"check":"added then removed around a common entry","expected":[["D","a"],["A","b"]],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"modified blob\", \"actual\": [[\"M\", \"a.txt\"]], \"expected\": [[\"M\", \"a.txt\"]], \"passed\": true}, {\"check\": \"exec bit change is a modification\", \"actual\": [], \"expected\": [[\"M\", \"run.sh\"]], \"passed\": false}, {\"check\": \"file becomes a symlink\", \"actual\": [[\"T\", \"lnk\"]], \"expected\": [[\"T\", \"lnk\"]], \"passed\": true}, {\"check\": \"file replaced by a directory of the same name\", \"actual\": [[\"D\", \"x\"], [\"A\", \"x\"]], \"expected\": [[\"D\", \"x\"], [\"A\", \"x\"]], \"passed\": true}, {\"check\": \"directory sorts as name plus slash\", \"actual\": [[\"A\", \"a-c\"], [\"M\", \"a\"]], \"expected\": [[\"A\", \"a-c\"], [\"M\", \"a\"]], \"passed\": true}, {\"check\": \"trailing additions and deletions\", \"actual\": [[\"A\", \"z0\"]], \"expected\": [[\"A\", \"z0\"]], \"passed\": true}, {\"check\": \"only deletions at the end\", \"actual\": [[\"D\", \"y\"]], \"expected\": [[\"D\", \"y\"]], \"passed\": true}, {\"check\": \"hashes sharing a long prefix\", \"actual\": [[\"M\", \"k\"]], \"expected\": [[\"M\", \"k\"]], \"passed\": true}, {\"check\": \"added then removed around a common entry\", \"actual\": [[\"D\", \"a\"], [\"A\", \"b\"]], \"expected\": [[\"D\", \"a\"], [\"A\", \"b\"]], \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":39.096,"exit_code":0,"observations":[{"actual":[["M","a.txt"]],"check":"modified blob","expected":[["M","a.txt"]],"passed":true},{"actual":[["M","run.sh"]],"check":"exec bit change is a modification","expected":[["M","run.sh"]],"passed":true},{"actual":[["T","lnk"]],"check":"file becomes a symlink","expected":[["T","lnk"]],"passed":true},{"actual":[["D","x"],["A","x"]],"check":"file replaced by a directory of the same name","expected":[["D","x"],["A","x"]],"passed":true},{"actual":[["A","a-c"],["M","a"]],"check":"directory sorts as name plus slash","expected":[["A","a-c"],["M","a"]],"passed":true},{"actual":[["A","z0"]],"check":"trailing additions and deletions","expected":[["A","z0"]],"passed":true},{"actual":[["D","y"]],"check":"only deletions at the end","expected":[["D","y"]],"passed":true},{"actual":[["M","k"]],"check":"hashes sharing a long prefix","expected":[["M","k"]],"passed":true},{"actual":[["D","a"],["A","b"]],"check":"added then removed around a common entry","expected":[["D","a"],["A","b"]],"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"modified blob\", \"actual\": [[\"M\", \"a.txt\"]], \"expected\": [[\"M\", \"a.txt\"]], \"passed\": true}, {\"check\": \"exec bit change is a modification\", \"actual\": [[\"M\", \"run.sh\"]], \"expected\": [[\"M\", \"run.sh\"]], \"passed\": true}, {\"check\": \"file becomes a symlink\", \"actual\": [[\"T\", \"lnk\"]], \"expected\": [[\"T\", \"lnk\"]], \"passed\": true}, {\"check\": \"file replaced by a directory of the same name\", \"actual\": [[\"D\", \"x\"], [\"A\", \"x\"]], \"expected\": [[\"D\", \"x\"], [\"A\", \"x\"]], \"passed\": true}, {\"check\": \"directory sorts as name plus slash\", \"actual\": [[\"A\", \"a-c\"], [\"M\", \"a\"]], \"expected\": [[\"A\", \"a-c\"], [\"M\", \"a\"]], \"passed\": true}, {\"check\": \"trailing additions and deletions\", \"actual\": [[\"A\", \"z0\"]], \"expected\": [[\"A\", \"z0\"]], \"passed\": true}, {\"check\": \"only deletions at the end\", \"actual\": [[\"D\", \"y\"]], \"expected\": [[\"D\", \"y\"]], \"passed\": true}, {\"check\": \"hashes sharing a long prefix\", \"actual\": [[\"M\", \"k\"]], \"expected\": [[\"M\", \"k\"]], \"passed\": true}, {\"check\": \"added then removed around a common entry\", \"actual\": [[\"D\", \"a\"], [\"A\", \"b\"]], \"expected\": [[\"D\", \"a\"], [\"A\", \"b\"]], \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}