FA-65396 / Ecological population dynamics / Open access
Beverton-Holt recruitment convergence: band scale · case 01
Convergence is almost never detected for large stocks.
ROOT CAUSE
The 1% band is treated as an absolute number of individuals.
VERIFIED REPAIR
Restore the band scale rule: `band = 0.01 * k`.
Unsuccessful approach: Scaling the band by the initial stock makes convergence depend on the starting point.
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
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]),
('control: 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]),
('control: 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: 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])],
[('regression: start within band', (995, 2.0, 1000, 3), [[997.4937, 998.7453, 999.3723], 1000.0, 0]),
('control: 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),
('control: 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]),
('control: 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),
('control: 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]),
('control: 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]),
('control: 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: replacement r0 one', (200, 1.0, 1000, 4), [[200.0, 200.0, 200.0, 200.0], 0.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])],
[('control: 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]),
('control: 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: 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, 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 |
| control: 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 |
| control: 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, None] | [[997.4937, 998.7453, 999.3723], 1000.0, 0] | Failed |
| control: 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, None] | [[250.0, 142.8571, 76.9231, 40.0, 20.4082, 10.3093, 5.1813, 2.5974], 0.0, 7] | Failed |
| regression: above capacity | [[1363.6364, 1119.403, 1044.5682, 1017.363, 1006.8736, 1002.7381], 1000.0, None] | [[1363.6364, 1119.403, 1044.5682, 1017.363, 1006.8736, 1002.7381], 1000.0, 5] | Failed |
SHA-256 / cf2262f82da3f1e6b5bfa9785997fd1031f978e292716713de2847d3edad70e1
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 * n0
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]),
('control: 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]),
('control: 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: 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])],
[('regression: start within band', (995, 2.0, 1000, 3), [[997.4937, 998.7453, 999.3723], 1000.0, 0]),
('control: 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),
('control: 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]),
('control: 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),
('control: 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]),
('control: 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]),
('control: 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: replacement r0 one', (200, 1.0, 1000, 4), [[200.0, 200.0, 200.0, 200.0], 0.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])],
[('control: 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]),
('control: 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: 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, 10] | [[136.3636, 321.4286, 586.9565, 810.0, 927.4809, 974.5989, 991.3871, 997.1125, 999.0356, 999.6783], 1000.0, 7] | Failed |
| control: 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 |
| control: 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 |
| control: 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, 8] | [[250.0, 142.8571, 76.9231, 40.0, 20.4082, 10.3093, 5.1813, 2.5974], 0.0, 7] | Failed |
| regression: above capacity | [[1363.6364, 1119.403, 1044.5682, 1017.363, 1006.8736, 1002.7381], 1000.0, 4] | [[1363.6364, 1119.403, 1044.5682, 1017.363, 1006.8736, 1002.7381], 1000.0, 5] | Failed |
SHA-256 / d76a5c134cd34a8f7510fc6c4b1e5ab3997cdfce27b76a221856f12f4a5d5610
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]),
('control: 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]),
('control: 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: 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])],
[('regression: start within band', (995, 2.0, 1000, 3), [[997.4937, 998.7453, 999.3723], 1000.0, 0]),
('control: 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),
('control: 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]),
('control: 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),
('control: 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]),
('control: 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]),
('control: 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: replacement r0 one', (200, 1.0, 1000, 4), [[200.0, 200.0, 200.0, 200.0], 0.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])],
[('control: 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]),
('control: 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: 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 |
| control: 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 |
| control: 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 |
| control: 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 |
| regression: above capacity | [[1363.6364, 1119.403, 1044.5682, 1017.363, 1006.8736, 1002.7381], 1000.0, 5] | [[1363.6364, 1119.403, 1044.5682, 1017.363, 1006.8736, 1002.7381], 1000.0, 5] | Passed |
SHA-256 / 382166950ec8014be1c74d30b7166c3712227f09745b6e40435d7e46a4b895e2
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.471858+00:00.
Case digest / fffc49f3d78984467200cd7c8e603168b93017bb1d36e9be1b4851b91520482a