FAILURE MAP
← Case archive

FA-60621 / Loyalty points ledgers / Open access

Idempotent points event ledger: timestamp tie ordering · case 01

Events with equal timestamps are applied in delivery order, so a redeem can be rejected before its funding earn.

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

ROOT CAUSE

Sorting uses the timestamp alone and relies on delivery order for ties.

VERIFIED REPAIR

Sort by (ts, id).

Unsuccessful approach: Sorting by id alone ignores timestamps entirely.

Case contract

Input {events:[{id,ts,type:"earn"|"redeem"|"reverse",pts,ref}]}. Duplicate ids are dropped keeping the first delivery in input order; survivors are applied sorted by (ts,id). Redeem requires balance >= pts or is rejected. Reverse undoes an applied earn or redeem once; unknown, rejected, already reversed, or reverse targets are rejected. Return {balance, rejected, applied}.

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):
    seen = set()
    evs = []
    for e in x['events']:
        if e['id'] in seen:
            continue
        seen.add(e['id'])
        evs.append(e)
    evs.sort(key=lambda e: e['ts'])
    bal = 0
    applied = {}
    undone = set()
    rej = []
    order = []
    for e in evs:
        t = e['type']
        if t == 'earn':
            bal += e['pts']
            applied[e['id']] = e['pts']
        elif t == 'redeem':
            if e['pts'] > bal:
                rej.append(e['id'])
                continue
            bal -= e['pts']
            applied[e['id']] = -e['pts']
        else:
            r = e['ref']
            if r not in applied or r in undone:
                rej.append(e['id'])
                continue
            bal -= applied[r]
            undone.add(r)
        order.append(e['id'])
    return {'balance': bal, 'rejected': rej, 'applied': order}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['out of order', {'events': [{'id': 'e2', 'ts': 5, 'type': 'redeem', 'pts': 50, 'ref': None}, {'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 101, 'ref': None}]}, {'balance': 51, 'rejected': [], 'applied': ['e1', 'e2']}], ['duplicate delivery', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 100, 'ref': None}, {'id': 'e1', 'ts': 9, 'type': 'earn', 'pts': 100, 'ref': None}, {'id': 'e2', 'ts': 5, 'type': 'redeem', 'pts': 151, 'ref': None}]}, {'balance': 100, 'rejected': ['e2'], 'applied': ['e1']}], ['reverse redemption', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 200, 'ref': None}, {'id': 'e2', 'ts': 2, 'type': 'redeem', 'pts': 81, 'ref': None}, {'id': 'e3', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e2'}]}, {'balance': 200, 'rejected': [], 'applied': ['e1', 'e2', 'e3']}], ['double reverse', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 61, 'ref': None}, {'id': 'r1', 'ts': 2, 'type': 'reverse', 'pts': 0, 'ref': 'e1'}, {'id': 'r2', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e1'}, {'id': 'r3', 'ts': 4, 'type': 'reverse', 'pts': 0, 'ref': 'r1'}]}, {'balance': 0, 'rejected': ['r2', 'r3'], 'applied': ['e1', 'r1']}], ['reverse rejected redeem', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 10, 'ref': None}, {'id': 'e2', 'ts': 2, 'type': 'redeem', 'pts': 51, 'ref': None}, {'id': 'e3', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e2'}]}, {'balance': 10, 'rejected': ['e2', 'e3'], 'applied': ['e1']}], ['same timestamp', {'events': [{'id': 'b', 'ts': 7, 'type': 'redeem', 'pts': 30, 'ref': None}, {'id': 'a', 'ts': 7, 'type': 'earn', 'pts': 31, 'ref': None}]}, {'balance': 1, 'rejected': [], 'applied': ['a', 'b']}], ['unknown reverse', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 5, 'ref': None}, {'id': 'x', 'ts': 2, 'type': 'reverse', 'pts': 0, 'ref': 'nope'}]}, {'balance': 5, 'rejected': ['x'], 'applied': ['e1']}], ['ids against time', {'events': [{'id': 'a', 'ts': 9, 'type': 'redeem', 'pts': 20, 'ref': None}, {'id': 'b', 'ts': 2, 'type': 'earn', 'pts': 31, 'ref': None}]}, {'balance': 11, 'rejected': [], 'applied': ['b', 'a']}]], [['out of order', {'events': [{'id': 'e2', 'ts': 5, 'type': 'redeem', 'pts': 50, 'ref': None}, {'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 102, 'ref': None}]}, {'balance': 52, 'rejected': [], 'applied': ['e1', 'e2']}], ['duplicate delivery', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 100, 'ref': None}, {'id': 'e1', 'ts': 9, 'type': 'earn', 'pts': 100, 'ref': None}, {'id': 'e2', 'ts': 5, 'type': 'redeem', 'pts': 152, 'ref': None}]}, {'balance': 100, 'rejected': ['e2'], 'applied': ['e1']}], ['reverse redemption', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 200, 'ref': None}, {'id': 'e2', 'ts': 2, 'type': 'redeem', 'pts': 82, 'ref': None}, {'id': 'e3', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e2'}]}, {'balance': 200, 'rejected': [], 'applied': ['e1', 'e2', 'e3']}], ['double reverse', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 62, 'ref': None}, {'id': 'r1', 'ts': 2, 'type': 'reverse', 'pts': 0, 'ref': 'e1'}, {'id': 'r2', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e1'}, {'id': 'r3', 'ts': 4, 'type': 'reverse', 'pts': 0, 'ref': 'r1'}]}, {'balance': 0, 'rejected': ['r2', 'r3'], 'applied': ['e1', 'r1']}], ['reverse rejected redeem', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 10, 'ref': None}, {'id': 'e2', 'ts': 2, 'type': 'redeem', 'pts': 52, 'ref': None}, {'id': 'e3', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e2'}]}, {'balance': 10, 'rejected': ['e2', 'e3'], 'applied': ['e1']}], ['same timestamp', {'events': [{'id': 'b', 'ts': 7, 'type': 'redeem', 'pts': 30, 'ref': None}, {'id': 'a', 'ts': 7, 'type': 'earn', 'pts': 32, 'ref': None}]}, {'balance': 2, 'rejected': [], 'applied': ['a', 'b']}], ['unknown reverse', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 10, 'ref': None}, {'id': 'x', 'ts': 2, 'type': 'reverse', 'pts': 0, 'ref': 'nope'}]}, {'balance': 10, 'rejected': ['x'], 'applied': ['e1']}], ['ids against time', {'events': [{'id': 'a', 'ts': 9, 'type': 'redeem', 'pts': 20, 'ref': None}, {'id': 'b', 'ts': 2, 'type': 'earn', 'pts': 32, 'ref': None}]}, {'balance': 12, 'rejected': [], 'applied': ['b', 'a']}]], [['out of order', {'events': [{'id': 'e2', 'ts': 5, 'type': 'redeem', 'pts': 50, 'ref': None}, {'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 103, 'ref': None}]}, {'balance': 53, 'rejected': [], 'applied': ['e1', 'e2']}], ['duplicate delivery', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 100, 'ref': None}, {'id': 'e1', 'ts': 9, 'type': 'earn', 'pts': 100, 'ref': None}, {'id': 'e2', 'ts': 5, 'type': 'redeem', 'pts': 153, 'ref': None}]}, {'balance': 100, 'rejected': ['e2'], 'applied': ['e1']}], ['reverse redemption', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 200, 'ref': None}, {'id': 'e2', 'ts': 2, 'type': 'redeem', 'pts': 83, 'ref': None}, {'id': 'e3', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e2'}]}, {'balance': 200, 'rejected': [], 'applied': ['e1', 'e2', 'e3']}], ['double reverse', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 63, 'ref': None}, {'id': 'r1', 'ts': 2, 'type': 'reverse', 'pts': 0, 'ref': 'e1'}, {'id': 'r2', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e1'}, {'id': 'r3', 'ts': 4, 'type': 'reverse', 'pts': 0, 'ref': 'r1'}]}, {'balance': 0, 'rejected': ['r2', 'r3'], 'applied': ['e1', 'r1']}], ['reverse rejected redeem', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 10, 'ref': None}, {'id': 'e2', 'ts': 2, 'type': 'redeem', 'pts': 53, 'ref': None}, {'id': 'e3', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e2'}]}, {'balance': 10, 'rejected': ['e2', 'e3'], 'applied': ['e1']}], ['same timestamp', {'events': [{'id': 'b', 'ts': 7, 'type': 'redeem', 'pts': 30, 'ref': None}, {'id': 'a', 'ts': 7, 'type': 'earn', 'pts': 33, 'ref': None}]}, {'balance': 3, 'rejected': [], 'applied': ['a', 'b']}], ['unknown reverse', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 15, 'ref': None}, {'id': 'x', 'ts': 2, 'type': 'reverse', 'pts': 0, 'ref': 'nope'}]}, {'balance': 15, 'rejected': ['x'], 'applied': ['e1']}], ['ids against time', {'events': [{'id': 'a', 'ts': 9, 'type': 'redeem', 'pts': 20, 'ref': None}, {'id': 'b', 'ts': 2, 'type': 'earn', 'pts': 33, 'ref': None}]}, {'balance': 13, 'rejected': [], 'applied': ['b', 'a']}]], [['out of order', {'events': [{'id': 'e2', 'ts': 5, 'type': 'redeem', 'pts': 50, 'ref': None}, {'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 104, 'ref': None}]}, {'balance': 54, 'rejected': [], 'applied': ['e1', 'e2']}], ['duplicate delivery', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 100, 'ref': None}, {'id': 'e1', 'ts': 9, 'type': 'earn', 'pts': 100, 'ref': None}, {'id': 'e2', 'ts': 5, 'type': 'redeem', 'pts': 154, 'ref': None}]}, {'balance': 100, 'rejected': ['e2'], 'applied': ['e1']}], ['reverse redemption', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 200, 'ref': None}, {'id': 'e2', 'ts': 2, 'type': 'redeem', 'pts': 84, 'ref': None}, {'id': 'e3', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e2'}]}, {'balance': 200, 'rejected': [], 'applied': ['e1', 'e2', 'e3']}], ['double reverse', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 64, 'ref': None}, {'id': 'r1', 'ts': 2, 'type': 'reverse', 'pts': 0, 'ref': 'e1'}, {'id': 'r2', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e1'}, {'id': 'r3', 'ts': 4, 'type': 'reverse', 'pts': 0, 'ref': 'r1'}]}, {'balance': 0, 'rejected': ['r2', 'r3'], 'applied': ['e1', 'r1']}], ['reverse rejected redeem', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 10, 'ref': None}, {'id': 'e2', 'ts': 2, 'type': 'redeem', 'pts': 54, 'ref': None}, {'id': 'e3', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e2'}]}, {'balance': 10, 'rejected': ['e2', 'e3'], 'applied': ['e1']}], ['same timestamp', {'events': [{'id': 'b', 'ts': 7, 'type': 'redeem', 'pts': 30, 'ref': None}, {'id': 'a', 'ts': 7, 'type': 'earn', 'pts': 34, 'ref': None}]}, {'balance': 4, 'rejected': [], 'applied': ['a', 'b']}], ['unknown reverse', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 20, 'ref': None}, {'id': 'x', 'ts': 2, 'type': 'reverse', 'pts': 0, 'ref': 'nope'}]}, {'balance': 20, 'rejected': ['x'], 'applied': ['e1']}], ['ids against time', {'events': [{'id': 'a', 'ts': 9, 'type': 'redeem', 'pts': 20, 'ref': None}, {'id': 'b', 'ts': 2, 'type': 'earn', 'pts': 34, 'ref': None}]}, {'balance': 14, 'rejected': [], 'applied': ['b', 'a']}]], [['out of order', {'events': [{'id': 'e2', 'ts': 5, 'type': 'redeem', 'pts': 50, 'ref': None}, {'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 105, 'ref': None}]}, {'balance': 55, 'rejected': [], 'applied': ['e1', 'e2']}], ['duplicate delivery', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 100, 'ref': None}, {'id': 'e1', 'ts': 9, 'type': 'earn', 'pts': 100, 'ref': None}, {'id': 'e2', 'ts': 5, 'type': 'redeem', 'pts': 155, 'ref': None}]}, {'balance': 100, 'rejected': ['e2'], 'applied': ['e1']}], ['reverse redemption', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 200, 'ref': None}, {'id': 'e2', 'ts': 2, 'type': 'redeem', 'pts': 85, 'ref': None}, {'id': 'e3', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e2'}]}, {'balance': 200, 'rejected': [], 'applied': ['e1', 'e2', 'e3']}], ['double reverse', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 65, 'ref': None}, {'id': 'r1', 'ts': 2, 'type': 'reverse', 'pts': 0, 'ref': 'e1'}, {'id': 'r2', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e1'}, {'id': 'r3', 'ts': 4, 'type': 'reverse', 'pts': 0, 'ref': 'r1'}]}, {'balance': 0, 'rejected': ['r2', 'r3'], 'applied': ['e1', 'r1']}], ['reverse rejected redeem', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 10, 'ref': None}, {'id': 'e2', 'ts': 2, 'type': 'redeem', 'pts': 55, 'ref': None}, {'id': 'e3', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e2'}]}, {'balance': 10, 'rejected': ['e2', 'e3'], 'applied': ['e1']}], ['same timestamp', {'events': [{'id': 'b', 'ts': 7, 'type': 'redeem', 'pts': 30, 'ref': None}, {'id': 'a', 'ts': 7, 'type': 'earn', 'pts': 35, 'ref': None}]}, {'balance': 5, 'rejected': [], 'applied': ['a', 'b']}], ['unknown reverse', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 25, 'ref': None}, {'id': 'x', 'ts': 2, 'type': 'reverse', 'pts': 0, 'ref': 'nope'}]}, {'balance': 25, 'rejected': ['x'], 'applied': ['e1']}], ['ids against time', {'events': [{'id': 'a', 'ts': 9, 'type': 'redeem', 'pts': 20, 'ref': None}, {'id': 'b', 'ts': 2, 'type': 'earn', 'pts': 35, 'ref': None}]}, {'balance': 15, 'rejected': [], 'applied': ['b', 'a']}]]]
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
out of order{'applied': ['e1', 'e2'], 'balance': 51, 'rejected': []}{'applied': ['e1', 'e2'], 'balance': 51, 'rejected': []}Passed
duplicate delivery{'applied': ['e1'], 'balance': 100, 'rejected': ['e2']}{'applied': ['e1'], 'balance': 100, 'rejected': ['e2']}Passed
reverse redemption{'applied': ['e1', 'e2', 'e3'], 'balance': 200, 'rejected': []}{'applied': ['e1', 'e2', 'e3'], 'balance': 200, 'rejected': []}Passed
double reverse{'applied': ['e1', 'r1'], 'balance': 0, 'rejected': ['r2', 'r3']}{'applied': ['e1', 'r1'], 'balance': 0, 'rejected': ['r2', 'r3']}Passed
reverse rejected redeem{'applied': ['e1'], 'balance': 10, 'rejected': ['e2', 'e3']}{'applied': ['e1'], 'balance': 10, 'rejected': ['e2', 'e3']}Passed
same timestamp{'applied': ['a'], 'balance': 31, 'rejected': ['b']}{'applied': ['a', 'b'], 'balance': 1, 'rejected': []}Failed
unknown reverse{'applied': ['e1'], 'balance': 5, 'rejected': ['x']}{'applied': ['e1'], 'balance': 5, 'rejected': ['x']}Passed
ids against time{'applied': ['b', 'a'], 'balance': 11, 'rejected': []}{'applied': ['b', 'a'], 'balance': 11, 'rejected': []}Passed

