{"abstract":"Bodies settle on the wrong side of the spring rest point.","category":"Physics integrator stability","checks":8,"contract":"solve(x0, v0, w2, g, dt, steps): acceleration -w2*x-g. The engine stores velocity at half steps: vh=v0+a(x0)*dt/2, then per step x+=vh*dt; vh+=a(x)*dt. Output synchronizes velocity back to the integer step: [x, vh-a(x)*dt/2] rounded to 6.","evaluation_group":"w2-physics_integrator_stability-leapfrog-staggered-velocity","failed_approach":"Folding g into the spring offset as -w2*(x-g) mixes units.","family":"w2-physics_integrator_stability-leapfrog-staggered-velocity-gravity-bias-sign","id":"FA-87086","implementations":{"attempt":{"sha256":"ed535446eee16a39d26c9d119640e4aa032d544fada71fdaaf8e2ab56c7bd623","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nN = 1\nobservations = []\ndef solve(x0, v0, w2, g, dt, steps):\n    def acc(p):\n        return -w2 * (p - g)\n    vh = v0 + acc(x0) * dt / 2\n    x = x0\n    for _ in range(steps):\n        x = x + vh * dt\n        vh = vh + acc(x) * dt\n    v = vh - acc(x) * dt / 2\n    return [round(x, 6), round(v, 6)]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[[[1.051, -1.98, 13.751, 9.81, 0.01, 1], [1.029987, -2.221178]], [[-0.493, -1.517, 17.061, 0.0, 0.01, 7], [-0.577279, -0.8735]], [[-0.631, -0.047, 16.626, 1.62, 0.01, 4], [-0.62579, 0.306844]], [[0.315, 1.535, 8.697, 9.81, 0.01, 3], [0.355353, 1.153028]], [[0.436, 1.25, 21.45, 9.81, 0.2, 5], [-0.668425, 3.776016]], [[-1.521, -0.162, 6.527, 1.62, 0.2, 0], [-1.521, -0.162]], [[-1.964, 1.259, 20.124, 1.62, 0.01, 6], [-1.821517, 3.460132]], [[1.7, 0.206, 28.764, 0.0, 0.05, 1], [1.649177, -2.202393]]], [[[-1.873, -1.269, 8.691, 9.81, 0.1, 5], [-1.630061, 2.045253]], [[-0.281, 1.62, 5.784, 9.81, 0.1, 3], [-0.186184, -1.021531]], [[-1.933, 0.742, 17.091, 9.81, 0.1, 0], [-1.933, 0.742]], [[1.251, -1.263, 11.392, 0.0, 0.2, 1], [0.713372, -3.500813]], [[-1.512, -0.917, 2.156, -3.0, 0.1, 10], [0.475297, 4.13743]], [[0.207, 0.644, 21.918, 1.62, 0.05, 6], [0.108366, -1.184217]], [[-1.537, -0.458, 19.191, 0.0, 0.1, 1], [-1.435317, 2.394087]], [[-1.057, 0.244, 12.747, 9.81, 0.01, 8], [-1.026095, 0.5232]]], [[[1.893, -0.282, 22.513, 0.0, 0.01, 5], [1.825995, -2.384623]], [[-0.611, -0.509, 8.029, 0.0, 0.1, 0], [-0.611, -0.509]], [[-1.277, -0.541, 11.271, 1.62, 0.1, 4], [-0.552191, 3.54015]], [[1.361, 1.476, 18.508, -3.0, 0.1, 14], [1.259752, 2.50659]], [[0.191, -1.592, 15.855, -3.0, 0.2, 2], [-0.245776, 0.100628]], [[-0.665, -0.888, 20.198, -3.0, 0.01, 7], [-0.686227, 0.286733]], [[-1.003, 0.428, 3.825, -3.0, 0.2, 2], [-0.318898, 2.730839]], [[-0.73, 0.772, 21.128, 0.0, 0.01, 14], [-0.483162, 2.630496]]], [[[-0.163, -0.394, 12.347, 1.62, 0.2, 7], [-0.027135, -0.22127]], [[-0.299, 0.546, 29.023, 0.0, 0.1, 10], [-0.279669, -0.774088]], [[-0.731, -0.105, 23.504, 9.81, 0.2, 8], [-0.365533, 1.315743]], [[-0.245, 1.761, 12.022, 1.62, 0.2, 9], [-0.195747, 1.786149]], [[-1.034, -1.918, 17.266, -3.0, 0.05, 0], [-1.034, -1.918]], [[-0.029, -0.774, 20.819, -3.0, 0.01, 6], [-0.06843, -0.531674]], [[1.944, -1.577, 8.082, -3.0, 0.05, 4], [1.39648, -3.731695]], [[-1.606, 1.339, 5.46, 0.0, 0.2, 9], [0.197038, -3.860859]]], [[[0.95, -1.335, 21.477, 1.62, 0.05, 13], [-1.128613, 0.748224]], [[0.489, 1.733, 26.727, 0.0, 0.1, 9], [-0.349993, 2.431476]], [[1.558, -0.861, 10.719, -3.0, 0.05, 7], [0.564719, -4.155803]], [[0.416, 1.191, 1.568, -3.0, 0.05, 19], [2.239843, 2.182456]], [[-0.515, 0.855, 16.541, 0.0, 0.1, 3], [0.0295, 2.21876]], [[-0.028, -0.375, 18.368, -3.0, 0.01, 13], [-0.045341, 0.115239]], [[-0.325, 0.3, 29.992, 9.81, 0.05, 7], [-0.275898, -0.114066]], [[0.32, -1.935, 12.544, 0.0, 0.05, 0], [0.32, -1.935]]]]\nfor i, (args, expected) in enumerate(fixtures[N-1]):\n    check(\"case %d\" % i, 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":"d2284d39f75ddd7cb6aa811b161ccf59daa22ba5e7347386edd745f63b55ea72","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nN = 1\nobservations = []\ndef solve(x0, v0, w2, g, dt, steps):\n    def acc(p):\n        return -w2 * p + g\n    vh = v0 + acc(x0) * dt / 2\n    x = x0\n    for _ in range(steps):\n        x = x + vh * dt\n        vh = vh + acc(x) * dt\n    v = vh - acc(x) * dt / 2\n    return [round(x, 6), round(v, 6)]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[[[1.051, -1.98, 13.751, 9.81, 0.01, 1], [1.029987, -2.221178]], [[-0.493, -1.517, 17.061, 0.0, 0.01, 7], [-0.577279, -0.8735]], [[-0.631, -0.047, 16.626, 1.62, 0.01, 4], [-0.62579, 0.306844]], [[0.315, 1.535, 8.697, 9.81, 0.01, 3], [0.355353, 1.153028]], [[0.436, 1.25, 21.45, 9.81, 0.2, 5], [-0.668425, 3.776016]], [[-1.521, -0.162, 6.527, 1.62, 0.2, 0], [-1.521, -0.162]], [[-1.964, 1.259, 20.124, 1.62, 0.01, 6], [-1.821517, 3.460132]], [[1.7, 0.206, 28.764, 0.0, 0.05, 1], [1.649177, -2.202393]]], [[[-1.873, -1.269, 8.691, 9.81, 0.1, 5], [-1.630061, 2.045253]], [[-0.281, 1.62, 5.784, 9.81, 0.1, 3], [-0.186184, -1.021531]], [[-1.933, 0.742, 17.091, 9.81, 0.1, 0], [-1.933, 0.742]], [[1.251, -1.263, 11.392, 0.0, 0.2, 1], [0.713372, -3.500813]], [[-1.512, -0.917, 2.156, -3.0, 0.1, 10], [0.475297, 4.13743]], [[0.207, 0.644, 21.918, 1.62, 0.05, 6], [0.108366, -1.184217]], [[-1.537, -0.458, 19.191, 0.0, 0.1, 1], [-1.435317, 2.394087]], [[-1.057, 0.244, 12.747, 9.81, 0.01, 8], [-1.026095, 0.5232]]], [[[1.893, -0.282, 22.513, 0.0, 0.01, 5], [1.825995, -2.384623]], [[-0.611, -0.509, 8.029, 0.0, 0.1, 0], [-0.611, -0.509]], [[-1.277, -0.541, 11.271, 1.62, 0.1, 4], [-0.552191, 3.54015]], [[1.361, 1.476, 18.508, -3.0, 0.1, 14], [1.259752, 2.50659]], [[0.191, -1.592, 15.855, -3.0, 0.2, 2], [-0.245776, 0.100628]], [[-0.665, -0.888, 20.198, -3.0, 0.01, 7], [-0.686227, 0.286733]], [[-1.003, 0.428, 3.825, -3.0, 0.2, 2], [-0.318898, 2.730839]], [[-0.73, 0.772, 21.128, 0.0, 0.01, 14], [-0.483162, 2.630496]]], [[[-0.163, -0.394, 12.347, 1.62, 0.2, 7], [-0.027135, -0.22127]], [[-0.299, 0.546, 29.023, 0.0, 0.1, 10], [-0.279669, -0.774088]], [[-0.731, -0.105, 23.504, 9.81, 0.2, 8], [-0.365533, 1.315743]], [[-0.245, 1.761, 12.022, 1.62, 0.2, 9], [-0.195747, 1.786149]], [[-1.034, -1.918, 17.266, -3.0, 0.05, 0], [-1.034, -1.918]], [[-0.029, -0.774, 20.819, -3.0, 0.01, 6], [-0.06843, -0.531674]], [[1.944, -1.577, 8.082, -3.0, 0.05, 4], [1.39648, -3.731695]], [[-1.606, 1.339, 5.46, 0.0, 0.2, 9], [0.197038, -3.860859]]], [[[0.95, -1.335, 21.477, 1.62, 0.05, 13], [-1.128613, 0.748224]], [[0.489, 1.733, 26.727, 0.0, 0.1, 9], [-0.349993, 2.431476]], [[1.558, -0.861, 10.719, -3.0, 0.05, 7], [0.564719, -4.155803]], [[0.416, 1.191, 1.568, -3.0, 0.05, 19], [2.239843, 2.182456]], [[-0.515, 0.855, 16.541, 0.0, 0.1, 3], [0.0295, 2.21876]], [[-0.028, -0.375, 18.368, -3.0, 0.01, 13], [-0.045341, 0.115239]], [[-0.325, 0.3, 29.992, 9.81, 0.05, 7], [-0.275898, -0.114066]], [[0.32, -1.935, 12.544, 0.0, 0.05, 0], [0.32, -1.935]]]]\nfor i, (args, expected) in enumerate(fixtures[N-1]):\n    check(\"case %d\" % i, 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":"4ed8f82c2c2bacdff5b3f3593754feb0fef8b52815a0c7e3a777e57f241aa845","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nN = 1\nobservations = []\ndef solve(x0, v0, w2, g, dt, steps):\n    def acc(p):\n        return -w2 * p - g\n    vh = v0 + acc(x0) * dt / 2\n    x = x0\n    for _ in range(steps):\n        x = x + vh * dt\n        vh = vh + acc(x) * dt\n    v = vh - acc(x) * dt / 2\n    return [round(x, 6), round(v, 6)]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[[[1.051, -1.98, 13.751, 9.81, 0.01, 1], [1.029987, -2.221178]], [[-0.493, -1.517, 17.061, 0.0, 0.01, 7], [-0.577279, -0.8735]], [[-0.631, -0.047, 16.626, 1.62, 0.01, 4], [-0.62579, 0.306844]], [[0.315, 1.535, 8.697, 9.81, 0.01, 3], [0.355353, 1.153028]], [[0.436, 1.25, 21.45, 9.81, 0.2, 5], [-0.668425, 3.776016]], [[-1.521, -0.162, 6.527, 1.62, 0.2, 0], [-1.521, -0.162]], [[-1.964, 1.259, 20.124, 1.62, 0.01, 6], [-1.821517, 3.460132]], [[1.7, 0.206, 28.764, 0.0, 0.05, 1], [1.649177, -2.202393]]], [[[-1.873, -1.269, 8.691, 9.81, 0.1, 5], [-1.630061, 2.045253]], [[-0.281, 1.62, 5.784, 9.81, 0.1, 3], [-0.186184, -1.021531]], [[-1.933, 0.742, 17.091, 9.81, 0.1, 0], [-1.933, 0.742]], [[1.251, -1.263, 11.392, 0.0, 0.2, 1], [0.713372, -3.500813]], [[-1.512, -0.917, 2.156, -3.0, 0.1, 10], [0.475297, 4.13743]], [[0.207, 0.644, 21.918, 1.62, 0.05, 6], [0.108366, -1.184217]], [[-1.537, -0.458, 19.191, 0.0, 0.1, 1], [-1.435317, 2.394087]], [[-1.057, 0.244, 12.747, 9.81, 0.01, 8], [-1.026095, 0.5232]]], [[[1.893, -0.282, 22.513, 0.0, 0.01, 5], [1.825995, -2.384623]], [[-0.611, -0.509, 8.029, 0.0, 0.1, 0], [-0.611, -0.509]], [[-1.277, -0.541, 11.271, 1.62, 0.1, 4], [-0.552191, 3.54015]], [[1.361, 1.476, 18.508, -3.0, 0.1, 14], [1.259752, 2.50659]], [[0.191, -1.592, 15.855, -3.0, 0.2, 2], [-0.245776, 0.100628]], [[-0.665, -0.888, 20.198, -3.0, 0.01, 7], [-0.686227, 0.286733]], [[-1.003, 0.428, 3.825, -3.0, 0.2, 2], [-0.318898, 2.730839]], [[-0.73, 0.772, 21.128, 0.0, 0.01, 14], [-0.483162, 2.630496]]], [[[-0.163, -0.394, 12.347, 1.62, 0.2, 7], [-0.027135, -0.22127]], [[-0.299, 0.546, 29.023, 0.0, 0.1, 10], [-0.279669, -0.774088]], [[-0.731, -0.105, 23.504, 9.81, 0.2, 8], [-0.365533, 1.315743]], [[-0.245, 1.761, 12.022, 1.62, 0.2, 9], [-0.195747, 1.786149]], [[-1.034, -1.918, 17.266, -3.0, 0.05, 0], [-1.034, -1.918]], [[-0.029, -0.774, 20.819, -3.0, 0.01, 6], [-0.06843, -0.531674]], [[1.944, -1.577, 8.082, -3.0, 0.05, 4], [1.39648, -3.731695]], [[-1.606, 1.339, 5.46, 0.0, 0.2, 9], [0.197038, -3.860859]]], [[[0.95, -1.335, 21.477, 1.62, 0.05, 13], [-1.128613, 0.748224]], [[0.489, 1.733, 26.727, 0.0, 0.1, 9], [-0.349993, 2.431476]], [[1.558, -0.861, 10.719, -3.0, 0.05, 7], [0.564719, -4.155803]], [[0.416, 1.191, 1.568, -3.0, 0.05, 19], [2.239843, 2.182456]], [[-0.515, 0.855, 16.541, 0.0, 0.1, 3], [0.0295, 2.21876]], [[-0.028, -0.375, 18.368, -3.0, 0.01, 13], [-0.045341, 0.115239]], [[-0.325, 0.3, 29.992, 9.81, 0.05, 7], [-0.275898, -0.114066]], [[0.32, -1.935, 12.544, 0.0, 0.05, 0], [0.32, -1.935]]]]\nfor i, (args, expected) in enumerate(fixtures[N-1]):\n    check(\"case %d\" % i, 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":"A deterministic bounded teaching model with stipulated toy conventions and rounded float output; not a production physics engine or a proof of numerical stability. 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-physics_integrator_stability-leapfrog-staggered-velocity-gravity-bias-sign","generated_at":"2026-09-29T14:50:55.417247+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Game and robotics physics loops depend on integrator update order, step control and stabilization terms; a wrong decision point turns a stable simulation into drifting or exploding motion.","repair":"The contract field term is -g.","root_cause":"The acceleration is -w2*x+g.","sha256":"001a4e6dc449c1331cf029e7cc7ca686a867d650b71a9665697eaabc3348c22c","title":"Constant field acceleration is added with the wrong sign · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":41.53,"exit_code":1,"observations":[{"actual":[1.037222,-0.774603],"check":"case 0","expected":[1.029987,-2.221178],"passed":false},{"actual":[-0.577279,-0.8735],"check":"case 1","expected":[-0.577279,-0.8735],"passed":true},{"actual":[-0.602994,1.443793],"check":"case 2","expected":[-0.62579,0.306844],"passed":false},{"actual":[0.398135,4.002926],"check":"case 3","expected":[0.355353,1.153028],"passed":false},{"actual":[8.543501,-38.145609],"check":"case 4","expected":[-0.668425,3.776016],"passed":false},{"actual":[-1.521,-0.162],"check":"case 5","expected":[-1.521,-0.162],"passed":true},{"actual":[-1.76028,5.488339],"check":"case 6","expected":[-1.821517,3.460132],"passed":false},{"actual":[1.649177,-2.202393],"check":"case 7","expected":[1.649177,-2.202393],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"case 0\", \"actual\": [1.037222, -0.774603], \"expected\": [1.029987, -2.221178], \"passed\": false}, {\"check\": \"case 1\", \"actual\": [-0.577279, -0.8735], \"expected\": [-0.577279, -0.8735], \"passed\": true}, {\"check\": \"case 2\", \"actual\": [-0.602994, 1.443793], \"expected\": [-0.62579, 0.306844], \"passed\": false}, {\"check\": \"case 3\", \"actual\": [0.398135, 4.002926], \"expected\": [0.355353, 1.153028], \"passed\": false}, {\"check\": \"case 4\", \"actual\": [8.543501, -38.145609], \"expected\": [-0.668425, 3.776016], \"passed\": false}, {\"check\": \"case 5\", \"actual\": [-1.521, -0.162], \"expected\": [-1.521, -0.162], \"passed\": true}, {\"check\": \"case 6\", \"actual\": [-1.76028, 5.488339], \"expected\": [-1.821517, 3.460132], \"passed\": false}, {\"check\": \"case 7\", \"actual\": [1.649177, -2.202393], \"expected\": [1.649177, -2.202393], \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":39.465,"exit_code":1,"observations":[{"actual":[1.030968,-2.025046],"check":"case 0","expected":[1.029987,-2.221178],"passed":false},{"actual":[-0.577279,-0.8735],"check":"case 1","expected":[-0.577279,-0.8735],"passed":true},{"actual":[-0.623204,0.435852],"check":"case 2","expected":[-0.62579,0.306844],"passed":false},{"actual":[0.364176,1.740817],"check":"case 3","expected":[0.355353,1.153028],"passed":false},{"actual":[0.152237,0.04135],"check":"case 4","expected":[-0.668425,3.776016],"passed":false},{"actual":[-1.521,-0.162],"check":"case 5","expected":[-1.521,-0.162],"passed":true},{"actual":[-1.815719,3.652161],"check":"case 6","expected":[-1.821517,3.460132],"passed":false},{"actual":[1.649177,-2.202393],"check":"case 7","expected":[1.649177,-2.202393],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"case 0\", \"actual\": [1.030968, -2.025046], \"expected\": [1.029987, -2.221178], \"passed\": false}, {\"check\": \"case 1\", \"actual\": [-0.577279, -0.8735], \"expected\": [-0.577279, -0.8735], \"passed\": true}, {\"check\": \"case 2\", \"actual\": [-0.623204, 0.435852], \"expected\": [-0.62579, 0.306844], \"passed\": false}, {\"check\": \"case 3\", \"actual\": [0.364176, 1.740817], \"expected\": [0.355353, 1.153028], \"passed\": false}, {\"check\": \"case 4\", \"actual\": [0.152237, 0.04135], \"expected\": [-0.668425, 3.776016], \"passed\": false}, {\"check\": \"case 5\", \"actual\": [-1.521, -0.162], \"expected\": [-1.521, -0.162], \"passed\": true}, {\"check\": \"case 6\", \"actual\": [-1.815719, 3.652161], \"expected\": [-1.821517, 3.460132], \"passed\": false}, {\"check\": \"case 7\", \"actual\": [1.649177, -2.202393], \"expected\": [1.649177, -2.202393], \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":40.87,"exit_code":0,"observations":[{"actual":[1.029987,-2.221178],"check":"case 0","expected":[1.029987,-2.221178],"passed":true},{"actual":[-0.577279,-0.8735],"check":"case 1","expected":[-0.577279,-0.8735],"passed":true},{"actual":[-0.62579,0.306844],"check":"case 2","expected":[-0.62579,0.306844],"passed":true},{"actual":[0.355353,1.153028],"check":"case 3","expected":[0.355353,1.153028],"passed":true},{"actual":[-0.668425,3.776016],"check":"case 4","expected":[-0.668425,3.776016],"passed":true},{"actual":[-1.521,-0.162],"check":"case 5","expected":[-1.521,-0.162],"passed":true},{"actual":[-1.821517,3.460132],"check":"case 6","expected":[-1.821517,3.460132],"passed":true},{"actual":[1.649177,-2.202393],"check":"case 7","expected":[1.649177,-2.202393],"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"case 0\", \"actual\": [1.029987, -2.221178], \"expected\": [1.029987, -2.221178], \"passed\": true}, {\"check\": \"case 1\", \"actual\": [-0.577279, -0.8735], \"expected\": [-0.577279, -0.8735], \"passed\": true}, {\"check\": \"case 2\", \"actual\": [-0.62579, 0.306844], \"expected\": [-0.62579, 0.306844], \"passed\": true}, {\"check\": \"case 3\", \"actual\": [0.355353, 1.153028], \"expected\": [0.355353, 1.153028], \"passed\": true}, {\"check\": \"case 4\", \"actual\": [-0.668425, 3.776016], \"expected\": [-0.668425, 3.776016], \"passed\": true}, {\"check\": \"case 5\", \"actual\": [-1.521, -0.162], \"expected\": [-1.521, -0.162], \"passed\": true}, {\"check\": \"case 6\", \"actual\": [-1.821517, 3.460132], \"expected\": [-1.821517, 3.460132], \"passed\": true}, {\"check\": \"case 7\", \"actual\": [1.649177, -2.202393], \"expected\": [1.649177, -2.202393], \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}