FA-70971 / Weather index computation / Open access
WBGT heat flag: outdoor weights · case 01
Sunny sites under-read WBGT when the globe is much hotter than the air.
ROOT CAUSE
The globe and dry-bulb weights are swapped in the outdoor formula.
VERIFIED REPAIR
Use 0.2 for the globe and 0.1 for the dry bulb in sun.
Unsuccessful approach: Using the indoor formula outdoors ignores the dry-bulb term.
Case contract
Inputs natural wet bulb, globe and dry bulb in degC and whether the site is in sun. Sun: WBGT = 0.7Tw + 0.2Tg + 0.1Td; shade/indoor: 0.7Tw + 0.3Tg; round to 0.1 degC. Convert the rounded value to degF (x*9/5+32) and flag: <80 white, <85 green, <88 yellow, <90 red, else black.
Why this case matters
Training and work/rest schedules follow the WBGT flag colour.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(tw, tg, td, solar):
if solar:
w = 0.7 * tw + 0.1 * tg + 0.2 * td
else:
w = 0.7 * tw + 0.3 * tg
w = round(w, 1)
wf = w * 9 / 5 + 32
if wf < 80:
flag = "white"
elif wf < 85:
flag = "green"
elif wf < 88:
flag = "yellow"
elif wf < 90:
flag = "red"
else:
flag = "black"
return [w, flag]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['Tw 20 Tg 30 Td 25 sun', [20, 30, 25, True], [22.5, 'white']], ['Tw 20 Tg 30 Td 25 indoor', [20, 30, 25, False], [23.0, 'white']], ['Tw 24 Tg 35 Td 30 sun', [24, 35, 30, True], [26.8, 'green']], ['Tw 24 Tg 35 Td 30 indoor', [24, 35, 30, False], [27.3, 'green']], ['Tw 25 Tg 40 Td 31 sun', [25, 40, 31, True], [28.6, 'green']], ['Tw 25 Tg 40 Td 31 indoor', [25, 40, 31, False], [29.5, 'yellow']], ['Tw 26 Tg 38 Td 30 sun', [26, 38, 30, True], [28.8, 'green']], ['Tw 26 Tg 38 Td 30 indoor', [26, 38, 30, False], [29.6, 'yellow']]], [['Tw 26 Tg 38 Td 30 sun', [26, 38, 30, True], [28.8, 'green']], ['Tw 26 Tg 38 Td 30 indoor', [26, 38, 30, False], [29.6, 'yellow']], ['Tw 27 Tg 36 Td 32 sun', [27, 36, 32, True], [29.3, 'green']], ['Tw 27 Tg 36 Td 32 indoor', [27, 36, 32, False], [29.7, 'yellow']], ['Tw 28 Tg 45 Td 34 sun', [28, 45, 34, True], [32.0, 'red']], ['Tw 28 Tg 45 Td 34 indoor', [28, 45, 34, False], [33.1, 'black']], ['Tw 29 Tg 30 Td 29 sun', [29, 30, 29, True], [29.2, 'green']], ['Tw 29 Tg 30 Td 29 indoor', [29, 30, 29, False], [29.3, 'green']]], [['Tw 29 Tg 30 Td 29 sun', [29, 30, 29, True], [29.2, 'green']], ['Tw 30 Tg 50 Td 35 sun', [30, 50, 35, True], [34.5, 'black']], ['Tw 30 Tg 50 Td 35 indoor', [30, 50, 35, False], [36.0, 'black']], ['Tw 31 Tg 40 Td 33 sun', [31, 40, 33, True], [33.0, 'black']], ['Tw 31 Tg 40 Td 33 indoor', [31, 40, 33, False], [33.7, 'black']], ['Tw 22 Tg 26 Td 24 sun', [22, 26, 24, True], [23.0, 'white']], ['Tw 22 Tg 26 Td 24 indoor', [22, 26, 24, False], [23.2, 'white']], ['Tw 26.4 Tg 30 Td 29 sun', [26.4, 30, 29, True], [27.4, 'green']]], [['Tw 22 Tg 26 Td 24 sun', [22, 26, 24, True], [23.0, 'white']], ['Tw 27 Tg 29.4 Td 30 indoor', [27, 29.4, 30, False], [27.7, 'green']], ['Tw 26.4 Tg 30 Td 29 sun', [26.4, 30, 29, True], [27.4, 'green']], ['Tw 26.4 Tg 30 Td 29 indoor', [26.4, 30, 29, False], [27.5, 'green']], ['indoor raw 26.66', [20, 42.2, 30, False], [26.7, 'green']], ['indoor raw 29.43', [21, 49.1, 30, False], [29.4, 'green']], ['sun raw 26.66', [20, 41.3, 30.6, True], [25.3, 'white']], ['field Tw 26.8 Tg 43.9 Td 31.4', [26.8, 43.9, 31.4, True], [30.7, 'yellow']]], [['field Tw 22.5 Tg 25.2 Td 27.7', [22.5, 25.2, 27.7, True], [23.6, 'white']], ['field Tw 25.5 Tg 32.1 Td 26.0', [25.5, 32.1, 26.0, False], [27.5, 'green']], ['field Tw 18.5 Tg 26.3 Td 19.1', [18.5, 26.3, 19.1, True], [20.1, 'white']], ['field Tw 23.9 Tg 38.8 Td 24.9', [23.9, 38.8, 24.9, True], [27.0, 'green']], ['field Tw 26.8 Tg 43.9 Td 31.4', [26.8, 43.9, 31.4, True], [30.7, 'yellow']], ['field Tw 31.7 Tg 32.5 Td 38.6', [31.7, 32.5, 38.6, True], [32.5, 'black']], ['field Tw 20.0 Tg 22.1 Td 22.5', [20.0, 22.1, 22.5, False], [20.6, 'white']], ['field Tw 27.1 Tg 45.0 Td 33.7', [27.1, 45.0, 33.7, True], [31.3, 'red']]]]
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 |
|---|---|---|---|
| Tw 20 Tg 30 Td 25 sun | [22.0, 'white'] | [22.5, 'white'] | Failed |
| Tw 20 Tg 30 Td 25 indoor | [23.0, 'white'] | [23.0, 'white'] | Passed |
| Tw 24 Tg 35 Td 30 sun | [26.3, 'white'] | [26.8, 'green'] | Failed |
| Tw 24 Tg 35 Td 30 indoor | [27.3, 'green'] | [27.3, 'green'] | Passed |
| Tw 25 Tg 40 Td 31 sun | [27.7, 'green'] | [28.6, 'green'] | Failed |
| Tw 25 Tg 40 Td 31 indoor | [29.5, 'yellow'] | [29.5, 'yellow'] | Passed |
| Tw 26 Tg 38 Td 30 sun | [28.0, 'green'] | [28.8, 'green'] | Failed |
| Tw 26 Tg 38 Td 30 indoor | [29.6, 'yellow'] | [29.6, 'yellow'] | Passed |
SHA-256 / 54cf3bd2485bacdc345d8dd9ef429eac61c36588cd780c7fafca4e0888b15b31
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(tw, tg, td, solar):
if solar:
w = 0.7 * tw + 0.3 * tg
else:
w = 0.7 * tw + 0.3 * tg
w = round(w, 1)
wf = w * 9 / 5 + 32
if wf < 80:
flag = "white"
elif wf < 85:
flag = "green"
elif wf < 88:
flag = "yellow"
elif wf < 90:
flag = "red"
else:
flag = "black"
return [w, flag]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['Tw 20 Tg 30 Td 25 sun', [20, 30, 25, True], [22.5, 'white']], ['Tw 20 Tg 30 Td 25 indoor', [20, 30, 25, False], [23.0, 'white']], ['Tw 24 Tg 35 Td 30 sun', [24, 35, 30, True], [26.8, 'green']], ['Tw 24 Tg 35 Td 30 indoor', [24, 35, 30, False], [27.3, 'green']], ['Tw 25 Tg 40 Td 31 sun', [25, 40, 31, True], [28.6, 'green']], ['Tw 25 Tg 40 Td 31 indoor', [25, 40, 31, False], [29.5, 'yellow']], ['Tw 26 Tg 38 Td 30 sun', [26, 38, 30, True], [28.8, 'green']], ['Tw 26 Tg 38 Td 30 indoor', [26, 38, 30, False], [29.6, 'yellow']]], [['Tw 26 Tg 38 Td 30 sun', [26, 38, 30, True], [28.8, 'green']], ['Tw 26 Tg 38 Td 30 indoor', [26, 38, 30, False], [29.6, 'yellow']], ['Tw 27 Tg 36 Td 32 sun', [27, 36, 32, True], [29.3, 'green']], ['Tw 27 Tg 36 Td 32 indoor', [27, 36, 32, False], [29.7, 'yellow']], ['Tw 28 Tg 45 Td 34 sun', [28, 45, 34, True], [32.0, 'red']], ['Tw 28 Tg 45 Td 34 indoor', [28, 45, 34, False], [33.1, 'black']], ['Tw 29 Tg 30 Td 29 sun', [29, 30, 29, True], [29.2, 'green']], ['Tw 29 Tg 30 Td 29 indoor', [29, 30, 29, False], [29.3, 'green']]], [['Tw 29 Tg 30 Td 29 sun', [29, 30, 29, True], [29.2, 'green']], ['Tw 30 Tg 50 Td 35 sun', [30, 50, 35, True], [34.5, 'black']], ['Tw 30 Tg 50 Td 35 indoor', [30, 50, 35, False], [36.0, 'black']], ['Tw 31 Tg 40 Td 33 sun', [31, 40, 33, True], [33.0, 'black']], ['Tw 31 Tg 40 Td 33 indoor', [31, 40, 33, False], [33.7, 'black']], ['Tw 22 Tg 26 Td 24 sun', [22, 26, 24, True], [23.0, 'white']], ['Tw 22 Tg 26 Td 24 indoor', [22, 26, 24, False], [23.2, 'white']], ['Tw 26.4 Tg 30 Td 29 sun', [26.4, 30, 29, True], [27.4, 'green']]], [['Tw 22 Tg 26 Td 24 sun', [22, 26, 24, True], [23.0, 'white']], ['Tw 27 Tg 29.4 Td 30 indoor', [27, 29.4, 30, False], [27.7, 'green']], ['Tw 26.4 Tg 30 Td 29 sun', [26.4, 30, 29, True], [27.4, 'green']], ['Tw 26.4 Tg 30 Td 29 indoor', [26.4, 30, 29, False], [27.5, 'green']], ['indoor raw 26.66', [20, 42.2, 30, False], [26.7, 'green']], ['indoor raw 29.43', [21, 49.1, 30, False], [29.4, 'green']], ['sun raw 26.66', [20, 41.3, 30.6, True], [25.3, 'white']], ['field Tw 26.8 Tg 43.9 Td 31.4', [26.8, 43.9, 31.4, True], [30.7, 'yellow']]], [['field Tw 22.5 Tg 25.2 Td 27.7', [22.5, 25.2, 27.7, True], [23.6, 'white']], ['field Tw 25.5 Tg 32.1 Td 26.0', [25.5, 32.1, 26.0, False], [27.5, 'green']], ['field Tw 18.5 Tg 26.3 Td 19.1', [18.5, 26.3, 19.1, True], [20.1, 'white']], ['field Tw 23.9 Tg 38.8 Td 24.9', [23.9, 38.8, 24.9, True], [27.0, 'green']], ['field Tw 26.8 Tg 43.9 Td 31.4', [26.8, 43.9, 31.4, True], [30.7, 'yellow']], ['field Tw 31.7 Tg 32.5 Td 38.6', [31.7, 32.5, 38.6, True], [32.5, 'black']], ['field Tw 20.0 Tg 22.1 Td 22.5', [20.0, 22.1, 22.5, False], [20.6, 'white']], ['field Tw 27.1 Tg 45.0 Td 33.7', [27.1, 45.0, 33.7, True], [31.3, 'red']]]]
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 |
|---|---|---|---|
| Tw 20 Tg 30 Td 25 sun | [23.0, 'white'] | [22.5, 'white'] | Failed |
| Tw 20 Tg 30 Td 25 indoor | [23.0, 'white'] | [23.0, 'white'] | Passed |
| Tw 24 Tg 35 Td 30 sun | [27.3, 'green'] | [26.8, 'green'] | Failed |
| Tw 24 Tg 35 Td 30 indoor | [27.3, 'green'] | [27.3, 'green'] | Passed |
| Tw 25 Tg 40 Td 31 sun | [29.5, 'yellow'] | [28.6, 'green'] | Failed |
| Tw 25 Tg 40 Td 31 indoor | [29.5, 'yellow'] | [29.5, 'yellow'] | Passed |
| Tw 26 Tg 38 Td 30 sun | [29.6, 'yellow'] | [28.8, 'green'] | Failed |
| Tw 26 Tg 38 Td 30 indoor | [29.6, 'yellow'] | [29.6, 'yellow'] | Passed |
SHA-256 / 668d09a866418700cbcfc4fe53a314b09a90f3351fd84b9c92c49998626e723c
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(tw, tg, td, solar):
if solar:
w = 0.7 * tw + 0.2 * tg + 0.1 * td
else:
w = 0.7 * tw + 0.3 * tg
w = round(w, 1)
wf = w * 9 / 5 + 32
if wf < 80:
flag = "white"
elif wf < 85:
flag = "green"
elif wf < 88:
flag = "yellow"
elif wf < 90:
flag = "red"
else:
flag = "black"
return [w, flag]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['Tw 20 Tg 30 Td 25 sun', [20, 30, 25, True], [22.5, 'white']], ['Tw 20 Tg 30 Td 25 indoor', [20, 30, 25, False], [23.0, 'white']], ['Tw 24 Tg 35 Td 30 sun', [24, 35, 30, True], [26.8, 'green']], ['Tw 24 Tg 35 Td 30 indoor', [24, 35, 30, False], [27.3, 'green']], ['Tw 25 Tg 40 Td 31 sun', [25, 40, 31, True], [28.6, 'green']], ['Tw 25 Tg 40 Td 31 indoor', [25, 40, 31, False], [29.5, 'yellow']], ['Tw 26 Tg 38 Td 30 sun', [26, 38, 30, True], [28.8, 'green']], ['Tw 26 Tg 38 Td 30 indoor', [26, 38, 30, False], [29.6, 'yellow']]], [['Tw 26 Tg 38 Td 30 sun', [26, 38, 30, True], [28.8, 'green']], ['Tw 26 Tg 38 Td 30 indoor', [26, 38, 30, False], [29.6, 'yellow']], ['Tw 27 Tg 36 Td 32 sun', [27, 36, 32, True], [29.3, 'green']], ['Tw 27 Tg 36 Td 32 indoor', [27, 36, 32, False], [29.7, 'yellow']], ['Tw 28 Tg 45 Td 34 sun', [28, 45, 34, True], [32.0, 'red']], ['Tw 28 Tg 45 Td 34 indoor', [28, 45, 34, False], [33.1, 'black']], ['Tw 29 Tg 30 Td 29 sun', [29, 30, 29, True], [29.2, 'green']], ['Tw 29 Tg 30 Td 29 indoor', [29, 30, 29, False], [29.3, 'green']]], [['Tw 29 Tg 30 Td 29 sun', [29, 30, 29, True], [29.2, 'green']], ['Tw 30 Tg 50 Td 35 sun', [30, 50, 35, True], [34.5, 'black']], ['Tw 30 Tg 50 Td 35 indoor', [30, 50, 35, False], [36.0, 'black']], ['Tw 31 Tg 40 Td 33 sun', [31, 40, 33, True], [33.0, 'black']], ['Tw 31 Tg 40 Td 33 indoor', [31, 40, 33, False], [33.7, 'black']], ['Tw 22 Tg 26 Td 24 sun', [22, 26, 24, True], [23.0, 'white']], ['Tw 22 Tg 26 Td 24 indoor', [22, 26, 24, False], [23.2, 'white']], ['Tw 26.4 Tg 30 Td 29 sun', [26.4, 30, 29, True], [27.4, 'green']]], [['Tw 22 Tg 26 Td 24 sun', [22, 26, 24, True], [23.0, 'white']], ['Tw 27 Tg 29.4 Td 30 indoor', [27, 29.4, 30, False], [27.7, 'green']], ['Tw 26.4 Tg 30 Td 29 sun', [26.4, 30, 29, True], [27.4, 'green']], ['Tw 26.4 Tg 30 Td 29 indoor', [26.4, 30, 29, False], [27.5, 'green']], ['indoor raw 26.66', [20, 42.2, 30, False], [26.7, 'green']], ['indoor raw 29.43', [21, 49.1, 30, False], [29.4, 'green']], ['sun raw 26.66', [20, 41.3, 30.6, True], [25.3, 'white']], ['field Tw 26.8 Tg 43.9 Td 31.4', [26.8, 43.9, 31.4, True], [30.7, 'yellow']]], [['field Tw 22.5 Tg 25.2 Td 27.7', [22.5, 25.2, 27.7, True], [23.6, 'white']], ['field Tw 25.5 Tg 32.1 Td 26.0', [25.5, 32.1, 26.0, False], [27.5, 'green']], ['field Tw 18.5 Tg 26.3 Td 19.1', [18.5, 26.3, 19.1, True], [20.1, 'white']], ['field Tw 23.9 Tg 38.8 Td 24.9', [23.9, 38.8, 24.9, True], [27.0, 'green']], ['field Tw 26.8 Tg 43.9 Td 31.4', [26.8, 43.9, 31.4, True], [30.7, 'yellow']], ['field Tw 31.7 Tg 32.5 Td 38.6', [31.7, 32.5, 38.6, True], [32.5, 'black']], ['field Tw 20.0 Tg 22.1 Td 22.5', [20.0, 22.1, 22.5, False], [20.6, 'white']], ['field Tw 27.1 Tg 45.0 Td 33.7', [27.1, 45.0, 33.7, True], [31.3, 'red']]]]
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 |
|---|---|---|---|
| Tw 20 Tg 30 Td 25 sun | [22.5, 'white'] | [22.5, 'white'] | Passed |
| Tw 20 Tg 30 Td 25 indoor | [23.0, 'white'] | [23.0, 'white'] | Passed |
| Tw 24 Tg 35 Td 30 sun | [26.8, 'green'] | [26.8, 'green'] | Passed |
| Tw 24 Tg 35 Td 30 indoor | [27.3, 'green'] | [27.3, 'green'] | Passed |
| Tw 25 Tg 40 Td 31 sun | [28.6, 'green'] | [28.6, 'green'] | Passed |
| Tw 25 Tg 40 Td 31 indoor | [29.5, 'yellow'] | [29.5, 'yellow'] | Passed |
| Tw 26 Tg 38 Td 30 sun | [28.8, 'green'] | [28.8, 'green'] | Passed |
| Tw 26 Tg 38 Td 30 indoor | [29.6, 'yellow'] | [29.6, 'yellow'] | Passed |
SHA-256 / 0de0de9a2cf003c0be0a7f27894ef7da6487b67c6067f56560b1d3a6443bdd27
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:25.524558+00:00.
Case digest / 762c2a391e0a5c4a945975e73ffce65f1c33803dba02d2f23eb4747a08137aaf