FAILURE MAP
← Case archive

FA-66796 / Airline fare rule evaluation / Open access

Piece charges restart after the free allowance · case 01

With one free bag the second bag is charged 30 instead of 40.

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

ROOT CAUSE

The fee schedule is indexed by paid-bag count instead of overall bag position.

VERIFIED REPAIR

Index the schedule by the bag position in check-in order.

Unsuccessful approach: Capping at the last schedule entry charges third and later bags 40 instead of 150.

Case contract

Input {'bags':[kg in check-in order],'allowance','elite'}. Any bag over 32 kg -> 'ERR_OVERWEIGHT_<i>' (first, zero-based). Free bags = allowance + 1 if elite, applied to the first bags. Base fee by overall bag position: 1st 30, 2nd 40, 3rd and later 150 (only for bags beyond the free count). Each bag over 23 kg adds 100, free or not. Return total.

Why this case matters

Baggage rules in fare families combine piece allowances, status benefits, position-based piece charges and weight surcharges.

1 / The failure

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

N = 1
observations = []
def solve(x):
    for i, kg in enumerate(x['bags']):
        if kg > 32: return 'ERR_OVERWEIGHT_%d' % i
    free = x['allowance'] + (1 if x['elite'] else 0)
    sched = [30, 40]
    total = 0
    for pos, kg in enumerate(x['bags'], 1):
        if pos > free:
            total += sched[pos - free - 1] if pos - free <= len(sched) else 150
        if kg > 23:
            total += 100
    return total
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['basic fare three bags', {'bags': [20.0, 18.5, 22.1], 'allowance': 0, 'elite': False}, 220], ['one free bag two paid', {'bags': [23.0, 21.0, 15.0], 'allowance': 1, 'elite': False}, 190], ['elite extra bag', {'bags': [19.0, 22.0, 20.0, 12.0], 'allowance': 1, 'elite': True}, 300], ['heavy free bag', {'bags': [28.0, 10.0], 'allowance': 1, 'elite': False}, 140], ['exactly hard limit', {'bags': [32.0, 23.4], 'allowance': 0, 'elite': False}, 270], ['over hard limit', {'bags': [20.0, 32.2], 'allowance': 2, 'elite': True}, 'ERR_OVERWEIGHT_1'], ['elite with two allowance', {'bags': [23.0, 23.0, 23.0, 23.0], 'allowance': 2, 'elite': True}, 150], ['sampled case 1', {'bags': [23.3, 23.3], 'allowance': 0, 'elite': False}, 270], ['sampled case 2', {'bags': [23.0], 'allowance': 1, 'elite': False}, 0], ['sampled case 3', {'bags': [23.3, 11.4, 20.9, 8.6], 'allowance': 2, 'elite': False}, 400]], [['basic fare three bags', {'bags': [20.0, 18.5, 22.2], 'allowance': 0, 'elite': False}, 220], ['one free bag two paid', {'bags': [23.0, 21.0, 15.0], 'allowance': 1, 'elite': False}, 190], ['elite extra bag', {'bags': [19.0, 22.0, 20.0, 12.0], 'allowance': 1, 'elite': True}, 300], ['heavy free bag', {'bags': [29.0, 10.0], 'allowance': 1, 'elite': False}, 140], ['exactly hard limit', {'bags': [32.0, 23.4], 'allowance': 0, 'elite': False}, 270], ['over hard limit', {'bags': [20.0, 32.300000000000004], 'allowance': 2, 'elite': True}, 'ERR_OVERWEIGHT_1'], ['elite with two allowance', {'bags': [23.0, 23.0, 23.0, 23.0, 23.0], 'allowance': 2, 'elite': True}, 300], ['sampled case 1', {'bags': [], 'allowance': 0, 'elite': True}, 0], ['sampled case 2', {'bags': [18.6, 32.0, 22.6], 'allowance': 2, 'elite': False}, 250], ['sampled case 3', {'bags': [18.1, 23.0, 32.0, 23.3, 23.0], 'allowance': 0, 'elite': False}, 720]], [['basic fare three bags', {'bags': [20.0, 18.5, 22.3], 'allowance': 0, 'elite': False}, 220], ['one free bag two paid', {'bags': [23.0, 21.0, 15.0], 'allowance': 1, 'elite': False}, 190], ['elite extra bag', {'bags': [19.0, 22.0, 20.0, 12.0], 'allowance': 1, 'elite': True}, 300], ['heavy free bag', {'bags': [30.0, 10.0], 'allowance': 1, 'elite': False}, 140], ['exactly hard limit', {'bags': [32.0, 23.4], 'allowance': 0, 'elite': False}, 270], ['over hard limit', {'bags': [20.0, 32.4], 'allowance': 2, 'elite': True}, 'ERR_OVERWEIGHT_1'], ['elite with two allowance', {'bags': [23.0, 23.0, 23.0], 'allowance': 2, 'elite': True}, 0], ['sampled case 1', {'bags': [32.0], 'allowance': 2, 'elite': True}, 100], ['sampled case 2', {'bags': [32.0, 23.3, 23.0], 'allowance': 0, 'elite': False}, 420], ['sampled case 3', {'bags': [], 'allowance': 1, 'elite': False}, 0]], [['basic fare three bags', {'bags': [20.0, 18.5, 22.4], 'allowance': 0, 'elite': False}, 220], ['one free bag two paid', {'bags': [23.0, 21.0, 15.0], 'allowance': 1, 'elite': False}, 190], ['elite extra bag', {'bags': [19.0, 22.0, 20.0, 12.0], 'allowance': 1, 'elite': True}, 300], ['heavy free bag', {'bags': [31.0, 10.0], 'allowance': 1, 'elite': False}, 140], ['exactly hard limit', {'bags': [32.0, 23.4], 'allowance': 0, 'elite': False}, 270], ['over hard limit', {'bags': [20.0, 32.5], 'allowance': 2, 'elite': True}, 'ERR_OVERWEIGHT_1'], ['elite with two allowance', {'bags': [23.0, 23.0, 23.0, 23.0], 'allowance': 2, 'elite': True}, 150], ['sampled case 1', {'bags': [32.0, 32.0, 32.0, 23.3, 23.3], 'allowance': 0, 'elite': False}, 1020], ['sampled case 2', {'bags': [], 'allowance': 1, 'elite': False}, 0], ['sampled case 3', {'bags': [20.4, 23.3], 'allowance': 1, 'elite': True}, 100]], [['basic fare three bags', {'bags': [20.0, 18.5, 22.5], 'allowance': 0, 'elite': False}, 220], ['one free bag two paid', {'bags': [23.0, 21.0, 15.0], 'allowance': 1, 'elite': False}, 190], ['elite extra bag', {'bags': [19.0, 22.0, 20.0, 12.0], 'allowance': 1, 'elite': True}, 300], ['heavy free bag', {'bags': [32.0, 10.0], 'allowance': 1, 'elite': False}, 140], ['exactly hard limit', {'bags': [32.0, 23.4], 'allowance': 0, 'elite': False}, 270], ['over hard limit', {'bags': [20.0, 32.6], 'allowance': 2, 'elite': True}, 'ERR_OVERWEIGHT_1'], ['elite with two allowance', {'bags': [23.0, 23.0, 23.0, 23.0, 23.0], 'allowance': 2, 'elite': True}, 300], ['sampled case 1', {'bags': [31.9, 23.3, 22.9, 32.0], 'allowance': 0, 'elite': False}, 670], ['sampled case 2', {'bags': [23.3, 32.0, 32.0, 23.0], 'allowance': 1, 'elite': True}, 600], ['sampled case 3', {'bags': [7.7, 32.0], 'allowance': 2, 'elite': True}, 100]]]
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
basic fare three bags220220Passed
one free bag two paid70190Failed
elite extra bag70300Failed
heavy free bag130140Failed
exactly hard limit270270Passed
over hard limitERR_OVERWEIGHT_1ERR_OVERWEIGHT_1Passed
elite with two allowance30150Failed
sampled case 1270270Passed
sampled case 200Passed
sampled case 3170400Failed

