FAILURE MAP
← Case archive

FA-86976 / Physics integrator stability / Open access

Accumulator adds unclamped frame deltas · case 01

A debugger pause produces a burst of dropped time and a huge catch-up.

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

ROOT CAUSE

The raw delta is added without the max_frame clamp.

VERIFIED REPAIR

Clamp each delta to max_frame before accumulating.

Unsuccessful approach: Clamping to max_frame*max_steps still admits oversized hitches.

Case contract

solve(frames, dt, max_frame, max_steps): game loop accumulator. Each frame delta is clamped to max_frame and added; run steps while acc >= dt up to max_steps; if a full dt still remains, whole multiples of dt are dropped (spiral-of-death guard). Return [steps per frame, acc/dt after last frame, dropped time].

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(frames, dt, max_frame, max_steps):
    acc = 0.0
    dropped = 0.0
    steps = []
    for delta in frames:
        acc += delta
        n = 0
        while acc >= dt and n < max_steps:
            acc -= dt
            n += 1
        if acc >= dt:
            keep = acc % dt
            dropped += acc - keep
            acc = keep
        steps.append(n)
    return [steps, acc / dt, dropped]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[[0.015625], 0.015625, 0.25, 2], [[1], 0.0, 0.0]], [[[0.0, 0.046875, 0.0, 0.125, 0.25, 0.625], 0.015625, 0.125, 1], [[0, 1, 0, 1, 1, 1], 0.0, 0.359375]], [[[0.0], 0.015625, 0.25, 2], [[0], 0.0, 0.0]], [[[0.0625, 0.0, 0.25, 0.125, 0.015625, 0.125], 0.0625, 0.125, 5], [[1, 0, 2, 2, 0, 2], 0.25, 0.0]], [[[0.25, 0.078125, 0.625, 0.015625, 0.046875, 0.0625], 0.0625, 0.125, 3], [[2, 1, 2, 0, 1, 1], 0.25, 0.0]], [[[0.03125, 0.25, 0.015625, 0.625, 0.015625, 0.015625], 0.015625, 0.125, 3], [[2, 3, 1, 3, 1, 1], 0.0, 0.15625]], [[[0.125, 0.25, 0.0, 0.046875, 0.046875, 0.078125], 0.03125, 0.25, 4], [[4, 4, 0, 1, 2, 2], 0.5, 0.125]], [[[0.25, 0.015625, 0.03125, 0.125, 0.046875, 0.25], 0.03125, 0.125, 5], [[4, 0, 1, 4, 2, 4], 0.0, 0.0]]], [[[[0.015625], 0.015625, 0.25, 2], [[1], 0.0, 0.0]], [[[0.0, 0.046875, 0.125, 0.0], 0.015625, 0.25, 5], [[0, 3, 5, 0], 0.0, 0.046875]], [[[0.625], 0.03125, 0.125, 2], [[2], 0.0, 0.0625]], [[[0.125, 0.25, 0.25], 0.03125, 0.125, 3], [[3, 3, 3], 0.0, 0.09375]], [[[0.125, 0.046875, 0.625, 0.0, 0.0, 0.125], 0.03125, 0.25, 5], [[4, 1, 5, 0, 0, 4], 0.5, 0.09375]], [[[0.0], 0.015625, 0.25, 2], [[0], 0.0, 0.0]], [[[0.015625, 0.0, 0.078125, 0.03125, 0.25], 0.015625, 0.125, 2], [[1, 0, 2, 2, 2], 0.0, 0.140625]], [[[0.25, 0.03125], 0.015625, 0.125, 3], [[3, 2], 0.0, 0.078125]]], [[[[0.125, 0.078125], 0.015625, 0.25, 4], [[4, 4], 0.0, 0.078125]], [[[0.078125, 0.625, 0.125, 0.25, 0.0, 0.25], 0.015625, 0.25, 5], [[5, 5, 5, 5, 0, 5], 0.0, 0.5625]], [[[0.25], 0.03125, 0.125, 2], [[2], 0.0, 0.0625]], [[[0.03125, 0.625, 0.046875, 0.125, 0.25], 0.0625, 0.125, 4], [[0, 2, 1, 2, 2], 0.25, 0.0]], [[[0.015625], 0.015625, 0.25, 2], [[1], 0.0, 0.0]], [[[0.0], 0.015625, 0.25, 2], [[0], 0.0, 0.0]], [[[0.0625, 0.078125, 0.25, 0.0625, 0.015625, 0.625], 0.015625, 0.125, 5], [[4, 5, 5, 4, 1, 5], 0.0, 0.09375]], [[[0.0625, 0.046875, 0.078125, 0.078125, 0.625], 0.03125, 0.25, 5], [[2, 1, 3, 2, 5], 0.5, 0.09375]]], [[[[0.125, 0.015625, 0.0, 0.625, 0.625, 0.25], 0.015625, 0.25, 4], [[4, 1, 0, 4, 4, 4], 0.0, 0.625]], [[[0.015625], 0.015625, 0.25, 2], [[1], 0.0, 0.0]], [[[0.125, 0.25, 0.125, 0.25, 0.25], 0.03125, 0.125, 2], [[2, 2, 2, 2, 2], 0.0, 0.3125]], [[[0.25, 0.625, 0.03125], 0.0625, 0.125, 3], [[2, 2, 0], 0.5, 0.0]], [[[0.125, 0.625, 0.046875, 0.0625, 0.0, 0.625], 0.0625, 0.25, 2], [[2, 2, 0, 1, 0, 2], 0.75, 0.25]], [[[0.0], 0.015625, 0.25, 2], [[0], 0.0, 0.0]], [[[0.0625, 0.046875, 0.015625, 0.0, 0.125, 0.0625], 0.03125, 0.125, 4], [[2, 1, 1, 0, 4, 2], 0.0, 0.0]], [[[0.046875, 0.25, 0.0625, 0.125, 0.125], 0.015625, 0.125, 3], [[3, 3, 3, 3, 3], 0.0, 0.25]]], [[[[0.078125, 0.078125, 0.625, 0.046875, 0.25], 0.03125, 0.25, 2], [[2, 2, 2, 1, 2], 0.5, 0.40625]], [[[0.625, 0.046875, 0.015625, 0.015625], 0.015625, 0.25, 3], [[3, 3, 1, 1], 0.0, 0.203125]], [[[0.0, 0.625, 0.046875], 0.03125, 0.125, 4], [[0, 4, 1], 0.5, 0.0]], [[[0.0625, 0.015625, 0.625, 0.25], 0.015625, 0.25, 5], [[4, 1, 5, 5], 0.0, 0.34375]], [[[0.0], 0.015625, 0.25, 2], [[0], 0.0, 0.0]], [[[0.078125, 0.046875, 0.03125], 0.03125, 0.125, 1], [[1, 1, 1], 0.0, 0.0625]], [[[0.015625], 0.015625, 0.25, 2], [[1], 0.0, 0.0]], [[[0.046875, 0.25, 0.25, 0.625], 0.0625, 0.125, 4], [[0, 2, 2, 2], 0.75, 0.0]]]]
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[[1], 0.0, 0.0][[1], 0.0, 0.0]Passed
case 1[[0, 1, 0, 1, 1, 1], 0.0, 0.984375][[0, 1, 0, 1, 1, 1], 0.0, 0.359375]Failed
case 2[[0], 0.0, 0.0][[0], 0.0, 0.0]Passed
case 3[[1, 0, 4, 2, 0, 2], 0.25, 0.0][[1, 0, 2, 2, 0, 2], 0.25, 0.0]Failed
case 4[[3, 1, 3, 0, 1, 1], 0.25, 0.5][[2, 1, 2, 0, 1, 1], 0.25, 0.0]Failed
case 5[[2, 3, 1, 3, 1, 1], 0.0, 0.78125][[2, 3, 1, 3, 1, 1], 0.0, 0.15625]Failed
case 6[[4, 4, 0, 1, 2, 2], 0.5, 0.125][[4, 4, 0, 1, 2, 2], 0.5, 0.125]Passed
case 7[[5, 0, 1, 4, 2, 5], 0.0, 0.1875][[4, 0, 1, 4, 2, 4], 0.0, 0.0]Failed

