FA-65381 / Ecological population dynamics / Open access
Beverton-Holt recruitment convergence: density denominator · case 01
The stock settles well below the stated carrying capacity.
ROOT CAUSE
The half-saturation constant is taken as K instead of K/(r0-1).
VERIFIED REPAIR
Restore the density denominator rule: `(1 + (r0 - 1) * n / k)`.
Unsuccessful approach: Using r0*N/K moves the equilibrium to K*(r0-1)/r0.
Case contract
N[t+1] = r0*N/(1+(r0-1)*N/K); equilibrium K if r0>1 else 0; band = 0.01*K; hit = first year (0 = start) with |N-eq|<=band, else None; return [trajectory rounded 4, equilibrium, hit]; None for invalid inputs.
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, r0, k, years):
if k <= 0 or r0 <= 0 or n0 < 0:
return None
eq = float(k) if r0 > 1 else 0.0
band = 0.01 * k
n = float(n0)
traj = []
hit = 0 if abs(n - eq) <= band else None
for year in range(1, years + 1):
n = r0 * n / (1 + n / k)
traj.append(round(n, 4))
if hit is None and abs(n - eq) <= band:
hit = year
return [traj, eq, hit]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: herring recruitment',
(50, 3.0, 1000, 10),
[[136.3636, 321.4286, 586.9565, 810.0, 927.4809, 974.5989, 991.3871, 997.1125, 999.0356, 999.6783],
1000.0,
7]),
('regression: slow approach',
(10, 1.5, 500, 12),
[[14.8515,
21.9512,
32.2196,
46.8208,
67.09,
94.3079,
129.2706,
171.709,
219.8186,
270.309,
319.1849,
362.9343],
500.0,
None]),
('regression: start at capacity', (1000, 2.0, 1000, 4), [[1000.0, 1000.0, 1000.0, 1000.0], 1000.0, 0]),
('regression: start within band', (995, 2.0, 1000, 3), [[997.4937, 998.7453, 999.3723], 1000.0, 0]),
('regression: replacement r0 one', (200, 1.0, 1000, 4), [[200.0, 200.0, 200.0, 200.0], 0.0, None]),
('regression: declining r0 half',
(400, 0.5, 1000, 8),
[[250.0, 142.8571, 76.9231, 40.0, 20.4082, 10.3093, 5.1813, 2.5974], 0.0, 7]),
('control: invalid r0', (100, 0.0, 1000, 5), None)],
[('regression: start within band', (995, 2.0, 1000, 3), [[997.4937, 998.7453, 999.3723], 1000.0, 0]),
('regression: replacement r0 one', (200, 1.0, 1000, 4), [[200.0, 200.0, 200.0, 200.0], 0.0, None]),
('regression: declining r0 half',
(400, 0.5, 1000, 8),
[[250.0, 142.8571, 76.9231, 40.0, 20.4082, 10.3093, 5.1813, 2.5974], 0.0, 7]),
('regression: above capacity',
(3000, 2.5, 1000, 6),
[[1363.6364, 1119.403, 1044.5682, 1017.363, 1006.8736, 1002.7381], 1000.0, 5]),
('control: invalid r0', (100, 0.0, 1000, 5), None),
('regression: never reaches band',
(1, 1.2, 10000, 5),
[[1.2, 1.4399, 1.7279, 2.0734, 2.4879], 10000.0, None]),
('regression: one year from band',
(985, 2.0, 1000, 4),
[[992.4433, 996.2073, 998.1001, 999.0491], 1000.0, 1])],
[('regression: herring recruitment',
(50, 3.0, 1000, 10),
[[136.3636, 321.4286, 586.9565, 810.0, 927.4809, 974.5989, 991.3871, 997.1125, 999.0356, 999.6783],
1000.0,
7]),
('regression: slow approach',
(10, 1.5, 500, 12),
[[14.8515,
21.9512,
32.2196,
46.8208,
67.09,
94.3079,
129.2706,
171.709,
219.8186,
270.309,
319.1849,
362.9343],
500.0,
None]),
('regression: above capacity',
(3000, 2.5, 1000, 6),
[[1363.6364, 1119.403, 1044.5682, 1017.363, 1006.8736, 1002.7381], 1000.0, 5]),
('control: invalid r0', (100, 0.0, 1000, 5), None),
('regression: never reaches band',
(1, 1.2, 10000, 5),
[[1.2, 1.4399, 1.7279, 2.0734, 2.4879], 10000.0, None]),
('regression: one year from band',
(985, 2.0, 1000, 4),
[[992.4433, 996.2073, 998.1001, 999.0491], 1000.0, 1]),
('regression: small capacity',
(2, 4.0, 20, 6),
[[6.1538, 12.8, 17.5342, 19.3208, 19.8258, 19.9562], 20.0, 5])],
[('regression: herring recruitment',
(50, 3.0, 1000, 10),
[[136.3636, 321.4286, 586.9565, 810.0, 927.4809, 974.5989, 991.3871, 997.1125, 999.0356, 999.6783],
1000.0,
7]),
('regression: slow approach',
(10, 1.5, 500, 12),
[[14.8515,
21.9512,
32.2196,
46.8208,
67.09,
94.3079,
129.2706,
171.709,
219.8186,
270.309,
319.1849,
362.9343],
500.0,
None]),
('regression: start at capacity', (1000, 2.0, 1000, 4), [[1000.0, 1000.0, 1000.0, 1000.0], 1000.0, 0]),
('regression: start within band', (995, 2.0, 1000, 3), [[997.4937, 998.7453, 999.3723], 1000.0, 0]),
('control: invalid r0', (100, 0.0, 1000, 5), None),
('regression: one year from band',
(985, 2.0, 1000, 4),
[[992.4433, 996.2073, 998.1001, 999.0491], 1000.0, 1]),
('regression: small capacity',
(2, 4.0, 20, 6),
[[6.1538, 12.8, 17.5342, 19.3208, 19.8258, 19.9562], 20.0, 5])],
[('regression: slow approach',
(10, 1.5, 500, 12),
[[14.8515,
21.9512,
32.2196,
46.8208,
67.09,
94.3079,
129.2706,
171.709,
219.8186,
270.309,
319.1849,
362.9343],
500.0,
None]),
('regression: start at capacity', (1000, 2.0, 1000, 4), [[1000.0, 1000.0, 1000.0, 1000.0], 1000.0, 0]),
('regression: start within band', (995, 2.0, 1000, 3), [[997.4937, 998.7453, 999.3723], 1000.0, 0]),
('regression: replacement r0 one', (200, 1.0, 1000, 4), [[200.0, 200.0, 200.0, 200.0], 0.0, None]),
('regression: declining r0 half',
(400, 0.5, 1000, 8),
[[250.0, 142.8571, 76.9231, 40.0, 20.4082, 10.3093, 5.1813, 2.5974], 0.0, 7]),
('regression: above capacity',
(3000, 2.5, 1000, 6),
[[1363.6364, 1119.403, 1044.5682, 1017.363, 1006.8736, 1002.7381], 1000.0, 5]),
('control: invalid r0', (100, 0.0, 1000, 5), None)]]
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: herring recruitment | [[142.8571, 375.0, 818.1818, 1350.0, 1723.4043, 1898.4375, 1964.9596, 1988.1818, 1996.045, 1998.6799], 1000.0, None] | [[136.3636, 321.4286, 586.9565, 810.0, 927.4809, 974.5989, 991.3871, 997.1125, 999.0356, 999.6783], 1000.0, 7] | Failed |
| regression: slow approach | [[14.7059, 21.4286, 30.8219, 43.5484, 60.089, 80.4636, 103.9646, 129.1027, 153.9129, 176.5291, 195.7002, 210.9747], 500.0, None] | [[14.8515, 21.9512, 32.2196, 46.8208, 67.09, 94.3079, 129.2706, 171.709, 219.8186, 270.309, 319.1849, 362.9343], 500.0, None] | Failed |
| regression: start at capacity | [[1000.0, 1000.0, 1000.0, 1000.0], 1000.0, 0] | [[1000.0, 1000.0, 1000.0, 1000.0], 1000.0, 0] | Passed |
| regression: start within band | [[997.4937, 998.7453, 999.3723], 1000.0, 0] | [[997.4937, 998.7453, 999.3723], 1000.0, 0] | Passed |
| regression: replacement r0 one | [[166.6667, 142.8571, 125.0, 111.1111], 0.0, None] | [[200.0, 200.0, 200.0, 200.0], 0.0, None] | Failed |
| regression: declining r0 half | [[142.8571, 62.5, 29.4118, 14.2857, 7.0423, 3.4965, 1.7422, 0.8696], 0.0, 5] | [[250.0, 142.8571, 76.9231, 40.0, 20.4082, 10.3093, 5.1813, 2.5974], 0.0, 7] | Failed |
| control: invalid r0 | None | None | Passed |
SHA-256 / f6d3307b9fa3c2c023514081b944ced687e68a0c2566484153aac8383ec442b6
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(n0, r0, k, years):
if k <= 0 or r0 <= 0 or n0 < 0:
return None
eq = float(k) if r0 > 1 else 0.0
band = 0.01 * k
n = float(n0)
traj = []
hit = 0 if abs(n - eq) <= band else None
for year in range(1, years + 1):
n = r0 * n / (1 + r0 * n / k)
traj.append(round(n, 4))
if hit is None and abs(n - eq) <= band:
hit = year
return [traj, eq, hit]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: herring recruitment',
(50, 3.0, 1000, 10),
[[136.3636, 321.4286, 586.9565, 810.0, 927.4809, 974.5989, 991.3871, 997.1125, 999.0356, 999.6783],
1000.0,
7]),
('regression: slow approach',
(10, 1.5, 500, 12),
[[14.8515,
21.9512,
32.2196,
46.8208,
67.09,
94.3079,
129.2706,
171.709,
219.8186,
270.309,
319.1849,
362.9343],
500.0,
None]),
('regression: start at capacity', (1000, 2.0, 1000, 4), [[1000.0, 1000.0, 1000.0, 1000.0], 1000.0, 0]),
('regression: start within band', (995, 2.0, 1000, 3), [[997.4937, 998.7453, 999.3723], 1000.0, 0]),
('regression: replacement r0 one', (200, 1.0, 1000, 4), [[200.0, 200.0, 200.0, 200.0], 0.0, None]),
('regression: declining r0 half',
(400, 0.5, 1000, 8),
[[250.0, 142.8571, 76.9231, 40.0, 20.4082, 10.3093, 5.1813, 2.5974], 0.0, 7]),
('control: invalid r0', (100, 0.0, 1000, 5), None)],
[('regression: start within band', (995, 2.0, 1000, 3), [[997.4937, 998.7453, 999.3723], 1000.0, 0]),
('regression: replacement r0 one', (200, 1.0, 1000, 4), [[200.0, 200.0, 200.0, 200.0], 0.0, None]),
('regression: declining r0 half',
(400, 0.5, 1000, 8),
[[250.0, 142.8571, 76.9231, 40.0, 20.4082, 10.3093, 5.1813, 2.5974], 0.0, 7]),
('regression: above capacity',
(3000, 2.5, 1000, 6),
[[1363.6364, 1119.403, 1044.5682, 1017.363, 1006.8736, 1002.7381], 1000.0, 5]),
('control: invalid r0', (100, 0.0, 1000, 5), None),
('regression: never reaches band',
(1, 1.2, 10000, 5),
[[1.2, 1.4399, 1.7279, 2.0734, 2.4879], 10000.0, None]),
('regression: one year from band',
(985, 2.0, 1000, 4),
[[992.4433, 996.2073, 998.1001, 999.0491], 1000.0, 1])],
[('regression: herring recruitment',
(50, 3.0, 1000, 10),
[[136.3636, 321.4286, 586.9565, 810.0, 927.4809, 974.5989, 991.3871, 997.1125, 999.0356, 999.6783],
1000.0,
7]),
('regression: slow approach',
(10, 1.5, 500, 12),
[[14.8515,
21.9512,
32.2196,
46.8208,
67.09,
94.3079,
129.2706,
171.709,
219.8186,
270.309,
319.1849,
362.9343],
500.0,
None]),
('regression: above capacity',
(3000, 2.5, 1000, 6),
[[1363.6364, 1119.403, 1044.5682, 1017.363, 1006.8736, 1002.7381], 1000.0, 5]),
('control: invalid r0', (100, 0.0, 1000, 5), None),
('regression: never reaches band',
(1, 1.2, 10000, 5),
[[1.2, 1.4399, 1.7279, 2.0734, 2.4879], 10000.0, None]),
('regression: one year from band',
(985, 2.0, 1000, 4),
[[992.4433, 996.2073, 998.1001, 999.0491], 1000.0, 1]),
('regression: small capacity',
(2, 4.0, 20, 6),
[[6.1538, 12.8, 17.5342, 19.3208, 19.8258, 19.9562], 20.0, 5])],
[('regression: herring recruitment',
(50, 3.0, 1000, 10),
[[136.3636, 321.4286, 586.9565, 810.0, 927.4809, 974.5989, 991.3871, 997.1125, 999.0356, 999.6783],
1000.0,
7]),
('regression: slow approach',
(10, 1.5, 500, 12),
[[14.8515,
21.9512,
32.2196,
46.8208,
67.09,
94.3079,
129.2706,
171.709,
219.8186,
270.309,
319.1849,
362.9343],
500.0,
None]),
('regression: start at capacity', (1000, 2.0, 1000, 4), [[1000.0, 1000.0, 1000.0, 1000.0], 1000.0, 0]),
('regression: start within band', (995, 2.0, 1000, 3), [[997.4937, 998.7453, 999.3723], 1000.0, 0]),
('control: invalid r0', (100, 0.0, 1000, 5), None),
('regression: one year from band',
(985, 2.0, 1000, 4),
[[992.4433, 996.2073, 998.1001, 999.0491], 1000.0, 1]),
('regression: small capacity',
(2, 4.0, 20, 6),
[[6.1538, 12.8, 17.5342, 19.3208, 19.8258, 19.9562], 20.0, 5])],
[('regression: slow approach',
(10, 1.5, 500, 12),
[[14.8515,
21.9512,
32.2196,
46.8208,
67.09,
94.3079,
129.2706,
171.709,
219.8186,
270.309,
319.1849,
362.9343],
500.0,
None]),
('regression: start at capacity', (1000, 2.0, 1000, 4), [[1000.0, 1000.0, 1000.0, 1000.0], 1000.0, 0]),
('regression: start within band', (995, 2.0, 1000, 3), [[997.4937, 998.7453, 999.3723], 1000.0, 0]),
('regression: replacement r0 one', (200, 1.0, 1000, 4), [[200.0, 200.0, 200.0, 200.0], 0.0, None]),
('regression: declining r0 half',
(400, 0.5, 1000, 8),
[[250.0, 142.8571, 76.9231, 40.0, 20.4082, 10.3093, 5.1813, 2.5974], 0.0, 7]),
('regression: above capacity',
(3000, 2.5, 1000, 6),
[[1363.6364, 1119.403, 1044.5682, 1017.363, 1006.8736, 1002.7381], 1000.0, 5]),
('control: invalid r0', (100, 0.0, 1000, 5), None)]]
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: herring recruitment | [[130.4348, 281.25, 457.6271, 578.5714, 634.4648, 655.5755, 662.9282, 665.4158, 666.2492, 666.5275], 1000.0, None] | [[136.3636, 321.4286, 586.9565, 810.0, 927.4809, 974.5989, 991.3871, 997.1125, 999.0356, 999.6783], 1000.0, 7] | Failed |
| regression: slow approach | [[14.5631, 20.9302, 29.5405, 40.7035, 54.4111, 70.1636, 86.9444, 103.4369, 118.4111, 131.0598, 141.1087, 148.7101], 500.0, None] | [[14.8515, 21.9512, 32.2196, 46.8208, 67.09, 94.3079, 129.2706, 171.709, 219.8186, 270.309, 319.1849, 362.9343], 500.0, None] | Failed |
| regression: start at capacity | [[666.6667, 571.4286, 533.3333, 516.129], 1000.0, 0] | [[1000.0, 1000.0, 1000.0, 1000.0], 1000.0, 0] | Failed |
| regression: start within band | [[665.5518, 571.0187, 533.1547], 1000.0, 0] | [[997.4937, 998.7453, 999.3723], 1000.0, 0] | Failed |
| regression: replacement r0 one | [[166.6667, 142.8571, 125.0, 111.1111], 0.0, None] | [[200.0, 200.0, 200.0, 200.0], 0.0, None] | Failed |
| regression: declining r0 half | [[166.6667, 76.9231, 37.037, 18.1818, 9.009, 4.4843, 2.2371, 1.1173], 0.0, 5] | [[250.0, 142.8571, 76.9231, 40.0, 20.4082, 10.3093, 5.1813, 2.5974], 0.0, 7] | Failed |
| control: invalid r0 | None | None | Passed |
SHA-256 / 93e452af5adaf024329a95f012383f9aa14a37c4f23bd8992579d0467f9bbf45
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(n0, r0, k, years):
if k <= 0 or r0 <= 0 or n0 < 0:
return None
eq = float(k) if r0 > 1 else 0.0
band = 0.01 * k
n = float(n0)
traj = []
hit = 0 if abs(n - eq) <= band else None
for year in range(1, years + 1):
n = r0 * n / (1 + (r0 - 1) * n / k)
traj.append(round(n, 4))
if hit is None and abs(n - eq) <= band:
hit = year
return [traj, eq, hit]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: herring recruitment',
(50, 3.0, 1000, 10),
[[136.3636, 321.4286, 586.9565, 810.0, 927.4809, 974.5989, 991.3871, 997.1125, 999.0356, 999.6783],
1000.0,
7]),
('regression: slow approach',
(10, 1.5, 500, 12),
[[14.8515,
21.9512,
32.2196,
46.8208,
67.09,
94.3079,
129.2706,
171.709,
219.8186,
270.309,
319.1849,
362.9343],
500.0,
None]),
('regression: start at capacity', (1000, 2.0, 1000, 4), [[1000.0, 1000.0, 1000.0, 1000.0], 1000.0, 0]),
('regression: start within band', (995, 2.0, 1000, 3), [[997.4937, 998.7453, 999.3723], 1000.0, 0]),
('regression: replacement r0 one', (200, 1.0, 1000, 4), [[200.0, 200.0, 200.0, 200.0], 0.0, None]),
('regression: declining r0 half',
(400, 0.5, 1000, 8),
[[250.0, 142.8571, 76.9231, 40.0, 20.4082, 10.3093, 5.1813, 2.5974], 0.0, 7]),
('control: invalid r0', (100, 0.0, 1000, 5), None)],
[('regression: start within band', (995, 2.0, 1000, 3), [[997.4937, 998.7453, 999.3723], 1000.0, 0]),
('regression: replacement r0 one', (200, 1.0, 1000, 4), [[200.0, 200.0, 200.0, 200.0], 0.0, None]),
('regression: declining r0 half',
(400, 0.5, 1000, 8),
[[250.0, 142.8571, 76.9231, 40.0, 20.4082, 10.3093, 5.1813, 2.5974], 0.0, 7]),
('regression: above capacity',
(3000, 2.5, 1000, 6),
[[1363.6364, 1119.403, 1044.5682, 1017.363, 1006.8736, 1002.7381], 1000.0, 5]),
('control: invalid r0', (100, 0.0, 1000, 5), None),
('regression: never reaches band',
(1, 1.2, 10000, 5),
[[1.2, 1.4399, 1.7279, 2.0734, 2.4879], 10000.0, None]),
('regression: one year from band',
(985, 2.0, 1000, 4),
[[992.4433, 996.2073, 998.1001, 999.0491], 1000.0, 1])],
[('regression: herring recruitment',
(50, 3.0, 1000, 10),
[[136.3636, 321.4286, 586.9565, 810.0, 927.4809, 974.5989, 991.3871, 997.1125, 999.0356, 999.6783],
1000.0,
7]),
('regression: slow approach',
(10, 1.5, 500, 12),
[[14.8515,
21.9512,
32.2196,
46.8208,
67.09,
94.3079,
129.2706,
171.709,
219.8186,
270.309,
319.1849,
362.9343],
500.0,
None]),
('regression: above capacity',
(3000, 2.5, 1000, 6),
[[1363.6364, 1119.403, 1044.5682, 1017.363, 1006.8736, 1002.7381], 1000.0, 5]),
('control: invalid r0', (100, 0.0, 1000, 5), None),
('regression: never reaches band',
(1, 1.2, 10000, 5),
[[1.2, 1.4399, 1.7279, 2.0734, 2.4879], 10000.0, None]),
('regression: one year from band',
(985, 2.0, 1000, 4),
[[992.4433, 996.2073, 998.1001, 999.0491], 1000.0, 1]),
('regression: small capacity',
(2, 4.0, 20, 6),
[[6.1538, 12.8, 17.5342, 19.3208, 19.8258, 19.9562], 20.0, 5])],
[('regression: herring recruitment',
(50, 3.0, 1000, 10),
[[136.3636, 321.4286, 586.9565, 810.0, 927.4809, 974.5989, 991.3871, 997.1125, 999.0356, 999.6783],
1000.0,
7]),
('regression: slow approach',
(10, 1.5, 500, 12),
[[14.8515,
21.9512,
32.2196,
46.8208,
67.09,
94.3079,
129.2706,
171.709,
219.8186,
270.309,
319.1849,
362.9343],
500.0,
None]),
('regression: start at capacity', (1000, 2.0, 1000, 4), [[1000.0, 1000.0, 1000.0, 1000.0], 1000.0, 0]),
('regression: start within band', (995, 2.0, 1000, 3), [[997.4937, 998.7453, 999.3723], 1000.0, 0]),
('control: invalid r0', (100, 0.0, 1000, 5), None),
('regression: one year from band',
(985, 2.0, 1000, 4),
[[992.4433, 996.2073, 998.1001, 999.0491], 1000.0, 1]),
('regression: small capacity',
(2, 4.0, 20, 6),
[[6.1538, 12.8, 17.5342, 19.3208, 19.8258, 19.9562], 20.0, 5])],
[('regression: slow approach',
(10, 1.5, 500, 12),
[[14.8515,
21.9512,
32.2196,
46.8208,
67.09,
94.3079,
129.2706,
171.709,
219.8186,
270.309,
319.1849,
362.9343],
500.0,
None]),
('regression: start at capacity', (1000, 2.0, 1000, 4), [[1000.0, 1000.0, 1000.0, 1000.0], 1000.0, 0]),
('regression: start within band', (995, 2.0, 1000, 3), [[997.4937, 998.7453, 999.3723], 1000.0, 0]),
('regression: replacement r0 one', (200, 1.0, 1000, 4), [[200.0, 200.0, 200.0, 200.0], 0.0, None]),
('regression: declining r0 half',
(400, 0.5, 1000, 8),
[[250.0, 142.8571, 76.9231, 40.0, 20.4082, 10.3093, 5.1813, 2.5974], 0.0, 7]),
('regression: above capacity',
(3000, 2.5, 1000, 6),
[[1363.6364, 1119.403, 1044.5682, 1017.363, 1006.8736, 1002.7381], 1000.0, 5]),
('control: invalid r0', (100, 0.0, 1000, 5), None)]]
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: herring recruitment | [[136.3636, 321.4286, 586.9565, 810.0, 927.4809, 974.5989, 991.3871, 997.1125, 999.0356, 999.6783], 1000.0, 7] | [[136.3636, 321.4286, 586.9565, 810.0, 927.4809, 974.5989, 991.3871, 997.1125, 999.0356, 999.6783], 1000.0, 7] | Passed |
| regression: slow approach | [[14.8515, 21.9512, 32.2196, 46.8208, 67.09, 94.3079, 129.2706, 171.709, 219.8186, 270.309, 319.1849, 362.9343], 500.0, None] | [[14.8515, 21.9512, 32.2196, 46.8208, 67.09, 94.3079, 129.2706, 171.709, 219.8186, 270.309, 319.1849, 362.9343], 500.0, None] | Passed |
| regression: start at capacity | [[1000.0, 1000.0, 1000.0, 1000.0], 1000.0, 0] | [[1000.0, 1000.0, 1000.0, 1000.0], 1000.0, 0] | Passed |
| regression: start within band | [[997.4937, 998.7453, 999.3723], 1000.0, 0] | [[997.4937, 998.7453, 999.3723], 1000.0, 0] | Passed |
| regression: replacement r0 one | [[200.0, 200.0, 200.0, 200.0], 0.0, None] | [[200.0, 200.0, 200.0, 200.0], 0.0, None] | Passed |
| regression: declining r0 half | [[250.0, 142.8571, 76.9231, 40.0, 20.4082, 10.3093, 5.1813, 2.5974], 0.0, 7] | [[250.0, 142.8571, 76.9231, 40.0, 20.4082, 10.3093, 5.1813, 2.5974], 0.0, 7] | Passed |
| control: invalid r0 | None | None | Passed |
SHA-256 / 7f5c8ecbbfdd4b3b3c5ed7e233fc2a862b48961d0c94c01a4f144df99aa495ec
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:33.378907+00:00.
Case digest / 2ebc0c240e46af04fe5cd6fffe5efea087eb0386452cab34e7629dcf91755814