FA-87006 / Physics integrator stability / Open access
RK4 third stage reuses the first-stage slope · case 01
The method degrades to second order and energy error grows with dt^2.
ROOT CAUSE
Stage three offsets the state with k1 instead of k2.
VERIFIED REPAIR
Stage three uses the stage-two slope at the half step.
Unsuccessful approach: A full-step offset with k2 overshoots the midpoint.
Case contract
solve(x0, v0, k, c, F, wf, dt, steps): unit mass x''=-k*x-c*v+F*cos(wf*t) with wf in rad/s, t starting at 0, integrated with classical RK4. Return [x, v, t] 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(x0, v0, k, c, F, wf, dt, steps):
def f(t, x, v):
return v, -k * x - c * v + F * math.cos(wf * t)
t = 0.0
x, v = x0, v0
for _ in range(steps):
k1x, k1v = f(t, x, v)
k2x, k2v = f(t + dt / 2, x + dt / 2 * k1x, v + dt / 2 * k1v)
k3x, k3v = f(t + dt / 2, x + dt / 2 * k1x, v + dt / 2 * k1v)
k4x, k4v = f(t + dt, x + dt * k3x, v + dt * k3v)
x = x + dt / 6 * (k1x + 2 * k2x + 2 * k3x + k4x)
v = v + dt / 6 * (k1v + 2 * k2v + 2 * k3v + k4v)
t = t + dt
return [round(x, 6), round(v, 6), round(t, 6)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[0.594, 0.724, 5.574, 1.414, 0.54, 2.544, 0.2, 5], [0.050911, -1.000788, 1.0]], [[-0.109, -0.682, 16.643, 0.151, 1.208, 3.199, 0.05, 3], [-0.171504, -0.13078, 0.15]], [[-0.645, -0.927, 5.903, 0.207, 1.514, 1.588, 0.1, 4], [-0.568498, 1.228043, 0.4]], [[-0.139, 0.949, 17.559, 1.301, 1.247, 3.451, 0.05, 3], [0.019347, 1.083815, 0.15]], [[0.459, 0.935, 0.513, 0.108, 1.916, 4.473, 0.2, 3], [1.117188, 0.809138, 0.6]], [[0.477, 0.804, 9.463, 0.795, 0.343, 4.866, 0.2, 1], [0.539279, -0.178827, 0.2]], [[-0.227, 0.276, 16.723, 1.386, 1.542, 0.923, 0.05, 4], [-0.091739, 0.96699, 0.2]], [[0.488, -0.59, 18.046, 0.065, 1.27, 1.284, 0.2, 3], [-0.348659, -0.553321, 0.6]]], [[[0.172, 0.062, 19.358, 1.2, 1.594, 1.527, 0.2, 8], [-0.035386, -0.171815, 1.6]], [[0.66, -0.415, 17.46, 1.046, 0.744, 4.773, 0.2, 5], [-0.269012, 1.388054, 1.0]], [[-0.541, -0.377, 16.521, 1.005, 0.304, 1.061, 0.05, 7], [-0.191246, 1.884299, 0.35]], [[0.631, 0.61, 11.708, 0.916, 0.873, 0.721, 0.2, 4], [-0.20642, -0.990871, 0.8]], [[-0.014, 0.128, 12.816, 0.848, 0.56, 4.952, 0.1, 6], [0.044569, -0.131567, 0.6]], [[-0.492, -0.144, 14.57, 1.424, 1.521, 1.605, 0.05, 3], [-0.421761, 1.012157, 0.15]], [[0.35, 0.024, 2.459, 0.489, 1.678, 3.184, 0.2, 2], [0.401172, 0.137673, 0.4]], [[-0.926, 0.952, 5.429, 0.55, 1.365, 4.948, 0.2, 1], [-0.633361, 1.884933, 0.2]]], [[[0.156, -0.808, 12.089, 0.635, 0.926, 3.013, 0.05, 7], [-0.092465, -0.474045, 0.35]], [[-0.911, 0.553, 12.655, 0.722, 0.381, 2.915, 0.1, 5], [0.227775, 2.570273, 0.5]], [[-0.226, -0.701, 16.947, 0.853, 0.897, 1.169, 0.1, 3], [-0.195897, 0.805228, 0.3]], [[0.525, -0.596, 15.898, 1.056, 0.284, 2.939, 0.05, 7], [0.027356, -1.707211, 0.35]], [[-0.571, 0.019, 10.668, 1.333, 0.813, 4.88, 0.1, 10], [0.238859, -0.217571, 1.0]], [[0.691, 0.017, 14.343, 1.226, 0.435, 1.417, 0.1, 8], [-0.368126, -0.281775, 0.8]], [[-0.937, -0.304, 11.202, 0.679, 0.335, 2.94, 0.2, 10], [-0.478219, 0.662422, 2.0]], [[-0.394, 0.849, 18.783, 1.27, 1.837, 1.788, 0.1, 10], [0.047492, -1.406422, 1.0]]], [[[-0.309, 0.574, 12.33, 0.475, 1.415, 3.541, 0.2, 6], [-0.164785, -1.352613, 1.2]], [[0.567, 0.622, 9.97, 0.157, 1.44, 3.493, 0.05, 12], [0.133328, -1.813702, 0.6]], [[-0.198, -0.028, 4.048, 0.079, 1.642, 1.588, 0.2, 8], [0.361524, -1.100738, 1.6]], [[0.969, 0.576, 13.488, 0.37, 0.269, 1.95, 0.05, 1], [0.981517, -0.07474, 0.05]], [[-0.772, 0.752, 2.823, 0.497, 1.621, 2.92, 0.1, 6], [0.065151, 1.550767, 0.6]], [[-0.778, 0.297, 11.945, 1.3, 0.526, 3.798, 0.05, 10], [0.054866, 1.909985, 0.5]], [[-0.484, -0.908, 18.372, 0.481, 1.964, 2.315, 0.2, 2], [-0.051507, 2.343495, 0.4]], [[0.694, -0.739, 4.023, 0.004, 1.55, 2.981, 0.05, 11], [0.150023, -1.196641, 0.55]]], [[[0.96, 0.368, 6.136, 0.868, 0.713, 4.277, 0.1, 13], [-0.632372, -0.226167, 1.3]], [[-0.789, -0.272, 3.161, 0.072, 0.574, 2.141, 0.2, 5], [0.127601, 1.403065, 1.0]], [[0.48, 0.991, 13.504, 0.938, 1.754, 1.99, 0.2, 8], [-0.112907, 0.598276, 1.6]], [[0.33, 0.887, 2.568, 0.104, 0.752, 1.169, 0.2, 4], [0.797375, 0.086132, 0.8]], [[-0.341, 0.921, 14.484, 0.78, 0.993, 4.954, 0.1, 11], [-0.092121, -0.961694, 1.1]], [[-0.416, -0.539, 19.016, 0.513, 0.89, 1.807, 0.2, 13], [0.006344, -0.983503, 2.6]], [[-0.496, -0.851, 15.128, 0.852, 1.807, 2.037, 0.2, 1], [-0.470568, 1.03059, 0.2]], [[-0.854, 0.097, 8.601, 0.582, 1.88, 2.113, 0.2, 9], [-0.696921, -1.634032, 1.8]]]]
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.037025, -0.973573, 1.0] | [0.050911, -1.000788, 1.0] | Failed |
| case 1 | [-0.17158, -0.128698, 0.15] | [-0.171504, -0.13078, 0.15] | Failed |
| case 2 | [-0.565939, 1.237092, 0.4] | [-0.568498, 1.228043, 0.4] | Failed |
| case 3 | [0.019975, 1.08293, 0.15] | [0.019347, 1.083815, 0.15] | Failed |
| case 4 | [1.129639, 0.806665, 0.6] | [1.117188, 0.809138, 0.6] | Failed |
| case 5 | [0.538811, -0.211439, 0.2] | [0.539279, -0.178827, 0.2] | Failed |
| case 6 | [-0.090964, 0.967437, 0.2] | [-0.091739, 0.96699, 0.2] | Failed |
| case 7 | [-0.393364, -0.309219, 0.6] | [-0.348659, -0.553321, 0.6] | Failed |
SHA-256 / 48f643b89f937c2ccc87a17a9259278f818ad865b655450eba72d3a775c86c48
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x0, v0, k, c, F, wf, dt, steps):
def f(t, x, v):
return v, -k * x - c * v + F * math.cos(wf * t)
t = 0.0
x, v = x0, v0
for _ in range(steps):
k1x, k1v = f(t, x, v)
k2x, k2v = f(t + dt / 2, x + dt / 2 * k1x, v + dt / 2 * k1v)
k3x, k3v = f(t + dt / 2, x + dt * k2x, v + dt * k2v)
k4x, k4v = f(t + dt, x + dt * k3x, v + dt * k3v)
x = x + dt / 6 * (k1x + 2 * k2x + 2 * k3x + k4x)
v = v + dt / 6 * (k1v + 2 * k2v + 2 * k3v + k4v)
t = t + dt
return [round(x, 6), round(v, 6), round(t, 6)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[0.594, 0.724, 5.574, 1.414, 0.54, 2.544, 0.2, 5], [0.050911, -1.000788, 1.0]], [[-0.109, -0.682, 16.643, 0.151, 1.208, 3.199, 0.05, 3], [-0.171504, -0.13078, 0.15]], [[-0.645, -0.927, 5.903, 0.207, 1.514, 1.588, 0.1, 4], [-0.568498, 1.228043, 0.4]], [[-0.139, 0.949, 17.559, 1.301, 1.247, 3.451, 0.05, 3], [0.019347, 1.083815, 0.15]], [[0.459, 0.935, 0.513, 0.108, 1.916, 4.473, 0.2, 3], [1.117188, 0.809138, 0.6]], [[0.477, 0.804, 9.463, 0.795, 0.343, 4.866, 0.2, 1], [0.539279, -0.178827, 0.2]], [[-0.227, 0.276, 16.723, 1.386, 1.542, 0.923, 0.05, 4], [-0.091739, 0.96699, 0.2]], [[0.488, -0.59, 18.046, 0.065, 1.27, 1.284, 0.2, 3], [-0.348659, -0.553321, 0.6]]], [[[0.172, 0.062, 19.358, 1.2, 1.594, 1.527, 0.2, 8], [-0.035386, -0.171815, 1.6]], [[0.66, -0.415, 17.46, 1.046, 0.744, 4.773, 0.2, 5], [-0.269012, 1.388054, 1.0]], [[-0.541, -0.377, 16.521, 1.005, 0.304, 1.061, 0.05, 7], [-0.191246, 1.884299, 0.35]], [[0.631, 0.61, 11.708, 0.916, 0.873, 0.721, 0.2, 4], [-0.20642, -0.990871, 0.8]], [[-0.014, 0.128, 12.816, 0.848, 0.56, 4.952, 0.1, 6], [0.044569, -0.131567, 0.6]], [[-0.492, -0.144, 14.57, 1.424, 1.521, 1.605, 0.05, 3], [-0.421761, 1.012157, 0.15]], [[0.35, 0.024, 2.459, 0.489, 1.678, 3.184, 0.2, 2], [0.401172, 0.137673, 0.4]], [[-0.926, 0.952, 5.429, 0.55, 1.365, 4.948, 0.2, 1], [-0.633361, 1.884933, 0.2]]], [[[0.156, -0.808, 12.089, 0.635, 0.926, 3.013, 0.05, 7], [-0.092465, -0.474045, 0.35]], [[-0.911, 0.553, 12.655, 0.722, 0.381, 2.915, 0.1, 5], [0.227775, 2.570273, 0.5]], [[-0.226, -0.701, 16.947, 0.853, 0.897, 1.169, 0.1, 3], [-0.195897, 0.805228, 0.3]], [[0.525, -0.596, 15.898, 1.056, 0.284, 2.939, 0.05, 7], [0.027356, -1.707211, 0.35]], [[-0.571, 0.019, 10.668, 1.333, 0.813, 4.88, 0.1, 10], [0.238859, -0.217571, 1.0]], [[0.691, 0.017, 14.343, 1.226, 0.435, 1.417, 0.1, 8], [-0.368126, -0.281775, 0.8]], [[-0.937, -0.304, 11.202, 0.679, 0.335, 2.94, 0.2, 10], [-0.478219, 0.662422, 2.0]], [[-0.394, 0.849, 18.783, 1.27, 1.837, 1.788, 0.1, 10], [0.047492, -1.406422, 1.0]]], [[[-0.309, 0.574, 12.33, 0.475, 1.415, 3.541, 0.2, 6], [-0.164785, -1.352613, 1.2]], [[0.567, 0.622, 9.97, 0.157, 1.44, 3.493, 0.05, 12], [0.133328, -1.813702, 0.6]], [[-0.198, -0.028, 4.048, 0.079, 1.642, 1.588, 0.2, 8], [0.361524, -1.100738, 1.6]], [[0.969, 0.576, 13.488, 0.37, 0.269, 1.95, 0.05, 1], [0.981517, -0.07474, 0.05]], [[-0.772, 0.752, 2.823, 0.497, 1.621, 2.92, 0.1, 6], [0.065151, 1.550767, 0.6]], [[-0.778, 0.297, 11.945, 1.3, 0.526, 3.798, 0.05, 10], [0.054866, 1.909985, 0.5]], [[-0.484, -0.908, 18.372, 0.481, 1.964, 2.315, 0.2, 2], [-0.051507, 2.343495, 0.4]], [[0.694, -0.739, 4.023, 0.004, 1.55, 2.981, 0.05, 11], [0.150023, -1.196641, 0.55]]], [[[0.96, 0.368, 6.136, 0.868, 0.713, 4.277, 0.1, 13], [-0.632372, -0.226167, 1.3]], [[-0.789, -0.272, 3.161, 0.072, 0.574, 2.141, 0.2, 5], [0.127601, 1.403065, 1.0]], [[0.48, 0.991, 13.504, 0.938, 1.754, 1.99, 0.2, 8], [-0.112907, 0.598276, 1.6]], [[0.33, 0.887, 2.568, 0.104, 0.752, 1.169, 0.2, 4], [0.797375, 0.086132, 0.8]], [[-0.341, 0.921, 14.484, 0.78, 0.993, 4.954, 0.1, 11], [-0.092121, -0.961694, 1.1]], [[-0.416, -0.539, 19.016, 0.513, 0.89, 1.807, 0.2, 13], [0.006344, -0.983503, 2.6]], [[-0.496, -0.851, 15.128, 0.852, 1.807, 2.037, 0.2, 1], [-0.470568, 1.03059, 0.2]], [[-0.854, 0.097, 8.601, 0.582, 1.88, 2.113, 0.2, 9], [-0.696921, -1.634032, 1.8]]]]
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.08011, -0.87773, 1.0] | [0.050911, -1.000788, 1.0] | Failed |
| case 1 | [-0.166443, -0.128877, 0.15] | [-0.171504, -0.13078, 0.15] | Failed |
| case 2 | [-0.538457, 1.172832, 0.4] | [-0.568498, 1.228043, 0.4] | Failed |
| case 3 | [0.018638, 1.060771, 0.15] | [0.019347, 1.083815, 0.15] | Failed |
| case 4 | [1.108865, 0.797284, 0.6] | [1.117188, 0.809138, 0.6] | Failed |
| case 5 | [0.505157, -0.139094, 0.2] | [0.539279, -0.178827, 0.2] | Failed |
| case 6 | [-0.088858, 0.936028, 0.2] | [-0.091739, 0.96699, 0.2] | Failed |
| case 7 | [-0.198924, -0.345424, 0.6] | [-0.348659, -0.553321, 0.6] | Failed |
SHA-256 / 58de9e61e56223c7aacd9aee1c55c0850624b61a9593dfdfee617a6c1861b513
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x0, v0, k, c, F, wf, dt, steps):
def f(t, x, v):
return v, -k * x - c * v + F * math.cos(wf * t)
t = 0.0
x, v = x0, v0
for _ in range(steps):
k1x, k1v = f(t, x, v)
k2x, k2v = f(t + dt / 2, x + dt / 2 * k1x, v + dt / 2 * k1v)
k3x, k3v = f(t + dt / 2, x + dt / 2 * k2x, v + dt / 2 * k2v)
k4x, k4v = f(t + dt, x + dt * k3x, v + dt * k3v)
x = x + dt / 6 * (k1x + 2 * k2x + 2 * k3x + k4x)
v = v + dt / 6 * (k1v + 2 * k2v + 2 * k3v + k4v)
t = t + dt
return [round(x, 6), round(v, 6), round(t, 6)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[0.594, 0.724, 5.574, 1.414, 0.54, 2.544, 0.2, 5], [0.050911, -1.000788, 1.0]], [[-0.109, -0.682, 16.643, 0.151, 1.208, 3.199, 0.05, 3], [-0.171504, -0.13078, 0.15]], [[-0.645, -0.927, 5.903, 0.207, 1.514, 1.588, 0.1, 4], [-0.568498, 1.228043, 0.4]], [[-0.139, 0.949, 17.559, 1.301, 1.247, 3.451, 0.05, 3], [0.019347, 1.083815, 0.15]], [[0.459, 0.935, 0.513, 0.108, 1.916, 4.473, 0.2, 3], [1.117188, 0.809138, 0.6]], [[0.477, 0.804, 9.463, 0.795, 0.343, 4.866, 0.2, 1], [0.539279, -0.178827, 0.2]], [[-0.227, 0.276, 16.723, 1.386, 1.542, 0.923, 0.05, 4], [-0.091739, 0.96699, 0.2]], [[0.488, -0.59, 18.046, 0.065, 1.27, 1.284, 0.2, 3], [-0.348659, -0.553321, 0.6]]], [[[0.172, 0.062, 19.358, 1.2, 1.594, 1.527, 0.2, 8], [-0.035386, -0.171815, 1.6]], [[0.66, -0.415, 17.46, 1.046, 0.744, 4.773, 0.2, 5], [-0.269012, 1.388054, 1.0]], [[-0.541, -0.377, 16.521, 1.005, 0.304, 1.061, 0.05, 7], [-0.191246, 1.884299, 0.35]], [[0.631, 0.61, 11.708, 0.916, 0.873, 0.721, 0.2, 4], [-0.20642, -0.990871, 0.8]], [[-0.014, 0.128, 12.816, 0.848, 0.56, 4.952, 0.1, 6], [0.044569, -0.131567, 0.6]], [[-0.492, -0.144, 14.57, 1.424, 1.521, 1.605, 0.05, 3], [-0.421761, 1.012157, 0.15]], [[0.35, 0.024, 2.459, 0.489, 1.678, 3.184, 0.2, 2], [0.401172, 0.137673, 0.4]], [[-0.926, 0.952, 5.429, 0.55, 1.365, 4.948, 0.2, 1], [-0.633361, 1.884933, 0.2]]], [[[0.156, -0.808, 12.089, 0.635, 0.926, 3.013, 0.05, 7], [-0.092465, -0.474045, 0.35]], [[-0.911, 0.553, 12.655, 0.722, 0.381, 2.915, 0.1, 5], [0.227775, 2.570273, 0.5]], [[-0.226, -0.701, 16.947, 0.853, 0.897, 1.169, 0.1, 3], [-0.195897, 0.805228, 0.3]], [[0.525, -0.596, 15.898, 1.056, 0.284, 2.939, 0.05, 7], [0.027356, -1.707211, 0.35]], [[-0.571, 0.019, 10.668, 1.333, 0.813, 4.88, 0.1, 10], [0.238859, -0.217571, 1.0]], [[0.691, 0.017, 14.343, 1.226, 0.435, 1.417, 0.1, 8], [-0.368126, -0.281775, 0.8]], [[-0.937, -0.304, 11.202, 0.679, 0.335, 2.94, 0.2, 10], [-0.478219, 0.662422, 2.0]], [[-0.394, 0.849, 18.783, 1.27, 1.837, 1.788, 0.1, 10], [0.047492, -1.406422, 1.0]]], [[[-0.309, 0.574, 12.33, 0.475, 1.415, 3.541, 0.2, 6], [-0.164785, -1.352613, 1.2]], [[0.567, 0.622, 9.97, 0.157, 1.44, 3.493, 0.05, 12], [0.133328, -1.813702, 0.6]], [[-0.198, -0.028, 4.048, 0.079, 1.642, 1.588, 0.2, 8], [0.361524, -1.100738, 1.6]], [[0.969, 0.576, 13.488, 0.37, 0.269, 1.95, 0.05, 1], [0.981517, -0.07474, 0.05]], [[-0.772, 0.752, 2.823, 0.497, 1.621, 2.92, 0.1, 6], [0.065151, 1.550767, 0.6]], [[-0.778, 0.297, 11.945, 1.3, 0.526, 3.798, 0.05, 10], [0.054866, 1.909985, 0.5]], [[-0.484, -0.908, 18.372, 0.481, 1.964, 2.315, 0.2, 2], [-0.051507, 2.343495, 0.4]], [[0.694, -0.739, 4.023, 0.004, 1.55, 2.981, 0.05, 11], [0.150023, -1.196641, 0.55]]], [[[0.96, 0.368, 6.136, 0.868, 0.713, 4.277, 0.1, 13], [-0.632372, -0.226167, 1.3]], [[-0.789, -0.272, 3.161, 0.072, 0.574, 2.141, 0.2, 5], [0.127601, 1.403065, 1.0]], [[0.48, 0.991, 13.504, 0.938, 1.754, 1.99, 0.2, 8], [-0.112907, 0.598276, 1.6]], [[0.33, 0.887, 2.568, 0.104, 0.752, 1.169, 0.2, 4], [0.797375, 0.086132, 0.8]], [[-0.341, 0.921, 14.484, 0.78, 0.993, 4.954, 0.1, 11], [-0.092121, -0.961694, 1.1]], [[-0.416, -0.539, 19.016, 0.513, 0.89, 1.807, 0.2, 13], [0.006344, -0.983503, 2.6]], [[-0.496, -0.851, 15.128, 0.852, 1.807, 2.037, 0.2, 1], [-0.470568, 1.03059, 0.2]], [[-0.854, 0.097, 8.601, 0.582, 1.88, 2.113, 0.2, 9], [-0.696921, -1.634032, 1.8]]]]
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.050911, -1.000788, 1.0] | [0.050911, -1.000788, 1.0] | Passed |
| case 1 | [-0.171504, -0.13078, 0.15] | [-0.171504, -0.13078, 0.15] | Passed |
| case 2 | [-0.568498, 1.228043, 0.4] | [-0.568498, 1.228043, 0.4] | Passed |
| case 3 | [0.019347, 1.083815, 0.15] | [0.019347, 1.083815, 0.15] | Passed |
| case 4 | [1.117188, 0.809138, 0.6] | [1.117188, 0.809138, 0.6] | Passed |
| case 5 | [0.539279, -0.178827, 0.2] | [0.539279, -0.178827, 0.2] | Passed |
| case 6 | [-0.091739, 0.96699, 0.2] | [-0.091739, 0.96699, 0.2] | Passed |
| case 7 | [-0.348659, -0.553321, 0.6] | [-0.348659, -0.553321, 0.6] | Passed |
SHA-256 / 07c568a923cf7dd842b4eaa4d8d4a6c69c0a742af2b9686ed6f0ef7e14de3502
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.724064+00:00.
Case digest / 2b5af534daef834eb33ad692fe51259a7fe3e99b0dbe1b6d025d71a51351132a