{"abstract":"Range end drops a partially addressed astral character.","category":"Accessibility interaction semantics","checks":10,"contract":"Input [text,start,end,unit] where indices are measured in utf16 or codepoint units. Negative indices count backward from end, clamp to valid extent, and sort reversed endpoints. A boundary inside a surrogate pair expands outward (start down, end up). CRLF is exposed as one LF after slicing. NUL becomes replacement character. Return [exposed_text,normalized_start,normalized_end,source_units]. UTF16 offsets refer to original source, not normalized text.","evaluation_group":"s3-accessibility-text-range-bridge","failed_approach":"The local repair substitutes min(i for i,x in enumerate(edges) if x >= end) if end == size else max(i for i,x in enumerate(edges) if x <= end) but still mishandles the regression fixtures.","family":"s3-accessibility-text-range-bridge-end-surrogate","id":"FA-53456","implementations":{"attempt":{"sha256":"46fc6cc18006a02511ff53f93e240d40d693448834a6389a55b7342507e7e4a2","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(data):\n    text,start,end,unit = data\n    widths = [2 if unit == 'utf16' and ord(c) > 65535 else 1 for c in text]\n    edges = [0]\n    for width in widths: edges.append(edges[-1]+width)\n    size = edges[-1]\n    if start < 0: start += size\n    if end < 0: end += size\n    start = min(size,max(0,start))\n    end = min(size,max(0,end))\n    if start > end: start,end = end,start\n    left = max(i for i,x in enumerate(edges) if x <= start)\n    right = min(i for i,x in enumerate(edges) if x >= end) if end == size else max(i for i,x in enumerate(edges) if x <= end)\n    snippet = text[left:right].replace('\\r\\n','\\n').replace('\\x00','\\ufffd')\n    return [snippet,edges[left],edges[right],size]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncheck('surrogate interior expands', solve(['A'*N+'😀Z',N+1,N+2,'utf16'],), ['😀',N,N+2,N+3])\ncheck('negative start', solve(['A'*N+'BC',-2,N+2,'codepoint'],), ['BC',N,N+2,N+2])\ncheck('negative end', solve(['A'*N+'BC',N,-1,'codepoint'],), ['B',N,N+1,N+2])\ncheck('clamp both', solve(['AB',-20,40,'utf16'],), ['AB',0,2,2])\ncheck('reverse', solve(['ABCDE',4,1,'codepoint'],), ['BCD',1,4,5])\ncheck('CRLF normalization', solve(['A\\r\\nB',0,4,'utf16'],), ['A\\nB',0,4,4])\ncheck('NUL replacement', solve(['A\\x00B',0,3,'utf16'],), ['A�B',0,3,3])\ncheck('codepoint emoji', solve(['😀B',1,2,'codepoint'],), ['B',1,2,2])\ncheck('empty', solve(['',0,0,'utf16'],), ['',0,0,0])\ncheck('surrogate end expands', solve(['A😀Z',0,2,'utf16'],), ['A😀',0,3,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":"f6492e8686d956b29d2adcf8a5d16afc9f301938a65e40d79904e36329b158c1","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(data):\n    text,start,end,unit = data\n    widths = [2 if unit == 'utf16' and ord(c) > 65535 else 1 for c in text]\n    edges = [0]\n    for width in widths: edges.append(edges[-1]+width)\n    size = edges[-1]\n    if start < 0: start += size\n    if end < 0: end += size\n    start = min(size,max(0,start))\n    end = min(size,max(0,end))\n    if start > end: start,end = end,start\n    left = max(i for i,x in enumerate(edges) if x <= start)\n    right = max(i for i,x in enumerate(edges) if x <= end)\n    snippet = text[left:right].replace('\\r\\n','\\n').replace('\\x00','\\ufffd')\n    return [snippet,edges[left],edges[right],size]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncheck('surrogate interior expands', solve(['A'*N+'😀Z',N+1,N+2,'utf16'],), ['😀',N,N+2,N+3])\ncheck('negative start', solve(['A'*N+'BC',-2,N+2,'codepoint'],), ['BC',N,N+2,N+2])\ncheck('negative end', solve(['A'*N+'BC',N,-1,'codepoint'],), ['B',N,N+1,N+2])\ncheck('clamp both', solve(['AB',-20,40,'utf16'],), ['AB',0,2,2])\ncheck('reverse', solve(['ABCDE',4,1,'codepoint'],), ['BCD',1,4,5])\ncheck('CRLF normalization', solve(['A\\r\\nB',0,4,'utf16'],), ['A\\nB',0,4,4])\ncheck('NUL replacement', solve(['A\\x00B',0,3,'utf16'],), ['A�B',0,3,3])\ncheck('codepoint emoji', solve(['😀B',1,2,'codepoint'],), ['B',1,2,2])\ncheck('empty', solve(['',0,0,'utf16'],), ['',0,0,0])\ncheck('surrogate end expands', solve(['A😀Z',0,2,'utf16'],), ['A😀',0,3,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":"7eaa050111be90c437ec742e294457f17a16a44e622078e38a0dd32f96a504e1","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(data):\n    text,start,end,unit = data\n    widths = [2 if unit == 'utf16' and ord(c) > 65535 else 1 for c in text]\n    edges = [0]\n    for width in widths: edges.append(edges[-1]+width)\n    size = edges[-1]\n    if start < 0: start += size\n    if end < 0: end += size\n    start = min(size,max(0,start))\n    end = min(size,max(0,end))\n    if start > end: start,end = end,start\n    left = max(i for i,x in enumerate(edges) if x <= start)\n    right = min(i for i,x in enumerate(edges) if x >= end)\n    snippet = text[left:right].replace('\\r\\n','\\n').replace('\\x00','\\ufffd')\n    return [snippet,edges[left],edges[right],size]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncheck('surrogate interior expands', solve(['A'*N+'😀Z',N+1,N+2,'utf16'],), ['😀',N,N+2,N+3])\ncheck('negative start', solve(['A'*N+'BC',-2,N+2,'codepoint'],), ['BC',N,N+2,N+2])\ncheck('negative end', solve(['A'*N+'BC',N,-1,'codepoint'],), ['B',N,N+1,N+2])\ncheck('clamp both', solve(['AB',-20,40,'utf16'],), ['AB',0,2,2])\ncheck('reverse', solve(['ABCDE',4,1,'codepoint'],), ['BCD',1,4,5])\ncheck('CRLF normalization', solve(['A\\r\\nB',0,4,'utf16'],), ['A\\nB',0,4,4])\ncheck('NUL replacement', solve(['A\\x00B',0,3,'utf16'],), ['A�B',0,3,3])\ncheck('codepoint emoji', solve(['😀B',1,2,'codepoint'],), ['B',1,2,2])\ncheck('empty', solve(['',0,0,'utf16'],), ['',0,0,0])\ncheck('surrogate end expands', solve(['A😀Z',0,2,'utf16'],), ['A😀',0,3,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":"Stipulated finite adapter contract, not a claim of platform accessibility or ARIA conformance. 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":"s3-accessibility-text-range-bridge-end-surrogate","generated_at":"2026-09-29T14:45:39.189395+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Offline accessibility bridge model with explicit policy; useful for testing semantic API adapters independently of browser implementations.","repair":"Apply the exact contract at the end surrogate decision: min(i for i,x in enumerate(edges) if x >= end)","root_cause":"The end surrogate decision in the text range bridge adapter violates its declared contract.","sha256":"c07b2cb8ea81d886bc01f806114985554926f1a351691f3ffd1cdfb1758ca50c","title":"Range end drops a partially addressed astral character · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":38.066,"exit_code":1,"observations":[{"actual":["😀",1,3,4],"check":"surrogate interior expands","expected":["😀",1,3,4],"passed":true},{"actual":["BC",1,3,3],"check":"negative start","expected":["BC",1,3,3],"passed":true},{"actual":["B",1,2,3],"check":"negative end","expected":["B",1,2,3],"passed":true},{"actual":["AB",0,2,2],"check":"clamp both","expected":["AB",0,2,2],"passed":true},{"actual":["BCD",1,4,5],"check":"reverse","expected":["BCD",1,4,5],"passed":true},{"actual":["A\nB",0,4,4],"check":"CRLF normalization","expected":["A\nB",0,4,4],"passed":true},{"actual":["A�B",0,3,3],"check":"NUL replacement","expected":["A�B",0,3,3],"passed":true},{"actual":["B",1,2,2],"check":"codepoint emoji","expected":["B",1,2,2],"passed":true},{"actual":["",0,0,0],"check":"empty","expected":["",0,0,0],"passed":true},{"actual":["A",0,1,4],"check":"surrogate end expands","expected":["A😀",0,3,4],"passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"surrogate interior expands\", \"actual\": [\"😀\", 1, 3, 4], \"expected\": [\"😀\", 1, 3, 4], \"passed\": true}, {\"check\": \"negative start\", \"actual\": [\"BC\", 1, 3, 3], \"expected\": [\"BC\", 1, 3, 3], \"passed\": true}, {\"check\": \"negative end\", \"actual\": [\"B\", 1, 2, 3], \"expected\": [\"B\", 1, 2, 3], \"passed\": true}, {\"check\": \"clamp both\", \"actual\": [\"AB\", 0, 2, 2], \"expected\": [\"AB\", 0, 2, 2], \"passed\": true}, {\"check\": \"reverse\", \"actual\": [\"BCD\", 1, 4, 5], \"expected\": [\"BCD\", 1, 4, 5], \"passed\": true}, {\"check\": \"CRLF normalization\", \"actual\": [\"A\\nB\", 0, 4, 4], \"expected\": [\"A\\nB\", 0, 4, 4], \"passed\": true}, {\"check\": \"NUL replacement\", \"actual\": [\"A�B\", 0, 3, 3], \"expected\": [\"A�B\", 0, 3, 3], \"passed\": true}, {\"check\": \"codepoint emoji\", \"actual\": [\"B\", 1, 2, 2], \"expected\": [\"B\", 1, 2, 2], \"passed\": true}, {\"check\": \"empty\", \"actual\": [\"\", 0, 0, 0], \"expected\": [\"\", 0, 0, 0], \"passed\": true}, {\"check\": \"surrogate end expands\", \"actual\": [\"A\", 0, 1, 4], \"expected\": [\"A😀\", 0, 3, 4], \"passed\": false}], \"passed\": false}\n"},"broken":{"elapsed_ms":40.796,"exit_code":1,"observations":[{"actual":["😀",1,3,4],"check":"surrogate interior expands","expected":["😀",1,3,4],"passed":true},{"actual":["BC",1,3,3],"check":"negative start","expected":["BC",1,3,3],"passed":true},{"actual":["B",1,2,3],"check":"negative end","expected":["B",1,2,3],"passed":true},{"actual":["AB",0,2,2],"check":"clamp both","expected":["AB",0,2,2],"passed":true},{"actual":["BCD",1,4,5],"check":"reverse","expected":["BCD",1,4,5],"passed":true},{"actual":["A\nB",0,4,4],"check":"CRLF normalization","expected":["A\nB",0,4,4],"passed":true},{"actual":["A�B",0,3,3],"check":"NUL replacement","expected":["A�B",0,3,3],"passed":true},{"actual":["B",1,2,2],"check":"codepoint emoji","expected":["B",1,2,2],"passed":true},{"actual":["",0,0,0],"check":"empty","expected":["",0,0,0],"passed":true},{"actual":["A",0,1,4],"check":"surrogate end expands","expected":["A😀",0,3,4],"passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"surrogate interior expands\", \"actual\": [\"😀\", 1, 3, 4], \"expected\": [\"😀\", 1, 3, 4], \"passed\": true}, {\"check\": \"negative start\", \"actual\": [\"BC\", 1, 3, 3], \"expected\": [\"BC\", 1, 3, 3], \"passed\": true}, {\"check\": \"negative end\", \"actual\": [\"B\", 1, 2, 3], \"expected\": [\"B\", 1, 2, 3], \"passed\": true}, {\"check\": \"clamp both\", \"actual\": [\"AB\", 0, 2, 2], \"expected\": [\"AB\", 0, 2, 2], \"passed\": true}, {\"check\": \"reverse\", \"actual\": [\"BCD\", 1, 4, 5], \"expected\": [\"BCD\", 1, 4, 5], \"passed\": true}, {\"check\": \"CRLF normalization\", \"actual\": [\"A\\nB\", 0, 4, 4], \"expected\": [\"A\\nB\", 0, 4, 4], \"passed\": true}, {\"check\": \"NUL replacement\", \"actual\": [\"A�B\", 0, 3, 3], \"expected\": [\"A�B\", 0, 3, 3], \"passed\": true}, {\"check\": \"codepoint emoji\", \"actual\": [\"B\", 1, 2, 2], \"expected\": [\"B\", 1, 2, 2], \"passed\": true}, {\"check\": \"empty\", \"actual\": [\"\", 0, 0, 0], \"expected\": [\"\", 0, 0, 0], \"passed\": true}, {\"check\": \"surrogate end expands\", \"actual\": [\"A\", 0, 1, 4], \"expected\": [\"A😀\", 0, 3, 4], \"passed\": false}], \"passed\": false}\n"},"fixed":{"elapsed_ms":42.873,"exit_code":0,"observations":[{"actual":["😀",1,3,4],"check":"surrogate interior expands","expected":["😀",1,3,4],"passed":true},{"actual":["BC",1,3,3],"check":"negative start","expected":["BC",1,3,3],"passed":true},{"actual":["B",1,2,3],"check":"negative end","expected":["B",1,2,3],"passed":true},{"actual":["AB",0,2,2],"check":"clamp both","expected":["AB",0,2,2],"passed":true},{"actual":["BCD",1,4,5],"check":"reverse","expected":["BCD",1,4,5],"passed":true},{"actual":["A\nB",0,4,4],"check":"CRLF normalization","expected":["A\nB",0,4,4],"passed":true},{"actual":["A�B",0,3,3],"check":"NUL replacement","expected":["A�B",0,3,3],"passed":true},{"actual":["B",1,2,2],"check":"codepoint emoji","expected":["B",1,2,2],"passed":true},{"actual":["",0,0,0],"check":"empty","expected":["",0,0,0],"passed":true},{"actual":["A😀",0,3,4],"check":"surrogate end expands","expected":["A😀",0,3,4],"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"surrogate interior expands\", \"actual\": [\"😀\", 1, 3, 4], \"expected\": [\"😀\", 1, 3, 4], \"passed\": true}, {\"check\": \"negative start\", \"actual\": [\"BC\", 1, 3, 3], \"expected\": [\"BC\", 1, 3, 3], \"passed\": true}, {\"check\": \"negative end\", \"actual\": [\"B\", 1, 2, 3], \"expected\": [\"B\", 1, 2, 3], \"passed\": true}, {\"check\": \"clamp both\", \"actual\": [\"AB\", 0, 2, 2], \"expected\": [\"AB\", 0, 2, 2], \"passed\": true}, {\"check\": \"reverse\", \"actual\": [\"BCD\", 1, 4, 5], \"expected\": [\"BCD\", 1, 4, 5], \"passed\": true}, {\"check\": \"CRLF normalization\", \"actual\": [\"A\\nB\", 0, 4, 4], \"expected\": [\"A\\nB\", 0, 4, 4], \"passed\": true}, {\"check\": \"NUL replacement\", \"actual\": [\"A�B\", 0, 3, 3], \"expected\": [\"A�B\", 0, 3, 3], \"passed\": true}, {\"check\": \"codepoint emoji\", \"actual\": [\"B\", 1, 2, 2], \"expected\": [\"B\", 1, 2, 2], \"passed\": true}, {\"check\": \"empty\", \"actual\": [\"\", 0, 0, 0], \"expected\": [\"\", 0, 0, 0], \"passed\": true}, {\"check\": \"surrogate end expands\", \"actual\": [\"A😀\", 0, 3, 4], \"expected\": [\"A😀\", 0, 3, 4], \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}