FAILURE MAP
← Case archive

FA-71286 / Weather index computation / Open access

Pasquill-Gifford stability class: night cloud threshold · case 01

Four-octa nights are treated as clear and too stable.

Verified by executionVariant 1 · 8 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The thin-overcast night table requires more than four octas.

VERIFIED REPAIR

Use the thin-cloud table for 4 or more octas.

Unsuccessful approach: Lowering the threshold to 3 octas treats clear nights as cloudy.

Case contract

Wind class: <2, <3, <5, <6, >=6 (index 0..4). 8 octas returns "D" day or night. Day: tables by insolation strong [A,A-B,B,C,C], moderate [A-B,B,B-C,C-D,D], slight [B,C,C,D,D]; unknown insolation returns None. Night: >=4 octas [E,E,D,D,D], <=3 octas [F,F,E,D,D].

Why this case matters

Air-dispersion screening models choose plume spread from the stability class.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(wind_ms, is_day, insolation, octas):
    day = {"strong": ["A", "A-B", "B", "C", "C"],
           "moderate": ["A-B", "B", "B-C", "C-D", "D"],
           "slight": ["B", "C", "C", "D", "D"]}
    thin = ["E", "E", "D", "D", "D"]
    clear = ["F", "F", "E", "D", "D"]
    if octas == 8:
        return "D"
    i = 0 if wind_ms < 2 else 1 if wind_ms < 3 else 2 if wind_ms < 5 else 3 if wind_ms < 6 else 4
    if is_day:
        if insolation not in day:
            return None
        return day[insolation][i]
    return (thin if octas > 4 else clear)[i]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['wind 1.0 day strong 2 octas', [1.0, True, 'strong', 2], 'A'], ['wind 1.0 day moderate 5 octas', [1.0, True, 'moderate', 5], 'A-B'], ['wind 1.0 day slight 8 octas', [1.0, True, 'slight', 8], 'D'], ['wind 1.0 day slight 3 octas', [1.0, True, 'slight', 3], 'B'], ['wind 1.0 night None 3 octas', [1.0, False, None, 3], 'F'], ['wind 1.0 night None 4 octas', [1.0, False, None, 4], 'E'], ['wind 1.0 night None 8 octas', [1.0, False, None, 8], 'D'], ['wind 1.9 night None 3 octas', [1.9, False, None, 3], 'F']], [['wind 1.0 night None 3 octas', [1.0, False, None, 3], 'F'], ['wind 1.0 day overcast-ish 4 octas', [1.0, True, 'overcast-ish', 4], None], ['wind 1.0 night None 7 octas', [1.0, False, None, 7], 'E'], ['wind 1.0 day strong 7 octas', [1.0, True, 'strong', 7], 'A'], ['wind 1.9 day strong 2 octas', [1.9, True, 'strong', 2], 'A'], ['wind 1.9 day moderate 5 octas', [1.9, True, 'moderate', 5], 'A-B'], ['wind 1.9 day slight 8 octas', [1.9, True, 'slight', 8], 'D'], ['wind 2.9 night None 4 octas', [2.9, False, None, 4], 'E']], [['wind 1.0 night None 4 octas', [1.0, False, None, 4], 'E'], ['wind 1.9 night None 3 octas', [1.9, False, None, 3], 'F'], ['wind 1.9 night None 4 octas', [1.9, False, None, 4], 'E'], ['wind 1.9 night None 8 octas', [1.9, False, None, 8], 'D'], ['wind 1.9 day overcast-ish 4 octas', [1.9, True, 'overcast-ish', 4], None], ['wind 1.9 night None 7 octas', [1.9, False, None, 7], 'E'], ['wind 1.9 day strong 7 octas', [1.9, True, 'strong', 7], 'A'], ['wind 4.9 night None 3 octas', [4.9, False, None, 3], 'E']], [['wind 2.0 day moderate 5 octas', [2.0, True, 'moderate', 5], 'B'], ['wind 2.0 day slight 8 octas', [2.0, True, 'slight', 8], 'D'], ['wind 2.0 day slight 3 octas', [2.0, True, 'slight', 3], 'C'], ['wind 2.0 night None 3 octas', [2.0, False, None, 3], 'F'], ['wind 2.0 night None 4 octas', [2.0, False, None, 4], 'E'], ['wind 2.0 night None 8 octas', [2.0, False, None, 8], 'D'], ['wind 2.9 night None 4 octas', [2.9, False, None, 4], 'E'], ['wind 3.0 night None 3 octas', [3.0, False, None, 3], 'E']], [['wind 1.0 night None 4 octas', [1.0, False, None, 4], 'E'], ['wind 2.0 night None 7 octas', [2.0, False, None, 7], 'E'], ['wind 2.0 day strong 7 octas', [2.0, True, 'strong', 7], 'A-B'], ['wind 2.9 day strong 2 octas', [2.9, True, 'strong', 2], 'A-B'], ['wind 2.9 day moderate 5 octas', [2.9, True, 'moderate', 5], 'B'], ['wind 2.9 day slight 8 octas', [2.9, True, 'slight', 8], 'D'], ['wind 2.9 day slight 3 octas', [2.9, True, 'slight', 3], 'C'], ['wind 2.9 night None 3 octas', [2.9, False, None, 3], 'F']]]
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 fixtureActualExpectedOutcome
wind 1.0 day strong 2 octasAAPassed
wind 1.0 day moderate 5 octasA-BA-BPassed
wind 1.0 day slight 8 octasDDPassed
wind 1.0 day slight 3 octasBBPassed
wind 1.0 night None 3 octasFFPassed
wind 1.0 night None 4 octasFEFailed
wind 1.0 night None 8 octasDDPassed
wind 1.9 night None 3 octasFFPassed

