{"abstract":"A second touch steals an active drag.","category":"Direct manipulation","checks":10,"contract":"First pointer captures ownership; only its movement and release affect a drag; cancellation and capture loss clear ownership while preserving position.","evaluation_group":"xi-pointer-capture","failed_approach":"Always retaining owner never captures the initial pointer.","family":"xi-pointer-capture-second-pointer","id":"FA-8231","implementations":{"attempt":{"sha256":"8d31798b1f605d0cecfeb036e8ef27da176dc7cffdfcb6792ffca44872d4d812","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(owner, position, event, pointer, delta):\n    if event == 'down': return (owner, position)\n    if event == 'move' and pointer == owner: return (owner, position + delta)\n    if event == 'up' and pointer == owner: return (None, position)\n    if event == 'cancel' and pointer == owner: return (None, position)\n    if event == 'lost': return (None, position)\n    return (owner, position)\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncheck('initial down', solve(None, 4, 'down', 1, 0), (1, 4))\ncheck('second down', solve(1, 4, 'down', 2, 0), (1, 4))\ncheck('other move', solve(1, 4, 'move', 2, 3), (1, 4))\ncheck('owner move', solve(1, 4, 'move', 1, 3), (1, 7))\ncheck('other up', solve(1, 4, 'up', 2, 0), (1, 4))\ncheck('owner up', solve(1, 4, 'up', 1, 0), (None, 4))\ncheck('cancel', solve(1, 4, 'cancel', 1, 0), (None, 4))\ncheck('lost', solve(1, 4, 'lost', 2, 0), (None, 4))\ncheck('parameterized pointer ownership', solve(N, N, 'move', N, N), (N,2*N))\nfor repetition in range(N):\n    check('repeat lost', solve(1, 4, 'lost', 2, 0), (None, 4))\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":"676eae6aea650a260e40b5871d6c7cd563a03ffcb4be5236d1797e16d077f64c","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(owner, position, event, pointer, delta):\n    if event == 'down': return (pointer, position)\n    if event == 'move' and pointer == owner: return (owner, position + delta)\n    if event == 'up' and pointer == owner: return (None, position)\n    if event == 'cancel' and pointer == owner: return (None, position)\n    if event == 'lost': return (None, position)\n    return (owner, position)\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncheck('initial down', solve(None, 4, 'down', 1, 0), (1, 4))\ncheck('second down', solve(1, 4, 'down', 2, 0), (1, 4))\ncheck('other move', solve(1, 4, 'move', 2, 3), (1, 4))\ncheck('owner move', solve(1, 4, 'move', 1, 3), (1, 7))\ncheck('other up', solve(1, 4, 'up', 2, 0), (1, 4))\ncheck('owner up', solve(1, 4, 'up', 1, 0), (None, 4))\ncheck('cancel', solve(1, 4, 'cancel', 1, 0), (None, 4))\ncheck('lost', solve(1, 4, 'lost', 2, 0), (None, 4))\ncheck('parameterized pointer ownership', solve(N, N, 'move', N, N), (N,2*N))\nfor repetition in range(N):\n    check('repeat lost', solve(1, 4, 'lost', 2, 0), (None, 4))\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":"b57d2a364c43b5fad81f31ca1ee3ae6da82ece5397810eca5948879bc52cd522","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(owner, position, event, pointer, delta):\n    if event == 'down': return (pointer if owner is None else owner, position)\n    if event == 'move' and pointer == owner: return (owner, position + delta)\n    if event == 'up' and pointer == owner: return (None, position)\n    if event == 'cancel' and pointer == owner: return (None, position)\n    if event == 'lost': return (None, position)\n    return (owner, position)\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncheck('initial down', solve(None, 4, 'down', 1, 0), (1, 4))\ncheck('second down', solve(1, 4, 'down', 2, 0), (1, 4))\ncheck('other move', solve(1, 4, 'move', 2, 3), (1, 4))\ncheck('owner move', solve(1, 4, 'move', 1, 3), (1, 7))\ncheck('other up', solve(1, 4, 'up', 2, 0), (1, 4))\ncheck('owner up', solve(1, 4, 'up', 1, 0), (None, 4))\ncheck('cancel', solve(1, 4, 'cancel', 1, 0), (None, 4))\ncheck('lost', solve(1, 4, 'lost', 2, 0), (None, 4))\ncheck('parameterized pointer ownership', solve(N, N, 'move', N, N), (N,2*N))\nfor repetition in range(N):\n    check('repeat lost', solve(1, 4, 'lost', 2, 0), (None, 4))\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-pointer-capture-second-pointer","generated_at":"2026-09-29T14:38:19.559329+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"A deterministic model of pointer-capture ownership; this isolates one interface invariant without requiring a browser.","repair":"Implement the second pointer operation as `pointer if owner is None else owner`.","root_cause":"The second pointer operation uses `pointer` where the contract requires `pointer if owner is None else owner`.","sha256":"4cc434d1eeae7e15aa5d43362c58e46db6f50ed47f66773cb48a6d5ffff46e3a","title":"Pointer-capture ownership: A second touch steals an active drag · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":38.014,"exit_code":1,"observations":[{"actual":[null,4],"check":"initial down","expected":[1,4],"passed":false},{"actual":[1,4],"check":"second down","expected":[1,4],"passed":true},{"actual":[1,4],"check":"other move","expected":[1,4],"passed":true},{"actual":[1,7],"check":"owner move","expected":[1,7],"passed":true},{"actual":[1,4],"check":"other up","expected":[1,4],"passed":true},{"actual":[null,4],"check":"owner up","expected":[null,4],"passed":true},{"actual":[null,4],"check":"cancel","expected":[null,4],"passed":true},{"actual":[null,4],"check":"lost","expected":[null,4],"passed":true},{"actual":[1,2],"check":"parameterized pointer ownership","expected":[1,2],"passed":true},{"actual":[null,4],"check":"repeat lost","expected":[null,4],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"initial down\", \"actual\": [null, 4], \"expected\": [1, 4], \"passed\": false}, {\"check\": \"second down\", \"actual\": [1, 4], \"expected\": [1, 4], \"passed\": true}, {\"check\": \"other move\", \"actual\": [1, 4], \"expected\": [1, 4], \"passed\": true}, {\"check\": \"owner move\", \"actual\": [1, 7], \"expected\": [1, 7], \"passed\": true}, {\"check\": \"other up\", \"actual\": [1, 4], \"expected\": [1, 4], \"passed\": true}, {\"check\": \"owner up\", \"actual\": [null, 4], \"expected\": [null, 4], \"passed\": true}, {\"check\": \"cancel\", \"actual\": [null, 4], \"expected\": [null, 4], \"passed\": true}, {\"check\": \"lost\", \"actual\": [null, 4], \"expected\": [null, 4], \"passed\": true}, {\"check\": \"parameterized pointer ownership\", \"actual\": [1, 2], \"expected\": [1, 2], \"passed\": true}, {\"check\": \"repeat lost\", \"actual\": [null, 4], \"expected\": [null, 4], \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":38.147,"exit_code":1,"observations":[{"actual":[1,4],"check":"initial down","expected":[1,4],"passed":true},{"actual":[2,4],"check":"second down","expected":[1,4],"passed":false},{"actual":[1,4],"check":"other move","expected":[1,4],"passed":true},{"actual":[1,7],"check":"owner move","expected":[1,7],"passed":true},{"actual":[1,4],"check":"other up","expected":[1,4],"passed":true},{"actual":[null,4],"check":"owner up","expected":[null,4],"passed":true},{"actual":[null,4],"check":"cancel","expected":[null,4],"passed":true},{"actual":[null,4],"check":"lost","expected":[null,4],"passed":true},{"actual":[1,2],"check":"parameterized pointer ownership","expected":[1,2],"passed":true},{"actual":[null,4],"check":"repeat lost","expected":[null,4],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"initial down\", \"actual\": [1, 4], \"expected\": [1, 4], \"passed\": true}, {\"check\": \"second down\", \"actual\": [2, 4], \"expected\": [1, 4], \"passed\": false}, {\"check\": \"other move\", \"actual\": [1, 4], \"expected\": [1, 4], \"passed\": true}, {\"check\": \"owner move\", \"actual\": [1, 7], \"expected\": [1, 7], \"passed\": true}, {\"check\": \"other up\", \"actual\": [1, 4], \"expected\": [1, 4], \"passed\": true}, {\"check\": \"owner up\", \"actual\": [null, 4], \"expected\": [null, 4], \"passed\": true}, {\"check\": \"cancel\", \"actual\": [null, 4], \"expected\": [null, 4], \"passed\": true}, {\"check\": \"lost\", \"actual\": [null, 4], \"expected\": [null, 4], \"passed\": true}, {\"check\": \"parameterized pointer ownership\", \"actual\": [1, 2], \"expected\": [1, 2], \"passed\": true}, {\"check\": \"repeat lost\", \"actual\": [null, 4], \"expected\": [null, 4], \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":36.47,"exit_code":0,"observations":[{"actual":[1,4],"check":"initial down","expected":[1,4],"passed":true},{"actual":[1,4],"check":"second down","expected":[1,4],"passed":true},{"actual":[1,4],"check":"other move","expected":[1,4],"passed":true},{"actual":[1,7],"check":"owner move","expected":[1,7],"passed":true},{"actual":[1,4],"check":"other up","expected":[1,4],"passed":true},{"actual":[null,4],"check":"owner up","expected":[null,4],"passed":true},{"actual":[null,4],"check":"cancel","expected":[null,4],"passed":true},{"actual":[null,4],"check":"lost","expected":[null,4],"passed":true},{"actual":[1,2],"check":"parameterized pointer ownership","expected":[1,2],"passed":true},{"actual":[null,4],"check":"repeat lost","expected":[null,4],"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"initial down\", \"actual\": [1, 4], \"expected\": [1, 4], \"passed\": true}, {\"check\": \"second down\", \"actual\": [1, 4], \"expected\": [1, 4], \"passed\": true}, {\"check\": \"other move\", \"actual\": [1, 4], \"expected\": [1, 4], \"passed\": true}, {\"check\": \"owner move\", \"actual\": [1, 7], \"expected\": [1, 7], \"passed\": true}, {\"check\": \"other up\", \"actual\": [1, 4], \"expected\": [1, 4], \"passed\": true}, {\"check\": \"owner up\", \"actual\": [null, 4], \"expected\": [null, 4], \"passed\": true}, {\"check\": \"cancel\", \"actual\": [null, 4], \"expected\": [null, 4], \"passed\": true}, {\"check\": \"lost\", \"actual\": [null, 4], \"expected\": [null, 4], \"passed\": true}, {\"check\": \"parameterized pointer ownership\", \"actual\": [1, 2], \"expected\": [1, 2], \"passed\": true}, {\"check\": \"repeat lost\", \"actual\": [null, 4], \"expected\": [null, 4], \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}