{"abstract":"Single-sort activation retains other sort priorities.","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":"Returning old state ignores the requested sort entirely.","family":"xi-sort-indicator-single-column","id":"FA-8946","implementations":{"attempt":{"sha256":"a813d87a5164588944b8438c6dbcf1957fe30f03f82368c9ec74337da87663ce","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 sorting\n    if index is None: return sorting + [entry]\n    if entry is None: return sorting[:index] + sorting[index+1:]\n    sorting[index] = 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":"47bff2abececb4c424ad6c6e461817d1e36f87435e6e90c8cfce79f3cb6bbc72","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 sorting + ([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[index] = 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-single-column","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 single column operation uses `if not multi: return sorting + ([entry] if entry else [])` where the contract requires `if not multi: return [entry] if entry else []`.","sha256":"28230cf1d1d430a23dfa823464ac8ff52084c2073eea015802ceed14db437e15","title":"Multi-column sort interaction: Single-sort activation retains other sort priorities · 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.066,"exit_code":1,"observations":[{"actual":[],"check":"new","expected":[["a","asc"]],"passed":false},{"actual":[["a","asc"]],"check":"reverse","expected":[["a","desc"]],"passed":false},{"actual":[["a","desc"]],"check":"locked","expected":[["a","asc"]],"passed":false},{"actual":[["a","desc"]],"check":"remove","expected":[],"passed":false},{"actual":[["a","asc"]],"check":"single","expected":[["b","asc"]],"passed":false},{"actual":[["a","desc"],["b","asc"]],"check":"priority","expected":[["a","desc"],["b","asc"]],"passed":true},{"actual":[["a","asc"],["b","asc"]],"check":"append","expected":[["a","asc"],["b","asc"]],"passed":true},{"actual":[],"check":"parameterized sort identity","expected":[["1","asc"]],"passed":false},{"actual":[["a","asc"],["b","asc"]],"check":"repeat append","expected":[["a","asc"],["b","asc"]],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"new\", \"actual\": [], \"expected\": [[\"a\", \"asc\"]], \"passed\": false}, {\"check\": \"reverse\", \"actual\": [[\"a\", \"asc\"]], \"expected\": [[\"a\", \"desc\"]], \"passed\": false}, {\"check\": \"locked\", \"actual\": [[\"a\", \"desc\"]], \"expected\": [[\"a\", \"asc\"]], \"passed\": false}, {\"check\": \"remove\", \"actual\": [[\"a\", \"desc\"]], \"expected\": [], \"passed\": false}, {\"check\": \"single\", \"actual\": [[\"a\", \"asc\"]], \"expected\": [[\"b\", \"asc\"]], \"passed\": false}, {\"check\": \"priority\", \"actual\": [[\"a\", \"desc\"], [\"b\", \"asc\"]], \"expected\": [[\"a\", \"desc\"], [\"b\", \"asc\"]], \"passed\": true}, {\"check\": \"append\", \"actual\": [[\"a\", \"asc\"], [\"b\", \"asc\"]], \"expected\": [[\"a\", \"asc\"], [\"b\", \"asc\"]], \"passed\": true}, {\"check\": \"parameterized sort identity\", \"actual\": [], \"expected\": [[\"1\", \"asc\"]], \"passed\": false}, {\"check\": \"repeat append\", \"actual\": [[\"a\", \"asc\"], [\"b\", \"asc\"]], \"expected\": [[\"a\", \"asc\"], [\"b\", \"asc\"]], \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":36.193,"exit_code":1,"observations":[{"actual":[["a","asc"]],"check":"new","expected":[["a","asc"]],"passed":true},{"actual":[["a","asc"],["a","desc"]],"check":"reverse","expected":[["a","desc"]],"passed":false},{"actual":[["a","desc"],["a","asc"]],"check":"locked","expected":[["a","asc"]],"passed":false},{"actual":[["a","desc"]],"check":"remove","expected":[],"passed":false},{"actual":[["a","asc"],["b","asc"]],"check":"single","expected":[["b","asc"]],"passed":false},{"actual":[["a","desc"],["b","asc"]],"check":"priority","expected":[["a","desc"],["b","asc"]],"passed":true},{"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\", \"asc\"], [\"a\", \"desc\"]], \"expected\": [[\"a\", \"desc\"]], \"passed\": false}, {\"check\": \"locked\", \"actual\": [[\"a\", \"desc\"], [\"a\", \"asc\"]], \"expected\": [[\"a\", \"asc\"]], \"passed\": false}, {\"check\": \"remove\", \"actual\": [[\"a\", \"desc\"]], \"expected\": [], \"passed\": false}, {\"check\": \"single\", \"actual\": [[\"a\", \"asc\"], [\"b\", \"asc\"]], \"expected\": [[\"b\", \"asc\"]], \"passed\": false}, {\"check\": \"priority\", \"actual\": [[\"a\", \"desc\"], [\"b\", \"asc\"]], \"expected\": [[\"a\", \"desc\"], [\"b\", \"asc\"]], \"passed\": true}, {\"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."}}