FA-71196 / Weather index computation / Open access
K-index and Total Totals: 700 hPa depression sign · case 01
Dry mid-levels increase the K-index instead of suppressing it.
ROOT CAUSE
The 700 hPa dew-point depression is added.
VERIFIED REPAIR
Subtract T700 - Td700.
Unsuccessful approach: Reversing the depression inside the parentheses leaves the same wrong sign.
Case contract
K = (T850 - T500) + Td850 - (T700 - Td700); VT = T850 - T500; CT = Td850 - T500; TT = VT + CT. Thunderstorm potential from K: <20 none, <=25 isolated, <=30 widely scattered, <=35 scattered, else numerous. Severe flag "severe possible" when TT >= 50 else "weak". Return [K, TT, potential, flag].
Why this case matters
Convective outlooks use K and TT as quick stability screens.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(t850, td850, t700, td700, t500):
k = (t850 - t500) + td850 + (t700 - td700)
vt = t850 - t500
ct = td850 - t500
tt = vt + ct
if k < 20:
pot = "none"
elif k <= 25:
pot = "isolated"
elif k <= 30:
pot = "widely scattered"
elif k <= 35:
pot = "scattered"
else:
pot = "numerous"
sev = "severe possible" if tt >= 50 else "weak"
return [k, tt, pot, sev]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['sounding 850 21/8 700 11/0 500 -3', [21, 8, 11, 0, -3], [21, 35, 'isolated', 'weak']], ['sounding 850 10/2 700 3/3 500 -10', [10, 2, 3, 3, -10], [22, 32, 'isolated', 'weak']], ['sounding 850 17/4 700 7/-9 500 -15', [17, 4, 7, -9, -15], [20, 51, 'isolated', 'severe possible']], ['sounding 850 15/3 700 7/-10 500 -3', [15, 3, 7, -10, -3], [4, 24, 'none', 'weak']], ['sounding 850 9/3 700 1/-16 500 -17', [9, 3, 1, -16, -17], [12, 46, 'none', 'weak']], ['sounding 850 26/20 700 15/-2 500 4', [26, 20, 15, -2, 4], [25, 38, 'isolated', 'weak']], ['sounding 850 25/23 700 15/2 500 4', [25, 23, 15, 2, 4], [31, 40, 'scattered', 'weak']], ['sounding 850 21/6 700 5/-14 500 -7', [21, 6, 5, -14, -7], [15, 41, 'none', 'weak']]], [['sounding 850 9/3 700 1/-16 500 -17', [9, 3, 1, -16, -17], [12, 46, 'none', 'weak']], ['sounding 850 21/6 700 5/-14 500 -7', [21, 6, 5, -14, -7], [15, 41, 'none', 'weak']], ['sounding 850 26/13 700 12/2 500 2', [26, 13, 12, 2, 2], [27, 35, 'widely scattered', 'weak']], ['sounding 850 18/7 700 3/2 500 -19', [18, 7, 3, 2, -19], [43, 63, 'numerous', 'severe possible']], ['sounding 850 16/15 700 3/-8 500 -16', [16, 15, 3, -8, -16], [36, 63, 'numerous', 'severe possible']], ['sounding 850 5/-7 700 -4/-7 500 -22', [5, -7, -4, -7, -22], [17, 42, 'none', 'weak']], ['sounding 850 11/4 700 -3/-14 500 -13', [11, 4, -3, -14, -13], [17, 41, 'none', 'weak']], ['sounding 850 13/11 700 3/-3 500 -18', [13, 11, 3, -3, -18], [36, 60, 'numerous', 'severe possible']]], [['sounding 850 21/6 700 5/-14 500 -7', [21, 6, 5, -14, -7], [15, 41, 'none', 'weak']], ['sounding 850 11/4 700 -3/-14 500 -13', [11, 4, -3, -14, -13], [17, 41, 'none', 'weak']], ['sounding 850 24/20 700 14/5 500 -1', [24, 20, 14, 5, -1], [36, 46, 'numerous', 'weak']], ['sounding 850 15/10 700 4/1 500 -15', [15, 10, 4, 1, -15], [37, 55, 'numerous', 'severe possible']], ['sounding 850 23/15 700 12/12 500 2', [23, 15, 12, 12, 2], [36, 34, 'numerous', 'weak']], ['sounding 850 16/16 700 3/-5 500 -14', [16, 16, 3, -5, -14], [38, 60, 'numerous', 'severe possible']], ['sounding 850 25/24 700 16/7 500 2', [25, 24, 16, 7, 2], [38, 45, 'numerous', 'weak']], ['sounding 850 7/-8 700 1/-18 500 -18', [7, -8, 1, -18, -18], [-2, 35, 'none', 'weak']]], [['sounding 850 16/15 700 3/-8 500 -16', [16, 15, 3, -8, -16], [36, 63, 'numerous', 'severe possible']], ['sounding 850 25/24 700 16/7 500 2', [25, 24, 16, 7, 2], [38, 45, 'numerous', 'weak']], ['sounding 850 23/11 700 15/9 500 1', [23, 11, 15, 9, 1], [27, 32, 'widely scattered', 'weak']], ['sounding 850 9/6 700 0/-1 500 -18', [9, 6, 0, -1, -18], [32, 51, 'scattered', 'severe possible']], ['sounding 850 14/4 700 3/2 500 -9', [14, 4, 3, 2, -9], [26, 36, 'widely scattered', 'weak']], ['sounding 850 18/16 700 8/0 500 -12', [18, 16, 8, 0, -12], [38, 58, 'numerous', 'severe possible']], ['sounding 850 17/2 700 10/-7 500 -1', [17, 2, 10, -7, -1], [3, 21, 'none', 'weak']], ['sounding 850 22/15 700 13/-4 500 -1', [22, 15, 13, -4, -1], [21, 39, 'isolated', 'weak']]], [['sounding 850 13/11 700 3/-3 500 -18', [13, 11, 3, -3, -18], [36, 60, 'numerous', 'severe possible']], ['sounding 850 14/4 700 3/2 500 -9', [14, 4, 3, 2, -9], [26, 36, 'widely scattered', 'weak']], ['sounding 850 20/8 700 7/0 500 -11', [20, 8, 7, 0, -11], [32, 50, 'scattered', 'severe possible']], ['sounding 850 18/4 700 11/-3 500 -11', [18, 4, 11, -3, -11], [19, 44, 'none', 'weak']], ['sounding 850 11/4 700 -2/-12 500 -15', [11, 4, -2, -12, -15], [20, 45, 'isolated', 'weak']], ['sounding 850 16/16 700 1/-17 500 -17', [16, 16, 1, -17, -17], [31, 66, 'scattered', 'severe possible']], ['sounding 850 18/17 700 7/-11 500 -5', [18, 17, 7, -11, -5], [22, 45, 'isolated', 'weak']], ['sounding 850 22/15 700 7/-3 500 -8', [22, 15, 7, -3, -8], [35, 53, 'scattered', 'severe possible']]]]
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 |
|---|---|---|---|
| sounding 850 21/8 700 11/0 500 -3 | [43, 35, 'numerous', 'weak'] | [21, 35, 'isolated', 'weak'] | Failed |
| sounding 850 10/2 700 3/3 500 -10 | [22, 32, 'isolated', 'weak'] | [22, 32, 'isolated', 'weak'] | Passed |
| sounding 850 17/4 700 7/-9 500 -15 | [52, 51, 'numerous', 'severe possible'] | [20, 51, 'isolated', 'severe possible'] | Failed |
| sounding 850 15/3 700 7/-10 500 -3 | [38, 24, 'numerous', 'weak'] | [4, 24, 'none', 'weak'] | Failed |
| sounding 850 9/3 700 1/-16 500 -17 | [46, 46, 'numerous', 'weak'] | [12, 46, 'none', 'weak'] | Failed |
| sounding 850 26/20 700 15/-2 500 4 | [59, 38, 'numerous', 'weak'] | [25, 38, 'isolated', 'weak'] | Failed |
| sounding 850 25/23 700 15/2 500 4 | [57, 40, 'numerous', 'weak'] | [31, 40, 'scattered', 'weak'] | Failed |
| sounding 850 21/6 700 5/-14 500 -7 | [53, 41, 'numerous', 'weak'] | [15, 41, 'none', 'weak'] | Failed |
SHA-256 / 9362289d07ba4b167f71b0e1e84d76735c2da3eed3a2c9c9ed4487071d49fad5
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(t850, td850, t700, td700, t500):
k = (t850 - t500) + td850 - (td700 - t700)
vt = t850 - t500
ct = td850 - t500
tt = vt + ct
if k < 20:
pot = "none"
elif k <= 25:
pot = "isolated"
elif k <= 30:
pot = "widely scattered"
elif k <= 35:
pot = "scattered"
else:
pot = "numerous"
sev = "severe possible" if tt >= 50 else "weak"
return [k, tt, pot, sev]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['sounding 850 21/8 700 11/0 500 -3', [21, 8, 11, 0, -3], [21, 35, 'isolated', 'weak']], ['sounding 850 10/2 700 3/3 500 -10', [10, 2, 3, 3, -10], [22, 32, 'isolated', 'weak']], ['sounding 850 17/4 700 7/-9 500 -15', [17, 4, 7, -9, -15], [20, 51, 'isolated', 'severe possible']], ['sounding 850 15/3 700 7/-10 500 -3', [15, 3, 7, -10, -3], [4, 24, 'none', 'weak']], ['sounding 850 9/3 700 1/-16 500 -17', [9, 3, 1, -16, -17], [12, 46, 'none', 'weak']], ['sounding 850 26/20 700 15/-2 500 4', [26, 20, 15, -2, 4], [25, 38, 'isolated', 'weak']], ['sounding 850 25/23 700 15/2 500 4', [25, 23, 15, 2, 4], [31, 40, 'scattered', 'weak']], ['sounding 850 21/6 700 5/-14 500 -7', [21, 6, 5, -14, -7], [15, 41, 'none', 'weak']]], [['sounding 850 9/3 700 1/-16 500 -17', [9, 3, 1, -16, -17], [12, 46, 'none', 'weak']], ['sounding 850 21/6 700 5/-14 500 -7', [21, 6, 5, -14, -7], [15, 41, 'none', 'weak']], ['sounding 850 26/13 700 12/2 500 2', [26, 13, 12, 2, 2], [27, 35, 'widely scattered', 'weak']], ['sounding 850 18/7 700 3/2 500 -19', [18, 7, 3, 2, -19], [43, 63, 'numerous', 'severe possible']], ['sounding 850 16/15 700 3/-8 500 -16', [16, 15, 3, -8, -16], [36, 63, 'numerous', 'severe possible']], ['sounding 850 5/-7 700 -4/-7 500 -22', [5, -7, -4, -7, -22], [17, 42, 'none', 'weak']], ['sounding 850 11/4 700 -3/-14 500 -13', [11, 4, -3, -14, -13], [17, 41, 'none', 'weak']], ['sounding 850 13/11 700 3/-3 500 -18', [13, 11, 3, -3, -18], [36, 60, 'numerous', 'severe possible']]], [['sounding 850 21/6 700 5/-14 500 -7', [21, 6, 5, -14, -7], [15, 41, 'none', 'weak']], ['sounding 850 11/4 700 -3/-14 500 -13', [11, 4, -3, -14, -13], [17, 41, 'none', 'weak']], ['sounding 850 24/20 700 14/5 500 -1', [24, 20, 14, 5, -1], [36, 46, 'numerous', 'weak']], ['sounding 850 15/10 700 4/1 500 -15', [15, 10, 4, 1, -15], [37, 55, 'numerous', 'severe possible']], ['sounding 850 23/15 700 12/12 500 2', [23, 15, 12, 12, 2], [36, 34, 'numerous', 'weak']], ['sounding 850 16/16 700 3/-5 500 -14', [16, 16, 3, -5, -14], [38, 60, 'numerous', 'severe possible']], ['sounding 850 25/24 700 16/7 500 2', [25, 24, 16, 7, 2], [38, 45, 'numerous', 'weak']], ['sounding 850 7/-8 700 1/-18 500 -18', [7, -8, 1, -18, -18], [-2, 35, 'none', 'weak']]], [['sounding 850 16/15 700 3/-8 500 -16', [16, 15, 3, -8, -16], [36, 63, 'numerous', 'severe possible']], ['sounding 850 25/24 700 16/7 500 2', [25, 24, 16, 7, 2], [38, 45, 'numerous', 'weak']], ['sounding 850 23/11 700 15/9 500 1', [23, 11, 15, 9, 1], [27, 32, 'widely scattered', 'weak']], ['sounding 850 9/6 700 0/-1 500 -18', [9, 6, 0, -1, -18], [32, 51, 'scattered', 'severe possible']], ['sounding 850 14/4 700 3/2 500 -9', [14, 4, 3, 2, -9], [26, 36, 'widely scattered', 'weak']], ['sounding 850 18/16 700 8/0 500 -12', [18, 16, 8, 0, -12], [38, 58, 'numerous', 'severe possible']], ['sounding 850 17/2 700 10/-7 500 -1', [17, 2, 10, -7, -1], [3, 21, 'none', 'weak']], ['sounding 850 22/15 700 13/-4 500 -1', [22, 15, 13, -4, -1], [21, 39, 'isolated', 'weak']]], [['sounding 850 13/11 700 3/-3 500 -18', [13, 11, 3, -3, -18], [36, 60, 'numerous', 'severe possible']], ['sounding 850 14/4 700 3/2 500 -9', [14, 4, 3, 2, -9], [26, 36, 'widely scattered', 'weak']], ['sounding 850 20/8 700 7/0 500 -11', [20, 8, 7, 0, -11], [32, 50, 'scattered', 'severe possible']], ['sounding 850 18/4 700 11/-3 500 -11', [18, 4, 11, -3, -11], [19, 44, 'none', 'weak']], ['sounding 850 11/4 700 -2/-12 500 -15', [11, 4, -2, -12, -15], [20, 45, 'isolated', 'weak']], ['sounding 850 16/16 700 1/-17 500 -17', [16, 16, 1, -17, -17], [31, 66, 'scattered', 'severe possible']], ['sounding 850 18/17 700 7/-11 500 -5', [18, 17, 7, -11, -5], [22, 45, 'isolated', 'weak']], ['sounding 850 22/15 700 7/-3 500 -8', [22, 15, 7, -3, -8], [35, 53, 'scattered', 'severe possible']]]]
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 |
|---|---|---|---|
| sounding 850 21/8 700 11/0 500 -3 | [43, 35, 'numerous', 'weak'] | [21, 35, 'isolated', 'weak'] | Failed |
| sounding 850 10/2 700 3/3 500 -10 | [22, 32, 'isolated', 'weak'] | [22, 32, 'isolated', 'weak'] | Passed |
| sounding 850 17/4 700 7/-9 500 -15 | [52, 51, 'numerous', 'severe possible'] | [20, 51, 'isolated', 'severe possible'] | Failed |
| sounding 850 15/3 700 7/-10 500 -3 | [38, 24, 'numerous', 'weak'] | [4, 24, 'none', 'weak'] | Failed |
| sounding 850 9/3 700 1/-16 500 -17 | [46, 46, 'numerous', 'weak'] | [12, 46, 'none', 'weak'] | Failed |
| sounding 850 26/20 700 15/-2 500 4 | [59, 38, 'numerous', 'weak'] | [25, 38, 'isolated', 'weak'] | Failed |
| sounding 850 25/23 700 15/2 500 4 | [57, 40, 'numerous', 'weak'] | [31, 40, 'scattered', 'weak'] | Failed |
| sounding 850 21/6 700 5/-14 500 -7 | [53, 41, 'numerous', 'weak'] | [15, 41, 'none', 'weak'] | Failed |
SHA-256 / 3d8931322cef4c74b96675dcf7bf1454b3c68f17c846f137c84f1af09b3460ab
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(t850, td850, t700, td700, t500):
k = (t850 - t500) + td850 - (t700 - td700)
vt = t850 - t500
ct = td850 - t500
tt = vt + ct
if k < 20:
pot = "none"
elif k <= 25:
pot = "isolated"
elif k <= 30:
pot = "widely scattered"
elif k <= 35:
pot = "scattered"
else:
pot = "numerous"
sev = "severe possible" if tt >= 50 else "weak"
return [k, tt, pot, sev]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['sounding 850 21/8 700 11/0 500 -3', [21, 8, 11, 0, -3], [21, 35, 'isolated', 'weak']], ['sounding 850 10/2 700 3/3 500 -10', [10, 2, 3, 3, -10], [22, 32, 'isolated', 'weak']], ['sounding 850 17/4 700 7/-9 500 -15', [17, 4, 7, -9, -15], [20, 51, 'isolated', 'severe possible']], ['sounding 850 15/3 700 7/-10 500 -3', [15, 3, 7, -10, -3], [4, 24, 'none', 'weak']], ['sounding 850 9/3 700 1/-16 500 -17', [9, 3, 1, -16, -17], [12, 46, 'none', 'weak']], ['sounding 850 26/20 700 15/-2 500 4', [26, 20, 15, -2, 4], [25, 38, 'isolated', 'weak']], ['sounding 850 25/23 700 15/2 500 4', [25, 23, 15, 2, 4], [31, 40, 'scattered', 'weak']], ['sounding 850 21/6 700 5/-14 500 -7', [21, 6, 5, -14, -7], [15, 41, 'none', 'weak']]], [['sounding 850 9/3 700 1/-16 500 -17', [9, 3, 1, -16, -17], [12, 46, 'none', 'weak']], ['sounding 850 21/6 700 5/-14 500 -7', [21, 6, 5, -14, -7], [15, 41, 'none', 'weak']], ['sounding 850 26/13 700 12/2 500 2', [26, 13, 12, 2, 2], [27, 35, 'widely scattered', 'weak']], ['sounding 850 18/7 700 3/2 500 -19', [18, 7, 3, 2, -19], [43, 63, 'numerous', 'severe possible']], ['sounding 850 16/15 700 3/-8 500 -16', [16, 15, 3, -8, -16], [36, 63, 'numerous', 'severe possible']], ['sounding 850 5/-7 700 -4/-7 500 -22', [5, -7, -4, -7, -22], [17, 42, 'none', 'weak']], ['sounding 850 11/4 700 -3/-14 500 -13', [11, 4, -3, -14, -13], [17, 41, 'none', 'weak']], ['sounding 850 13/11 700 3/-3 500 -18', [13, 11, 3, -3, -18], [36, 60, 'numerous', 'severe possible']]], [['sounding 850 21/6 700 5/-14 500 -7', [21, 6, 5, -14, -7], [15, 41, 'none', 'weak']], ['sounding 850 11/4 700 -3/-14 500 -13', [11, 4, -3, -14, -13], [17, 41, 'none', 'weak']], ['sounding 850 24/20 700 14/5 500 -1', [24, 20, 14, 5, -1], [36, 46, 'numerous', 'weak']], ['sounding 850 15/10 700 4/1 500 -15', [15, 10, 4, 1, -15], [37, 55, 'numerous', 'severe possible']], ['sounding 850 23/15 700 12/12 500 2', [23, 15, 12, 12, 2], [36, 34, 'numerous', 'weak']], ['sounding 850 16/16 700 3/-5 500 -14', [16, 16, 3, -5, -14], [38, 60, 'numerous', 'severe possible']], ['sounding 850 25/24 700 16/7 500 2', [25, 24, 16, 7, 2], [38, 45, 'numerous', 'weak']], ['sounding 850 7/-8 700 1/-18 500 -18', [7, -8, 1, -18, -18], [-2, 35, 'none', 'weak']]], [['sounding 850 16/15 700 3/-8 500 -16', [16, 15, 3, -8, -16], [36, 63, 'numerous', 'severe possible']], ['sounding 850 25/24 700 16/7 500 2', [25, 24, 16, 7, 2], [38, 45, 'numerous', 'weak']], ['sounding 850 23/11 700 15/9 500 1', [23, 11, 15, 9, 1], [27, 32, 'widely scattered', 'weak']], ['sounding 850 9/6 700 0/-1 500 -18', [9, 6, 0, -1, -18], [32, 51, 'scattered', 'severe possible']], ['sounding 850 14/4 700 3/2 500 -9', [14, 4, 3, 2, -9], [26, 36, 'widely scattered', 'weak']], ['sounding 850 18/16 700 8/0 500 -12', [18, 16, 8, 0, -12], [38, 58, 'numerous', 'severe possible']], ['sounding 850 17/2 700 10/-7 500 -1', [17, 2, 10, -7, -1], [3, 21, 'none', 'weak']], ['sounding 850 22/15 700 13/-4 500 -1', [22, 15, 13, -4, -1], [21, 39, 'isolated', 'weak']]], [['sounding 850 13/11 700 3/-3 500 -18', [13, 11, 3, -3, -18], [36, 60, 'numerous', 'severe possible']], ['sounding 850 14/4 700 3/2 500 -9', [14, 4, 3, 2, -9], [26, 36, 'widely scattered', 'weak']], ['sounding 850 20/8 700 7/0 500 -11', [20, 8, 7, 0, -11], [32, 50, 'scattered', 'severe possible']], ['sounding 850 18/4 700 11/-3 500 -11', [18, 4, 11, -3, -11], [19, 44, 'none', 'weak']], ['sounding 850 11/4 700 -2/-12 500 -15', [11, 4, -2, -12, -15], [20, 45, 'isolated', 'weak']], ['sounding 850 16/16 700 1/-17 500 -17', [16, 16, 1, -17, -17], [31, 66, 'scattered', 'severe possible']], ['sounding 850 18/17 700 7/-11 500 -5', [18, 17, 7, -11, -5], [22, 45, 'isolated', 'weak']], ['sounding 850 22/15 700 7/-3 500 -8', [22, 15, 7, -3, -8], [35, 53, 'scattered', 'severe possible']]]]
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 |
|---|---|---|---|
| sounding 850 21/8 700 11/0 500 -3 | [21, 35, 'isolated', 'weak'] | [21, 35, 'isolated', 'weak'] | Passed |
| sounding 850 10/2 700 3/3 500 -10 | [22, 32, 'isolated', 'weak'] | [22, 32, 'isolated', 'weak'] | Passed |
| sounding 850 17/4 700 7/-9 500 -15 | [20, 51, 'isolated', 'severe possible'] | [20, 51, 'isolated', 'severe possible'] | Passed |
| sounding 850 15/3 700 7/-10 500 -3 | [4, 24, 'none', 'weak'] | [4, 24, 'none', 'weak'] | Passed |
| sounding 850 9/3 700 1/-16 500 -17 | [12, 46, 'none', 'weak'] | [12, 46, 'none', 'weak'] | Passed |
| sounding 850 26/20 700 15/-2 500 4 | [25, 38, 'isolated', 'weak'] | [25, 38, 'isolated', 'weak'] | Passed |
| sounding 850 25/23 700 15/2 500 4 | [31, 40, 'scattered', 'weak'] | [31, 40, 'scattered', 'weak'] | Passed |
| sounding 850 21/6 700 5/-14 500 -7 | [15, 41, 'none', 'weak'] | [15, 41, 'none', 'weak'] | Passed |
SHA-256 / 635bded17a8a400704ebe47409246f5947917107fb81d6d439f68e55dce45f3a
Verification & scope
Stipulated deterministic teaching model of an operational weather index; coefficients and thresholds are fixed by the contract and no claim of standards conformance is made. 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:48:27.464336+00:00.
Case digest / a024f1452b279e9659dfc6bd3cd253f7891b351d21c680874c122fa45dce8726