SHA-256 / 441724358a85559ee401852b23648b15d2ba572c9002942910cb20b2f82ec51d

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(x):
    seen = set()
    evs = []
    for e in x['events']:
        if e['id'] in seen:
            continue
        seen.add(e['id'])
        evs.append(e)
    evs.sort(key=lambda e: e['id'])
    bal = 0
    applied = {}
    undone = set()
    rej = []
    order = []
    for e in evs:
        t = e['type']
        if t == 'earn':
            bal += e['pts']
            applied[e['id']] = e['pts']
        elif t == 'redeem':
            if e['pts'] > bal:
                rej.append(e['id'])
                continue
            bal -= e['pts']
            applied[e['id']] = -e['pts']
        else:
            r = e['ref']
            if r not in applied or r in undone:
                rej.append(e['id'])
                continue
            bal -= applied[r]
            undone.add(r)
        order.append(e['id'])
    return {'balance': bal, 'rejected': rej, 'applied': order}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['out of order', {'events': [{'id': 'e2', 'ts': 5, 'type': 'redeem', 'pts': 50, 'ref': None}, {'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 101, 'ref': None}]}, {'balance': 51, 'rejected': [], 'applied': ['e1', 'e2']}], ['duplicate delivery', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 100, 'ref': None}, {'id': 'e1', 'ts': 9, 'type': 'earn', 'pts': 100, 'ref': None}, {'id': 'e2', 'ts': 5, 'type': 'redeem', 'pts': 151, 'ref': None}]}, {'balance': 100, 'rejected': ['e2'], 'applied': ['e1']}], ['reverse redemption', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 200, 'ref': None}, {'id': 'e2', 'ts': 2, 'type': 'redeem', 'pts': 81, 'ref': None}, {'id': 'e3', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e2'}]}, {'balance': 200, 'rejected': [], 'applied': ['e1', 'e2', 'e3']}], ['double reverse', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 61, 'ref': None}, {'id': 'r1', 'ts': 2, 'type': 'reverse', 'pts': 0, 'ref': 'e1'}, {'id': 'r2', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e1'}, {'id': 'r3', 'ts': 4, 'type': 'reverse', 'pts': 0, 'ref': 'r1'}]}, {'balance': 0, 'rejected': ['r2', 'r3'], 'applied': ['e1', 'r1']}], ['reverse rejected redeem', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 10, 'ref': None}, {'id': 'e2', 'ts': 2, 'type': 'redeem', 'pts': 51, 'ref': None}, {'id': 'e3', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e2'}]}, {'balance': 10, 'rejected': ['e2', 'e3'], 'applied': ['e1']}], ['same timestamp', {'events': [{'id': 'b', 'ts': 7, 'type': 'redeem', 'pts': 30, 'ref': None}, {'id': 'a', 'ts': 7, 'type': 'earn', 'pts': 31, 'ref': None}]}, {'balance': 1, 'rejected': [], 'applied': ['a', 'b']}], ['unknown reverse', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 5, 'ref': None}, {'id': 'x', 'ts': 2, 'type': 'reverse', 'pts': 0, 'ref': 'nope'}]}, {'balance': 5, 'rejected': ['x'], 'applied': ['e1']}], ['ids against time', {'events': [{'id': 'a', 'ts': 9, 'type': 'redeem', 'pts': 20, 'ref': None}, {'id': 'b', 'ts': 2, 'type': 'earn', 'pts': 31, 'ref': None}]}, {'balance': 11, 'rejected': [], 'applied': ['b', 'a']}]], [['out of order', {'events': [{'id': 'e2', 'ts': 5, 'type': 'redeem', 'pts': 50, 'ref': None}, {'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 102, 'ref': None}]}, {'balance': 52, 'rejected': [], 'applied': ['e1', 'e2']}], ['duplicate delivery', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 100, 'ref': None}, {'id': 'e1', 'ts': 9, 'type': 'earn', 'pts': 100, 'ref': None}, {'id': 'e2', 'ts': 5, 'type': 'redeem', 'pts': 152, 'ref': None}]}, {'balance': 100, 'rejected': ['e2'], 'applied': ['e1']}], ['reverse redemption', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 200, 'ref': None}, {'id': 'e2', 'ts': 2, 'type': 'redeem', 'pts': 82, 'ref': None}, {'id': 'e3', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e2'}]}, {'balance': 200, 'rejected': [], 'applied': ['e1', 'e2', 'e3']}], ['double reverse', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 62, 'ref': None}, {'id': 'r1', 'ts': 2, 'type': 'reverse', 'pts': 0, 'ref': 'e1'}, {'id': 'r2', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e1'}, {'id': 'r3', 'ts': 4, 'type': 'reverse', 'pts': 0, 'ref': 'r1'}]}, {'balance': 0, 'rejected': ['r2', 'r3'], 'applied': ['e1', 'r1']}], ['reverse rejected redeem', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 10, 'ref': None}, {'id': 'e2', 'ts': 2, 'type': 'redeem', 'pts': 52, 'ref': None}, {'id': 'e3', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e2'}]}, {'balance': 10, 'rejected': ['e2', 'e3'], 'applied': ['e1']}], ['same timestamp', {'events': [{'id': 'b', 'ts': 7, 'type': 'redeem', 'pts': 30, 'ref': None}, {'id': 'a', 'ts': 7, 'type': 'earn', 'pts': 32, 'ref': None}]}, {'balance': 2, 'rejected': [], 'applied': ['a', 'b']}], ['unknown reverse', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 10, 'ref': None}, {'id': 'x', 'ts': 2, 'type': 'reverse', 'pts': 0, 'ref': 'nope'}]}, {'balance': 10, 'rejected': ['x'], 'applied': ['e1']}], ['ids against time', {'events': [{'id': 'a', 'ts': 9, 'type': 'redeem', 'pts': 20, 'ref': None}, {'id': 'b', 'ts': 2, 'type': 'earn', 'pts': 32, 'ref': None}]}, {'balance': 12, 'rejected': [], 'applied': ['b', 'a']}]], [['out of order', {'events': [{'id': 'e2', 'ts': 5, 'type': 'redeem', 'pts': 50, 'ref': None}, {'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 103, 'ref': None}]}, {'balance': 53, 'rejected': [], 'applied': ['e1', 'e2']}], ['duplicate delivery', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 100, 'ref': None}, {'id': 'e1', 'ts': 9, 'type': 'earn', 'pts': 100, 'ref': None}, {'id': 'e2', 'ts': 5, 'type': 'redeem', 'pts': 153, 'ref': None}]}, {'balance': 100, 'rejected': ['e2'], 'applied': ['e1']}], ['reverse redemption', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 200, 'ref': None}, {'id': 'e2', 'ts': 2, 'type': 'redeem', 'pts': 83, 'ref': None}, {'id': 'e3', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e2'}]}, {'balance': 200, 'rejected': [], 'applied': ['e1', 'e2', 'e3']}], ['double reverse', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 63, 'ref': None}, {'id': 'r1', 'ts': 2, 'type': 'reverse', 'pts': 0, 'ref': 'e1'}, {'id': 'r2', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e1'}, {'id': 'r3', 'ts': 4, 'type': 'reverse', 'pts': 0, 'ref': 'r1'}]}, {'balance': 0, 'rejected': ['r2', 'r3'], 'applied': ['e1', 'r1']}], ['reverse rejected redeem', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 10, 'ref': None}, {'id': 'e2', 'ts': 2, 'type': 'redeem', 'pts': 53, 'ref': None}, {'id': 'e3', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e2'}]}, {'balance': 10, 'rejected': ['e2', 'e3'], 'applied': ['e1']}], ['same timestamp', {'events': [{'id': 'b', 'ts': 7, 'type': 'redeem', 'pts': 30, 'ref': None}, {'id': 'a', 'ts': 7, 'type': 'earn', 'pts': 33, 'ref': None}]}, {'balance': 3, 'rejected': [], 'applied': ['a', 'b']}], ['unknown reverse', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 15, 'ref': None}, {'id': 'x', 'ts': 2, 'type': 'reverse', 'pts': 0, 'ref': 'nope'}]}, {'balance': 15, 'rejected': ['x'], 'applied': ['e1']}], ['ids against time', {'events': [{'id': 'a', 'ts': 9, 'type': 'redeem', 'pts': 20, 'ref': None}, {'id': 'b', 'ts': 2, 'type': 'earn', 'pts': 33, 'ref': None}]}, {'balance': 13, 'rejected': [], 'applied': ['b', 'a']}]], [['out of order', {'events': [{'id': 'e2', 'ts': 5, 'type': 'redeem', 'pts': 50, 'ref': None}, {'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 104, 'ref': None}]}, {'balance': 54, 'rejected': [], 'applied': ['e1', 'e2']}], ['duplicate delivery', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 100, 'ref': None}, {'id': 'e1', 'ts': 9, 'type': 'earn', 'pts': 100, 'ref': None}, {'id': 'e2', 'ts': 5, 'type': 'redeem', 'pts': 154, 'ref': None}]}, {'balance': 100, 'rejected': ['e2'], 'applied': ['e1']}], ['reverse redemption', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 200, 'ref': None}, {'id': 'e2', 'ts': 2, 'type': 'redeem', 'pts': 84, 'ref': None}, {'id': 'e3', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e2'}]}, {'balance': 200, 'rejected': [], 'applied': ['e1', 'e2', 'e3']}], ['double reverse', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 64, 'ref': None}, {'id': 'r1', 'ts': 2, 'type': 'reverse', 'pts': 0, 'ref': 'e1'}, {'id': 'r2', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e1'}, {'id': 'r3', 'ts': 4, 'type': 'reverse', 'pts': 0, 'ref': 'r1'}]}, {'balance': 0, 'rejected': ['r2', 'r3'], 'applied': ['e1', 'r1']}], ['reverse rejected redeem', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 10, 'ref': None}, {'id': 'e2', 'ts': 2, 'type': 'redeem', 'pts': 54, 'ref': None}, {'id': 'e3', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e2'}]}, {'balance': 10, 'rejected': ['e2', 'e3'], 'applied': ['e1']}], ['same timestamp', {'events': [{'id': 'b', 'ts': 7, 'type': 'redeem', 'pts': 30, 'ref': None}, {'id': 'a', 'ts': 7, 'type': 'earn', 'pts': 34, 'ref': None}]}, {'balance': 4, 'rejected': [], 'applied': ['a', 'b']}], ['unknown reverse', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 20, 'ref': None}, {'id': 'x', 'ts': 2, 'type': 'reverse', 'pts': 0, 'ref': 'nope'}]}, {'balance': 20, 'rejected': ['x'], 'applied': ['e1']}], ['ids against time', {'events': [{'id': 'a', 'ts': 9, 'type': 'redeem', 'pts': 20, 'ref': None}, {'id': 'b', 'ts': 2, 'type': 'earn', 'pts': 34, 'ref': None}]}, {'balance': 14, 'rejected': [], 'applied': ['b', 'a']}]], [['out of order', {'events': [{'id': 'e2', 'ts': 5, 'type': 'redeem', 'pts': 50, 'ref': None}, {'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 105, 'ref': None}]}, {'balance': 55, 'rejected': [], 'applied': ['e1', 'e2']}], ['duplicate delivery', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 100, 'ref': None}, {'id': 'e1', 'ts': 9, 'type': 'earn', 'pts': 100, 'ref': None}, {'id': 'e2', 'ts': 5, 'type': 'redeem', 'pts': 155, 'ref': None}]}, {'balance': 100, 'rejected': ['e2'], 'applied': ['e1']}], ['reverse redemption', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 200, 'ref': None}, {'id': 'e2', 'ts': 2, 'type': 'redeem', 'pts': 85, 'ref': None}, {'id': 'e3', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e2'}]}, {'balance': 200, 'rejected': [], 'applied': ['e1', 'e2', 'e3']}], ['double reverse', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 65, 'ref': None}, {'id': 'r1', 'ts': 2, 'type': 'reverse', 'pts': 0, 'ref': 'e1'}, {'id': 'r2', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e1'}, {'id': 'r3', 'ts': 4, 'type': 'reverse', 'pts': 0, 'ref': 'r1'}]}, {'balance': 0, 'rejected': ['r2', 'r3'], 'applied': ['e1', 'r1']}], ['reverse rejected redeem', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 10, 'ref': None}, {'id': 'e2', 'ts': 2, 'type': 'redeem', 'pts': 55, 'ref': None}, {'id': 'e3', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e2'}]}, {'balance': 10, 'rejected': ['e2', 'e3'], 'applied': ['e1']}], ['same timestamp', {'events': [{'id': 'b', 'ts': 7, 'type': 'redeem', 'pts': 30, 'ref': None}, {'id': 'a', 'ts': 7, 'type': 'earn', 'pts': 35, 'ref': None}]}, {'balance': 5, 'rejected': [], 'applied': ['a', 'b']}], ['unknown reverse', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 25, 'ref': None}, {'id': 'x', 'ts': 2, 'type': 'reverse', 'pts': 0, 'ref': 'nope'}]}, {'balance': 25, 'rejected': ['x'], 'applied': ['e1']}], ['ids against time', {'events': [{'id': 'a', 'ts': 9, 'type': 'redeem', 'pts': 20, 'ref': None}, {'id': 'b', 'ts': 2, 'type': 'earn', 'pts': 35, 'ref': None}]}, {'balance': 15, 'rejected': [], 'applied': ['b', 'a']}]]]
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
out of order{'applied': ['e1', 'e2'], 'balance': 51, 'rejected': []}{'applied': ['e1', 'e2'], 'balance': 51, 'rejected': []}Passed
duplicate delivery{'applied': ['e1'], 'balance': 100, 'rejected': ['e2']}{'applied': ['e1'], 'balance': 100, 'rejected': ['e2']}Passed
reverse redemption{'applied': ['e1', 'e2', 'e3'], 'balance': 200, 'rejected': []}{'applied': ['e1', 'e2', 'e3'], 'balance': 200, 'rejected': []}Passed
double reverse{'applied': ['e1', 'r1'], 'balance': 0, 'rejected': ['r2', 'r3']}{'applied': ['e1', 'r1'], 'balance': 0, 'rejected': ['r2', 'r3']}Passed
reverse rejected redeem{'applied': ['e1'], 'balance': 10, 'rejected': ['e2', 'e3']}{'applied': ['e1'], 'balance': 10, 'rejected': ['e2', 'e3']}Passed
same timestamp{'applied': ['a', 'b'], 'balance': 1, 'rejected': []}{'applied': ['a', 'b'], 'balance': 1, 'rejected': []}Passed
unknown reverse{'applied': ['e1'], 'balance': 5, 'rejected': ['x']}{'applied': ['e1'], 'balance': 5, 'rejected': ['x']}Passed
ids against time{'applied': ['b'], 'balance': 31, 'rejected': ['a']}{'applied': ['b', 'a'], 'balance': 11, 'rejected': []}Failed

