FA-86966 / Physics integrator stability / Open access
Critical step keeps the loosest spring rather than the stiffest · case 01
A single stiff spring in a soft network is integrated with the soft spring step.
ROOT CAUSE
The minimum search uses h > hc.
VERIFIED REPAIR
Keep the smallest critical step over all springs.
Unsuccessful approach: Taking only the first limiting spring ignores later stiffer ones.
Case contract
solve(springs, safety, dt_frame, max_sub): springs are [k, inv_mass_a, inv_mass_b] (inverse mass 0 = static). A spring with k>0 and nonzero summed inverse mass w limits the substep to safety*2/sqrt(k*w). n=ceil(dt_frame/h_min) clamped to [1,max_sub]; return [n, dt_frame/n rounded to 6, whether n had to be clamped down]. No limiting spring gives [1, dt_frame, False].
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(springs, safety, dt_frame, max_sub):
hc = None
for k, im1, im2 in springs:
w = im1 + im2
if w == 0 or k <= 0:
continue
h = safety * 2.0 / math.sqrt(k * w)
if hc is None or h > hc:
hc = h
if hc is None:
return [1, round(dt_frame, 6), False]
n = math.ceil(dt_frame / hc - 1e-12)
clamped = n > max_sub
n = min(max(n, 1), max_sub)
return [n, round(dt_frame / n, 6), clamped]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[[[274.6, 1.615, 1.293], [279.2, 0.0, 1.072], [36.0, 1.606, 0.0]], 0.8, 0.1, 8], [2, 0.05, False]], [[[[176.6, 0.318, 1.727]], 0.9, 0.1, 1], [1, 0.1, True]], [[[[217.3, 0.0, 0.272], [226.4, 1.256, 1.506], [86.4, 1.936, 1.121]], 0.8, 0.1, 7], [2, 0.05, False]], [[[[51.4, 0.26, 0.0], [194.4, 1.517, 0.0]], 0.5, 0.1, 5], [2, 0.05, False]], [[[[148.8, 1.386, 0.442]], 0.8, 0.016666666666666666, 4], [1, 0.016667, False]], [[[[260.1, 0.0, 1.95]], 0.9, 0.016666666666666666, 1], [1, 0.016667, False]], [[[[299.0, 0.587, 0.527], [101.7, 1.086, 0.0], [96.2, 1.589, 0.676]], 0.9, 0.05, 9], [1, 0.05, False]], [[[[140.9, 1.164, 1.839], [288.3, 1.884, 0.0]], 0.9, 0.016666666666666666, 5], [1, 0.016667, False]]], [[[[[252.4, 0.823, 0.921], [0.0, 0.0, 1.281], [144.4, 0.0, 0.0], [399.0, 0.924, 1.926]], 0.9, 0.03333333333333333, 12], [1, 0.033333, False]], [[[[225.1, 0.0, 1.023]], 0.5, 0.016666666666666666, 4], [1, 0.016667, False]], [[[[239.0, 0.421, 0.398], [322.8, 0.0, 1.917], [189.8, 0.0, 0.0], [229.0, 1.496, 0.0]], 0.5, 0.05, 9], [2, 0.025, False]], [[[[297.9, 0.714, 1.84], [274.1, 0.797, 0.0], [150.2, 0.931, 1.101], [84.3, 0.7, 1.504]], 0.9, 0.016666666666666666, 12], [1, 0.016667, False]], [[[[331.5, 0.435, 0.0], [309.7, 1.309, 1.986]], 0.8, 0.1, 9], [2, 0.05, False]], [[[[208.5, 1.926, 0.106]], 0.9, 0.1, 11], [2, 0.05, False]], [[[[176.2, 1.797, 1.825], [298.2, 0.526, 0.891], [118.3, 0.227, 0.0]], 0.5, 0.1, 2], [2, 0.05, True]], [[[[288.5, 0.0, 0.0], [135.2, 0.764, 0.24], [389.1, 0.45, 1.145]], 0.5, 0.05, 6], [2, 0.025, False]]], [[[[[312.6, 0.0, 1.453]], 0.5, 0.1, 12], [3, 0.033333, False]], [[[[160.0, 1.174, 1.024], [222.4, 0.746, 0.568], [234.1, 0.0, 0.0], [305.9, 0.261, 0.0]], 0.8, 0.1, 5], [2, 0.05, False]], [[[[219.4, 0.47, 0.357], [244.7, 1.869, 0.0], [206.2, 0.734, 1.4]], 0.9, 0.1, 8], [2, 0.05, False]], [[[[8.4, 0.0, 1.944]], 0.9, 0.016666666666666666, 2], [1, 0.016667, False]], [[[[187.2, 0.446, 0.0], [384.2, 0.164, 1.101]], 0.5, 0.1, 6], [3, 0.033333, False]], [[[[0.0, 0.0, 0.802], [39.7, 0.0, 0.859]], 0.5, 0.1, 8], [1, 0.1, False]], [[[[98.4, 0.155, 0.544], [243.2, 0.0, 0.932], [174.9, 0.0, 0.913], [326.4, 1.87, 1.935]], 0.8, 0.05, 8], [2, 0.025, False]], [[[[308.1, 0.0, 0.454], [396.0, 0.194, 1.062]], 0.5, 0.05, 10], [2, 0.025, False]]], [[[[[231.0, 0.0, 1.82], [25.6, 1.068, 0.0], [268.8, 1.477, 0.0]], 0.5, 0.05, 5], [2, 0.025, False]], [[[[112.1, 1.181, 0.0], [364.2, 0.0, 0.0], [122.5, 0.0, 1.265]], 0.5, 0.05, 5], [1, 0.05, False]], [[[[74.9, 1.534, 1.135]], 0.8, 0.016666666666666666, 12], [1, 0.016667, False]], [[[[30.9, 0.794, 0.198], [0.0, 0.658, 0.0], [398.0, 1.934, 0.424]], 0.8, 0.1, 12], [2, 0.05, False]], [[[[385.7, 1.862, 1.408], [57.2, 1.136, 0.0], [93.5, 0.0, 0.0]], 0.5, 0.05, 12], [2, 0.025, False]], [[[[12.1, 0.309, 1.274], [153.5, 0.738, 0.969]], 0.5, 0.1, 12], [2, 0.05, False]], [[[[112.1, 1.978, 0.662]], 0.9, 0.016666666666666666, 10], [1, 0.016667, False]], [[[[103.2, 0.656, 0.0], [364.0, 0.395, 1.113]], 0.8, 0.016666666666666666, 1], [1, 0.016667, False]]], [[[[[25.9, 0.416, 0.0], [156.4, 1.139, 0.483], [279.4, 0.175, 1.863], [0.0, 1.682, 0.782]], 0.9, 0.03333333333333333, 7], [1, 0.033333, False]], [[[[0.0, 1.7, 0.0], [0.0, 0.0, 1.054], [328.3, 0.57, 0.359], [398.1, 1.479, 0.689]], 0.9, 0.1, 12], [2, 0.05, False]], [[[[0.0, 0.0, 0.743], [153.1, 1.007, 0.97]], 0.5, 0.05, 6], [1, 0.05, False]], [[[[97.9, 0.752, 1.178], [382.4, 1.927, 1.693], [68.3, 0.0, 0.0]], 0.9, 0.1, 11], [3, 0.033333, False]], [[[[149.6, 1.802, 0.77], [102.2, 1.828, 0.436]], 0.5, 0.1, 7], [2, 0.05, False]], [[[[0.0, 1.613, 0.0], [46.8, 1.168, 1.601], [255.1, 0.0, 0.0], [397.8, 0.0, 0.649]], 0.8, 0.1, 1], [1, 0.1, True]], [[[[338.0, 0.517, 0.0], [288.8, 0.0, 1.978], [37.6, 1.094, 1.076]], 0.9, 0.05, 11], [1, 0.05, False]], [[[[333.7, 1.663, 0.348], [161.4, 0.0, 0.877]], 0.5, 0.1, 7], [3, 0.033333, False]]]]
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 | [1, 0.1, False] | [2, 0.05, False] | Failed |
| case 1 | [1, 0.1, True] | [1, 0.1, True] | Passed |
| case 2 | [1, 0.1, False] | [2, 0.05, False] | Failed |
| case 3 | [1, 0.1, False] | [2, 0.05, False] | Failed |
| case 4 | [1, 0.016667, False] | [1, 0.016667, False] | Passed |
| case 5 | [1, 0.016667, False] | [1, 0.016667, False] | Passed |
| case 6 | [1, 0.05, False] | [1, 0.05, False] | Passed |
| case 7 | [1, 0.016667, False] | [1, 0.016667, False] | Passed |
SHA-256 / 44c15d0cd1488432f5a1e202c30149548a979170186b93272ab7f8c7ce4e22bd
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(springs, safety, dt_frame, max_sub):
hc = None
for k, im1, im2 in springs:
w = im1 + im2
if w == 0 or k <= 0:
continue
h = safety * 2.0 / math.sqrt(k * w)
if hc is None:
hc = h
if hc is None:
return [1, round(dt_frame, 6), False]
n = math.ceil(dt_frame / hc - 1e-12)
clamped = n > max_sub
n = min(max(n, 1), max_sub)
return [n, round(dt_frame / n, 6), clamped]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[[[274.6, 1.615, 1.293], [279.2, 0.0, 1.072], [36.0, 1.606, 0.0]], 0.8, 0.1, 8], [2, 0.05, False]], [[[[176.6, 0.318, 1.727]], 0.9, 0.1, 1], [1, 0.1, True]], [[[[217.3, 0.0, 0.272], [226.4, 1.256, 1.506], [86.4, 1.936, 1.121]], 0.8, 0.1, 7], [2, 0.05, False]], [[[[51.4, 0.26, 0.0], [194.4, 1.517, 0.0]], 0.5, 0.1, 5], [2, 0.05, False]], [[[[148.8, 1.386, 0.442]], 0.8, 0.016666666666666666, 4], [1, 0.016667, False]], [[[[260.1, 0.0, 1.95]], 0.9, 0.016666666666666666, 1], [1, 0.016667, False]], [[[[299.0, 0.587, 0.527], [101.7, 1.086, 0.0], [96.2, 1.589, 0.676]], 0.9, 0.05, 9], [1, 0.05, False]], [[[[140.9, 1.164, 1.839], [288.3, 1.884, 0.0]], 0.9, 0.016666666666666666, 5], [1, 0.016667, False]]], [[[[[252.4, 0.823, 0.921], [0.0, 0.0, 1.281], [144.4, 0.0, 0.0], [399.0, 0.924, 1.926]], 0.9, 0.03333333333333333, 12], [1, 0.033333, False]], [[[[225.1, 0.0, 1.023]], 0.5, 0.016666666666666666, 4], [1, 0.016667, False]], [[[[239.0, 0.421, 0.398], [322.8, 0.0, 1.917], [189.8, 0.0, 0.0], [229.0, 1.496, 0.0]], 0.5, 0.05, 9], [2, 0.025, False]], [[[[297.9, 0.714, 1.84], [274.1, 0.797, 0.0], [150.2, 0.931, 1.101], [84.3, 0.7, 1.504]], 0.9, 0.016666666666666666, 12], [1, 0.016667, False]], [[[[331.5, 0.435, 0.0], [309.7, 1.309, 1.986]], 0.8, 0.1, 9], [2, 0.05, False]], [[[[208.5, 1.926, 0.106]], 0.9, 0.1, 11], [2, 0.05, False]], [[[[176.2, 1.797, 1.825], [298.2, 0.526, 0.891], [118.3, 0.227, 0.0]], 0.5, 0.1, 2], [2, 0.05, True]], [[[[288.5, 0.0, 0.0], [135.2, 0.764, 0.24], [389.1, 0.45, 1.145]], 0.5, 0.05, 6], [2, 0.025, False]]], [[[[[312.6, 0.0, 1.453]], 0.5, 0.1, 12], [3, 0.033333, False]], [[[[160.0, 1.174, 1.024], [222.4, 0.746, 0.568], [234.1, 0.0, 0.0], [305.9, 0.261, 0.0]], 0.8, 0.1, 5], [2, 0.05, False]], [[[[219.4, 0.47, 0.357], [244.7, 1.869, 0.0], [206.2, 0.734, 1.4]], 0.9, 0.1, 8], [2, 0.05, False]], [[[[8.4, 0.0, 1.944]], 0.9, 0.016666666666666666, 2], [1, 0.016667, False]], [[[[187.2, 0.446, 0.0], [384.2, 0.164, 1.101]], 0.5, 0.1, 6], [3, 0.033333, False]], [[[[0.0, 0.0, 0.802], [39.7, 0.0, 0.859]], 0.5, 0.1, 8], [1, 0.1, False]], [[[[98.4, 0.155, 0.544], [243.2, 0.0, 0.932], [174.9, 0.0, 0.913], [326.4, 1.87, 1.935]], 0.8, 0.05, 8], [2, 0.025, False]], [[[[308.1, 0.0, 0.454], [396.0, 0.194, 1.062]], 0.5, 0.05, 10], [2, 0.025, False]]], [[[[[231.0, 0.0, 1.82], [25.6, 1.068, 0.0], [268.8, 1.477, 0.0]], 0.5, 0.05, 5], [2, 0.025, False]], [[[[112.1, 1.181, 0.0], [364.2, 0.0, 0.0], [122.5, 0.0, 1.265]], 0.5, 0.05, 5], [1, 0.05, False]], [[[[74.9, 1.534, 1.135]], 0.8, 0.016666666666666666, 12], [1, 0.016667, False]], [[[[30.9, 0.794, 0.198], [0.0, 0.658, 0.0], [398.0, 1.934, 0.424]], 0.8, 0.1, 12], [2, 0.05, False]], [[[[385.7, 1.862, 1.408], [57.2, 1.136, 0.0], [93.5, 0.0, 0.0]], 0.5, 0.05, 12], [2, 0.025, False]], [[[[12.1, 0.309, 1.274], [153.5, 0.738, 0.969]], 0.5, 0.1, 12], [2, 0.05, False]], [[[[112.1, 1.978, 0.662]], 0.9, 0.016666666666666666, 10], [1, 0.016667, False]], [[[[103.2, 0.656, 0.0], [364.0, 0.395, 1.113]], 0.8, 0.016666666666666666, 1], [1, 0.016667, False]]], [[[[[25.9, 0.416, 0.0], [156.4, 1.139, 0.483], [279.4, 0.175, 1.863], [0.0, 1.682, 0.782]], 0.9, 0.03333333333333333, 7], [1, 0.033333, False]], [[[[0.0, 1.7, 0.0], [0.0, 0.0, 1.054], [328.3, 0.57, 0.359], [398.1, 1.479, 0.689]], 0.9, 0.1, 12], [2, 0.05, False]], [[[[0.0, 0.0, 0.743], [153.1, 1.007, 0.97]], 0.5, 0.05, 6], [1, 0.05, False]], [[[[97.9, 0.752, 1.178], [382.4, 1.927, 1.693], [68.3, 0.0, 0.0]], 0.9, 0.1, 11], [3, 0.033333, False]], [[[[149.6, 1.802, 0.77], [102.2, 1.828, 0.436]], 0.5, 0.1, 7], [2, 0.05, False]], [[[[0.0, 1.613, 0.0], [46.8, 1.168, 1.601], [255.1, 0.0, 0.0], [397.8, 0.0, 0.649]], 0.8, 0.1, 1], [1, 0.1, True]], [[[[338.0, 0.517, 0.0], [288.8, 0.0, 1.978], [37.6, 1.094, 1.076]], 0.9, 0.05, 11], [1, 0.05, False]], [[[[333.7, 1.663, 0.348], [161.4, 0.0, 0.877]], 0.5, 0.1, 7], [3, 0.033333, False]]]]
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 | [2, 0.05, False] | [2, 0.05, False] | Passed |
| case 1 | [1, 0.1, True] | [1, 0.1, True] | Passed |
| case 2 | [1, 0.1, False] | [2, 0.05, False] | Failed |
| case 3 | [1, 0.1, False] | [2, 0.05, False] | Failed |
| case 4 | [1, 0.016667, False] | [1, 0.016667, False] | Passed |
| case 5 | [1, 0.016667, False] | [1, 0.016667, False] | Passed |
| case 6 | [1, 0.05, False] | [1, 0.05, False] | Passed |
| case 7 | [1, 0.016667, False] | [1, 0.016667, False] | Passed |
SHA-256 / 9e4efd5b474d5c95f79a74263ffbe3815e0aee4abdbded09e202074a515ef172
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(springs, safety, dt_frame, max_sub):
hc = None
for k, im1, im2 in springs:
w = im1 + im2
if w == 0 or k <= 0:
continue
h = safety * 2.0 / math.sqrt(k * w)
if hc is None or h < hc:
hc = h
if hc is None:
return [1, round(dt_frame, 6), False]
n = math.ceil(dt_frame / hc - 1e-12)
clamped = n > max_sub
n = min(max(n, 1), max_sub)
return [n, round(dt_frame / n, 6), clamped]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[[[274.6, 1.615, 1.293], [279.2, 0.0, 1.072], [36.0, 1.606, 0.0]], 0.8, 0.1, 8], [2, 0.05, False]], [[[[176.6, 0.318, 1.727]], 0.9, 0.1, 1], [1, 0.1, True]], [[[[217.3, 0.0, 0.272], [226.4, 1.256, 1.506], [86.4, 1.936, 1.121]], 0.8, 0.1, 7], [2, 0.05, False]], [[[[51.4, 0.26, 0.0], [194.4, 1.517, 0.0]], 0.5, 0.1, 5], [2, 0.05, False]], [[[[148.8, 1.386, 0.442]], 0.8, 0.016666666666666666, 4], [1, 0.016667, False]], [[[[260.1, 0.0, 1.95]], 0.9, 0.016666666666666666, 1], [1, 0.016667, False]], [[[[299.0, 0.587, 0.527], [101.7, 1.086, 0.0], [96.2, 1.589, 0.676]], 0.9, 0.05, 9], [1, 0.05, False]], [[[[140.9, 1.164, 1.839], [288.3, 1.884, 0.0]], 0.9, 0.016666666666666666, 5], [1, 0.016667, False]]], [[[[[252.4, 0.823, 0.921], [0.0, 0.0, 1.281], [144.4, 0.0, 0.0], [399.0, 0.924, 1.926]], 0.9, 0.03333333333333333, 12], [1, 0.033333, False]], [[[[225.1, 0.0, 1.023]], 0.5, 0.016666666666666666, 4], [1, 0.016667, False]], [[[[239.0, 0.421, 0.398], [322.8, 0.0, 1.917], [189.8, 0.0, 0.0], [229.0, 1.496, 0.0]], 0.5, 0.05, 9], [2, 0.025, False]], [[[[297.9, 0.714, 1.84], [274.1, 0.797, 0.0], [150.2, 0.931, 1.101], [84.3, 0.7, 1.504]], 0.9, 0.016666666666666666, 12], [1, 0.016667, False]], [[[[331.5, 0.435, 0.0], [309.7, 1.309, 1.986]], 0.8, 0.1, 9], [2, 0.05, False]], [[[[208.5, 1.926, 0.106]], 0.9, 0.1, 11], [2, 0.05, False]], [[[[176.2, 1.797, 1.825], [298.2, 0.526, 0.891], [118.3, 0.227, 0.0]], 0.5, 0.1, 2], [2, 0.05, True]], [[[[288.5, 0.0, 0.0], [135.2, 0.764, 0.24], [389.1, 0.45, 1.145]], 0.5, 0.05, 6], [2, 0.025, False]]], [[[[[312.6, 0.0, 1.453]], 0.5, 0.1, 12], [3, 0.033333, False]], [[[[160.0, 1.174, 1.024], [222.4, 0.746, 0.568], [234.1, 0.0, 0.0], [305.9, 0.261, 0.0]], 0.8, 0.1, 5], [2, 0.05, False]], [[[[219.4, 0.47, 0.357], [244.7, 1.869, 0.0], [206.2, 0.734, 1.4]], 0.9, 0.1, 8], [2, 0.05, False]], [[[[8.4, 0.0, 1.944]], 0.9, 0.016666666666666666, 2], [1, 0.016667, False]], [[[[187.2, 0.446, 0.0], [384.2, 0.164, 1.101]], 0.5, 0.1, 6], [3, 0.033333, False]], [[[[0.0, 0.0, 0.802], [39.7, 0.0, 0.859]], 0.5, 0.1, 8], [1, 0.1, False]], [[[[98.4, 0.155, 0.544], [243.2, 0.0, 0.932], [174.9, 0.0, 0.913], [326.4, 1.87, 1.935]], 0.8, 0.05, 8], [2, 0.025, False]], [[[[308.1, 0.0, 0.454], [396.0, 0.194, 1.062]], 0.5, 0.05, 10], [2, 0.025, False]]], [[[[[231.0, 0.0, 1.82], [25.6, 1.068, 0.0], [268.8, 1.477, 0.0]], 0.5, 0.05, 5], [2, 0.025, False]], [[[[112.1, 1.181, 0.0], [364.2, 0.0, 0.0], [122.5, 0.0, 1.265]], 0.5, 0.05, 5], [1, 0.05, False]], [[[[74.9, 1.534, 1.135]], 0.8, 0.016666666666666666, 12], [1, 0.016667, False]], [[[[30.9, 0.794, 0.198], [0.0, 0.658, 0.0], [398.0, 1.934, 0.424]], 0.8, 0.1, 12], [2, 0.05, False]], [[[[385.7, 1.862, 1.408], [57.2, 1.136, 0.0], [93.5, 0.0, 0.0]], 0.5, 0.05, 12], [2, 0.025, False]], [[[[12.1, 0.309, 1.274], [153.5, 0.738, 0.969]], 0.5, 0.1, 12], [2, 0.05, False]], [[[[112.1, 1.978, 0.662]], 0.9, 0.016666666666666666, 10], [1, 0.016667, False]], [[[[103.2, 0.656, 0.0], [364.0, 0.395, 1.113]], 0.8, 0.016666666666666666, 1], [1, 0.016667, False]]], [[[[[25.9, 0.416, 0.0], [156.4, 1.139, 0.483], [279.4, 0.175, 1.863], [0.0, 1.682, 0.782]], 0.9, 0.03333333333333333, 7], [1, 0.033333, False]], [[[[0.0, 1.7, 0.0], [0.0, 0.0, 1.054], [328.3, 0.57, 0.359], [398.1, 1.479, 0.689]], 0.9, 0.1, 12], [2, 0.05, False]], [[[[0.0, 0.0, 0.743], [153.1, 1.007, 0.97]], 0.5, 0.05, 6], [1, 0.05, False]], [[[[97.9, 0.752, 1.178], [382.4, 1.927, 1.693], [68.3, 0.0, 0.0]], 0.9, 0.1, 11], [3, 0.033333, False]], [[[[149.6, 1.802, 0.77], [102.2, 1.828, 0.436]], 0.5, 0.1, 7], [2, 0.05, False]], [[[[0.0, 1.613, 0.0], [46.8, 1.168, 1.601], [255.1, 0.0, 0.0], [397.8, 0.0, 0.649]], 0.8, 0.1, 1], [1, 0.1, True]], [[[[338.0, 0.517, 0.0], [288.8, 0.0, 1.978], [37.6, 1.094, 1.076]], 0.9, 0.05, 11], [1, 0.05, False]], [[[[333.7, 1.663, 0.348], [161.4, 0.0, 0.877]], 0.5, 0.1, 7], [3, 0.033333, False]]]]
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 | [2, 0.05, False] | [2, 0.05, False] | Passed |
| case 1 | [1, 0.1, True] | [1, 0.1, True] | Passed |
| case 2 | [2, 0.05, False] | [2, 0.05, False] | Passed |
| case 3 | [2, 0.05, False] | [2, 0.05, False] | Passed |
| case 4 | [1, 0.016667, False] | [1, 0.016667, False] | Passed |
| case 5 | [1, 0.016667, False] | [1, 0.016667, False] | Passed |
| case 6 | [1, 0.05, False] | [1, 0.05, False] | Passed |
| case 7 | [1, 0.016667, False] | [1, 0.016667, False] | Passed |
SHA-256 / 5fb6cbb1a6c251ae4c131661d97e242d2992d63bec2d84b76cb7c5e10b99b080
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:54.453885+00:00.
Case digest / 24d09f9e3796444dc1d2d2c23fc5bba762ddd3035cca6e2b16469108251602b0