SHA-256 / a0c36dd544ccc3f097b6e0c6930fb8f936737b2514d03195c6bcf81b660633f3

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(frames, dt, max_frame, max_steps):
    acc = 0.0
    dropped = 0.0
    steps = []
    for delta in frames:
        acc += min(delta, max_frame * max_steps)
        n = 0
        while acc >= dt and n < max_steps:
            acc -= dt
            n += 1
        if acc >= dt:
            keep = acc % dt
            dropped += acc - keep
            acc = keep
        steps.append(n)
    return [steps, acc / dt, dropped]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[[0.015625], 0.015625, 0.25, 2], [[1], 0.0, 0.0]], [[[0.0, 0.046875, 0.0, 0.125, 0.25, 0.625], 0.015625, 0.125, 1], [[0, 1, 0, 1, 1, 1], 0.0, 0.359375]], [[[0.0], 0.015625, 0.25, 2], [[0], 0.0, 0.0]], [[[0.0625, 0.0, 0.25, 0.125, 0.015625, 0.125], 0.0625, 0.125, 5], [[1, 0, 2, 2, 0, 2], 0.25, 0.0]], [[[0.25, 0.078125, 0.625, 0.015625, 0.046875, 0.0625], 0.0625, 0.125, 3], [[2, 1, 2, 0, 1, 1], 0.25, 0.0]], [[[0.03125, 0.25, 0.015625, 0.625, 0.015625, 0.015625], 0.015625, 0.125, 3], [[2, 3, 1, 3, 1, 1], 0.0, 0.15625]], [[[0.125, 0.25, 0.0, 0.046875, 0.046875, 0.078125], 0.03125, 0.25, 4], [[4, 4, 0, 1, 2, 2], 0.5, 0.125]], [[[0.25, 0.015625, 0.03125, 0.125, 0.046875, 0.25], 0.03125, 0.125, 5], [[4, 0, 1, 4, 2, 4], 0.0, 0.0]]], [[[[0.015625], 0.015625, 0.25, 2], [[1], 0.0, 0.0]], [[[0.0, 0.046875, 0.125, 0.0], 0.015625, 0.25, 5], [[0, 3, 5, 0], 0.0, 0.046875]], [[[0.625], 0.03125, 0.125, 2], [[2], 0.0, 0.0625]], [[[0.125, 0.25, 0.25], 0.03125, 0.125, 3], [[3, 3, 3], 0.0, 0.09375]], [[[0.125, 0.046875, 0.625, 0.0, 0.0, 0.125], 0.03125, 0.25, 5], [[4, 1, 5, 0, 0, 4], 0.5, 0.09375]], [[[0.0], 0.015625, 0.25, 2], [[0], 0.0, 0.0]], [[[0.015625, 0.0, 0.078125, 0.03125, 0.25], 0.015625, 0.125, 2], [[1, 0, 2, 2, 2], 0.0, 0.140625]], [[[0.25, 0.03125], 0.015625, 0.125, 3], [[3, 2], 0.0, 0.078125]]], [[[[0.125, 0.078125], 0.015625, 0.25, 4], [[4, 4], 0.0, 0.078125]], [[[0.078125, 0.625, 0.125, 0.25, 0.0, 0.25], 0.015625, 0.25, 5], [[5, 5, 5, 5, 0, 5], 0.0, 0.5625]], [[[0.25], 0.03125, 0.125, 2], [[2], 0.0, 0.0625]], [[[0.03125, 0.625, 0.046875, 0.125, 0.25], 0.0625, 0.125, 4], [[0, 2, 1, 2, 2], 0.25, 0.0]], [[[0.015625], 0.015625, 0.25, 2], [[1], 0.0, 0.0]], [[[0.0], 0.015625, 0.25, 2], [[0], 0.0, 0.0]], [[[0.0625, 0.078125, 0.25, 0.0625, 0.015625, 0.625], 0.015625, 0.125, 5], [[4, 5, 5, 4, 1, 5], 0.0, 0.09375]], [[[0.0625, 0.046875, 0.078125, 0.078125, 0.625], 0.03125, 0.25, 5], [[2, 1, 3, 2, 5], 0.5, 0.09375]]], [[[[0.125, 0.015625, 0.0, 0.625, 0.625, 0.25], 0.015625, 0.25, 4], [[4, 1, 0, 4, 4, 4], 0.0, 0.625]], [[[0.015625], 0.015625, 0.25, 2], [[1], 0.0, 0.0]], [[[0.125, 0.25, 0.125, 0.25, 0.25], 0.03125, 0.125, 2], [[2, 2, 2, 2, 2], 0.0, 0.3125]], [[[0.25, 0.625, 0.03125], 0.0625, 0.125, 3], [[2, 2, 0], 0.5, 0.0]], [[[0.125, 0.625, 0.046875, 0.0625, 0.0, 0.625], 0.0625, 0.25, 2], [[2, 2, 0, 1, 0, 2], 0.75, 0.25]], [[[0.0], 0.015625, 0.25, 2], [[0], 0.0, 0.0]], [[[0.0625, 0.046875, 0.015625, 0.0, 0.125, 0.0625], 0.03125, 0.125, 4], [[2, 1, 1, 0, 4, 2], 0.0, 0.0]], [[[0.046875, 0.25, 0.0625, 0.125, 0.125], 0.015625, 0.125, 3], [[3, 3, 3, 3, 3], 0.0, 0.25]]], [[[[0.078125, 0.078125, 0.625, 0.046875, 0.25], 0.03125, 0.25, 2], [[2, 2, 2, 1, 2], 0.5, 0.40625]], [[[0.625, 0.046875, 0.015625, 0.015625], 0.015625, 0.25, 3], [[3, 3, 1, 1], 0.0, 0.203125]], [[[0.0, 0.625, 0.046875], 0.03125, 0.125, 4], [[0, 4, 1], 0.5, 0.0]], [[[0.0625, 0.015625, 0.625, 0.25], 0.015625, 0.25, 5], [[4, 1, 5, 5], 0.0, 0.34375]], [[[0.0], 0.015625, 0.25, 2], [[0], 0.0, 0.0]], [[[0.078125, 0.046875, 0.03125], 0.03125, 0.125, 1], [[1, 1, 1], 0.0, 0.0625]], [[[0.015625], 0.015625, 0.25, 2], [[1], 0.0, 0.0]], [[[0.046875, 0.25, 0.25, 0.625], 0.0625, 0.125, 4], [[0, 2, 2, 2], 0.75, 0.0]]]]
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[[1], 0.0, 0.0][[1], 0.0, 0.0]Passed
case 1[[0, 1, 0, 1, 1, 1], 0.0, 0.359375][[0, 1, 0, 1, 1, 1], 0.0, 0.359375]Passed
case 2[[0], 0.0, 0.0][[0], 0.0, 0.0]Passed
case 3[[1, 0, 4, 2, 0, 2], 0.25, 0.0][[1, 0, 2, 2, 0, 2], 0.25, 0.0]Failed
case 4[[3, 1, 3, 0, 1, 1], 0.25, 0.25][[2, 1, 2, 0, 1, 1], 0.25, 0.0]Failed
case 5[[2, 3, 1, 3, 1, 1], 0.0, 0.53125][[2, 3, 1, 3, 1, 1], 0.0, 0.15625]Failed
case 6[[4, 4, 0, 1, 2, 2], 0.5, 0.125][[4, 4, 0, 1, 2, 2], 0.5, 0.125]Passed
case 7[[5, 0, 1, 4, 2, 5], 0.0, 0.1875][[4, 0, 1, 4, 2, 4], 0.0, 0.0]Failed

