FAILURE MAP
← Case archive

FA-65741 / Ecological population dynamics / Open access

Discrete delayed logistic (Hutchinson) with lag: growth base · case 01

Recruitment tracks the lagged population instead of current breeders.

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

ROOT CAUSE

Per-capita growth multiplies the lagged density.

VERIFIED REPAIR

Restore the growth base rule: `now + r * now * (1 - past / k)`.

Unsuccessful approach: Starting from the lagged density discards the current state.

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] if t - lag >= 0 else hist[0]
        now = hist[t]
        hist.append(max(0.0, now + r * past * (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]),
  ('control: no lag', (10, 0.5, 100, 0, 6), [[10.0, 14.5, 20.6988, 28.9059, 39.1811, 51.0959, 63.5899], 0.0]),
  ('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]),
  ('regression: 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]),
  ('control: no lag', (10, 0.5, 100, 0, 6), [[10.0, 14.5, 20.6988, 28.9059, 39.1811, 51.0959, 63.5899], 0.0]),
  ('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]),
  ('regression: 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]),
  ('control: no lag', (10, 0.5, 100, 0, 6), [[10.0, 14.5, 20.6988, 28.9059, 39.1811, 51.0959, 63.5899], 0.0]),
  ('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]),
  ('regression: 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]),
  ('control: no lag', (10, 0.5, 100, 0, 6), [[10.0, 14.5, 20.6988, 28.9059, 39.1811, 51.0959, 63.5899], 0.0]),
  ('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]),
  ('regression: 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]),
  ('control: no lag', (10, 0.5, 100, 0, 6), [[10.0, 14.5, 20.6988, 28.9059, 39.1811, 51.0959, 63.5899], 0.0]),
  ('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]),
  ('regression: 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 fixtureActualExpectedOutcome
regression: daphnia with 2 step lag[[10.0, 17.2, 24.4, 31.6, 42.9933, 57.7504, 75.0419, 94.6492, 114.1686], 14.1686][[10.0, 17.2, 29.584, 50.8845, 84.5904, 132.2425, 184.2037, 206.9118, 153.541], 106.9118]Failed
control: no lag[[10.0, 14.5, 20.6988, 28.9059, 39.1811, 51.0959, 63.5899], 0.0][[10.0, 14.5, 20.6988, 28.9059, 39.1811, 51.0959, 63.5899], 0.0]Passed
regression: long lag oscillation[[50.0, 65.0, 80.0, 95.0, 110.0, 123.65, 133.25, 136.1, 129.5, 111.9541, 85.3707], 36.1][[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, 105.0, 94.4813, 92.9062, 94.4705], 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, 63.2, 102.7366, 154.6112, 214.5663, 256.672, 237.9194], 56.672][[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
regression: 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 / c15748843abf505bbaca8e16106881cd786c432303aa144c83db75fd200e96b7

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[t - lag] if t - lag >= 0 else hist[0]
        now = hist[t]
        hist.append(max(0.0, past + 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]),
  ('control: no lag', (10, 0.5, 100, 0, 6), [[10.0, 14.5, 20.6988, 28.9059, 39.1811, 51.0959, 63.5899], 0.0]),
  ('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]),
  ('regression: 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]),
  ('control: no lag', (10, 0.5, 100, 0, 6), [[10.0, 14.5, 20.6988, 28.9059, 39.1811, 51.0959, 63.5899], 0.0]),
  ('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]),
  ('regression: 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]),
  ('control: no lag', (10, 0.5, 100, 0, 6), [[10.0, 14.5, 20.6988, 28.9059, 39.1811, 51.0959, 63.5899], 0.0]),
  ('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]),
  ('regression: 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]),
  ('control: no lag', (10, 0.5, 100, 0, 6), [[10.0, 14.5, 20.6988, 28.9059, 39.1811, 51.0959, 63.5899], 0.0]),
  ('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]),
  ('regression: 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]),
  ('control: no lag', (10, 0.5, 100, 0, 6), [[10.0, 14.5, 20.6988, 28.9059, 39.1811, 51.0959, 63.5899], 0.0]),
  ('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]),
  ('regression: 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 fixtureActualExpectedOutcome
regression: daphnia with 2 step lag[[10.0, 17.2, 22.384, 26.1165, 34.4996, 43.8057, 52.0087, 61.7523, 71.5667], 0.0][[10.0, 17.2, 29.584, 50.8845, 84.5904, 132.2425, 184.2037, 206.9118, 153.541], 106.9118]Failed
control: no lag[[10.0, 14.5, 20.6988, 28.9059, 39.1811, 51.0959, 63.5899], 0.0][[10.0, 14.5, 20.6988, 28.9059, 39.1811, 51.0959, 63.5899], 0.0]Passed
regression: long lag oscillation[[50.0, 65.0, 69.5, 70.85, 71.255, 79.9635, 84.1333, 85.5649, 86.0124, 90.3038, 92.7303], 0.0][[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, 130.875, 116.7028, 120.0654, 110.6865], 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, 64.928, 103.3076, 148.6518, 189.5486, 207.0497, 202.5324], 7.0497][[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
regression: crash to zero[[180.0, 0.0, 180.0, 450.0, 0.0], 350.0][[180.0, 0.0, 0.0, 0.0, 0.0], 80.0]Failed

SHA-256 / 30bb6771dc97dd7330fd288d5cd66c6a5d8d93135db6684a8bc0c29245ada78d

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]),
  ('control: no lag', (10, 0.5, 100, 0, 6), [[10.0, 14.5, 20.6988, 28.9059, 39.1811, 51.0959, 63.5899], 0.0]),
  ('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]),
  ('regression: 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]),
  ('control: no lag', (10, 0.5, 100, 0, 6), [[10.0, 14.5, 20.6988, 28.9059, 39.1811, 51.0959, 63.5899], 0.0]),
  ('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]),
  ('regression: 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]),
  ('control: no lag', (10, 0.5, 100, 0, 6), [[10.0, 14.5, 20.6988, 28.9059, 39.1811, 51.0959, 63.5899], 0.0]),
  ('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]),
  ('regression: 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]),
  ('control: no lag', (10, 0.5, 100, 0, 6), [[10.0, 14.5, 20.6988, 28.9059, 39.1811, 51.0959, 63.5899], 0.0]),
  ('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]),
  ('regression: 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]),
  ('control: no lag', (10, 0.5, 100, 0, 6), [[10.0, 14.5, 20.6988, 28.9059, 39.1811, 51.0959, 63.5899], 0.0]),
  ('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]),
  ('regression: 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 fixtureActualExpectedOutcome
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
control: no lag[[10.0, 14.5, 20.6988, 28.9059, 39.1811, 51.0959, 63.5899], 0.0][[10.0, 14.5, 20.6988, 28.9059, 39.1811, 51.0959, 63.5899], 0.0]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
regression: 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 / 3ae662246968217c12068c39e69306df69947a259935090e8ef25b0dcc2af779

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

Case digest / 804d2002acb69f18f8544e6c3b9208dd93d074ad448f8aa8cb8decd225673141