SHA-256 / d9956f5c344104937805096da9be6b37454c5e2f1af2fe70d5579d6c98463c2d

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(wind_ms, is_day, insolation, octas):
    day = {"strong": ["A", "A-B", "B", "C", "C"],
           "moderate": ["A-B", "B", "B-C", "C-D", "D"],
           "slight": ["B", "C", "C", "D", "D"]}
    thin = ["E", "E", "D", "D", "D"]
    clear = ["F", "F", "E", "D", "D"]
    if octas == 8:
        return "D"
    i = 0 if wind_ms < 2 else 1 if wind_ms < 3 else 2 if wind_ms < 5 else 3 if wind_ms < 6 else 4
    if is_day:
        if insolation not in day:
            return None
        return day[insolation][i]
    return (thin if octas >= 3 else clear)[i]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['wind 1.0 day strong 2 octas', [1.0, True, 'strong', 2], 'A'], ['wind 1.0 day moderate 5 octas', [1.0, True, 'moderate', 5], 'A-B'], ['wind 1.0 day slight 8 octas', [1.0, True, 'slight', 8], 'D'], ['wind 1.0 day slight 3 octas', [1.0, True, 'slight', 3], 'B'], ['wind 1.0 night None 3 octas', [1.0, False, None, 3], 'F'], ['wind 1.0 night None 4 octas', [1.0, False, None, 4], 'E'], ['wind 1.0 night None 8 octas', [1.0, False, None, 8], 'D'], ['wind 1.9 night None 3 octas', [1.9, False, None, 3], 'F']], [['wind 1.0 night None 3 octas', [1.0, False, None, 3], 'F'], ['wind 1.0 day overcast-ish 4 octas', [1.0, True, 'overcast-ish', 4], None], ['wind 1.0 night None 7 octas', [1.0, False, None, 7], 'E'], ['wind 1.0 day strong 7 octas', [1.0, True, 'strong', 7], 'A'], ['wind 1.9 day strong 2 octas', [1.9, True, 'strong', 2], 'A'], ['wind 1.9 day moderate 5 octas', [1.9, True, 'moderate', 5], 'A-B'], ['wind 1.9 day slight 8 octas', [1.9, True, 'slight', 8], 'D'], ['wind 2.9 night None 4 octas', [2.9, False, None, 4], 'E']], [['wind 1.0 night None 4 octas', [1.0, False, None, 4], 'E'], ['wind 1.9 night None 3 octas', [1.9, False, None, 3], 'F'], ['wind 1.9 night None 4 octas', [1.9, False, None, 4], 'E'], ['wind 1.9 night None 8 octas', [1.9, False, None, 8], 'D'], ['wind 1.9 day overcast-ish 4 octas', [1.9, True, 'overcast-ish', 4], None], ['wind 1.9 night None 7 octas', [1.9, False, None, 7], 'E'], ['wind 1.9 day strong 7 octas', [1.9, True, 'strong', 7], 'A'], ['wind 4.9 night None 3 octas', [4.9, False, None, 3], 'E']], [['wind 2.0 day moderate 5 octas', [2.0, True, 'moderate', 5], 'B'], ['wind 2.0 day slight 8 octas', [2.0, True, 'slight', 8], 'D'], ['wind 2.0 day slight 3 octas', [2.0, True, 'slight', 3], 'C'], ['wind 2.0 night None 3 octas', [2.0, False, None, 3], 'F'], ['wind 2.0 night None 4 octas', [2.0, False, None, 4], 'E'], ['wind 2.0 night None 8 octas', [2.0, False, None, 8], 'D'], ['wind 2.9 night None 4 octas', [2.9, False, None, 4], 'E'], ['wind 3.0 night None 3 octas', [3.0, False, None, 3], 'E']], [['wind 1.0 night None 4 octas', [1.0, False, None, 4], 'E'], ['wind 2.0 night None 7 octas', [2.0, False, None, 7], 'E'], ['wind 2.0 day strong 7 octas', [2.0, True, 'strong', 7], 'A-B'], ['wind 2.9 day strong 2 octas', [2.9, True, 'strong', 2], 'A-B'], ['wind 2.9 day moderate 5 octas', [2.9, True, 'moderate', 5], 'B'], ['wind 2.9 day slight 8 octas', [2.9, True, 'slight', 8], 'D'], ['wind 2.9 day slight 3 octas', [2.9, True, 'slight', 3], 'C'], ['wind 2.9 night None 3 octas', [2.9, False, None, 3], 'F']]]
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 fixtureActualExpectedOutcome
wind 1.0 day strong 2 octasAAPassed
wind 1.0 day moderate 5 octasA-BA-BPassed
wind 1.0 day slight 8 octasDDPassed
wind 1.0 day slight 3 octasBBPassed
wind 1.0 night None 3 octasEFFailed
wind 1.0 night None 4 octasEEPassed
wind 1.0 night None 8 octasDDPassed
wind 1.9 night None 3 octasEFFailed

