FAILURE MAP
← Case archive

FA-71261 / Weather index computation / Open access

Aviation flight category: lowest qualifying layer · case 01

When a report lists a higher deck first, the lower ceiling is ignored.

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

ROOT CAUSE

The first qualifying layer is taken as the ceiling.

THE FAILURE

The first qualifying layer is taken as the ceiling.

Unsuccessful approach: Taking the maximum selects the highest deck.

Case contract

layers are [cover, height_ft]; the ceiling is the lowest BKN, OVC or VV layer (None if none). Ceiling class: None or >3000 VFR, 1000-3000 MVFR, 500-999 IFR, <500 LIFR. Visibility class: >5 VFR, 3-5 MVFR, 1 to <3 IFR, <1 LIFR. Report [ceiling, worse of the two classes].

Why this case matters

Pilots and dispatch use flight categories for go/no-go and alternate planning.

1 / The failure

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

N = 1
observations = []
def solve(vis_sm, layers):
    ceil = None
    for cover, h in layers:
        if cover in ("BKN", "OVC", "VV"):
            if ceil is None:
                ceil = h
    def cls_c(c):
        if c is None:
            return 3
        if c < 500:
            return 0
        if c < 1000:
            return 1
        if c <= 3000:
            return 2
        return 3
    def cls_v(v):
        if v < 1:
            return 0
        if v < 3:
            return 1
        if v <= 5:
            return 2
        return 3
    names = ["LIFR", "IFR", "MVFR", "VFR"]
    return [ceil, names[min(cls_c(ceil), cls_v(vis_sm))]]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[["vis 4 layers [['BKN', 400]]", [4, [['BKN', 400]]], [400, 'LIFR']], ["vis 5 layers [['FEW', 2500]]", [5, [['FEW', 2500]]], [None, 'MVFR']], ['vis 0.5 layers []', [0.5, []], [None, 'LIFR']], ["vis 6 layers [['BKN', 3000]]", [6, [['BKN', 3000]]], [3000, 'MVFR']], ["vis 0.5 layers [['SCT', 800], ['BKN', 1500], ['BKN', 2500]]", [0.5, [['SCT', 800], ['BKN', 1500], ['BKN', 2500]]], [1500, 'LIFR']], ["vis 2 layers [['OVC', 400], ['SCT', 5000], ['SCT', 200]]", [2, [['OVC', 400], ['SCT', 5000], ['SCT', 200]]], [400, 'LIFR']], ["vis 6 layers [['BKN', 500], ['BKN', 5000]]", [6, [['BKN', 500], ['BKN', 5000]]], [500, 'IFR']], ["vis 0.25 layers [['BKN', 400], ['BKN', 200]]", [0.25, [['BKN', 400], ['BKN', 200]]], [200, 'LIFR']]], [["vis 0.5 layers [['SCT', 800], ['BKN', 1500], ['BKN', 2500]]", [0.5, [['SCT', 800], ['BKN', 1500], ['BKN', 2500]]], [1500, 'LIFR']], ["vis 3 layers [['BKN', 1000]]", [3, [['BKN', 1000]]], [1000, 'MVFR']], ["vis 3 layers [['SCT', 5000], ['FEW', 200]]", [3, [['SCT', 5000], ['FEW', 200]]], [None, 'MVFR']], ["vis 2 layers [['SCT', 5000]]", [2, [['SCT', 5000]]], [None, 'IFR']], ['vis 0.25 layers []', [0.25, []], [None, 'LIFR']], ["vis 6 layers [['BKN', 500], ['BKN', 5000]]", [6, [['BKN', 500], ['BKN', 5000]]], [500, 'IFR']], ["vis 5 layers [['BKN', 3100]]", [5, [['BKN', 3100]]], [3100, 'MVFR']], ["vis 0.25 layers [['BKN', 400], ['BKN', 200]]", [0.25, [['BKN', 400], ['BKN', 200]]], [200, 'LIFR']]], [["vis 4 layers [['VV', 2500]]", [4, [['VV', 2500]]], [2500, 'MVFR']], ["vis 0.25 layers [['FEW', 5000]]", [0.25, [['FEW', 5000]]], [None, 'LIFR']], ["vis 1 layers [['OVC', 500]]", [1, [['OVC', 500]]], [500, 'IFR']], ['vis 0.5 layers []', [0.5, []], [None, 'LIFR']], ["vis 10 layers [['FEW', 1500], ['OVC', 3000]]", [10, [['FEW', 1500], ['OVC', 3000]]], [3000, 'MVFR']], ['vis 1 layers []', [1, []], [None, 'IFR']], ["vis 0.25 layers [['BKN', 400], ['BKN', 200]]", [0.25, [['BKN', 400], ['BKN', 200]]], [200, 'LIFR']], ['unsorted layers', [10, [['OVC', 2500], ['BKN', 900]]], [900, 'IFR']]], [["vis 0.5 layers [['FEW', 400], ['VV', 400]]", [0.5, [['FEW', 400], ['VV', 400]]], [400, 'LIFR']], ["vis 0.25 layers [['BKN', 400], ['BKN', 200]]", [0.25, [['BKN', 400], ['BKN', 200]]], [200, 'LIFR']], ["vis 10 layers [['SCT', 3100]]", [10, [['SCT', 3100]]], [None, 'VFR']], ['vis 1 layers []', [1, []], [None, 'IFR']], ['vis 10 layers []', [10, []], [None, 'VFR']], ["vis 5 layers [['BKN', 500]]", [5, [['BKN', 500]]], [500, 'IFR']], ["vis 2 layers [['FEW', 2500], ['FEW', 800]]", [2, [['FEW', 2500], ['FEW', 800]]], [None, 'IFR']], ["vis 4 layers [['SCT', 200], ['VV', 400], ['VV', 5000]]", [4, [['SCT', 200], ['VV', 400], ['VV', 5000]]], [400, 'LIFR']]], [["vis 0.25 layers [['BKN', 400], ['BKN', 200]]", [0.25, [['BKN', 400], ['BKN', 200]]], [200, 'LIFR']], ["vis 3 layers [['SCT', 400]]", [3, [['SCT', 400]]], [None, 'MVFR']], ["vis 1 layers [['VV', 2500]]", [1, [['VV', 2500]]], [2500, 'IFR']], ['vis 6 layers []', [6, []], [None, 'VFR']], ["vis 3 layers [['FEW', 500], ['SCT', 1000], ['OVC', 400]]", [3, [['FEW', 500], ['SCT', 1000], ['OVC', 400]]], [400, 'LIFR']], ["vis 3 layers [['BKN', 5000]]", [3, [['BKN', 5000]]], [5000, 'MVFR']], ["vis 3 layers [['FEW', 200]]", [3, [['FEW', 200]]], [None, 'MVFR']], ["vis 0.5 layers [['BKN', 2500], ['OVC', 400]]", [0.5, [['BKN', 2500], ['OVC', 400]]], [400, 'LIFR']]]]
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
vis 4 layers [['BKN', 400]][400, 'LIFR'][400, 'LIFR']Passed
vis 5 layers [['FEW', 2500]][None, 'MVFR'][None, 'MVFR']Passed
vis 0.5 layers [][None, 'LIFR'][None, 'LIFR']Passed
vis 6 layers [['BKN', 3000]][3000, 'MVFR'][3000, 'MVFR']Passed
vis 0.5 layers [['SCT', 800], ['BKN', 1500], ['BKN', 2500]][1500, 'LIFR'][1500, 'LIFR']Passed
vis 2 layers [['OVC', 400], ['SCT', 5000], ['SCT', 200]][400, 'LIFR'][400, 'LIFR']Passed
vis 6 layers [['BKN', 500], ['BKN', 5000]][500, 'IFR'][500, 'IFR']Passed
vis 0.25 layers [['BKN', 400], ['BKN', 200]][400, 'LIFR'][200, 'LIFR']Failed

