FA-58481 / Loan amortization schedules / Open access
Payment application waterfall: suspense release · case 01
Funds held in suspense disappear once a qualifying payment arrives.
ROOT CAUSE
Suspense funds are not combined with the new payment.
VERIFIED REPAIR
Combine the payment with suspense funds before testing and applying.
Unsuccessful approach: Adding suspense only when the payment alone is short still strands it when the payment qualifies.
Case contract
x = {'due': {'interest', 'principal', 'late_fee', 'fees'}, 'payment', 'suspense', 'threshold', 'balance'}. Available = payment + suspense. If available < threshold, everything goes to suspense and nothing is applied. Otherwise apply in order interest, principal, late_fee, fees, then curtail principal with the remainder up to balance - applied principal; the rest is refunded. Return {'applied', 'curtailment', 'refund', 'suspense', 'new_balance'}.
Why this case matters
Amortization engines drive borrower statements, payoff quotes and investor remittances; a misplaced rounding step, boundary or ordering rule compounds across hundreds of periods.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
avail = x['payment']
applied = {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 0}
if avail < x['threshold']:
return {'applied': applied, 'curtailment': 0, 'refund': 0, 'suspense': avail, 'new_balance': x['balance']}
for k in ('interest', 'principal', 'late_fee', 'fees'):
take = min(avail, x['due'][k])
applied[k] = take
avail -= take
room = x['balance'] - applied['principal']
curt = min(avail, room)
refund = avail - curt
return {'applied': applied, 'curtailment': curt, 'refund': refund, 'suspense': 0, 'new_balance': x['balance'] - applied['principal'] - curt}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: suspense release', {'due': {'interest': 1250, 'principal': 800, 'late_fee': 150, 'fees': 0}, 'payment': 7200, 'suspense': 200, 'threshold': 1250, 'balance': 2000}, {'applied': {'interest': 1250, 'principal': 800, 'late_fee': 150, 'fees': 0}, 'curtailment': 1200, 'refund': 4000, 'suspense': 0, 'new_balance': 0}], ['control 1', {'due': {'interest': 1250, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'payment': 300, 'suspense': 0, 'threshold': 1250, 'balance': 800}, {'applied': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 300, 'new_balance': 800}], ['control 2', {'due': {'interest': 1250, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'payment': 0, 'suspense': 0, 'threshold': 1000, 'balance': 800}, {'applied': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 800}], ['control 3', {'due': {'interest': 500, 'principal': 800, 'late_fee': 0, 'fees': 0}, 'payment': 300, 'suspense': 0, 'threshold': 1300, 'balance': 800}, {'applied': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 300, 'new_balance': 800}], ['control 4', {'due': {'interest': 1250, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'payment': 1285, 'suspense': 0, 'threshold': 1000, 'balance': 2000}, {'applied': {'interest': 1250, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 2000}], ['control 5', {'due': {'interest': 0, 'principal': 800, 'late_fee': 0, 'fees': 0}, 'payment': 800, 'suspense': 0, 'threshold': 0, 'balance': 5000}, {'applied': {'interest': 0, 'principal': 800, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 4200}], ['control 6', {'due': {'interest': 500, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'payment': 0, 'suspense': 0, 'threshold': 535, 'balance': 5000}, {'applied': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 5000}]], [['regression: suspense release', {'due': {'interest': 500, 'principal': 2000, 'late_fee': 0, 'fees': 35}, 'payment': 300, 'suspense': 700, 'threshold': 1000, 'balance': 2000}, {'applied': {'interest': 500, 'principal': 500, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 1500}], ['regression: suspense release, partial-repair probe', {'due': {'interest': 500, 'principal': 2000, 'late_fee': 0, 'fees': 35}, 'payment': 2500, 'suspense': 200, 'threshold': 0, 'balance': 5000}, {'applied': {'interest': 500, 'principal': 2000, 'late_fee': 0, 'fees': 35}, 'curtailment': 165, 'refund': 0, 'suspense': 0, 'new_balance': 2835}], ['control 1', {'due': {'interest': 0, 'principal': 800, 'late_fee': 150, 'fees': 0}, 'payment': 2500, 'suspense': 0, 'threshold': 950, 'balance': 2000}, {'applied': {'interest': 0, 'principal': 800, 'late_fee': 150, 'fees': 0}, 'curtailment': 1200, 'refund': 350, 'suspense': 0, 'new_balance': 0}], ['control 2', {'due': {'interest': 500, 'principal': 0, 'late_fee': 150, 'fees': 0}, 'payment': 649, 'suspense': 0, 'threshold': 650, 'balance': 100000}, {'applied': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 649, 'new_balance': 100000}], ['control 3', {'due': {'interest': 0, 'principal': 800, 'late_fee': 150, 'fees': 0}, 'payment': 2500, 'suspense': 0, 'threshold': 0, 'balance': 800}, {'applied': {'interest': 0, 'principal': 800, 'late_fee': 150, 'fees': 0}, 'curtailment': 0, 'refund': 1550, 'suspense': 0, 'new_balance': 0}], ['control 4', {'due': {'interest': 500, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'payment': 1000, 'suspense': 0, 'threshold': 535, 'balance': 2000}, {'applied': {'interest': 500, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'curtailment': 465, 'refund': 0, 'suspense': 0, 'new_balance': 1535}], ['control 5', {'due': {'interest': 1250, 'principal': 800, 'late_fee': 150, 'fees': 0}, 'payment': 7200, 'suspense': 0, 'threshold': 2200, 'balance': 5000}, {'applied': {'interest': 1250, 'principal': 800, 'late_fee': 150, 'fees': 0}, 'curtailment': 4200, 'refund': 800, 'suspense': 0, 'new_balance': 0}]], [['regression: suspense release', {'due': {'interest': 0, 'principal': 2000, 'late_fee': 150, 'fees': 0}, 'payment': 300, 'suspense': 700, 'threshold': 0, 'balance': 800}, {'applied': {'interest': 0, 'principal': 1000, 'late_fee': 0, 'fees': 0}, 'curtailment': -200, 'refund': 200, 'suspense': 0, 'new_balance': 0}], ['control 1', {'due': {'interest': 0, 'principal': 2000, 'late_fee': 0, 'fees': 0}, 'payment': 1000, 'suspense': 0, 'threshold': 1000, 'balance': 5000}, {'applied': {'interest': 0, 'principal': 1000, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 4000}], ['control 2', {'due': {'interest': 0, 'principal': 800, 'late_fee': 0, 'fees': 35}, 'payment': 835, 'suspense': 0, 'threshold': 835, 'balance': 5000}, {'applied': {'interest': 0, 'principal': 800, 'late_fee': 0, 'fees': 35}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 4200}], ['control 3', {'due': {'interest': 0, 'principal': 800, 'late_fee': 0, 'fees': 0}, 'payment': 5800, 'suspense': 0, 'threshold': 800, 'balance': 100000}, {'applied': {'interest': 0, 'principal': 800, 'late_fee': 0, 'fees': 0}, 'curtailment': 5000, 'refund': 0, 'suspense': 0, 'new_balance': 94200}], ['control 4', {'due': {'interest': 1250, 'principal': 800, 'late_fee': 0, 'fees': 35}, 'payment': 2084, 'suspense': 0, 'threshold': 1000, 'balance': 2000}, {'applied': {'interest': 1250, 'principal': 800, 'late_fee': 0, 'fees': 34}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 1200}], ['control 5', {'due': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'payment': 5035, 'suspense': 0, 'threshold': 0, 'balance': 100000}, {'applied': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'curtailment': 5000, 'refund': 0, 'suspense': 0, 'new_balance': 95000}], ['control 6', {'due': {'interest': 0, 'principal': 2000, 'late_fee': 150, 'fees': 35}, 'payment': 2184, 'suspense': 0, 'threshold': 0, 'balance': 100000}, {'applied': {'interest': 0, 'principal': 2000, 'late_fee': 150, 'fees': 34}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 98000}]], [['regression: suspense release', {'due': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'payment': 36, 'suspense': 700, 'threshold': 35, 'balance': 800}, {'applied': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'curtailment': 701, 'refund': 0, 'suspense': 0, 'new_balance': 99}], ['control 1', {'due': {'interest': 1250, 'principal': 0, 'late_fee': 150, 'fees': 0}, 'payment': 1000, 'suspense': 0, 'threshold': 1000, 'balance': 2000}, {'applied': {'interest': 1000, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 2000}], ['control 2', {'due': {'interest': 500, 'principal': 2000, 'late_fee': 150, 'fees': 0}, 'payment': 2650, 'suspense': 0, 'threshold': 2650, 'balance': 2000}, {'applied': {'interest': 500, 'principal': 2000, 'late_fee': 150, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 0}], ['control 3', {'due': {'interest': 500, 'principal': 2000, 'late_fee': 150, 'fees': 0}, 'payment': 2500, 'suspense': 0, 'threshold': 0, 'balance': 5000}, {'applied': {'interest': 500, 'principal': 2000, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 3000}], ['control 4', {'due': {'interest': 1250, 'principal': 800, 'late_fee': 150, 'fees': 0}, 'payment': 7200, 'suspense': 0, 'threshold': 2200, 'balance': 800}, {'applied': {'interest': 1250, 'principal': 800, 'late_fee': 150, 'fees': 0}, 'curtailment': 0, 'refund': 5000, 'suspense': 0, 'new_balance': 0}], ['control 5', {'due': {'interest': 500, 'principal': 800, 'late_fee': 150, 'fees': 35}, 'payment': 1485, 'suspense': 0, 'threshold': 0, 'balance': 5000}, {'applied': {'interest': 500, 'principal': 800, 'late_fee': 150, 'fees': 35}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 4200}], ['control 6', {'due': {'interest': 500, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'payment': 534, 'suspense': 0, 'threshold': 535, 'balance': 100000}, {'applied': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 534, 'new_balance': 100000}]], [['regression: suspense release', {'due': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'payment': -1, 'suspense': 200, 'threshold': 0, 'balance': 2000}, {'applied': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'curtailment': 199, 'refund': 0, 'suspense': 0, 'new_balance': 1801}], ['regression: suspense release, partial-repair probe', {'due': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'payment': 300, 'suspense': 700, 'threshold': 0, 'balance': 800}, {'applied': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'curtailment': 800, 'refund': 165, 'suspense': 0, 'new_balance': 0}], ['control 1', {'due': {'interest': 500, 'principal': 800, 'late_fee': 0, 'fees': 0}, 'payment': 1300, 'suspense': 0, 'threshold': 1000, 'balance': 800}, {'applied': {'interest': 500, 'principal': 800, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 0}], ['control 2', {'due': {'interest': 1250, 'principal': 0, 'late_fee': 150, 'fees': 0}, 'payment': 300, 'suspense': 0, 'threshold': 0, 'balance': 100000}, {'applied': {'interest': 300, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 100000}], ['control 3', {'due': {'interest': 1250, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'payment': 1000, 'suspense': 0, 'threshold': 1000, 'balance': 2000}, {'applied': {'interest': 1000, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 2000}], ['control 4', {'due': {'interest': 1250, 'principal': 800, 'late_fee': 0, 'fees': 0}, 'payment': 2050, 'suspense': 0, 'threshold': 2050, 'balance': 2000}, {'applied': {'interest': 1250, 'principal': 800, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 1200}], ['control 5', {'due': {'interest': 500, 'principal': 0, 'late_fee': 150, 'fees': 0}, 'payment': 2500, 'suspense': 0, 'threshold': 0, 'balance': 2000}, {'applied': {'interest': 500, 'principal': 0, 'late_fee': 150, 'fees': 0}, 'curtailment': 1850, 'refund': 0, 'suspense': 0, 'new_balance': 150}]]]
for label, args, expected in fixtures[N-1]:
try:
actual = solve(args)
except Exception as exc:
actual = 'raised ' + type(exc).__name__
check(label, actual, 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 |
|---|---|---|---|
| regression: suspense release | {'applied': {'fees': 0, 'interest': 1250, 'late_fee': 150, 'principal': 800}, 'curtailment': 1200, 'new_balance': 0, 'refund': 3800, 'suspense': 0} | {'applied': {'fees': 0, 'interest': 1250, 'late_fee': 150, 'principal': 800}, 'curtailment': 1200, 'new_balance': 0, 'refund': 4000, 'suspense': 0} | Failed |
| control 1 | {'applied': {'fees': 0, 'interest': 0, 'late_fee': 0, 'principal': 0}, 'curtailment': 0, 'new_balance': 800, 'refund': 0, 'suspense': 300} | {'applied': {'fees': 0, 'interest': 0, 'late_fee': 0, 'principal': 0}, 'curtailment': 0, 'new_balance': 800, 'refund': 0, 'suspense': 300} | Passed |
| control 2 | {'applied': {'fees': 0, 'interest': 0, 'late_fee': 0, 'principal': 0}, 'curtailment': 0, 'new_balance': 800, 'refund': 0, 'suspense': 0} | {'applied': {'fees': 0, 'interest': 0, 'late_fee': 0, 'principal': 0}, 'curtailment': 0, 'new_balance': 800, 'refund': 0, 'suspense': 0} | Passed |
| control 3 | {'applied': {'fees': 0, 'interest': 0, 'late_fee': 0, 'principal': 0}, 'curtailment': 0, 'new_balance': 800, 'refund': 0, 'suspense': 300} | {'applied': {'fees': 0, 'interest': 0, 'late_fee': 0, 'principal': 0}, 'curtailment': 0, 'new_balance': 800, 'refund': 0, 'suspense': 300} | Passed |
| control 4 | {'applied': {'fees': 35, 'interest': 1250, 'late_fee': 0, 'principal': 0}, 'curtailment': 0, 'new_balance': 2000, 'refund': 0, 'suspense': 0} | {'applied': {'fees': 35, 'interest': 1250, 'late_fee': 0, 'principal': 0}, 'curtailment': 0, 'new_balance': 2000, 'refund': 0, 'suspense': 0} | Passed |
| control 5 | {'applied': {'fees': 0, 'interest': 0, 'late_fee': 0, 'principal': 800}, 'curtailment': 0, 'new_balance': 4200, 'refund': 0, 'suspense': 0} | {'applied': {'fees': 0, 'interest': 0, 'late_fee': 0, 'principal': 800}, 'curtailment': 0, 'new_balance': 4200, 'refund': 0, 'suspense': 0} | Passed |
| control 6 | {'applied': {'fees': 0, 'interest': 0, 'late_fee': 0, 'principal': 0}, 'curtailment': 0, 'new_balance': 5000, 'refund': 0, 'suspense': 0} | {'applied': {'fees': 0, 'interest': 0, 'late_fee': 0, 'principal': 0}, 'curtailment': 0, 'new_balance': 5000, 'refund': 0, 'suspense': 0} | Passed |
SHA-256 / a14b9c1c7eb67f7135ac41fe5f36d1d43d2be37b48e1814acebf057144e55a35
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
avail = x['payment'] + (x['suspense'] if x['payment'] < x['threshold'] else 0)
applied = {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 0}
if avail < x['threshold']:
return {'applied': applied, 'curtailment': 0, 'refund': 0, 'suspense': avail, 'new_balance': x['balance']}
for k in ('interest', 'principal', 'late_fee', 'fees'):
take = min(avail, x['due'][k])
applied[k] = take
avail -= take
room = x['balance'] - applied['principal']
curt = min(avail, room)
refund = avail - curt
return {'applied': applied, 'curtailment': curt, 'refund': refund, 'suspense': 0, 'new_balance': x['balance'] - applied['principal'] - curt}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: suspense release', {'due': {'interest': 1250, 'principal': 800, 'late_fee': 150, 'fees': 0}, 'payment': 7200, 'suspense': 200, 'threshold': 1250, 'balance': 2000}, {'applied': {'interest': 1250, 'principal': 800, 'late_fee': 150, 'fees': 0}, 'curtailment': 1200, 'refund': 4000, 'suspense': 0, 'new_balance': 0}], ['control 1', {'due': {'interest': 1250, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'payment': 300, 'suspense': 0, 'threshold': 1250, 'balance': 800}, {'applied': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 300, 'new_balance': 800}], ['control 2', {'due': {'interest': 1250, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'payment': 0, 'suspense': 0, 'threshold': 1000, 'balance': 800}, {'applied': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 800}], ['control 3', {'due': {'interest': 500, 'principal': 800, 'late_fee': 0, 'fees': 0}, 'payment': 300, 'suspense': 0, 'threshold': 1300, 'balance': 800}, {'applied': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 300, 'new_balance': 800}], ['control 4', {'due': {'interest': 1250, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'payment': 1285, 'suspense': 0, 'threshold': 1000, 'balance': 2000}, {'applied': {'interest': 1250, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 2000}], ['control 5', {'due': {'interest': 0, 'principal': 800, 'late_fee': 0, 'fees': 0}, 'payment': 800, 'suspense': 0, 'threshold': 0, 'balance': 5000}, {'applied': {'interest': 0, 'principal': 800, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 4200}], ['control 6', {'due': {'interest': 500, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'payment': 0, 'suspense': 0, 'threshold': 535, 'balance': 5000}, {'applied': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 5000}]], [['regression: suspense release', {'due': {'interest': 500, 'principal': 2000, 'late_fee': 0, 'fees': 35}, 'payment': 300, 'suspense': 700, 'threshold': 1000, 'balance': 2000}, {'applied': {'interest': 500, 'principal': 500, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 1500}], ['regression: suspense release, partial-repair probe', {'due': {'interest': 500, 'principal': 2000, 'late_fee': 0, 'fees': 35}, 'payment': 2500, 'suspense': 200, 'threshold': 0, 'balance': 5000}, {'applied': {'interest': 500, 'principal': 2000, 'late_fee': 0, 'fees': 35}, 'curtailment': 165, 'refund': 0, 'suspense': 0, 'new_balance': 2835}], ['control 1', {'due': {'interest': 0, 'principal': 800, 'late_fee': 150, 'fees': 0}, 'payment': 2500, 'suspense': 0, 'threshold': 950, 'balance': 2000}, {'applied': {'interest': 0, 'principal': 800, 'late_fee': 150, 'fees': 0}, 'curtailment': 1200, 'refund': 350, 'suspense': 0, 'new_balance': 0}], ['control 2', {'due': {'interest': 500, 'principal': 0, 'late_fee': 150, 'fees': 0}, 'payment': 649, 'suspense': 0, 'threshold': 650, 'balance': 100000}, {'applied': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 649, 'new_balance': 100000}], ['control 3', {'due': {'interest': 0, 'principal': 800, 'late_fee': 150, 'fees': 0}, 'payment': 2500, 'suspense': 0, 'threshold': 0, 'balance': 800}, {'applied': {'interest': 0, 'principal': 800, 'late_fee': 150, 'fees': 0}, 'curtailment': 0, 'refund': 1550, 'suspense': 0, 'new_balance': 0}], ['control 4', {'due': {'interest': 500, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'payment': 1000, 'suspense': 0, 'threshold': 535, 'balance': 2000}, {'applied': {'interest': 500, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'curtailment': 465, 'refund': 0, 'suspense': 0, 'new_balance': 1535}], ['control 5', {'due': {'interest': 1250, 'principal': 800, 'late_fee': 150, 'fees': 0}, 'payment': 7200, 'suspense': 0, 'threshold': 2200, 'balance': 5000}, {'applied': {'interest': 1250, 'principal': 800, 'late_fee': 150, 'fees': 0}, 'curtailment': 4200, 'refund': 800, 'suspense': 0, 'new_balance': 0}]], [['regression: suspense release', {'due': {'interest': 0, 'principal': 2000, 'late_fee': 150, 'fees': 0}, 'payment': 300, 'suspense': 700, 'threshold': 0, 'balance': 800}, {'applied': {'interest': 0, 'principal': 1000, 'late_fee': 0, 'fees': 0}, 'curtailment': -200, 'refund': 200, 'suspense': 0, 'new_balance': 0}], ['control 1', {'due': {'interest': 0, 'principal': 2000, 'late_fee': 0, 'fees': 0}, 'payment': 1000, 'suspense': 0, 'threshold': 1000, 'balance': 5000}, {'applied': {'interest': 0, 'principal': 1000, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 4000}], ['control 2', {'due': {'interest': 0, 'principal': 800, 'late_fee': 0, 'fees': 35}, 'payment': 835, 'suspense': 0, 'threshold': 835, 'balance': 5000}, {'applied': {'interest': 0, 'principal': 800, 'late_fee': 0, 'fees': 35}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 4200}], ['control 3', {'due': {'interest': 0, 'principal': 800, 'late_fee': 0, 'fees': 0}, 'payment': 5800, 'suspense': 0, 'threshold': 800, 'balance': 100000}, {'applied': {'interest': 0, 'principal': 800, 'late_fee': 0, 'fees': 0}, 'curtailment': 5000, 'refund': 0, 'suspense': 0, 'new_balance': 94200}], ['control 4', {'due': {'interest': 1250, 'principal': 800, 'late_fee': 0, 'fees': 35}, 'payment': 2084, 'suspense': 0, 'threshold': 1000, 'balance': 2000}, {'applied': {'interest': 1250, 'principal': 800, 'late_fee': 0, 'fees': 34}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 1200}], ['control 5', {'due': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'payment': 5035, 'suspense': 0, 'threshold': 0, 'balance': 100000}, {'applied': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'curtailment': 5000, 'refund': 0, 'suspense': 0, 'new_balance': 95000}], ['control 6', {'due': {'interest': 0, 'principal': 2000, 'late_fee': 150, 'fees': 35}, 'payment': 2184, 'suspense': 0, 'threshold': 0, 'balance': 100000}, {'applied': {'interest': 0, 'principal': 2000, 'late_fee': 150, 'fees': 34}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 98000}]], [['regression: suspense release', {'due': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'payment': 36, 'suspense': 700, 'threshold': 35, 'balance': 800}, {'applied': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'curtailment': 701, 'refund': 0, 'suspense': 0, 'new_balance': 99}], ['control 1', {'due': {'interest': 1250, 'principal': 0, 'late_fee': 150, 'fees': 0}, 'payment': 1000, 'suspense': 0, 'threshold': 1000, 'balance': 2000}, {'applied': {'interest': 1000, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 2000}], ['control 2', {'due': {'interest': 500, 'principal': 2000, 'late_fee': 150, 'fees': 0}, 'payment': 2650, 'suspense': 0, 'threshold': 2650, 'balance': 2000}, {'applied': {'interest': 500, 'principal': 2000, 'late_fee': 150, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 0}], ['control 3', {'due': {'interest': 500, 'principal': 2000, 'late_fee': 150, 'fees': 0}, 'payment': 2500, 'suspense': 0, 'threshold': 0, 'balance': 5000}, {'applied': {'interest': 500, 'principal': 2000, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 3000}], ['control 4', {'due': {'interest': 1250, 'principal': 800, 'late_fee': 150, 'fees': 0}, 'payment': 7200, 'suspense': 0, 'threshold': 2200, 'balance': 800}, {'applied': {'interest': 1250, 'principal': 800, 'late_fee': 150, 'fees': 0}, 'curtailment': 0, 'refund': 5000, 'suspense': 0, 'new_balance': 0}], ['control 5', {'due': {'interest': 500, 'principal': 800, 'late_fee': 150, 'fees': 35}, 'payment': 1485, 'suspense': 0, 'threshold': 0, 'balance': 5000}, {'applied': {'interest': 500, 'principal': 800, 'late_fee': 150, 'fees': 35}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 4200}], ['control 6', {'due': {'interest': 500, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'payment': 534, 'suspense': 0, 'threshold': 535, 'balance': 100000}, {'applied': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 534, 'new_balance': 100000}]], [['regression: suspense release', {'due': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'payment': -1, 'suspense': 200, 'threshold': 0, 'balance': 2000}, {'applied': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'curtailment': 199, 'refund': 0, 'suspense': 0, 'new_balance': 1801}], ['regression: suspense release, partial-repair probe', {'due': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'payment': 300, 'suspense': 700, 'threshold': 0, 'balance': 800}, {'applied': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'curtailment': 800, 'refund': 165, 'suspense': 0, 'new_balance': 0}], ['control 1', {'due': {'interest': 500, 'principal': 800, 'late_fee': 0, 'fees': 0}, 'payment': 1300, 'suspense': 0, 'threshold': 1000, 'balance': 800}, {'applied': {'interest': 500, 'principal': 800, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 0}], ['control 2', {'due': {'interest': 1250, 'principal': 0, 'late_fee': 150, 'fees': 0}, 'payment': 300, 'suspense': 0, 'threshold': 0, 'balance': 100000}, {'applied': {'interest': 300, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 100000}], ['control 3', {'due': {'interest': 1250, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'payment': 1000, 'suspense': 0, 'threshold': 1000, 'balance': 2000}, {'applied': {'interest': 1000, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 2000}], ['control 4', {'due': {'interest': 1250, 'principal': 800, 'late_fee': 0, 'fees': 0}, 'payment': 2050, 'suspense': 0, 'threshold': 2050, 'balance': 2000}, {'applied': {'interest': 1250, 'principal': 800, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 1200}], ['control 5', {'due': {'interest': 500, 'principal': 0, 'late_fee': 150, 'fees': 0}, 'payment': 2500, 'suspense': 0, 'threshold': 0, 'balance': 2000}, {'applied': {'interest': 500, 'principal': 0, 'late_fee': 150, 'fees': 0}, 'curtailment': 1850, 'refund': 0, 'suspense': 0, 'new_balance': 150}]]]
for label, args, expected in fixtures[N-1]:
try:
actual = solve(args)
except Exception as exc:
actual = 'raised ' + type(exc).__name__
check(label, actual, 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 |
|---|---|---|---|
| regression: suspense release | {'applied': {'fees': 0, 'interest': 1250, 'late_fee': 150, 'principal': 800}, 'curtailment': 1200, 'new_balance': 0, 'refund': 3800, 'suspense': 0} | {'applied': {'fees': 0, 'interest': 1250, 'late_fee': 150, 'principal': 800}, 'curtailment': 1200, 'new_balance': 0, 'refund': 4000, 'suspense': 0} | Failed |
| control 1 | {'applied': {'fees': 0, 'interest': 0, 'late_fee': 0, 'principal': 0}, 'curtailment': 0, 'new_balance': 800, 'refund': 0, 'suspense': 300} | {'applied': {'fees': 0, 'interest': 0, 'late_fee': 0, 'principal': 0}, 'curtailment': 0, 'new_balance': 800, 'refund': 0, 'suspense': 300} | Passed |
| control 2 | {'applied': {'fees': 0, 'interest': 0, 'late_fee': 0, 'principal': 0}, 'curtailment': 0, 'new_balance': 800, 'refund': 0, 'suspense': 0} | {'applied': {'fees': 0, 'interest': 0, 'late_fee': 0, 'principal': 0}, 'curtailment': 0, 'new_balance': 800, 'refund': 0, 'suspense': 0} | Passed |
| control 3 | {'applied': {'fees': 0, 'interest': 0, 'late_fee': 0, 'principal': 0}, 'curtailment': 0, 'new_balance': 800, 'refund': 0, 'suspense': 300} | {'applied': {'fees': 0, 'interest': 0, 'late_fee': 0, 'principal': 0}, 'curtailment': 0, 'new_balance': 800, 'refund': 0, 'suspense': 300} | Passed |
| control 4 | {'applied': {'fees': 35, 'interest': 1250, 'late_fee': 0, 'principal': 0}, 'curtailment': 0, 'new_balance': 2000, 'refund': 0, 'suspense': 0} | {'applied': {'fees': 35, 'interest': 1250, 'late_fee': 0, 'principal': 0}, 'curtailment': 0, 'new_balance': 2000, 'refund': 0, 'suspense': 0} | Passed |
| control 5 | {'applied': {'fees': 0, 'interest': 0, 'late_fee': 0, 'principal': 800}, 'curtailment': 0, 'new_balance': 4200, 'refund': 0, 'suspense': 0} | {'applied': {'fees': 0, 'interest': 0, 'late_fee': 0, 'principal': 800}, 'curtailment': 0, 'new_balance': 4200, 'refund': 0, 'suspense': 0} | Passed |
| control 6 | {'applied': {'fees': 0, 'interest': 0, 'late_fee': 0, 'principal': 0}, 'curtailment': 0, 'new_balance': 5000, 'refund': 0, 'suspense': 0} | {'applied': {'fees': 0, 'interest': 0, 'late_fee': 0, 'principal': 0}, 'curtailment': 0, 'new_balance': 5000, 'refund': 0, 'suspense': 0} | Passed |
SHA-256 / f0c72e6c6e26ee86f8d024ad2bf509b863a95cf0d1931eb5e1e77d8356a110b0
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
avail = x['payment'] + x['suspense']
applied = {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 0}
if avail < x['threshold']:
return {'applied': applied, 'curtailment': 0, 'refund': 0, 'suspense': avail, 'new_balance': x['balance']}
for k in ('interest', 'principal', 'late_fee', 'fees'):
take = min(avail, x['due'][k])
applied[k] = take
avail -= take
room = x['balance'] - applied['principal']
curt = min(avail, room)
refund = avail - curt
return {'applied': applied, 'curtailment': curt, 'refund': refund, 'suspense': 0, 'new_balance': x['balance'] - applied['principal'] - curt}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: suspense release', {'due': {'interest': 1250, 'principal': 800, 'late_fee': 150, 'fees': 0}, 'payment': 7200, 'suspense': 200, 'threshold': 1250, 'balance': 2000}, {'applied': {'interest': 1250, 'principal': 800, 'late_fee': 150, 'fees': 0}, 'curtailment': 1200, 'refund': 4000, 'suspense': 0, 'new_balance': 0}], ['control 1', {'due': {'interest': 1250, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'payment': 300, 'suspense': 0, 'threshold': 1250, 'balance': 800}, {'applied': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 300, 'new_balance': 800}], ['control 2', {'due': {'interest': 1250, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'payment': 0, 'suspense': 0, 'threshold': 1000, 'balance': 800}, {'applied': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 800}], ['control 3', {'due': {'interest': 500, 'principal': 800, 'late_fee': 0, 'fees': 0}, 'payment': 300, 'suspense': 0, 'threshold': 1300, 'balance': 800}, {'applied': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 300, 'new_balance': 800}], ['control 4', {'due': {'interest': 1250, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'payment': 1285, 'suspense': 0, 'threshold': 1000, 'balance': 2000}, {'applied': {'interest': 1250, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 2000}], ['control 5', {'due': {'interest': 0, 'principal': 800, 'late_fee': 0, 'fees': 0}, 'payment': 800, 'suspense': 0, 'threshold': 0, 'balance': 5000}, {'applied': {'interest': 0, 'principal': 800, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 4200}], ['control 6', {'due': {'interest': 500, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'payment': 0, 'suspense': 0, 'threshold': 535, 'balance': 5000}, {'applied': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 5000}]], [['regression: suspense release', {'due': {'interest': 500, 'principal': 2000, 'late_fee': 0, 'fees': 35}, 'payment': 300, 'suspense': 700, 'threshold': 1000, 'balance': 2000}, {'applied': {'interest': 500, 'principal': 500, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 1500}], ['regression: suspense release, partial-repair probe', {'due': {'interest': 500, 'principal': 2000, 'late_fee': 0, 'fees': 35}, 'payment': 2500, 'suspense': 200, 'threshold': 0, 'balance': 5000}, {'applied': {'interest': 500, 'principal': 2000, 'late_fee': 0, 'fees': 35}, 'curtailment': 165, 'refund': 0, 'suspense': 0, 'new_balance': 2835}], ['control 1', {'due': {'interest': 0, 'principal': 800, 'late_fee': 150, 'fees': 0}, 'payment': 2500, 'suspense': 0, 'threshold': 950, 'balance': 2000}, {'applied': {'interest': 0, 'principal': 800, 'late_fee': 150, 'fees': 0}, 'curtailment': 1200, 'refund': 350, 'suspense': 0, 'new_balance': 0}], ['control 2', {'due': {'interest': 500, 'principal': 0, 'late_fee': 150, 'fees': 0}, 'payment': 649, 'suspense': 0, 'threshold': 650, 'balance': 100000}, {'applied': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 649, 'new_balance': 100000}], ['control 3', {'due': {'interest': 0, 'principal': 800, 'late_fee': 150, 'fees': 0}, 'payment': 2500, 'suspense': 0, 'threshold': 0, 'balance': 800}, {'applied': {'interest': 0, 'principal': 800, 'late_fee': 150, 'fees': 0}, 'curtailment': 0, 'refund': 1550, 'suspense': 0, 'new_balance': 0}], ['control 4', {'due': {'interest': 500, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'payment': 1000, 'suspense': 0, 'threshold': 535, 'balance': 2000}, {'applied': {'interest': 500, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'curtailment': 465, 'refund': 0, 'suspense': 0, 'new_balance': 1535}], ['control 5', {'due': {'interest': 1250, 'principal': 800, 'late_fee': 150, 'fees': 0}, 'payment': 7200, 'suspense': 0, 'threshold': 2200, 'balance': 5000}, {'applied': {'interest': 1250, 'principal': 800, 'late_fee': 150, 'fees': 0}, 'curtailment': 4200, 'refund': 800, 'suspense': 0, 'new_balance': 0}]], [['regression: suspense release', {'due': {'interest': 0, 'principal': 2000, 'late_fee': 150, 'fees': 0}, 'payment': 300, 'suspense': 700, 'threshold': 0, 'balance': 800}, {'applied': {'interest': 0, 'principal': 1000, 'late_fee': 0, 'fees': 0}, 'curtailment': -200, 'refund': 200, 'suspense': 0, 'new_balance': 0}], ['control 1', {'due': {'interest': 0, 'principal': 2000, 'late_fee': 0, 'fees': 0}, 'payment': 1000, 'suspense': 0, 'threshold': 1000, 'balance': 5000}, {'applied': {'interest': 0, 'principal': 1000, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 4000}], ['control 2', {'due': {'interest': 0, 'principal': 800, 'late_fee': 0, 'fees': 35}, 'payment': 835, 'suspense': 0, 'threshold': 835, 'balance': 5000}, {'applied': {'interest': 0, 'principal': 800, 'late_fee': 0, 'fees': 35}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 4200}], ['control 3', {'due': {'interest': 0, 'principal': 800, 'late_fee': 0, 'fees': 0}, 'payment': 5800, 'suspense': 0, 'threshold': 800, 'balance': 100000}, {'applied': {'interest': 0, 'principal': 800, 'late_fee': 0, 'fees': 0}, 'curtailment': 5000, 'refund': 0, 'suspense': 0, 'new_balance': 94200}], ['control 4', {'due': {'interest': 1250, 'principal': 800, 'late_fee': 0, 'fees': 35}, 'payment': 2084, 'suspense': 0, 'threshold': 1000, 'balance': 2000}, {'applied': {'interest': 1250, 'principal': 800, 'late_fee': 0, 'fees': 34}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 1200}], ['control 5', {'due': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'payment': 5035, 'suspense': 0, 'threshold': 0, 'balance': 100000}, {'applied': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'curtailment': 5000, 'refund': 0, 'suspense': 0, 'new_balance': 95000}], ['control 6', {'due': {'interest': 0, 'principal': 2000, 'late_fee': 150, 'fees': 35}, 'payment': 2184, 'suspense': 0, 'threshold': 0, 'balance': 100000}, {'applied': {'interest': 0, 'principal': 2000, 'late_fee': 150, 'fees': 34}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 98000}]], [['regression: suspense release', {'due': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'payment': 36, 'suspense': 700, 'threshold': 35, 'balance': 800}, {'applied': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'curtailment': 701, 'refund': 0, 'suspense': 0, 'new_balance': 99}], ['control 1', {'due': {'interest': 1250, 'principal': 0, 'late_fee': 150, 'fees': 0}, 'payment': 1000, 'suspense': 0, 'threshold': 1000, 'balance': 2000}, {'applied': {'interest': 1000, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 2000}], ['control 2', {'due': {'interest': 500, 'principal': 2000, 'late_fee': 150, 'fees': 0}, 'payment': 2650, 'suspense': 0, 'threshold': 2650, 'balance': 2000}, {'applied': {'interest': 500, 'principal': 2000, 'late_fee': 150, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 0}], ['control 3', {'due': {'interest': 500, 'principal': 2000, 'late_fee': 150, 'fees': 0}, 'payment': 2500, 'suspense': 0, 'threshold': 0, 'balance': 5000}, {'applied': {'interest': 500, 'principal': 2000, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 3000}], ['control 4', {'due': {'interest': 1250, 'principal': 800, 'late_fee': 150, 'fees': 0}, 'payment': 7200, 'suspense': 0, 'threshold': 2200, 'balance': 800}, {'applied': {'interest': 1250, 'principal': 800, 'late_fee': 150, 'fees': 0}, 'curtailment': 0, 'refund': 5000, 'suspense': 0, 'new_balance': 0}], ['control 5', {'due': {'interest': 500, 'principal': 800, 'late_fee': 150, 'fees': 35}, 'payment': 1485, 'suspense': 0, 'threshold': 0, 'balance': 5000}, {'applied': {'interest': 500, 'principal': 800, 'late_fee': 150, 'fees': 35}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 4200}], ['control 6', {'due': {'interest': 500, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'payment': 534, 'suspense': 0, 'threshold': 535, 'balance': 100000}, {'applied': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 534, 'new_balance': 100000}]], [['regression: suspense release', {'due': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'payment': -1, 'suspense': 200, 'threshold': 0, 'balance': 2000}, {'applied': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'curtailment': 199, 'refund': 0, 'suspense': 0, 'new_balance': 1801}], ['regression: suspense release, partial-repair probe', {'due': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'payment': 300, 'suspense': 700, 'threshold': 0, 'balance': 800}, {'applied': {'interest': 0, 'principal': 0, 'late_fee': 0, 'fees': 35}, 'curtailment': 800, 'refund': 165, 'suspense': 0, 'new_balance': 0}], ['control 1', {'due': {'interest': 500, 'principal': 800, 'late_fee': 0, 'fees': 0}, 'payment': 1300, 'suspense': 0, 'threshold': 1000, 'balance': 800}, {'applied': {'interest': 500, 'principal': 800, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 0}], ['control 2', {'due': {'interest': 1250, 'principal': 0, 'late_fee': 150, 'fees': 0}, 'payment': 300, 'suspense': 0, 'threshold': 0, 'balance': 100000}, {'applied': {'interest': 300, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 100000}], ['control 3', {'due': {'interest': 1250, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'payment': 1000, 'suspense': 0, 'threshold': 1000, 'balance': 2000}, {'applied': {'interest': 1000, 'principal': 0, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 2000}], ['control 4', {'due': {'interest': 1250, 'principal': 800, 'late_fee': 0, 'fees': 0}, 'payment': 2050, 'suspense': 0, 'threshold': 2050, 'balance': 2000}, {'applied': {'interest': 1250, 'principal': 800, 'late_fee': 0, 'fees': 0}, 'curtailment': 0, 'refund': 0, 'suspense': 0, 'new_balance': 1200}], ['control 5', {'due': {'interest': 500, 'principal': 0, 'late_fee': 150, 'fees': 0}, 'payment': 2500, 'suspense': 0, 'threshold': 0, 'balance': 2000}, {'applied': {'interest': 500, 'principal': 0, 'late_fee': 150, 'fees': 0}, 'curtailment': 1850, 'refund': 0, 'suspense': 0, 'new_balance': 150}]]]
for label, args, expected in fixtures[N-1]:
try:
actual = solve(args)
except Exception as exc:
actual = 'raised ' + type(exc).__name__
check(label, actual, 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 |
|---|---|---|---|
| regression: suspense release | {'applied': {'fees': 0, 'interest': 1250, 'late_fee': 150, 'principal': 800}, 'curtailment': 1200, 'new_balance': 0, 'refund': 4000, 'suspense': 0} | {'applied': {'fees': 0, 'interest': 1250, 'late_fee': 150, 'principal': 800}, 'curtailment': 1200, 'new_balance': 0, 'refund': 4000, 'suspense': 0} | Passed |
| control 1 | {'applied': {'fees': 0, 'interest': 0, 'late_fee': 0, 'principal': 0}, 'curtailment': 0, 'new_balance': 800, 'refund': 0, 'suspense': 300} | {'applied': {'fees': 0, 'interest': 0, 'late_fee': 0, 'principal': 0}, 'curtailment': 0, 'new_balance': 800, 'refund': 0, 'suspense': 300} | Passed |
| control 2 | {'applied': {'fees': 0, 'interest': 0, 'late_fee': 0, 'principal': 0}, 'curtailment': 0, 'new_balance': 800, 'refund': 0, 'suspense': 0} | {'applied': {'fees': 0, 'interest': 0, 'late_fee': 0, 'principal': 0}, 'curtailment': 0, 'new_balance': 800, 'refund': 0, 'suspense': 0} | Passed |
| control 3 | {'applied': {'fees': 0, 'interest': 0, 'late_fee': 0, 'principal': 0}, 'curtailment': 0, 'new_balance': 800, 'refund': 0, 'suspense': 300} | {'applied': {'fees': 0, 'interest': 0, 'late_fee': 0, 'principal': 0}, 'curtailment': 0, 'new_balance': 800, 'refund': 0, 'suspense': 300} | Passed |
| control 4 | {'applied': {'fees': 35, 'interest': 1250, 'late_fee': 0, 'principal': 0}, 'curtailment': 0, 'new_balance': 2000, 'refund': 0, 'suspense': 0} | {'applied': {'fees': 35, 'interest': 1250, 'late_fee': 0, 'principal': 0}, 'curtailment': 0, 'new_balance': 2000, 'refund': 0, 'suspense': 0} | Passed |
| control 5 | {'applied': {'fees': 0, 'interest': 0, 'late_fee': 0, 'principal': 800}, 'curtailment': 0, 'new_balance': 4200, 'refund': 0, 'suspense': 0} | {'applied': {'fees': 0, 'interest': 0, 'late_fee': 0, 'principal': 800}, 'curtailment': 0, 'new_balance': 4200, 'refund': 0, 'suspense': 0} | Passed |
| control 6 | {'applied': {'fees': 0, 'interest': 0, 'late_fee': 0, 'principal': 0}, 'curtailment': 0, 'new_balance': 5000, 'refund': 0, 'suspense': 0} | {'applied': {'fees': 0, 'interest': 0, 'late_fee': 0, 'principal': 0}, 'curtailment': 0, 'new_balance': 5000, 'refund': 0, 'suspense': 0} | Passed |
SHA-256 / dea0b6692a99d4fa0793284dc33ccbf94afefc26cd57cd2e88d08a89f985fd7b
Verification & scope
A deterministic bounded teaching model with stipulated toy lending rules stated in the contract; money is integer cents and rates are basis points; it makes no claim of conformance to any regulation, servicing standard or product. 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:27.182673+00:00.
Case digest / b98dec6447acf5e8ad9dc94c79b0602d0a3554a3bd61432083517daa6a0f2ca8