SHA-256 / 77d87bd0528cc7dce3d1eb97303b5858816e7fb188b6fd7494907f95a115220d

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(x):
    for i, kg in enumerate(x['bags']):
        if kg > 32: return 'ERR_OVERWEIGHT_%d' % i
    free = x['allowance'] + (1 if x['elite'] else 0)
    sched = [30, 40]
    total = 0
    for pos, kg in enumerate(x['bags'], 1):
        if pos > free:
            total += sched[min(pos, len(sched)) - 1]
        if kg > 23:
            total += 100
    return total
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['basic fare three bags', {'bags': [20.0, 18.5, 22.1], 'allowance': 0, 'elite': False}, 220], ['one free bag two paid', {'bags': [23.0, 21.0, 15.0], 'allowance': 1, 'elite': False}, 190], ['elite extra bag', {'bags': [19.0, 22.0, 20.0, 12.0], 'allowance': 1, 'elite': True}, 300], ['heavy free bag', {'bags': [28.0, 10.0], 'allowance': 1, 'elite': False}, 140], ['exactly hard limit', {'bags': [32.0, 23.4], 'allowance': 0, 'elite': False}, 270], ['over hard limit', {'bags': [20.0, 32.2], 'allowance': 2, 'elite': True}, 'ERR_OVERWEIGHT_1'], ['elite with two allowance', {'bags': [23.0, 23.0, 23.0, 23.0], 'allowance': 2, 'elite': True}, 150], ['sampled case 1', {'bags': [23.3, 23.3], 'allowance': 0, 'elite': False}, 270], ['sampled case 2', {'bags': [23.0], 'allowance': 1, 'elite': False}, 0], ['sampled case 3', {'bags': [23.3, 11.4, 20.9, 8.6], 'allowance': 2, 'elite': False}, 400]], [['basic fare three bags', {'bags': [20.0, 18.5, 22.2], 'allowance': 0, 'elite': False}, 220], ['one free bag two paid', {'bags': [23.0, 21.0, 15.0], 'allowance': 1, 'elite': False}, 190], ['elite extra bag', {'bags': [19.0, 22.0, 20.0, 12.0], 'allowance': 1, 'elite': True}, 300], ['heavy free bag', {'bags': [29.0, 10.0], 'allowance': 1, 'elite': False}, 140], ['exactly hard limit', {'bags': [32.0, 23.4], 'allowance': 0, 'elite': False}, 270], ['over hard limit', {'bags': [20.0, 32.300000000000004], 'allowance': 2, 'elite': True}, 'ERR_OVERWEIGHT_1'], ['elite with two allowance', {'bags': [23.0, 23.0, 23.0, 23.0, 23.0], 'allowance': 2, 'elite': True}, 300], ['sampled case 1', {'bags': [], 'allowance': 0, 'elite': True}, 0], ['sampled case 2', {'bags': [18.6, 32.0, 22.6], 'allowance': 2, 'elite': False}, 250], ['sampled case 3', {'bags': [18.1, 23.0, 32.0, 23.3, 23.0], 'allowance': 0, 'elite': False}, 720]], [['basic fare three bags', {'bags': [20.0, 18.5, 22.3], 'allowance': 0, 'elite': False}, 220], ['one free bag two paid', {'bags': [23.0, 21.0, 15.0], 'allowance': 1, 'elite': False}, 190], ['elite extra bag', {'bags': [19.0, 22.0, 20.0, 12.0], 'allowance': 1, 'elite': True}, 300], ['heavy free bag', {'bags': [30.0, 10.0], 'allowance': 1, 'elite': False}, 140], ['exactly hard limit', {'bags': [32.0, 23.4], 'allowance': 0, 'elite': False}, 270], ['over hard limit', {'bags': [20.0, 32.4], 'allowance': 2, 'elite': True}, 'ERR_OVERWEIGHT_1'], ['elite with two allowance', {'bags': [23.0, 23.0, 23.0], 'allowance': 2, 'elite': True}, 0], ['sampled case 1', {'bags': [32.0], 'allowance': 2, 'elite': True}, 100], ['sampled case 2', {'bags': [32.0, 23.3, 23.0], 'allowance': 0, 'elite': False}, 420], ['sampled case 3', {'bags': [], 'allowance': 1, 'elite': False}, 0]], [['basic fare three bags', {'bags': [20.0, 18.5, 22.4], 'allowance': 0, 'elite': False}, 220], ['one free bag two paid', {'bags': [23.0, 21.0, 15.0], 'allowance': 1, 'elite': False}, 190], ['elite extra bag', {'bags': [19.0, 22.0, 20.0, 12.0], 'allowance': 1, 'elite': True}, 300], ['heavy free bag', {'bags': [31.0, 10.0], 'allowance': 1, 'elite': False}, 140], ['exactly hard limit', {'bags': [32.0, 23.4], 'allowance': 0, 'elite': False}, 270], ['over hard limit', {'bags': [20.0, 32.5], 'allowance': 2, 'elite': True}, 'ERR_OVERWEIGHT_1'], ['elite with two allowance', {'bags': [23.0, 23.0, 23.0, 23.0], 'allowance': 2, 'elite': True}, 150], ['sampled case 1', {'bags': [32.0, 32.0, 32.0, 23.3, 23.3], 'allowance': 0, 'elite': False}, 1020], ['sampled case 2', {'bags': [], 'allowance': 1, 'elite': False}, 0], ['sampled case 3', {'bags': [20.4, 23.3], 'allowance': 1, 'elite': True}, 100]], [['basic fare three bags', {'bags': [20.0, 18.5, 22.5], 'allowance': 0, 'elite': False}, 220], ['one free bag two paid', {'bags': [23.0, 21.0, 15.0], 'allowance': 1, 'elite': False}, 190], ['elite extra bag', {'bags': [19.0, 22.0, 20.0, 12.0], 'allowance': 1, 'elite': True}, 300], ['heavy free bag', {'bags': [32.0, 10.0], 'allowance': 1, 'elite': False}, 140], ['exactly hard limit', {'bags': [32.0, 23.4], 'allowance': 0, 'elite': False}, 270], ['over hard limit', {'bags': [20.0, 32.6], 'allowance': 2, 'elite': True}, 'ERR_OVERWEIGHT_1'], ['elite with two allowance', {'bags': [23.0, 23.0, 23.0, 23.0, 23.0], 'allowance': 2, 'elite': True}, 300], ['sampled case 1', {'bags': [31.9, 23.3, 22.9, 32.0], 'allowance': 0, 'elite': False}, 670], ['sampled case 2', {'bags': [23.3, 32.0, 32.0, 23.0], 'allowance': 1, 'elite': True}, 600], ['sampled case 3', {'bags': [7.7, 32.0], 'allowance': 2, 'elite': True}, 100]]]
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
basic fare three bags110220Failed
one free bag two paid80190Failed
elite extra bag80300Failed
heavy free bag140140Passed
exactly hard limit270270Passed
over hard limitERR_OVERWEIGHT_1ERR_OVERWEIGHT_1Passed
elite with two allowance40150Failed
sampled case 1270270Passed
sampled case 200Passed
sampled case 3180400Failed

