FAILURE MAP
← Case archive

FA-58551 / Loan amortization schedules / Open access

Adjustable rate reset with caps: downward adjustment cap · case 01

The note rate drops by more than the cap when the index falls.

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

ROOT CAUSE

Only upward movement is limited by the cap.

VERIFIED REPAIR

Limit movement in both directions.

Unsuccessful approach: Using the periodic cap downward at the first reset ignores the initial cap.

Case contract

x = {'initial_bp', 'index_path': index at each reset, 'margin_bp', 'round_to', 'initial_cap_bp', 'periodic_cap_bp', 'lifetime_cap_bp' (above initial), 'floor_bp'}. At each reset the fully indexed rate index + margin is rounded half-up to a multiple of round_to, limited to within the cap of the previous note rate (initial cap at the first reset, periodic afterwards, both directions), then limited to [floor_bp, initial + lifetime cap]. Return the list of note rates.

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):
    rate = x['initial_bp']
    out = []
    life_max = x['initial_bp'] + x['lifetime_cap_bp']
    for i, idx in enumerate(x['index_path']):
        fi = idx + x['margin_bp']
        q, r = divmod(fi, x['round_to'])
        fi = (q + (1 if 2 * r >= x['round_to'] else 0)) * x['round_to']
        cap = x['initial_cap_bp'] if i == 0 else x['periodic_cap_bp']
        new = min(fi, rate + cap)
        new = max(x['floor_bp'], min(new, life_max))
        out.append(new)
        rate = new
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: downward adjustment cap', {'initial_bp': 450, 'index_path': [250, 650, 100, 650, 650], 'margin_bp': 225, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [475, 575, 475, 575, 675]], ['regression: downward adjustment cap, partial-repair probe', {'initial_bp': 450, 'index_path': [50, 700], 'margin_bp': 250, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [250, 350]], ['control 1', {'initial_bp': 500, 'index_path': [212, 100, 50, 250, 700], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [500, 400, 400, 500, 600]], ['control 2', {'initial_bp': 500, 'index_path': [650], 'margin_bp': 225, 'round_to': 25, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [875]], ['control 3', {'initial_bp': 450, 'index_path': [50, 537, 400, 650], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 300}, [375, 475, 575, 675]], ['control 4', {'initial_bp': 300, 'index_path': [212, 212], 'margin_bp': 275, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [475, 475]], ['control 5', {'initial_bp': 300, 'index_path': [100, 50, 250], 'margin_bp': 275, 'round_to': 50, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 300}, [400, 350, 550]]], [['regression: downward adjustment cap', {'initial_bp': 450, 'index_path': [650, 50, 212], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [650, 550, 500]], ['regression: downward adjustment cap, partial-repair probe', {'initial_bp': 500, 'index_path': [212], 'margin_bp': 225, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [375]], ['control 1', {'initial_bp': 450, 'index_path': [250, 100, 700], 'margin_bp': 225, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [475, 325, 525]], ['control 2', {'initial_bp': 450, 'index_path': [400, 700], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [625, 825]], ['control 3', {'initial_bp': 300, 'index_path': [250], 'margin_bp': 275, 'round_to': 25, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [525]], ['control 4', {'initial_bp': 450, 'index_path': [50], 'margin_bp': 250, 'round_to': 50, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 400}, [400]], ['control 5', {'initial_bp': 500, 'index_path': [212], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [500]]], [['regression: downward adjustment cap', {'initial_bp': 450, 'index_path': [212, 650, 50, 650], 'margin_bp': 250, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 300}, [500, 700, 500, 700]], ['regression: downward adjustment cap, partial-repair probe', {'initial_bp': 500, 'index_path': [50, 50, 50], 'margin_bp': 275, 'round_to': 50, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [350, 350, 350]], ['control 1', {'initial_bp': 450, 'index_path': [250, 250, 212], 'margin_bp': 225, 'round_to': 50, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [500, 500, 450]], ['control 2', {'initial_bp': 450, 'index_path': [100], 'margin_bp': 225, 'round_to': 25, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [400]], ['control 3', {'initial_bp': 500, 'index_path': [212, 537], 'margin_bp': 275, 'round_to': 50, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [500, 700]], ['control 4', {'initial_bp': 500, 'index_path': [700], 'margin_bp': 275, 'round_to': 50, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 400}, [1000]], ['control 5', {'initial_bp': 300, 'index_path': [650, 650], 'margin_bp': 250, 'round_to': 25, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 400}, [800, 900]]], [['regression: downward adjustment cap', {'initial_bp': 450, 'index_path': [537, 250, 212, 212], 'margin_bp': 250, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 300}, [650, 550, 450, 450]], ['regression: downward adjustment cap, partial-repair probe', {'initial_bp': 450, 'index_path': [50], 'margin_bp': 225, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [250]], ['control 1', {'initial_bp': 300, 'index_path': [650, 250, 50, 537, 50], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [500, 500, 375, 575, 375]], ['control 2', {'initial_bp': 300, 'index_path': [400, 400, 537], 'margin_bp': 275, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [500, 675, 800]], ['control 3', {'initial_bp': 500, 'index_path': [537], 'margin_bp': 250, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [700]], ['control 4', {'initial_bp': 300, 'index_path': [250, 250, 250], 'margin_bp': 250, 'round_to': 50, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 300}, [500, 500, 500]], ['control 5', {'initial_bp': 500, 'index_path': [100, 212, 100], 'margin_bp': 250, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [350, 450, 350]]], [['regression: downward adjustment cap', {'initial_bp': 300, 'index_path': [400, 537, 100], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 400}, [500, 700, 500]], ['regression: downward adjustment cap, partial-repair probe', {'initial_bp': 450, 'index_path': [50, 650, 700, 400], 'margin_bp': 250, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [250, 350, 450, 550]], ['control 1', {'initial_bp': 450, 'index_path': [650], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 300}, [875]], ['control 2', {'initial_bp': 300, 'index_path': [50, 650, 50, 250, 537], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [400, 600, 400, 500, 700]], ['control 3', {'initial_bp': 450, 'index_path': [400, 537], 'margin_bp': 250, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 400}, [650, 775]], ['control 4', {'initial_bp': 300, 'index_path': [250], 'margin_bp': 225, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 300}, [500]], ['control 5', {'initial_bp': 450, 'index_path': [250, 537, 250, 700], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [500, 600, 500, 600]]]]
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 fixtureActualExpectedOutcome
regression: downward adjustment cap[475, 575, 325, 425, 525][475, 575, 475, 575, 675]Failed
regression: downward adjustment cap, partial-repair probe[250, 350][250, 350]Passed
control 1[500, 400, 400, 500, 600][500, 400, 400, 500, 600]Passed
control 2[875][875]Passed
control 3[375, 475, 575, 675][375, 475, 575, 675]Passed
control 4[475, 475][475, 475]Passed
control 5[400, 350, 550][400, 350, 550]Passed

