{"abstract":"Changing direction moves the column to lowest priority.","category":"Table interactions","checks":9,"contract":"New sort is ascending; activation cycles ascending to descending to removed when allowed; single mode replaces all sorts; multi mode preserves priorities when changing direction.","contract_signature":"sorting, column, multi, removable","evaluation_group":"xi-sort-indicator","failed_approach":"Prepending duplicates the column instead of replacing its entry.","family":"xi-sort-indicator-priority","id":"FA-8951","implementations":{"attempt":{"sha256":"2d81295850a5e412abace5974d77fbd9a852e9057c4701737d9af1ac80151957","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(sorting, column, multi, removable):\n    sorting = list(sorting)\n    index = next((i for i, (c, d) in enumerate(sorting) if c == column), None)\n    if index is None: entry = (column, 'asc')\n    elif sorting[index][1] == 'asc': entry = (column, 'desc')\n    else: entry = None if removable else (column, 'asc')\n    if not multi: return [entry] if entry else []\n    if index is None: return sorting + [entry]\n    if entry is None: return sorting[:index] + sorting[index+1:]\n    sorting.insert(0, entry)\n    return sorting\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncheck('new', solve([], 'a', False, True), [('a', 'asc')])\ncheck('reverse', solve([('a','asc')], 'a', False, True), [('a', 'desc')])\ncheck('locked', solve([('a','desc')], 'a', False, False), [('a', 'asc')])\ncheck('remove', solve([('a','desc')], 'a', False, True), [])\ncheck('single', solve([('a','asc')], 'b', False, True), [('b', 'asc')])\ncheck('priority', solve([('a','asc'),('b','asc')], 'a', True, True), [('a', 'desc'), ('b', 'asc')])\ncheck('append', solve([('a','asc')], 'b', True, True), [('a', 'asc'), ('b', 'asc')])\ncheck('parameterized sort identity', solve([],str(N),False,True), [(str(N),'asc')])\nfor repetition in range(N):\n    check('repeat append', solve([('a','asc')], 'b', True, True), [('a', 'asc'), ('b', 'asc')])\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":"d71854637197a566753d2855914da30fb7e28ff8f12ed2cd511498353b1664d7","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(sorting, column, multi, removable):\n    sorting = list(sorting)\n    index = next((i for i, (c, d) in enumerate(sorting) if c == column), None)\n    if index is None: entry = (column, 'asc')\n    elif sorting[index][1] == 'asc': entry = (column, 'desc')\n    else: entry = None if removable else (column, 'asc')\n    if not multi: return [entry] if entry else []\n    if index is None: return sorting + [entry]\n    if entry is None: return sorting[:index] + sorting[index+1:]\n    sorting.pop(index); sorting.append(entry)\n    return sorting\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncheck('new', solve([], 'a', False, True), [('a', 'asc')])\ncheck('reverse', solve([('a','asc')], 'a', False, True), [('a', 'desc')])\ncheck('locked', solve([('a','desc')], 'a', False, False), [('a', 'asc')])\ncheck('remove', solve([('a','desc')], 'a', False, True), [])\ncheck('single', solve([('a','asc')], 'b', False, True), [('b', 'asc')])\ncheck('priority', solve([('a','asc'),('b','asc')], 'a', True, True), [('a', 'desc'), ('b', 'asc')])\ncheck('append', solve([('a','asc')], 'b', True, True), [('a', 'asc'), ('b', 'asc')])\ncheck('parameterized sort identity', solve([],str(N),False,True), [(str(N),'asc')])\nfor repetition in range(N):\n    check('repeat append', solve([('a','asc')], 'b', True, True), [('a', 'asc'), ('b', 'asc')])\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":" 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":"xi-sort-indicator-priority","generated_at":"2026-09-29T14:38:25.741482+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"A deterministic model of multi-column sort interaction; this isolates one interface invariant without requiring a browser.","root_cause":"The priority operation uses `sorting.pop(index); sorting.append(entry)` where the contract requires `sorting[index] = entry`.","sha256":"cfa41620e9d318874a34aaf58ea29225f28f21dc2c1422eca820bea9fa7d670d","title":"Multi-column sort interaction: Changing direction moves the column to lowest priority · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verified":true,"visibility":"public","verification":{"attempt":{"elapsed_ms":37.557,"exit_code":1,"observations":[{"actual":[["a","asc"]],"check":"new","expected":[["a","asc"]],"passed":true},{"actual":[["a","desc"]],"check":"reverse","expected":[["a","desc"]],"passed":true},{"actual":[["a","asc"]],"check":"locked","expected":[["a","asc"]],"passed":true},{"actual":[],"check":"remove","expected":[],"passed":true},{"actual":[["b","asc"]],"check":"single","expected":[["b","asc"]],"passed":true},{"actual":[["a","desc"],["a","asc"],["b","asc"]],"check":"priority","expected":[["a","desc"],["b","asc"]],"passed":false},{"actual":[["a","asc"],["b","asc"]],"check":"append","expected":[["a","asc"],["b","asc"]],"passed":true},{"actual":[["1","asc"]],"check":"parameterized sort identity","expected":[["1","asc"]],"passed":true},{"actual":[["a","asc"],["b","asc"]],"check":"repeat append","expected":[["a","asc"],["b","asc"]],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"new\", \"actual\": [[\"a\", \"asc\"]], \"expected\": [[\"a\", \"asc\"]], \"passed\": true}, {\"check\": \"reverse\", \"actual\": [[\"a\", \"desc\"]], \"expected\": [[\"a\", \"desc\"]], \"passed\": true}, {\"check\": \"locked\", \"actual\": [[\"a\", \"asc\"]], \"expected\": [[\"a\", \"asc\"]], \"passed\": true}, {\"check\": \"remove\", \"actual\": [], \"expected\": [], \"passed\": true}, {\"check\": \"single\", \"actual\": [[\"b\", \"asc\"]], \"expected\": [[\"b\", \"asc\"]], \"passed\": true}, {\"check\": \"priority\", \"actual\": [[\"a\", \"desc\"], [\"a\", \"asc\"], [\"b\", \"asc\"]], \"expected\": [[\"a\", \"desc\"], [\"b\", \"asc\"]], \"passed\": false}, {\"check\": \"append\", \"actual\": [[\"a\", \"asc\"], [\"b\", \"asc\"]], \"expected\": [[\"a\", \"asc\"], [\"b\", \"asc\"]], \"passed\": true}, {\"check\": \"parameterized sort identity\", \"actual\": [[\"1\", \"asc\"]], \"expected\": [[\"1\", \"asc\"]], \"passed\": true}, {\"check\": \"repeat append\", \"actual\": [[\"a\", \"asc\"], [\"b\", \"asc\"]], \"expected\": [[\"a\", \"asc\"], [\"b\", \"asc\"]], \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":37.768,"exit_code":1,"observations":[{"actual":[["a","asc"]],"check":"new","expected":[["a","asc"]],"passed":true},{"actual":[["a","desc"]],"check":"reverse","expected":[["a","desc"]],"passed":true},{"actual":[["a","asc"]],"check":"locked","expected":[["a","asc"]],"passed":true},{"actual":[],"check":"remove","expected":[],"passed":true},{"actual":[["b","asc"]],"check":"single","expected":[["b","asc"]],"passed":true},{"actual":[["b","asc"],["a","desc"]],"check":"priority","expected":[["a","desc"],["b","asc"]],"passed":false},{"actual":[["a","asc"],["b","asc"]],"check":"append","expected":[["a","asc"],["b","asc"]],"passed":true},{"actual":[["1","asc"]],"check":"parameterized sort identity","expected":[["1","asc"]],"passed":true},{"actual":[["a","asc"],["b","asc"]],"check":"repeat append","expected":[["a","asc"],["b","asc"]],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"new\", \"actual\": [[\"a\", \"asc\"]], \"expected\": [[\"a\", \"asc\"]], \"passed\": true}, {\"check\": \"reverse\", \"actual\": [[\"a\", \"desc\"]], \"expected\": [[\"a\", \"desc\"]], \"passed\": true}, {\"check\": \"locked\", \"actual\": [[\"a\", \"asc\"]], \"expected\": [[\"a\", \"asc\"]], \"passed\": true}, {\"check\": \"remove\", \"actual\": [], \"expected\": [], \"passed\": true}, {\"check\": \"single\", \"actual\": [[\"b\", \"asc\"]], \"expected\": [[\"b\", \"asc\"]], \"passed\": true}, {\"check\": \"priority\", \"actual\": [[\"b\", \"asc\"], [\"a\", \"desc\"]], \"expected\": [[\"a\", \"desc\"], [\"b\", \"asc\"]], \"passed\": false}, {\"check\": \"append\", \"actual\": [[\"a\", \"asc\"], [\"b\", \"asc\"]], \"expected\": [[\"a\", \"asc\"], [\"b\", \"asc\"]], \"passed\": true}, {\"check\": \"parameterized sort identity\", \"actual\": [[\"1\", \"asc\"]], \"expected\": [[\"1\", \"asc\"]], \"passed\": true}, {\"check\": \"repeat append\", \"actual\": [[\"a\", \"asc\"], [\"b\", \"asc\"]], \"expected\": [[\"a\", \"asc\"], [\"b\", \"asc\"]], \"passed\": true}], \"passed\": false}\n"}},"member_only":{"stages":["fixed"],"fields":["implementations.fixed","verification.fixed","harness","repair"],"note":"The verified repair, its recorded checks, the repair description, and the scoring harness are available to members."}}