FA-58726 / Loan amortization schedules / Open access
Forbearance capitalization or deferral: deferral payment · case 01
Deferred forbearance raises the monthly payment.
ROOT CAUSE
The deferred interest is re-leveled into the payment.
VERIFIED REPAIR
Keep the original payment in defer mode.
Unsuccessful approach: Re-leveling the unchanged balance is not the contractual payment.
Case contract
x = {'principal', 'rate_bp', 'months' n, 'forbear': [start_month, count], 'mode': 'capitalize'|'defer'}. Months before start_month are paid with the level payment (exact annuity, half-up, interest round_half_up(balance*bp/120000)). During the count forbearance months interest accrues on the unchanged balance, rounded monthly, without compounding. The remaining payment count n - (start - 1) is preserved (term extended). capitalize: accrued interest is added to the balance and the payment re-leveled over the remaining count; defer: accrued interest goes to a non-interest bucket and the payment is unchanged. Return {'balance', 'deferred', 'payment'}.
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']
n = x['months']
P = x['principal']
pay = level(P, n)
bal = P
start, count = x['forbear']
for k in range(1, start):
interest = rnd(bal * bp, 120000)
bal -= pay - interest
acc = 0
for k in range(count):
acc += rnd(bal * bp, 120000)
remaining = n - (start - 1)
if x['mode'] == 'capitalize':
bal += acc
new_pay = level(bal, remaining)
deferred = 0
else:
deferred = acc
new_pay = level(bal + acc, remaining)
return {'balance': bal, 'deferred': deferred, 'payment': new_pay}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: deferral payment', {'principal': 250000, 'rate_bp': 1200, 'months': 12, 'forbear': [2, 6], 'mode': 'defer'}, {'balance': 230288, 'deferred': 13818, 'payment': 22212}], ['regression: deferral payment, partial-repair probe', {'principal': 100000, 'rate_bp': 0, 'months': 12, 'forbear': [12, 3], 'mode': 'defer'}, {'balance': 8337, 'deferred': 0, 'payment': 8333}], ['control 1', {'principal': 100000, 'rate_bp': 0, 'months': 24, 'forbear': [1, 3], 'mode': 'defer'}, {'balance': 100000, 'deferred': 0, 'payment': 4167}], ['control 2', {'principal': 100000, 'rate_bp': 1200, 'months': 24, 'forbear': [2, 6], 'mode': 'capitalize'}, {'balance': 102071, 'deferred': 0, 'payment': 4990}], ['control 3', {'principal': 1000000, 'rate_bp': 0, 'months': 60, 'forbear': [1, 3], 'mode': 'capitalize'}, {'balance': 1000000, 'deferred': 0, 'payment': 16667}], ['control 4', {'principal': 100000, 'rate_bp': 0, 'months': 24, 'forbear': [12, 1], 'mode': 'capitalize'}, {'balance': 54163, 'deferred': 0, 'payment': 4166}], ['control 5', {'principal': 100000, 'rate_bp': 1200, 'months': 60, 'forbear': [12, 3], 'mode': 'capitalize'}, {'balance': 88417, 'deferred': 0, 'payment': 2291}]], [['regression: deferral payment', {'principal': 1000000, 'rate_bp': 600, 'months': 24, 'forbear': [6, 6], 'mode': 'defer'}, {'balance': 801419, 'deferred': 24042, 'payment': 44321}], ['control 1', {'principal': 100000, 'rate_bp': 0, 'months': 60, 'forbear': [1, 1], 'mode': 'defer'}, {'balance': 100000, 'deferred': 0, 'payment': 1667}], ['control 2', {'principal': 100000, 'rate_bp': 0, 'months': 60, 'forbear': [6, 6], 'mode': 'defer'}, {'balance': 91665, 'deferred': 0, 'payment': 1667}], ['control 3', {'principal': 250000, 'rate_bp': 1200, 'months': 12, 'forbear': [12, 6], 'mode': 'capitalize'}, {'balance': 23316, 'deferred': 0, 'payment': 23549}], ['control 4', {'principal': 1000000, 'rate_bp': 600, 'months': 24, 'forbear': [2, 3], 'mode': 'capitalize'}, {'balance': 975088, 'deferred': 0, 'payment': 44985}], ['control 5', {'principal': 1000000, 'rate_bp': 0, 'months': 24, 'forbear': [1, 3], 'mode': 'defer'}, {'balance': 1000000, 'deferred': 0, 'payment': 41667}], ['control 6', {'principal': 100000, 'rate_bp': 0, 'months': 24, 'forbear': [6, 1], 'mode': 'defer'}, {'balance': 79165, 'deferred': 0, 'payment': 4167}]], [['regression: deferral payment', {'principal': 250000, 'rate_bp': 1200, 'months': 24, 'forbear': [12, 3], 'mode': 'defer'}, {'balance': 142798, 'deferred': 4284, 'payment': 11768}], ['control 1', {'principal': 1000000, 'rate_bp': 600, 'months': 24, 'forbear': [2, 3], 'mode': 'capitalize'}, {'balance': 975088, 'deferred': 0, 'payment': 44985}], ['control 2', {'principal': 1000000, 'rate_bp': 1200, 'months': 24, 'forbear': [6, 6], 'mode': 'capitalize'}, {'balance': 859545, 'deferred': 0, 'payment': 49898}], ['control 3', {'principal': 100000, 'rate_bp': 1200, 'months': 60, 'forbear': [1, 1], 'mode': 'capitalize'}, {'balance': 101000, 'deferred': 0, 'payment': 2247}], ['control 4', {'principal': 100000, 'rate_bp': 0, 'months': 60, 'forbear': [1, 6], 'mode': 'defer'}, {'balance': 100000, 'deferred': 0, 'payment': 1667}], ['control 5', {'principal': 100000, 'rate_bp': 1200, 'months': 12, 'forbear': [6, 6], 'mode': 'capitalize'}, {'balance': 63367, 'deferred': 0, 'payment': 9418}], ['control 6', {'principal': 250000, 'rate_bp': 1200, 'months': 60, 'forbear': [6, 6], 'mode': 'capitalize'}, {'balance': 248449, 'deferred': 0, 'payment': 5895}]], [['regression: deferral payment', {'principal': 250000, 'rate_bp': 600, 'months': 12, 'forbear': [1, 1], 'mode': 'defer'}, {'balance': 250000, 'deferred': 1250, 'payment': 21517}], ['regression: deferral payment, partial-repair probe', {'principal': 100000, 'rate_bp': 0, 'months': 12, 'forbear': [12, 6], 'mode': 'defer'}, {'balance': 8337, 'deferred': 0, 'payment': 8333}], ['control 1', {'principal': 250000, 'rate_bp': 600, 'months': 60, 'forbear': [6, 3], 'mode': 'capitalize'}, {'balance': 235385, 'deferred': 0, 'payment': 4906}], ['control 2', {'principal': 250000, 'rate_bp': 0, 'months': 12, 'forbear': [12, 1], 'mode': 'capitalize'}, {'balance': 20837, 'deferred': 0, 'payment': 20837}], ['control 3', {'principal': 1000000, 'rate_bp': 0, 'months': 60, 'forbear': [1, 1], 'mode': 'capitalize'}, {'balance': 1000000, 'deferred': 0, 'payment': 16667}], ['control 4', {'principal': 100000, 'rate_bp': 600, 'months': 24, 'forbear': [12, 1], 'mode': 'capitalize'}, {'balance': 55929, 'deferred': 0, 'payment': 4454}], ['control 5', {'principal': 100000, 'rate_bp': 1200, 'months': 60, 'forbear': [6, 1], 'mode': 'capitalize'}, {'balance': 94694, 'deferred': 0, 'payment': 2247}]], [['regression: deferral payment', {'principal': 100000, 'rate_bp': 600, 'months': 60, 'forbear': [12, 3], 'mode': 'defer'}, {'balance': 83837, 'deferred': 1257, 'payment': 1933}], ['regression: deferral payment, partial-repair probe', {'principal': 100000, 'rate_bp': 600, 'months': 12, 'forbear': [6, 3], 'mode': 'defer'}, {'balance': 59058, 'deferred': 885, 'payment': 8607}], ['control 1', {'principal': 100000, 'rate_bp': 0, 'months': 60, 'forbear': [2, 3], 'mode': 'capitalize'}, {'balance': 98333, 'deferred': 0, 'payment': 1667}], ['control 2', {'principal': 1000000, 'rate_bp': 0, 'months': 60, 'forbear': [1, 6], 'mode': 'defer'}, {'balance': 1000000, 'deferred': 0, 'payment': 16667}], ['control 3', {'principal': 1000000, 'rate_bp': 1200, 'months': 24, 'forbear': [2, 3], 'mode': 'capitalize'}, {'balance': 991814, 'deferred': 0, 'payment': 48486}], ['control 4', {'principal': 1000000, 'rate_bp': 0, 'months': 24, 'forbear': [12, 3], 'mode': 'capitalize'}, {'balance': 541663, 'deferred': 0, 'payment': 41666}], ['control 5', {'principal': 100000, 'rate_bp': 1200, 'months': 12, 'forbear': [1, 6], 'mode': 'capitalize'}, {'balance': 106000, 'deferred': 0, 'payment': 9418}]]]
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: deferral payment | {'balance': 230288, 'deferred': 13818, 'payment': 23545} | {'balance': 230288, 'deferred': 13818, 'payment': 22212} | Failed |
| regression: deferral payment, partial-repair probe | {'balance': 8337, 'deferred': 0, 'payment': 8337} | {'balance': 8337, 'deferred': 0, 'payment': 8333} | Failed |
| control 1 | {'balance': 100000, 'deferred': 0, 'payment': 4167} | {'balance': 100000, 'deferred': 0, 'payment': 4167} | Passed |
| control 2 | {'balance': 102071, 'deferred': 0, 'payment': 4990} | {'balance': 102071, 'deferred': 0, 'payment': 4990} | Passed |
| control 3 | {'balance': 1000000, 'deferred': 0, 'payment': 16667} | {'balance': 1000000, 'deferred': 0, 'payment': 16667} | Passed |
| control 4 | {'balance': 54163, 'deferred': 0, 'payment': 4166} | {'balance': 54163, 'deferred': 0, 'payment': 4166} | Passed |
| control 5 | {'balance': 88417, 'deferred': 0, 'payment': 2291} | {'balance': 88417, 'deferred': 0, 'payment': 2291} | Passed |
SHA-256 / 826c2bcf5aada7f5ac1fa4cf9dbfdc9b08fb01c69aae295a113f7029f01f7407
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']
n = x['months']
P = x['principal']
pay = level(P, n)
bal = P
start, count = x['forbear']
for k in range(1, start):
interest = rnd(bal * bp, 120000)
bal -= pay - interest
acc = 0
for k in range(count):
acc += rnd(bal * bp, 120000)
remaining = n - (start - 1)
if x['mode'] == 'capitalize':
bal += acc
new_pay = level(bal, remaining)
deferred = 0
else:
deferred = acc
new_pay = level(bal, remaining)
return {'balance': bal, 'deferred': deferred, 'payment': new_pay}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: deferral payment', {'principal': 250000, 'rate_bp': 1200, 'months': 12, 'forbear': [2, 6], 'mode': 'defer'}, {'balance': 230288, 'deferred': 13818, 'payment': 22212}], ['regression: deferral payment, partial-repair probe', {'principal': 100000, 'rate_bp': 0, 'months': 12, 'forbear': [12, 3], 'mode': 'defer'}, {'balance': 8337, 'deferred': 0, 'payment': 8333}], ['control 1', {'principal': 100000, 'rate_bp': 0, 'months': 24, 'forbear': [1, 3], 'mode': 'defer'}, {'balance': 100000, 'deferred': 0, 'payment': 4167}], ['control 2', {'principal': 100000, 'rate_bp': 1200, 'months': 24, 'forbear': [2, 6], 'mode': 'capitalize'}, {'balance': 102071, 'deferred': 0, 'payment': 4990}], ['control 3', {'principal': 1000000, 'rate_bp': 0, 'months': 60, 'forbear': [1, 3], 'mode': 'capitalize'}, {'balance': 1000000, 'deferred': 0, 'payment': 16667}], ['control 4', {'principal': 100000, 'rate_bp': 0, 'months': 24, 'forbear': [12, 1], 'mode': 'capitalize'}, {'balance': 54163, 'deferred': 0, 'payment': 4166}], ['control 5', {'principal': 100000, 'rate_bp': 1200, 'months': 60, 'forbear': [12, 3], 'mode': 'capitalize'}, {'balance': 88417, 'deferred': 0, 'payment': 2291}]], [['regression: deferral payment', {'principal': 1000000, 'rate_bp': 600, 'months': 24, 'forbear': [6, 6], 'mode': 'defer'}, {'balance': 801419, 'deferred': 24042, 'payment': 44321}], ['control 1', {'principal': 100000, 'rate_bp': 0, 'months': 60, 'forbear': [1, 1], 'mode': 'defer'}, {'balance': 100000, 'deferred': 0, 'payment': 1667}], ['control 2', {'principal': 100000, 'rate_bp': 0, 'months': 60, 'forbear': [6, 6], 'mode': 'defer'}, {'balance': 91665, 'deferred': 0, 'payment': 1667}], ['control 3', {'principal': 250000, 'rate_bp': 1200, 'months': 12, 'forbear': [12, 6], 'mode': 'capitalize'}, {'balance': 23316, 'deferred': 0, 'payment': 23549}], ['control 4', {'principal': 1000000, 'rate_bp': 600, 'months': 24, 'forbear': [2, 3], 'mode': 'capitalize'}, {'balance': 975088, 'deferred': 0, 'payment': 44985}], ['control 5', {'principal': 1000000, 'rate_bp': 0, 'months': 24, 'forbear': [1, 3], 'mode': 'defer'}, {'balance': 1000000, 'deferred': 0, 'payment': 41667}], ['control 6', {'principal': 100000, 'rate_bp': 0, 'months': 24, 'forbear': [6, 1], 'mode': 'defer'}, {'balance': 79165, 'deferred': 0, 'payment': 4167}]], [['regression: deferral payment', {'principal': 250000, 'rate_bp': 1200, 'months': 24, 'forbear': [12, 3], 'mode': 'defer'}, {'balance': 142798, 'deferred': 4284, 'payment': 11768}], ['control 1', {'principal': 1000000, 'rate_bp': 600, 'months': 24, 'forbear': [2, 3], 'mode': 'capitalize'}, {'balance': 975088, 'deferred': 0, 'payment': 44985}], ['control 2', {'principal': 1000000, 'rate_bp': 1200, 'months': 24, 'forbear': [6, 6], 'mode': 'capitalize'}, {'balance': 859545, 'deferred': 0, 'payment': 49898}], ['control 3', {'principal': 100000, 'rate_bp': 1200, 'months': 60, 'forbear': [1, 1], 'mode': 'capitalize'}, {'balance': 101000, 'deferred': 0, 'payment': 2247}], ['control 4', {'principal': 100000, 'rate_bp': 0, 'months': 60, 'forbear': [1, 6], 'mode': 'defer'}, {'balance': 100000, 'deferred': 0, 'payment': 1667}], ['control 5', {'principal': 100000, 'rate_bp': 1200, 'months': 12, 'forbear': [6, 6], 'mode': 'capitalize'}, {'balance': 63367, 'deferred': 0, 'payment': 9418}], ['control 6', {'principal': 250000, 'rate_bp': 1200, 'months': 60, 'forbear': [6, 6], 'mode': 'capitalize'}, {'balance': 248449, 'deferred': 0, 'payment': 5895}]], [['regression: deferral payment', {'principal': 250000, 'rate_bp': 600, 'months': 12, 'forbear': [1, 1], 'mode': 'defer'}, {'balance': 250000, 'deferred': 1250, 'payment': 21517}], ['regression: deferral payment, partial-repair probe', {'principal': 100000, 'rate_bp': 0, 'months': 12, 'forbear': [12, 6], 'mode': 'defer'}, {'balance': 8337, 'deferred': 0, 'payment': 8333}], ['control 1', {'principal': 250000, 'rate_bp': 600, 'months': 60, 'forbear': [6, 3], 'mode': 'capitalize'}, {'balance': 235385, 'deferred': 0, 'payment': 4906}], ['control 2', {'principal': 250000, 'rate_bp': 0, 'months': 12, 'forbear': [12, 1], 'mode': 'capitalize'}, {'balance': 20837, 'deferred': 0, 'payment': 20837}], ['control 3', {'principal': 1000000, 'rate_bp': 0, 'months': 60, 'forbear': [1, 1], 'mode': 'capitalize'}, {'balance': 1000000, 'deferred': 0, 'payment': 16667}], ['control 4', {'principal': 100000, 'rate_bp': 600, 'months': 24, 'forbear': [12, 1], 'mode': 'capitalize'}, {'balance': 55929, 'deferred': 0, 'payment': 4454}], ['control 5', {'principal': 100000, 'rate_bp': 1200, 'months': 60, 'forbear': [6, 1], 'mode': 'capitalize'}, {'balance': 94694, 'deferred': 0, 'payment': 2247}]], [['regression: deferral payment', {'principal': 100000, 'rate_bp': 600, 'months': 60, 'forbear': [12, 3], 'mode': 'defer'}, {'balance': 83837, 'deferred': 1257, 'payment': 1933}], ['regression: deferral payment, partial-repair probe', {'principal': 100000, 'rate_bp': 600, 'months': 12, 'forbear': [6, 3], 'mode': 'defer'}, {'balance': 59058, 'deferred': 885, 'payment': 8607}], ['control 1', {'principal': 100000, 'rate_bp': 0, 'months': 60, 'forbear': [2, 3], 'mode': 'capitalize'}, {'balance': 98333, 'deferred': 0, 'payment': 1667}], ['control 2', {'principal': 1000000, 'rate_bp': 0, 'months': 60, 'forbear': [1, 6], 'mode': 'defer'}, {'balance': 1000000, 'deferred': 0, 'payment': 16667}], ['control 3', {'principal': 1000000, 'rate_bp': 1200, 'months': 24, 'forbear': [2, 3], 'mode': 'capitalize'}, {'balance': 991814, 'deferred': 0, 'payment': 48486}], ['control 4', {'principal': 1000000, 'rate_bp': 0, 'months': 24, 'forbear': [12, 3], 'mode': 'capitalize'}, {'balance': 541663, 'deferred': 0, 'payment': 41666}], ['control 5', {'principal': 100000, 'rate_bp': 1200, 'months': 12, 'forbear': [1, 6], 'mode': 'capitalize'}, {'balance': 106000, 'deferred': 0, 'payment': 9418}]]]
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: deferral payment | {'balance': 230288, 'deferred': 13818, 'payment': 22212} | {'balance': 230288, 'deferred': 13818, 'payment': 22212} | Passed |
| regression: deferral payment, partial-repair probe | {'balance': 8337, 'deferred': 0, 'payment': 8337} | {'balance': 8337, 'deferred': 0, 'payment': 8333} | Failed |
| control 1 | {'balance': 100000, 'deferred': 0, 'payment': 4167} | {'balance': 100000, 'deferred': 0, 'payment': 4167} | Passed |
| control 2 | {'balance': 102071, 'deferred': 0, 'payment': 4990} | {'balance': 102071, 'deferred': 0, 'payment': 4990} | Passed |
| control 3 | {'balance': 1000000, 'deferred': 0, 'payment': 16667} | {'balance': 1000000, 'deferred': 0, 'payment': 16667} | Passed |
| control 4 | {'balance': 54163, 'deferred': 0, 'payment': 4166} | {'balance': 54163, 'deferred': 0, 'payment': 4166} | Passed |
| control 5 | {'balance': 88417, 'deferred': 0, 'payment': 2291} | {'balance': 88417, 'deferred': 0, 'payment': 2291} | Passed |
SHA-256 / 30a93fc90280079f7b836bc19a1f60201caf7f4eeba30b535a511abb4bcbee4e
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']
n = x['months']
P = x['principal']
pay = level(P, n)
bal = P
start, count = x['forbear']
for k in range(1, start):
interest = rnd(bal * bp, 120000)
bal -= pay - interest
acc = 0
for k in range(count):
acc += rnd(bal * bp, 120000)
remaining = n - (start - 1)
if x['mode'] == 'capitalize':
bal += acc
new_pay = level(bal, remaining)
deferred = 0
else:
deferred = acc
new_pay = pay
return {'balance': bal, 'deferred': deferred, 'payment': new_pay}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: deferral payment', {'principal': 250000, 'rate_bp': 1200, 'months': 12, 'forbear': [2, 6], 'mode': 'defer'}, {'balance': 230288, 'deferred': 13818, 'payment': 22212}], ['regression: deferral payment, partial-repair probe', {'principal': 100000, 'rate_bp': 0, 'months': 12, 'forbear': [12, 3], 'mode': 'defer'}, {'balance': 8337, 'deferred': 0, 'payment': 8333}], ['control 1', {'principal': 100000, 'rate_bp': 0, 'months': 24, 'forbear': [1, 3], 'mode': 'defer'}, {'balance': 100000, 'deferred': 0, 'payment': 4167}], ['control 2', {'principal': 100000, 'rate_bp': 1200, 'months': 24, 'forbear': [2, 6], 'mode': 'capitalize'}, {'balance': 102071, 'deferred': 0, 'payment': 4990}], ['control 3', {'principal': 1000000, 'rate_bp': 0, 'months': 60, 'forbear': [1, 3], 'mode': 'capitalize'}, {'balance': 1000000, 'deferred': 0, 'payment': 16667}], ['control 4', {'principal': 100000, 'rate_bp': 0, 'months': 24, 'forbear': [12, 1], 'mode': 'capitalize'}, {'balance': 54163, 'deferred': 0, 'payment': 4166}], ['control 5', {'principal': 100000, 'rate_bp': 1200, 'months': 60, 'forbear': [12, 3], 'mode': 'capitalize'}, {'balance': 88417, 'deferred': 0, 'payment': 2291}]], [['regression: deferral payment', {'principal': 1000000, 'rate_bp': 600, 'months': 24, 'forbear': [6, 6], 'mode': 'defer'}, {'balance': 801419, 'deferred': 24042, 'payment': 44321}], ['control 1', {'principal': 100000, 'rate_bp': 0, 'months': 60, 'forbear': [1, 1], 'mode': 'defer'}, {'balance': 100000, 'deferred': 0, 'payment': 1667}], ['control 2', {'principal': 100000, 'rate_bp': 0, 'months': 60, 'forbear': [6, 6], 'mode': 'defer'}, {'balance': 91665, 'deferred': 0, 'payment': 1667}], ['control 3', {'principal': 250000, 'rate_bp': 1200, 'months': 12, 'forbear': [12, 6], 'mode': 'capitalize'}, {'balance': 23316, 'deferred': 0, 'payment': 23549}], ['control 4', {'principal': 1000000, 'rate_bp': 600, 'months': 24, 'forbear': [2, 3], 'mode': 'capitalize'}, {'balance': 975088, 'deferred': 0, 'payment': 44985}], ['control 5', {'principal': 1000000, 'rate_bp': 0, 'months': 24, 'forbear': [1, 3], 'mode': 'defer'}, {'balance': 1000000, 'deferred': 0, 'payment': 41667}], ['control 6', {'principal': 100000, 'rate_bp': 0, 'months': 24, 'forbear': [6, 1], 'mode': 'defer'}, {'balance': 79165, 'deferred': 0, 'payment': 4167}]], [['regression: deferral payment', {'principal': 250000, 'rate_bp': 1200, 'months': 24, 'forbear': [12, 3], 'mode': 'defer'}, {'balance': 142798, 'deferred': 4284, 'payment': 11768}], ['control 1', {'principal': 1000000, 'rate_bp': 600, 'months': 24, 'forbear': [2, 3], 'mode': 'capitalize'}, {'balance': 975088, 'deferred': 0, 'payment': 44985}], ['control 2', {'principal': 1000000, 'rate_bp': 1200, 'months': 24, 'forbear': [6, 6], 'mode': 'capitalize'}, {'balance': 859545, 'deferred': 0, 'payment': 49898}], ['control 3', {'principal': 100000, 'rate_bp': 1200, 'months': 60, 'forbear': [1, 1], 'mode': 'capitalize'}, {'balance': 101000, 'deferred': 0, 'payment': 2247}], ['control 4', {'principal': 100000, 'rate_bp': 0, 'months': 60, 'forbear': [1, 6], 'mode': 'defer'}, {'balance': 100000, 'deferred': 0, 'payment': 1667}], ['control 5', {'principal': 100000, 'rate_bp': 1200, 'months': 12, 'forbear': [6, 6], 'mode': 'capitalize'}, {'balance': 63367, 'deferred': 0, 'payment': 9418}], ['control 6', {'principal': 250000, 'rate_bp': 1200, 'months': 60, 'forbear': [6, 6], 'mode': 'capitalize'}, {'balance': 248449, 'deferred': 0, 'payment': 5895}]], [['regression: deferral payment', {'principal': 250000, 'rate_bp': 600, 'months': 12, 'forbear': [1, 1], 'mode': 'defer'}, {'balance': 250000, 'deferred': 1250, 'payment': 21517}], ['regression: deferral payment, partial-repair probe', {'principal': 100000, 'rate_bp': 0, 'months': 12, 'forbear': [12, 6], 'mode': 'defer'}, {'balance': 8337, 'deferred': 0, 'payment': 8333}], ['control 1', {'principal': 250000, 'rate_bp': 600, 'months': 60, 'forbear': [6, 3], 'mode': 'capitalize'}, {'balance': 235385, 'deferred': 0, 'payment': 4906}], ['control 2', {'principal': 250000, 'rate_bp': 0, 'months': 12, 'forbear': [12, 1], 'mode': 'capitalize'}, {'balance': 20837, 'deferred': 0, 'payment': 20837}], ['control 3', {'principal': 1000000, 'rate_bp': 0, 'months': 60, 'forbear': [1, 1], 'mode': 'capitalize'}, {'balance': 1000000, 'deferred': 0, 'payment': 16667}], ['control 4', {'principal': 100000, 'rate_bp': 600, 'months': 24, 'forbear': [12, 1], 'mode': 'capitalize'}, {'balance': 55929, 'deferred': 0, 'payment': 4454}], ['control 5', {'principal': 100000, 'rate_bp': 1200, 'months': 60, 'forbear': [6, 1], 'mode': 'capitalize'}, {'balance': 94694, 'deferred': 0, 'payment': 2247}]], [['regression: deferral payment', {'principal': 100000, 'rate_bp': 600, 'months': 60, 'forbear': [12, 3], 'mode': 'defer'}, {'balance': 83837, 'deferred': 1257, 'payment': 1933}], ['regression: deferral payment, partial-repair probe', {'principal': 100000, 'rate_bp': 600, 'months': 12, 'forbear': [6, 3], 'mode': 'defer'}, {'balance': 59058, 'deferred': 885, 'payment': 8607}], ['control 1', {'principal': 100000, 'rate_bp': 0, 'months': 60, 'forbear': [2, 3], 'mode': 'capitalize'}, {'balance': 98333, 'deferred': 0, 'payment': 1667}], ['control 2', {'principal': 1000000, 'rate_bp': 0, 'months': 60, 'forbear': [1, 6], 'mode': 'defer'}, {'balance': 1000000, 'deferred': 0, 'payment': 16667}], ['control 3', {'principal': 1000000, 'rate_bp': 1200, 'months': 24, 'forbear': [2, 3], 'mode': 'capitalize'}, {'balance': 991814, 'deferred': 0, 'payment': 48486}], ['control 4', {'principal': 1000000, 'rate_bp': 0, 'months': 24, 'forbear': [12, 3], 'mode': 'capitalize'}, {'balance': 541663, 'deferred': 0, 'payment': 41666}], ['control 5', {'principal': 100000, 'rate_bp': 1200, 'months': 12, 'forbear': [1, 6], 'mode': 'capitalize'}, {'balance': 106000, 'deferred': 0, 'payment': 9418}]]]
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: deferral payment | {'balance': 230288, 'deferred': 13818, 'payment': 22212} | {'balance': 230288, 'deferred': 13818, 'payment': 22212} | Passed |
| regression: deferral payment, partial-repair probe | {'balance': 8337, 'deferred': 0, 'payment': 8333} | {'balance': 8337, 'deferred': 0, 'payment': 8333} | Passed |
| control 1 | {'balance': 100000, 'deferred': 0, 'payment': 4167} | {'balance': 100000, 'deferred': 0, 'payment': 4167} | Passed |
| control 2 | {'balance': 102071, 'deferred': 0, 'payment': 4990} | {'balance': 102071, 'deferred': 0, 'payment': 4990} | Passed |
| control 3 | {'balance': 1000000, 'deferred': 0, 'payment': 16667} | {'balance': 1000000, 'deferred': 0, 'payment': 16667} | Passed |
| control 4 | {'balance': 54163, 'deferred': 0, 'payment': 4166} | {'balance': 54163, 'deferred': 0, 'payment': 4166} | Passed |
| control 5 | {'balance': 88417, 'deferred': 0, 'payment': 2291} | {'balance': 88417, 'deferred': 0, 'payment': 2291} | Passed |
SHA-256 / a30c9b5a8b2f9032a7f2e5033706cffc9caba28a4480fe089161fbe0b8e475c4
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:29.475994+00:00.
Case digest / f32fead9b2edf5d900fd39d1e575fc5a8d9daea950c688001216686b9bea68c5