{"abstract":"Penetrating bouncy contacts launch with excess energy.","category":"Physics integrator stability","checks":8,"contract":"solve(vn, depth, ima, imb, beta, slop, dt, e, e_thresh): one normal contact, vn<0 approaching. bias=(beta/dt)*(depth-slop) if positive; bounce=-e*vn when vn<-e_thresh. Target separating speed is max(bias,bounce); impulse=(target-vn)/(ima+imb) clamped at 0 (no pulling). Zero summed inverse mass gives [0, vn]. Return [impulse, post velocity] rounded to 6.","contract_signature":"vn, depth, ima, imb, beta, slop, dt, e, e_thresh","evaluation_group":"w2-physics_integrator_stability-baumgarte-contact-impulse","failed_approach":"Preferring bounce whenever it is nonzero ignores a larger positional bias.","family":"w2-physics_integrator_stability-baumgarte-contact-impulse-bias-and-bounce-combination","id":"FA-87196","implementations":{"attempt":{"sha256":"c1bb7e523bce82d03ef6ee48cd1bb82a90f518529aef4d47734d1e6bd83dd142","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nN = 1\nobservations = []\ndef solve(vn, depth, ima, imb, beta, slop, dt, e, e_thresh):\n    w = ima + imb\n    if w == 0:\n        return [0.0, round(vn, 6)]\n    pen = depth - slop\n    bias = beta / dt * pen if pen > 0 else 0.0\n    bounce = -e * vn if vn < -e_thresh else 0.0\n    target = bounce if bounce else bias\n    lam = (target - vn) / w\n    if lam < 0:\n        lam = 0.0\n    return [round(lam, 6), round(vn + lam * w, 6)]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[[[-4.773, 0.009, 0.604, 0.0, 0.1, 0.005, 0.03333333333333333, 0.3, 1.0], [10.273013, 1.4319]], [[-2.562, 0.154, 1.351, 0.513, 0.2, 0.02, 0.016666666666666666, 0.3, 1.0], [2.237124, 1.608]], [[0.67, 0.186, 1.405, 0.0, 0.3, 0.005, 0.03333333333333333, 0.0, 0.5], [0.682562, 1.629]], [[-2.91, 0.165, 0.386, 0.597, 0.3, 0.005, 0.016666666666666666, 0.8, 0.5], [5.890132, 2.88]], [[-2.811, 0.056, 0.589, 0.274, 0.1, 0.01, 0.03333333333333333, 0.8, 1.0], [5.863036, 2.2488]], [[-4.27, 0.161, 0.0, 0.0, 0.3, 0.02, 0.016666666666666666, 0.8, 0.5], [0.0, -4.27]], [[-1.707, 0.165, 1.092, 1.877, 0.2, 0.02, 0.03333333333333333, 0.3, 0.5], [0.867969, 0.87]], [[1.41, 0.135, 0.151, 1.614, 0.3, 0.01, 0.016666666666666666, 0.0, 0.5], [0.475921, 2.25]]], [[[-3.976, 0.068, 0.0, 1.176, 0.1, 0.01, 0.016666666666666666, 0.0, 1.0], [3.676871, 0.348]], [[-1.758, 0.161, 1.195, 0.199, 0.1, 0.02, 0.016666666666666666, 0.3, 1.0], [1.868006, 0.846]], [[0.546, 0.076, 0.0, 0.0, 0.1, 0.005, 0.03333333333333333, 0.0, 0.5], [0.0, 0.546]], [[-2.457, 0.025, 1.653, 0.59, 0.2, 0.02, 0.016666666666666666, 0.3, 0.5], [1.42403, 0.7371]], [[-2.446, 0.046, 0.549, 0.631, 0.1, 0.02, 0.016666666666666666, 0.8, 1.0], [3.731186, 1.9568]], [[-1.066, 0.099, 0.967, 1.983, 0.2, 0.005, 0.016666666666666666, 0.8, 0.5], [0.743729, 1.128]], [[0.063, 0.12, 0.372, 0.0, 0.1, 0.005, 0.03333333333333333, 0.3, 1.0], [0.758065, 0.345]], [[-3.625, 0.161, 0.346, 1.734, 0.1, 0.01, 0.016666666666666666, 0.3, 0.5], [2.265625, 1.0875]]], [[[-2.848, 0.066, 0.963, 0.962, 0.3, 0.005, 0.016666666666666666, 0.3, 1.0], [2.04987, 1.098]], [[1.993, 0.15, 0.513, 1.909, 0.2, 0.005, 0.03333333333333333, 0.8, 1.0], [0.0, 1.993]], [[-1.515, 0.171, 1.571, 0.0, 0.1, 0.02, 0.03333333333333333, 0.3, 1.0], [1.25366, 0.4545]], [[-2.491, 0.113, 0.986, 0.734, 0.2, 0.005, 0.016666666666666666, 0.3, 1.0], [2.201744, 1.296]], [[-1.057, 0.121, 1.527, 0.0, 0.1, 0.01, 0.03333333333333333, 0.8, 0.5], [1.245972, 0.8456]], [[-4.604, 0.061, 0.767, 0.833, 0.3, 0.005, 0.016666666666666666, 0.8, 0.5], [5.1795, 3.6832]], [[-4.581, 0.068, 0.0, 0.0, 0.3, 0.02, 0.016666666666666666, 0.3, 1.0], [0.0, -4.581]], [[0.928, -0.015, 0.698, 0.397, 0.2, 0.01, 0.016666666666666666, 0.8, 1.0], [0.0, 0.928]]], [[[-3.049, 0.072, 1.828, 0.939, 0.3, 0.02, 0.016666666666666666, 0.3, 1.0], [1.440188, 0.936]], [[-0.847, 0.07, 0.608, 0.0, 0.2, 0.01, 0.03333333333333333, 0.3, 0.5], [1.985197, 0.36]], [[-2.12, 0.078, 0.86, 0.0, 0.2, 0.01, 0.016666666666666666, 0.8, 0.5], [4.437209, 1.696]], [[0.052, 0.085, 1.985, 1.159, 0.2, 0.02, 0.03333333333333333, 0.3, 1.0], [0.107506, 0.39]], [[-0.61, 0.047, 0.543, 0.0, 0.2, 0.02, 0.016666666666666666, 0.3, 0.5], [1.720074, 0.324]], [[-1.706, 0.151, 0.445, 0.0, 0.1, 0.02, 0.03333333333333333, 0.3, 1.0], [4.98382, 0.5118]], [[0.08, 0.097, 0.146, 0.0, 0.3, 0.005, 0.016666666666666666, 0.8, 0.5], [10.794521, 1.656]], [[1.301, 0.198, 0.37, 1.907, 0.2, 0.01, 0.016666666666666666, 0.0, 0.5], [0.419412, 2.256]]], [[[-1.984, 0.152, 0.177, 0.796, 0.1, 0.005, 0.016666666666666666, 0.3, 0.5], [2.945529, 0.882]], [[-1.296, 0.02, 1.331, 0.0, 0.1, 0.005, 0.03333333333333333, 0.3, 1.0], [1.265815, 0.3888]], [[-1.445, 0.095, 1.787, 0.0, 0.1, 0.005, 0.03333333333333333, 0.8, 1.0], [1.455512, 1.156]], [[-2.372, 0.177, 1.352, 1.076, 0.2, 0.02, 0.03333333333333333, 0.8, 0.5], [1.758484, 1.8976]], [[-2.146, 0.086, 0.0, 0.793, 0.3, 0.02, 0.016666666666666666, 0.3, 1.0], [4.204288, 1.188]], [[1.424, 0.05, 0.809, 1.444, 0.1, 0.02, 0.016666666666666666, 0.0, 1.0], [0.0, 1.424]], [[-0.222, 0.103, 0.0, 1.833, 0.2, 0.02, 0.03333333333333333, 0.3, 0.5], [0.392799, 0.498]], [[1.4, 0.124, 0.0, 1.761, 0.1, 0.02, 0.016666666666666666, 0.8, 1.0], [0.0, 1.4]]]]\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":"1547736c2ec066001c07f62e3a173f789f6c9d77d2b8f28ca6be617ef029689b","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nN = 1\nobservations = []\ndef solve(vn, depth, ima, imb, beta, slop, dt, e, e_thresh):\n    w = ima + imb\n    if w == 0:\n        return [0.0, round(vn, 6)]\n    pen = depth - slop\n    bias = beta / dt * pen if pen > 0 else 0.0\n    bounce = -e * vn if vn < -e_thresh else 0.0\n    target = bias + bounce\n    lam = (target - vn) / w\n    if lam < 0:\n        lam = 0.0\n    return [round(lam, 6), round(vn + lam * w, 6)]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[[[-4.773, 0.009, 0.604, 0.0, 0.1, 0.005, 0.03333333333333333, 0.3, 1.0], [10.273013, 1.4319]], [[-2.562, 0.154, 1.351, 0.513, 0.2, 0.02, 0.016666666666666666, 0.3, 1.0], [2.237124, 1.608]], [[0.67, 0.186, 1.405, 0.0, 0.3, 0.005, 0.03333333333333333, 0.0, 0.5], [0.682562, 1.629]], [[-2.91, 0.165, 0.386, 0.597, 0.3, 0.005, 0.016666666666666666, 0.8, 0.5], [5.890132, 2.88]], [[-2.811, 0.056, 0.589, 0.274, 0.1, 0.01, 0.03333333333333333, 0.8, 1.0], [5.863036, 2.2488]], [[-4.27, 0.161, 0.0, 0.0, 0.3, 0.02, 0.016666666666666666, 0.8, 0.5], [0.0, -4.27]], [[-1.707, 0.165, 1.092, 1.877, 0.2, 0.02, 0.03333333333333333, 0.3, 0.5], [0.867969, 0.87]], [[1.41, 0.135, 0.151, 1.614, 0.3, 0.01, 0.016666666666666666, 0.0, 0.5], [0.475921, 2.25]]], [[[-3.976, 0.068, 0.0, 1.176, 0.1, 0.01, 0.016666666666666666, 0.0, 1.0], [3.676871, 0.348]], [[-1.758, 0.161, 1.195, 0.199, 0.1, 0.02, 0.016666666666666666, 0.3, 1.0], [1.868006, 0.846]], [[0.546, 0.076, 0.0, 0.0, 0.1, 0.005, 0.03333333333333333, 0.0, 0.5], [0.0, 0.546]], [[-2.457, 0.025, 1.653, 0.59, 0.2, 0.02, 0.016666666666666666, 0.3, 0.5], [1.42403, 0.7371]], [[-2.446, 0.046, 0.549, 0.631, 0.1, 0.02, 0.016666666666666666, 0.8, 1.0], [3.731186, 1.9568]], [[-1.066, 0.099, 0.967, 1.983, 0.2, 0.005, 0.016666666666666666, 0.8, 0.5], [0.743729, 1.128]], [[0.063, 0.12, 0.372, 0.0, 0.1, 0.005, 0.03333333333333333, 0.3, 1.0], [0.758065, 0.345]], [[-3.625, 0.161, 0.346, 1.734, 0.1, 0.01, 0.016666666666666666, 0.3, 0.5], [2.265625, 1.0875]]], [[[-2.848, 0.066, 0.963, 0.962, 0.3, 0.005, 0.016666666666666666, 0.3, 1.0], [2.04987, 1.098]], [[1.993, 0.15, 0.513, 1.909, 0.2, 0.005, 0.03333333333333333, 0.8, 1.0], [0.0, 1.993]], [[-1.515, 0.171, 1.571, 0.0, 0.1, 0.02, 0.03333333333333333, 0.3, 1.0], [1.25366, 0.4545]], [[-2.491, 0.113, 0.986, 0.734, 0.2, 0.005, 0.016666666666666666, 0.3, 1.0], [2.201744, 1.296]], [[-1.057, 0.121, 1.527, 0.0, 0.1, 0.01, 0.03333333333333333, 0.8, 0.5], [1.245972, 0.8456]], [[-4.604, 0.061, 0.767, 0.833, 0.3, 0.005, 0.016666666666666666, 0.8, 0.5], [5.1795, 3.6832]], [[-4.581, 0.068, 0.0, 0.0, 0.3, 0.02, 0.016666666666666666, 0.3, 1.0], [0.0, -4.581]], [[0.928, -0.015, 0.698, 0.397, 0.2, 0.01, 0.016666666666666666, 0.8, 1.0], [0.0, 0.928]]], [[[-3.049, 0.072, 1.828, 0.939, 0.3, 0.02, 0.016666666666666666, 0.3, 1.0], [1.440188, 0.936]], [[-0.847, 0.07, 0.608, 0.0, 0.2, 0.01, 0.03333333333333333, 0.3, 0.5], [1.985197, 0.36]], [[-2.12, 0.078, 0.86, 0.0, 0.2, 0.01, 0.016666666666666666, 0.8, 0.5], [4.437209, 1.696]], [[0.052, 0.085, 1.985, 1.159, 0.2, 0.02, 0.03333333333333333, 0.3, 1.0], [0.107506, 0.39]], [[-0.61, 0.047, 0.543, 0.0, 0.2, 0.02, 0.016666666666666666, 0.3, 0.5], [1.720074, 0.324]], [[-1.706, 0.151, 0.445, 0.0, 0.1, 0.02, 0.03333333333333333, 0.3, 1.0], [4.98382, 0.5118]], [[0.08, 0.097, 0.146, 0.0, 0.3, 0.005, 0.016666666666666666, 0.8, 0.5], [10.794521, 1.656]], [[1.301, 0.198, 0.37, 1.907, 0.2, 0.01, 0.016666666666666666, 0.0, 0.5], [0.419412, 2.256]]], [[[-1.984, 0.152, 0.177, 0.796, 0.1, 0.005, 0.016666666666666666, 0.3, 0.5], [2.945529, 0.882]], [[-1.296, 0.02, 1.331, 0.0, 0.1, 0.005, 0.03333333333333333, 0.3, 1.0], [1.265815, 0.3888]], [[-1.445, 0.095, 1.787, 0.0, 0.1, 0.005, 0.03333333333333333, 0.8, 1.0], [1.455512, 1.156]], [[-2.372, 0.177, 1.352, 1.076, 0.2, 0.02, 0.03333333333333333, 0.8, 0.5], [1.758484, 1.8976]], [[-2.146, 0.086, 0.0, 0.793, 0.3, 0.02, 0.016666666666666666, 0.3, 1.0], [4.204288, 1.188]], [[1.424, 0.05, 0.809, 1.444, 0.1, 0.02, 0.016666666666666666, 0.0, 1.0], [0.0, 1.424]], [[-0.222, 0.103, 0.0, 1.833, 0.2, 0.02, 0.03333333333333333, 0.3, 0.5], [0.392799, 0.498]], [[1.4, 0.124, 0.0, 1.761, 0.1, 0.02, 0.016666666666666666, 0.8, 1.0], [0.0, 1.4]]]]\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-baumgarte-contact-impulse-bias-and-bounce-combination","generated_at":"2026-09-29T14:50:56.555664+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.","root_cause":"target = bias + bounce.","sha256":"80937b2e394ace520b4101e2d41ddcb67c187fd76415c2b804a2640f920e1a1b","title":"Positional bias and restitution bounce are summed · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verified":true,"visibility":"public","verification":{"attempt":{"elapsed_ms":38.515,"exit_code":1,"observations":[{"actual":[10.273013,1.4319],"check":"case 0","expected":[10.273013,1.4319],"passed":true},{"actual":[1.786803,0.7686],"check":"case 1","expected":[2.237124,1.608],"passed":false},{"actual":[0.682562,1.629],"check":"case 2","expected":[0.682562,1.629],"passed":true},{"actual":[5.328586,2.328],"check":"case 3","expected":[5.890132,2.88],"passed":false},{"actual":[5.863036,2.2488],"check":"case 4","expected":[5.863036,2.2488],"passed":true},{"actual":[0.0,-4.27],"check":"case 5","expected":[0.0,-4.27],"passed":true},{"actual":[0.747423,0.5121],"check":"case 6","expected":[0.867969,0.87],"passed":false},{"actual":[0.475921,2.25],"check":"case 7","expected":[0.475921,2.25],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"case 0\", \"actual\": [10.273013, 1.4319], \"expected\": [10.273013, 1.4319], \"passed\": true}, {\"check\": \"case 1\", \"actual\": [1.786803, 0.7686], \"expected\": [2.237124, 1.608], \"passed\": false}, {\"check\": \"case 2\", \"actual\": [0.682562, 1.629], \"expected\": [0.682562, 1.629], \"passed\": true}, {\"check\": \"case 3\", \"actual\": [5.328586, 2.328], \"expected\": [5.890132, 2.88], \"passed\": false}, {\"check\": \"case 4\", \"actual\": [5.863036, 2.2488], \"expected\": [5.863036, 2.2488], \"passed\": true}, {\"check\": \"case 5\", \"actual\": [0.0, -4.27], \"expected\": [0.0, -4.27], \"passed\": true}, {\"check\": \"case 6\", \"actual\": [0.747423, 0.5121], \"expected\": [0.867969, 0.87], \"passed\": false}, {\"check\": \"case 7\", \"actual\": [0.475921, 2.25], \"expected\": [0.475921, 2.25], \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":40.567,"exit_code":1,"observations":[{"actual":[10.292881,1.4439],"check":"case 0","expected":[10.273013,1.4319],"passed":false},{"actual":[2.649464,2.3766],"check":"case 1","expected":[2.237124,1.608],"passed":false},{"actual":[0.682562,1.629],"check":"case 2","expected":[0.682562,1.629],"passed":true},{"actual":[8.258393,5.208],"check":"case 3","expected":[5.890132,2.88],"passed":false},{"actual":[6.022943,2.3868],"check":"case 4","expected":[5.863036,2.2488],"passed":false},{"actual":[0.0,-4.27],"check":"case 5","expected":[0.0,-4.27],"passed":true},{"actual":[1.040451,1.3821],"check":"case 6","expected":[0.867969,0.87],"passed":false},{"actual":[0.475921,2.25],"check":"case 7","expected":[0.475921,2.25],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"case 0\", \"actual\": [10.292881, 1.4439], \"expected\": [10.273013, 1.4319], \"passed\": false}, {\"check\": \"case 1\", \"actual\": [2.649464, 2.3766], \"expected\": [2.237124, 1.608], \"passed\": false}, {\"check\": \"case 2\", \"actual\": [0.682562, 1.629], \"expected\": [0.682562, 1.629], \"passed\": true}, {\"check\": \"case 3\", \"actual\": [8.258393, 5.208], \"expected\": [5.890132, 2.88], \"passed\": false}, {\"check\": \"case 4\", \"actual\": [6.022943, 2.3868], \"expected\": [5.863036, 2.2488], \"passed\": false}, {\"check\": \"case 5\", \"actual\": [0.0, -4.27], \"expected\": [0.0, -4.27], \"passed\": true}, {\"check\": \"case 6\", \"actual\": [1.040451, 1.3821], \"expected\": [0.867969, 0.87], \"passed\": false}, {\"check\": \"case 7\", \"actual\": [0.475921, 2.25], \"expected\": [0.475921, 2.25], \"passed\": true}], \"passed\": false}\n"}},"member_only":{"stages":["fixed"],"fields":["implementations.fixed","verification.fixed","harness","repair"],"note":"The verified repair, its recorded checks, the repair description, and the scoring harness are available to members."}}