SHA-256 / 014b7e78eb37c949f988e684177593d22ccb685e1e41130c6e0e5480724a5311

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(x):
    rate = x['initial_bp']
    out = []
    life_max = x['initial_bp'] + x['lifetime_cap_bp']
    for i, idx in enumerate(x['index_path']):
        fi = idx + x['margin_bp']
        q, r = divmod(fi, x['round_to'])
        fi = (q + (1 if 2 * r >= x['round_to'] else 0)) * x['round_to']
        cap = x['initial_cap_bp'] if i == 0 else x['periodic_cap_bp']
        new = max(rate - x['periodic_cap_bp'], min(fi, rate + cap))
        new = max(x['floor_bp'], min(new, life_max))
        out.append(new)
        rate = new
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: downward adjustment cap', {'initial_bp': 450, 'index_path': [250, 650, 100, 650, 650], 'margin_bp': 225, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [475, 575, 475, 575, 675]], ['regression: downward adjustment cap, partial-repair probe', {'initial_bp': 450, 'index_path': [50, 700], 'margin_bp': 250, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [250, 350]], ['control 1', {'initial_bp': 500, 'index_path': [212, 100, 50, 250, 700], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [500, 400, 400, 500, 600]], ['control 2', {'initial_bp': 500, 'index_path': [650], 'margin_bp': 225, 'round_to': 25, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [875]], ['control 3', {'initial_bp': 450, 'index_path': [50, 537, 400, 650], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 300}, [375, 475, 575, 675]], ['control 4', {'initial_bp': 300, 'index_path': [212, 212], 'margin_bp': 275, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [475, 475]], ['control 5', {'initial_bp': 300, 'index_path': [100, 50, 250], 'margin_bp': 275, 'round_to': 50, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 300}, [400, 350, 550]]], [['regression: downward adjustment cap', {'initial_bp': 450, 'index_path': [650, 50, 212], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [650, 550, 500]], ['regression: downward adjustment cap, partial-repair probe', {'initial_bp': 500, 'index_path': [212], 'margin_bp': 225, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [375]], ['control 1', {'initial_bp': 450, 'index_path': [250, 100, 700], 'margin_bp': 225, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [475, 325, 525]], ['control 2', {'initial_bp': 450, 'index_path': [400, 700], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [625, 825]], ['control 3', {'initial_bp': 300, 'index_path': [250], 'margin_bp': 275, 'round_to': 25, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [525]], ['control 4', {'initial_bp': 450, 'index_path': [50], 'margin_bp': 250, 'round_to': 50, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 400}, [400]], ['control 5', {'initial_bp': 500, 'index_path': [212], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [500]]], [['regression: downward adjustment cap', {'initial_bp': 450, 'index_path': [212, 650, 50, 650], 'margin_bp': 250, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 300}, [500, 700, 500, 700]], ['regression: downward adjustment cap, partial-repair probe', {'initial_bp': 500, 'index_path': [50, 50, 50], 'margin_bp': 275, 'round_to': 50, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [350, 350, 350]], ['control 1', {'initial_bp': 450, 'index_path': [250, 250, 212], 'margin_bp': 225, 'round_to': 50, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [500, 500, 450]], ['control 2', {'initial_bp': 450, 'index_path': [100], 'margin_bp': 225, 'round_to': 25, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [400]], ['control 3', {'initial_bp': 500, 'index_path': [212, 537], 'margin_bp': 275, 'round_to': 50, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [500, 700]], ['control 4', {'initial_bp': 500, 'index_path': [700], 'margin_bp': 275, 'round_to': 50, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 400}, [1000]], ['control 5', {'initial_bp': 300, 'index_path': [650, 650], 'margin_bp': 250, 'round_to': 25, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 400}, [800, 900]]], [['regression: downward adjustment cap', {'initial_bp': 450, 'index_path': [537, 250, 212, 212], 'margin_bp': 250, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 300}, [650, 550, 450, 450]], ['regression: downward adjustment cap, partial-repair probe', {'initial_bp': 450, 'index_path': [50], 'margin_bp': 225, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [250]], ['control 1', {'initial_bp': 300, 'index_path': [650, 250, 50, 537, 50], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [500, 500, 375, 575, 375]], ['control 2', {'initial_bp': 300, 'index_path': [400, 400, 537], 'margin_bp': 275, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [500, 675, 800]], ['control 3', {'initial_bp': 500, 'index_path': [537], 'margin_bp': 250, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [700]], ['control 4', {'initial_bp': 300, 'index_path': [250, 250, 250], 'margin_bp': 250, 'round_to': 50, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 300}, [500, 500, 500]], ['control 5', {'initial_bp': 500, 'index_path': [100, 212, 100], 'margin_bp': 250, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [350, 450, 350]]], [['regression: downward adjustment cap', {'initial_bp': 300, 'index_path': [400, 537, 100], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 400}, [500, 700, 500]], ['regression: downward adjustment cap, partial-repair probe', {'initial_bp': 450, 'index_path': [50, 650, 700, 400], 'margin_bp': 250, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [250, 350, 450, 550]], ['control 1', {'initial_bp': 450, 'index_path': [650], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 300}, [875]], ['control 2', {'initial_bp': 300, 'index_path': [50, 650, 50, 250, 537], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [400, 600, 400, 500, 700]], ['control 3', {'initial_bp': 450, 'index_path': [400, 537], 'margin_bp': 250, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 400}, [650, 775]], ['control 4', {'initial_bp': 300, 'index_path': [250], 'margin_bp': 225, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 300}, [500]], ['control 5', {'initial_bp': 450, 'index_path': [250, 537, 250, 700], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [500, 600, 500, 600]]]]
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 fixtureActualExpectedOutcome
regression: downward adjustment cap[475, 575, 475, 575, 675][475, 575, 475, 575, 675]Passed
regression: downward adjustment cap, partial-repair probe[350, 450][250, 350]Failed
control 1[500, 400, 400, 500, 600][500, 400, 400, 500, 600]Passed
control 2[875][875]Passed
control 3[375, 475, 575, 675][375, 475, 575, 675]Passed
control 4[475, 475][475, 475]Passed
control 5[400, 350, 550][400, 350, 550]Passed

