FAILURE MAP
← Case archive

FA-87181 / Physics integrator stability / Open access

Baumgarte bias ignores the allowed penetration slop · case 01

Resting contacts jitter because every tiny overlap is pushed apart.

Verified by executionVariant 1 · 8 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The bias uses raw depth instead of depth minus slop.

VERIFIED REPAIR

Subtract the slop before computing the positional bias.

Unsuccessful approach: Adding the slop increases the correction instead of creating a dead zone.

Case 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.

Why this case matters

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.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(vn, depth, ima, imb, beta, slop, dt, e, e_thresh):
    w = ima + imb
    if w == 0:
        return [0.0, round(vn, 6)]
    pen = depth
    bias = beta / dt * pen if pen > 0 else 0.0
    bounce = -e * vn if vn < -e_thresh else 0.0
    target = max(bias, bounce)
    lam = (target - vn) / w
    if lam < 0:
        lam = 0.0
    return [round(lam, 6), round(vn + lam * w, 6)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[1.061, 0.153, 1.061, 0.71, 0.1, 0.01, 0.016666666666666666, 0.0, 1.0], [0.0, 1.061]], [[-3.544, -0.008, 0.323, 0.295, 0.3, 0.01, 0.03333333333333333, 0.0, 1.0], [5.734628, 0.0]], [[-4.27, 0.161, 0.0, 0.0, 0.3, 0.02, 0.016666666666666666, 0.8, 0.5], [0.0, -4.27]], [[-0.17, 0.187, 1.663, 0.132, 0.2, 0.02, 0.03333333333333333, 0.3, 1.0], [0.652925, 1.002]], [[-1.967, 0.032, 0.824, 0.115, 0.1, 0.01, 0.016666666666666666, 0.3, 1.0], [2.723216, 0.5901]], [[1.41, 0.135, 0.151, 1.614, 0.3, 0.01, 0.016666666666666666, 0.0, 0.5], [0.475921, 2.25]], [[-1.707, 0.165, 1.092, 1.877, 0.2, 0.02, 0.03333333333333333, 0.3, 0.5], [0.867969, 0.87]], [[0.481, 0.132, 1.594, 0.0, 0.3, 0.005, 0.016666666666666666, 0.3, 1.0], [1.132371, 2.286]]], [[[-3.128, 0.032, 1.25, 0.499, 0.3, 0.01, 0.016666666666666666, 0.0, 0.5], [2.014866, 0.396]], [[-4.507, 0.039, 0.426, 0.118, 0.1, 0.005, 0.03333333333333333, 0.0, 1.0], [8.472426, 0.102]], [[-1.309, 0.06, 0.588, 0.3, 0.3, 0.005, 0.016666666666666666, 0.8, 0.5], [2.653378, 1.0472]], [[-1.806, 0.01, 0.207, 1.574, 0.3, 0.02, 0.016666666666666666, 0.3, 0.5], [1.318248, 0.5418]], [[-0.804, 0.036, 0.433, 0.234, 0.2, 0.02, 0.016666666666666666, 0.3, 0.5], [1.567016, 0.2412]], [[-0.597, 0.075, 0.0, 1.813, 0.2, 0.01, 0.03333333333333333, 0.8, 0.5], [0.592719, 0.4776]], [[0.188, 0.181, 0.523, 0.76, 0.2, 0.005, 0.03333333333333333, 0.3, 1.0], [0.676539, 1.056]], [[-0.097, -0.005, 0.0, 0.0, 0.3, 0.02, 0.03333333333333333, 0.0, 0.5], [0.0, -0.097]]], [[[-3.223, 0.016, 0.0, 0.775, 0.3, 0.02, 0.03333333333333333, 0.0, 0.5], [4.15871, 0.0]], [[-3.414, 0.011, 0.771, 0.0, 0.3, 0.01, 0.03333333333333333, 0.0, 1.0], [4.439689, 0.009]], [[-4.774, 0.152, 0.577, 0.464, 0.2, 0.02, 0.03333333333333333, 0.3, 1.0], [5.961768, 1.4322]], [[-0.936, 0.188, 0.0, 1.517, 0.1, 0.02, 0.016666666666666666, 0.0, 1.0], [1.281477, 1.008]], [[-1.031, 0.026, 0.991, 1.885, 0.3, 0.01, 0.03333333333333333, 0.3, 0.5], [0.466029, 0.3093]], [[-1.057, 0.121, 1.527, 0.0, 0.1, 0.01, 0.03333333333333333, 0.8, 0.5], [1.245972, 0.8456]], [[0.862, 0.12, 1.337, 0.0, 0.2, 0.01, 0.016666666666666666, 0.3, 1.0], [0.342558, 1.32]], [[-0.511, 0.189, 1.377, 0.149, 0.1, 0.01, 0.016666666666666666, 0.0, 1.0], [1.038663, 1.074]]], [[[0.968, 0.133, 0.66, 0.792, 0.1, 0.02, 0.016666666666666666, 0.0, 1.0], [0.0, 0.968]], [[-2.143, 0.194, 0.0, 0.669, 0.3, 0.02, 0.03333333333333333, 0.8, 0.5], [5.765919, 1.7144]], [[0.68, 0.139, 0.0, 0.0, 0.2, 0.005, 0.03333333333333333, 0.8, 1.0], [0.0, 0.68]], [[-1.838, 0.169, 0.681, 0.247, 0.1, 0.01, 0.016666666666666666, 0.3, 1.0], [3.008621, 0.954]], [[1.301, 0.198, 0.37, 1.907, 0.2, 0.01, 0.016666666666666666, 0.0, 0.5], [0.419412, 2.256]], [[-3.478, 0.113, 1.262, 0.0, 0.1, 0.02, 0.03333333333333333, 0.8, 1.0], [4.960697, 2.7824]], [[-1.908, 0.096, 0.0, 1.607, 0.3, 0.02, 0.03333333333333333, 0.3, 1.0], [1.612943, 0.684]], [[0.114, 0.091, 1.781, 1.698, 0.2, 0.005, 0.03333333333333333, 0.8, 1.0], [0.11555, 0.516]]], [[[0.417, 0.123, 1.855, 0.385, 0.1, 0.01, 0.016666666666666666, 0.0, 1.0], [0.116518, 0.678]], [[-0.664, 0.157, 0.422, 1.429, 0.1, 0.02, 0.03333333333333333, 0.0, 0.5], [0.580767, 0.411]], [[-0.356, 0.162, 0.573, 0.0, 0.1, 0.005, 0.016666666666666666, 0.0, 0.5], [2.265271, 0.942]], [[-4.44, 0.057, 0.354, 0.785, 0.1, 0.01, 0.016666666666666666, 0.0, 0.5], [4.145742, 0.282]], [[-2.015, 0.144, 1.236, 0.634, 0.2, 0.02, 0.03333333333333333, 0.8, 1.0], [1.939572, 1.612]], [[-2.728, 0.159, 0.525, 0.0, 0.1, 0.005, 0.016666666666666666, 0.3, 0.5], [6.95619, 0.924]], [[-4.001, 0.059, 0.0, 0.0, 0.3, 0.02, 0.016666666666666666, 0.3, 0.5], [0.0, -4.001]], [[-1.445, 0.095, 1.787, 0.0, 0.1, 0.005, 0.03333333333333333, 0.8, 1.0], [1.455512, 1.156]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("case %d" % i, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
case 0[0.0, 1.061][0.0, 1.061]Passed
case 1[5.734628, 0.0][5.734628, 0.0]Passed
case 2[0.0, -4.27][0.0, -4.27]Passed
case 3[0.719777, 1.122][0.652925, 1.002]Failed
case 4[2.723216, 0.5901][2.723216, 0.5901]Passed
case 5[0.577904, 2.43][0.475921, 2.25]Failed
case 6[0.908387, 0.99][0.867969, 0.87]Failed
case 7[1.188833, 2.376][1.132371, 2.286]Failed

SHA-256 / 6ac6827c95e7db1d52c074d25da1ca30ce5ac49ba3e1e05a437efb441e44fd4e

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(vn, depth, ima, imb, beta, slop, dt, e, e_thresh):
    w = ima + imb
    if w == 0:
        return [0.0, round(vn, 6)]
    pen = depth + slop
    bias = beta / dt * pen if pen > 0 else 0.0
    bounce = -e * vn if vn < -e_thresh else 0.0
    target = max(bias, bounce)
    lam = (target - vn) / w
    if lam < 0:
        lam = 0.0
    return [round(lam, 6), round(vn + lam * w, 6)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[1.061, 0.153, 1.061, 0.71, 0.1, 0.01, 0.016666666666666666, 0.0, 1.0], [0.0, 1.061]], [[-3.544, -0.008, 0.323, 0.295, 0.3, 0.01, 0.03333333333333333, 0.0, 1.0], [5.734628, 0.0]], [[-4.27, 0.161, 0.0, 0.0, 0.3, 0.02, 0.016666666666666666, 0.8, 0.5], [0.0, -4.27]], [[-0.17, 0.187, 1.663, 0.132, 0.2, 0.02, 0.03333333333333333, 0.3, 1.0], [0.652925, 1.002]], [[-1.967, 0.032, 0.824, 0.115, 0.1, 0.01, 0.016666666666666666, 0.3, 1.0], [2.723216, 0.5901]], [[1.41, 0.135, 0.151, 1.614, 0.3, 0.01, 0.016666666666666666, 0.0, 0.5], [0.475921, 2.25]], [[-1.707, 0.165, 1.092, 1.877, 0.2, 0.02, 0.03333333333333333, 0.3, 0.5], [0.867969, 0.87]], [[0.481, 0.132, 1.594, 0.0, 0.3, 0.005, 0.016666666666666666, 0.3, 1.0], [1.132371, 2.286]]], [[[-3.128, 0.032, 1.25, 0.499, 0.3, 0.01, 0.016666666666666666, 0.0, 0.5], [2.014866, 0.396]], [[-4.507, 0.039, 0.426, 0.118, 0.1, 0.005, 0.03333333333333333, 0.0, 1.0], [8.472426, 0.102]], [[-1.309, 0.06, 0.588, 0.3, 0.3, 0.005, 0.016666666666666666, 0.8, 0.5], [2.653378, 1.0472]], [[-1.806, 0.01, 0.207, 1.574, 0.3, 0.02, 0.016666666666666666, 0.3, 0.5], [1.318248, 0.5418]], [[-0.804, 0.036, 0.433, 0.234, 0.2, 0.02, 0.016666666666666666, 0.3, 0.5], [1.567016, 0.2412]], [[-0.597, 0.075, 0.0, 1.813, 0.2, 0.01, 0.03333333333333333, 0.8, 0.5], [0.592719, 0.4776]], [[0.188, 0.181, 0.523, 0.76, 0.2, 0.005, 0.03333333333333333, 0.3, 1.0], [0.676539, 1.056]], [[-0.097, -0.005, 0.0, 0.0, 0.3, 0.02, 0.03333333333333333, 0.0, 0.5], [0.0, -0.097]]], [[[-3.223, 0.016, 0.0, 0.775, 0.3, 0.02, 0.03333333333333333, 0.0, 0.5], [4.15871, 0.0]], [[-3.414, 0.011, 0.771, 0.0, 0.3, 0.01, 0.03333333333333333, 0.0, 1.0], [4.439689, 0.009]], [[-4.774, 0.152, 0.577, 0.464, 0.2, 0.02, 0.03333333333333333, 0.3, 1.0], [5.961768, 1.4322]], [[-0.936, 0.188, 0.0, 1.517, 0.1, 0.02, 0.016666666666666666, 0.0, 1.0], [1.281477, 1.008]], [[-1.031, 0.026, 0.991, 1.885, 0.3, 0.01, 0.03333333333333333, 0.3, 0.5], [0.466029, 0.3093]], [[-1.057, 0.121, 1.527, 0.0, 0.1, 0.01, 0.03333333333333333, 0.8, 0.5], [1.245972, 0.8456]], [[0.862, 0.12, 1.337, 0.0, 0.2, 0.01, 0.016666666666666666, 0.3, 1.0], [0.342558, 1.32]], [[-0.511, 0.189, 1.377, 0.149, 0.1, 0.01, 0.016666666666666666, 0.0, 1.0], [1.038663, 1.074]]], [[[0.968, 0.133, 0.66, 0.792, 0.1, 0.02, 0.016666666666666666, 0.0, 1.0], [0.0, 0.968]], [[-2.143, 0.194, 0.0, 0.669, 0.3, 0.02, 0.03333333333333333, 0.8, 0.5], [5.765919, 1.7144]], [[0.68, 0.139, 0.0, 0.0, 0.2, 0.005, 0.03333333333333333, 0.8, 1.0], [0.0, 0.68]], [[-1.838, 0.169, 0.681, 0.247, 0.1, 0.01, 0.016666666666666666, 0.3, 1.0], [3.008621, 0.954]], [[1.301, 0.198, 0.37, 1.907, 0.2, 0.01, 0.016666666666666666, 0.0, 0.5], [0.419412, 2.256]], [[-3.478, 0.113, 1.262, 0.0, 0.1, 0.02, 0.03333333333333333, 0.8, 1.0], [4.960697, 2.7824]], [[-1.908, 0.096, 0.0, 1.607, 0.3, 0.02, 0.03333333333333333, 0.3, 1.0], [1.612943, 0.684]], [[0.114, 0.091, 1.781, 1.698, 0.2, 0.005, 0.03333333333333333, 0.8, 1.0], [0.11555, 0.516]]], [[[0.417, 0.123, 1.855, 0.385, 0.1, 0.01, 0.016666666666666666, 0.0, 1.0], [0.116518, 0.678]], [[-0.664, 0.157, 0.422, 1.429, 0.1, 0.02, 0.03333333333333333, 0.0, 0.5], [0.580767, 0.411]], [[-0.356, 0.162, 0.573, 0.0, 0.1, 0.005, 0.016666666666666666, 0.0, 0.5], [2.265271, 0.942]], [[-4.44, 0.057, 0.354, 0.785, 0.1, 0.01, 0.016666666666666666, 0.0, 0.5], [4.145742, 0.282]], [[-2.015, 0.144, 1.236, 0.634, 0.2, 0.02, 0.03333333333333333, 0.8, 1.0], [1.939572, 1.612]], [[-2.728, 0.159, 0.525, 0.0, 0.1, 0.005, 0.016666666666666666, 0.3, 0.5], [6.95619, 0.924]], [[-4.001, 0.059, 0.0, 0.0, 0.3, 0.02, 0.016666666666666666, 0.3, 0.5], [0.0, -4.001]], [[-1.445, 0.095, 1.787, 0.0, 0.1, 0.005, 0.03333333333333333, 0.8, 1.0], [1.455512, 1.156]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("case %d" % i, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
case 0[0.0, 1.061][0.0, 1.061]Passed
case 1[5.763754, 0.018][5.734628, 0.0]Failed
case 2[0.0, -4.27][0.0, -4.27]Passed
case 3[0.78663, 1.242][0.652925, 1.002]Failed
case 4[2.723216, 0.5901][2.723216, 0.5901]Passed
case 5[0.679887, 2.61][0.475921, 2.25]Failed
case 6[0.948804, 1.11][0.867969, 0.87]Failed
case 7[1.245295, 2.466][1.132371, 2.286]Failed

SHA-256 / f843faaeae94d306f31ebbb1df360537d1a1a616385a4224a51fa033673be9dc

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(vn, depth, ima, imb, beta, slop, dt, e, e_thresh):
    w = ima + imb
    if w == 0:
        return [0.0, round(vn, 6)]
    pen = depth - slop
    bias = beta / dt * pen if pen > 0 else 0.0
    bounce = -e * vn if vn < -e_thresh else 0.0
    target = max(bias, bounce)
    lam = (target - vn) / w
    if lam < 0:
        lam = 0.0
    return [round(lam, 6), round(vn + lam * w, 6)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[1.061, 0.153, 1.061, 0.71, 0.1, 0.01, 0.016666666666666666, 0.0, 1.0], [0.0, 1.061]], [[-3.544, -0.008, 0.323, 0.295, 0.3, 0.01, 0.03333333333333333, 0.0, 1.0], [5.734628, 0.0]], [[-4.27, 0.161, 0.0, 0.0, 0.3, 0.02, 0.016666666666666666, 0.8, 0.5], [0.0, -4.27]], [[-0.17, 0.187, 1.663, 0.132, 0.2, 0.02, 0.03333333333333333, 0.3, 1.0], [0.652925, 1.002]], [[-1.967, 0.032, 0.824, 0.115, 0.1, 0.01, 0.016666666666666666, 0.3, 1.0], [2.723216, 0.5901]], [[1.41, 0.135, 0.151, 1.614, 0.3, 0.01, 0.016666666666666666, 0.0, 0.5], [0.475921, 2.25]], [[-1.707, 0.165, 1.092, 1.877, 0.2, 0.02, 0.03333333333333333, 0.3, 0.5], [0.867969, 0.87]], [[0.481, 0.132, 1.594, 0.0, 0.3, 0.005, 0.016666666666666666, 0.3, 1.0], [1.132371, 2.286]]], [[[-3.128, 0.032, 1.25, 0.499, 0.3, 0.01, 0.016666666666666666, 0.0, 0.5], [2.014866, 0.396]], [[-4.507, 0.039, 0.426, 0.118, 0.1, 0.005, 0.03333333333333333, 0.0, 1.0], [8.472426, 0.102]], [[-1.309, 0.06, 0.588, 0.3, 0.3, 0.005, 0.016666666666666666, 0.8, 0.5], [2.653378, 1.0472]], [[-1.806, 0.01, 0.207, 1.574, 0.3, 0.02, 0.016666666666666666, 0.3, 0.5], [1.318248, 0.5418]], [[-0.804, 0.036, 0.433, 0.234, 0.2, 0.02, 0.016666666666666666, 0.3, 0.5], [1.567016, 0.2412]], [[-0.597, 0.075, 0.0, 1.813, 0.2, 0.01, 0.03333333333333333, 0.8, 0.5], [0.592719, 0.4776]], [[0.188, 0.181, 0.523, 0.76, 0.2, 0.005, 0.03333333333333333, 0.3, 1.0], [0.676539, 1.056]], [[-0.097, -0.005, 0.0, 0.0, 0.3, 0.02, 0.03333333333333333, 0.0, 0.5], [0.0, -0.097]]], [[[-3.223, 0.016, 0.0, 0.775, 0.3, 0.02, 0.03333333333333333, 0.0, 0.5], [4.15871, 0.0]], [[-3.414, 0.011, 0.771, 0.0, 0.3, 0.01, 0.03333333333333333, 0.0, 1.0], [4.439689, 0.009]], [[-4.774, 0.152, 0.577, 0.464, 0.2, 0.02, 0.03333333333333333, 0.3, 1.0], [5.961768, 1.4322]], [[-0.936, 0.188, 0.0, 1.517, 0.1, 0.02, 0.016666666666666666, 0.0, 1.0], [1.281477, 1.008]], [[-1.031, 0.026, 0.991, 1.885, 0.3, 0.01, 0.03333333333333333, 0.3, 0.5], [0.466029, 0.3093]], [[-1.057, 0.121, 1.527, 0.0, 0.1, 0.01, 0.03333333333333333, 0.8, 0.5], [1.245972, 0.8456]], [[0.862, 0.12, 1.337, 0.0, 0.2, 0.01, 0.016666666666666666, 0.3, 1.0], [0.342558, 1.32]], [[-0.511, 0.189, 1.377, 0.149, 0.1, 0.01, 0.016666666666666666, 0.0, 1.0], [1.038663, 1.074]]], [[[0.968, 0.133, 0.66, 0.792, 0.1, 0.02, 0.016666666666666666, 0.0, 1.0], [0.0, 0.968]], [[-2.143, 0.194, 0.0, 0.669, 0.3, 0.02, 0.03333333333333333, 0.8, 0.5], [5.765919, 1.7144]], [[0.68, 0.139, 0.0, 0.0, 0.2, 0.005, 0.03333333333333333, 0.8, 1.0], [0.0, 0.68]], [[-1.838, 0.169, 0.681, 0.247, 0.1, 0.01, 0.016666666666666666, 0.3, 1.0], [3.008621, 0.954]], [[1.301, 0.198, 0.37, 1.907, 0.2, 0.01, 0.016666666666666666, 0.0, 0.5], [0.419412, 2.256]], [[-3.478, 0.113, 1.262, 0.0, 0.1, 0.02, 0.03333333333333333, 0.8, 1.0], [4.960697, 2.7824]], [[-1.908, 0.096, 0.0, 1.607, 0.3, 0.02, 0.03333333333333333, 0.3, 1.0], [1.612943, 0.684]], [[0.114, 0.091, 1.781, 1.698, 0.2, 0.005, 0.03333333333333333, 0.8, 1.0], [0.11555, 0.516]]], [[[0.417, 0.123, 1.855, 0.385, 0.1, 0.01, 0.016666666666666666, 0.0, 1.0], [0.116518, 0.678]], [[-0.664, 0.157, 0.422, 1.429, 0.1, 0.02, 0.03333333333333333, 0.0, 0.5], [0.580767, 0.411]], [[-0.356, 0.162, 0.573, 0.0, 0.1, 0.005, 0.016666666666666666, 0.0, 0.5], [2.265271, 0.942]], [[-4.44, 0.057, 0.354, 0.785, 0.1, 0.01, 0.016666666666666666, 0.0, 0.5], [4.145742, 0.282]], [[-2.015, 0.144, 1.236, 0.634, 0.2, 0.02, 0.03333333333333333, 0.8, 1.0], [1.939572, 1.612]], [[-2.728, 0.159, 0.525, 0.0, 0.1, 0.005, 0.016666666666666666, 0.3, 0.5], [6.95619, 0.924]], [[-4.001, 0.059, 0.0, 0.0, 0.3, 0.02, 0.016666666666666666, 0.3, 0.5], [0.0, -4.001]], [[-1.445, 0.095, 1.787, 0.0, 0.1, 0.005, 0.03333333333333333, 0.8, 1.0], [1.455512, 1.156]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("case %d" % i, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
case 0[0.0, 1.061][0.0, 1.061]Passed
case 1[5.734628, 0.0][5.734628, 0.0]Passed
case 2[0.0, -4.27][0.0, -4.27]Passed
case 3[0.652925, 1.002][0.652925, 1.002]Passed
case 4[2.723216, 0.5901][2.723216, 0.5901]Passed
case 5[0.475921, 2.25][0.475921, 2.25]Passed
case 6[0.867969, 0.87][0.867969, 0.87]Passed
case 7[1.132371, 2.286][1.132371, 2.286]Passed

SHA-256 / 72e276032bc0b48611a781c691aa7c86fcef839fdb141c5ccb7c9ebaadb14ad6

Verification & scope

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.

Observations recorded using Python 3.12.14 at 2026-09-29T14:50:56.389126+00:00.

Case digest / ae4161aebeee467cb023223530fcfdf1214cccbfe22f5e9b4fe0d091c1941db9