FA-65731 / Ecological population dynamics / Open access
Discrete delayed logistic (Hutchinson) with lag: lag index · case 01
Oscillations are weaker than the stated delay produces.
ROOT CAUSE
The lagged density is read one step too recent.
VERIFIED REPAIR
Restore the lag index rule: `hist[t - lag] if t - lag >= 0`.
Unsuccessful approach: Reading one step too old lengthens the delay.
Case contract
hist[0]=N0; N[t+1] = max(0, N[t] + r*N[t]*(1 - N[t-lag]/K)) where values before time 0 equal N0; return [history rounded 4, overshoot max(0, max(history)-K) rounded 4].
Why this case matters
Population projections set harvest quotas, conservation status and pest-control timing; a wrong update order, boundary or rate conversion silently changes management advice.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(n0, r, k, lag, steps):
hist = [float(n0)]
for t in range(steps):
past = hist[t - lag + 1] if t - lag + 1 >= 0 else hist[0]
now = hist[t]
hist.append(max(0.0, now + r * now * (1 - past / k)))
over = max(0.0, max(hist) - k)
return [[round(x, 4) for x in hist], round(over, 4)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: daphnia with 2 step lag',
(10, 0.8, 100, 2, 8),
[[10.0, 17.2, 29.584, 50.8845, 84.5904, 132.2425, 184.2037, 206.9118, 153.541], 106.9118]),
('regression: long lag oscillation',
(50, 0.6, 100, 3, 10),
[[50.0, 65.0, 84.5, 109.85, 142.805, 172.794, 188.8639, 177.702, 132.0628, 74.3825, 34.723], 88.8639]),
('regression: start above capacity',
(150, 0.3, 100, 1, 5),
[[150.0, 127.5, 108.375, 99.4341, 96.9358, 97.1004], 50.0]),
('regression: one-step lag',
(20, 1.2, 200, 1, 7),
[[20.0, 41.6, 86.528, 168.7642, 283.6643, 336.8272, 167.7447, 30.0325], 136.8272]),
('control: zero steps', (30, 0.5, 100, 2, 0), [[30.0], 0.0]),
('control: crash to zero', (180, 2.5, 100, 1, 4), [[180.0, 0.0, 0.0, 0.0, 0.0], 80.0])],
[('regression: daphnia with 2 step lag',
(10, 0.8, 100, 2, 8),
[[10.0, 17.2, 29.584, 50.8845, 84.5904, 132.2425, 184.2037, 206.9118, 153.541], 106.9118]),
('regression: long lag oscillation',
(50, 0.6, 100, 3, 10),
[[50.0, 65.0, 84.5, 109.85, 142.805, 172.794, 188.8639, 177.702, 132.0628, 74.3825, 34.723], 88.8639]),
('regression: start above capacity',
(150, 0.3, 100, 1, 5),
[[150.0, 127.5, 108.375, 99.4341, 96.9358, 97.1004], 50.0]),
('regression: one-step lag',
(20, 1.2, 200, 1, 7),
[[20.0, 41.6, 86.528, 168.7642, 283.6643, 336.8272, 167.7447, 30.0325], 136.8272]),
('control: zero steps', (30, 0.5, 100, 2, 0), [[30.0], 0.0]),
('control: crash to zero', (180, 2.5, 100, 1, 4), [[180.0, 0.0, 0.0, 0.0, 0.0], 80.0])],
[('regression: daphnia with 2 step lag',
(10, 0.8, 100, 2, 8),
[[10.0, 17.2, 29.584, 50.8845, 84.5904, 132.2425, 184.2037, 206.9118, 153.541], 106.9118]),
('regression: long lag oscillation',
(50, 0.6, 100, 3, 10),
[[50.0, 65.0, 84.5, 109.85, 142.805, 172.794, 188.8639, 177.702, 132.0628, 74.3825, 34.723], 88.8639]),
('regression: start above capacity',
(150, 0.3, 100, 1, 5),
[[150.0, 127.5, 108.375, 99.4341, 96.9358, 97.1004], 50.0]),
('regression: one-step lag',
(20, 1.2, 200, 1, 7),
[[20.0, 41.6, 86.528, 168.7642, 283.6643, 336.8272, 167.7447, 30.0325], 136.8272]),
('control: zero steps', (30, 0.5, 100, 2, 0), [[30.0], 0.0]),
('control: crash to zero', (180, 2.5, 100, 1, 4), [[180.0, 0.0, 0.0, 0.0, 0.0], 80.0])],
[('regression: daphnia with 2 step lag',
(10, 0.8, 100, 2, 8),
[[10.0, 17.2, 29.584, 50.8845, 84.5904, 132.2425, 184.2037, 206.9118, 153.541], 106.9118]),
('regression: long lag oscillation',
(50, 0.6, 100, 3, 10),
[[50.0, 65.0, 84.5, 109.85, 142.805, 172.794, 188.8639, 177.702, 132.0628, 74.3825, 34.723], 88.8639]),
('regression: start above capacity',
(150, 0.3, 100, 1, 5),
[[150.0, 127.5, 108.375, 99.4341, 96.9358, 97.1004], 50.0]),
('regression: one-step lag',
(20, 1.2, 200, 1, 7),
[[20.0, 41.6, 86.528, 168.7642, 283.6643, 336.8272, 167.7447, 30.0325], 136.8272]),
('control: zero steps', (30, 0.5, 100, 2, 0), [[30.0], 0.0]),
('control: crash to zero', (180, 2.5, 100, 1, 4), [[180.0, 0.0, 0.0, 0.0, 0.0], 80.0])],
[('regression: daphnia with 2 step lag',
(10, 0.8, 100, 2, 8),
[[10.0, 17.2, 29.584, 50.8845, 84.5904, 132.2425, 184.2037, 206.9118, 153.541], 106.9118]),
('regression: long lag oscillation',
(50, 0.6, 100, 3, 10),
[[50.0, 65.0, 84.5, 109.85, 142.805, 172.794, 188.8639, 177.702, 132.0628, 74.3825, 34.723], 88.8639]),
('regression: start above capacity',
(150, 0.3, 100, 1, 5),
[[150.0, 127.5, 108.375, 99.4341, 96.9358, 97.1004], 50.0]),
('regression: one-step lag',
(20, 1.2, 200, 1, 7),
[[20.0, 41.6, 86.528, 168.7642, 283.6643, 336.8272, 167.7447, 30.0325], 136.8272]),
('control: zero steps', (30, 0.5, 100, 2, 0), [[30.0], 0.0]),
('control: crash to zero', (180, 2.5, 100, 1, 4), [[180.0, 0.0, 0.0, 0.0, 0.0], 80.0])]]
for label, args, expected in fixtures[N - 1]:
check(label, 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 |
|---|---|---|---|
| regression: daphnia with 2 step lag | [[10.0, 17.2, 29.584, 49.1804, 76.8852, 108.1433, 128.141, 119.7931, 92.8243], 28.141] | [[10.0, 17.2, 29.584, 50.8845, 84.5904, 132.2425, 184.2037, 206.9118, 153.541], 106.9118] | Failed |
| regression: long lag oscillation | [[50.0, 65.0, 84.5, 109.85, 132.9185, 145.2799, 136.6939, 109.6953, 79.8934, 62.3038, 58.6794], 45.2799] | [[50.0, 65.0, 84.5, 109.85, 142.805, 172.794, 188.8639, 177.702, 132.0628, 74.3825, 34.723], 88.8639] | Failed |
| regression: start above capacity | [[150.0, 127.5, 116.9813, 111.0218, 107.3508, 104.9835], 50.0] | [[150.0, 127.5, 108.375, 99.4341, 96.9358, 97.1004], 50.0] | Failed |
| regression: one-step lag | [[20.0, 41.6, 81.1366, 139.0017, 189.8749, 201.4099, 199.7061, 200.0583], 1.4099] | [[20.0, 41.6, 86.528, 168.7642, 283.6643, 336.8272, 167.7447, 30.0325], 136.8272] | Failed |
| control: zero steps | [[30.0], 0.0] | [[30.0], 0.0] | Passed |
| control: crash to zero | [[180.0, 0.0, 0.0, 0.0, 0.0], 80.0] | [[180.0, 0.0, 0.0, 0.0, 0.0], 80.0] | Passed |
SHA-256 / b0e8f4cac87f057956744aa2cd5cb750296584aa023949ad6f176f424ff29e4c
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(n0, r, k, lag, steps):
hist = [float(n0)]
for t in range(steps):
past = hist[max(0, t - lag - 1)] if t - lag >= 0 else hist[0]
now = hist[t]
hist.append(max(0.0, now + r * now * (1 - past / k)))
over = max(0.0, max(hist) - k)
return [[round(x, 4) for x in hist], round(over, 4)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: daphnia with 2 step lag',
(10, 0.8, 100, 2, 8),
[[10.0, 17.2, 29.584, 50.8845, 84.5904, 132.2425, 184.2037, 206.9118, 153.541], 106.9118]),
('regression: long lag oscillation',
(50, 0.6, 100, 3, 10),
[[50.0, 65.0, 84.5, 109.85, 142.805, 172.794, 188.8639, 177.702, 132.0628, 74.3825, 34.723], 88.8639]),
('regression: start above capacity',
(150, 0.3, 100, 1, 5),
[[150.0, 127.5, 108.375, 99.4341, 96.9358, 97.1004], 50.0]),
('regression: one-step lag',
(20, 1.2, 200, 1, 7),
[[20.0, 41.6, 86.528, 168.7642, 283.6643, 336.8272, 167.7447, 30.0325], 136.8272]),
('control: zero steps', (30, 0.5, 100, 2, 0), [[30.0], 0.0]),
('control: crash to zero', (180, 2.5, 100, 1, 4), [[180.0, 0.0, 0.0, 0.0, 0.0], 80.0])],
[('regression: daphnia with 2 step lag',
(10, 0.8, 100, 2, 8),
[[10.0, 17.2, 29.584, 50.8845, 84.5904, 132.2425, 184.2037, 206.9118, 153.541], 106.9118]),
('regression: long lag oscillation',
(50, 0.6, 100, 3, 10),
[[50.0, 65.0, 84.5, 109.85, 142.805, 172.794, 188.8639, 177.702, 132.0628, 74.3825, 34.723], 88.8639]),
('regression: start above capacity',
(150, 0.3, 100, 1, 5),
[[150.0, 127.5, 108.375, 99.4341, 96.9358, 97.1004], 50.0]),
('regression: one-step lag',
(20, 1.2, 200, 1, 7),
[[20.0, 41.6, 86.528, 168.7642, 283.6643, 336.8272, 167.7447, 30.0325], 136.8272]),
('control: zero steps', (30, 0.5, 100, 2, 0), [[30.0], 0.0]),
('control: crash to zero', (180, 2.5, 100, 1, 4), [[180.0, 0.0, 0.0, 0.0, 0.0], 80.0])],
[('regression: daphnia with 2 step lag',
(10, 0.8, 100, 2, 8),
[[10.0, 17.2, 29.584, 50.8845, 84.5904, 132.2425, 184.2037, 206.9118, 153.541], 106.9118]),
('regression: long lag oscillation',
(50, 0.6, 100, 3, 10),
[[50.0, 65.0, 84.5, 109.85, 142.805, 172.794, 188.8639, 177.702, 132.0628, 74.3825, 34.723], 88.8639]),
('regression: start above capacity',
(150, 0.3, 100, 1, 5),
[[150.0, 127.5, 108.375, 99.4341, 96.9358, 97.1004], 50.0]),
('regression: one-step lag',
(20, 1.2, 200, 1, 7),
[[20.0, 41.6, 86.528, 168.7642, 283.6643, 336.8272, 167.7447, 30.0325], 136.8272]),
('control: zero steps', (30, 0.5, 100, 2, 0), [[30.0], 0.0]),
('control: crash to zero', (180, 2.5, 100, 1, 4), [[180.0, 0.0, 0.0, 0.0, 0.0], 80.0])],
[('regression: daphnia with 2 step lag',
(10, 0.8, 100, 2, 8),
[[10.0, 17.2, 29.584, 50.8845, 84.5904, 132.2425, 184.2037, 206.9118, 153.541], 106.9118]),
('regression: long lag oscillation',
(50, 0.6, 100, 3, 10),
[[50.0, 65.0, 84.5, 109.85, 142.805, 172.794, 188.8639, 177.702, 132.0628, 74.3825, 34.723], 88.8639]),
('regression: start above capacity',
(150, 0.3, 100, 1, 5),
[[150.0, 127.5, 108.375, 99.4341, 96.9358, 97.1004], 50.0]),
('regression: one-step lag',
(20, 1.2, 200, 1, 7),
[[20.0, 41.6, 86.528, 168.7642, 283.6643, 336.8272, 167.7447, 30.0325], 136.8272]),
('control: zero steps', (30, 0.5, 100, 2, 0), [[30.0], 0.0]),
('control: crash to zero', (180, 2.5, 100, 1, 4), [[180.0, 0.0, 0.0, 0.0, 0.0], 80.0])],
[('regression: daphnia with 2 step lag',
(10, 0.8, 100, 2, 8),
[[10.0, 17.2, 29.584, 50.8845, 84.5904, 132.2425, 184.2037, 206.9118, 153.541], 106.9118]),
('regression: long lag oscillation',
(50, 0.6, 100, 3, 10),
[[50.0, 65.0, 84.5, 109.85, 142.805, 172.794, 188.8639, 177.702, 132.0628, 74.3825, 34.723], 88.8639]),
('regression: start above capacity',
(150, 0.3, 100, 1, 5),
[[150.0, 127.5, 108.375, 99.4341, 96.9358, 97.1004], 50.0]),
('regression: one-step lag',
(20, 1.2, 200, 1, 7),
[[20.0, 41.6, 86.528, 168.7642, 283.6643, 336.8272, 167.7447, 30.0325], 136.8272]),
('control: zero steps', (30, 0.5, 100, 2, 0), [[30.0], 0.0]),
('control: crash to zero', (180, 2.5, 100, 1, 4), [[180.0, 0.0, 0.0, 0.0, 0.0], 80.0])]]
for label, args, expected in fixtures[N - 1]:
check(label, 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 |
|---|---|---|---|
| regression: daphnia with 2 step lag | [[10.0, 17.2, 29.584, 50.8845, 87.5213, 145.4954, 227.4571, 316.8304, 348.4595], 248.4595] | [[10.0, 17.2, 29.584, 50.8845, 84.5904, 132.2425, 184.2037, 206.9118, 153.541], 106.9118] | Failed |
| regression: long lag oscillation | [[50.0, 65.0, 84.5, 109.85, 142.805, 185.6465, 224.6323, 245.5231, 231.0127, 171.6817, 83.4581], 145.5231] | [[50.0, 65.0, 84.5, 109.85, 142.805, 172.794, 188.8639, 177.702, 132.0628, 74.3825, 34.723], 88.8639] | Failed |
| regression: start above capacity | [[150.0, 127.5, 108.375, 92.1188, 84.519, 82.3954], 50.0] | [[150.0, 127.5, 108.375, 99.4341, 96.9358, 97.1004], 50.0] | Failed |
| regression: one-step lag | [[20.0, 41.6, 86.528, 179.9782, 351.0296, 590.0217, 660.9014, 62.0075], 460.9014] | [[20.0, 41.6, 86.528, 168.7642, 283.6643, 336.8272, 167.7447, 30.0325], 136.8272] | Failed |
| control: zero steps | [[30.0], 0.0] | [[30.0], 0.0] | Passed |
| control: crash to zero | [[180.0, 0.0, 0.0, 0.0, 0.0], 80.0] | [[180.0, 0.0, 0.0, 0.0, 0.0], 80.0] | Passed |
SHA-256 / 17d62e2218badb2ceb37bc326cb9b7a3457f7b09365e8343cc821a8c2e62ed42
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(n0, r, k, lag, steps):
hist = [float(n0)]
for t in range(steps):
past = hist[t - lag] if t - lag >= 0 else hist[0]
now = hist[t]
hist.append(max(0.0, now + r * now * (1 - past / k)))
over = max(0.0, max(hist) - k)
return [[round(x, 4) for x in hist], round(over, 4)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: daphnia with 2 step lag',
(10, 0.8, 100, 2, 8),
[[10.0, 17.2, 29.584, 50.8845, 84.5904, 132.2425, 184.2037, 206.9118, 153.541], 106.9118]),
('regression: long lag oscillation',
(50, 0.6, 100, 3, 10),
[[50.0, 65.0, 84.5, 109.85, 142.805, 172.794, 188.8639, 177.702, 132.0628, 74.3825, 34.723], 88.8639]),
('regression: start above capacity',
(150, 0.3, 100, 1, 5),
[[150.0, 127.5, 108.375, 99.4341, 96.9358, 97.1004], 50.0]),
('regression: one-step lag',
(20, 1.2, 200, 1, 7),
[[20.0, 41.6, 86.528, 168.7642, 283.6643, 336.8272, 167.7447, 30.0325], 136.8272]),
('control: zero steps', (30, 0.5, 100, 2, 0), [[30.0], 0.0]),
('control: crash to zero', (180, 2.5, 100, 1, 4), [[180.0, 0.0, 0.0, 0.0, 0.0], 80.0])],
[('regression: daphnia with 2 step lag',
(10, 0.8, 100, 2, 8),
[[10.0, 17.2, 29.584, 50.8845, 84.5904, 132.2425, 184.2037, 206.9118, 153.541], 106.9118]),
('regression: long lag oscillation',
(50, 0.6, 100, 3, 10),
[[50.0, 65.0, 84.5, 109.85, 142.805, 172.794, 188.8639, 177.702, 132.0628, 74.3825, 34.723], 88.8639]),
('regression: start above capacity',
(150, 0.3, 100, 1, 5),
[[150.0, 127.5, 108.375, 99.4341, 96.9358, 97.1004], 50.0]),
('regression: one-step lag',
(20, 1.2, 200, 1, 7),
[[20.0, 41.6, 86.528, 168.7642, 283.6643, 336.8272, 167.7447, 30.0325], 136.8272]),
('control: zero steps', (30, 0.5, 100, 2, 0), [[30.0], 0.0]),
('control: crash to zero', (180, 2.5, 100, 1, 4), [[180.0, 0.0, 0.0, 0.0, 0.0], 80.0])],
[('regression: daphnia with 2 step lag',
(10, 0.8, 100, 2, 8),
[[10.0, 17.2, 29.584, 50.8845, 84.5904, 132.2425, 184.2037, 206.9118, 153.541], 106.9118]),
('regression: long lag oscillation',
(50, 0.6, 100, 3, 10),
[[50.0, 65.0, 84.5, 109.85, 142.805, 172.794, 188.8639, 177.702, 132.0628, 74.3825, 34.723], 88.8639]),
('regression: start above capacity',
(150, 0.3, 100, 1, 5),
[[150.0, 127.5, 108.375, 99.4341, 96.9358, 97.1004], 50.0]),
('regression: one-step lag',
(20, 1.2, 200, 1, 7),
[[20.0, 41.6, 86.528, 168.7642, 283.6643, 336.8272, 167.7447, 30.0325], 136.8272]),
('control: zero steps', (30, 0.5, 100, 2, 0), [[30.0], 0.0]),
('control: crash to zero', (180, 2.5, 100, 1, 4), [[180.0, 0.0, 0.0, 0.0, 0.0], 80.0])],
[('regression: daphnia with 2 step lag',
(10, 0.8, 100, 2, 8),
[[10.0, 17.2, 29.584, 50.8845, 84.5904, 132.2425, 184.2037, 206.9118, 153.541], 106.9118]),
('regression: long lag oscillation',
(50, 0.6, 100, 3, 10),
[[50.0, 65.0, 84.5, 109.85, 142.805, 172.794, 188.8639, 177.702, 132.0628, 74.3825, 34.723], 88.8639]),
('regression: start above capacity',
(150, 0.3, 100, 1, 5),
[[150.0, 127.5, 108.375, 99.4341, 96.9358, 97.1004], 50.0]),
('regression: one-step lag',
(20, 1.2, 200, 1, 7),
[[20.0, 41.6, 86.528, 168.7642, 283.6643, 336.8272, 167.7447, 30.0325], 136.8272]),
('control: zero steps', (30, 0.5, 100, 2, 0), [[30.0], 0.0]),
('control: crash to zero', (180, 2.5, 100, 1, 4), [[180.0, 0.0, 0.0, 0.0, 0.0], 80.0])],
[('regression: daphnia with 2 step lag',
(10, 0.8, 100, 2, 8),
[[10.0, 17.2, 29.584, 50.8845, 84.5904, 132.2425, 184.2037, 206.9118, 153.541], 106.9118]),
('regression: long lag oscillation',
(50, 0.6, 100, 3, 10),
[[50.0, 65.0, 84.5, 109.85, 142.805, 172.794, 188.8639, 177.702, 132.0628, 74.3825, 34.723], 88.8639]),
('regression: start above capacity',
(150, 0.3, 100, 1, 5),
[[150.0, 127.5, 108.375, 99.4341, 96.9358, 97.1004], 50.0]),
('regression: one-step lag',
(20, 1.2, 200, 1, 7),
[[20.0, 41.6, 86.528, 168.7642, 283.6643, 336.8272, 167.7447, 30.0325], 136.8272]),
('control: zero steps', (30, 0.5, 100, 2, 0), [[30.0], 0.0]),
('control: crash to zero', (180, 2.5, 100, 1, 4), [[180.0, 0.0, 0.0, 0.0, 0.0], 80.0])]]
for label, args, expected in fixtures[N - 1]:
check(label, 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 |
|---|---|---|---|
| regression: daphnia with 2 step lag | [[10.0, 17.2, 29.584, 50.8845, 84.5904, 132.2425, 184.2037, 206.9118, 153.541], 106.9118] | [[10.0, 17.2, 29.584, 50.8845, 84.5904, 132.2425, 184.2037, 206.9118, 153.541], 106.9118] | Passed |
| regression: long lag oscillation | [[50.0, 65.0, 84.5, 109.85, 142.805, 172.794, 188.8639, 177.702, 132.0628, 74.3825, 34.723], 88.8639] | [[50.0, 65.0, 84.5, 109.85, 142.805, 172.794, 188.8639, 177.702, 132.0628, 74.3825, 34.723], 88.8639] | Passed |
| regression: start above capacity | [[150.0, 127.5, 108.375, 99.4341, 96.9358, 97.1004], 50.0] | [[150.0, 127.5, 108.375, 99.4341, 96.9358, 97.1004], 50.0] | Passed |
| regression: one-step lag | [[20.0, 41.6, 86.528, 168.7642, 283.6643, 336.8272, 167.7447, 30.0325], 136.8272] | [[20.0, 41.6, 86.528, 168.7642, 283.6643, 336.8272, 167.7447, 30.0325], 136.8272] | Passed |
| control: zero steps | [[30.0], 0.0] | [[30.0], 0.0] | Passed |
| control: crash to zero | [[180.0, 0.0, 0.0, 0.0, 0.0], 80.0] | [[180.0, 0.0, 0.0, 0.0, 0.0], 80.0] | Passed |
SHA-256 / edc2a895a3b59acd092ced6e4e9c5c190863cfde1e45a985a139b2443a579392
Verification & scope
Deterministic bounded teaching model with a stipulated contract; not a validated scientific or public-health modelling library. 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:47:36.640885+00:00.
Case digest / 3f06c1fbac173fdc2d458a26f8371ca00510118edd1bf067912f4b273a48e19a