FA-58446 / Loan amortization schedules / Open access
Interest-only period with funding stub: stub month selection · case 01
Every interest-only bill is prorated like the funding month.
ROOT CAUSE
The stub proration is applied to all interest-only months.
VERIFIED REPAIR
Prorate only the first interest-only month.
Unsuccessful approach: Prorating the last interest-only month moves the stub to the wrong bill.
Case contract
x = {'principal', 'rate_bp', 'io_months' >= 1, 'amort_months' >= 1, 'fund_day' 1..30}. IO month m pays interest round_half_up(P*bp*days/(120000*30)) with days = 31 - fund_day for the first IO month and 30 otherwise. Then the level payment on the full principal over amort_months (exact annuity, half-up) amortizes with monthly interest round_half_up(balance*bp/120000); the last month pays balance + interest. Return {'io_bills': list of IO payments, 'payment', 'final_payment', 'total_interest'}.
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
import math
from fractions import Fraction
N = 1
observations = []
def solve(x):
def rnd(n, d):
q, r = divmod(n, d)
return q + (1 if 2 * r >= d else 0)
def level(P, n):
if n <= 0 or P <= 0:
return 0
if bp == 0:
exact = Fraction(P, n)
else:
r = Fraction(bp, 120000)
exact = P * r / (1 - (1 + r) ** -n)
return math.floor(exact + Fraction(1, 2))
bp = x['rate_bp']
P = x['principal']
io_bills = []
total_int = 0
for m in range(x['io_months']):
days = 31 - x['fund_day']
interest = rnd(P * bp * days, 120000 * 30)
io_bills.append(interest)
total_int += interest
pay = level(P, x['amort_months'])
bal = P
final = 0
for k in range(1, x['amort_months'] + 1):
interest = rnd(bal * bp, 120000)
total_int += interest
if k == x['amort_months']:
final = bal + interest
else:
bal -= pay - interest
return {'io_bills': io_bills, 'payment': pay, 'final_payment': final, 'total_interest': total_int}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: stub month selection', {'principal': 12345, 'rate_bp': 725, 'io_months': 12, 'amort_months': 12, 'fund_day': 15}, {'io_bills': [40, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75], 'payment': 1070, 'final_payment': 1065, 'total_interest': 1355}], ['control 1', {'principal': 3000000, 'rate_bp': 500, 'io_months': 3, 'amort_months': 60, 'fund_day': 1}, {'io_bills': [12500, 12500, 12500], 'payment': 56614, 'final_payment': 56596, 'total_interest': 434322}], ['control 2', {'principal': 12345, 'rate_bp': 0, 'io_months': 1, 'amort_months': 24, 'fund_day': 2}, {'io_bills': [0], 'payment': 514, 'final_payment': 523, 'total_interest': 0}], ['control 3', {'principal': 3000000, 'rate_bp': 725, 'io_months': 2, 'amort_months': 1, 'fund_day': 1}, {'io_bills': [18125, 18125], 'payment': 3018125, 'final_payment': 3018125, 'total_interest': 54375}], ['control 4', {'principal': 12345, 'rate_bp': 0, 'io_months': 1, 'amort_months': 1, 'fund_day': 2}, {'io_bills': [0], 'payment': 12345, 'final_payment': 12345, 'total_interest': 0}], ['control 5', {'principal': 12345, 'rate_bp': 725, 'io_months': 1, 'amort_months': 60, 'fund_day': 2}, {'io_bills': [72], 'payment': 246, 'final_payment': 239, 'total_interest': 2480}], ['control 6', {'principal': 250000, 'rate_bp': 0, 'io_months': 2, 'amort_months': 60, 'fund_day': 15}, {'io_bills': [0, 0], 'payment': 4167, 'final_payment': 4147, 'total_interest': 0}]], [['regression: stub month selection', {'principal': 250000, 'rate_bp': 500, 'io_months': 2, 'amort_months': 60, 'fund_day': 30}, {'io_bills': [35, 1042], 'payment': 4718, 'final_payment': 4703, 'total_interest': 34142}], ['control 1', {'principal': 12345, 'rate_bp': 0, 'io_months': 3, 'amort_months': 12, 'fund_day': 1}, {'io_bills': [0, 0, 0], 'payment': 1029, 'final_payment': 1026, 'total_interest': 0}], ['control 2', {'principal': 100000, 'rate_bp': 725, 'io_months': 2, 'amort_months': 60, 'fund_day': 1}, {'io_bills': [604, 604], 'payment': 1992, 'final_payment': 1987, 'total_interest': 20723}], ['control 3', {'principal': 3000000, 'rate_bp': 0, 'io_months': 12, 'amort_months': 60, 'fund_day': 2}, {'io_bills': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'payment': 50000, 'final_payment': 50000, 'total_interest': 0}], ['control 4', {'principal': 3000000, 'rate_bp': 500, 'io_months': 3, 'amort_months': 12, 'fund_day': 1}, {'io_bills': [12500, 12500, 12500], 'payment': 256822, 'final_payment': 256827, 'total_interest': 119369}], ['control 5', {'principal': 250000, 'rate_bp': 0, 'io_months': 2, 'amort_months': 24, 'fund_day': 15}, {'io_bills': [0, 0], 'payment': 10417, 'final_payment': 10409, 'total_interest': 0}], ['control 6', {'principal': 3000000, 'rate_bp': 0, 'io_months': 2, 'amort_months': 1, 'fund_day': 2}, {'io_bills': [0, 0], 'payment': 3000000, 'final_payment': 3000000, 'total_interest': 0}]], [['regression: stub month selection', {'principal': 3000000, 'rate_bp': 500, 'io_months': 2, 'amort_months': 24, 'fund_day': 29}, {'io_bills': [833, 12500], 'payment': 131614, 'final_payment': 131618, 'total_interest': 172073}], ['control 1', {'principal': 3000000, 'rate_bp': 500, 'io_months': 3, 'amort_months': 24, 'fund_day': 1}, {'io_bills': [12500, 12500, 12500], 'payment': 131614, 'final_payment': 131618, 'total_interest': 196240}], ['control 2', {'principal': 100000, 'rate_bp': 0, 'io_months': 12, 'amort_months': 24, 'fund_day': 29}, {'io_bills': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'payment': 4167, 'final_payment': 4159, 'total_interest': 0}], ['control 3', {'principal': 12345, 'rate_bp': 0, 'io_months': 2, 'amort_months': 24, 'fund_day': 30}, {'io_bills': [0, 0], 'payment': 514, 'final_payment': 523, 'total_interest': 0}], ['control 4', {'principal': 250000, 'rate_bp': 0, 'io_months': 1, 'amort_months': 1, 'fund_day': 30}, {'io_bills': [0], 'payment': 250000, 'final_payment': 250000, 'total_interest': 0}], ['control 5', {'principal': 250000, 'rate_bp': 500, 'io_months': 2, 'amort_months': 12, 'fund_day': 1}, {'io_bills': [1042, 1042], 'payment': 21402, 'final_payment': 21400, 'total_interest': 8906}], ['control 6', {'principal': 250000, 'rate_bp': 1200, 'io_months': 1, 'amort_months': 1, 'fund_day': 15}, {'io_bills': [1333], 'payment': 252500, 'final_payment': 252500, 'total_interest': 3833}]], [['regression: stub month selection', {'principal': 250000, 'rate_bp': 500, 'io_months': 12, 'amort_months': 60, 'fund_day': 15}, {'io_bills': [556, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042], 'payment': 4718, 'final_payment': 4703, 'total_interest': 45083}], ['control 1', {'principal': 100000, 'rate_bp': 0, 'io_months': 12, 'amort_months': 60, 'fund_day': 29}, {'io_bills': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'payment': 1667, 'final_payment': 1647, 'total_interest': 0}], ['control 2', {'principal': 250000, 'rate_bp': 0, 'io_months': 3, 'amort_months': 1, 'fund_day': 2}, {'io_bills': [0, 0, 0], 'payment': 250000, 'final_payment': 250000, 'total_interest': 0}], ['control 3', {'principal': 100000, 'rate_bp': 500, 'io_months': 1, 'amort_months': 12, 'fund_day': 30}, {'io_bills': [14], 'payment': 8561, 'final_payment': 8559, 'total_interest': 2744}], ['control 4', {'principal': 12345, 'rate_bp': 0, 'io_months': 12, 'amort_months': 60, 'fund_day': 15}, {'io_bills': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'payment': 206, 'final_payment': 191, 'total_interest': 0}], ['control 5', {'principal': 100000, 'rate_bp': 725, 'io_months': 3, 'amort_months': 12, 'fund_day': 1}, {'io_bills': [604, 604, 604], 'payment': 8664, 'final_payment': 8666, 'total_interest': 5782}], ['control 6', {'principal': 12345, 'rate_bp': 0, 'io_months': 2, 'amort_months': 24, 'fund_day': 15}, {'io_bills': [0, 0], 'payment': 514, 'final_payment': 523, 'total_interest': 0}]], [['regression: stub month selection', {'principal': 100000, 'rate_bp': 500, 'io_months': 3, 'amort_months': 60, 'fund_day': 2}, {'io_bills': [403, 417, 417], 'payment': 1887, 'final_payment': 1894, 'total_interest': 14464}], ['control 1', {'principal': 12345, 'rate_bp': 725, 'io_months': 1, 'amort_months': 12, 'fund_day': 2}, {'io_bills': [72], 'payment': 1070, 'final_payment': 1065, 'total_interest': 562}], ['control 2', {'principal': 3000000, 'rate_bp': 725, 'io_months': 1, 'amort_months': 60, 'fund_day': 29}, {'io_bills': [1208], 'payment': 59758, 'final_payment': 59764, 'total_interest': 586694}], ['control 3', {'principal': 250000, 'rate_bp': 725, 'io_months': 1, 'amort_months': 60, 'fund_day': 15}, {'io_bills': [806], 'payment': 4980, 'final_payment': 4967, 'total_interest': 49593}], ['control 4', {'principal': 100000, 'rate_bp': 0, 'io_months': 12, 'amort_months': 24, 'fund_day': 30}, {'io_bills': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'payment': 4167, 'final_payment': 4159, 'total_interest': 0}], ['control 5', {'principal': 3000000, 'rate_bp': 0, 'io_months': 12, 'amort_months': 24, 'fund_day': 15}, {'io_bills': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'payment': 125000, 'final_payment': 125000, 'total_interest': 0}], ['control 6', {'principal': 3000000, 'rate_bp': 500, 'io_months': 1, 'amort_months': 12, 'fund_day': 30}, {'io_bills': [417], 'payment': 256822, 'final_payment': 256827, 'total_interest': 82286}]]]
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: stub month selection | {'final_payment': 1065, 'io_bills': [40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40], 'payment': 1070, 'total_interest': 970} | {'final_payment': 1065, 'io_bills': [40, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75], 'payment': 1070, 'total_interest': 1355} | Failed |
| control 1 | {'final_payment': 56596, 'io_bills': [12500, 12500, 12500], 'payment': 56614, 'total_interest': 434322} | {'final_payment': 56596, 'io_bills': [12500, 12500, 12500], 'payment': 56614, 'total_interest': 434322} | Passed |
| control 2 | {'final_payment': 523, 'io_bills': [0], 'payment': 514, 'total_interest': 0} | {'final_payment': 523, 'io_bills': [0], 'payment': 514, 'total_interest': 0} | Passed |
| control 3 | {'final_payment': 3018125, 'io_bills': [18125, 18125], 'payment': 3018125, 'total_interest': 54375} | {'final_payment': 3018125, 'io_bills': [18125, 18125], 'payment': 3018125, 'total_interest': 54375} | Passed |
| control 4 | {'final_payment': 12345, 'io_bills': [0], 'payment': 12345, 'total_interest': 0} | {'final_payment': 12345, 'io_bills': [0], 'payment': 12345, 'total_interest': 0} | Passed |
| control 5 | {'final_payment': 239, 'io_bills': [72], 'payment': 246, 'total_interest': 2480} | {'final_payment': 239, 'io_bills': [72], 'payment': 246, 'total_interest': 2480} | Passed |
| control 6 | {'final_payment': 4147, 'io_bills': [0, 0], 'payment': 4167, 'total_interest': 0} | {'final_payment': 4147, 'io_bills': [0, 0], 'payment': 4167, 'total_interest': 0} | Passed |
SHA-256 / fca6018b44ff0eccdfd77f56dac3c31250e89f5940352e75df6ce38c6063c555
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(x):
def rnd(n, d):
q, r = divmod(n, d)
return q + (1 if 2 * r >= d else 0)
def level(P, n):
if n <= 0 or P <= 0:
return 0
if bp == 0:
exact = Fraction(P, n)
else:
r = Fraction(bp, 120000)
exact = P * r / (1 - (1 + r) ** -n)
return math.floor(exact + Fraction(1, 2))
bp = x['rate_bp']
P = x['principal']
io_bills = []
total_int = 0
for m in range(x['io_months']):
days = 31 - x['fund_day'] if m == x['io_months'] - 1 else 30
interest = rnd(P * bp * days, 120000 * 30)
io_bills.append(interest)
total_int += interest
pay = level(P, x['amort_months'])
bal = P
final = 0
for k in range(1, x['amort_months'] + 1):
interest = rnd(bal * bp, 120000)
total_int += interest
if k == x['amort_months']:
final = bal + interest
else:
bal -= pay - interest
return {'io_bills': io_bills, 'payment': pay, 'final_payment': final, 'total_interest': total_int}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: stub month selection', {'principal': 12345, 'rate_bp': 725, 'io_months': 12, 'amort_months': 12, 'fund_day': 15}, {'io_bills': [40, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75], 'payment': 1070, 'final_payment': 1065, 'total_interest': 1355}], ['control 1', {'principal': 3000000, 'rate_bp': 500, 'io_months': 3, 'amort_months': 60, 'fund_day': 1}, {'io_bills': [12500, 12500, 12500], 'payment': 56614, 'final_payment': 56596, 'total_interest': 434322}], ['control 2', {'principal': 12345, 'rate_bp': 0, 'io_months': 1, 'amort_months': 24, 'fund_day': 2}, {'io_bills': [0], 'payment': 514, 'final_payment': 523, 'total_interest': 0}], ['control 3', {'principal': 3000000, 'rate_bp': 725, 'io_months': 2, 'amort_months': 1, 'fund_day': 1}, {'io_bills': [18125, 18125], 'payment': 3018125, 'final_payment': 3018125, 'total_interest': 54375}], ['control 4', {'principal': 12345, 'rate_bp': 0, 'io_months': 1, 'amort_months': 1, 'fund_day': 2}, {'io_bills': [0], 'payment': 12345, 'final_payment': 12345, 'total_interest': 0}], ['control 5', {'principal': 12345, 'rate_bp': 725, 'io_months': 1, 'amort_months': 60, 'fund_day': 2}, {'io_bills': [72], 'payment': 246, 'final_payment': 239, 'total_interest': 2480}], ['control 6', {'principal': 250000, 'rate_bp': 0, 'io_months': 2, 'amort_months': 60, 'fund_day': 15}, {'io_bills': [0, 0], 'payment': 4167, 'final_payment': 4147, 'total_interest': 0}]], [['regression: stub month selection', {'principal': 250000, 'rate_bp': 500, 'io_months': 2, 'amort_months': 60, 'fund_day': 30}, {'io_bills': [35, 1042], 'payment': 4718, 'final_payment': 4703, 'total_interest': 34142}], ['control 1', {'principal': 12345, 'rate_bp': 0, 'io_months': 3, 'amort_months': 12, 'fund_day': 1}, {'io_bills': [0, 0, 0], 'payment': 1029, 'final_payment': 1026, 'total_interest': 0}], ['control 2', {'principal': 100000, 'rate_bp': 725, 'io_months': 2, 'amort_months': 60, 'fund_day': 1}, {'io_bills': [604, 604], 'payment': 1992, 'final_payment': 1987, 'total_interest': 20723}], ['control 3', {'principal': 3000000, 'rate_bp': 0, 'io_months': 12, 'amort_months': 60, 'fund_day': 2}, {'io_bills': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'payment': 50000, 'final_payment': 50000, 'total_interest': 0}], ['control 4', {'principal': 3000000, 'rate_bp': 500, 'io_months': 3, 'amort_months': 12, 'fund_day': 1}, {'io_bills': [12500, 12500, 12500], 'payment': 256822, 'final_payment': 256827, 'total_interest': 119369}], ['control 5', {'principal': 250000, 'rate_bp': 0, 'io_months': 2, 'amort_months': 24, 'fund_day': 15}, {'io_bills': [0, 0], 'payment': 10417, 'final_payment': 10409, 'total_interest': 0}], ['control 6', {'principal': 3000000, 'rate_bp': 0, 'io_months': 2, 'amort_months': 1, 'fund_day': 2}, {'io_bills': [0, 0], 'payment': 3000000, 'final_payment': 3000000, 'total_interest': 0}]], [['regression: stub month selection', {'principal': 3000000, 'rate_bp': 500, 'io_months': 2, 'amort_months': 24, 'fund_day': 29}, {'io_bills': [833, 12500], 'payment': 131614, 'final_payment': 131618, 'total_interest': 172073}], ['control 1', {'principal': 3000000, 'rate_bp': 500, 'io_months': 3, 'amort_months': 24, 'fund_day': 1}, {'io_bills': [12500, 12500, 12500], 'payment': 131614, 'final_payment': 131618, 'total_interest': 196240}], ['control 2', {'principal': 100000, 'rate_bp': 0, 'io_months': 12, 'amort_months': 24, 'fund_day': 29}, {'io_bills': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'payment': 4167, 'final_payment': 4159, 'total_interest': 0}], ['control 3', {'principal': 12345, 'rate_bp': 0, 'io_months': 2, 'amort_months': 24, 'fund_day': 30}, {'io_bills': [0, 0], 'payment': 514, 'final_payment': 523, 'total_interest': 0}], ['control 4', {'principal': 250000, 'rate_bp': 0, 'io_months': 1, 'amort_months': 1, 'fund_day': 30}, {'io_bills': [0], 'payment': 250000, 'final_payment': 250000, 'total_interest': 0}], ['control 5', {'principal': 250000, 'rate_bp': 500, 'io_months': 2, 'amort_months': 12, 'fund_day': 1}, {'io_bills': [1042, 1042], 'payment': 21402, 'final_payment': 21400, 'total_interest': 8906}], ['control 6', {'principal': 250000, 'rate_bp': 1200, 'io_months': 1, 'amort_months': 1, 'fund_day': 15}, {'io_bills': [1333], 'payment': 252500, 'final_payment': 252500, 'total_interest': 3833}]], [['regression: stub month selection', {'principal': 250000, 'rate_bp': 500, 'io_months': 12, 'amort_months': 60, 'fund_day': 15}, {'io_bills': [556, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042], 'payment': 4718, 'final_payment': 4703, 'total_interest': 45083}], ['control 1', {'principal': 100000, 'rate_bp': 0, 'io_months': 12, 'amort_months': 60, 'fund_day': 29}, {'io_bills': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'payment': 1667, 'final_payment': 1647, 'total_interest': 0}], ['control 2', {'principal': 250000, 'rate_bp': 0, 'io_months': 3, 'amort_months': 1, 'fund_day': 2}, {'io_bills': [0, 0, 0], 'payment': 250000, 'final_payment': 250000, 'total_interest': 0}], ['control 3', {'principal': 100000, 'rate_bp': 500, 'io_months': 1, 'amort_months': 12, 'fund_day': 30}, {'io_bills': [14], 'payment': 8561, 'final_payment': 8559, 'total_interest': 2744}], ['control 4', {'principal': 12345, 'rate_bp': 0, 'io_months': 12, 'amort_months': 60, 'fund_day': 15}, {'io_bills': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'payment': 206, 'final_payment': 191, 'total_interest': 0}], ['control 5', {'principal': 100000, 'rate_bp': 725, 'io_months': 3, 'amort_months': 12, 'fund_day': 1}, {'io_bills': [604, 604, 604], 'payment': 8664, 'final_payment': 8666, 'total_interest': 5782}], ['control 6', {'principal': 12345, 'rate_bp': 0, 'io_months': 2, 'amort_months': 24, 'fund_day': 15}, {'io_bills': [0, 0], 'payment': 514, 'final_payment': 523, 'total_interest': 0}]], [['regression: stub month selection', {'principal': 100000, 'rate_bp': 500, 'io_months': 3, 'amort_months': 60, 'fund_day': 2}, {'io_bills': [403, 417, 417], 'payment': 1887, 'final_payment': 1894, 'total_interest': 14464}], ['control 1', {'principal': 12345, 'rate_bp': 725, 'io_months': 1, 'amort_months': 12, 'fund_day': 2}, {'io_bills': [72], 'payment': 1070, 'final_payment': 1065, 'total_interest': 562}], ['control 2', {'principal': 3000000, 'rate_bp': 725, 'io_months': 1, 'amort_months': 60, 'fund_day': 29}, {'io_bills': [1208], 'payment': 59758, 'final_payment': 59764, 'total_interest': 586694}], ['control 3', {'principal': 250000, 'rate_bp': 725, 'io_months': 1, 'amort_months': 60, 'fund_day': 15}, {'io_bills': [806], 'payment': 4980, 'final_payment': 4967, 'total_interest': 49593}], ['control 4', {'principal': 100000, 'rate_bp': 0, 'io_months': 12, 'amort_months': 24, 'fund_day': 30}, {'io_bills': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'payment': 4167, 'final_payment': 4159, 'total_interest': 0}], ['control 5', {'principal': 3000000, 'rate_bp': 0, 'io_months': 12, 'amort_months': 24, 'fund_day': 15}, {'io_bills': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'payment': 125000, 'final_payment': 125000, 'total_interest': 0}], ['control 6', {'principal': 3000000, 'rate_bp': 500, 'io_months': 1, 'amort_months': 12, 'fund_day': 30}, {'io_bills': [417], 'payment': 256822, 'final_payment': 256827, 'total_interest': 82286}]]]
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: stub month selection | {'final_payment': 1065, 'io_bills': [75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 40], 'payment': 1070, 'total_interest': 1355} | {'final_payment': 1065, 'io_bills': [40, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75], 'payment': 1070, 'total_interest': 1355} | Failed |
| control 1 | {'final_payment': 56596, 'io_bills': [12500, 12500, 12500], 'payment': 56614, 'total_interest': 434322} | {'final_payment': 56596, 'io_bills': [12500, 12500, 12500], 'payment': 56614, 'total_interest': 434322} | Passed |
| control 2 | {'final_payment': 523, 'io_bills': [0], 'payment': 514, 'total_interest': 0} | {'final_payment': 523, 'io_bills': [0], 'payment': 514, 'total_interest': 0} | Passed |
| control 3 | {'final_payment': 3018125, 'io_bills': [18125, 18125], 'payment': 3018125, 'total_interest': 54375} | {'final_payment': 3018125, 'io_bills': [18125, 18125], 'payment': 3018125, 'total_interest': 54375} | Passed |
| control 4 | {'final_payment': 12345, 'io_bills': [0], 'payment': 12345, 'total_interest': 0} | {'final_payment': 12345, 'io_bills': [0], 'payment': 12345, 'total_interest': 0} | Passed |
| control 5 | {'final_payment': 239, 'io_bills': [72], 'payment': 246, 'total_interest': 2480} | {'final_payment': 239, 'io_bills': [72], 'payment': 246, 'total_interest': 2480} | Passed |
| control 6 | {'final_payment': 4147, 'io_bills': [0, 0], 'payment': 4167, 'total_interest': 0} | {'final_payment': 4147, 'io_bills': [0, 0], 'payment': 4167, 'total_interest': 0} | Passed |
SHA-256 / 8f2cb89f7d7422172539a6e0e9318f91ef2b5b8bfed73de5cb07f16e9b42d513
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(x):
def rnd(n, d):
q, r = divmod(n, d)
return q + (1 if 2 * r >= d else 0)
def level(P, n):
if n <= 0 or P <= 0:
return 0
if bp == 0:
exact = Fraction(P, n)
else:
r = Fraction(bp, 120000)
exact = P * r / (1 - (1 + r) ** -n)
return math.floor(exact + Fraction(1, 2))
bp = x['rate_bp']
P = x['principal']
io_bills = []
total_int = 0
for m in range(x['io_months']):
days = 31 - x['fund_day'] if m == 0 else 30
interest = rnd(P * bp * days, 120000 * 30)
io_bills.append(interest)
total_int += interest
pay = level(P, x['amort_months'])
bal = P
final = 0
for k in range(1, x['amort_months'] + 1):
interest = rnd(bal * bp, 120000)
total_int += interest
if k == x['amort_months']:
final = bal + interest
else:
bal -= pay - interest
return {'io_bills': io_bills, 'payment': pay, 'final_payment': final, 'total_interest': total_int}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: stub month selection', {'principal': 12345, 'rate_bp': 725, 'io_months': 12, 'amort_months': 12, 'fund_day': 15}, {'io_bills': [40, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75], 'payment': 1070, 'final_payment': 1065, 'total_interest': 1355}], ['control 1', {'principal': 3000000, 'rate_bp': 500, 'io_months': 3, 'amort_months': 60, 'fund_day': 1}, {'io_bills': [12500, 12500, 12500], 'payment': 56614, 'final_payment': 56596, 'total_interest': 434322}], ['control 2', {'principal': 12345, 'rate_bp': 0, 'io_months': 1, 'amort_months': 24, 'fund_day': 2}, {'io_bills': [0], 'payment': 514, 'final_payment': 523, 'total_interest': 0}], ['control 3', {'principal': 3000000, 'rate_bp': 725, 'io_months': 2, 'amort_months': 1, 'fund_day': 1}, {'io_bills': [18125, 18125], 'payment': 3018125, 'final_payment': 3018125, 'total_interest': 54375}], ['control 4', {'principal': 12345, 'rate_bp': 0, 'io_months': 1, 'amort_months': 1, 'fund_day': 2}, {'io_bills': [0], 'payment': 12345, 'final_payment': 12345, 'total_interest': 0}], ['control 5', {'principal': 12345, 'rate_bp': 725, 'io_months': 1, 'amort_months': 60, 'fund_day': 2}, {'io_bills': [72], 'payment': 246, 'final_payment': 239, 'total_interest': 2480}], ['control 6', {'principal': 250000, 'rate_bp': 0, 'io_months': 2, 'amort_months': 60, 'fund_day': 15}, {'io_bills': [0, 0], 'payment': 4167, 'final_payment': 4147, 'total_interest': 0}]], [['regression: stub month selection', {'principal': 250000, 'rate_bp': 500, 'io_months': 2, 'amort_months': 60, 'fund_day': 30}, {'io_bills': [35, 1042], 'payment': 4718, 'final_payment': 4703, 'total_interest': 34142}], ['control 1', {'principal': 12345, 'rate_bp': 0, 'io_months': 3, 'amort_months': 12, 'fund_day': 1}, {'io_bills': [0, 0, 0], 'payment': 1029, 'final_payment': 1026, 'total_interest': 0}], ['control 2', {'principal': 100000, 'rate_bp': 725, 'io_months': 2, 'amort_months': 60, 'fund_day': 1}, {'io_bills': [604, 604], 'payment': 1992, 'final_payment': 1987, 'total_interest': 20723}], ['control 3', {'principal': 3000000, 'rate_bp': 0, 'io_months': 12, 'amort_months': 60, 'fund_day': 2}, {'io_bills': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'payment': 50000, 'final_payment': 50000, 'total_interest': 0}], ['control 4', {'principal': 3000000, 'rate_bp': 500, 'io_months': 3, 'amort_months': 12, 'fund_day': 1}, {'io_bills': [12500, 12500, 12500], 'payment': 256822, 'final_payment': 256827, 'total_interest': 119369}], ['control 5', {'principal': 250000, 'rate_bp': 0, 'io_months': 2, 'amort_months': 24, 'fund_day': 15}, {'io_bills': [0, 0], 'payment': 10417, 'final_payment': 10409, 'total_interest': 0}], ['control 6', {'principal': 3000000, 'rate_bp': 0, 'io_months': 2, 'amort_months': 1, 'fund_day': 2}, {'io_bills': [0, 0], 'payment': 3000000, 'final_payment': 3000000, 'total_interest': 0}]], [['regression: stub month selection', {'principal': 3000000, 'rate_bp': 500, 'io_months': 2, 'amort_months': 24, 'fund_day': 29}, {'io_bills': [833, 12500], 'payment': 131614, 'final_payment': 131618, 'total_interest': 172073}], ['control 1', {'principal': 3000000, 'rate_bp': 500, 'io_months': 3, 'amort_months': 24, 'fund_day': 1}, {'io_bills': [12500, 12500, 12500], 'payment': 131614, 'final_payment': 131618, 'total_interest': 196240}], ['control 2', {'principal': 100000, 'rate_bp': 0, 'io_months': 12, 'amort_months': 24, 'fund_day': 29}, {'io_bills': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'payment': 4167, 'final_payment': 4159, 'total_interest': 0}], ['control 3', {'principal': 12345, 'rate_bp': 0, 'io_months': 2, 'amort_months': 24, 'fund_day': 30}, {'io_bills': [0, 0], 'payment': 514, 'final_payment': 523, 'total_interest': 0}], ['control 4', {'principal': 250000, 'rate_bp': 0, 'io_months': 1, 'amort_months': 1, 'fund_day': 30}, {'io_bills': [0], 'payment': 250000, 'final_payment': 250000, 'total_interest': 0}], ['control 5', {'principal': 250000, 'rate_bp': 500, 'io_months': 2, 'amort_months': 12, 'fund_day': 1}, {'io_bills': [1042, 1042], 'payment': 21402, 'final_payment': 21400, 'total_interest': 8906}], ['control 6', {'principal': 250000, 'rate_bp': 1200, 'io_months': 1, 'amort_months': 1, 'fund_day': 15}, {'io_bills': [1333], 'payment': 252500, 'final_payment': 252500, 'total_interest': 3833}]], [['regression: stub month selection', {'principal': 250000, 'rate_bp': 500, 'io_months': 12, 'amort_months': 60, 'fund_day': 15}, {'io_bills': [556, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042], 'payment': 4718, 'final_payment': 4703, 'total_interest': 45083}], ['control 1', {'principal': 100000, 'rate_bp': 0, 'io_months': 12, 'amort_months': 60, 'fund_day': 29}, {'io_bills': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'payment': 1667, 'final_payment': 1647, 'total_interest': 0}], ['control 2', {'principal': 250000, 'rate_bp': 0, 'io_months': 3, 'amort_months': 1, 'fund_day': 2}, {'io_bills': [0, 0, 0], 'payment': 250000, 'final_payment': 250000, 'total_interest': 0}], ['control 3', {'principal': 100000, 'rate_bp': 500, 'io_months': 1, 'amort_months': 12, 'fund_day': 30}, {'io_bills': [14], 'payment': 8561, 'final_payment': 8559, 'total_interest': 2744}], ['control 4', {'principal': 12345, 'rate_bp': 0, 'io_months': 12, 'amort_months': 60, 'fund_day': 15}, {'io_bills': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'payment': 206, 'final_payment': 191, 'total_interest': 0}], ['control 5', {'principal': 100000, 'rate_bp': 725, 'io_months': 3, 'amort_months': 12, 'fund_day': 1}, {'io_bills': [604, 604, 604], 'payment': 8664, 'final_payment': 8666, 'total_interest': 5782}], ['control 6', {'principal': 12345, 'rate_bp': 0, 'io_months': 2, 'amort_months': 24, 'fund_day': 15}, {'io_bills': [0, 0], 'payment': 514, 'final_payment': 523, 'total_interest': 0}]], [['regression: stub month selection', {'principal': 100000, 'rate_bp': 500, 'io_months': 3, 'amort_months': 60, 'fund_day': 2}, {'io_bills': [403, 417, 417], 'payment': 1887, 'final_payment': 1894, 'total_interest': 14464}], ['control 1', {'principal': 12345, 'rate_bp': 725, 'io_months': 1, 'amort_months': 12, 'fund_day': 2}, {'io_bills': [72], 'payment': 1070, 'final_payment': 1065, 'total_interest': 562}], ['control 2', {'principal': 3000000, 'rate_bp': 725, 'io_months': 1, 'amort_months': 60, 'fund_day': 29}, {'io_bills': [1208], 'payment': 59758, 'final_payment': 59764, 'total_interest': 586694}], ['control 3', {'principal': 250000, 'rate_bp': 725, 'io_months': 1, 'amort_months': 60, 'fund_day': 15}, {'io_bills': [806], 'payment': 4980, 'final_payment': 4967, 'total_interest': 49593}], ['control 4', {'principal': 100000, 'rate_bp': 0, 'io_months': 12, 'amort_months': 24, 'fund_day': 30}, {'io_bills': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'payment': 4167, 'final_payment': 4159, 'total_interest': 0}], ['control 5', {'principal': 3000000, 'rate_bp': 0, 'io_months': 12, 'amort_months': 24, 'fund_day': 15}, {'io_bills': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'payment': 125000, 'final_payment': 125000, 'total_interest': 0}], ['control 6', {'principal': 3000000, 'rate_bp': 500, 'io_months': 1, 'amort_months': 12, 'fund_day': 30}, {'io_bills': [417], 'payment': 256822, 'final_payment': 256827, 'total_interest': 82286}]]]
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: stub month selection | {'final_payment': 1065, 'io_bills': [40, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75], 'payment': 1070, 'total_interest': 1355} | {'final_payment': 1065, 'io_bills': [40, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75], 'payment': 1070, 'total_interest': 1355} | Passed |
| control 1 | {'final_payment': 56596, 'io_bills': [12500, 12500, 12500], 'payment': 56614, 'total_interest': 434322} | {'final_payment': 56596, 'io_bills': [12500, 12500, 12500], 'payment': 56614, 'total_interest': 434322} | Passed |
| control 2 | {'final_payment': 523, 'io_bills': [0], 'payment': 514, 'total_interest': 0} | {'final_payment': 523, 'io_bills': [0], 'payment': 514, 'total_interest': 0} | Passed |
| control 3 | {'final_payment': 3018125, 'io_bills': [18125, 18125], 'payment': 3018125, 'total_interest': 54375} | {'final_payment': 3018125, 'io_bills': [18125, 18125], 'payment': 3018125, 'total_interest': 54375} | Passed |
| control 4 | {'final_payment': 12345, 'io_bills': [0], 'payment': 12345, 'total_interest': 0} | {'final_payment': 12345, 'io_bills': [0], 'payment': 12345, 'total_interest': 0} | Passed |
| control 5 | {'final_payment': 239, 'io_bills': [72], 'payment': 246, 'total_interest': 2480} | {'final_payment': 239, 'io_bills': [72], 'payment': 246, 'total_interest': 2480} | Passed |
| control 6 | {'final_payment': 4147, 'io_bills': [0, 0], 'payment': 4167, 'total_interest': 0} | {'final_payment': 4147, 'io_bills': [0, 0], 'payment': 4167, 'total_interest': 0} | Passed |
SHA-256 / 34915caf7f786482d7e1173001fe42f136ff149cfb1074dffe0150a65561bf79
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:26.803919+00:00.
Case digest / e030a9c7d5373c1ab0dae71d1fb915e561d4f4b74c8a238a0c806477f1161ff1