{"abstract":"Features east of the antimeridian or given in [180, 540) ranges land off the projected world extent.","category":"Map projection transforms","checks":8,"contract":"Input [lon, lat] in degrees. Longitude is first wrapped into the half-open range [-180, 180); latitude is clamped to +/-85.05112878. Return [x, y] metres on a sphere of radius 6378137 with y growing northward, each rounded to 3 decimals.","evaluation_group":"w2-map-projection-transforms-web-mercator-forward","failed_approach":"math.fmod keeps the sign of the dividend, so longitudes below -180 still come out below -180.","family":"w2-map-projection-transforms-web-mercator-forward-longitude-wrap","id":"FA-69841","implementations":{"attempt":{"sha256":"d84a71cf9a090a5794f49d9870535fc33a699e53b9a8f8ccb26796033446f8a7","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nN = 1\nobservations = []\ndef solve(x):\n    lon, lat = x\n    lon = math.fmod(lon + 180.0, 360.0) - 180.0\n    lat = max(-85.05112878, min(85.05112878, lat))\n    R = 6378137.0\n    px = R * math.radians(lon)\n    py = R * math.log(math.tan(math.pi / 4 + math.radians(lat) / 2))\n    return [round(px, 3), round(py, 3)]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('regression #0', [190.0, 10.0], [-18924313.435, 1118889.975]), ('regression #1', [-200.0, -20.0], [17811118.527, -2273030.927]), ('boundary #2', [180.0, 0.0], [-20037508.343, -0.0]), ('boundary #3', [-180.0, 45.0], [-20037508.343, 5621521.486]), ('regression #4', [545.0, 5.0], [-19480910.889, 557305.257]), ('boundary #5', [0.0, 89.0], [0.0, 20037508.343]), ('boundary #6', [10.0, -88.0], [1113194.908, -20037508.343]), ('regression #10', [-250.0, 12.5], [12245143.987, 1402665.19])], [('boundary #2', [180.0, 0.0], [-20037508.343, -0.0]), ('regression #4', [545.0, 5.0], [-19480910.889, 557305.257]), ('boundary #5', [0.0, 89.0], [0.0, 20037508.343]), ('boundary #6', [10.0, -88.0], [1113194.908, -20037508.343]), ('boundary #7', [0.0, 85.05112878], [0.0, 20037508.343]), ('control #8', [0.0, 0.0], [0.0, -0.0]), ('regression #9', [-540.0, 30.0], [-20037508.343, 3503549.844]), ('regression #10', [-250.0, 12.5], [12245143.987, 1402665.19])], [('regression #4', [545.0, 5.0], [-19480910.889, 557305.257]), ('boundary #7', [0.0, 85.05112878], [0.0, 20037508.343]), ('control #8', [0.0, 0.0], [0.0, -0.0]), ('regression #9', [-540.0, 30.0], [-20037508.343, 3503549.844]), ('regression #10', [-250.0, 12.5], [12245143.987, 1402665.19]), ('regression #11', [-359.5, -40.0], [55659.745, -4865942.28]), ('boundary #12', [45.0, -86.5], [5009377.086, -20037508.343]), ('boundary #13', [-120.0, -87.25], [-13358338.895, -20037508.343])], [('regression #9', [-540.0, 30.0], [-20037508.343, 3503549.844]), ('regression #10', [-250.0, 12.5], [12245143.987, 1402665.19]), ('regression #11', [-359.5, -40.0], [55659.745, -4865942.28]), ('boundary #12', [45.0, -86.5], [5009377.086, -20037508.343]), ('boundary #13', [-120.0, -87.25], [-13358338.895, -20037508.343]), ('regression #14', [-181.0, 0.5], [19926188.852, 55660.452]), ('control #15', [-17.048, 10.042], [-1897774.679, 1123637.827]), ('control #16', [151.867, -5.771], [16905757.108, -643513.79])], [('regression #10', [-250.0, 12.5], [12245143.987, 1402665.19]), ('regression #11', [-359.5, -40.0], [55659.745, -4865942.28]), ('regression #14', [-181.0, 0.5], [19926188.852, 55660.452]), ('control #15', [-17.048, 10.042], [-1897774.679, 1123637.827]), ('control #16', [151.867, -5.771], [16905757.108, -643513.79]), ('control #17', [2.807, 14.681], [312473.811, 1652463.738]), ('control #18', [-112.892, 2.001], [-12567079.955, 222795.596]), ('control #19', [46.498, 49.22], [5176133.683, 6312273.571])]]\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":"12bc903f10fbf807780a501880be6218ba92853f46b16378030db73b773239f1","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nN = 1\nobservations = []\ndef solve(x):\n    lon, lat = x\n    lon = lon if abs(lon) <= 180.0 else lon - 360.0\n    lat = max(-85.05112878, min(85.05112878, lat))\n    R = 6378137.0\n    px = R * math.radians(lon)\n    py = R * math.log(math.tan(math.pi / 4 + math.radians(lat) / 2))\n    return [round(px, 3), round(py, 3)]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('regression #0', [190.0, 10.0], [-18924313.435, 1118889.975]), ('regression #1', [-200.0, -20.0], [17811118.527, -2273030.927]), ('boundary #2', [180.0, 0.0], [-20037508.343, -0.0]), ('boundary #3', [-180.0, 45.0], [-20037508.343, 5621521.486]), ('regression #4', [545.0, 5.0], [-19480910.889, 557305.257]), ('boundary #5', [0.0, 89.0], [0.0, 20037508.343]), ('boundary #6', [10.0, -88.0], [1113194.908, -20037508.343]), ('regression #10', [-250.0, 12.5], [12245143.987, 1402665.19])], [('boundary #2', [180.0, 0.0], [-20037508.343, -0.0]), ('regression #4', [545.0, 5.0], [-19480910.889, 557305.257]), ('boundary #5', [0.0, 89.0], [0.0, 20037508.343]), ('boundary #6', [10.0, -88.0], [1113194.908, -20037508.343]), ('boundary #7', [0.0, 85.05112878], [0.0, 20037508.343]), ('control #8', [0.0, 0.0], [0.0, -0.0]), ('regression #9', [-540.0, 30.0], [-20037508.343, 3503549.844]), ('regression #10', [-250.0, 12.5], [12245143.987, 1402665.19])], [('regression #4', [545.0, 5.0], [-19480910.889, 557305.257]), ('boundary #7', [0.0, 85.05112878], [0.0, 20037508.343]), ('control #8', [0.0, 0.0], [0.0, -0.0]), ('regression #9', [-540.0, 30.0], [-20037508.343, 3503549.844]), ('regression #10', [-250.0, 12.5], [12245143.987, 1402665.19]), ('regression #11', [-359.5, -40.0], [55659.745, -4865942.28]), ('boundary #12', [45.0, -86.5], [5009377.086, -20037508.343]), ('boundary #13', [-120.0, -87.25], [-13358338.895, -20037508.343])], [('regression #9', [-540.0, 30.0], [-20037508.343, 3503549.844]), ('regression #10', [-250.0, 12.5], [12245143.987, 1402665.19]), ('regression #11', [-359.5, -40.0], [55659.745, -4865942.28]), ('boundary #12', [45.0, -86.5], [5009377.086, -20037508.343]), ('boundary #13', [-120.0, -87.25], [-13358338.895, -20037508.343]), ('regression #14', [-181.0, 0.5], [19926188.852, 55660.452]), ('control #15', [-17.048, 10.042], [-1897774.679, 1123637.827]), ('control #16', [151.867, -5.771], [16905757.108, -643513.79])], [('regression #10', [-250.0, 12.5], [12245143.987, 1402665.19]), ('regression #11', [-359.5, -40.0], [55659.745, -4865942.28]), ('regression #14', [-181.0, 0.5], [19926188.852, 55660.452]), ('control #15', [-17.048, 10.042], [-1897774.679, 1123637.827]), ('control #16', [151.867, -5.771], [16905757.108, -643513.79]), ('control #17', [2.807, 14.681], [312473.811, 1652463.738]), ('control #18', [-112.892, 2.001], [-12567079.955, 222795.596]), ('control #19', [46.498, 49.22], [5176133.683, 6312273.571])]]\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":"3b7025574842ff1df70d59dae61b72c8562f297f43cbbf41923a818220f09d04","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nN = 1\nobservations = []\ndef solve(x):\n    lon, lat = x\n    lon = ((lon + 180.0) % 360.0) - 180.0\n    lat = max(-85.05112878, min(85.05112878, lat))\n    R = 6378137.0\n    px = R * math.radians(lon)\n    py = R * math.log(math.tan(math.pi / 4 + math.radians(lat) / 2))\n    return [round(px, 3), round(py, 3)]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('regression #0', [190.0, 10.0], [-18924313.435, 1118889.975]), ('regression #1', [-200.0, -20.0], [17811118.527, -2273030.927]), ('boundary #2', [180.0, 0.0], [-20037508.343, -0.0]), ('boundary #3', [-180.0, 45.0], [-20037508.343, 5621521.486]), ('regression #4', [545.0, 5.0], [-19480910.889, 557305.257]), ('boundary #5', [0.0, 89.0], [0.0, 20037508.343]), ('boundary #6', [10.0, -88.0], [1113194.908, -20037508.343]), ('regression #10', [-250.0, 12.5], [12245143.987, 1402665.19])], [('boundary #2', [180.0, 0.0], [-20037508.343, -0.0]), ('regression #4', [545.0, 5.0], [-19480910.889, 557305.257]), ('boundary #5', [0.0, 89.0], [0.0, 20037508.343]), ('boundary #6', [10.0, -88.0], [1113194.908, -20037508.343]), ('boundary #7', [0.0, 85.05112878], [0.0, 20037508.343]), ('control #8', [0.0, 0.0], [0.0, -0.0]), ('regression #9', [-540.0, 30.0], [-20037508.343, 3503549.844]), ('regression #10', [-250.0, 12.5], [12245143.987, 1402665.19])], [('regression #4', [545.0, 5.0], [-19480910.889, 557305.257]), ('boundary #7', [0.0, 85.05112878], [0.0, 20037508.343]), ('control #8', [0.0, 0.0], [0.0, -0.0]), ('regression #9', [-540.0, 30.0], [-20037508.343, 3503549.844]), ('regression #10', [-250.0, 12.5], [12245143.987, 1402665.19]), ('regression #11', [-359.5, -40.0], [55659.745, -4865942.28]), ('boundary #12', [45.0, -86.5], [5009377.086, -20037508.343]), ('boundary #13', [-120.0, -87.25], [-13358338.895, -20037508.343])], [('regression #9', [-540.0, 30.0], [-20037508.343, 3503549.844]), ('regression #10', [-250.0, 12.5], [12245143.987, 1402665.19]), ('regression #11', [-359.5, -40.0], [55659.745, -4865942.28]), ('boundary #12', [45.0, -86.5], [5009377.086, -20037508.343]), ('boundary #13', [-120.0, -87.25], [-13358338.895, -20037508.343]), ('regression #14', [-181.0, 0.5], [19926188.852, 55660.452]), ('control #15', [-17.048, 10.042], [-1897774.679, 1123637.827]), ('control #16', [151.867, -5.771], [16905757.108, -643513.79])], [('regression #10', [-250.0, 12.5], [12245143.987, 1402665.19]), ('regression #11', [-359.5, -40.0], [55659.745, -4865942.28]), ('regression #14', [-181.0, 0.5], [19926188.852, 55660.452]), ('control #15', [-17.048, 10.042], [-1897774.679, 1123637.827]), ('control #16', [151.867, -5.771], [16905757.108, -643513.79]), ('control #17', [2.807, 14.681], [312473.811, 1652463.738]), ('control #18', [-112.892, 2.001], [-12567079.955, 222795.596]), ('control #19', [46.498, 49.22], [5176133.683, 6312273.571])]]\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-forward-longitude-wrap","generated_at":"2026-09-29T14:48:15.183263+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Web map tiles, vector tile encoders and map viewers all start from this forward transform; small mistakes shift features by kilometres or mirror them across the equator.","repair":"At the longitude wrap step restore `lon = ((lon + 180.0) % 360.0) - 180.0`, leaving the rest of the model unchanged.","root_cause":"The wrap step only subtracts one turn for out-of-range longitudes, so values below -180 or beyond one extra turn are never normalised and +180 stays at +180 instead of mapping to -180.","sha256":"246396c07fd430328e3c4788ef30daecd92d46ca17a6be122089e532b8fefd93","title":"Spherical web mercator forward projection: longitude wrap · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":76.126,"exit_code":1,"observations":[{"actual":[-18924313.435,1118889.975],"check":"regression #0","expected":[-18924313.435,1118889.975],"passed":true},{"actual":[-22263898.159,-2273030.927],"check":"regression #1","expected":[17811118.527,-2273030.927],"passed":false},{"actual":[-20037508.343,-0.0],"check":"boundary #2","expected":[-20037508.343,-0.0],"passed":true},{"actual":[-20037508.343,5621521.486],"check":"boundary #3","expected":[-20037508.343,5621521.486],"passed":true},{"actual":[-19480910.889,557305.257],"check":"regression #4","expected":[-19480910.889,557305.257],"passed":true},{"actual":[0.0,20037508.343],"check":"boundary #5","expected":[0.0,20037508.343],"passed":true},{"actual":[1113194.908,-20037508.343],"check":"boundary #6","expected":[1113194.908,-20037508.343],"passed":true},{"actual":[-27829872.698,1402665.19],"check":"regression #10","expected":[12245143.987,1402665.19],"passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression #0\", \"actual\": [-18924313.435, 1118889.975], \"expected\": [-18924313.435, 1118889.975], \"passed\": true}, {\"check\": \"regression #1\", \"actual\": [-22263898.159, -2273030.927], \"expected\": [17811118.527, -2273030.927], \"passed\": false}, {\"check\": \"boundary #2\", \"actual\": [-20037508.343, -0.0], \"expected\": [-20037508.343, -0.0], \"passed\": true}, {\"check\": \"boundary #3\", \"actual\": [-20037508.343, 5621521.486], \"expected\": [-20037508.343, 5621521.486], \"passed\": true}, {\"check\": \"regression #4\", \"actual\": [-19480910.889, 557305.257], \"expected\": [-19480910.889, 557305.257], \"passed\": true}, {\"check\": \"boundary #5\", \"actual\": [0.0, 20037508.343], \"expected\": [0.0, 20037508.343], \"passed\": true}, {\"check\": \"boundary #6\", \"actual\": [1113194.908, -20037508.343], \"expected\": [1113194.908, -20037508.343], \"passed\": true}, {\"check\": \"regression #10\", \"actual\": [-27829872.698, 1402665.19], \"expected\": [12245143.987, 1402665.19], \"passed\": false}], \"passed\": false}\n"},"broken":{"elapsed_ms":54.181,"exit_code":1,"observations":[{"actual":[-18924313.435,1118889.975],"check":"regression #0","expected":[-18924313.435,1118889.975],"passed":true},{"actual":[-62338914.844,-2273030.927],"check":"regression #1","expected":[17811118.527,-2273030.927],"passed":false},{"actual":[20037508.343,-0.0],"check":"boundary #2","expected":[-20037508.343,-0.0],"passed":false},{"actual":[-20037508.343,5621521.486],"check":"boundary #3","expected":[-20037508.343,5621521.486],"passed":true},{"actual":[20594105.797,557305.257],"check":"regression #4","expected":[-19480910.889,557305.257],"passed":false},{"actual":[0.0,20037508.343],"check":"boundary #5","expected":[0.0,20037508.343],"passed":true},{"actual":[1113194.908,-20037508.343],"check":"boundary #6","expected":[1113194.908,-20037508.343],"passed":true},{"actual":[-67904889.384,1402665.19],"check":"regression #10","expected":[12245143.987,1402665.19],"passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression #0\", \"actual\": [-18924313.435, 1118889.975], \"expected\": [-18924313.435, 1118889.975], \"passed\": true}, {\"check\": \"regression #1\", \"actual\": [-62338914.844, -2273030.927], \"expected\": [17811118.527, -2273030.927], \"passed\": false}, {\"check\": \"boundary #2\", \"actual\": [20037508.343, -0.0], \"expected\": [-20037508.343, -0.0], \"passed\": false}, {\"check\": \"boundary #3\", \"actual\": [-20037508.343, 5621521.486], \"expected\": [-20037508.343, 5621521.486], \"passed\": true}, {\"check\": \"regression #4\", \"actual\": [20594105.797, 557305.257], \"expected\": [-19480910.889, 557305.257], \"passed\": false}, {\"check\": \"boundary #5\", \"actual\": [0.0, 20037508.343], \"expected\": [0.0, 20037508.343], \"passed\": true}, {\"check\": \"boundary #6\", \"actual\": [1113194.908, -20037508.343], \"expected\": [1113194.908, -20037508.343], \"passed\": true}, {\"check\": \"regression #10\", \"actual\": [-67904889.384, 1402665.19], \"expected\": [12245143.987, 1402665.19], \"passed\": false}], \"passed\": false}\n"},"fixed":{"elapsed_ms":40.847,"exit_code":0,"observations":[{"actual":[-18924313.435,1118889.975],"check":"regression #0","expected":[-18924313.435,1118889.975],"passed":true},{"actual":[17811118.527,-2273030.927],"check":"regression #1","expected":[17811118.527,-2273030.927],"passed":true},{"actual":[-20037508.343,-0.0],"check":"boundary #2","expected":[-20037508.343,-0.0],"passed":true},{"actual":[-20037508.343,5621521.486],"check":"boundary #3","expected":[-20037508.343,5621521.486],"passed":true},{"actual":[-19480910.889,557305.257],"check":"regression #4","expected":[-19480910.889,557305.257],"passed":true},{"actual":[0.0,20037508.343],"check":"boundary #5","expected":[0.0,20037508.343],"passed":true},{"actual":[1113194.908,-20037508.343],"check":"boundary #6","expected":[1113194.908,-20037508.343],"passed":true},{"actual":[12245143.987,1402665.19],"check":"regression #10","expected":[12245143.987,1402665.19],"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression #0\", \"actual\": [-18924313.435, 1118889.975], \"expected\": [-18924313.435, 1118889.975], \"passed\": true}, {\"check\": \"regression #1\", \"actual\": [17811118.527, -2273030.927], \"expected\": [17811118.527, -2273030.927], \"passed\": true}, {\"check\": \"boundary #2\", \"actual\": [-20037508.343, -0.0], \"expected\": [-20037508.343, -0.0], \"passed\": true}, {\"check\": \"boundary #3\", \"actual\": [-20037508.343, 5621521.486], \"expected\": [-20037508.343, 5621521.486], \"passed\": true}, {\"check\": \"regression #4\", \"actual\": [-19480910.889, 557305.257], \"expected\": [-19480910.889, 557305.257], \"passed\": true}, {\"check\": \"boundary #5\", \"actual\": [0.0, 20037508.343], \"expected\": [0.0, 20037508.343], \"passed\": true}, {\"check\": \"boundary #6\", \"actual\": [1113194.908, -20037508.343], \"expected\": [1113194.908, -20037508.343], \"passed\": true}, {\"check\": \"regression #10\", \"actual\": [12245143.987, 1402665.19], \"expected\": [12245143.987, 1402665.19], \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}