SHA-256 / 140d6d41bbb560fb5ca2c826b7336c8551367676ef0bf02b1493c69fce446695

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(frames, dt, max_frame, max_steps):
    acc = 0.0
    dropped = 0.0
    steps = []
    for delta in frames:
        acc += min(delta, max_frame)
        n = 0
        while acc >= dt and n < max_steps:
            acc -= dt
            n += 1
        if acc >= dt:
            keep = acc % dt
            dropped += acc - keep
            acc = keep
        steps.append(n)
    return [steps, acc / dt, dropped]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[[0.015625], 0.015625, 0.25, 2], [[1], 0.0, 0.0]], [[[0.0, 0.046875, 0.0, 0.125, 0.25, 0.625], 0.015625, 0.125, 1], [[0, 1, 0, 1, 1, 1], 0.0, 0.359375]], [[[0.0], 0.015625, 0.25, 2], [[0], 0.0, 0.0]], [[[0.0625, 0.0, 0.25, 0.125, 0.015625, 0.125], 0.0625, 0.125, 5], [[1, 0, 2, 2, 0, 2], 0.25, 0.0]], [[[0.25, 0.078125, 0.625, 0.015625, 0.046875, 0.0625], 0.0625, 0.125, 3], [[2, 1, 2, 0, 1, 1], 0.25, 0.0]], [[[0.03125, 0.25, 0.015625, 0.625, 0.015625, 0.015625], 0.015625, 0.125, 3], [[2, 3, 1, 3, 1, 1], 0.0, 0.15625]], [[[0.125, 0.25, 0.0, 0.046875, 0.046875, 0.078125], 0.03125, 0.25, 4], [[4, 4, 0, 1, 2, 2], 0.5, 0.125]], [[[0.25, 0.015625, 0.03125, 0.125, 0.046875, 0.25], 0.03125, 0.125, 5], [[4, 0, 1, 4, 2, 4], 0.0, 0.0]]], [[[[0.015625], 0.015625, 0.25, 2], [[1], 0.0, 0.0]], [[[0.0, 0.046875, 0.125, 0.0], 0.015625, 0.25, 5], [[0, 3, 5, 0], 0.0, 0.046875]], [[[0.625], 0.03125, 0.125, 2], [[2], 0.0, 0.0625]], [[[0.125, 0.25, 0.25], 0.03125, 0.125, 3], [[3, 3, 3], 0.0, 0.09375]], [[[0.125, 0.046875, 0.625, 0.0, 0.0, 0.125], 0.03125, 0.25, 5], [[4, 1, 5, 0, 0, 4], 0.5, 0.09375]], [[[0.0], 0.015625, 0.25, 2], [[0], 0.0, 0.0]], [[[0.015625, 0.0, 0.078125, 0.03125, 0.25], 0.015625, 0.125, 2], [[1, 0, 2, 2, 2], 0.0, 0.140625]], [[[0.25, 0.03125], 0.015625, 0.125, 3], [[3, 2], 0.0, 0.078125]]], [[[[0.125, 0.078125], 0.015625, 0.25, 4], [[4, 4], 0.0, 0.078125]], [[[0.078125, 0.625, 0.125, 0.25, 0.0, 0.25], 0.015625, 0.25, 5], [[5, 5, 5, 5, 0, 5], 0.0, 0.5625]], [[[0.25], 0.03125, 0.125, 2], [[2], 0.0, 0.0625]], [[[0.03125, 0.625, 0.046875, 0.125, 0.25], 0.0625, 0.125, 4], [[0, 2, 1, 2, 2], 0.25, 0.0]], [[[0.015625], 0.015625, 0.25, 2], [[1], 0.0, 0.0]], [[[0.0], 0.015625, 0.25, 2], [[0], 0.0, 0.0]], [[[0.0625, 0.078125, 0.25, 0.0625, 0.015625, 0.625], 0.015625, 0.125, 5], [[4, 5, 5, 4, 1, 5], 0.0, 0.09375]], [[[0.0625, 0.046875, 0.078125, 0.078125, 0.625], 0.03125, 0.25, 5], [[2, 1, 3, 2, 5], 0.5, 0.09375]]], [[[[0.125, 0.015625, 0.0, 0.625, 0.625, 0.25], 0.015625, 0.25, 4], [[4, 1, 0, 4, 4, 4], 0.0, 0.625]], [[[0.015625], 0.015625, 0.25, 2], [[1], 0.0, 0.0]], [[[0.125, 0.25, 0.125, 0.25, 0.25], 0.03125, 0.125, 2], [[2, 2, 2, 2, 2], 0.0, 0.3125]], [[[0.25, 0.625, 0.03125], 0.0625, 0.125, 3], [[2, 2, 0], 0.5, 0.0]], [[[0.125, 0.625, 0.046875, 0.0625, 0.0, 0.625], 0.0625, 0.25, 2], [[2, 2, 0, 1, 0, 2], 0.75, 0.25]], [[[0.0], 0.015625, 0.25, 2], [[0], 0.0, 0.0]], [[[0.0625, 0.046875, 0.015625, 0.0, 0.125, 0.0625], 0.03125, 0.125, 4], [[2, 1, 1, 0, 4, 2], 0.0, 0.0]], [[[0.046875, 0.25, 0.0625, 0.125, 0.125], 0.015625, 0.125, 3], [[3, 3, 3, 3, 3], 0.0, 0.25]]], [[[[0.078125, 0.078125, 0.625, 0.046875, 0.25], 0.03125, 0.25, 2], [[2, 2, 2, 1, 2], 0.5, 0.40625]], [[[0.625, 0.046875, 0.015625, 0.015625], 0.015625, 0.25, 3], [[3, 3, 1, 1], 0.0, 0.203125]], [[[0.0, 0.625, 0.046875], 0.03125, 0.125, 4], [[0, 4, 1], 0.5, 0.0]], [[[0.0625, 0.015625, 0.625, 0.25], 0.015625, 0.25, 5], [[4, 1, 5, 5], 0.0, 0.34375]], [[[0.0], 0.015625, 0.25, 2], [[0], 0.0, 0.0]], [[[0.078125, 0.046875, 0.03125], 0.03125, 0.125, 1], [[1, 1, 1], 0.0, 0.0625]], [[[0.015625], 0.015625, 0.25, 2], [[1], 0.0, 0.0]], [[[0.046875, 0.25, 0.25, 0.625], 0.0625, 0.125, 4], [[0, 2, 2, 2], 0.75, 0.0]]]]
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[[1], 0.0, 0.0][[1], 0.0, 0.0]Passed
case 1[[0, 1, 0, 1, 1, 1], 0.0, 0.359375][[0, 1, 0, 1, 1, 1], 0.0, 0.359375]Passed
case 2[[0], 0.0, 0.0][[0], 0.0, 0.0]Passed
case 3[[1, 0, 2, 2, 0, 2], 0.25, 0.0][[1, 0, 2, 2, 0, 2], 0.25, 0.0]Passed
case 4[[2, 1, 2, 0, 1, 1], 0.25, 0.0][[2, 1, 2, 0, 1, 1], 0.25, 0.0]Passed
case 5[[2, 3, 1, 3, 1, 1], 0.0, 0.15625][[2, 3, 1, 3, 1, 1], 0.0, 0.15625]Passed
case 6[[4, 4, 0, 1, 2, 2], 0.5, 0.125][[4, 4, 0, 1, 2, 2], 0.5, 0.125]Passed
case 7[[4, 0, 1, 4, 2, 4], 0.0, 0.0][[4, 0, 1, 4, 2, 4], 0.0, 0.0]Passed

SHA-256 / 600ae4dabcb22038de64ad968e3ea903185643b1d74234f8012bdd6a6974cab6

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

Case digest / cc63b56ccabad187cfd59b207ca0d0a5c4ffbe3d711c9b8f5c2182dfd1aef404