SHA-256 / feebe5535b0182df986c7eba4d56b51c6a799784b540c70abbc3620989e795e4

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(vis_sm, layers):
    ceil = None
    for cover, h in layers:
        if cover in ("BKN", "OVC", "VV"):
            if ceil is None or h > ceil:
                ceil = h
    def cls_c(c):
        if c is None:
            return 3
        if c < 500:
            return 0
        if c < 1000:
            return 1
        if c <= 3000:
            return 2
        return 3
    def cls_v(v):
        if v < 1:
            return 0
        if v < 3:
            return 1
        if v <= 5:
            return 2
        return 3
    names = ["LIFR", "IFR", "MVFR", "VFR"]
    return [ceil, names[min(cls_c(ceil), cls_v(vis_sm))]]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[["vis 4 layers [['BKN', 400]]", [4, [['BKN', 400]]], [400, 'LIFR']], ["vis 5 layers [['FEW', 2500]]", [5, [['FEW', 2500]]], [None, 'MVFR']], ['vis 0.5 layers []', [0.5, []], [None, 'LIFR']], ["vis 6 layers [['BKN', 3000]]", [6, [['BKN', 3000]]], [3000, 'MVFR']], ["vis 0.5 layers [['SCT', 800], ['BKN', 1500], ['BKN', 2500]]", [0.5, [['SCT', 800], ['BKN', 1500], ['BKN', 2500]]], [1500, 'LIFR']], ["vis 2 layers [['OVC', 400], ['SCT', 5000], ['SCT', 200]]", [2, [['OVC', 400], ['SCT', 5000], ['SCT', 200]]], [400, 'LIFR']], ["vis 6 layers [['BKN', 500], ['BKN', 5000]]", [6, [['BKN', 500], ['BKN', 5000]]], [500, 'IFR']], ["vis 0.25 layers [['BKN', 400], ['BKN', 200]]", [0.25, [['BKN', 400], ['BKN', 200]]], [200, 'LIFR']]], [["vis 0.5 layers [['SCT', 800], ['BKN', 1500], ['BKN', 2500]]", [0.5, [['SCT', 800], ['BKN', 1500], ['BKN', 2500]]], [1500, 'LIFR']], ["vis 3 layers [['BKN', 1000]]", [3, [['BKN', 1000]]], [1000, 'MVFR']], ["vis 3 layers [['SCT', 5000], ['FEW', 200]]", [3, [['SCT', 5000], ['FEW', 200]]], [None, 'MVFR']], ["vis 2 layers [['SCT', 5000]]", [2, [['SCT', 5000]]], [None, 'IFR']], ['vis 0.25 layers []', [0.25, []], [None, 'LIFR']], ["vis 6 layers [['BKN', 500], ['BKN', 5000]]", [6, [['BKN', 500], ['BKN', 5000]]], [500, 'IFR']], ["vis 5 layers [['BKN', 3100]]", [5, [['BKN', 3100]]], [3100, 'MVFR']], ["vis 0.25 layers [['BKN', 400], ['BKN', 200]]", [0.25, [['BKN', 400], ['BKN', 200]]], [200, 'LIFR']]], [["vis 4 layers [['VV', 2500]]", [4, [['VV', 2500]]], [2500, 'MVFR']], ["vis 0.25 layers [['FEW', 5000]]", [0.25, [['FEW', 5000]]], [None, 'LIFR']], ["vis 1 layers [['OVC', 500]]", [1, [['OVC', 500]]], [500, 'IFR']], ['vis 0.5 layers []', [0.5, []], [None, 'LIFR']], ["vis 10 layers [['FEW', 1500], ['OVC', 3000]]", [10, [['FEW', 1500], ['OVC', 3000]]], [3000, 'MVFR']], ['vis 1 layers []', [1, []], [None, 'IFR']], ["vis 0.25 layers [['BKN', 400], ['BKN', 200]]", [0.25, [['BKN', 400], ['BKN', 200]]], [200, 'LIFR']], ['unsorted layers', [10, [['OVC', 2500], ['BKN', 900]]], [900, 'IFR']]], [["vis 0.5 layers [['FEW', 400], ['VV', 400]]", [0.5, [['FEW', 400], ['VV', 400]]], [400, 'LIFR']], ["vis 0.25 layers [['BKN', 400], ['BKN', 200]]", [0.25, [['BKN', 400], ['BKN', 200]]], [200, 'LIFR']], ["vis 10 layers [['SCT', 3100]]", [10, [['SCT', 3100]]], [None, 'VFR']], ['vis 1 layers []', [1, []], [None, 'IFR']], ['vis 10 layers []', [10, []], [None, 'VFR']], ["vis 5 layers [['BKN', 500]]", [5, [['BKN', 500]]], [500, 'IFR']], ["vis 2 layers [['FEW', 2500], ['FEW', 800]]", [2, [['FEW', 2500], ['FEW', 800]]], [None, 'IFR']], ["vis 4 layers [['SCT', 200], ['VV', 400], ['VV', 5000]]", [4, [['SCT', 200], ['VV', 400], ['VV', 5000]]], [400, 'LIFR']]], [["vis 0.25 layers [['BKN', 400], ['BKN', 200]]", [0.25, [['BKN', 400], ['BKN', 200]]], [200, 'LIFR']], ["vis 3 layers [['SCT', 400]]", [3, [['SCT', 400]]], [None, 'MVFR']], ["vis 1 layers [['VV', 2500]]", [1, [['VV', 2500]]], [2500, 'IFR']], ['vis 6 layers []', [6, []], [None, 'VFR']], ["vis 3 layers [['FEW', 500], ['SCT', 1000], ['OVC', 400]]", [3, [['FEW', 500], ['SCT', 1000], ['OVC', 400]]], [400, 'LIFR']], ["vis 3 layers [['BKN', 5000]]", [3, [['BKN', 5000]]], [5000, 'MVFR']], ["vis 3 layers [['FEW', 200]]", [3, [['FEW', 200]]], [None, 'MVFR']], ["vis 0.5 layers [['BKN', 2500], ['OVC', 400]]", [0.5, [['BKN', 2500], ['OVC', 400]]], [400, 'LIFR']]]]
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
vis 4 layers [['BKN', 400]][400, 'LIFR'][400, 'LIFR']Passed
vis 5 layers [['FEW', 2500]][None, 'MVFR'][None, 'MVFR']Passed
vis 0.5 layers [][None, 'LIFR'][None, 'LIFR']Passed
vis 6 layers [['BKN', 3000]][3000, 'MVFR'][3000, 'MVFR']Passed
vis 0.5 layers [['SCT', 800], ['BKN', 1500], ['BKN', 2500]][2500, 'LIFR'][1500, 'LIFR']Failed
vis 2 layers [['OVC', 400], ['SCT', 5000], ['SCT', 200]][400, 'LIFR'][400, 'LIFR']Passed
vis 6 layers [['BKN', 500], ['BKN', 5000]][5000, 'VFR'][500, 'IFR']Failed
vis 0.25 layers [['BKN', 400], ['BKN', 200]][400, 'LIFR'][200, 'LIFR']Failed

SHA-256 / 59817d9d63f2e1d047ddb11ab78bc4643def0b5ee974314450a9cb7ede0e5d8c

HELD IN THE MEMBER ARCHIVE

The verified repair and its recorded checks are member-only.

This mechanism has 8 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

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

Case digest / 158deb665872a9579ad8d9ddbec291f49d6f7736cfb0198801341311b0e5ab7d