SHA-256 / 897c0557354d013e210dbac947beb94f1f8b22c99e4013deef15531aa35d933c

3 / The verified repair

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

N = 1
observations = []
def solve(x):
    rate = x['initial_bp']
    out = []
    life_max = x['initial_bp'] + x['lifetime_cap_bp']
    for i, idx in enumerate(x['index_path']):
        fi = idx + x['margin_bp']
        q, r = divmod(fi, x['round_to'])
        fi = (q + (1 if 2 * r >= x['round_to'] else 0)) * x['round_to']
        cap = x['initial_cap_bp'] if i == 0 else x['periodic_cap_bp']
        new = max(rate - cap, min(fi, rate + cap))
        new = max(x['floor_bp'], min(new, life_max))
        out.append(new)
        rate = new
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: downward adjustment cap', {'initial_bp': 450, 'index_path': [250, 650, 100, 650, 650], 'margin_bp': 225, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [475, 575, 475, 575, 675]], ['regression: downward adjustment cap, partial-repair probe', {'initial_bp': 450, 'index_path': [50, 700], 'margin_bp': 250, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [250, 350]], ['control 1', {'initial_bp': 500, 'index_path': [212, 100, 50, 250, 700], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [500, 400, 400, 500, 600]], ['control 2', {'initial_bp': 500, 'index_path': [650], 'margin_bp': 225, 'round_to': 25, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [875]], ['control 3', {'initial_bp': 450, 'index_path': [50, 537, 400, 650], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 300}, [375, 475, 575, 675]], ['control 4', {'initial_bp': 300, 'index_path': [212, 212], 'margin_bp': 275, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [475, 475]], ['control 5', {'initial_bp': 300, 'index_path': [100, 50, 250], 'margin_bp': 275, 'round_to': 50, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 300}, [400, 350, 550]]], [['regression: downward adjustment cap', {'initial_bp': 450, 'index_path': [650, 50, 212], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [650, 550, 500]], ['regression: downward adjustment cap, partial-repair probe', {'initial_bp': 500, 'index_path': [212], 'margin_bp': 225, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [375]], ['control 1', {'initial_bp': 450, 'index_path': [250, 100, 700], 'margin_bp': 225, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [475, 325, 525]], ['control 2', {'initial_bp': 450, 'index_path': [400, 700], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [625, 825]], ['control 3', {'initial_bp': 300, 'index_path': [250], 'margin_bp': 275, 'round_to': 25, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [525]], ['control 4', {'initial_bp': 450, 'index_path': [50], 'margin_bp': 250, 'round_to': 50, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 400}, [400]], ['control 5', {'initial_bp': 500, 'index_path': [212], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [500]]], [['regression: downward adjustment cap', {'initial_bp': 450, 'index_path': [212, 650, 50, 650], 'margin_bp': 250, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 300}, [500, 700, 500, 700]], ['regression: downward adjustment cap, partial-repair probe', {'initial_bp': 500, 'index_path': [50, 50, 50], 'margin_bp': 275, 'round_to': 50, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [350, 350, 350]], ['control 1', {'initial_bp': 450, 'index_path': [250, 250, 212], 'margin_bp': 225, 'round_to': 50, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [500, 500, 450]], ['control 2', {'initial_bp': 450, 'index_path': [100], 'margin_bp': 225, 'round_to': 25, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [400]], ['control 3', {'initial_bp': 500, 'index_path': [212, 537], 'margin_bp': 275, 'round_to': 50, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [500, 700]], ['control 4', {'initial_bp': 500, 'index_path': [700], 'margin_bp': 275, 'round_to': 50, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 400}, [1000]], ['control 5', {'initial_bp': 300, 'index_path': [650, 650], 'margin_bp': 250, 'round_to': 25, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 400}, [800, 900]]], [['regression: downward adjustment cap', {'initial_bp': 450, 'index_path': [537, 250, 212, 212], 'margin_bp': 250, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 300}, [650, 550, 450, 450]], ['regression: downward adjustment cap, partial-repair probe', {'initial_bp': 450, 'index_path': [50], 'margin_bp': 225, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [250]], ['control 1', {'initial_bp': 300, 'index_path': [650, 250, 50, 537, 50], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [500, 500, 375, 575, 375]], ['control 2', {'initial_bp': 300, 'index_path': [400, 400, 537], 'margin_bp': 275, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [500, 675, 800]], ['control 3', {'initial_bp': 500, 'index_path': [537], 'margin_bp': 250, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [700]], ['control 4', {'initial_bp': 300, 'index_path': [250, 250, 250], 'margin_bp': 250, 'round_to': 50, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 300}, [500, 500, 500]], ['control 5', {'initial_bp': 500, 'index_path': [100, 212, 100], 'margin_bp': 250, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [350, 450, 350]]], [['regression: downward adjustment cap', {'initial_bp': 300, 'index_path': [400, 537, 100], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 400}, [500, 700, 500]], ['regression: downward adjustment cap, partial-repair probe', {'initial_bp': 450, 'index_path': [50, 650, 700, 400], 'margin_bp': 250, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [250, 350, 450, 550]], ['control 1', {'initial_bp': 450, 'index_path': [650], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 300}, [875]], ['control 2', {'initial_bp': 300, 'index_path': [50, 650, 50, 250, 537], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [400, 600, 400, 500, 700]], ['control 3', {'initial_bp': 450, 'index_path': [400, 537], 'margin_bp': 250, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 400}, [650, 775]], ['control 4', {'initial_bp': 300, 'index_path': [250], 'margin_bp': 225, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 300}, [500]], ['control 5', {'initial_bp': 450, 'index_path': [250, 537, 250, 700], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [500, 600, 500, 600]]]]
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 fixtureActualExpectedOutcome
regression: downward adjustment cap[475, 575, 475, 575, 675][475, 575, 475, 575, 675]Passed
regression: downward adjustment cap, partial-repair probe[250, 350][250, 350]Passed
control 1[500, 400, 400, 500, 600][500, 400, 400, 500, 600]Passed
control 2[875][875]Passed
control 3[375, 475, 575, 675][375, 475, 575, 675]Passed
control 4[475, 475][475, 475]Passed
control 5[400, 350, 550][400, 350, 550]Passed

SHA-256 / f2315614ed308831d4737915549d36c993c617069a399cbdea81e9944c36367e

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

Case digest / 90f3ed0da9cd6c74a004159ce15d4da62b1b344bf65848a1ec1eab252dd54865