SHA-256 / 71f5c40e3ecab3a457a9e9942dfc2dc2b3928fbea512efe93b50ce892ca12981

3 / The verified repair

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

N = 1
observations = []
def solve(x):
    seen = set()
    evs = []
    for e in x['events']:
        if e['id'] in seen:
            continue
        seen.add(e['id'])
        evs.append(e)
    evs.sort(key=lambda e: (e['ts'], e['id']))
    bal = 0
    applied = {}
    undone = set()
    rej = []
    order = []
    for e in evs:
        t = e['type']
        if t == 'earn':
            bal += e['pts']
            applied[e['id']] = e['pts']
        elif t == 'redeem':
            if e['pts'] > bal:
                rej.append(e['id'])
                continue
            bal -= e['pts']
            applied[e['id']] = -e['pts']
        else:
            r = e['ref']
            if r not in applied or r in undone:
                rej.append(e['id'])
                continue
            bal -= applied[r]
            undone.add(r)
        order.append(e['id'])
    return {'balance': bal, 'rejected': rej, 'applied': order}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['out of order', {'events': [{'id': 'e2', 'ts': 5, 'type': 'redeem', 'pts': 50, 'ref': None}, {'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 101, 'ref': None}]}, {'balance': 51, 'rejected': [], 'applied': ['e1', 'e2']}], ['duplicate delivery', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 100, 'ref': None}, {'id': 'e1', 'ts': 9, 'type': 'earn', 'pts': 100, 'ref': None}, {'id': 'e2', 'ts': 5, 'type': 'redeem', 'pts': 151, 'ref': None}]}, {'balance': 100, 'rejected': ['e2'], 'applied': ['e1']}], ['reverse redemption', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 200, 'ref': None}, {'id': 'e2', 'ts': 2, 'type': 'redeem', 'pts': 81, 'ref': None}, {'id': 'e3', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e2'}]}, {'balance': 200, 'rejected': [], 'applied': ['e1', 'e2', 'e3']}], ['double reverse', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 61, 'ref': None}, {'id': 'r1', 'ts': 2, 'type': 'reverse', 'pts': 0, 'ref': 'e1'}, {'id': 'r2', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e1'}, {'id': 'r3', 'ts': 4, 'type': 'reverse', 'pts': 0, 'ref': 'r1'}]}, {'balance': 0, 'rejected': ['r2', 'r3'], 'applied': ['e1', 'r1']}], ['reverse rejected redeem', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 10, 'ref': None}, {'id': 'e2', 'ts': 2, 'type': 'redeem', 'pts': 51, 'ref': None}, {'id': 'e3', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e2'}]}, {'balance': 10, 'rejected': ['e2', 'e3'], 'applied': ['e1']}], ['same timestamp', {'events': [{'id': 'b', 'ts': 7, 'type': 'redeem', 'pts': 30, 'ref': None}, {'id': 'a', 'ts': 7, 'type': 'earn', 'pts': 31, 'ref': None}]}, {'balance': 1, 'rejected': [], 'applied': ['a', 'b']}], ['unknown reverse', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 5, 'ref': None}, {'id': 'x', 'ts': 2, 'type': 'reverse', 'pts': 0, 'ref': 'nope'}]}, {'balance': 5, 'rejected': ['x'], 'applied': ['e1']}], ['ids against time', {'events': [{'id': 'a', 'ts': 9, 'type': 'redeem', 'pts': 20, 'ref': None}, {'id': 'b', 'ts': 2, 'type': 'earn', 'pts': 31, 'ref': None}]}, {'balance': 11, 'rejected': [], 'applied': ['b', 'a']}]], [['out of order', {'events': [{'id': 'e2', 'ts': 5, 'type': 'redeem', 'pts': 50, 'ref': None}, {'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 102, 'ref': None}]}, {'balance': 52, 'rejected': [], 'applied': ['e1', 'e2']}], ['duplicate delivery', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 100, 'ref': None}, {'id': 'e1', 'ts': 9, 'type': 'earn', 'pts': 100, 'ref': None}, {'id': 'e2', 'ts': 5, 'type': 'redeem', 'pts': 152, 'ref': None}]}, {'balance': 100, 'rejected': ['e2'], 'applied': ['e1']}], ['reverse redemption', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 200, 'ref': None}, {'id': 'e2', 'ts': 2, 'type': 'redeem', 'pts': 82, 'ref': None}, {'id': 'e3', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e2'}]}, {'balance': 200, 'rejected': [], 'applied': ['e1', 'e2', 'e3']}], ['double reverse', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 62, 'ref': None}, {'id': 'r1', 'ts': 2, 'type': 'reverse', 'pts': 0, 'ref': 'e1'}, {'id': 'r2', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e1'}, {'id': 'r3', 'ts': 4, 'type': 'reverse', 'pts': 0, 'ref': 'r1'}]}, {'balance': 0, 'rejected': ['r2', 'r3'], 'applied': ['e1', 'r1']}], ['reverse rejected redeem', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 10, 'ref': None}, {'id': 'e2', 'ts': 2, 'type': 'redeem', 'pts': 52, 'ref': None}, {'id': 'e3', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e2'}]}, {'balance': 10, 'rejected': ['e2', 'e3'], 'applied': ['e1']}], ['same timestamp', {'events': [{'id': 'b', 'ts': 7, 'type': 'redeem', 'pts': 30, 'ref': None}, {'id': 'a', 'ts': 7, 'type': 'earn', 'pts': 32, 'ref': None}]}, {'balance': 2, 'rejected': [], 'applied': ['a', 'b']}], ['unknown reverse', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 10, 'ref': None}, {'id': 'x', 'ts': 2, 'type': 'reverse', 'pts': 0, 'ref': 'nope'}]}, {'balance': 10, 'rejected': ['x'], 'applied': ['e1']}], ['ids against time', {'events': [{'id': 'a', 'ts': 9, 'type': 'redeem', 'pts': 20, 'ref': None}, {'id': 'b', 'ts': 2, 'type': 'earn', 'pts': 32, 'ref': None}]}, {'balance': 12, 'rejected': [], 'applied': ['b', 'a']}]], [['out of order', {'events': [{'id': 'e2', 'ts': 5, 'type': 'redeem', 'pts': 50, 'ref': None}, {'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 103, 'ref': None}]}, {'balance': 53, 'rejected': [], 'applied': ['e1', 'e2']}], ['duplicate delivery', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 100, 'ref': None}, {'id': 'e1', 'ts': 9, 'type': 'earn', 'pts': 100, 'ref': None}, {'id': 'e2', 'ts': 5, 'type': 'redeem', 'pts': 153, 'ref': None}]}, {'balance': 100, 'rejected': ['e2'], 'applied': ['e1']}], ['reverse redemption', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 200, 'ref': None}, {'id': 'e2', 'ts': 2, 'type': 'redeem', 'pts': 83, 'ref': None}, {'id': 'e3', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e2'}]}, {'balance': 200, 'rejected': [], 'applied': ['e1', 'e2', 'e3']}], ['double reverse', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 63, 'ref': None}, {'id': 'r1', 'ts': 2, 'type': 'reverse', 'pts': 0, 'ref': 'e1'}, {'id': 'r2', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e1'}, {'id': 'r3', 'ts': 4, 'type': 'reverse', 'pts': 0, 'ref': 'r1'}]}, {'balance': 0, 'rejected': ['r2', 'r3'], 'applied': ['e1', 'r1']}], ['reverse rejected redeem', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 10, 'ref': None}, {'id': 'e2', 'ts': 2, 'type': 'redeem', 'pts': 53, 'ref': None}, {'id': 'e3', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e2'}]}, {'balance': 10, 'rejected': ['e2', 'e3'], 'applied': ['e1']}], ['same timestamp', {'events': [{'id': 'b', 'ts': 7, 'type': 'redeem', 'pts': 30, 'ref': None}, {'id': 'a', 'ts': 7, 'type': 'earn', 'pts': 33, 'ref': None}]}, {'balance': 3, 'rejected': [], 'applied': ['a', 'b']}], ['unknown reverse', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 15, 'ref': None}, {'id': 'x', 'ts': 2, 'type': 'reverse', 'pts': 0, 'ref': 'nope'}]}, {'balance': 15, 'rejected': ['x'], 'applied': ['e1']}], ['ids against time', {'events': [{'id': 'a', 'ts': 9, 'type': 'redeem', 'pts': 20, 'ref': None}, {'id': 'b', 'ts': 2, 'type': 'earn', 'pts': 33, 'ref': None}]}, {'balance': 13, 'rejected': [], 'applied': ['b', 'a']}]], [['out of order', {'events': [{'id': 'e2', 'ts': 5, 'type': 'redeem', 'pts': 50, 'ref': None}, {'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 104, 'ref': None}]}, {'balance': 54, 'rejected': [], 'applied': ['e1', 'e2']}], ['duplicate delivery', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 100, 'ref': None}, {'id': 'e1', 'ts': 9, 'type': 'earn', 'pts': 100, 'ref': None}, {'id': 'e2', 'ts': 5, 'type': 'redeem', 'pts': 154, 'ref': None}]}, {'balance': 100, 'rejected': ['e2'], 'applied': ['e1']}], ['reverse redemption', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 200, 'ref': None}, {'id': 'e2', 'ts': 2, 'type': 'redeem', 'pts': 84, 'ref': None}, {'id': 'e3', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e2'}]}, {'balance': 200, 'rejected': [], 'applied': ['e1', 'e2', 'e3']}], ['double reverse', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 64, 'ref': None}, {'id': 'r1', 'ts': 2, 'type': 'reverse', 'pts': 0, 'ref': 'e1'}, {'id': 'r2', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e1'}, {'id': 'r3', 'ts': 4, 'type': 'reverse', 'pts': 0, 'ref': 'r1'}]}, {'balance': 0, 'rejected': ['r2', 'r3'], 'applied': ['e1', 'r1']}], ['reverse rejected redeem', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 10, 'ref': None}, {'id': 'e2', 'ts': 2, 'type': 'redeem', 'pts': 54, 'ref': None}, {'id': 'e3', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e2'}]}, {'balance': 10, 'rejected': ['e2', 'e3'], 'applied': ['e1']}], ['same timestamp', {'events': [{'id': 'b', 'ts': 7, 'type': 'redeem', 'pts': 30, 'ref': None}, {'id': 'a', 'ts': 7, 'type': 'earn', 'pts': 34, 'ref': None}]}, {'balance': 4, 'rejected': [], 'applied': ['a', 'b']}], ['unknown reverse', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 20, 'ref': None}, {'id': 'x', 'ts': 2, 'type': 'reverse', 'pts': 0, 'ref': 'nope'}]}, {'balance': 20, 'rejected': ['x'], 'applied': ['e1']}], ['ids against time', {'events': [{'id': 'a', 'ts': 9, 'type': 'redeem', 'pts': 20, 'ref': None}, {'id': 'b', 'ts': 2, 'type': 'earn', 'pts': 34, 'ref': None}]}, {'balance': 14, 'rejected': [], 'applied': ['b', 'a']}]], [['out of order', {'events': [{'id': 'e2', 'ts': 5, 'type': 'redeem', 'pts': 50, 'ref': None}, {'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 105, 'ref': None}]}, {'balance': 55, 'rejected': [], 'applied': ['e1', 'e2']}], ['duplicate delivery', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 100, 'ref': None}, {'id': 'e1', 'ts': 9, 'type': 'earn', 'pts': 100, 'ref': None}, {'id': 'e2', 'ts': 5, 'type': 'redeem', 'pts': 155, 'ref': None}]}, {'balance': 100, 'rejected': ['e2'], 'applied': ['e1']}], ['reverse redemption', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 200, 'ref': None}, {'id': 'e2', 'ts': 2, 'type': 'redeem', 'pts': 85, 'ref': None}, {'id': 'e3', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e2'}]}, {'balance': 200, 'rejected': [], 'applied': ['e1', 'e2', 'e3']}], ['double reverse', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 65, 'ref': None}, {'id': 'r1', 'ts': 2, 'type': 'reverse', 'pts': 0, 'ref': 'e1'}, {'id': 'r2', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e1'}, {'id': 'r3', 'ts': 4, 'type': 'reverse', 'pts': 0, 'ref': 'r1'}]}, {'balance': 0, 'rejected': ['r2', 'r3'], 'applied': ['e1', 'r1']}], ['reverse rejected redeem', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 10, 'ref': None}, {'id': 'e2', 'ts': 2, 'type': 'redeem', 'pts': 55, 'ref': None}, {'id': 'e3', 'ts': 3, 'type': 'reverse', 'pts': 0, 'ref': 'e2'}]}, {'balance': 10, 'rejected': ['e2', 'e3'], 'applied': ['e1']}], ['same timestamp', {'events': [{'id': 'b', 'ts': 7, 'type': 'redeem', 'pts': 30, 'ref': None}, {'id': 'a', 'ts': 7, 'type': 'earn', 'pts': 35, 'ref': None}]}, {'balance': 5, 'rejected': [], 'applied': ['a', 'b']}], ['unknown reverse', {'events': [{'id': 'e1', 'ts': 1, 'type': 'earn', 'pts': 25, 'ref': None}, {'id': 'x', 'ts': 2, 'type': 'reverse', 'pts': 0, 'ref': 'nope'}]}, {'balance': 25, 'rejected': ['x'], 'applied': ['e1']}], ['ids against time', {'events': [{'id': 'a', 'ts': 9, 'type': 'redeem', 'pts': 20, 'ref': None}, {'id': 'b', 'ts': 2, 'type': 'earn', 'pts': 35, 'ref': None}]}, {'balance': 15, 'rejected': [], 'applied': ['b', 'a']}]]]
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
out of order{'applied': ['e1', 'e2'], 'balance': 51, 'rejected': []}{'applied': ['e1', 'e2'], 'balance': 51, 'rejected': []}Passed
duplicate delivery{'applied': ['e1'], 'balance': 100, 'rejected': ['e2']}{'applied': ['e1'], 'balance': 100, 'rejected': ['e2']}Passed
reverse redemption{'applied': ['e1', 'e2', 'e3'], 'balance': 200, 'rejected': []}{'applied': ['e1', 'e2', 'e3'], 'balance': 200, 'rejected': []}Passed
double reverse{'applied': ['e1', 'r1'], 'balance': 0, 'rejected': ['r2', 'r3']}{'applied': ['e1', 'r1'], 'balance': 0, 'rejected': ['r2', 'r3']}Passed
reverse rejected redeem{'applied': ['e1'], 'balance': 10, 'rejected': ['e2', 'e3']}{'applied': ['e1'], 'balance': 10, 'rejected': ['e2', 'e3']}Passed
same timestamp{'applied': ['a', 'b'], 'balance': 1, 'rejected': []}{'applied': ['a', 'b'], 'balance': 1, 'rejected': []}Passed
unknown reverse{'applied': ['e1'], 'balance': 5, 'rejected': ['x']}{'applied': ['e1'], 'balance': 5, 'rejected': ['x']}Passed
ids against time{'applied': ['b', 'a'], 'balance': 11, 'rejected': []}{'applied': ['b', 'a'], 'balance': 11, 'rejected': []}Passed

SHA-256 / 2aad8b06937f39ff25ad3d727b534ec5ff1e3ffbe9141d8097268bc76dc67d76

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

Case digest / 2f89a095cd53cdd5f89e5e853aba98618c1c6fdbc60b0804a012a85f1ca1da7f