FA-64966 / Epidemic compartment models / Open access
SIRS waning-immunity simulation: waning source · case 01
People recovering today already lose immunity in the same step.
ROOT CAUSE
The waning flow includes the same-day recoveries rather than start-of-day R.
THE FAILURE
The waning flow includes the same-day recoveries rather than start-of-day R.
Unsuccessful approach: Frequency-scaling the waning flow by S/pop has no basis in a per-capita loss rate.
Case contract
Daily forward-Euler SIRS; waning flow is R/immunity_days back to S (immunity_days 0 means permanent immunity); cumulative incidence sums every S->I flow including reinfections; return [S, I, R, cumulative incidence] rounded to 3.
Why this case matters
Compartmental epidemic calculations drive outbreak forecasts, vaccine targets and hospital planning; a single wrong flow, rate conversion or boundary silently changes every downstream number.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(beta, gamma, immunity_days, pop, i0, days):
s, i, r = float(pop - i0), float(i0), 0.0
cumulative = 0.0
for _ in range(days):
inf = beta * s * i / pop
rec = gamma * i
wane = (r + rec) / immunity_days if immunity_days > 0 else 0.0
s += wane - inf
i += inf - rec
r += rec - wane
cumulative += inf
return [round(s, 3), round(i, 3), round(r, 3), round(cumulative, 3)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: seasonal coronavirus', (0.4, 0.2, 30, 1000, 5, 80), [543.377, 58.225, 398.398, 1339.789]),
('control: permanent immunity sentinel', (0.5, 0.2, 0, 500, 5, 40), [48.675, 7.802, 443.523, 446.325]),
('regression: short immunity endemic', (0.6, 0.25, 10, 800, 8, 100), [333.272, 133.331, 333.396, 3385.33]),
('control: boundary zero days', (0.4, 0.2, 30, 100, 5, 0), [95.0, 5.0, 0.0, 0.0]),
('regression: no transmission waning only', (0.0, 0.3, 5, 100, 50, 20), [98.35, 0.04, 1.61, 0.0]),
('regression: long immunity single wave',
(0.5, 0.1, 365, 2000, 10, 120),
[376.102, 3.345, 1620.554, 2084.424]),
('regression: one day immunity', (0.5, 0.3, 1, 300, 3, 30), [188.175, 86.35, 25.475, 420.744])],
[('regression: seasonal coronavirus', (0.4, 0.2, 30, 1000, 5, 80), [543.377, 58.225, 398.398, 1339.789]),
('control: permanent immunity sentinel', (0.5, 0.2, 0, 500, 5, 40), [48.675, 7.802, 443.523, 446.325]),
('control: boundary zero days', (0.4, 0.2, 30, 100, 5, 0), [95.0, 5.0, 0.0, 0.0]),
('regression: no transmission waning only', (0.0, 0.3, 5, 100, 50, 20), [98.35, 0.04, 1.61, 0.0]),
('regression: long immunity single wave',
(0.5, 0.1, 365, 2000, 10, 120),
[376.102, 3.345, 1620.554, 2084.424]),
('regression: one day immunity', (0.5, 0.3, 1, 300, 3, 30), [188.175, 86.35, 25.475, 420.744]),
('regression: two week run', (0.9, 0.3, 20, 400, 4, 14), [58.25, 94.786, 246.964, 386.248])],
[('regression: seasonal coronavirus', (0.4, 0.2, 30, 1000, 5, 80), [543.377, 58.225, 398.398, 1339.789]),
('control: permanent immunity sentinel', (0.5, 0.2, 0, 500, 5, 40), [48.675, 7.802, 443.523, 446.325]),
('regression: short immunity endemic', (0.6, 0.25, 10, 800, 8, 100), [333.272, 133.331, 333.396, 3385.33]),
('control: boundary zero days', (0.4, 0.2, 30, 100, 5, 0), [95.0, 5.0, 0.0, 0.0]),
('regression: no transmission waning only', (0.0, 0.3, 5, 100, 50, 20), [98.35, 0.04, 1.61, 0.0]),
('regression: one day immunity', (0.5, 0.3, 1, 300, 3, 30), [188.175, 86.35, 25.475, 420.744]),
('regression: two week run', (0.9, 0.3, 20, 400, 4, 14), [58.25, 94.786, 246.964, 386.248])],
[('control: permanent immunity sentinel', (0.5, 0.2, 0, 500, 5, 40), [48.675, 7.802, 443.523, 446.325]),
('regression: short immunity endemic', (0.6, 0.25, 10, 800, 8, 100), [333.272, 133.331, 333.396, 3385.33]),
('control: boundary zero days', (0.4, 0.2, 30, 100, 5, 0), [95.0, 5.0, 0.0, 0.0]),
('regression: no transmission waning only', (0.0, 0.3, 5, 100, 50, 20), [98.35, 0.04, 1.61, 0.0]),
('regression: long immunity single wave',
(0.5, 0.1, 365, 2000, 10, 120),
[376.102, 3.345, 1620.554, 2084.424]),
('regression: one day immunity', (0.5, 0.3, 1, 300, 3, 30), [188.175, 86.35, 25.475, 420.744]),
('regression: two week run', (0.9, 0.3, 20, 400, 4, 14), [58.25, 94.786, 246.964, 386.248])],
[('regression: seasonal coronavirus', (0.4, 0.2, 30, 1000, 5, 80), [543.377, 58.225, 398.398, 1339.789]),
('control: permanent immunity sentinel', (0.5, 0.2, 0, 500, 5, 40), [48.675, 7.802, 443.523, 446.325]),
('control: boundary zero days', (0.4, 0.2, 30, 100, 5, 0), [95.0, 5.0, 0.0, 0.0]),
('regression: no transmission waning only', (0.0, 0.3, 5, 100, 50, 20), [98.35, 0.04, 1.61, 0.0]),
('regression: long immunity single wave',
(0.5, 0.1, 365, 2000, 10, 120),
[376.102, 3.345, 1620.554, 2084.424]),
('regression: one day immunity', (0.5, 0.3, 1, 300, 3, 30), [188.175, 86.35, 25.475, 420.744]),
('regression: two week run', (0.9, 0.3, 20, 400, 4, 14), [58.25, 94.786, 246.964, 386.248])]]
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: seasonal coronavirus | [541.47, 60.145, 398.384, 1377.12] | [543.377, 58.225, 398.398, 1339.789] | Failed |
| control: permanent immunity sentinel | [48.675, 7.802, 443.523, 446.325] | [48.675, 7.802, 443.523, 446.325] | Passed |
| regression: short immunity endemic | [333.288, 143.595, 323.117, 3630.408] | [333.272, 133.331, 333.396, 3385.33] | Failed |
| control: boundary zero days | [95.0, 5.0, 0.0, 0.0] | [95.0, 5.0, 0.0, 0.0] | Passed |
| regression: no transmission waning only | [98.672, 0.04, 1.288, 0.0] | [98.35, 0.04, 1.61, 0.0] | Failed |
| regression: long immunity single wave | [376.367, 3.401, 1620.232, 2089.589] | [376.102, 3.345, 1620.554, 2084.424] | Failed |
| regression: one day immunity | [191.879, 108.121, 0.0, 491.595] | [188.175, 86.35, 25.475, 420.744] | Failed |
SHA-256 / c365fbb29f4b39d09b5db285b8f4480950181595518c0b04cefc35b6d1b317e7
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(beta, gamma, immunity_days, pop, i0, days):
s, i, r = float(pop - i0), float(i0), 0.0
cumulative = 0.0
for _ in range(days):
inf = beta * s * i / pop
rec = gamma * i
wane = r * s / pop / immunity_days if immunity_days > 0 else 0.0
s += wane - inf
i += inf - rec
r += rec - wane
cumulative += inf
return [round(s, 3), round(i, 3), round(r, 3), round(cumulative, 3)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: seasonal coronavirus', (0.4, 0.2, 30, 1000, 5, 80), [543.377, 58.225, 398.398, 1339.789]),
('control: permanent immunity sentinel', (0.5, 0.2, 0, 500, 5, 40), [48.675, 7.802, 443.523, 446.325]),
('regression: short immunity endemic', (0.6, 0.25, 10, 800, 8, 100), [333.272, 133.331, 333.396, 3385.33]),
('control: boundary zero days', (0.4, 0.2, 30, 100, 5, 0), [95.0, 5.0, 0.0, 0.0]),
('regression: no transmission waning only', (0.0, 0.3, 5, 100, 50, 20), [98.35, 0.04, 1.61, 0.0]),
('regression: long immunity single wave',
(0.5, 0.1, 365, 2000, 10, 120),
[376.102, 3.345, 1620.554, 2084.424]),
('regression: one day immunity', (0.5, 0.3, 1, 300, 3, 30), [188.175, 86.35, 25.475, 420.744])],
[('regression: seasonal coronavirus', (0.4, 0.2, 30, 1000, 5, 80), [543.377, 58.225, 398.398, 1339.789]),
('control: permanent immunity sentinel', (0.5, 0.2, 0, 500, 5, 40), [48.675, 7.802, 443.523, 446.325]),
('control: boundary zero days', (0.4, 0.2, 30, 100, 5, 0), [95.0, 5.0, 0.0, 0.0]),
('regression: no transmission waning only', (0.0, 0.3, 5, 100, 50, 20), [98.35, 0.04, 1.61, 0.0]),
('regression: long immunity single wave',
(0.5, 0.1, 365, 2000, 10, 120),
[376.102, 3.345, 1620.554, 2084.424]),
('regression: one day immunity', (0.5, 0.3, 1, 300, 3, 30), [188.175, 86.35, 25.475, 420.744]),
('regression: two week run', (0.9, 0.3, 20, 400, 4, 14), [58.25, 94.786, 246.964, 386.248])],
[('regression: seasonal coronavirus', (0.4, 0.2, 30, 1000, 5, 80), [543.377, 58.225, 398.398, 1339.789]),
('control: permanent immunity sentinel', (0.5, 0.2, 0, 500, 5, 40), [48.675, 7.802, 443.523, 446.325]),
('regression: short immunity endemic', (0.6, 0.25, 10, 800, 8, 100), [333.272, 133.331, 333.396, 3385.33]),
('control: boundary zero days', (0.4, 0.2, 30, 100, 5, 0), [95.0, 5.0, 0.0, 0.0]),
('regression: no transmission waning only', (0.0, 0.3, 5, 100, 50, 20), [98.35, 0.04, 1.61, 0.0]),
('regression: one day immunity', (0.5, 0.3, 1, 300, 3, 30), [188.175, 86.35, 25.475, 420.744]),
('regression: two week run', (0.9, 0.3, 20, 400, 4, 14), [58.25, 94.786, 246.964, 386.248])],
[('control: permanent immunity sentinel', (0.5, 0.2, 0, 500, 5, 40), [48.675, 7.802, 443.523, 446.325]),
('regression: short immunity endemic', (0.6, 0.25, 10, 800, 8, 100), [333.272, 133.331, 333.396, 3385.33]),
('control: boundary zero days', (0.4, 0.2, 30, 100, 5, 0), [95.0, 5.0, 0.0, 0.0]),
('regression: no transmission waning only', (0.0, 0.3, 5, 100, 50, 20), [98.35, 0.04, 1.61, 0.0]),
('regression: long immunity single wave',
(0.5, 0.1, 365, 2000, 10, 120),
[376.102, 3.345, 1620.554, 2084.424]),
('regression: one day immunity', (0.5, 0.3, 1, 300, 3, 30), [188.175, 86.35, 25.475, 420.744]),
('regression: two week run', (0.9, 0.3, 20, 400, 4, 14), [58.25, 94.786, 246.964, 386.248])],
[('regression: seasonal coronavirus', (0.4, 0.2, 30, 1000, 5, 80), [543.377, 58.225, 398.398, 1339.789]),
('control: permanent immunity sentinel', (0.5, 0.2, 0, 500, 5, 40), [48.675, 7.802, 443.523, 446.325]),
('control: boundary zero days', (0.4, 0.2, 30, 100, 5, 0), [95.0, 5.0, 0.0, 0.0]),
('regression: no transmission waning only', (0.0, 0.3, 5, 100, 50, 20), [98.35, 0.04, 1.61, 0.0]),
('regression: long immunity single wave',
(0.5, 0.1, 365, 2000, 10, 120),
[376.102, 3.345, 1620.554, 2084.424]),
('regression: one day immunity', (0.5, 0.3, 1, 300, 3, 30), [188.175, 86.35, 25.475, 420.744]),
('regression: two week run', (0.9, 0.3, 20, 400, 4, 14), [58.25, 94.786, 246.964, 386.248])]]
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: seasonal coronavirus | [442.81, 5.347, 551.843, 956.358] | [543.377, 58.225, 398.398, 1339.789] | Failed |
| control: permanent immunity sentinel | [48.675, 7.802, 443.523, 446.325] | [48.675, 7.802, 443.523, 446.325] | Passed |
| regression: short immunity endemic | [346.394, 37.703, 415.903, 1791.824] | [333.272, 133.331, 333.396, 3385.33] | Failed |
| control: boundary zero days | [95.0, 5.0, 0.0, 0.0] | [95.0, 5.0, 0.0, 0.0] | Passed |
| regression: no transmission waning only | [96.842, 0.04, 3.118, 0.0] | [98.35, 0.04, 1.61, 0.0] | Failed |
| regression: long immunity single wave | [11.123, 0.047, 1988.83, 1986.335] | [376.102, 3.345, 1620.554, 2084.424] | Failed |
| regression: one day immunity | [183.354, 79.113, 37.533, 403.097] | [188.175, 86.35, 25.475, 420.744] | Failed |
SHA-256 / a46da19fb18b106162a17a8d03869a51e1c221fb45b2237152474052758a6ab7
HELD IN THE MEMBER ARCHIVE
The verified repair and its recorded checks are member-only.
This mechanism has 7 recorded checks per implementation. The open-access tier publishes the failure and the unsuccessful fix; the repaired source that passes every check, and the observations that prove it, are available to members.
Every case sharing this mechanism uses the same contract and the same repair, so this one record is held back for all of them.
Member access is invitation-based. Sign in with your invited account to inspect the repair.
Sign in to the archive ↗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:29.531639+00:00.
Case digest / 1def2098c907dd615f55ccc5a5de232ea0d34319c8ecd72a50e59d750f65a482