SHA-256 / 201142a07d7fe5556e0a13eb590e6a2d87bcf9f369b7d7f544a41e4834f1cc6c

3 / The verified repair

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

N = 1
observations = []
def solve(x):
    for i, kg in enumerate(x['bags']):
        if kg > 32: return 'ERR_OVERWEIGHT_%d' % i
    free = x['allowance'] + (1 if x['elite'] else 0)
    sched = [30, 40]
    total = 0
    for pos, kg in enumerate(x['bags'], 1):
        if pos > free:
            total += sched[pos - 1] if pos <= len(sched) else 150
        if kg > 23:
            total += 100
    return total
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['basic fare three bags', {'bags': [20.0, 18.5, 22.1], 'allowance': 0, 'elite': False}, 220], ['one free bag two paid', {'bags': [23.0, 21.0, 15.0], 'allowance': 1, 'elite': False}, 190], ['elite extra bag', {'bags': [19.0, 22.0, 20.0, 12.0], 'allowance': 1, 'elite': True}, 300], ['heavy free bag', {'bags': [28.0, 10.0], 'allowance': 1, 'elite': False}, 140], ['exactly hard limit', {'bags': [32.0, 23.4], 'allowance': 0, 'elite': False}, 270], ['over hard limit', {'bags': [20.0, 32.2], 'allowance': 2, 'elite': True}, 'ERR_OVERWEIGHT_1'], ['elite with two allowance', {'bags': [23.0, 23.0, 23.0, 23.0], 'allowance': 2, 'elite': True}, 150], ['sampled case 1', {'bags': [23.3, 23.3], 'allowance': 0, 'elite': False}, 270], ['sampled case 2', {'bags': [23.0], 'allowance': 1, 'elite': False}, 0], ['sampled case 3', {'bags': [23.3, 11.4, 20.9, 8.6], 'allowance': 2, 'elite': False}, 400]], [['basic fare three bags', {'bags': [20.0, 18.5, 22.2], 'allowance': 0, 'elite': False}, 220], ['one free bag two paid', {'bags': [23.0, 21.0, 15.0], 'allowance': 1, 'elite': False}, 190], ['elite extra bag', {'bags': [19.0, 22.0, 20.0, 12.0], 'allowance': 1, 'elite': True}, 300], ['heavy free bag', {'bags': [29.0, 10.0], 'allowance': 1, 'elite': False}, 140], ['exactly hard limit', {'bags': [32.0, 23.4], 'allowance': 0, 'elite': False}, 270], ['over hard limit', {'bags': [20.0, 32.300000000000004], 'allowance': 2, 'elite': True}, 'ERR_OVERWEIGHT_1'], ['elite with two allowance', {'bags': [23.0, 23.0, 23.0, 23.0, 23.0], 'allowance': 2, 'elite': True}, 300], ['sampled case 1', {'bags': [], 'allowance': 0, 'elite': True}, 0], ['sampled case 2', {'bags': [18.6, 32.0, 22.6], 'allowance': 2, 'elite': False}, 250], ['sampled case 3', {'bags': [18.1, 23.0, 32.0, 23.3, 23.0], 'allowance': 0, 'elite': False}, 720]], [['basic fare three bags', {'bags': [20.0, 18.5, 22.3], 'allowance': 0, 'elite': False}, 220], ['one free bag two paid', {'bags': [23.0, 21.0, 15.0], 'allowance': 1, 'elite': False}, 190], ['elite extra bag', {'bags': [19.0, 22.0, 20.0, 12.0], 'allowance': 1, 'elite': True}, 300], ['heavy free bag', {'bags': [30.0, 10.0], 'allowance': 1, 'elite': False}, 140], ['exactly hard limit', {'bags': [32.0, 23.4], 'allowance': 0, 'elite': False}, 270], ['over hard limit', {'bags': [20.0, 32.4], 'allowance': 2, 'elite': True}, 'ERR_OVERWEIGHT_1'], ['elite with two allowance', {'bags': [23.0, 23.0, 23.0], 'allowance': 2, 'elite': True}, 0], ['sampled case 1', {'bags': [32.0], 'allowance': 2, 'elite': True}, 100], ['sampled case 2', {'bags': [32.0, 23.3, 23.0], 'allowance': 0, 'elite': False}, 420], ['sampled case 3', {'bags': [], 'allowance': 1, 'elite': False}, 0]], [['basic fare three bags', {'bags': [20.0, 18.5, 22.4], 'allowance': 0, 'elite': False}, 220], ['one free bag two paid', {'bags': [23.0, 21.0, 15.0], 'allowance': 1, 'elite': False}, 190], ['elite extra bag', {'bags': [19.0, 22.0, 20.0, 12.0], 'allowance': 1, 'elite': True}, 300], ['heavy free bag', {'bags': [31.0, 10.0], 'allowance': 1, 'elite': False}, 140], ['exactly hard limit', {'bags': [32.0, 23.4], 'allowance': 0, 'elite': False}, 270], ['over hard limit', {'bags': [20.0, 32.5], 'allowance': 2, 'elite': True}, 'ERR_OVERWEIGHT_1'], ['elite with two allowance', {'bags': [23.0, 23.0, 23.0, 23.0], 'allowance': 2, 'elite': True}, 150], ['sampled case 1', {'bags': [32.0, 32.0, 32.0, 23.3, 23.3], 'allowance': 0, 'elite': False}, 1020], ['sampled case 2', {'bags': [], 'allowance': 1, 'elite': False}, 0], ['sampled case 3', {'bags': [20.4, 23.3], 'allowance': 1, 'elite': True}, 100]], [['basic fare three bags', {'bags': [20.0, 18.5, 22.5], 'allowance': 0, 'elite': False}, 220], ['one free bag two paid', {'bags': [23.0, 21.0, 15.0], 'allowance': 1, 'elite': False}, 190], ['elite extra bag', {'bags': [19.0, 22.0, 20.0, 12.0], 'allowance': 1, 'elite': True}, 300], ['heavy free bag', {'bags': [32.0, 10.0], 'allowance': 1, 'elite': False}, 140], ['exactly hard limit', {'bags': [32.0, 23.4], 'allowance': 0, 'elite': False}, 270], ['over hard limit', {'bags': [20.0, 32.6], 'allowance': 2, 'elite': True}, 'ERR_OVERWEIGHT_1'], ['elite with two allowance', {'bags': [23.0, 23.0, 23.0, 23.0, 23.0], 'allowance': 2, 'elite': True}, 300], ['sampled case 1', {'bags': [31.9, 23.3, 22.9, 32.0], 'allowance': 0, 'elite': False}, 670], ['sampled case 2', {'bags': [23.3, 32.0, 32.0, 23.0], 'allowance': 1, 'elite': True}, 600], ['sampled case 3', {'bags': [7.7, 32.0], 'allowance': 2, 'elite': True}, 100]]]
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
basic fare three bags220220Passed
one free bag two paid190190Passed
elite extra bag300300Passed
heavy free bag140140Passed
exactly hard limit270270Passed
over hard limitERR_OVERWEIGHT_1ERR_OVERWEIGHT_1Passed
elite with two allowance150150Passed
sampled case 1270270Passed
sampled case 200Passed
sampled case 3400400Passed

SHA-256 / 7b029ecc83ee8ed6d85bdbd34c5a87dd8bb519b8bd5c19a826ccde10937c9fbf

Verification & scope

A stipulated toy fare-rule contract with invented constants; it is not an ATPCO or carrier tariff implementation and makes no claim of industry-standard conformance. 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:46.916881+00:00.

Case digest / 0d35174f84d41eb0583c56a8bf9ee749291495f0f53bb752aa585c15ee36861d