FA-87201 / Physics integrator stability / Open access
Contact impulse is allowed to pull bodies together · case 01
Separating bodies stick to each other as if glued.
ROOT CAUSE
The clamp to non-negative impulse is missing.
VERIFIED REPAIR
Clamp the normal impulse at zero.
Unsuccessful approach: Clamping only when vn>0 still pulls on approaching-but-overcorrected contacts and zeroes valid pushes.
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 - 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 = lam
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 = [[[[0.754, 0.012, 0.882, 1.713, 0.2, 0.005, 0.016666666666666666, 0.0, 0.5], [0.0, 0.754]], [[1.105, 0.118, 0.831, 0.859, 0.3, 0.01, 0.03333333333333333, 0.3, 1.0], [0.0, 1.105]], [[-3.8, 0.137, 0.0, 0.729, 0.3, 0.005, 0.03333333333333333, 0.0, 1.0], [6.84225, 1.188]], [[0.269, 0.166, 0.604, 1.06, 0.2, 0.005, 0.016666666666666666, 0.0, 1.0], [0.999399, 1.932]], [[1.633, 0.101, 1.608, 0.0, 0.3, 0.01, 0.016666666666666666, 0.3, 0.5], [0.003109, 1.638]], [[1.672, 0.187, 0.0, 1.181, 0.1, 0.01, 0.03333333333333333, 0.8, 1.0], [0.0, 1.672]], [[0.67, 0.186, 1.405, 0.0, 0.3, 0.005, 0.03333333333333333, 0.0, 0.5], [0.682562, 1.629]], [[-4.073, 0.153, 1.667, 1.541, 0.1, 0.02, 0.016666666666666666, 0.3, 1.0], [1.65053, 1.2219]]], [[[-1.342, 0.19, 1.447, 0.0, 0.3, 0.01, 0.03333333333333333, 0.0, 0.5], [2.046994, 1.62]], [[0.818, 0.046, 0.978, 0.855, 0.1, 0.01, 0.03333333333333333, 0.0, 0.5], [0.0, 0.818]], [[0.065, 0.089, 1.737, 0.0, 0.1, 0.005, 0.03333333333333333, 0.3, 0.5], [0.107657, 0.252]], [[-3.153, 0.024, 1.019, 1.692, 0.2, 0.02, 0.016666666666666666, 0.3, 1.0], [1.511951, 0.9459]], [[0.188, 0.181, 0.523, 0.76, 0.2, 0.005, 0.03333333333333333, 0.3, 1.0], [0.676539, 1.056]], [[1.15, 0.103, 1.199, 0.438, 0.3, 0.005, 0.03333333333333333, 0.0, 0.5], [0.0, 1.15]], [[0.743, -0.018, 0.823, 0.0, 0.2, 0.01, 0.016666666666666666, 0.0, 0.5], [0.0, 0.743]], [[0.906, 0.171, 1.426, 0.0, 0.2, 0.01, 0.03333333333333333, 0.8, 1.0], [0.042076, 0.966]]], [[[1.934, 0.049, 1.154, 0.411, 0.1, 0.02, 0.016666666666666666, 0.3, 0.5], [0.0, 1.934]], [[1.323, 0.08, 1.104, 0.0, 0.2, 0.01, 0.016666666666666666, 0.8, 0.5], [0.0, 1.323]], [[0.388, 0.152, 0.68, 1.334, 0.1, 0.005, 0.016666666666666666, 0.3, 1.0], [0.245283, 0.882]], [[1.076, 0.015, 1.679, 1.249, 0.2, 0.02, 0.016666666666666666, 0.8, 0.5], [0.0, 1.076]], [[-1.884, 0.178, 0.644, 0.121, 0.2, 0.01, 0.016666666666666666, 0.8, 0.5], [5.098039, 2.016]], [[-1.637, 0.003, 0.0, 0.0, 0.1, 0.005, 0.03333333333333333, 0.3, 1.0], [0.0, -1.637]], [[0.862, 0.12, 1.337, 0.0, 0.2, 0.01, 0.016666666666666666, 0.3, 1.0], [0.342558, 1.32]], [[0.891, 0.162, 0.327, 0.106, 0.2, 0.01, 0.016666666666666666, 0.0, 1.0], [2.154734, 1.824]]], [[[1.004, 0.112, 0.796, 0.0, 0.1, 0.01, 0.03333333333333333, 0.8, 1.0], [0.0, 1.004]], [[1.516, 0.165, 1.051, 0.0, 0.1, 0.01, 0.016666666666666666, 0.3, 1.0], [0.0, 1.516]], [[0.08, 0.097, 0.146, 0.0, 0.3, 0.005, 0.016666666666666666, 0.8, 0.5], [10.794521, 1.656]], [[-1.908, 0.096, 0.0, 1.607, 0.3, 0.02, 0.03333333333333333, 0.3, 1.0], [1.612943, 0.684]], [[0.513, 0.1, 0.238, 0.744, 0.1, 0.005, 0.03333333333333333, 0.8, 1.0], [0.0, 0.513]], [[-4.768, 0.04, 1.908, 1.371, 0.3, 0.01, 0.016666666666666666, 0.8, 1.0], [2.617383, 3.8144]], [[0.169, 0.16, 0.966, 0.0, 0.1, 0.005, 0.03333333333333333, 0.0, 0.5], [0.306418, 0.465]], [[-1.706, 0.151, 0.445, 0.0, 0.1, 0.02, 0.03333333333333333, 0.3, 1.0], [4.98382, 0.5118]]], [[[0.417, 0.123, 1.855, 0.385, 0.1, 0.01, 0.016666666666666666, 0.0, 1.0], [0.116518, 0.678]], [[1.669, 0.084, 0.494, 0.237, 0.1, 0.02, 0.016666666666666666, 0.8, 0.5], [0.0, 1.669]], [[-0.664, 0.157, 0.422, 1.429, 0.1, 0.02, 0.03333333333333333, 0.0, 0.5], [0.580767, 0.411]], [[1.424, 0.05, 0.809, 1.444, 0.1, 0.02, 0.016666666666666666, 0.0, 1.0], [0.0, 1.424]], [[1.002, 0.164, 0.192, 0.217, 0.2, 0.02, 0.016666666666666666, 0.3, 1.0], [1.775061, 1.728]], [[-1.761, 0.061, 0.961, 0.0, 0.1, 0.02, 0.016666666666666666, 0.8, 0.5], [3.298439, 1.4088]], [[1.967, 0.183, 0.871, 0.109, 0.1, 0.01, 0.016666666666666666, 0.3, 0.5], [0.0, 1.967]], [[-2.83, 0.119, 1.216, 0.0, 0.3, 0.01, 0.016666666666666666, 0.0, 1.0], [3.940789, 1.962]]]]
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| case 0 | [-0.258189, 0.084] | [0.0, 0.754] | Failed |
| case 1 | [-0.078698, 0.972] | [0.0, 1.105] | Failed |
| case 2 | [6.84225, 1.188] | [6.84225, 1.188] | Passed |
| case 3 | [0.999399, 1.932] | [0.999399, 1.932] | Passed |
| case 4 | [0.003109, 1.638] | [0.003109, 1.638] | Passed |
| case 5 | [-0.96613, 0.531] | [0.0, 1.672] | Failed |
| case 6 | [0.682562, 1.629] | [0.682562, 1.629] | Passed |
| case 7 | [1.65053, 1.2219] | [1.65053, 1.2219] | Passed |
SHA-256 / 7b2b5d7353c24a9d55f4cf09355de8c07e9a914decc9742d0420731648bed3a6
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 vn > 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 = [[[[0.754, 0.012, 0.882, 1.713, 0.2, 0.005, 0.016666666666666666, 0.0, 0.5], [0.0, 0.754]], [[1.105, 0.118, 0.831, 0.859, 0.3, 0.01, 0.03333333333333333, 0.3, 1.0], [0.0, 1.105]], [[-3.8, 0.137, 0.0, 0.729, 0.3, 0.005, 0.03333333333333333, 0.0, 1.0], [6.84225, 1.188]], [[0.269, 0.166, 0.604, 1.06, 0.2, 0.005, 0.016666666666666666, 0.0, 1.0], [0.999399, 1.932]], [[1.633, 0.101, 1.608, 0.0, 0.3, 0.01, 0.016666666666666666, 0.3, 0.5], [0.003109, 1.638]], [[1.672, 0.187, 0.0, 1.181, 0.1, 0.01, 0.03333333333333333, 0.8, 1.0], [0.0, 1.672]], [[0.67, 0.186, 1.405, 0.0, 0.3, 0.005, 0.03333333333333333, 0.0, 0.5], [0.682562, 1.629]], [[-4.073, 0.153, 1.667, 1.541, 0.1, 0.02, 0.016666666666666666, 0.3, 1.0], [1.65053, 1.2219]]], [[[-1.342, 0.19, 1.447, 0.0, 0.3, 0.01, 0.03333333333333333, 0.0, 0.5], [2.046994, 1.62]], [[0.818, 0.046, 0.978, 0.855, 0.1, 0.01, 0.03333333333333333, 0.0, 0.5], [0.0, 0.818]], [[0.065, 0.089, 1.737, 0.0, 0.1, 0.005, 0.03333333333333333, 0.3, 0.5], [0.107657, 0.252]], [[-3.153, 0.024, 1.019, 1.692, 0.2, 0.02, 0.016666666666666666, 0.3, 1.0], [1.511951, 0.9459]], [[0.188, 0.181, 0.523, 0.76, 0.2, 0.005, 0.03333333333333333, 0.3, 1.0], [0.676539, 1.056]], [[1.15, 0.103, 1.199, 0.438, 0.3, 0.005, 0.03333333333333333, 0.0, 0.5], [0.0, 1.15]], [[0.743, -0.018, 0.823, 0.0, 0.2, 0.01, 0.016666666666666666, 0.0, 0.5], [0.0, 0.743]], [[0.906, 0.171, 1.426, 0.0, 0.2, 0.01, 0.03333333333333333, 0.8, 1.0], [0.042076, 0.966]]], [[[1.934, 0.049, 1.154, 0.411, 0.1, 0.02, 0.016666666666666666, 0.3, 0.5], [0.0, 1.934]], [[1.323, 0.08, 1.104, 0.0, 0.2, 0.01, 0.016666666666666666, 0.8, 0.5], [0.0, 1.323]], [[0.388, 0.152, 0.68, 1.334, 0.1, 0.005, 0.016666666666666666, 0.3, 1.0], [0.245283, 0.882]], [[1.076, 0.015, 1.679, 1.249, 0.2, 0.02, 0.016666666666666666, 0.8, 0.5], [0.0, 1.076]], [[-1.884, 0.178, 0.644, 0.121, 0.2, 0.01, 0.016666666666666666, 0.8, 0.5], [5.098039, 2.016]], [[-1.637, 0.003, 0.0, 0.0, 0.1, 0.005, 0.03333333333333333, 0.3, 1.0], [0.0, -1.637]], [[0.862, 0.12, 1.337, 0.0, 0.2, 0.01, 0.016666666666666666, 0.3, 1.0], [0.342558, 1.32]], [[0.891, 0.162, 0.327, 0.106, 0.2, 0.01, 0.016666666666666666, 0.0, 1.0], [2.154734, 1.824]]], [[[1.004, 0.112, 0.796, 0.0, 0.1, 0.01, 0.03333333333333333, 0.8, 1.0], [0.0, 1.004]], [[1.516, 0.165, 1.051, 0.0, 0.1, 0.01, 0.016666666666666666, 0.3, 1.0], [0.0, 1.516]], [[0.08, 0.097, 0.146, 0.0, 0.3, 0.005, 0.016666666666666666, 0.8, 0.5], [10.794521, 1.656]], [[-1.908, 0.096, 0.0, 1.607, 0.3, 0.02, 0.03333333333333333, 0.3, 1.0], [1.612943, 0.684]], [[0.513, 0.1, 0.238, 0.744, 0.1, 0.005, 0.03333333333333333, 0.8, 1.0], [0.0, 0.513]], [[-4.768, 0.04, 1.908, 1.371, 0.3, 0.01, 0.016666666666666666, 0.8, 1.0], [2.617383, 3.8144]], [[0.169, 0.16, 0.966, 0.0, 0.1, 0.005, 0.03333333333333333, 0.0, 0.5], [0.306418, 0.465]], [[-1.706, 0.151, 0.445, 0.0, 0.1, 0.02, 0.03333333333333333, 0.3, 1.0], [4.98382, 0.5118]]], [[[0.417, 0.123, 1.855, 0.385, 0.1, 0.01, 0.016666666666666666, 0.0, 1.0], [0.116518, 0.678]], [[1.669, 0.084, 0.494, 0.237, 0.1, 0.02, 0.016666666666666666, 0.8, 0.5], [0.0, 1.669]], [[-0.664, 0.157, 0.422, 1.429, 0.1, 0.02, 0.03333333333333333, 0.0, 0.5], [0.580767, 0.411]], [[1.424, 0.05, 0.809, 1.444, 0.1, 0.02, 0.016666666666666666, 0.0, 1.0], [0.0, 1.424]], [[1.002, 0.164, 0.192, 0.217, 0.2, 0.02, 0.016666666666666666, 0.3, 1.0], [1.775061, 1.728]], [[-1.761, 0.061, 0.961, 0.0, 0.1, 0.02, 0.016666666666666666, 0.8, 0.5], [3.298439, 1.4088]], [[1.967, 0.183, 0.871, 0.109, 0.1, 0.01, 0.016666666666666666, 0.3, 0.5], [0.0, 1.967]], [[-2.83, 0.119, 1.216, 0.0, 0.3, 0.01, 0.016666666666666666, 0.0, 1.0], [3.940789, 1.962]]]]
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| case 0 | [0.0, 0.754] | [0.0, 0.754] | Passed |
| case 1 | [0.0, 1.105] | [0.0, 1.105] | Passed |
| case 2 | [6.84225, 1.188] | [6.84225, 1.188] | Passed |
| case 3 | [0.0, 0.269] | [0.999399, 1.932] | Failed |
| case 4 | [0.0, 1.633] | [0.003109, 1.638] | Failed |
| case 5 | [0.0, 1.672] | [0.0, 1.672] | Passed |
| case 6 | [0.0, 0.67] | [0.682562, 1.629] | Failed |
| case 7 | [1.65053, 1.2219] | [1.65053, 1.2219] | Passed |
SHA-256 / 5cfa4665a66b65d6de30c591ee76b55f37e9026d4591a475dd5f8008138333ba
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 = [[[[0.754, 0.012, 0.882, 1.713, 0.2, 0.005, 0.016666666666666666, 0.0, 0.5], [0.0, 0.754]], [[1.105, 0.118, 0.831, 0.859, 0.3, 0.01, 0.03333333333333333, 0.3, 1.0], [0.0, 1.105]], [[-3.8, 0.137, 0.0, 0.729, 0.3, 0.005, 0.03333333333333333, 0.0, 1.0], [6.84225, 1.188]], [[0.269, 0.166, 0.604, 1.06, 0.2, 0.005, 0.016666666666666666, 0.0, 1.0], [0.999399, 1.932]], [[1.633, 0.101, 1.608, 0.0, 0.3, 0.01, 0.016666666666666666, 0.3, 0.5], [0.003109, 1.638]], [[1.672, 0.187, 0.0, 1.181, 0.1, 0.01, 0.03333333333333333, 0.8, 1.0], [0.0, 1.672]], [[0.67, 0.186, 1.405, 0.0, 0.3, 0.005, 0.03333333333333333, 0.0, 0.5], [0.682562, 1.629]], [[-4.073, 0.153, 1.667, 1.541, 0.1, 0.02, 0.016666666666666666, 0.3, 1.0], [1.65053, 1.2219]]], [[[-1.342, 0.19, 1.447, 0.0, 0.3, 0.01, 0.03333333333333333, 0.0, 0.5], [2.046994, 1.62]], [[0.818, 0.046, 0.978, 0.855, 0.1, 0.01, 0.03333333333333333, 0.0, 0.5], [0.0, 0.818]], [[0.065, 0.089, 1.737, 0.0, 0.1, 0.005, 0.03333333333333333, 0.3, 0.5], [0.107657, 0.252]], [[-3.153, 0.024, 1.019, 1.692, 0.2, 0.02, 0.016666666666666666, 0.3, 1.0], [1.511951, 0.9459]], [[0.188, 0.181, 0.523, 0.76, 0.2, 0.005, 0.03333333333333333, 0.3, 1.0], [0.676539, 1.056]], [[1.15, 0.103, 1.199, 0.438, 0.3, 0.005, 0.03333333333333333, 0.0, 0.5], [0.0, 1.15]], [[0.743, -0.018, 0.823, 0.0, 0.2, 0.01, 0.016666666666666666, 0.0, 0.5], [0.0, 0.743]], [[0.906, 0.171, 1.426, 0.0, 0.2, 0.01, 0.03333333333333333, 0.8, 1.0], [0.042076, 0.966]]], [[[1.934, 0.049, 1.154, 0.411, 0.1, 0.02, 0.016666666666666666, 0.3, 0.5], [0.0, 1.934]], [[1.323, 0.08, 1.104, 0.0, 0.2, 0.01, 0.016666666666666666, 0.8, 0.5], [0.0, 1.323]], [[0.388, 0.152, 0.68, 1.334, 0.1, 0.005, 0.016666666666666666, 0.3, 1.0], [0.245283, 0.882]], [[1.076, 0.015, 1.679, 1.249, 0.2, 0.02, 0.016666666666666666, 0.8, 0.5], [0.0, 1.076]], [[-1.884, 0.178, 0.644, 0.121, 0.2, 0.01, 0.016666666666666666, 0.8, 0.5], [5.098039, 2.016]], [[-1.637, 0.003, 0.0, 0.0, 0.1, 0.005, 0.03333333333333333, 0.3, 1.0], [0.0, -1.637]], [[0.862, 0.12, 1.337, 0.0, 0.2, 0.01, 0.016666666666666666, 0.3, 1.0], [0.342558, 1.32]], [[0.891, 0.162, 0.327, 0.106, 0.2, 0.01, 0.016666666666666666, 0.0, 1.0], [2.154734, 1.824]]], [[[1.004, 0.112, 0.796, 0.0, 0.1, 0.01, 0.03333333333333333, 0.8, 1.0], [0.0, 1.004]], [[1.516, 0.165, 1.051, 0.0, 0.1, 0.01, 0.016666666666666666, 0.3, 1.0], [0.0, 1.516]], [[0.08, 0.097, 0.146, 0.0, 0.3, 0.005, 0.016666666666666666, 0.8, 0.5], [10.794521, 1.656]], [[-1.908, 0.096, 0.0, 1.607, 0.3, 0.02, 0.03333333333333333, 0.3, 1.0], [1.612943, 0.684]], [[0.513, 0.1, 0.238, 0.744, 0.1, 0.005, 0.03333333333333333, 0.8, 1.0], [0.0, 0.513]], [[-4.768, 0.04, 1.908, 1.371, 0.3, 0.01, 0.016666666666666666, 0.8, 1.0], [2.617383, 3.8144]], [[0.169, 0.16, 0.966, 0.0, 0.1, 0.005, 0.03333333333333333, 0.0, 0.5], [0.306418, 0.465]], [[-1.706, 0.151, 0.445, 0.0, 0.1, 0.02, 0.03333333333333333, 0.3, 1.0], [4.98382, 0.5118]]], [[[0.417, 0.123, 1.855, 0.385, 0.1, 0.01, 0.016666666666666666, 0.0, 1.0], [0.116518, 0.678]], [[1.669, 0.084, 0.494, 0.237, 0.1, 0.02, 0.016666666666666666, 0.8, 0.5], [0.0, 1.669]], [[-0.664, 0.157, 0.422, 1.429, 0.1, 0.02, 0.03333333333333333, 0.0, 0.5], [0.580767, 0.411]], [[1.424, 0.05, 0.809, 1.444, 0.1, 0.02, 0.016666666666666666, 0.0, 1.0], [0.0, 1.424]], [[1.002, 0.164, 0.192, 0.217, 0.2, 0.02, 0.016666666666666666, 0.3, 1.0], [1.775061, 1.728]], [[-1.761, 0.061, 0.961, 0.0, 0.1, 0.02, 0.016666666666666666, 0.8, 0.5], [3.298439, 1.4088]], [[1.967, 0.183, 0.871, 0.109, 0.1, 0.01, 0.016666666666666666, 0.3, 0.5], [0.0, 1.967]], [[-2.83, 0.119, 1.216, 0.0, 0.3, 0.01, 0.016666666666666666, 0.0, 1.0], [3.940789, 1.962]]]]
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| case 0 | [0.0, 0.754] | [0.0, 0.754] | Passed |
| case 1 | [0.0, 1.105] | [0.0, 1.105] | Passed |
| case 2 | [6.84225, 1.188] | [6.84225, 1.188] | Passed |
| case 3 | [0.999399, 1.932] | [0.999399, 1.932] | Passed |
| case 4 | [0.003109, 1.638] | [0.003109, 1.638] | Passed |
| case 5 | [0.0, 1.672] | [0.0, 1.672] | Passed |
| case 6 | [0.682562, 1.629] | [0.682562, 1.629] | Passed |
| case 7 | [1.65053, 1.2219] | [1.65053, 1.2219] | Passed |
SHA-256 / fd89b0cad292703922b985611ff0a5dcdfc705840ddb031b75ce51be42c706c9
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.570639+00:00.
Case digest / 6750a129bd4262be5ca7c531cf86aa91b256c546af944cb34ac00584de5fe691