FAILURE MAP
← Case archive

FA-87026 / Physics integrator stability / Open access

Damping term in the RK4 derivative adds energy · case 01

A damped, driven system grows without bound.

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

ROOT CAUSE

The derivative uses +c*v.

VERIFIED REPAIR

Viscous damping opposes velocity: -c*v.

Unsuccessful approach: Using -c*abs(v) pushes in one direction regardless of motion.

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 * 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.488, -0.59, 18.046, 0.065, 1.27, 1.284, 0.2, 3], [-0.348659, -0.553321, 0.6]], [[-0.109, -0.682, 16.643, 0.151, 1.208, 3.199, 0.05, 3], [-0.171504, -0.13078, 0.15]], [[0.206, 0.096, 17.287, 0.284, 1.767, 2.847, 0.2, 1], [0.188435, -0.265686, 0.2]], [[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.594, 0.724, 5.574, 1.414, 0.54, 2.544, 0.2, 5], [0.050911, -1.000788, 1.0]], [[0.882, 0.468, 0.596, 1.065, 0.599, 2.931, 0.2, 6], [0.969734, -0.430672, 1.2]], [[0.46, -0.102, 18.559, 1.381, 1.125, 3.81, 0.05, 6], [0.182226, -1.424067, 0.3]]], [[[0.35, 0.024, 2.459, 0.489, 1.678, 3.184, 0.2, 2], [0.401172, 0.137673, 0.4]], [[-0.481, 0.53, 14.853, 0.266, 1.141, 1.43, 0.2, 5], [0.329344, -1.698979, 1.0]], [[-0.015, -0.728, 3.619, 0.305, 1.759, 0.971, 0.05, 5], [-0.129743, -0.181737, 0.25]], [[0.893, -0.338, 8.218, 0.106, 1.088, 1.181, 0.05, 7], [0.446933, -1.988356, 0.35]], [[0.306, -0.723, 3.65, 0.703, 0.392, 3.569, 0.05, 8], [0.02265, -0.651232, 0.4]], [[-0.032, 0.808, 18.227, 0.749, 0.437, 3.703, 0.1, 1], [0.04836, 0.775101, 0.1]], [[-0.926, 0.952, 5.429, 0.55, 1.365, 4.948, 0.2, 1], [-0.633361, 1.884933, 0.2]], [[-0.492, -0.144, 14.57, 1.424, 1.521, 1.605, 0.05, 3], [-0.421761, 1.012157, 0.15]]], [[[-0.074, -0.116, 3.028, 1.181, 1.104, 3.696, 0.1, 7], [0.009692, 0.027829, 0.7]], [[-0.394, 0.849, 18.783, 1.27, 1.837, 1.788, 0.1, 10], [0.047492, -1.406422, 1.0]], [[0.156, -0.808, 12.089, 0.635, 0.926, 3.013, 0.05, 7], [-0.092465, -0.474045, 0.35]], [[-0.571, 0.019, 10.668, 1.333, 0.813, 4.88, 0.1, 10], [0.238859, -0.217571, 1.0]], [[-0.336, -0.209, 18.772, 1.161, 1.672, 0.598, 0.1, 1], [-0.317345, 0.561515, 0.1]], [[0.175, -0.704, 15.599, 0.073, 1.327, 4.931, 0.1, 1], [0.099641, -0.786337, 0.1]], [[-0.346, -0.2, 8.452, 1.354, 0.585, 4.532, 0.1, 9], [0.091625, 0.239009, 0.9]], [[-0.72, 0.798, 11.51, 0.327, 1.73, 2.962, 0.2, 6], [0.044463, -2.814758, 1.2]]], [[[-0.484, -0.908, 18.372, 0.481, 1.964, 2.315, 0.2, 2], [-0.051507, 2.343495, 0.4]], [[-0.198, -0.028, 4.048, 0.079, 1.642, 1.588, 0.2, 8], [0.361524, -1.100738, 1.6]], [[0.28, 0.052, 4.066, 1.361, 0.882, 2.789, 0.2, 1], [0.283811, -0.015909, 0.2]], [[0.523, 0.745, 19.459, 1.381, 1.891, 2.276, 0.2, 8], [0.024331, -0.114203, 1.6]], [[-0.772, 0.752, 2.823, 0.497, 1.621, 2.92, 0.1, 6], [0.065151, 1.550767, 0.6]], [[0.803, -0.478, 17.921, 1.302, 0.586, 1.694, 0.05, 8], [-0.025126, -2.449079, 0.4]], [[0.962, 0.482, 3.289, 0.436, 1.4, 4.793, 0.05, 12], [0.785086, -1.262878, 0.6]], [[-0.744, -0.9, 18.945, 0.957, 1.391, 2.184, 0.05, 5], [-0.502149, 2.490953, 0.25]]], [[[-0.341, 0.921, 14.484, 0.78, 0.993, 4.954, 0.1, 11], [-0.092121, -0.961694, 1.1]], [[0.066, 0.743, 19.62, 0.364, 1.169, 2.555, 0.05, 9], [0.188006, -0.41408, 0.45]], [[0.624, -0.28, 15.071, 1.265, 1.479, 0.882, 0.05, 7], [0.2044, -1.636348, 0.35]], [[-0.527, 0.382, 9.694, 0.75, 1.418, 3.954, 0.05, 3], [-0.405723, 1.184269, 0.15]], [[-0.365, 0.422, 2.804, 0.62, 1.65, 2.687, 0.2, 6], [0.356334, -0.39711, 1.2]], [[0.48, 0.991, 13.504, 0.938, 1.754, 1.99, 0.2, 8], [-0.112907, 0.598276, 1.6]], [[0.96, 0.368, 6.136, 0.868, 0.713, 4.277, 0.1, 13], [-0.632372, -0.226167, 1.3]], [[-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 fixtureActualExpectedOutcome
case 0[-0.368597, -0.5779, 0.6][-0.348659, -0.553321, 0.6]Failed
case 1[-0.173186, -0.148364, 0.15][-0.171504, -0.13078, 0.15]Failed
case 2[0.188015, -0.275865, 0.2][0.188435, -0.265686, 0.2]Failed
case 3[1.160775, 0.951595, 0.6][1.117188, 0.809138, 0.6]Failed
case 4[0.554403, -0.079726, 0.2][0.539279, -0.178827, 0.2]Failed
case 5[-0.408205, -2.951085, 1.0][0.050911, -1.000788, 1.0]Failed
case 6[1.555559, 0.22365, 1.2][0.969734, -0.430672, 1.2]Failed
case 7[0.093525, -2.177727, 0.3][0.182226, -1.424067, 0.3]Failed

SHA-256 / 5171b90c0ff1f33ff371e179bfcdb1e1d3be2bba6d1bdfb0ba23a3c1cc5855c9

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 * abs(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.488, -0.59, 18.046, 0.065, 1.27, 1.284, 0.2, 3], [-0.348659, -0.553321, 0.6]], [[-0.109, -0.682, 16.643, 0.151, 1.208, 3.199, 0.05, 3], [-0.171504, -0.13078, 0.15]], [[0.206, 0.096, 17.287, 0.284, 1.767, 2.847, 0.2, 1], [0.188435, -0.265686, 0.2]], [[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.594, 0.724, 5.574, 1.414, 0.54, 2.544, 0.2, 5], [0.050911, -1.000788, 1.0]], [[0.882, 0.468, 0.596, 1.065, 0.599, 2.931, 0.2, 6], [0.969734, -0.430672, 1.2]], [[0.46, -0.102, 18.559, 1.381, 1.125, 3.81, 0.05, 6], [0.182226, -1.424067, 0.3]]], [[[0.35, 0.024, 2.459, 0.489, 1.678, 3.184, 0.2, 2], [0.401172, 0.137673, 0.4]], [[-0.481, 0.53, 14.853, 0.266, 1.141, 1.43, 0.2, 5], [0.329344, -1.698979, 1.0]], [[-0.015, -0.728, 3.619, 0.305, 1.759, 0.971, 0.05, 5], [-0.129743, -0.181737, 0.25]], [[0.893, -0.338, 8.218, 0.106, 1.088, 1.181, 0.05, 7], [0.446933, -1.988356, 0.35]], [[0.306, -0.723, 3.65, 0.703, 0.392, 3.569, 0.05, 8], [0.02265, -0.651232, 0.4]], [[-0.032, 0.808, 18.227, 0.749, 0.437, 3.703, 0.1, 1], [0.04836, 0.775101, 0.1]], [[-0.926, 0.952, 5.429, 0.55, 1.365, 4.948, 0.2, 1], [-0.633361, 1.884933, 0.2]], [[-0.492, -0.144, 14.57, 1.424, 1.521, 1.605, 0.05, 3], [-0.421761, 1.012157, 0.15]]], [[[-0.074, -0.116, 3.028, 1.181, 1.104, 3.696, 0.1, 7], [0.009692, 0.027829, 0.7]], [[-0.394, 0.849, 18.783, 1.27, 1.837, 1.788, 0.1, 10], [0.047492, -1.406422, 1.0]], [[0.156, -0.808, 12.089, 0.635, 0.926, 3.013, 0.05, 7], [-0.092465, -0.474045, 0.35]], [[-0.571, 0.019, 10.668, 1.333, 0.813, 4.88, 0.1, 10], [0.238859, -0.217571, 1.0]], [[-0.336, -0.209, 18.772, 1.161, 1.672, 0.598, 0.1, 1], [-0.317345, 0.561515, 0.1]], [[0.175, -0.704, 15.599, 0.073, 1.327, 4.931, 0.1, 1], [0.099641, -0.786337, 0.1]], [[-0.346, -0.2, 8.452, 1.354, 0.585, 4.532, 0.1, 9], [0.091625, 0.239009, 0.9]], [[-0.72, 0.798, 11.51, 0.327, 1.73, 2.962, 0.2, 6], [0.044463, -2.814758, 1.2]]], [[[-0.484, -0.908, 18.372, 0.481, 1.964, 2.315, 0.2, 2], [-0.051507, 2.343495, 0.4]], [[-0.198, -0.028, 4.048, 0.079, 1.642, 1.588, 0.2, 8], [0.361524, -1.100738, 1.6]], [[0.28, 0.052, 4.066, 1.361, 0.882, 2.789, 0.2, 1], [0.283811, -0.015909, 0.2]], [[0.523, 0.745, 19.459, 1.381, 1.891, 2.276, 0.2, 8], [0.024331, -0.114203, 1.6]], [[-0.772, 0.752, 2.823, 0.497, 1.621, 2.92, 0.1, 6], [0.065151, 1.550767, 0.6]], [[0.803, -0.478, 17.921, 1.302, 0.586, 1.694, 0.05, 8], [-0.025126, -2.449079, 0.4]], [[0.962, 0.482, 3.289, 0.436, 1.4, 4.793, 0.05, 12], [0.785086, -1.262878, 0.6]], [[-0.744, -0.9, 18.945, 0.957, 1.391, 2.184, 0.05, 5], [-0.502149, 2.490953, 0.25]]], [[[-0.341, 0.921, 14.484, 0.78, 0.993, 4.954, 0.1, 11], [-0.092121, -0.961694, 1.1]], [[0.066, 0.743, 19.62, 0.364, 1.169, 2.555, 0.05, 9], [0.188006, -0.41408, 0.45]], [[0.624, -0.28, 15.071, 1.265, 1.479, 0.882, 0.05, 7], [0.2044, -1.636348, 0.35]], [[-0.527, 0.382, 9.694, 0.75, 1.418, 3.954, 0.05, 3], [-0.405723, 1.184269, 0.15]], [[-0.365, 0.422, 2.804, 0.62, 1.65, 2.687, 0.2, 6], [0.356334, -0.39711, 1.2]], [[0.48, 0.991, 13.504, 0.938, 1.754, 1.99, 0.2, 8], [-0.112907, 0.598276, 1.6]], [[0.96, 0.368, 6.136, 0.868, 0.713, 4.277, 0.1, 13], [-0.632372, -0.226167, 1.3]], [[-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 fixtureActualExpectedOutcome
case 0[-0.368597, -0.5779, 0.6][-0.348659, -0.553321, 0.6]Failed
case 1[-0.173186, -0.148364, 0.15][-0.171504, -0.13078, 0.15]Failed
case 2[0.187703, -0.277124, 0.2][0.188435, -0.265686, 0.2]Failed
case 3[1.117188, 0.809138, 0.6][1.117188, 0.809138, 0.6]Passed
case 4[0.539279, -0.186458, 0.2][0.539279, -0.178827, 0.2]Failed
case 5[-0.557779, -2.858439, 1.0][0.050911, -1.000788, 1.0]Failed
case 6[0.928217, -0.701467, 1.2][0.969734, -0.430672, 1.2]Failed
case 7[0.093525, -2.177727, 0.3][0.182226, -1.424067, 0.3]Failed

SHA-256 / 95ba6fd7134a1b1fa1864c4d240667af91b80193d3475e0b58b9d7c93f181b11

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.488, -0.59, 18.046, 0.065, 1.27, 1.284, 0.2, 3], [-0.348659, -0.553321, 0.6]], [[-0.109, -0.682, 16.643, 0.151, 1.208, 3.199, 0.05, 3], [-0.171504, -0.13078, 0.15]], [[0.206, 0.096, 17.287, 0.284, 1.767, 2.847, 0.2, 1], [0.188435, -0.265686, 0.2]], [[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.594, 0.724, 5.574, 1.414, 0.54, 2.544, 0.2, 5], [0.050911, -1.000788, 1.0]], [[0.882, 0.468, 0.596, 1.065, 0.599, 2.931, 0.2, 6], [0.969734, -0.430672, 1.2]], [[0.46, -0.102, 18.559, 1.381, 1.125, 3.81, 0.05, 6], [0.182226, -1.424067, 0.3]]], [[[0.35, 0.024, 2.459, 0.489, 1.678, 3.184, 0.2, 2], [0.401172, 0.137673, 0.4]], [[-0.481, 0.53, 14.853, 0.266, 1.141, 1.43, 0.2, 5], [0.329344, -1.698979, 1.0]], [[-0.015, -0.728, 3.619, 0.305, 1.759, 0.971, 0.05, 5], [-0.129743, -0.181737, 0.25]], [[0.893, -0.338, 8.218, 0.106, 1.088, 1.181, 0.05, 7], [0.446933, -1.988356, 0.35]], [[0.306, -0.723, 3.65, 0.703, 0.392, 3.569, 0.05, 8], [0.02265, -0.651232, 0.4]], [[-0.032, 0.808, 18.227, 0.749, 0.437, 3.703, 0.1, 1], [0.04836, 0.775101, 0.1]], [[-0.926, 0.952, 5.429, 0.55, 1.365, 4.948, 0.2, 1], [-0.633361, 1.884933, 0.2]], [[-0.492, -0.144, 14.57, 1.424, 1.521, 1.605, 0.05, 3], [-0.421761, 1.012157, 0.15]]], [[[-0.074, -0.116, 3.028, 1.181, 1.104, 3.696, 0.1, 7], [0.009692, 0.027829, 0.7]], [[-0.394, 0.849, 18.783, 1.27, 1.837, 1.788, 0.1, 10], [0.047492, -1.406422, 1.0]], [[0.156, -0.808, 12.089, 0.635, 0.926, 3.013, 0.05, 7], [-0.092465, -0.474045, 0.35]], [[-0.571, 0.019, 10.668, 1.333, 0.813, 4.88, 0.1, 10], [0.238859, -0.217571, 1.0]], [[-0.336, -0.209, 18.772, 1.161, 1.672, 0.598, 0.1, 1], [-0.317345, 0.561515, 0.1]], [[0.175, -0.704, 15.599, 0.073, 1.327, 4.931, 0.1, 1], [0.099641, -0.786337, 0.1]], [[-0.346, -0.2, 8.452, 1.354, 0.585, 4.532, 0.1, 9], [0.091625, 0.239009, 0.9]], [[-0.72, 0.798, 11.51, 0.327, 1.73, 2.962, 0.2, 6], [0.044463, -2.814758, 1.2]]], [[[-0.484, -0.908, 18.372, 0.481, 1.964, 2.315, 0.2, 2], [-0.051507, 2.343495, 0.4]], [[-0.198, -0.028, 4.048, 0.079, 1.642, 1.588, 0.2, 8], [0.361524, -1.100738, 1.6]], [[0.28, 0.052, 4.066, 1.361, 0.882, 2.789, 0.2, 1], [0.283811, -0.015909, 0.2]], [[0.523, 0.745, 19.459, 1.381, 1.891, 2.276, 0.2, 8], [0.024331, -0.114203, 1.6]], [[-0.772, 0.752, 2.823, 0.497, 1.621, 2.92, 0.1, 6], [0.065151, 1.550767, 0.6]], [[0.803, -0.478, 17.921, 1.302, 0.586, 1.694, 0.05, 8], [-0.025126, -2.449079, 0.4]], [[0.962, 0.482, 3.289, 0.436, 1.4, 4.793, 0.05, 12], [0.785086, -1.262878, 0.6]], [[-0.744, -0.9, 18.945, 0.957, 1.391, 2.184, 0.05, 5], [-0.502149, 2.490953, 0.25]]], [[[-0.341, 0.921, 14.484, 0.78, 0.993, 4.954, 0.1, 11], [-0.092121, -0.961694, 1.1]], [[0.066, 0.743, 19.62, 0.364, 1.169, 2.555, 0.05, 9], [0.188006, -0.41408, 0.45]], [[0.624, -0.28, 15.071, 1.265, 1.479, 0.882, 0.05, 7], [0.2044, -1.636348, 0.35]], [[-0.527, 0.382, 9.694, 0.75, 1.418, 3.954, 0.05, 3], [-0.405723, 1.184269, 0.15]], [[-0.365, 0.422, 2.804, 0.62, 1.65, 2.687, 0.2, 6], [0.356334, -0.39711, 1.2]], [[0.48, 0.991, 13.504, 0.938, 1.754, 1.99, 0.2, 8], [-0.112907, 0.598276, 1.6]], [[0.96, 0.368, 6.136, 0.868, 0.713, 4.277, 0.1, 13], [-0.632372, -0.226167, 1.3]], [[-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 fixtureActualExpectedOutcome
case 0[-0.348659, -0.553321, 0.6][-0.348659, -0.553321, 0.6]Passed
case 1[-0.171504, -0.13078, 0.15][-0.171504, -0.13078, 0.15]Passed
case 2[0.188435, -0.265686, 0.2][0.188435, -0.265686, 0.2]Passed
case 3[1.117188, 0.809138, 0.6][1.117188, 0.809138, 0.6]Passed
case 4[0.539279, -0.178827, 0.2][0.539279, -0.178827, 0.2]Passed
case 5[0.050911, -1.000788, 1.0][0.050911, -1.000788, 1.0]Passed
case 6[0.969734, -0.430672, 1.2][0.969734, -0.430672, 1.2]Passed
case 7[0.182226, -1.424067, 0.3][0.182226, -1.424067, 0.3]Passed

SHA-256 / 32690947905c25ff3cea2bb1774373b8fd7eb5d3704d6b2eebe4f752fb4c6cbc

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:55.055524+00:00.

Case digest / ae52bcf3dcf695a961b892b2c0546e8ec3bd7a2ec6e418dbb29814968a1d4bdf