FA-60766 / Loyalty points ledgers / Open access
Points plus cash split: minimum cash reservation · case 01
Awards are fully paid with points although a cash co-pay is required.
ROOT CAUSE
The room for points is the whole price, not price minus minimum cash.
VERIFIED REPAIR
Room = price - minimum cash.
Unsuccessful approach: Forcing cash up to the minimum afterwards still deducts the extra points.
Case contract
Input {price, balance, cpp10 (point value in tenths of a cent), min_cash}. Points may cover at most price - min_cash (never negative): max points = floor((price - min_cash)*10/cpp10), limited by balance. Credit = floor(points*cpp10/10); cash = price - credit. Return {points, cash}.
Why this case matters
Member point balances, statements and the program liability depend on this ledger rule.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
room = x['price']
maxp = max(0, room * 10 // x['cpp10'])
pts = min(x['balance'], maxp)
credit = pts * x['cpp10'] // 10
return {'points': pts, 'cash': x['price'] - credit}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['points cover most', {'price': 10000, 'balance': 50000, 'cpp10': 12, 'min_cash': 501}, {'points': 7915, 'cash': 502}], ['balance limits', {'price': 10000, 'balance': 3001, 'cpp10': 10, 'min_cash': 100}, {'points': 3001, 'cash': 6999}], ['fractional value', {'price': 4999, 'balance': 99999, 'cpp10': 7, 'min_cash': 2}, {'points': 7138, 'cash': 3}], ['price below minimum cash', {'price': 300, 'balance': 1000, 'cpp10': 10, 'min_cash': 401}, {'points': 0, 'cash': 300}], ['exact minimum', {'price': 1000, 'balance': 100000, 'cpp10': 25, 'min_cash': 990}, {'points': 4, 'cash': 990}], ['odd credit', {'price': 2503, 'balance': 1238, 'cpp10': 13, 'min_cash': 3}, {'points': 1238, 'cash': 894}]], [['points cover most', {'price': 10000, 'balance': 50000, 'cpp10': 12, 'min_cash': 502}, {'points': 7915, 'cash': 502}], ['balance limits', {'price': 10000, 'balance': 3002, 'cpp10': 10, 'min_cash': 100}, {'points': 3002, 'cash': 6998}], ['fractional value', {'price': 4999, 'balance': 99999, 'cpp10': 7, 'min_cash': 3}, {'points': 7137, 'cash': 4}], ['price below minimum cash', {'price': 300, 'balance': 1000, 'cpp10': 10, 'min_cash': 402}, {'points': 0, 'cash': 300}], ['exact minimum', {'price': 1000, 'balance': 100000, 'cpp10': 25, 'min_cash': 980}, {'points': 8, 'cash': 980}], ['odd credit', {'price': 2503, 'balance': 1239, 'cpp10': 13, 'min_cash': 3}, {'points': 1239, 'cash': 893}]], [['points cover most', {'price': 10000, 'balance': 50000, 'cpp10': 12, 'min_cash': 503}, {'points': 7914, 'cash': 504}], ['balance limits', {'price': 10000, 'balance': 3003, 'cpp10': 10, 'min_cash': 100}, {'points': 3003, 'cash': 6997}], ['fractional value', {'price': 4999, 'balance': 99999, 'cpp10': 7, 'min_cash': 4}, {'points': 7135, 'cash': 5}], ['price below minimum cash', {'price': 300, 'balance': 1000, 'cpp10': 10, 'min_cash': 403}, {'points': 0, 'cash': 300}], ['exact minimum', {'price': 1000, 'balance': 100000, 'cpp10': 25, 'min_cash': 970}, {'points': 12, 'cash': 970}], ['odd credit', {'price': 2503, 'balance': 1240, 'cpp10': 13, 'min_cash': 3}, {'points': 1240, 'cash': 891}]], [['points cover most', {'price': 10000, 'balance': 50000, 'cpp10': 12, 'min_cash': 504}, {'points': 7913, 'cash': 505}], ['balance limits', {'price': 10000, 'balance': 3004, 'cpp10': 10, 'min_cash': 100}, {'points': 3004, 'cash': 6996}], ['fractional value', {'price': 4999, 'balance': 99999, 'cpp10': 7, 'min_cash': 5}, {'points': 7134, 'cash': 6}], ['price below minimum cash', {'price': 300, 'balance': 1000, 'cpp10': 10, 'min_cash': 404}, {'points': 0, 'cash': 300}], ['exact minimum', {'price': 1000, 'balance': 100000, 'cpp10': 25, 'min_cash': 960}, {'points': 16, 'cash': 960}], ['odd credit', {'price': 2503, 'balance': 1241, 'cpp10': 13, 'min_cash': 3}, {'points': 1241, 'cash': 890}]], [['points cover most', {'price': 10000, 'balance': 50000, 'cpp10': 12, 'min_cash': 505}, {'points': 7912, 'cash': 506}], ['balance limits', {'price': 10000, 'balance': 3005, 'cpp10': 10, 'min_cash': 100}, {'points': 3005, 'cash': 6995}], ['fractional value', {'price': 4999, 'balance': 99999, 'cpp10': 7, 'min_cash': 6}, {'points': 7132, 'cash': 7}], ['price below minimum cash', {'price': 300, 'balance': 1000, 'cpp10': 10, 'min_cash': 405}, {'points': 0, 'cash': 300}], ['exact minimum', {'price': 1000, 'balance': 100000, 'cpp10': 25, 'min_cash': 950}, {'points': 20, 'cash': 950}], ['odd credit', {'price': 2503, 'balance': 1242, 'cpp10': 13, 'min_cash': 3}, {'points': 1242, 'cash': 889}]]]
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 |
|---|---|---|---|
| points cover most | {'cash': 1, 'points': 8333} | {'cash': 502, 'points': 7915} | Failed |
| balance limits | {'cash': 6999, 'points': 3001} | {'cash': 6999, 'points': 3001} | Passed |
| fractional value | {'cash': 1, 'points': 7141} | {'cash': 3, 'points': 7138} | Failed |
| price below minimum cash | {'cash': 0, 'points': 300} | {'cash': 300, 'points': 0} | Failed |
| exact minimum | {'cash': 0, 'points': 400} | {'cash': 990, 'points': 4} | Failed |
| odd credit | {'cash': 894, 'points': 1238} | {'cash': 894, 'points': 1238} | Passed |
SHA-256 / 2e7979165e345de3e5a08b7b37a8923b5559a28c0694ab14a56bd36c4474fded
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
room = x['price']
maxp = max(0, room * 10 // x['cpp10'])
pts = min(x['balance'], maxp)
credit = pts * x['cpp10'] // 10
return {'points': pts, 'cash': max(x['min_cash'], x['price'] - credit)}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['points cover most', {'price': 10000, 'balance': 50000, 'cpp10': 12, 'min_cash': 501}, {'points': 7915, 'cash': 502}], ['balance limits', {'price': 10000, 'balance': 3001, 'cpp10': 10, 'min_cash': 100}, {'points': 3001, 'cash': 6999}], ['fractional value', {'price': 4999, 'balance': 99999, 'cpp10': 7, 'min_cash': 2}, {'points': 7138, 'cash': 3}], ['price below minimum cash', {'price': 300, 'balance': 1000, 'cpp10': 10, 'min_cash': 401}, {'points': 0, 'cash': 300}], ['exact minimum', {'price': 1000, 'balance': 100000, 'cpp10': 25, 'min_cash': 990}, {'points': 4, 'cash': 990}], ['odd credit', {'price': 2503, 'balance': 1238, 'cpp10': 13, 'min_cash': 3}, {'points': 1238, 'cash': 894}]], [['points cover most', {'price': 10000, 'balance': 50000, 'cpp10': 12, 'min_cash': 502}, {'points': 7915, 'cash': 502}], ['balance limits', {'price': 10000, 'balance': 3002, 'cpp10': 10, 'min_cash': 100}, {'points': 3002, 'cash': 6998}], ['fractional value', {'price': 4999, 'balance': 99999, 'cpp10': 7, 'min_cash': 3}, {'points': 7137, 'cash': 4}], ['price below minimum cash', {'price': 300, 'balance': 1000, 'cpp10': 10, 'min_cash': 402}, {'points': 0, 'cash': 300}], ['exact minimum', {'price': 1000, 'balance': 100000, 'cpp10': 25, 'min_cash': 980}, {'points': 8, 'cash': 980}], ['odd credit', {'price': 2503, 'balance': 1239, 'cpp10': 13, 'min_cash': 3}, {'points': 1239, 'cash': 893}]], [['points cover most', {'price': 10000, 'balance': 50000, 'cpp10': 12, 'min_cash': 503}, {'points': 7914, 'cash': 504}], ['balance limits', {'price': 10000, 'balance': 3003, 'cpp10': 10, 'min_cash': 100}, {'points': 3003, 'cash': 6997}], ['fractional value', {'price': 4999, 'balance': 99999, 'cpp10': 7, 'min_cash': 4}, {'points': 7135, 'cash': 5}], ['price below minimum cash', {'price': 300, 'balance': 1000, 'cpp10': 10, 'min_cash': 403}, {'points': 0, 'cash': 300}], ['exact minimum', {'price': 1000, 'balance': 100000, 'cpp10': 25, 'min_cash': 970}, {'points': 12, 'cash': 970}], ['odd credit', {'price': 2503, 'balance': 1240, 'cpp10': 13, 'min_cash': 3}, {'points': 1240, 'cash': 891}]], [['points cover most', {'price': 10000, 'balance': 50000, 'cpp10': 12, 'min_cash': 504}, {'points': 7913, 'cash': 505}], ['balance limits', {'price': 10000, 'balance': 3004, 'cpp10': 10, 'min_cash': 100}, {'points': 3004, 'cash': 6996}], ['fractional value', {'price': 4999, 'balance': 99999, 'cpp10': 7, 'min_cash': 5}, {'points': 7134, 'cash': 6}], ['price below minimum cash', {'price': 300, 'balance': 1000, 'cpp10': 10, 'min_cash': 404}, {'points': 0, 'cash': 300}], ['exact minimum', {'price': 1000, 'balance': 100000, 'cpp10': 25, 'min_cash': 960}, {'points': 16, 'cash': 960}], ['odd credit', {'price': 2503, 'balance': 1241, 'cpp10': 13, 'min_cash': 3}, {'points': 1241, 'cash': 890}]], [['points cover most', {'price': 10000, 'balance': 50000, 'cpp10': 12, 'min_cash': 505}, {'points': 7912, 'cash': 506}], ['balance limits', {'price': 10000, 'balance': 3005, 'cpp10': 10, 'min_cash': 100}, {'points': 3005, 'cash': 6995}], ['fractional value', {'price': 4999, 'balance': 99999, 'cpp10': 7, 'min_cash': 6}, {'points': 7132, 'cash': 7}], ['price below minimum cash', {'price': 300, 'balance': 1000, 'cpp10': 10, 'min_cash': 405}, {'points': 0, 'cash': 300}], ['exact minimum', {'price': 1000, 'balance': 100000, 'cpp10': 25, 'min_cash': 950}, {'points': 20, 'cash': 950}], ['odd credit', {'price': 2503, 'balance': 1242, 'cpp10': 13, 'min_cash': 3}, {'points': 1242, 'cash': 889}]]]
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 |
|---|---|---|---|
| points cover most | {'cash': 501, 'points': 8333} | {'cash': 502, 'points': 7915} | Failed |
| balance limits | {'cash': 6999, 'points': 3001} | {'cash': 6999, 'points': 3001} | Passed |
| fractional value | {'cash': 2, 'points': 7141} | {'cash': 3, 'points': 7138} | Failed |
| price below minimum cash | {'cash': 401, 'points': 300} | {'cash': 300, 'points': 0} | Failed |
| exact minimum | {'cash': 990, 'points': 400} | {'cash': 990, 'points': 4} | Failed |
| odd credit | {'cash': 894, 'points': 1238} | {'cash': 894, 'points': 1238} | Passed |
SHA-256 / df103ba2d9ca3eb2623e1e774614f9e3fddbb69be6f8c4ddd5ed4f83962356bb
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
room = x['price'] - x['min_cash']
maxp = max(0, room * 10 // x['cpp10'])
pts = min(x['balance'], maxp)
credit = pts * x['cpp10'] // 10
return {'points': pts, 'cash': x['price'] - credit}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['points cover most', {'price': 10000, 'balance': 50000, 'cpp10': 12, 'min_cash': 501}, {'points': 7915, 'cash': 502}], ['balance limits', {'price': 10000, 'balance': 3001, 'cpp10': 10, 'min_cash': 100}, {'points': 3001, 'cash': 6999}], ['fractional value', {'price': 4999, 'balance': 99999, 'cpp10': 7, 'min_cash': 2}, {'points': 7138, 'cash': 3}], ['price below minimum cash', {'price': 300, 'balance': 1000, 'cpp10': 10, 'min_cash': 401}, {'points': 0, 'cash': 300}], ['exact minimum', {'price': 1000, 'balance': 100000, 'cpp10': 25, 'min_cash': 990}, {'points': 4, 'cash': 990}], ['odd credit', {'price': 2503, 'balance': 1238, 'cpp10': 13, 'min_cash': 3}, {'points': 1238, 'cash': 894}]], [['points cover most', {'price': 10000, 'balance': 50000, 'cpp10': 12, 'min_cash': 502}, {'points': 7915, 'cash': 502}], ['balance limits', {'price': 10000, 'balance': 3002, 'cpp10': 10, 'min_cash': 100}, {'points': 3002, 'cash': 6998}], ['fractional value', {'price': 4999, 'balance': 99999, 'cpp10': 7, 'min_cash': 3}, {'points': 7137, 'cash': 4}], ['price below minimum cash', {'price': 300, 'balance': 1000, 'cpp10': 10, 'min_cash': 402}, {'points': 0, 'cash': 300}], ['exact minimum', {'price': 1000, 'balance': 100000, 'cpp10': 25, 'min_cash': 980}, {'points': 8, 'cash': 980}], ['odd credit', {'price': 2503, 'balance': 1239, 'cpp10': 13, 'min_cash': 3}, {'points': 1239, 'cash': 893}]], [['points cover most', {'price': 10000, 'balance': 50000, 'cpp10': 12, 'min_cash': 503}, {'points': 7914, 'cash': 504}], ['balance limits', {'price': 10000, 'balance': 3003, 'cpp10': 10, 'min_cash': 100}, {'points': 3003, 'cash': 6997}], ['fractional value', {'price': 4999, 'balance': 99999, 'cpp10': 7, 'min_cash': 4}, {'points': 7135, 'cash': 5}], ['price below minimum cash', {'price': 300, 'balance': 1000, 'cpp10': 10, 'min_cash': 403}, {'points': 0, 'cash': 300}], ['exact minimum', {'price': 1000, 'balance': 100000, 'cpp10': 25, 'min_cash': 970}, {'points': 12, 'cash': 970}], ['odd credit', {'price': 2503, 'balance': 1240, 'cpp10': 13, 'min_cash': 3}, {'points': 1240, 'cash': 891}]], [['points cover most', {'price': 10000, 'balance': 50000, 'cpp10': 12, 'min_cash': 504}, {'points': 7913, 'cash': 505}], ['balance limits', {'price': 10000, 'balance': 3004, 'cpp10': 10, 'min_cash': 100}, {'points': 3004, 'cash': 6996}], ['fractional value', {'price': 4999, 'balance': 99999, 'cpp10': 7, 'min_cash': 5}, {'points': 7134, 'cash': 6}], ['price below minimum cash', {'price': 300, 'balance': 1000, 'cpp10': 10, 'min_cash': 404}, {'points': 0, 'cash': 300}], ['exact minimum', {'price': 1000, 'balance': 100000, 'cpp10': 25, 'min_cash': 960}, {'points': 16, 'cash': 960}], ['odd credit', {'price': 2503, 'balance': 1241, 'cpp10': 13, 'min_cash': 3}, {'points': 1241, 'cash': 890}]], [['points cover most', {'price': 10000, 'balance': 50000, 'cpp10': 12, 'min_cash': 505}, {'points': 7912, 'cash': 506}], ['balance limits', {'price': 10000, 'balance': 3005, 'cpp10': 10, 'min_cash': 100}, {'points': 3005, 'cash': 6995}], ['fractional value', {'price': 4999, 'balance': 99999, 'cpp10': 7, 'min_cash': 6}, {'points': 7132, 'cash': 7}], ['price below minimum cash', {'price': 300, 'balance': 1000, 'cpp10': 10, 'min_cash': 405}, {'points': 0, 'cash': 300}], ['exact minimum', {'price': 1000, 'balance': 100000, 'cpp10': 25, 'min_cash': 950}, {'points': 20, 'cash': 950}], ['odd credit', {'price': 2503, 'balance': 1242, 'cpp10': 13, 'min_cash': 3}, {'points': 1242, 'cash': 889}]]]
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 |
|---|---|---|---|
| points cover most | {'cash': 502, 'points': 7915} | {'cash': 502, 'points': 7915} | Passed |
| balance limits | {'cash': 6999, 'points': 3001} | {'cash': 6999, 'points': 3001} | Passed |
| fractional value | {'cash': 3, 'points': 7138} | {'cash': 3, 'points': 7138} | Passed |
| price below minimum cash | {'cash': 300, 'points': 0} | {'cash': 300, 'points': 0} | Passed |
| exact minimum | {'cash': 990, 'points': 4} | {'cash': 990, 'points': 4} | Passed |
| odd credit | {'cash': 894, 'points': 1238} | {'cash': 894, 'points': 1238} | Passed |
SHA-256 / 6a3a096f75629960c941299f5b1f3aa96e6ad7e702b531f61a3cf1fcd888a4e7
Verification & scope
Stipulated bounded loyalty-program model with explicit toy rules; not any real program terms. 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:46:48.648915+00:00.
Case digest / 0dc2b674dc651ca48243cffb72ae8fe4cb51f79d6ee487ca7001689903f85c53