{"abstract":"Slow resting contacts bounce and never settle.","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":"Bouncing for any approaching contact removes the threshold dead zone.","family":"w2-physics_integrator_stability-baumgarte-contact-impulse-restitution-threshold","id":"FA-87191","implementations":{"attempt":{"sha256":"e940aa6d6c5ca05db4ea4985076d5b68d649581ccce693fb72af8a466d799b4b","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 <= 0 else 0.0\n    target = max(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 = [[[[1.672, 0.187, 0.0, 1.181, 0.1, 0.01, 0.03333333333333333, 0.8, 1.0], [0.0, 1.672]], [[-0.93, 0.035, 1.228, 0.0, 0.2, 0.005, 0.03333333333333333, 0.3, 0.5], [0.984528, 0.279]], [[-1.137, 0.018, 0.0, 1.358, 0.2, 0.02, 0.016666666666666666, 0.3, 0.5], [1.088439, 0.3411]], [[-0.957, 0.082, 0.0, 1.535, 0.2, 0.01, 0.03333333333333333, 0.8, 1.0], [0.904886, 0.432]], [[1.061, 0.153, 1.061, 0.71, 0.1, 0.01, 0.016666666666666666, 0.0, 1.0], [0.0, 1.061]], [[-3.32, 0.182, 1.149, 0.694, 0.3, 0.005, 0.016666666666666666, 0.0, 0.5], [3.530114, 3.186]], [[-4.873, 0.122, 1.161, 0.497, 0.2, 0.01, 0.016666666666666666, 0.0, 0.5], [3.749698, 1.344]], [[-3.544, -0.008, 0.323, 0.295, 0.3, 0.01, 0.03333333333333333, 0.0, 1.0], [5.734628, 0.0]]], [[[-0.388, 0.011, 1.622, 0.286, 0.3, 0.02, 0.03333333333333333, 0.3, 1.0], [0.203354, 0.0]], [[-0.697, 0.017, 1.546, 0.153, 0.3, 0.005, 0.016666666666666666, 0.3, 0.5], [0.537375, 0.216]], [[-4.277, 0.089, 0.354, 0.619, 0.3, 0.005, 0.016666666666666666, 0.3, 1.0], [5.94964, 1.512]], [[-2.457, 0.025, 1.653, 0.59, 0.2, 0.02, 0.016666666666666666, 0.3, 0.5], [1.42403, 0.7371]], [[-4.263, 0.084, 1.159, 0.666, 0.2, 0.02, 0.03333333333333333, 0.3, 0.5], [3.036658, 1.2789]], [[-2.936, -0.015, 0.939, 0.612, 0.2, 0.005, 0.03333333333333333, 0.8, 1.0], [3.40735, 2.3488]], [[-0.329, 0.013, 0.582, 0.0, 0.2, 0.01, 0.016666666666666666, 0.3, 0.5], [0.627148, 0.036]], [[-1.549, 0.022, 0.361, 0.0, 0.2, 0.01, 0.016666666666666666, 0.3, 0.5], [5.578116, 0.4647]]], [[[-4.168, 0.016, 0.479, 0.247, 0.1, 0.005, 0.03333333333333333, 0.8, 1.0], [10.333884, 3.3344]], [[-0.936, 0.188, 0.0, 1.517, 0.1, 0.02, 0.016666666666666666, 0.0, 1.0], [1.281477, 1.008]], [[-0.762, 0.056, 0.0, 1.034, 0.1, 0.005, 0.016666666666666666, 0.8, 0.5], [1.326499, 0.6096]], [[-0.511, 0.189, 1.377, 0.149, 0.1, 0.01, 0.016666666666666666, 0.0, 1.0], [1.038663, 1.074]], [[-3.134, 0.061, 0.847, 1.706, 0.3, 0.005, 0.03333333333333333, 0.3, 1.0], [1.595848, 0.9402]], [[-0.852, 0.001, 0.896, 1.443, 0.2, 0.02, 0.03333333333333333, 0.3, 1.0], [0.364258, 0.0]], [[0.891, 0.162, 0.327, 0.106, 0.2, 0.01, 0.016666666666666666, 0.0, 1.0], [2.154734, 1.824]], [[0.667, 0.008, 0.0, 0.0, 0.2, 0.01, 0.03333333333333333, 0.0, 0.5], [0.0, 0.667]]], [[[-1.706, 0.151, 0.445, 0.0, 0.1, 0.02, 0.03333333333333333, 0.3, 1.0], [4.98382, 0.5118]], [[-0.043, -0.004, 1.068, 0.0, 0.3, 0.005, 0.03333333333333333, 0.8, 1.0], [0.040262, 0.0]], [[-3.044, 0.169, 0.452, 0.836, 0.1, 0.02, 0.03333333333333333, 0.0, 0.5], [2.710404, 0.447]], [[1.005, 0.062, 1.813, 0.0, 0.2, 0.005, 0.03333333333333333, 0.8, 0.5], [0.0, 1.005]], [[-1.618, 0.083, 0.255, 0.217, 0.3, 0.01, 0.03333333333333333, 0.8, 0.5], [6.170339, 1.2944]], [[-4.582, 0.146, 0.0, 0.0, 0.1, 0.005, 0.03333333333333333, 0.0, 0.5], [0.0, -4.582]], [[1.499, -0.006, 0.0, 0.0, 0.2, 0.005, 0.03333333333333333, 0.3, 0.5], [0.0, 1.499]], [[0.478, 0.116, 1.213, 0.0, 0.2, 0.01, 0.03333333333333333, 0.3, 0.5], [0.130256, 0.636]]], [[[-1.984, 0.152, 0.177, 0.796, 0.1, 0.005, 0.016666666666666666, 0.3, 0.5], [2.945529, 0.882]], [[-2.54, 0.199, 0.0, 0.782, 0.3, 0.02, 0.016666666666666666, 0.0, 1.0], [7.368286, 3.222]], [[-2.372, 0.177, 1.352, 1.076, 0.2, 0.02, 0.03333333333333333, 0.8, 0.5], [1.758484, 1.8976]], [[0.326, -0.004, 0.0, 0.0, 0.2, 0.02, 0.03333333333333333, 0.8, 0.5], [0.0, 0.326]], [[0.566, 0.042, 0.0, 0.0, 0.1, 0.02, 0.03333333333333333, 0.8, 0.5], [0.0, 0.566]], [[-0.039, 0.017, 0.133, 0.913, 0.3, 0.02, 0.03333333333333333, 0.8, 0.5], [0.037285, 0.0]], [[-0.863, 0.138, 0.0, 0.0, 0.1, 0.005, 0.016666666666666666, 0.3, 0.5], [0.0, -0.863]], [[-0.434, 0.117, 0.778, 0.221, 0.1, 0.005, 0.016666666666666666, 0.8, 1.0], [1.107107, 0.672]]]]\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":"4618ef881320da3e9ee6d3b522f5e90077ab4bf160f2af97f7d3b2dcfbc4ee3b","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 = max(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 = [[[[1.672, 0.187, 0.0, 1.181, 0.1, 0.01, 0.03333333333333333, 0.8, 1.0], [0.0, 1.672]], [[-0.93, 0.035, 1.228, 0.0, 0.2, 0.005, 0.03333333333333333, 0.3, 0.5], [0.984528, 0.279]], [[-1.137, 0.018, 0.0, 1.358, 0.2, 0.02, 0.016666666666666666, 0.3, 0.5], [1.088439, 0.3411]], [[-0.957, 0.082, 0.0, 1.535, 0.2, 0.01, 0.03333333333333333, 0.8, 1.0], [0.904886, 0.432]], [[1.061, 0.153, 1.061, 0.71, 0.1, 0.01, 0.016666666666666666, 0.0, 1.0], [0.0, 1.061]], [[-3.32, 0.182, 1.149, 0.694, 0.3, 0.005, 0.016666666666666666, 0.0, 0.5], [3.530114, 3.186]], [[-4.873, 0.122, 1.161, 0.497, 0.2, 0.01, 0.016666666666666666, 0.0, 0.5], [3.749698, 1.344]], [[-3.544, -0.008, 0.323, 0.295, 0.3, 0.01, 0.03333333333333333, 0.0, 1.0], [5.734628, 0.0]]], [[[-0.388, 0.011, 1.622, 0.286, 0.3, 0.02, 0.03333333333333333, 0.3, 1.0], [0.203354, 0.0]], [[-0.697, 0.017, 1.546, 0.153, 0.3, 0.005, 0.016666666666666666, 0.3, 0.5], [0.537375, 0.216]], [[-4.277, 0.089, 0.354, 0.619, 0.3, 0.005, 0.016666666666666666, 0.3, 1.0], [5.94964, 1.512]], [[-2.457, 0.025, 1.653, 0.59, 0.2, 0.02, 0.016666666666666666, 0.3, 0.5], [1.42403, 0.7371]], [[-4.263, 0.084, 1.159, 0.666, 0.2, 0.02, 0.03333333333333333, 0.3, 0.5], [3.036658, 1.2789]], [[-2.936, -0.015, 0.939, 0.612, 0.2, 0.005, 0.03333333333333333, 0.8, 1.0], [3.40735, 2.3488]], [[-0.329, 0.013, 0.582, 0.0, 0.2, 0.01, 0.016666666666666666, 0.3, 0.5], [0.627148, 0.036]], [[-1.549, 0.022, 0.361, 0.0, 0.2, 0.01, 0.016666666666666666, 0.3, 0.5], [5.578116, 0.4647]]], [[[-4.168, 0.016, 0.479, 0.247, 0.1, 0.005, 0.03333333333333333, 0.8, 1.0], [10.333884, 3.3344]], [[-0.936, 0.188, 0.0, 1.517, 0.1, 0.02, 0.016666666666666666, 0.0, 1.0], [1.281477, 1.008]], [[-0.762, 0.056, 0.0, 1.034, 0.1, 0.005, 0.016666666666666666, 0.8, 0.5], [1.326499, 0.6096]], [[-0.511, 0.189, 1.377, 0.149, 0.1, 0.01, 0.016666666666666666, 0.0, 1.0], [1.038663, 1.074]], [[-3.134, 0.061, 0.847, 1.706, 0.3, 0.005, 0.03333333333333333, 0.3, 1.0], [1.595848, 0.9402]], [[-0.852, 0.001, 0.896, 1.443, 0.2, 0.02, 0.03333333333333333, 0.3, 1.0], [0.364258, 0.0]], [[0.891, 0.162, 0.327, 0.106, 0.2, 0.01, 0.016666666666666666, 0.0, 1.0], [2.154734, 1.824]], [[0.667, 0.008, 0.0, 0.0, 0.2, 0.01, 0.03333333333333333, 0.0, 0.5], [0.0, 0.667]]], [[[-1.706, 0.151, 0.445, 0.0, 0.1, 0.02, 0.03333333333333333, 0.3, 1.0], [4.98382, 0.5118]], [[-0.043, -0.004, 1.068, 0.0, 0.3, 0.005, 0.03333333333333333, 0.8, 1.0], [0.040262, 0.0]], [[-3.044, 0.169, 0.452, 0.836, 0.1, 0.02, 0.03333333333333333, 0.0, 0.5], [2.710404, 0.447]], [[1.005, 0.062, 1.813, 0.0, 0.2, 0.005, 0.03333333333333333, 0.8, 0.5], [0.0, 1.005]], [[-1.618, 0.083, 0.255, 0.217, 0.3, 0.01, 0.03333333333333333, 0.8, 0.5], [6.170339, 1.2944]], [[-4.582, 0.146, 0.0, 0.0, 0.1, 0.005, 0.03333333333333333, 0.0, 0.5], [0.0, -4.582]], [[1.499, -0.006, 0.0, 0.0, 0.2, 0.005, 0.03333333333333333, 0.3, 0.5], [0.0, 1.499]], [[0.478, 0.116, 1.213, 0.0, 0.2, 0.01, 0.03333333333333333, 0.3, 0.5], [0.130256, 0.636]]], [[[-1.984, 0.152, 0.177, 0.796, 0.1, 0.005, 0.016666666666666666, 0.3, 0.5], [2.945529, 0.882]], [[-2.54, 0.199, 0.0, 0.782, 0.3, 0.02, 0.016666666666666666, 0.0, 1.0], [7.368286, 3.222]], [[-2.372, 0.177, 1.352, 1.076, 0.2, 0.02, 0.03333333333333333, 0.8, 0.5], [1.758484, 1.8976]], [[0.326, -0.004, 0.0, 0.0, 0.2, 0.02, 0.03333333333333333, 0.8, 0.5], [0.0, 0.326]], [[0.566, 0.042, 0.0, 0.0, 0.1, 0.02, 0.03333333333333333, 0.8, 0.5], [0.0, 0.566]], [[-0.039, 0.017, 0.133, 0.913, 0.3, 0.02, 0.03333333333333333, 0.8, 0.5], [0.037285, 0.0]], [[-0.863, 0.138, 0.0, 0.0, 0.1, 0.005, 0.016666666666666666, 0.3, 0.5], [0.0, -0.863]], [[-0.434, 0.117, 0.778, 0.221, 0.1, 0.005, 0.016666666666666666, 0.8, 1.0], [1.107107, 0.672]]]]\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-restitution-threshold","generated_at":"2026-09-29T14:50:56.555608+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":"The bounce condition is vn < e_thresh.","sha256":"7ed848637d2d86b60b8de33320395e0c73ac6e5507e75179da410396bce1e02c","title":"Restitution threshold compares the signed velocity against a positive limit · 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.428,"exit_code":1,"observations":[{"actual":[0.0,1.672],"check":"case 0","expected":[0.0,1.672],"passed":true},{"actual":[0.984528,0.279],"check":"case 1","expected":[0.984528,0.279],"passed":true},{"actual":[1.088439,0.3411],"check":"case 2","expected":[1.088439,0.3411],"passed":true},{"actual":[1.122215,0.7656],"check":"case 3","expected":[0.904886,0.432],"passed":false},{"actual":[0.0,1.061],"check":"case 4","expected":[0.0,1.061],"passed":true},{"actual":[3.530114,3.186],"check":"case 5","expected":[3.530114,3.186],"passed":true},{"actual":[3.749698,1.344],"check":"case 6","expected":[3.749698,1.344],"passed":true},{"actual":[5.734628,0.0],"check":"case 7","expected":[5.734628,0.0],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"case 0\", \"actual\": [0.0, 1.672], \"expected\": [0.0, 1.672], \"passed\": true}, {\"check\": \"case 1\", \"actual\": [0.984528, 0.279], \"expected\": [0.984528, 0.279], \"passed\": true}, {\"check\": \"case 2\", \"actual\": [1.088439, 0.3411], \"expected\": [1.088439, 0.3411], \"passed\": true}, {\"check\": \"case 3\", \"actual\": [1.122215, 0.7656], \"expected\": [0.904886, 0.432], \"passed\": false}, {\"check\": \"case 4\", \"actual\": [0.0, 1.061], \"expected\": [0.0, 1.061], \"passed\": true}, {\"check\": \"case 5\", \"actual\": [3.530114, 3.186], \"expected\": [3.530114, 3.186], \"passed\": true}, {\"check\": \"case 6\", \"actual\": [3.749698, 1.344], \"expected\": [3.749698, 1.344], \"passed\": true}, {\"check\": \"case 7\", \"actual\": [5.734628, 0.0], \"expected\": [5.734628, 0.0], \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":38.891,"exit_code":1,"observations":[{"actual":[0.0,1.672],"check":"case 0","expected":[0.0,1.672],"passed":true},{"actual":[0.984528,0.279],"check":"case 1","expected":[0.984528,0.279],"passed":true},{"actual":[1.088439,0.3411],"check":"case 2","expected":[1.088439,0.3411],"passed":true},{"actual":[1.122215,0.7656],"check":"case 3","expected":[0.904886,0.432],"passed":false},{"actual":[0.0,1.061],"check":"case 4","expected":[0.0,1.061],"passed":true},{"actual":[3.530114,3.186],"check":"case 5","expected":[3.530114,3.186],"passed":true},{"actual":[3.749698,1.344],"check":"case 6","expected":[3.749698,1.344],"passed":true},{"actual":[5.734628,0.0],"check":"case 7","expected":[5.734628,0.0],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"case 0\", \"actual\": [0.0, 1.672], \"expected\": [0.0, 1.672], \"passed\": true}, {\"check\": \"case 1\", \"actual\": [0.984528, 0.279], \"expected\": [0.984528, 0.279], \"passed\": true}, {\"check\": \"case 2\", \"actual\": [1.088439, 0.3411], \"expected\": [1.088439, 0.3411], \"passed\": true}, {\"check\": \"case 3\", \"actual\": [1.122215, 0.7656], \"expected\": [0.904886, 0.432], \"passed\": false}, {\"check\": \"case 4\", \"actual\": [0.0, 1.061], \"expected\": [0.0, 1.061], \"passed\": true}, {\"check\": \"case 5\", \"actual\": [3.530114, 3.186], \"expected\": [3.530114, 3.186], \"passed\": true}, {\"check\": \"case 6\", \"actual\": [3.749698, 1.344], \"expected\": [3.749698, 1.344], \"passed\": true}, {\"check\": \"case 7\", \"actual\": [5.734628, 0.0], \"expected\": [5.734628, 0.0], \"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."}}