{"abstract":"Latitudes are returned in radians.","category":"Map projection transforms","checks":8,"contract":"Input [x, y] metres (sphere radius 6378137). Eastings outside the world extent E = 20037508.342789244 are wrapped into [-E, E) first. Return [lon, lat] in degrees rounded to 7 decimals.","evaluation_group":"w2-map-projection-transforms-web-mercator-inverse","failed_approach":"The degree conversion is applied before subtracting pi/2, mixing units in the offset.","family":"w2-map-projection-transforms-web-mercator-inverse-latitude-radian-conversion","id":"FA-69886","implementations":{"attempt":{"sha256":"766924d6ae12b4029bcf2d531f3f8a076c2e13ff86102344aefa790e6f02e8f2","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nN = 1\nobservations = []\ndef solve(x):\n    px, py = x\n    R = 6378137.0\n    E = 20037508.342789244\n    px = ((px + E) % (2 * E)) - E\n    lon = math.degrees(px / R)\n    lat = math.degrees(2 * math.atan(math.exp(py / R))) - math.pi / 2\n    return [round(lon, 7), round(lat, 7)]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('regression #0', [25000000.0, 1000000.0], [-135.421179, 8.9465739]), ('regression #1', [-30000000.0, -2000000.0], [90.5054148, -17.6789142]), ('boundary #2', [20037508.342789244, 0.0], [-180.0, 0.0]), ('control #3', [0.0, 0.0], [0.0, 0.0]), ('control #4', [1113194.9, 1118889.97], [9.9999999, 10.0]), ('control #5', [-8237642.3, 4970241.3], [-73.9999998, 40.7139556]), ('control #6', [15000000.0, -6000000.0], [134.7472926, -47.3537047]), ('boundary #7', [0.0, 20037508.342789244], [0.0, 85.0511288])], [('regression #1', [-30000000.0, -2000000.0], [90.5054148, -17.6789142]), ('boundary #2', [20037508.342789244, 0.0], [-180.0, 0.0]), ('control #5', [-8237642.3, 4970241.3], [-73.9999998, 40.7139556]), ('control #6', [15000000.0, -6000000.0], [134.7472926, -47.3537047]), ('boundary #7', [0.0, 20037508.342789244], [0.0, 85.0511288]), ('boundary #8', [0.0, -20037508.342789244], [0.0, -85.0511288]), ('control #9', [500000.0, -500000.0], [4.4915764, -4.486983]), ('control #10', [-19000000.0, 12000000.0], [-170.679904, 72.6726763])], [('boundary #2', [20037508.342789244, 0.0], [-180.0, 0.0]), ('control #4', [1113194.9, 1118889.97], [9.9999999, 10.0]), ('boundary #8', [0.0, -20037508.342789244], [0.0, -85.0511288]), ('control #9', [500000.0, -500000.0], [4.4915764, -4.486983]), ('control #10', [-19000000.0, 12000000.0], [-170.679904, 72.6726763]), ('control #11', [3000000.0, 9000000.0], [26.9494585, 62.5882773]), ('regression #12', [45000000.0, 3000000.0], [44.2418779, 26.0074202]), ('control #13', [-1234567.0, 7654321.0], [-11.0903041, 56.4787668])], [('control #3', [0.0, 0.0], [0.0, 0.0]), ('control #5', [-8237642.3, 4970241.3], [-73.9999998, 40.7139556]), ('control #11', [3000000.0, 9000000.0], [26.9494585, 62.5882773]), ('regression #12', [45000000.0, 3000000.0], [44.2418779, 26.0074202]), ('control #13', [-1234567.0, 7654321.0], [-11.0903041, 56.4787668]), ('regression #14', [-21000000.0, 500000.0], [171.3537903, 4.486983]), ('regression #15', [-25000000.0, -4000000.0], [135.421179, -33.7852301]), ('regression #16', [-40075016.0, 0.0], [6.2e-06, 0.0])], [('regression #0', [25000000.0, 1000000.0], [-135.421179, 8.9465739]), ('regression #1', [-30000000.0, -2000000.0], [90.5054148, -17.6789142]), ('boundary #2', [20037508.342789244, 0.0], [-180.0, 0.0]), ('control #4', [1113194.9, 1118889.97], [9.9999999, 10.0]), ('control #6', [15000000.0, -6000000.0], [134.7472926, -47.3537047]), ('regression #14', [-21000000.0, 500000.0], [171.3537903, 4.486983]), ('regression #15', [-25000000.0, -4000000.0], [135.421179, -33.7852301]), ('regression #16', [-40075016.0, 0.0], [6.2e-06, 0.0])]]\nfor label, args, expected in fixtures[N-1]:\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":"36db59cf449ad17b80b004580255bc96057109f42ded3120be456dd9283ba314","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nN = 1\nobservations = []\ndef solve(x):\n    px, py = x\n    R = 6378137.0\n    E = 20037508.342789244\n    px = ((px + E) % (2 * E)) - E\n    lon = math.degrees(px / R)\n    lat = 2 * math.atan(math.exp(py / R)) - math.pi / 2\n    return [round(lon, 7), round(lat, 7)]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('regression #0', [25000000.0, 1000000.0], [-135.421179, 8.9465739]), ('regression #1', [-30000000.0, -2000000.0], [90.5054148, -17.6789142]), ('boundary #2', [20037508.342789244, 0.0], [-180.0, 0.0]), ('control #3', [0.0, 0.0], [0.0, 0.0]), ('control #4', [1113194.9, 1118889.97], [9.9999999, 10.0]), ('control #5', [-8237642.3, 4970241.3], [-73.9999998, 40.7139556]), ('control #6', [15000000.0, -6000000.0], [134.7472926, -47.3537047]), ('boundary #7', [0.0, 20037508.342789244], [0.0, 85.0511288])], [('regression #1', [-30000000.0, -2000000.0], [90.5054148, -17.6789142]), ('boundary #2', [20037508.342789244, 0.0], [-180.0, 0.0]), ('control #5', [-8237642.3, 4970241.3], [-73.9999998, 40.7139556]), ('control #6', [15000000.0, -6000000.0], [134.7472926, -47.3537047]), ('boundary #7', [0.0, 20037508.342789244], [0.0, 85.0511288]), ('boundary #8', [0.0, -20037508.342789244], [0.0, -85.0511288]), ('control #9', [500000.0, -500000.0], [4.4915764, -4.486983]), ('control #10', [-19000000.0, 12000000.0], [-170.679904, 72.6726763])], [('boundary #2', [20037508.342789244, 0.0], [-180.0, 0.0]), ('control #4', [1113194.9, 1118889.97], [9.9999999, 10.0]), ('boundary #8', [0.0, -20037508.342789244], [0.0, -85.0511288]), ('control #9', [500000.0, -500000.0], [4.4915764, -4.486983]), ('control #10', [-19000000.0, 12000000.0], [-170.679904, 72.6726763]), ('control #11', [3000000.0, 9000000.0], [26.9494585, 62.5882773]), ('regression #12', [45000000.0, 3000000.0], [44.2418779, 26.0074202]), ('control #13', [-1234567.0, 7654321.0], [-11.0903041, 56.4787668])], [('control #3', [0.0, 0.0], [0.0, 0.0]), ('control #5', [-8237642.3, 4970241.3], [-73.9999998, 40.7139556]), ('control #11', [3000000.0, 9000000.0], [26.9494585, 62.5882773]), ('regression #12', [45000000.0, 3000000.0], [44.2418779, 26.0074202]), ('control #13', [-1234567.0, 7654321.0], [-11.0903041, 56.4787668]), ('regression #14', [-21000000.0, 500000.0], [171.3537903, 4.486983]), ('regression #15', [-25000000.0, -4000000.0], [135.421179, -33.7852301]), ('regression #16', [-40075016.0, 0.0], [6.2e-06, 0.0])], [('regression #0', [25000000.0, 1000000.0], [-135.421179, 8.9465739]), ('regression #1', [-30000000.0, -2000000.0], [90.5054148, -17.6789142]), ('boundary #2', [20037508.342789244, 0.0], [-180.0, 0.0]), ('control #4', [1113194.9, 1118889.97], [9.9999999, 10.0]), ('control #6', [15000000.0, -6000000.0], [134.7472926, -47.3537047]), ('regression #14', [-21000000.0, 500000.0], [171.3537903, 4.486983]), ('regression #15', [-25000000.0, -4000000.0], [135.421179, -33.7852301]), ('regression #16', [-40075016.0, 0.0], [6.2e-06, 0.0])]]\nfor label, args, expected in fixtures[N-1]:\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":"d0b617e3650aada5398d846d37a5b750d23ff047f2a5d8eb36ca8974c9021eec","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nN = 1\nobservations = []\ndef solve(x):\n    px, py = x\n    R = 6378137.0\n    E = 20037508.342789244\n    px = ((px + E) % (2 * E)) - E\n    lon = math.degrees(px / R)\n    lat = math.degrees(2 * math.atan(math.exp(py / R)) - math.pi / 2)\n    return [round(lon, 7), round(lat, 7)]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('regression #0', [25000000.0, 1000000.0], [-135.421179, 8.9465739]), ('regression #1', [-30000000.0, -2000000.0], [90.5054148, -17.6789142]), ('boundary #2', [20037508.342789244, 0.0], [-180.0, 0.0]), ('control #3', [0.0, 0.0], [0.0, 0.0]), ('control #4', [1113194.9, 1118889.97], [9.9999999, 10.0]), ('control #5', [-8237642.3, 4970241.3], [-73.9999998, 40.7139556]), ('control #6', [15000000.0, -6000000.0], [134.7472926, -47.3537047]), ('boundary #7', [0.0, 20037508.342789244], [0.0, 85.0511288])], [('regression #1', [-30000000.0, -2000000.0], [90.5054148, -17.6789142]), ('boundary #2', [20037508.342789244, 0.0], [-180.0, 0.0]), ('control #5', [-8237642.3, 4970241.3], [-73.9999998, 40.7139556]), ('control #6', [15000000.0, -6000000.0], [134.7472926, -47.3537047]), ('boundary #7', [0.0, 20037508.342789244], [0.0, 85.0511288]), ('boundary #8', [0.0, -20037508.342789244], [0.0, -85.0511288]), ('control #9', [500000.0, -500000.0], [4.4915764, -4.486983]), ('control #10', [-19000000.0, 12000000.0], [-170.679904, 72.6726763])], [('boundary #2', [20037508.342789244, 0.0], [-180.0, 0.0]), ('control #4', [1113194.9, 1118889.97], [9.9999999, 10.0]), ('boundary #8', [0.0, -20037508.342789244], [0.0, -85.0511288]), ('control #9', [500000.0, -500000.0], [4.4915764, -4.486983]), ('control #10', [-19000000.0, 12000000.0], [-170.679904, 72.6726763]), ('control #11', [3000000.0, 9000000.0], [26.9494585, 62.5882773]), ('regression #12', [45000000.0, 3000000.0], [44.2418779, 26.0074202]), ('control #13', [-1234567.0, 7654321.0], [-11.0903041, 56.4787668])], [('control #3', [0.0, 0.0], [0.0, 0.0]), ('control #5', [-8237642.3, 4970241.3], [-73.9999998, 40.7139556]), ('control #11', [3000000.0, 9000000.0], [26.9494585, 62.5882773]), ('regression #12', [45000000.0, 3000000.0], [44.2418779, 26.0074202]), ('control #13', [-1234567.0, 7654321.0], [-11.0903041, 56.4787668]), ('regression #14', [-21000000.0, 500000.0], [171.3537903, 4.486983]), ('regression #15', [-25000000.0, -4000000.0], [135.421179, -33.7852301]), ('regression #16', [-40075016.0, 0.0], [6.2e-06, 0.0])], [('regression #0', [25000000.0, 1000000.0], [-135.421179, 8.9465739]), ('regression #1', [-30000000.0, -2000000.0], [90.5054148, -17.6789142]), ('boundary #2', [20037508.342789244, 0.0], [-180.0, 0.0]), ('control #4', [1113194.9, 1118889.97], [9.9999999, 10.0]), ('control #6', [15000000.0, -6000000.0], [134.7472926, -47.3537047]), ('regression #14', [-21000000.0, 500000.0], [171.3537903, 4.486983]), ('regression #15', [-25000000.0, -4000000.0], [135.421179, -33.7852301]), ('regression #16', [-40075016.0, 0.0], [6.2e-06, 0.0])]]\nfor label, args, expected in fixtures[N-1]:\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":"Stipulated deterministic toy contract on a bounded input domain; results are rounded as stated and no conformance with any published standard or library is claimed. 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-map-projection-transforms-web-mercator-inverse-latitude-radian-conversion","generated_at":"2026-09-29T14:48:15.572353+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Converting clicked map positions or tile corners back to geographic coordinates uses this inverse; faults misplace every reverse-geocoded point.","repair":"At the latitude radian conversion step restore `lat = math.degrees(2 * math.atan(math.exp(py / R)) - math.pi / 2)`, leaving the rest of the model unchanged.","root_cause":"The inverse Gudermannian result is never converted from radians to degrees.","sha256":"b806f7e8e26b8ce900bd91207ca911d259667503b962c835c74292d80b90d6a5","title":"Spherical web mercator inverse projection: latitude radian conversion · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":39.447,"exit_code":1,"observations":[{"actual":[-135.421179,97.3757775],"check":"regression #0","expected":[-135.421179,8.9465739],"passed":false},{"actual":[90.5054148,70.7502894],"check":"regression #1","expected":[90.5054148,-17.6789142],"passed":false},{"actual":[-180.0,88.4292037],"check":"boundary #2","expected":[-180.0,0.0],"passed":false},{"actual":[0.0,88.4292037],"check":"control #3","expected":[0.0,0.0],"passed":false},{"actual":[9.9999999,98.4292036],"check":"control #4","expected":[9.9999999,10.0],"passed":false},{"actual":[-73.9999998,129.1431593],"check":"control #5","expected":[-73.9999998,40.7139556],"passed":false},{"actual":[134.7472926,41.075499],"check":"control #6","expected":[134.7472926,-47.3537047],"passed":false},{"actual":[0.0,173.4803325],"check":"boundary #7","expected":[0.0,85.0511288],"passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression #0\", \"actual\": [-135.421179, 97.3757775], \"expected\": [-135.421179, 8.9465739], \"passed\": false}, {\"check\": \"regression #1\", \"actual\": [90.5054148, 70.7502894], \"expected\": [90.5054148, -17.6789142], \"passed\": false}, {\"check\": \"boundary #2\", \"actual\": [-180.0, 88.4292037], \"expected\": [-180.0, 0.0], \"passed\": false}, {\"check\": \"control #3\", \"actual\": [0.0, 88.4292037], \"expected\": [0.0, 0.0], \"passed\": false}, {\"check\": \"control #4\", \"actual\": [9.9999999, 98.4292036], \"expected\": [9.9999999, 10.0], \"passed\": false}, {\"check\": \"control #5\", \"actual\": [-73.9999998, 129.1431593], \"expected\": [-73.9999998, 40.7139556], \"passed\": false}, {\"check\": \"control #6\", \"actual\": [134.7472926, 41.075499], \"expected\": [134.7472926, -47.3537047], \"passed\": false}, {\"check\": \"boundary #7\", \"actual\": [0.0, 173.4803325], \"expected\": [0.0, 85.0511288], \"passed\": false}], \"passed\": false}\n"},"broken":{"elapsed_ms":38.249,"exit_code":1,"observations":[{"actual":[-135.421179,0.1561472],"check":"regression #0","expected":[-135.421179,8.9465739],"passed":false},{"actual":[90.5054148,-0.3085553],"check":"regression #1","expected":[90.5054148,-17.6789142],"passed":false},{"actual":[-180.0,0.0],"check":"boundary #2","expected":[-180.0,0.0],"passed":true},{"actual":[0.0,0.0],"check":"control #3","expected":[0.0,0.0],"passed":true},{"actual":[9.9999999,0.1745329],"check":"control #4","expected":[9.9999999,10.0],"passed":false},{"actual":[-73.9999998,0.7105926],"check":"control #5","expected":[-73.9999998,40.7139556],"passed":false},{"actual":[134.7472926,-0.8264781],"check":"control #6","expected":[134.7472926,-47.3537047],"passed":false},{"actual":[0.0,1.4844222],"check":"boundary #7","expected":[0.0,85.0511288],"passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression #0\", \"actual\": [-135.421179, 0.1561472], \"expected\": [-135.421179, 8.9465739], \"passed\": false}, {\"check\": \"regression #1\", \"actual\": [90.5054148, -0.3085553], \"expected\": [90.5054148, -17.6789142], \"passed\": false}, {\"check\": \"boundary #2\", \"actual\": [-180.0, 0.0], \"expected\": [-180.0, 0.0], \"passed\": true}, {\"check\": \"control #3\", \"actual\": [0.0, 0.0], \"expected\": [0.0, 0.0], \"passed\": true}, {\"check\": \"control #4\", \"actual\": [9.9999999, 0.1745329], \"expected\": [9.9999999, 10.0], \"passed\": false}, {\"check\": \"control #5\", \"actual\": [-73.9999998, 0.7105926], \"expected\": [-73.9999998, 40.7139556], \"passed\": false}, {\"check\": \"control #6\", \"actual\": [134.7472926, -0.8264781], \"expected\": [134.7472926, -47.3537047], \"passed\": false}, {\"check\": \"boundary #7\", \"actual\": [0.0, 1.4844222], \"expected\": [0.0, 85.0511288], \"passed\": false}], \"passed\": false}\n"},"fixed":{"elapsed_ms":43.076,"exit_code":0,"observations":[{"actual":[-135.421179,8.9465739],"check":"regression #0","expected":[-135.421179,8.9465739],"passed":true},{"actual":[90.5054148,-17.6789142],"check":"regression #1","expected":[90.5054148,-17.6789142],"passed":true},{"actual":[-180.0,0.0],"check":"boundary #2","expected":[-180.0,0.0],"passed":true},{"actual":[0.0,0.0],"check":"control #3","expected":[0.0,0.0],"passed":true},{"actual":[9.9999999,10.0],"check":"control #4","expected":[9.9999999,10.0],"passed":true},{"actual":[-73.9999998,40.7139556],"check":"control #5","expected":[-73.9999998,40.7139556],"passed":true},{"actual":[134.7472926,-47.3537047],"check":"control #6","expected":[134.7472926,-47.3537047],"passed":true},{"actual":[0.0,85.0511288],"check":"boundary #7","expected":[0.0,85.0511288],"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression #0\", \"actual\": [-135.421179, 8.9465739], \"expected\": [-135.421179, 8.9465739], \"passed\": true}, {\"check\": \"regression #1\", \"actual\": [90.5054148, -17.6789142], \"expected\": [90.5054148, -17.6789142], \"passed\": true}, {\"check\": \"boundary #2\", \"actual\": [-180.0, 0.0], \"expected\": [-180.0, 0.0], \"passed\": true}, {\"check\": \"control #3\", \"actual\": [0.0, 0.0], \"expected\": [0.0, 0.0], \"passed\": true}, {\"check\": \"control #4\", \"actual\": [9.9999999, 10.0], \"expected\": [9.9999999, 10.0], \"passed\": true}, {\"check\": \"control #5\", \"actual\": [-73.9999998, 40.7139556], \"expected\": [-73.9999998, 40.7139556], \"passed\": true}, {\"check\": \"control #6\", \"actual\": [134.7472926, -47.3537047], \"expected\": [134.7472926, -47.3537047], \"passed\": true}, {\"check\": \"boundary #7\", \"actual\": [0.0, 85.0511288], \"expected\": [0.0, 85.0511288], \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}