{"abstract":"Heavy bodies appear strongly damped and light ones barely damped.","category":"Physics integrator stability","checks":8,"contract":"solve(k, m, c, dt): classify explicit Euler on x'=v, v'=(-k*x-c*v)/m. Eigenvalues are the roots of s^2+(c/m)s+k/m; amplification is max |1+dt*lambda|. Return [\"marginal\" if |amp-1|<=1e-9, else \"stable\" if amp<1, else \"unstable\", amp rounded to 6].","evaluation_group":"w2-physics_integrator_stability-explicit-euler-stability","failed_approach":"Using c/(2m) confuses the rate with the damping ratio numerator.","family":"w2-physics_integrator_stability-explicit-euler-stability-damping-rate-scaling","id":"FA-86931","implementations":{"attempt":{"sha256":"ff1773c0422c791eed15e9c0f8a29330c04259305e88d1a4fc5917f6146ef17f","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nN = 1\nobservations = []\ndef solve(k, m, c, dt):\n    a = c / (2 * m)\n    b = k / m\n    disc = a * a - 4 * b\n    if disc >= 0:\n        r = math.sqrt(disc)\n        lams = [complex((-a + r) / 2, 0), complex((-a - r) / 2, 0)]\n    else:\n        r = math.sqrt(-disc)\n        lams = [complex(-a / 2, r / 2), complex(-a / 2, -r / 2)]\n    amp = max(abs(1 + dt * lam) for lam in lams)\n    if abs(amp - 1) <= 1e-9:\n        label = 'marginal'\n    elif amp < 1:\n        label = 'stable'\n    else:\n        label = 'unstable'\n    return [label, round(amp, 6)]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[[[0.0, 1.0, 2.0008, 1.0], ['unstable', 1.0008]], [[42.221, 2.418, 7.819, 0.01], ['stable', 0.984586]], [[16.494, 1.905, 4.155, 0.05], ['stable', 0.955296]], [[28.666, 0.459, 5.82, 0.1], ['stable', 0.597125]], [[42.548, 3.763, 4.806, 0.1], ['stable', 0.992649]], [[0.0, 3.907, 1.097, 1.0], ['marginal', 1.0]], [[0.0, 1.0, 1.0, 0.5], ['marginal', 1.0]], [[0.0, 0.421, 0.691, 0.05], ['marginal', 1.0]]], [[[0.0, 1.0, 2.0008, 1.0], ['unstable', 1.0008]], [[38.018, 1.276, 0.385, 0.2], ['unstable', 1.459946]], [[59.677, 2.374, 3.266, 1.0], ['unstable', 4.976144]], [[6.203, 0.678, 1.745, 0.05], ['stable', 0.945614]], [[0.0, 0.907, 6.001, 0.01], ['marginal', 1.0]], [[0.0, 1.0, 1.0, 0.5], ['marginal', 1.0]], [[0.0, 1.043, 3.236, 0.05], ['marginal', 1.0]], [[18.985, 2.12, 2.861, 1.0], ['unstable', 2.933541]]], [[[48.986, 0.701, 3.497, 0.1], ['unstable', 1.095419]], [[49.989, 2.073, 1.922, 0.8], ['unstable', 3.961243]], [[0.0, 1.763, 0.013, 0.8], ['marginal', 1.0]], [[17.741, 0.849, 5.676, 0.01], ['stable', 0.967075]], [[20.646, 3.925, 4.888, 0.2], ['stable', 0.980477]], [[0.0, 1.0, 2.0008, 1.0], ['unstable', 1.0008]], [[42.196, 3.443, 4.277, 0.8], ['unstable', 2.801748]], [[0.0, 1.0, 1.0, 0.5], ['marginal', 1.0]]], [[[41.131, 0.314, 6.187, 0.4], ['unstable', 3.751925]], [[23.134, 3.325, 2.902, 0.05], ['stable', 0.98679]], [[3.87, 2.12, 0.308, 0.05], ['stable', 0.998649]], [[0.0, 1.0, 2.0008, 1.0], ['unstable', 1.0008]], [[0.0, 3.102, 2.755, 0.05], ['marginal', 1.0]], [[9.079, 3.699, 5.728, 0.05], ['stable', 0.963696]], [[0.0, 1.0, 1.0, 0.5], ['marginal', 1.0]], [[57.413, 2.505, 6.221, 0.2], ['unstable', 1.191674]]], [[[0.0, 1.0, 1.0, 0.5], ['marginal', 1.0]], [[0.0, 1.0, 2.0008, 1.0], ['unstable', 1.0008]], [[0.0, 1.889, 7.242, 0.8], ['unstable', 2.06702]], [[31.247, 2.981, 5.247, 0.01], ['stable', 0.991689]], [[29.999, 0.715, 0.909, 0.01], ['stable', 0.995732]], [[18.339, 0.83, 4.998, 0.4], ['unstable', 1.458271]], [[20.299, 1.465, 6.715, 0.05], ['stable', 0.897474]], [[1.0, 1.0, 3.0, 0.1], ['stable', 0.961803]]]]\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":"a2238a2cd5a3d0fdfcc05da9d2721c20e080f2a4cfa116f60e9e0dff4083d0e6","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nN = 1\nobservations = []\ndef solve(k, m, c, dt):\n    a = c * m\n    b = k / m\n    disc = a * a - 4 * b\n    if disc >= 0:\n        r = math.sqrt(disc)\n        lams = [complex((-a + r) / 2, 0), complex((-a - r) / 2, 0)]\n    else:\n        r = math.sqrt(-disc)\n        lams = [complex(-a / 2, r / 2), complex(-a / 2, -r / 2)]\n    amp = max(abs(1 + dt * lam) for lam in lams)\n    if abs(amp - 1) <= 1e-9:\n        label = 'marginal'\n    elif amp < 1:\n        label = 'stable'\n    else:\n        label = 'unstable'\n    return [label, round(amp, 6)]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[[[0.0, 1.0, 2.0008, 1.0], ['unstable', 1.0008]], [[42.221, 2.418, 7.819, 0.01], ['stable', 0.984586]], [[16.494, 1.905, 4.155, 0.05], ['stable', 0.955296]], [[28.666, 0.459, 5.82, 0.1], ['stable', 0.597125]], [[42.548, 3.763, 4.806, 0.1], ['stable', 0.992649]], [[0.0, 3.907, 1.097, 1.0], ['marginal', 1.0]], [[0.0, 1.0, 1.0, 0.5], ['marginal', 1.0]], [[0.0, 0.421, 0.691, 0.05], ['marginal', 1.0]]], [[[0.0, 1.0, 2.0008, 1.0], ['unstable', 1.0008]], [[38.018, 1.276, 0.385, 0.2], ['unstable', 1.459946]], [[59.677, 2.374, 3.266, 1.0], ['unstable', 4.976144]], [[6.203, 0.678, 1.745, 0.05], ['stable', 0.945614]], [[0.0, 0.907, 6.001, 0.01], ['marginal', 1.0]], [[0.0, 1.0, 1.0, 0.5], ['marginal', 1.0]], [[0.0, 1.043, 3.236, 0.05], ['marginal', 1.0]], [[18.985, 2.12, 2.861, 1.0], ['unstable', 2.933541]]], [[[48.986, 0.701, 3.497, 0.1], ['unstable', 1.095419]], [[49.989, 2.073, 1.922, 0.8], ['unstable', 3.961243]], [[0.0, 1.763, 0.013, 0.8], ['marginal', 1.0]], [[17.741, 0.849, 5.676, 0.01], ['stable', 0.967075]], [[20.646, 3.925, 4.888, 0.2], ['stable', 0.980477]], [[0.0, 1.0, 2.0008, 1.0], ['unstable', 1.0008]], [[42.196, 3.443, 4.277, 0.8], ['unstable', 2.801748]], [[0.0, 1.0, 1.0, 0.5], ['marginal', 1.0]]], [[[41.131, 0.314, 6.187, 0.4], ['unstable', 3.751925]], [[23.134, 3.325, 2.902, 0.05], ['stable', 0.98679]], [[3.87, 2.12, 0.308, 0.05], ['stable', 0.998649]], [[0.0, 1.0, 2.0008, 1.0], ['unstable', 1.0008]], [[0.0, 3.102, 2.755, 0.05], ['marginal', 1.0]], [[9.079, 3.699, 5.728, 0.05], ['stable', 0.963696]], [[0.0, 1.0, 1.0, 0.5], ['marginal', 1.0]], [[57.413, 2.505, 6.221, 0.2], ['unstable', 1.191674]]], [[[0.0, 1.0, 1.0, 0.5], ['marginal', 1.0]], [[0.0, 1.0, 2.0008, 1.0], ['unstable', 1.0008]], [[0.0, 1.889, 7.242, 0.8], ['unstable', 2.06702]], [[31.247, 2.981, 5.247, 0.01], ['stable', 0.991689]], [[29.999, 0.715, 0.909, 0.01], ['stable', 0.995732]], [[18.339, 0.83, 4.998, 0.4], ['unstable', 1.458271]], [[20.299, 1.465, 6.715, 0.05], ['stable', 0.897474]], [[1.0, 1.0, 3.0, 0.1], ['stable', 0.961803]]]]\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":"43a5f6724b1b78616a06def5eb4d5ed34f5939cf27a3ba251b768aef54c06888","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nN = 1\nobservations = []\ndef solve(k, m, c, dt):\n    a = c / m\n    b = k / m\n    disc = a * a - 4 * b\n    if disc >= 0:\n        r = math.sqrt(disc)\n        lams = [complex((-a + r) / 2, 0), complex((-a - r) / 2, 0)]\n    else:\n        r = math.sqrt(-disc)\n        lams = [complex(-a / 2, r / 2), complex(-a / 2, -r / 2)]\n    amp = max(abs(1 + dt * lam) for lam in lams)\n    if abs(amp - 1) <= 1e-9:\n        label = 'marginal'\n    elif amp < 1:\n        label = 'stable'\n    else:\n        label = 'unstable'\n    return [label, round(amp, 6)]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[[[0.0, 1.0, 2.0008, 1.0], ['unstable', 1.0008]], [[42.221, 2.418, 7.819, 0.01], ['stable', 0.984586]], [[16.494, 1.905, 4.155, 0.05], ['stable', 0.955296]], [[28.666, 0.459, 5.82, 0.1], ['stable', 0.597125]], [[42.548, 3.763, 4.806, 0.1], ['stable', 0.992649]], [[0.0, 3.907, 1.097, 1.0], ['marginal', 1.0]], [[0.0, 1.0, 1.0, 0.5], ['marginal', 1.0]], [[0.0, 0.421, 0.691, 0.05], ['marginal', 1.0]]], [[[0.0, 1.0, 2.0008, 1.0], ['unstable', 1.0008]], [[38.018, 1.276, 0.385, 0.2], ['unstable', 1.459946]], [[59.677, 2.374, 3.266, 1.0], ['unstable', 4.976144]], [[6.203, 0.678, 1.745, 0.05], ['stable', 0.945614]], [[0.0, 0.907, 6.001, 0.01], ['marginal', 1.0]], [[0.0, 1.0, 1.0, 0.5], ['marginal', 1.0]], [[0.0, 1.043, 3.236, 0.05], ['marginal', 1.0]], [[18.985, 2.12, 2.861, 1.0], ['unstable', 2.933541]]], [[[48.986, 0.701, 3.497, 0.1], ['unstable', 1.095419]], [[49.989, 2.073, 1.922, 0.8], ['unstable', 3.961243]], [[0.0, 1.763, 0.013, 0.8], ['marginal', 1.0]], [[17.741, 0.849, 5.676, 0.01], ['stable', 0.967075]], [[20.646, 3.925, 4.888, 0.2], ['stable', 0.980477]], [[0.0, 1.0, 2.0008, 1.0], ['unstable', 1.0008]], [[42.196, 3.443, 4.277, 0.8], ['unstable', 2.801748]], [[0.0, 1.0, 1.0, 0.5], ['marginal', 1.0]]], [[[41.131, 0.314, 6.187, 0.4], ['unstable', 3.751925]], [[23.134, 3.325, 2.902, 0.05], ['stable', 0.98679]], [[3.87, 2.12, 0.308, 0.05], ['stable', 0.998649]], [[0.0, 1.0, 2.0008, 1.0], ['unstable', 1.0008]], [[0.0, 3.102, 2.755, 0.05], ['marginal', 1.0]], [[9.079, 3.699, 5.728, 0.05], ['stable', 0.963696]], [[0.0, 1.0, 1.0, 0.5], ['marginal', 1.0]], [[57.413, 2.505, 6.221, 0.2], ['unstable', 1.191674]]], [[[0.0, 1.0, 1.0, 0.5], ['marginal', 1.0]], [[0.0, 1.0, 2.0008, 1.0], ['unstable', 1.0008]], [[0.0, 1.889, 7.242, 0.8], ['unstable', 2.06702]], [[31.247, 2.981, 5.247, 0.01], ['stable', 0.991689]], [[29.999, 0.715, 0.909, 0.01], ['stable', 0.995732]], [[18.339, 0.83, 4.998, 0.4], ['unstable', 1.458271]], [[20.299, 1.465, 6.715, 0.05], ['stable', 0.897474]], [[1.0, 1.0, 3.0, 0.1], ['stable', 0.961803]]]]\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-explicit-euler-stability-damping-rate-scaling","generated_at":"2026-09-29T14:50:54.077404+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":"Use c/m as the linear coefficient.","root_cause":"The normalized damping is computed as c*m.","sha256":"e929f502ad2ea29de7709d4dfa66bf058645271b11c058822a2835e969bab18f","title":"Damping rate multiplies by mass instead of dividing · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":39.63,"exit_code":1,"observations":[{"actual":["marginal",1.0],"check":"case 0","expected":["unstable",1.0008],"passed":false},{"actual":["stable",0.992763],"check":"case 1","expected":["stable",0.984586],"passed":false},{"actual":["stable",0.983422],"check":"case 2","expected":["stable",0.955296],"passed":false},{"actual":["stable",0.995261],"check":"case 3","expected":["stable",0.597125],"passed":false},{"actual":["unstable",1.02431],"check":"case 4","expected":["stable",0.992649],"passed":false},{"actual":["marginal",1.0],"check":"case 5","expected":["marginal",1.0],"passed":true},{"actual":["marginal",1.0],"check":"case 6","expected":["marginal",1.0],"passed":true},{"actual":["marginal",1.0],"check":"case 7","expected":["marginal",1.0],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"case 0\", \"actual\": [\"marginal\", 1.0], \"expected\": [\"unstable\", 1.0008], \"passed\": false}, {\"check\": \"case 1\", \"actual\": [\"stable\", 0.992763], \"expected\": [\"stable\", 0.984586], \"passed\": false}, {\"check\": \"case 2\", \"actual\": [\"stable\", 0.983422], \"expected\": [\"stable\", 0.955296], \"passed\": false}, {\"check\": \"case 3\", \"actual\": [\"stable\", 0.995261], \"expected\": [\"stable\", 0.597125], \"passed\": false}, {\"check\": \"case 4\", \"actual\": [\"unstable\", 1.02431], \"expected\": [\"stable\", 0.992649], \"passed\": false}, {\"check\": \"case 5\", \"actual\": [\"marginal\", 1.0], \"expected\": [\"marginal\", 1.0], \"passed\": true}, {\"check\": \"case 6\", \"actual\": [\"marginal\", 1.0], \"expected\": [\"marginal\", 1.0], \"passed\": true}, {\"check\": \"case 7\", \"actual\": [\"marginal\", 1.0], \"expected\": [\"marginal\", 1.0], \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":40.011,"exit_code":1,"observations":[{"actual":["unstable",1.0008],"check":"case 0","expected":["unstable",1.0008],"passed":true},{"actual":["stable",0.990263],"check":"case 1","expected":["stable",0.984586],"passed":false},{"actual":["stable",0.934449],"check":"case 2","expected":["stable",0.955296],"passed":false},{"actual":["unstable",1.165072],"check":"case 3","expected":["stable",0.597125],"passed":false},{"actual":["stable",0.935154],"check":"case 4","expected":["stable",0.992649],"passed":false},{"actual":["unstable",3.285979],"check":"case 5","expected":["marginal",1.0],"passed":false},{"actual":["marginal",1.0],"check":"case 6","expected":["marginal",1.0],"passed":true},{"actual":["marginal",1.0],"check":"case 7","expected":["marginal",1.0],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"case 0\", \"actual\": [\"unstable\", 1.0008], \"expected\": [\"unstable\", 1.0008], \"passed\": true}, {\"check\": \"case 1\", \"actual\": [\"stable\", 0.990263], \"expected\": [\"stable\", 0.984586], \"passed\": false}, {\"check\": \"case 2\", \"actual\": [\"stable\", 0.934449], \"expected\": [\"stable\", 0.955296], \"passed\": false}, {\"check\": \"case 3\", \"actual\": [\"unstable\", 1.165072], \"expected\": [\"stable\", 0.597125], \"passed\": false}, {\"check\": \"case 4\", \"actual\": [\"stable\", 0.935154], \"expected\": [\"stable\", 0.992649], \"passed\": false}, {\"check\": \"case 5\", \"actual\": [\"unstable\", 3.285979], \"expected\": [\"marginal\", 1.0], \"passed\": false}, {\"check\": \"case 6\", \"actual\": [\"marginal\", 1.0], \"expected\": [\"marginal\", 1.0], \"passed\": true}, {\"check\": \"case 7\", \"actual\": [\"marginal\", 1.0], \"expected\": [\"marginal\", 1.0], \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":39.22,"exit_code":0,"observations":[{"actual":["unstable",1.0008],"check":"case 0","expected":["unstable",1.0008],"passed":true},{"actual":["stable",0.984586],"check":"case 1","expected":["stable",0.984586],"passed":true},{"actual":["stable",0.955296],"check":"case 2","expected":["stable",0.955296],"passed":true},{"actual":["stable",0.597125],"check":"case 3","expected":["stable",0.597125],"passed":true},{"actual":["stable",0.992649],"check":"case 4","expected":["stable",0.992649],"passed":true},{"actual":["marginal",1.0],"check":"case 5","expected":["marginal",1.0],"passed":true},{"actual":["marginal",1.0],"check":"case 6","expected":["marginal",1.0],"passed":true},{"actual":["marginal",1.0],"check":"case 7","expected":["marginal",1.0],"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"case 0\", \"actual\": [\"unstable\", 1.0008], \"expected\": [\"unstable\", 1.0008], \"passed\": true}, {\"check\": \"case 1\", \"actual\": [\"stable\", 0.984586], \"expected\": [\"stable\", 0.984586], \"passed\": true}, {\"check\": \"case 2\", \"actual\": [\"stable\", 0.955296], \"expected\": [\"stable\", 0.955296], \"passed\": true}, {\"check\": \"case 3\", \"actual\": [\"stable\", 0.597125], \"expected\": [\"stable\", 0.597125], \"passed\": true}, {\"check\": \"case 4\", \"actual\": [\"stable\", 0.992649], \"expected\": [\"stable\", 0.992649], \"passed\": true}, {\"check\": \"case 5\", \"actual\": [\"marginal\", 1.0], \"expected\": [\"marginal\", 1.0], \"passed\": true}, {\"check\": \"case 6\", \"actual\": [\"marginal\", 1.0], \"expected\": [\"marginal\", 1.0], \"passed\": true}, {\"check\": \"case 7\", \"actual\": [\"marginal\", 1.0], \"expected\": [\"marginal\", 1.0], \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}