SHA-256 / beaad6c226925c43907ff46ddc49ae9a7b403f790aca226a0791da85029d8c62

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(wind_ms, is_day, insolation, octas):
    day = {"strong": ["A", "A-B", "B", "C", "C"],
           "moderate": ["A-B", "B", "B-C", "C-D", "D"],
           "slight": ["B", "C", "C", "D", "D"]}
    thin = ["E", "E", "D", "D", "D"]
    clear = ["F", "F", "E", "D", "D"]
    if octas == 8:
        return "D"
    i = 0 if wind_ms < 2 else 1 if wind_ms < 3 else 2 if wind_ms < 5 else 3 if wind_ms < 6 else 4
    if is_day:
        if insolation not in day:
            return None
        return day[insolation][i]
    return (thin if octas >= 4 else clear)[i]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['wind 1.0 day strong 2 octas', [1.0, True, 'strong', 2], 'A'], ['wind 1.0 day moderate 5 octas', [1.0, True, 'moderate', 5], 'A-B'], ['wind 1.0 day slight 8 octas', [1.0, True, 'slight', 8], 'D'], ['wind 1.0 day slight 3 octas', [1.0, True, 'slight', 3], 'B'], ['wind 1.0 night None 3 octas', [1.0, False, None, 3], 'F'], ['wind 1.0 night None 4 octas', [1.0, False, None, 4], 'E'], ['wind 1.0 night None 8 octas', [1.0, False, None, 8], 'D'], ['wind 1.9 night None 3 octas', [1.9, False, None, 3], 'F']], [['wind 1.0 night None 3 octas', [1.0, False, None, 3], 'F'], ['wind 1.0 day overcast-ish 4 octas', [1.0, True, 'overcast-ish', 4], None], ['wind 1.0 night None 7 octas', [1.0, False, None, 7], 'E'], ['wind 1.0 day strong 7 octas', [1.0, True, 'strong', 7], 'A'], ['wind 1.9 day strong 2 octas', [1.9, True, 'strong', 2], 'A'], ['wind 1.9 day moderate 5 octas', [1.9, True, 'moderate', 5], 'A-B'], ['wind 1.9 day slight 8 octas', [1.9, True, 'slight', 8], 'D'], ['wind 2.9 night None 4 octas', [2.9, False, None, 4], 'E']], [['wind 1.0 night None 4 octas', [1.0, False, None, 4], 'E'], ['wind 1.9 night None 3 octas', [1.9, False, None, 3], 'F'], ['wind 1.9 night None 4 octas', [1.9, False, None, 4], 'E'], ['wind 1.9 night None 8 octas', [1.9, False, None, 8], 'D'], ['wind 1.9 day overcast-ish 4 octas', [1.9, True, 'overcast-ish', 4], None], ['wind 1.9 night None 7 octas', [1.9, False, None, 7], 'E'], ['wind 1.9 day strong 7 octas', [1.9, True, 'strong', 7], 'A'], ['wind 4.9 night None 3 octas', [4.9, False, None, 3], 'E']], [['wind 2.0 day moderate 5 octas', [2.0, True, 'moderate', 5], 'B'], ['wind 2.0 day slight 8 octas', [2.0, True, 'slight', 8], 'D'], ['wind 2.0 day slight 3 octas', [2.0, True, 'slight', 3], 'C'], ['wind 2.0 night None 3 octas', [2.0, False, None, 3], 'F'], ['wind 2.0 night None 4 octas', [2.0, False, None, 4], 'E'], ['wind 2.0 night None 8 octas', [2.0, False, None, 8], 'D'], ['wind 2.9 night None 4 octas', [2.9, False, None, 4], 'E'], ['wind 3.0 night None 3 octas', [3.0, False, None, 3], 'E']], [['wind 1.0 night None 4 octas', [1.0, False, None, 4], 'E'], ['wind 2.0 night None 7 octas', [2.0, False, None, 7], 'E'], ['wind 2.0 day strong 7 octas', [2.0, True, 'strong', 7], 'A-B'], ['wind 2.9 day strong 2 octas', [2.9, True, 'strong', 2], 'A-B'], ['wind 2.9 day moderate 5 octas', [2.9, True, 'moderate', 5], 'B'], ['wind 2.9 day slight 8 octas', [2.9, True, 'slight', 8], 'D'], ['wind 2.9 day slight 3 octas', [2.9, True, 'slight', 3], 'C'], ['wind 2.9 night None 3 octas', [2.9, False, None, 3], 'F']]]
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 fixtureActualExpectedOutcome
wind 1.0 day strong 2 octasAAPassed
wind 1.0 day moderate 5 octasA-BA-BPassed
wind 1.0 day slight 8 octasDDPassed
wind 1.0 day slight 3 octasBBPassed
wind 1.0 night None 3 octasFFPassed
wind 1.0 night None 4 octasEEPassed
wind 1.0 night None 8 octasDDPassed
wind 1.9 night None 3 octasFFPassed

SHA-256 / 68ae3518a1a0d30b45136ddbc0d4479492bed2efdc0c9f39c638a268dd8f8f10

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:28.339539+00:00.

Case digest / 0b12581507035edad45b967c180d8facaf09ead987268bb3e823db0a783c99a3